A progress bar, counters that count up, a pinned reveal sequence, a staggered gallery — every motion below is driven by native CSS scroll-timelines. Open dev tools, search the source for <script>. You won't find one.
The stack: animation-timeline: scroll() / view() + @property for animatable counters + position: sticky for the pin. Chromium-first (Chrome/Edge/Arc); Safari and Firefox get a clean static fallback via @supports — nothing ever breaks.
No requestAnimationFrame, no IntersectionObserver — a CSS custom property with an integer syntax, animated by scroll position, rendered through a counter.
Each card's animation-range starts a touch later than the last — the stagger effect everyone reaches for a JS library to get.
Most scrollytelling ships a library. This page is proof the platform caught up — for the right brief, that's a real performance and reliability win, not just a party trick.
Back to the Labs →