'use client' // HeroSection.tsx — Cinematic hero with GSAP + ScrollTrigger // Dependencies: gsap @gsap/react framer-motion // Replace all brand.* references with values from src/lib/brand.ts import { useRef } from 'react' import { useGSAP } from '@gsap/react' import gsap from 'gsap' import { ScrollTrigger } from 'gsap/ScrollTrigger' import { MagneticButton } from '@/components/ui/magnetic-button' import { brand } from '@/lib/brand' gsap.registerPlugin(ScrollTrigger) export default function HeroSection() { const containerRef = useRef(null) useGSAP( () => { const tl = gsap.timeline() // 1. Word-by-word headline reveal tl.from('.word-inner', { y: 60, opacity: 0, duration: 0.8, stagger: 0.08, ease: 'power4.out', }) // 2. Subheadline fade-up tl.from( '.hero-sub', { y: 30, opacity: 0, duration: 0.7, ease: 'power3.out', }, '-=0.4' ) // 3. CTA spring entrance tl.from( '.hero-cta-wrap', { scale: 0.9, opacity: 0, duration: 0.6, ease: 'back.out(1.4)', }, '-=0.3' ) // 4. Ken-Burns background gsap.to('.hero-bg', { scale: 1.06, duration: 8, ease: 'none', repeat: -1, yoyo: true, }) // 5. ScrollTrigger — pin + parallax exit ScrollTrigger.create({ trigger: containerRef.current, start: 'top top', end: '+=80%', pin: true, scrub: 0.5, onUpdate: (self) => { gsap.set('.hero-content', { y: self.progress * -60, opacity: Math.max(0, 1 - self.progress * 2), }) gsap.set('.hero-bg', { scale: 1 + self.progress * 0.04, }) }, }) }, { scope: containerRef } ) return (
{/* Left: Text content */}
{/* Eyebrow tag */} {brand.industry} {/* Headline with word-split spans */}

{brand.heroHeadline.split(' ').map((word, i) => ( {word} ))}

{/* Subheadline */}

{brand.tagline}

{/* CTA */}
{brand.ctaText}
{/* Scroll indicator — no text, just a line */}
{/* Right: Visual — hidden on mobile, shown on lg+ */}
{/* Gradient fade from bg color on left edge */}
{/* Mobile: decorative background strip at bottom */}
) }