Skip to content

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.

Extra small

--shadow-xs

Resting cards that need the faintest separation

Primary button, a card in a busy grid

Small

--shadow-sm

Hovered cards and sticky bars

Card hover, the switch thumb

Medium

--shadow-md

Surfaces that overlay content temporarily

Dropdown menu, select list, tooltip

Overlay

--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.

LevelValueOpacity
--shadow-xs0 1px 2px rgb(80 45 24 / 0.04)4%
--shadow-sm0 2px 8px rgb(80 45 24 / 0.06)6%
--shadow-md0 12px 32px rgb(80 45 24 / 0.10), 0 2px 6px rgb(80 45 24 / 0.05)10% + 5%
--shadow-overlay0 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.

SurfaceShadowz-index
Page contentnoneauto
Cardnone or xsauto
Sticky navbarnone — a border instead40
Dropdown, select, tooltipmd50
Dialog, command menu, draweroverlay50
Skip linknone60

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

Doreserve shadow for floating surfaces

The difference between the two is immediately legible, because only one of them lifts.

Card

Card

Don'televate 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

component.tsx
// 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>

TokensPermalink to this section