One question, nothing else. Not how high something floats or how far the shadow throws — only whether this thing is in front of that one, and whether you can tell without being told. Odin has two shadow scales and one ladder of numbers, and they exist so nobody has to invent a third.
Depth lives in two namespaces, and they are not two ends of one ruler. page is in-page lift: a card, a canvas, something that is part of the document. overlay is the browser’s top layer: things that are not part of the document at all and are painted above the whole of it.
A third page step is reserved — page-lg — and deliberately has no value yet. It appears when design decides what a higher in-page lift is for, rather than when someone needs one and picks a number.
Is page-md above or below overlay-sm? The question has no answer, and it never needs one: they cannot compete. The top layer wins structurally, whatever either shadow looks like. A dropdown is above a floating card because it is on a different layer of the browser, not because its shadow is darker.
Cross-namespace ordering is undefined, and treating it as undefined is what keeps the two scales independent. The moment someone reasons about it, the two ladders become one and every value has to be re-argued against every other.
Page shadows carry the content tint, rgba(48, 45, 37, …) — a warm near-black that belongs to the same family as the ink. They fall on cream, and a neutral grey shadow on a warm ground reads as dirt.
Overlay shadows are pure black. They fall on a dimmed backdrop, where the warmth would be invisible and the extra depth is doing the work instead. It is the same reason the reversed logo cut is not the positive one on a dark ground: the surround changes what the mark has to do.
Every layer that leaves the flow has a name and a number. Nothing in the product writes a raw z-index; if a thing needs to be above another thing, it needs a token, and adding one is a decision somebody makes on purpose.
| Token | Value | Note |
|---|---|---|
| --z-below | -1 | Behind the flow |
| --z-base | 0 | |
| --z-above | 1 | In front of a sibling |
| --z-dropdown | 1,000 | The first layer that leaves the flow |
| --z-combobox-* | 1,010 | Four tokens, all 1010 — parts of one control |
| --z-drawer-backdrop | 1,140 | |
| --z-drawer | 1,150 | |
| --z-dialog-backdrop | 1,240 | |
| --z-dialog | 1,250 | |
| --z-toast | 1,300 | Above the dialog: it can report on what the dialog just did |
| --z-toolbar | 2,000 | |
| --z-mainnav-mobile-backdrop | 5,000 | |
| --z-aside | 5,100 | |
| --z-mainnav-mobile | 5,200 | |
| --z-closemobilenav | 5,300 | |
| --z-debug | 10,000 | Over everything, because it is for looking at everything |
| --z-toolpanel | 1,000,000,000 | A billion. See below. |
Two of these are worth reading twice. toast sits at 1300, above dialog at 1250, because a toast frequently reports on what the dialog just did and would be useless underneath it.
And toolpanel is a billion. Not a scale position — a surrender, written by someone who needed a panel on top and had no number to reach for.
These carry the elevation- prefix for historical reasons and are component-specific effects rather than steps on either scale. Nothing picks one to raise a surface; each belongs to exactly one component.
| Token | Value | Where |
|---|---|---|
| elevation-button-primary | 0px 4px 8px 0px rgba(0, 120, 255, 0.3) | The primary button’s glow. |
| elevation-toolbar | 0px 0px 10px 0px rgba(0, 0, 0, 0.05), 0px 4px 4px 0px rgba(0, 0, 0, 0.05) | The floating toolbar. Two shadows: a soft halo and a directional drop. |
| elevation-tabs-marker | 0px 2px 6px 0px rgba(0, 0, 0, 0.15) | The marker under the active tab. |
The first of them is wrong, and visibly so. elevation-button-primary glows rgba(0, 120, 255, 0.3) — blue, from before the primary was sienna. focus-state has the same blue in it. Both are the colour of a brand this system no longer has, sitting on the two most-used interactive elements in the product.
These were the old names. They resolve to nothing, which means a component using one loses its shadow without any error — the worst kind of failure, because it looks like a design decision.
A lint rule rejects all eight. That is the right shape of fix: a name that fails quietly needs something that fails loudly on its behalf.
Two things, and neither is a shadow value.
The blue. The primary button’s glow and the focus ring are both a colour the brand no longer uses. They are the most-seen interactive states in the product, and they are the last place the old palette is still visible.
The billion. toolpanel should have a number that sits in the ladder rather than one that opts out of it.
The page scale gets a third step when there is a reason for one, not before.