Card stack
A fanned card stack navigated with carousel controls and a top-left pop between cards.
API reference
Components
<CardStackCard />
One card in the stack. Reads its position from the CardStack context and renders a compositor-only transform layer carrying the resting depth fan (y offset, scale, fan rotation, opacity) that re-animates whenever the card's depth changes. Buried cards are aria-hidden and pointer-inert. Must be rendered inside a CardStack.
children?
The card face to fan - typically a TestimonialCard or any elevated bg-card block. The mechanic supplies the movement; this is the content that moves.
className?
Merged onto the card face. Positioning (the absolute depth fan) is owned by the mechanic; use this for extra per-card styling only.
<CardStack />
The stack stage. Renders the keyboard-reachable carousel group (Arrow keys step it), resolves the fan geometry + reduced-motion mode + the shuffle/return transitions, and provides all of it to every CardStackCard through context. Drop CardStackCard children inside; the stage fans them, they supply their own faces.
state
The card-stack controller from useCardStack - the index and transition direction the cards resolve against. Share it with your own navigation controls so one state drives both.
children?
The CardStackCard children, one per card, in a stable order (buried cards stay mounted so the fan keeps its depth).
visibleBehind?
How many cards behind the front stay visible in the fan before the rest fade out. Defaults to 2.
cardGap?
Vertical push, in px, applied per step back in the fan. Defaults to 16.
cardScaleStep?
Scale shed per step back in the fan (0.05 = 5% smaller each). Defaults to 0.05.
fanRotation?
Degrees of fan rotation applied per step back. Defaults to 4.
cardMinHeight?
The front card's min-height, used to size the stage tall enough for the fan to sink into. Match the min-height you give your card face. Defaults to "19rem".
label?
aria-label for the carousel group. Defaults to "Card stack".
className?
Merged onto the stack group element.
Hooks
useCardStack
The headless card-stack controller. Owns the front-card index and the last-movement direction and nothing visual, so a consumer wires the same state into CardStack and their own prev/next controls. The index wraps, so the stack loops in both directions.
useCardStack(options: { total: number }): CardStackHandleReturns
index
The current front-card index (0-based), wrapped into [0, total).
direction
The direction of the last move: 1 forward, -1 backward. It controls the exit/return path while the fan stays fixed.
movement
Monotonically increasing movement count. Used by the visual stack to distinguish its initial resting render from a navigation transition.
total
The total number of cards - the wrap modulus.
advance
Advance the stack by dir (1 next, -1 previous), recording the direction for the exit/return path, and wrapping the index.
next
Advance to the next card (advance(1)).
prev
Return to the previous card (advance(-1)).
Featured in
See the card stack composed into full sections.

