Foundations

Depth

Nine semantic shadow tokens across four categories — Surface, Floating, Container, Side panel — plus three control-level micro accents (shadow-thumb, shadow-thumb-lg, shadow-well) for seated thumbs and recessed wells in the filter rail. Each composition stacks 3-6 low-opacity layers (2-6% each) so the accumulation reads as natural light, not a single drop shadow. Direction matches the surface's relationship to its surroundings: directional for cards and side panels, all-sides for containers.

01Philosophy

Five principles that separate shadows that feel crafted from shadows that feel generated. Borrowed from the working notes of designers (Josh Comeau, Jakub Krawczyk) who've thought about this carefully.

01

Low opacity, many layers

Never use a single high-opacity shadow. Stack 3-6 layers at 2-6% each. Accumulation creates depth without harshness; a single 25%-opacity drop shadow reads as a Photoshop relic.

02

Progressive blur

Blur should increase as Y-offset increases. Light diffuses as it travels — shadows get softer the further they fall from the source. 2px → 4px → 8px → 16px → 32px is the canonical ladder.

03

Negative spread on outer layers

On the largest-blur layers, use negative spread (e.g. -4px, -8px) to keep the shadow from bloating outward. That contains the falloff while preserving softness.

04

The border-shadow

A 0 0 0 1px shadow at 6% opacity acts as a soft border that respects border-radius. Use this instead of a real border — same visual weight, no fight with the radius.

05

Context dictates direction

Cards on a page cast downward (directional). Containers within a page glow on all sides (symmetric). Side panels cast toward the body they overlap (directional left or right). Match the shadow to the relationship between surface and surroundings.

02The scale

Nine tokens, grouped by what kind of surface they're for. Each row shows the same surface on light (neutral-50) and dark (neutral-950) pages so you can see how the token flips across themes.

Surface

3 tokens

shadow-flat

--shadow-flat

—0 layers

light

surface

dark

surface

Truly inline content. No ring, no shadow.

Plain page text, headings, anything that's part of the document flow with no surface of its own.

paragraphheadinglist item

shadow-hairline

--shadow-hairline

⊙ symmetric1 layer

light

surface

dark

surface

Soft 1px border-shadow at 6% — respects radius.

The default for resting cards and list items. Replaces a real border with a subtle 1px shadow at 6% opacity — same visual weight, but doesn't fight the border-radius.

Card (default)list itemtable rowinput frame

shadow-base

--shadow-base

↓ casts down3 layers

light

surface

dark

surface

Directional lift — a card that's been singled out.

Cards designed to look raised over their siblings. Stat cards on a dashboard, hero cards, the active step in a wizard.

raised Cardelevated statactive wizard step

Floating

1 token

shadow-elevated

--shadow-elevated

↓ casts down6 layers

light

surface

dark

surface

The universal lift for anything that floats above the page.

Use this for every transient + modal surface — popovers, dropdowns, hover cards, tooltips, menus, combobox results, AND dialogs, alert-dialogs, drawers, sheets. 6 progressive layers (1px ring → 2 → 4 → 12 → 24 → 40 px) at 2-4% opacity each create the natural light falloff. Size + position carry most of the elevation signal; the shadow accumulates softly.

PopoverDropdownMenuTooltipCombobox contentMenubarSelectContextMenuDialogAlertDialogDrawer

Container

2 tokens

shadow-section

--shadow-section

⊙ symmetric5 layers

light

surface

dark

surface

Symmetric all-sides glow, contained spread.

Inner page containers — sidebars detached from the chrome, grouped surfaces that hold a sub-region. 1px contact ring + symmetric layers, no Y offset.

embedded sectionkanban columnpreview panel

shadow-page

--shadow-page

⊙ symmetric5 layers

light

surface

dark

surface

Soft symmetric, atmospheric, no hard border.

Full-page wrappers floating on a neutral backdrop — the kind you see in centered-app layouts where the page itself feels like a card on top of the workspace.

page wrappercentered app shellcard-like full route

Panels

3 tokens

shadow-panel-float

--shadow-panel-float

⊙ symmetric5 layers

light

surface

dark

surface

Atmospheric all-sides — for free-floating panels.

Use for panels that aren't docked to a single edge — a floating tool tray, a bottom-mounted music player dock, an inspector card that follows your cursor. The 40px ambient layer carries the depth signal on every side.

floating tool traybottom dockfollow-cursor card

shadow-panel-left

--shadow-panel-left

← casts left5 layers

light

surface

dark

surface

Directional — for panels docked to the right edge.

Persistent side panels that live on the right of the workspace (e.g. inspector, activity feed). The shadow casts left toward the page body to anchor the panel's edge.

right-docked inspectorright activity panel

shadow-panel-right

--shadow-panel-right

→ casts right5 layers

light

surface

dark

surface

Directional — for panels docked to the left edge.

Persistent side panels on the left — navigation rails, file-tree drawers. The shadow casts right onto the main canvas so the panel reads as overlaid, not embedded.

left navigation railfile-tree drawer

03In context

Six destinations from the scale wired to real components: a resting Card (hairline), a singled-out stat (base), a Popover (elevated), a Dialog (also elevated — modals share the floating shadow), an embedded Section (section), and a right-docked panel (panel-left).

shadow-hairline · resting Card

Marcus Reed

QB · Class of 2027

2,847 yards · 24 TDs · 4 INTs over six straight wins.

shadow-base · singled-out stat

Conversion

73%

+5.4 vs last cycle

shadow-elevated · Popover

Filter by status

shadow-elevated · Dialog

Pull this offer?

The recruit will see this status change on next sync. You can re-open the offer later from the activity log.

shadow-section · embedded container

Kanban · Class of 2027

Watching12
Outreach started8
Pre-committed4
Signed2

shadow-panel-left · right-docked Sheet

Activity

Marcus Reed

  • Coach Patel logged a call · 14 min
  • Status: Pending visit
  • Film clips synced

04Hover transitions

When a Card is interactive, hairline → base on hover with a 160ms transition is the canonical move. The 1px translateY adds the optical lift; the shadow change carries the rest.

05Creating new shadows

When you need a shadow not covered above, follow this four-step process. Almost always: pick the closest existing token and adjust opacity / blur — don't reinvent the layer count.

01

Determine the elevation level

Sitting on the surface → base. Floating above (popovers, dialogs, drawers, sheets) → elevated. A container within a page → section or page. A side panel (left- or right-docked, or free-floating tool tray) → panel-left, panel-right, or panel-float.

02

Determine directionality

Cast downward → use Y offsets (down). Glow evenly → keep X and Y at 0 (all-sides). Docked to an edge → use X offset on the edge layer only.

03

Start with a template

Pick the closest existing token and adjust: more presence → bump middle-layer opacities (not the outer ones). More spread → larger blur, less negative spread. Less intense → reduce all opacities. Tighter → more negative spread.

04

Test on white and off-white

Shadows that look good on pure white may be invisible on neutral-100. Test the surface against the real backgrounds it'll live on, not just a stage.

06Dark mode

Shadows behave badly on dark surfaces — the contrast between dark and slightly darker is too low to register lift. The dark-mode tokens compensate with a brighter contact ring and a top-edge highlight, the same way real glass catches a window.

Black shadows on dark surfaces don't register — there's not enough contrast between a dark surface and a slightly darker shadow for the eye to read elevation. We don't fight that.

Dark-mode tokens lean on a brighter contact ring (one neutral step lighter than the page) plus a faint top-edge highlight— the kind of inset light you'd see on a glass surface near a window. The bottom shadows remain, but contribute less. Net result: a card reads as "made of a different material" than its background, which is what elevation actually communicates.

Dark preview

shadow-base

Lit by the top-edge highlight.

shadow-elevated

Lit by the top-edge highlight.

shadow-section

Lit by the top-edge highlight.

shadow-panel-float

Lit by the top-edge highlight.