- Sync all content from Instagram: fix addresses, trainer names, add 5 new trainers, remove 2 inactive, update class descriptions - Add FAQ section (11 Q&A items) and Pricing section (tabs: subscriptions, rental, rules) - Redesign with editorial magazine feel: centered headings, generous spacing, section glow effects, glassmorphism cards - Migrate entire accent palette from rose to warm gold (#c9a96e) - Replace low-res PNG logo with vector SVG traced via potrace — crisp at any size, animated gradient (black↔gold), heartbeat pulse animation - Make header brand name gold Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
51 lines
1.2 KiB
TypeScript
51 lines
1.2 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
|
|
interface Heart {
|
|
id: number;
|
|
left: number;
|
|
size: number;
|
|
delay: number;
|
|
duration: number;
|
|
opacity: number;
|
|
}
|
|
|
|
export function FloatingHearts() {
|
|
const [hearts, setHearts] = useState<Heart[]>([]);
|
|
|
|
useEffect(() => {
|
|
const generated: Heart[] = Array.from({ length: 12 }, (_, i) => ({
|
|
id: i,
|
|
left: Math.random() * 100,
|
|
size: 8 + Math.random() * 16,
|
|
delay: Math.random() * 10,
|
|
duration: 10 + Math.random() * 15,
|
|
opacity: 0.03 + Math.random() * 0.08,
|
|
}));
|
|
setHearts(generated);
|
|
}, []);
|
|
|
|
if (hearts.length === 0) return null;
|
|
|
|
return (
|
|
<div className="pointer-events-none absolute inset-0 overflow-hidden">
|
|
{hearts.map((heart) => (
|
|
<div
|
|
key={heart.id}
|
|
className="absolute text-[#c9a96e]"
|
|
style={{
|
|
left: `${heart.left}%`,
|
|
bottom: "-20px",
|
|
fontSize: `${heart.size}px`,
|
|
opacity: heart.opacity,
|
|
animation: `heart-float ${heart.duration}s ease-in ${heart.delay}s infinite`,
|
|
}}
|
|
>
|
|
♥
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|