# Elevation

The seven shadows Propel ships, what each one lifts, and where depth comes from instead.

Propel ships 7 shadows in three groups: `raised` for things that lift within the
page, `overlay` for things that float above it, and `direction` for panels that cast sideways.

Each one is a two-layer shadow: a tight contact layer that grounds the edge, and a wide ambient layer that does the lifting.

```html
<div class="rounded-lg bg-surface-1 shadow-overlay-100">…</div>
```

Shadow is the smaller half of the depth system. Only 14 component
families cast one directly, alongside 4 shared internal surfaces;
everything else separates itself with a 1px border and a step on the surface ladder. Reach for the
ladder first, and add a shadow only when an element genuinely leaves the layout.

## Raised

On-surface lift for controls and cards that stay in the layout. The shallowest tier — a raised element is still part of the page, not floating above it.

| Utility | Layers | Used by | Used for |
| --- | --- | --- | --- |
| `shadow-raised-100` | `0px 1px 6px -1px rgb(41 47 61 / 0.03)`, `0px 1px 4px 0px rgb(41 47 61 / 0.04)` | button-group, internal/control-chrome, number-field, slider, switch, toggle | The subtlest lift. Controls that sit in flow and need an edge without looking detached. |
| `shadow-raised-200` | `0px 1px 2px -1px rgb(41 47 61 / 0.06)`, `0px 1px 3px 0px rgb(41 47 61 / 0.05)` | tabs | A tighter, slightly darker lift for a surface that overlaps its neighbours. |
| `shadow-raised-300` | `0px 2px 4px -1px rgb(41 47 61 / 0.04)`, `0px 4px 6px -1px rgb(41 47 61 / 0.05)` | alert-dialog, dialog | The deepest in-flow lift — hover-lifted cards and trigger surfaces. |

## Overlay

Floating layers that sit above the page and take focus with them. Pair with a real surface color — a shadow alone doesn't separate an overlay from what's behind it.

| Utility | Layers | Used by | Used for |
| --- | --- | --- | --- |
| `shadow-overlay-100` | `0px 10px 10px -5px rgb(41 47 61 / 0.04)`, `0px 10px 40px -5px rgb(41 47 61 / 0.04)` | internal/listbox-popup, internal/popup-surface, internal/surface, preview-card, suggestion-menu | Dropdowns, selects, popovers, drawers — anything anchored to a trigger. |
| `shadow-overlay-200` | `0px 10px 10px -10px rgb(41 47 61 / 0.04)`, `0px 30px 60px -12px rgb(41 47 61 / 0.1)` | internal/surface, popover, preview-card, tooltip | The deepest shadow in the system, for the modal layer. Its 60px second blur is what separates a dialog from the whole page beneath it. |

## Directional

Side-anchored panels casting onto the content they cover. Horizontal offset only, no vertical component — these read as a panel edge, not as height.

| Utility | Layers | Used by | Used for |
| --- | --- | --- | --- |
| `shadow-direction-left` | `-10px 0px 30px -5px rgb(41 47 61 / 0.02)`, `-5px 0px 80px -5px rgb(41 47 61 / 0.04)` | drawer, table | A panel or sticky column casting toward the inline-start edge. |
| `shadow-direction-right` | `10px 0px 30px -5px rgb(0 0 0 / 0.04)`, `5px 0px 80px -5px rgb(0 0 0 / 0.04)` | drawer, table | The mirror, casting toward the inline-end edge. |

## What the reset removes

`--shadow-*: initial` clears Tailwind's scale before Propel declares its own, so every utility below
generates no CSS and fails silently. The bare `shadow` goes with them, since it read `--shadow`.
There is no replacement: a shadow should come from the three groups above, chosen by what the
element is rather than by how heavy it should look.

| Removed | Tailwind's value |
| --- | --- |
| `shadow-2xs` | `0 1px rgb(0 0 0 / 0.05)` |
| `shadow-xs` | `0 1px 2px 0 rgb(0 0 0 / 0.05)` |
| `shadow-sm` | `0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)` |
| `shadow-md` | `0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)` |
| `shadow-lg` | `0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)` |
| `shadow-xl` | `0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)` |
| `shadow-2xl` | `0 25px 50px -12px rgb(0 0 0 / 0.25)` |
| `shadow-inner` | `inset 0 2px 4px 0 rgb(0 0 0 / 0.05)` |

Three things survive. `shadow-none` is a static utility rather than a token, so it still cancels an
inherited shadow. `inset-shadow-*` and `drop-shadow-*` are separate namespaces Propel never touches,
so Tailwind's defaults apply unchanged — they carry a generic pure-black tint rather than Propel's
slate ink, and will look subtly foreign beside the tokens above.

## Guidelines

A shadow alone does not separate a floating layer from the page; it darkens the edge of something
that still shows whatever is behind it. Pair every overlay with a real background, as
`bg-surface-1 shadow-overlay-100`, and never ship the shadow on its own.

Shadows don't compose. Two elevated surfaces nested inside each other produce overlapping ambient
layers that read as a smudge rather than as two levels, so let the outer layer carry the shadow and
give the inner one a border.

Elevation says an element sits on a layer above, not that it is interactive. Hover and pressed
states belong to the surface and border tokens, and a control that lifts on hover is claiming to
float, which almost nothing in Propel does.

Stacking order is a separate concern again. Propel declares no `z-index` tokens, and a deeper shadow
does not put an element in front of anything.

## Theme behavior

All seven shadows are declared once, outside every theme selector, so the same ink renders in light, dark, light-contrast, and dark-contrast.

They are tuned for a light canvas, using slate ink `rgb(41 47 61)` at 2–10% alpha, which is close to
invisible against a dark background. That is not a bug to route around with a heavier shadow. In
dark themes depth comes from the surface ladder and borders, and the shadow quietly stops
contributing.

One shadow breaks the pattern: `shadow-direction-right` is tinted pure black rather than slate ink,
the only one in the system that is. It reads as an inconsistency rather than a decision.
