Skip to contact form
← BlogEngineeringSeptember 27, 2026 · 5 min read

Four worlds, one scrollbar

How the homepage presents Web, iOS, macOS, and Vision Pro as physical sheets stacking on top of each other — try it below.

ur homepage has a section that doesn't scroll like the rest of the page. Instead of content sliding past, four full-screen panels — Web, iOS, macOS, Vision Pro — rise up and dock into place one after another, each one burying the last slightly into the background, the way an iOS sheet slides up over whatever was on screen before it. It's not a slideshow and it's not a carousel. It's four sheets of glass, physically stacking, and your scrollbar is the only thing moving them.

Thesectionispinnedinplaceforfivescreen-heightsofscrolling,andeverythingyouseeisjustonenumberscrollprogressmappedontofoursheetsatonce.

Try it

Web

iOS

macOS

Vision Pro

scroll to stack them

live demo — same technique as the homepage

That's a scaled-down version of exactly the same code driving the real section — same math, same easing, same four-panel idea, just a smaller pinned region. Scrolling through it doesn't play a video or trigger a sequence of separate animations; every panel's position and depth-dimming is a pure function of one scrollYProgress value, read fresh on every frame.

The trick is a pinned container

The section wrapper is five screen-heights tall, but position: sticky holds its inner content pinned to the top of the viewport for the entire time you're scrolling through that height. From the outside it looks like the page stopped scrolling and something else took over — really, the page never stopped; the tall wrapper is just giving the sticky content somewhere to stay pinned while five screens' worth of scroll distance quietly pass underneath it.

tsx

<section className="relative h-[500vh]"> <div className="sticky top-0 h-screen overflow-hidden"> {/* every panel lives here, position is derived, not stepped */} </div> </section>

One progress value, four interpretations

Each panel gets handed the exact same scrollYProgress and asks a different question of it: am I in my arrival window, my resting window, or my burial window? A panel arriving translates from 104% down to 0% — fully offscreen below to fully docked. A panel already resting just sits at 0% doing nothing, which is why the section feels calm instead of constantly busy. And a panel about to be buried by the next one scales down a touch and dims, so depth reads as a physical stack rather than a cut.

None of the four panels animate on a timer, and none of them know what the others are doing — they all just react independently to the same shared number. That's what makes scrolling backward feel correct instantly, with no special-case code for reverse: run the same math with a smaller progress value and the whole stack unwinds exactly as it built.