Foundations
Elevation
Shadow is spent, not applied. It is the system's way of saying “this surface is temporarily above the page”, and that statement only means something while it stays rare.
The rule
If a surface can be dismissed — a menu, a tooltip, a dialog — it gets a shadow. If it is simply part of the page, it gets a border. Almost every elevation question resolves to that one test.
The levelsPermalink to this section
Four steps. Two of them are so subtle that they read as a slight lift rather than as a shadow.
--shadow-xs
Resting cards that need the faintest separation
Primary button, a card in a busy grid
--shadow-sm
Hovered cards and sticky bars
Card hover, the switch thumb
--shadow-md
Surfaces that overlay content temporarily
Dropdown menu, select list, tooltip
--shadow-overlay
Surfaces that take over the screen
Dialog, command menu, mobile drawer
ValuesPermalink to this section
Light-mode shadows carry a restrained warm tint from the neutral palette; dark-mode shadows stay near-black so elevation remains natural on deep surfaces.
| Level | Value | Opacity |
|---|---|---|
--shadow-xs | 0 1px 2px rgb(80 45 24 / 0.04) | 4% |
--shadow-sm | 0 2px 8px rgb(80 45 24 / 0.06) | 6% |
--shadow-md | 0 12px 32px rgb(80 45 24 / 0.10), 0 2px 6px rgb(80 45 24 / 0.05) | 10% + 5% |
--shadow-overlay | 0 24px 72px rgb(80 45 24 / 0.16), 0 4px 14px rgb(80 45 24 / 0.07) | 16% + 7% |
The two larger levels use paired shadows: a wide, soft one for the ambient light and a tight one for contact. A single blur at high opacity looks like a smudge; the pair looks like an object.
LayeringPermalink to this section
Elevation and z-index move together. A surface with a bigger shadow always sits at a higher stacking level.
| Surface | Shadow | z-index |
|---|---|---|
| Page content | none | auto |
| Card | none or xs | auto |
| Sticky navbar | none — a border instead | 40 |
| Dropdown, select, tooltip | md | 50 |
| Dialog, command menu, drawer | overlay | 50 |
| Skip link | none | 60 |
The navbar has no shadow
It is sticky, but it is not floating — it is part of the frame. A bottom border and a slightly translucent background separate it from the content scrolling beneath, without implying it can be dismissed.
Spending itPermalink to this section
The failure mode is uniform elevation, where every surface lifts and none of them mean anything.
Card — border
Menu — shadow-md
Do — reserve shadow for floating surfaces
The difference between the two is immediately legible, because only one of them lifts.
Card
Card
Don't — elevate the whole page
With everything at the same height, elevation stops carrying information and becomes texture.
Elevation is not the only signalPermalink to this section
A shadow is invisible in high-contrast mode and to anyone who cannot perceive the subtle gradient. Floating surfaces are also identified structurally.
- Overlay surfaces have a border as well as a shadow, so their edge survives when the shadow does not render.
- Dialogs dim the page behind them — the scrim, not the shadow, is what communicates modality.
- Menus and dialogs are announced by their role, so their layer is conveyed semantically as well as visually.
- Nothing in the system depends on a shadow to be usable; removing every shadow leaves an interface that still works.
In codePermalink to this section
// Utilities generated from the shadow tokens
<div className="shadow-xs">…</div>
<div className="shadow-sm">…</div>
<div className="shadow-md">…</div>
<div className="shadow-overlay">…</div>
// Overlay surfaces always pair the shadow with a border,
// so the edge survives if the shadow does not render.
<div className="rounded-lg border border-line bg-surface-raised shadow-md">
…
</div>