Surfaces
Eight-level surface and shadow ladder for elevation.
Light mode: two color steps then flat white, differentiated by shadow.
: additive white-opacity ladder with layered inset highlights and drops.
Installation
app/globals.css. Once added, every bg-surface-N and shadow-surface-N utility (where N is 1–8) becomes available. The existing --background, --muted, and --card tokens are re-derived as aliases of --surface-1, --surface-2, and --surface-3.Playground
The ladder
Usage
Each surface level pairs a background color with a shadow recipe of matching elevation. Apply them together: className="bg-surface-3 shadow-surface-3".
In light mode, surfaces 3–8 share the same #FFFFFF background; the shadow alone communicates elevation. , each level adds a small amount of white opacity over #171717, and the shadow recipe layers an inset top-edge highlight, an inset border ring, an outer hairline, and stacked drop shadows.
Shadows compose additively — surface N + 1's recipe is surface N's recipe with one additional drop layer at the next halving offset. This makes the elevation walk smoothly across the full ladder.
Relative elevation
Elevated components don't pick a fixed surface level — they elevate relative to whatever they sit on. A Dropdown opened on the page background renders at one level; the same Dropdown opened inside a Dialog renders higher. Without this, nesting collapses (a popover inside a popover renders the same color as its parent and disappears).
The mechanism: SurfaceProvider declares the current substrate level via React context. useSurface() reads it (default 1, the page background). Each elevated component computes its level as substrate + offset and re-provides the new substrate to its children, so further nesting walks up the ladder.