Elevation
Elevation system — 6 levels (0-5) expressed as shadows + tonal surface colors. Material parity (`/styles/elevation`). Defines WHEN to use which level (per element family) and HOW to render it (shadow + tonal overlay per theme mode).
Spec — Elevation
Facet *isual*do Koder Design. Material parity: https://m3.material.io/styles/elevation.
The 6 elevation levels (0-5)
| Level | Shadow recipe | Tonal overlay (dark mode) | Use |
|---|---|---|---|
| ** | none | none (surface = bg) |
Page background, flat elements |
| ** | 0 1px 2px rgba(0,0,0,0.10), 0 2px 6px rgba(0,0,0,0.06) |
5% accent over surface | Default card, list item |
| ** | 0 1px 3px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.08) |
8% accent | Raised card, app bar (scrolled) |
| ** | 0 4px 8px rgba(0,0,0,0.14), 0 8px 16px rgba(0,0,0,0.10) |
11% accent | FAB (default), elevated button |
| ** | 0 6px 10px rgba(0,0,0,0.16), 0 12px 24px rgba(0,0,0,0.12) |
12% accent | FAB hover, contextual menu |
| ** | 0 8px 16px rgba(0,0,0,0.18), 0 16px 32px rgba(0,0,0,0.14) |
14% accent | Modal sheet, dialog, dropdown |
Token names: --shadow-1 through --shadow-5, --tonal-1 through --tonal-5.
R1 — Element family default elevation
| Family | Default level |
|---|---|
| Surface (page bg) | 0 |
| Container (card) | 1 |
| Container (sheet) | 3 |
| Control (button — filled) | 0 (matches surface) |
| Control (button — elevated) | 1 |
| Control (button — outlined/text) | 0 |
| Control (FAB) | 3 |
| Modal/dialog | 5 |
| Snackbar | 4 |
| Tooltip | 3 |
| Menu | 4 |
| Dropdown | 4 |
| Drawer (overlay) | 5 |
| Bottom sheet (scrim attached) | 5 |
R2 — Light vs dark elevation
Light mode: shadow-driven
Shadow visible because surfaces are bright; tonal overlay barely contributes (0-3% accent maximum).
:root {
--shadow-1: 0 1px 2px rgba(0,0,0,0.10), 0 2px 6px rgba(0,0,0,0.06);
--tonal-1: rgba(59, 91, 253, 0.00);
}
.card { box-shadow: var(--shadow-1); background: var(--surface); }Dark mode: tonal-driven
Shadows are mostly invisible on dark backgrounds; *onal overlay*of the accent color shifts the surface toward "lighter / closer" to communicate elevation. Material 3 default.
[data-theme="dark"] {
--shadow-1: 0 1px 2px rgba(0,0,0,0.40), 0 4px 12px rgba(0,0,0,0.30);
--tonal-1: rgba(126, 151, 255, 0.05);
}
.card {
box-shadow: var(--shadow-1);
background:
linear-gradient(var(--tonal-1), var(--tonal-1)),
var(--surface);
}The linear-gradient trick lets the tonal overlay compose on top of the surface color without nesting.
R3 — State-driven elevation changes
Per interaction/states.kmd:
| State | Elevation change |
|---|---|
| Hover (mouse) | +1 level (card 1 → 2) |
| Focus (keyboard) | No elevation change (focus uses ring) |
| Press (touch) | -1 level (FAB 3 → 2, "pushed in") |
| Drag | +2 levels (lifts) |
| Dropped/settled | back to default |
Animation: transition: box-shadow var(--motion-fast) var(--ease-standard);
R4 — Per-preset variation
Presets vary in "depth" feel:
| Preset | Shadow scale |
|---|---|
verge (default) |
Standard (Adwaita-based v0) |
material3 |
Standard |
material2 |
Slightly stronger shadows |
gnome |
Subtle shadows; tonal-heavy in dark |
windows_11 |
Mica blur replaces shadow at level 3+ |
windows_95 |
NO shadows — flat 3D bevel borders instead |
macos_sonoma |
Soft, longer shadows; iOS-like depth |
flat_design (planned) |
Level 0 for everything |
brutalist |
NO shadows |
neumorphism |
INVERSE shadows (inset for "pressed in" feel) |
glassmorphism |
Combines shadow + backdrop blur |
material_expressive |
Larger shadows; +1 level baseline |
terminal_classic |
NO shadows |
carbon_ibm |
NO shadows (flat by design) |
Perpreset details in `uistyle.kmd`.
R5 — Forbidden combinations
- ❌ Level 5 element inside a level 3 element (parent must be ≥ child)
- ❌ Animating elevation > 1 level on hover (jarring)
- ❌ Using box-shadow for purely decorative reasons (use level 0)
- ❌ Hardcoded shadow values in widget code (always token)
- ❌ Different shadow colors per element (use the system — single color, varying opacity)
R6 — Forced colors / high contrast
When OS reports forced-colors: active or prefers-contrast: more:
- All shadows → none (forced-colors mode strips shadows anyway)
- Tonal overlay → none
- Elevation indicated by *order*instead: 1px solid
borderforeach level above 0
R7 — Accessibility
- Shadow MUST NOT be the only indicator of elevation/state
- Always pair shadow with: border color shift, position offset, or
background tonal change
- Color-blind users should perceive elevation via tonal lightness
change, not shadow alone
Cross-link
themes/color-roles.kmd— accent color used for tonal overlaythemes/light-dark.kmd— lightdark mode switches shadowtonal balancethemes/ui-style.kmd— per-preset elevation defaultsinteraction/states.kmd— state-driven elevation changesfoundations/elements.kmd— family ↔ default elevation