fitmate-landing/components/Hero.tsx
2025-11-20 22:22:22 +07:00

208 lines
12 KiB
TypeScript

import React, { useRef } from 'react';
import { motion, useScroll, useTransform } from 'framer-motion';
import { ChevronRight, Zap, Activity, User } from 'lucide-react';
import { PhoneFrame } from './PhoneFrame';
export const Hero: React.FC = () => {
const targetRef = useRef(null);
const { scrollYProgress } = useScroll({
target: targetRef,
offset: ["start start", "end start"]
});
const y = useTransform(scrollYProgress, [0, 1], [0, 150]);
const opacity = useTransform(scrollYProgress, [0, 0.5], [1, 0]);
return (
<section ref={targetRef} className="relative min-h-screen pt-32 pb-20 lg:pt-40 overflow-hidden flex flex-col justify-center items-center">
{/* Ambient Background */}
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-full h-[1000px] bg-gradient-radial from-primary-500/10 via-transparent to-transparent opacity-50 pointer-events-none" />
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10 w-full">
<div className="flex flex-col items-center text-center">
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, ease: "easeOut" }}
className="mb-8"
>
<div className="inline-flex items-center gap-2 px-4 py-1.5 rounded-full bg-white/5 border border-white/10 backdrop-blur-md hover:bg-white/10 transition-colors cursor-default">
<span className="flex h-2 w-2 rounded-full bg-primary-400 shadow-[0_0_10px_#22d3ee]"></span>
<span className="text-sm font-medium text-gray-300 tracking-wide">
Now Available on iOS & Android
</span>
<ChevronRight className="w-3 h-3 text-gray-500" />
</div>
</motion.div>
<h1 className="text-6xl sm:text-7xl lg:text-8xl font-extrabold tracking-tighter text-white mb-8 leading-[1] max-w-5xl">
<motion.span
initial={{ opacity: 0, y: 40 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.1 }}
className="block"
>
Make Every
</motion.span>
<motion.span
initial={{ opacity: 0, y: 40 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.2 }}
className="block text-transparent bg-clip-text bg-gradient-to-r from-white via-gray-200 to-gray-400"
>
Workout Count.
</motion.span>
</h1>
<motion.p
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.4 }}
className="text-xl md:text-2xl text-gray-400 mb-12 leading-relaxed max-w-2xl"
>
Stop using rearview mirrors. FitMate is your <span className="text-primary-400">GPS</span>.
We turn training data into a shame-free game plan for your <em>next</em> meal.
</motion.p>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.5 }}
className="flex flex-col sm:flex-row items-center gap-4 mb-16"
>
{/* App Store Button */}
<button
onClick={() => alert('Redirecting to App Store...')}
className="group flex items-center gap-3 bg-white text-black px-6 py-3 rounded-xl hover:scale-105 transition-all duration-300 shadow-[0_0_40px_rgba(255,255,255,0.2)] cursor-pointer"
>
<svg className="w-6 h-6" viewBox="0 0 24 24" fill="currentColor">
<path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.3-3.14-2.53-2.14-3.08-2.67-7.36-1.97-10.32 1-4.24 3.7-6.76 6.7-1.48.68-1.26.68-1.44.68-1.44.68.85 1.51.85 3.5.7 4.98.82 2.38-.03 3.22-1.33 3.22-1.33.94 2.66 4.41 2.66 4.41s-1.71 3.73-2.62 5.09zM12 5.31c-.77 1.35-2.76 1.78-4.09 1.6-.57-2.02.6-4.24 2.38-5.11 1.78-.87 3.77-.9 4.07 1.61.03.65.03.65-2.36 1.9z"/>
</svg>
<div className="text-left">
<div className="text-[10px] font-medium uppercase tracking-wide opacity-80">Download on the</div>
<div className="text-sm font-bold leading-none">App Store</div>
</div>
</button>
{/* Google Play Button */}
<button
onClick={() => alert('Redirecting to Play Store...')}
className="group flex items-center gap-3 bg-white/5 border border-white/10 text-white px-6 py-3 rounded-xl hover:bg-white/10 hover:scale-105 transition-all duration-300 backdrop-blur-sm cursor-pointer"
>
<svg className="w-6 h-6" viewBox="0 0 24 24" fill="currentColor">
<path d="M3,20.5V3.5C3,2.91,3.34,2.39,3.84,2.15L13.69,12L3.84,21.85C3.34,21.6,3,21.09,3,20.5M16.81,15.12L6.05,21.34L14.54,12.85L16.81,15.12M20.16,10.81C20.5,11.08,20.75,11.5,20.75,12C20.75,12.5,20.53,12.92,20.16,13.19L17.89,14.5L15.39,12L17.89,9.5L20.16,10.81M6.05,2.66L16.81,8.88L14.54,11.15L6.05,2.66Z" />
</svg>
<div className="text-left">
<div className="text-[10px] font-medium uppercase tracking-wide opacity-60">Get it on</div>
<div className="text-sm font-bold leading-none">Google Play</div>
</div>
</button>
</motion.div>
</div>
{/* Parallax Phone Mockup */}
<motion.div
style={{ y, opacity }}
className="mt-4 relative w-full max-w-[340px] mx-auto perspective-1000"
>
{/* Glow behind phone */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[120%] h-[80%] bg-primary-500/30 blur-[120px] rounded-full" />
<PhoneFrame className="h-[700px]">
<div className="h-full w-full pt-14 pb-8 px-6 flex flex-col relative z-10 bg-black">
{/* Header */}
<div className="flex justify-between items-end mb-6">
<div>
<div className="text-gray-400 text-xs font-semibold uppercase tracking-wide">Wednesday</div>
<h1 className="text-3xl font-bold text-white tracking-tight">Leg Day <span className="text-primary-500">.</span></h1>
</div>
<div className="w-9 h-9 rounded-full bg-[#2C2C2E] flex items-center justify-center border border-white/10">
<User size={16} className="text-gray-400" />
</div>
</div>
{/* Segmented Control Lookalike */}
<div className="bg-[#1C1C1E] p-1 rounded-lg mb-8 flex relative">
<div className="absolute top-1 bottom-1 left-1 w-[calc(50%-4px)] bg-[#636366] rounded-[6px] shadow-sm z-0" />
<div className="flex-1 py-1.5 text-[13px] font-semibold rounded-md relative z-10 text-center text-white">
Training Day
</div>
<div className="flex-1 py-1.5 text-[13px] font-semibold rounded-md relative z-10 text-center text-gray-400">
Rest Day
</div>
</div>
{/* Main Ring */}
<div className="flex justify-center mb-8">
<div className="relative w-52 h-52 flex items-center justify-center">
{/* Static SVG for Hero to save perf */}
<svg className="w-full h-full transform -rotate-90 drop-shadow-2xl">
<defs>
<linearGradient id="heroGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stopColor="#06b6d4" />
<stop offset="100%" stopColor="#22d3ee" />
</linearGradient>
</defs>
<circle cx="104" cy="104" r="84" stroke="#1C1C1E" strokeWidth="18" fill="none" />
<circle
cx="104" cy="104" r="84"
stroke="url(#heroGradient)"
strokeWidth="18"
fill="none"
strokeLinecap="round"
strokeDasharray="420 527"
className="filter drop-shadow-[0_0_10px_rgba(34,211,238,0.3)]"
/>
</svg>
<div className="absolute inset-0 flex flex-col items-center justify-center">
<div className="text-5xl font-bold text-white tracking-tighter font-sans">2,850</div>
<div className="text-primary-400 text-sm font-semibold uppercase tracking-wide mt-1">kcal Left</div>
</div>
</div>
</div>
{/* Cards */}
<div className="grid grid-cols-2 gap-4 mb-4">
<div className="bg-[#1C1C1E] rounded-2xl p-4 relative overflow-hidden border border-white/5">
<div className="absolute top-0 right-0 p-2 opacity-20"><Activity /></div>
<div className="text-[13px] font-medium text-gray-400 mb-1">Carbs</div>
<div className="text-2xl font-bold text-white mb-2">320g</div>
<div className="w-full bg-gray-800 h-1.5 rounded-full overflow-hidden">
<div className="h-full bg-primary-500 w-[85%]" />
</div>
</div>
<div className="bg-[#1C1C1E] rounded-2xl p-4 relative overflow-hidden border border-white/5">
<div className="absolute top-0 right-0 p-2 opacity-20"><Zap /></div>
<div className="text-[13px] font-medium text-gray-400 mb-1">Protein</div>
<div className="text-2xl font-bold text-white mb-2">200g</div>
<div className="w-full bg-gray-800 h-1.5 rounded-full overflow-hidden">
<div className="h-full bg-purple-500 w-[65%]" />
</div>
</div>
</div>
{/* Insight Card */}
<div className="bg-gradient-to-br from-[#1C1C1E] to-[#111] border border-white/5 rounded-2xl p-4 flex-1 min-h-0 relative overflow-hidden">
<div className="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-primary-500 to-transparent" />
<div className="flex items-center gap-2 mb-3">
<div className="p-1.5 bg-primary-500/10 rounded-lg text-primary-400">
<Zap size={14} fill="currentColor" />
</div>
<span className="text-sm font-bold text-white">Co-Pilot Insight</span>
</div>
<p className="text-[13px] text-gray-300 leading-relaxed">
Squat volume is high. I've increased pre-workout carbs by 40g. Drink 500ml water now.
</p>
</div>
</div>
</PhoneFrame>
</motion.div>
</div>
</section>
);
};