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

102 lines
3.8 KiB
TypeScript

import React, { useRef, useState } from 'react';
import { Brain, LineChart, Mic, CalendarClock } from 'lucide-react';
import { FeatureItem } from '../types';
const FEATURES: FeatureItem[] = [
{
title: "The Performance Co-Pilot",
description: "Training-aware guidance. We tell you to eat more carbs on Leg Day and prioritize protein on Rest Days.",
icon: Brain,
className: "md:col-span-2 md:row-span-2"
},
{
title: "Day 1 Action Plan",
description: "No 'learning phase.' Get an intelligent, customized plan immediately.",
icon: CalendarClock,
className: "md:col-span-1 md:row-span-1"
},
{
title: "Purposeful Logging",
description: "Log via photo, voice, or text. Inputs act as commands to the Co-Pilot.",
icon: Mic,
className: "md:col-span-1 md:row-span-1"
},
{
title: "Forward-Looking Dashboard",
description: "See how 92% consistency translates to trend weight changes.",
icon: LineChart,
className: "md:col-span-3 lg:col-span-2"
}
];
const SpotlightCard: React.FC<{ feature: FeatureItem }> = ({ feature }) => {
const divRef = useRef<HTMLDivElement>(null);
const [position, setPosition] = useState({ x: 0, y: 0 });
const [opacity, setOpacity] = useState(0);
const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
if (!divRef.current) return;
const rect = divRef.current.getBoundingClientRect();
setPosition({ x: e.clientX - rect.left, y: e.clientY - rect.top });
};
const handleMouseEnter = () => setOpacity(1);
const handleMouseLeave = () => setOpacity(0);
return (
<div
ref={divRef}
onMouseMove={handleMouseMove}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
className={`relative rounded-3xl border border-white/10 bg-black overflow-hidden group ${feature.className}`}
>
{/* Spotlight Gradient */}
<div
className="pointer-events-none absolute -inset-px transition duration-300 opacity-0 group-hover:opacity-100"
style={{
background: `radial-gradient(600px circle at ${position.x}px ${position.y}px, rgba(255,255,255,0.1), transparent 40%)`,
}}
/>
{/* Content Container */}
<div className="relative h-full p-8 flex flex-col bg-surface/50 backdrop-blur-xl z-10 m-[1px] rounded-[23px]">
<div className="mb-6 w-12 h-12 rounded-2xl bg-white/5 border border-white/10 flex items-center justify-center text-primary-400 group-hover:scale-110 transition-transform duration-300">
<feature.icon size={24} />
</div>
<div className="mt-auto">
<h3 className="text-xl font-bold text-white mb-3 tracking-tight">
{feature.title}
</h3>
<p className="text-gray-400 text-sm leading-relaxed">
{feature.description}
</p>
</div>
</div>
</div>
);
};
export const Features: React.FC = () => {
return (
<section id="features" className="py-32 bg-black relative scroll-mt-32">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="mb-20 text-center max-w-3xl mx-auto">
<h2 className="text-4xl md:text-6xl font-bold text-white mb-6 tracking-tighter">
Engineered for <span className="text-transparent bg-clip-text bg-gradient-to-r from-primary-400 to-blue-500">Results</span>
</h2>
<p className="text-gray-400 text-lg">
A suite of tools designed to minimize friction and maximize adherence.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4 lg:gap-6 auto-rows-[minmax(280px,auto)]">
{FEATURES.map((feature, idx) => (
<SpotlightCard key={idx} feature={feature} />
))}
</div>
</div>
</section>
);
};