"use client"; /** * Hero — type IS the hero. A display headline at 8-14vw reveals line by line * (manual masked split via KineticText), the iridescent wave asset floats as a * tasteful accent layer, and a trust line anchors the claim. Parallax on the * accent + headline as the hero scrolls out. */ import { useEffect, useRef } from "react"; import { gsap } from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; import KineticText from "./KineticText"; import Magnetic from "./Magnetic"; gsap.registerPlugin(ScrollTrigger); export default function Hero() { const root = useRef(null); useEffect(() => { const el = root.current; if (!el) return; if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return; const ctx = gsap.context(() => { const tl = gsap.timeline({ defaults: { ease: "power4.out" } }); tl.from(".hero__eyebrow", { y: 18, opacity: 0, duration: 0.9, delay: 0.15 }) .from(".hero__accent", { opacity: 0, scale: 1.06, duration: 1.4 }, 0) .from(".hero__sub", { y: 22, opacity: 0, duration: 0.9 }, "-=0.2") .from(".hero__actions > *", { y: 20, opacity: 0, stagger: 0.1, duration: 0.7 }, "-=0.5") .from(".hero__trust", { opacity: 0, duration: 0.8 }, "-=0.4"); // parallax: accent drifts up, headline lifts + fades as hero scrolls out gsap.to(".hero__accent", { yPercent: -18, ease: "none", scrollTrigger: { trigger: el, start: "top top", end: "bottom top", scrub: true }, }); gsap.to(".hero__display", { yPercent: 14, opacity: 0.18, ease: "none", scrollTrigger: { trigger: el, start: "top top", end: "bottom top", scrub: true }, }); }, el); return () => ctx.revert(); }, []); return (
{/* iridescent wave accent — decorative texture layer */} {/* eslint-disable-next-line @next/next/no-img-element */}

We're a results-driven digital marketing agency. We run paid, SEO, and content programs built around your revenue targets, then show you what they returned. Every month.

Get your growth audit See the results

$40M+ in client revenue generated

scroll
); }