Foundations / Elevation
Elevation you feel, not a shadow you notice.
Every floating surface picks one of three heights, each a soft two-layer shadow tinted with the brand indigo instead of hard black. Three levels build every overlay a product needs, and a shadow says one thing only: this surface sits above another. Add a focus ring at --shadow-focus and that is the entire system.
The elevation ladder
Flat on the page, raised, overlay, floating. The taller a surface reads, the higher it sits, and lg is the ceiling every surface stays within.
Three levels, plus a ring
Each height is one token, shown on a real surface. The focus ring is the fourth token and the only one that is not elevation.
--shadow-smButtons and resting cards. A whisper of lift that separates an element from the page.
--shadow-mdDropdowns, popovers, and menus. Content that opens over the current view and closes again.
--shadow-lgModals, sheets, command palettes. The highest surface. If something must feel higher, add a scrim, not more blur.
--shadow-focusA two-tone ring, a white gap inside an indigo edge, paired with :focus-visible to show keyboard position on any surface. Accessibility, never decoration.
Two layers, tinted indigo
Real shadows are two things at once: a crisp contact shadow close to the object, and a soft ambient shadow far from it. Stacking one near layer and one far layer reproduces that falloff, so the surface reads as lifted, not pasted on. Tinting both with indigo lets the shadow belong to the surface instead of staining it.
Short offset, tight blur. The crisp contact shadow that grounds the object.
Long offset, wide blur, negative spread. The soft ambient shadow that gives height.
The two combined and tinted. This is --shadow-md.
Shadow is height
A shadow says one thing: this surface sits physically above another. Match that meaning and elevation stays a clean, single-purpose channel.
RulePick one of the three elevation levels for a surface and keep it fixed for the surface's whole life.
WhyA constant elevation reads as real, physical height, so the surface feels solid and hover, press, and selection stay legible in their own channel: color.
Fix each surface at one level, then carry hover, press, and selection in color and state layers. Color answers "what is happening to this control", shadow answers "how high does this surface sit", and both channels stay quiet.
Swelling a dramatic shadow on hover, usually paired with a translateY lift. It fakes physics the surface does not have and collides with the rule against transform-based hover.
State feedback lives in color. Hover, press, and selection ride on color and state layers rather than elevation. See Patterns / Interactive for the state-layer model.
In the dark, tint carries height
Shadow is not the only way to say "higher". As a surface rises it can take a stronger indigo tint, and in dark themes a drop shadow nearly vanishes against a dark background. A lighter, more tinted surface is the clearer signal there. Prefer tint in the dark, shadow in the light, and the two can combine.
Dark surface rising through indigo-tinted levels with no shadow at all. Height reads from lightness, not from ink.
Token reference
Four tokens, the whole system. The scale stays closed at these four: lg is the top, and hover reuses the resting shadow, so every surface maps to one of the four.
| Token | Role | Value |
|---|---|---|
--shadow-sm | Raised, buttons and resting cards | 0 1px 2px rgba(79, 70, 229, .06), 0 1px 3px rgba(15, 23, 42, .04) |
--shadow-md | Overlay, dropdowns and popovers | 0 2px 4px -1px rgba(79, 70, 229, .06), 0 8px 16px -4px rgba(79, 70, 229, .10) |
--shadow-lg | Floating ceiling, modals and sheets | 0 4px 8px -2px rgba(79, 70, 229, .06), 0 16px 32px -8px rgba(79, 70, 229, .12) |
--shadow-focus | Focus ring, pairs with :focus-visible | 0 0 0 2px #ffffff, 0 0 0 4px #4f46e5 |
Sources
Material 3, elevation and tonal elevation: level count and the surface-tint approach where a tint of the primary color expresses height, with dark surfaces lightening as they rise (m3.material.io/styles/elevation). Tobias Ahlin, layered smooth shadows: stacking soft box-shadow layers instead of one hard shadow for a natural falloff (tobiasahlin.com/blog/layered-smooth-box-shadows). Apple Human Interface Guidelines, Materials: soft, minimal shadows for depth over heavy drops (developer.apple.com/design/human-interface-guidelines/materials). Exact rgba layer values are specific to this system's tokens, and reading lg as an absolute ceiling is a house rule, not a rule from the cited sources.SPA