Every section on this site has one signature move. The hero reveals its name by masked characters. The manifesto brightens word by word as you scroll. The work cards pin and stack. None of those effects were chosen because GSAP can do them; each had to answer one question first: what does this animation tell the reader?
Three rules
- Only transform, opacity and clip-path animate. Width, height, margin and colour changes are left to CSS transitions or avoided. The compositor handles the first three without a repaint, which is the difference between 60 frames per second and a stutter on a mid-range phone.
- One primitive layer.
SplitReveal,ScrambleText,Magnetic,ClipReveal,Counter,Marquee,DrawSVGandTiltCardare built once incomponents/motionand reused. A section never writes its own tween for something a primitive already does. - Reduced motion is a design, not a switch-off. Under
prefers-reduced-motion, or the manual toggle in the footer, every scrubbed, pinned or parallax effect becomes a plain fade, the marquees stop, the cursor disappears and Lenis is never created. The page is still laid out as if it moved.
Why GSAP and not CSS
CSS handles hover, press and the small state changes. GSAP handles anything tied to scroll position or to the pointer, because those need to be interruptible: a user who scrolls back halfway through a reveal should see it reverse, not restart. ScrollTrigger with scrub gives that for free, and quickTo gives the same for pointer-driven values without a React render per frame.
The one bug worth writing down
Pinned sections inside a flex column lose their spacing: ScrollTrigger turns pinSpacing off when the pinned element's parent is display: flex. The hero pin worked by accident because it set the option explicitly, and the services pan silently overlapped the section below it until the same line was added. If a pinned section seems to swallow the one after it, check the parent's display first.
Measuring it
Every route is screenshotted at section anchors with Playwright, in both themes and at phone width, and the home page is held to a Lighthouse performance score of 95 on mobile. A motion system that cannot survive that budget is not finished.