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

111 lines
5.0 KiB
TypeScript

import React, { useRef } from 'react';
import { motion, useScroll, useTransform } from 'framer-motion';
import { Dumbbell, Cpu, Utensils, TrendingUp } from 'lucide-react';
const STEPS = [
{
icon: Dumbbell,
title: "Input",
subtitle: "Log Training",
description: "You log your workout (e.g., Heavy Leg Day, 90 min).",
color: "bg-blue-500"
},
{
icon: Cpu,
title: "Process",
subtitle: "Analysis",
description: "The Co-Pilot analyzes your metabolic state and recovery needs.",
color: "bg-purple-500"
},
{
icon: Utensils,
title: "Output",
subtitle: "The Plan",
description: "You get a specific food target: 'Eat 60g Carbs + 40g Protein now.'",
color: "bg-primary-500"
},
{
icon: TrendingUp,
title: "Result",
subtitle: "Optimization",
description: "You wake up stronger, not fatter. Performance is prioritized.",
color: "bg-green-500"
}
];
export const Logic: React.FC = () => {
const containerRef = useRef<HTMLDivElement>(null);
const { scrollYProgress } = useScroll({
target: containerRef,
offset: ["start end", "end start"]
});
const lineHeight = useTransform(scrollYProgress, [0, 0.8], ["0%", "100%"]);
return (
<section id="logic" className="py-32 bg-black relative overflow-hidden scroll-mt-32">
{/* Background Effects */}
<div className="absolute inset-0 bg-[radial-gradient(circle_at_top_right,_var(--tw-gradient-stops))] from-primary-900/10 via-black to-black pointer-events-none" />
<div className="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
<div className="text-center mb-20">
<h2 className="text-4xl md:text-6xl font-bold text-white mb-6 tracking-tighter">
The Logic
</h2>
<p className="text-xl text-gray-400 max-w-2xl mx-auto">
How FitMate turns your sweat into data, and data into direction.
</p>
</div>
<div ref={containerRef} className="relative">
{/* Connecting Line */}
<div className="absolute left-[28px] md:left-1/2 top-0 bottom-0 w-0.5 bg-white/10 md:-translate-x-1/2" />
<motion.div
style={{ height: lineHeight }}
className="absolute left-[28px] md:left-1/2 top-0 w-0.5 bg-gradient-to-b from-primary-500 via-purple-500 to-primary-500 md:-translate-x-1/2 shadow-[0_0_15px_rgba(34,211,238,0.5)]"
/>
<div className="space-y-12 md:space-y-24">
{STEPS.map((step, idx) => (
<motion.div
key={idx}
initial={{ opacity: 0, y: 50 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-100px" }}
transition={{ duration: 0.6, delay: idx * 0.1 }}
className={`relative flex flex-col md:flex-row gap-8 md:gap-16 items-start md:items-center ${idx % 2 === 0 ? 'md:flex-row-reverse' : ''}`}
>
{/* Content Card */}
<div className="flex-1 ml-16 md:ml-0 w-full md:w-auto">
<div className={`bg-surfaceHighlight/50 border border-white/10 p-6 rounded-2xl backdrop-blur-sm hover:border-primary-500/30 transition-colors duration-500 group w-full md:max-w-md ${idx % 2 === 0 ? 'mr-auto' : 'ml-auto'}`}>
<div className="flex items-center gap-3 mb-3">
<span className="text-xs font-mono text-gray-500 uppercase tracking-widest">Step 0{idx + 1}</span>
<span className="h-px flex-1 bg-white/10 group-hover:bg-primary-500/30 transition-colors" />
</div>
<h3 className="text-2xl font-bold text-white mb-1">{step.subtitle}</h3>
<h4 className="text-lg text-gray-400 mb-3">{step.title}</h4>
<p className="text-gray-400 leading-relaxed text-sm">
{step.description}
</p>
</div>
</div>
{/* Icon Marker */}
<div className="absolute left-0 md:left-1/2 md:-translate-x-1/2 flex items-center justify-center w-14 h-14 rounded-full bg-black border-4 border-surface z-10">
<div className={`w-full h-full rounded-full flex items-center justify-center bg-surfaceHighlight border border-white/10 text-white relative overflow-hidden`}>
<div className={`absolute inset-0 opacity-20 ${step.color}`} />
<step.icon size={20} className="relative z-10" />
</div>
</div>
{/* Empty spacer for layout balance */}
<div className="hidden md:block flex-1" />
</motion.div>
))}
</div>
</div>
</div>
</section>
);
};