// MOTION & SCROLL
Motion & Scroll
GSAP, Lenis, scrubbed effects and the scroll-reveal system.
Motion on the site is driven by GSAP (with ScrollTrigger and SplitText) and Lenis for smooth scrolling, registered once in lib/gsap.ts.
One ticker
The SmoothScrollprovider runs Lenis off GSAP's ticker and feeds scroll position straight into ScrollTrigger, so smooth scroll and scroll-driven animation never fight:
lenis.on('scroll', ScrollTrigger.update)
gsap.ticker.add((t) => lenis.raf(t * 1000))
gsap.ticker.lagSmoothing(0)Scrubbed, not looping
The scroll effects — the hero drifting away as you leave it, the mountain backdrop parallax — are all scrubbed to scroll position. They move only while you scroll and cost nothing when the page is still, which keeps them in line with the performance model.
Reveals and nav
- Sections fade in via an IntersectionObserver toggling a CSS class — no per-frame work
- Project cards take a pointer-driven 3D tilt that springs back on leave
- The nav bounces in once you scroll past the hero and highlights the section currently in view
- Under reduced motion, anchor clicks fall back to native scrolling and animations are disabled