A tilted deck of cards starts stacked on top of each other. As you scroll, they fan out into a tidy horizontal row — and collapse back. Dealer-style "hand-of-cards" reveal.
A stack of cards appears overlapped and tilted (like a hand of playing cards), then "fans out" into a clean row of separate cards as you scroll, then back together at the bottom. Good for showing a small set of "all our features at once" or a product family without a static row jumping into view. Lightweight version of the "Apple iPhone color picker" reveal.
Each card has CSS custom properties for its destination X position and its stack rotation (different for each card). A single shared --p progress variable interpolates between the two states: at --p:0 all cards transform to translate(-50%, ...) rotate(stack-rotation); at --p:1 each card transforms to its own translate(targetX, -50%) rotate(0deg). The transform calc() handles the lerp inline. Map the scroll progress with an easing curve like 1 - |p - 0.5| * 2 so cards stack at start, spread at middle, stack again at end.
Scroll inside. Cards fan out into a row at the middle, collapse back at the bottom.
Blank page, infinite canvas, zero ceremony.
Operator-grade metrics, calmly delivered.
Headless, fast, version-controlled.
P&L in plain English, monthly.
Relationships, not pipelines.
Build a scroll-driven "deck of cards" fan-out animation. Sticky pin (top:0 height:100vh) inside a 2200px-tall section. Inside the pin: a stage holding 5 absolutely-positioned cards (180×260, rounded 18px corners, deep shadow, white text). Each card has a different gradient background (violet/pink/cyan/amber/teal) and content: ix label + display title + short description. Give each card two CSS custom properties: --target-x (its destination X offset in pixels when spread out — for 5 cards e.g. -380, -190, 0, 190, 380) AND --base-rotate (its rotation when stacked — small angles like -8, -4, 0, 4, 8 degrees) AND --stack-y (slight Y bias for back cards). Every card uses the SAME transform formula: transform: translate(calc(-90px + var(--p) * (var(--target-x) - -90)px), calc(-50% + (1 - var(--p)) * var(--stack-y)px)) rotate(calc((1 - var(--p)) * var(--base-rotate)deg)). When --p:0 all cards collapse to the center stack (overlapped, tilted). When --p:1 each card sits at its target X (fanned out row). Scroll listener: compute scroll progress 0→1, map to a peak-at-middle easing (1 - |p - 0.5| * 2) so cards stack → spread → stack as you scroll through the section. Update a label that toggles between "stacked" and "spread" based on the eased progress.