feat: animated hero with parallax rocket + scroll reveal animations

- Add animated hero section with parallax rocket SVG that descends on scroll
- Add floating decorative particles and gradient layers in hero
- Add staggered text reveal animation on hero h1
- Create ScrollReveal component (IntersectionObserver-based fade/slide)
- Create AnimatedCounter component for stat numbers
- Add scroll animations to all sections (Problematique, System, Demos, AboutMe, FAQ, Contact, Footer)
- Add smooth FAQ accordion transitions
- Add extensive CSS keyframe animations (float, flame, particles, stat glow)

https://claude.ai/code/session_01V8YAjpqRQ3bfBYsABYsEgo
This commit is contained in:
Claude
2026-02-16 19:09:16 +00:00
parent e94a03f302
commit 6555969c30
13 changed files with 1143 additions and 444 deletions

View File

@@ -0,0 +1,62 @@
"use client";
import { useEffect, useRef, type ReactNode } from "react";
interface ScrollRevealProps {
children: ReactNode;
className?: string;
delay?: number;
direction?: "up" | "down" | "left" | "right" | "none";
duration?: number;
once?: boolean;
}
export default function ScrollReveal({
children,
className = "",
delay = 0,
direction = "up",
duration = 700,
once = true,
}: ScrollRevealProps) {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
el.style.transitionDelay = `${delay}ms`;
el.classList.add("scroll-revealed");
if (once) observer.unobserve(el);
} else if (!once) {
el.classList.remove("scroll-revealed");
}
},
{ threshold: 0.15, rootMargin: "0px 0px -50px 0px" }
);
observer.observe(el);
return () => observer.disconnect();
}, [delay, once]);
const directionClass = {
up: "scroll-reveal-up",
down: "scroll-reveal-down",
left: "scroll-reveal-left",
right: "scroll-reveal-right",
none: "scroll-reveal-fade",
}[direction];
return (
<div
ref={ref}
className={`${directionClass} ${className}`}
style={{ transitionDuration: `${duration}ms` }}
>
{children}
</div>
);
}