Foundations
Color
Generated ramps supply the raw colours. Components draw with semantic roles, each with a light and a dark value, and every contracted pair of roles is checked against WCAG 2.2 in both modes.
Reference palettes
An OKLCH generator builds each ramp and maps it into sRGB in a documented, deterministic way. Generated ramps do not guarantee contrast, so the role pairs that components actually draw are checked instead.
- 50
#f3f4ff - 100
#e7e9ff - 200
#d0d4ff - 300
#b2b6ff - 400
#9393ff - 500
#776cff - 600
#624fe7 - 700
#4d3bc0 - 800
#3a2b95 - 900
#281c6c - 950
#160e46
- 0
#ffffff - 50
#f5f5f6 - 100
#ebebed - 200
#d7d7db - 300
#bcbdc4 - 400
#a0a1a9 - 500
#84858f - 600
#6d6e77 - 700
#565760 - 800
#414248 - 900
#2d2d32 - 950
#1a1a1e - 1000
#000000
- 50
#ecf7ff - 100
#daeffe - 200
#b7ddf9 - 300
#86c6f3 - 400
#53abe4 - 500
#0a8fd1 - 600
#0076af - 700
#005e8c - 800
#00476c - 900
#00314c - 950
#001d2f
- 50
#edf9ef - 100
#dcf2e0 - 200
#bce3c3 - 300
#90d09d - 400
#61b876 - 500
#2e9e52 - 600
#00853c - 700
#006b2e - 800
#005121 - 900
#003915 - 950
#00220a
- 50
#fcf4e8 - 100
#f9e9d3 - 200
#efd3ac - 300
#e3b575 - 400
#d09538 - 500
#b37900 - 600
#956300 - 700
#774f00 - 800
#5b3b00 - 900
#402800 - 950
#271700
- 50
#fff2f0 - 100
#ffe4e0 - 200
#ffc8c1 - 300
#ffa196 - 400
#f97165 - 500
#e6443d - 600
#c92324 - 700
#a50e15 - 800
#80070d - 900
#5c0206 - 950
#3a0002
Semantic roles
Components read roles, not ramp steps. Each swatch below is drawn by its own token inside a data-odd-mode scope, so it shows the value that mode resolves.
| Role | Light | Dark | Use |
|---|---|---|---|
color.canvas | #f6f5f1 | #171821 | Page background |
color.surface.default | #ffffff | #242631 | Cards, panels, controls |
color.surface.raised | #ffffff | #2d2f3b | Raised surfaces (with an elevation. |
color.surface.sunken | #f0eff3 | #111219 | Wells, code, inset areas |
color.surface.hover | #f0eff5 | #30323f | Hover and transient highlights |
color.surface.specimen | #efedfc | #29263d | Documentation specimen stages only (24 px inset); never a selected state |
color.text.primary | #23252b | #f5f3fd | Body and headings |
color.text.secondary | #5f626f | #bdbbcd | Supporting text |
color.text.disabled | #767985 | #858393 | Disabled text (exempt from contrast minimums) |
color.link | #6250e8 | #b4a8ff | Links; 2 px focus ring at 2 px offset |
color.focus.ring | #6250e8 | #b4a8ff | Links; 2 px focus ring at 2 px offset |
color.border.default | #d9d8e1 | #555368 | Dividers / control borders (3:1) |
color.border.strong | #868997 | #858395 | Dividers / control borders (3:1) |
color.selection.background | #6250e8 | #b4a8ff | Selected controls, with a state marker |
color.selection.foreground | #ffffff | #23252b | Selected controls, with a state marker |
color.selection.surface | #e7e9ff | #281c6c | Selected rows (listbox options, menu items) under text.primary, with a check mark; hover stays surface.hover |
color.scrim | rgb(0 0 0 / 0.4) | rgb(0 0 0 / 0.6) | Modal backdrops (::backdrop of dialogs and drawers) |
color.accent.decorative | #dfedaa | #dfedaa | Citron decoration; never status, text, or interaction |
Interactive states
A primary action has a role per state, and text on it uses color.text.on-action.
| Role | Light | Dark | Use |
|---|---|---|---|
color.action.default | #6250e8 | #b4a8ff | Primary actions |
color.action.hover | #5140cc | #c5bcff | Primary actions |
color.action.pressed | #4333ad | #9b8cf0 | Primary actions |
color.text.on-action | #ffffff | #23252b | Text on actions and selections |
Status tones
Each tone has a foreground, a surface, and a decorative edge, which has no contrast minimum. Below, odd-alert in each tone.
| Role | Light | Dark | Use |
|---|---|---|---|
color.neutral.foreground | #5f626f | #bdbbcd | The neutral tone (aliases) |
color.neutral.surface | #f0eff3 | #111219 | The neutral tone (aliases) |
color.neutral.border | #d9d8e1 | #555368 | The neutral tone (aliases) |
color.info.foreground | #0076af | #53abe4 | Information. |
color.info.surface | #ecf7ff | #001d2f | Information. |
color.info.border | #b7ddf9 | #00476c | Decorative tone edges (alerts, badges); not control boundaries, so no contrast minimum |
color.success.foreground | #267653 | #8fd6b3 | Success |
color.success.surface | #eaf6ef | #1c352b | Success |
color.success.border | #bce3c3 | #005121 | Decorative tone edges (alerts, badges); not control boundaries, so no contrast minimum |
color.warning.foreground | #8a5900 | #e9c478 | Warnings (status.warning seeds the ref.warning. |
color.warning.surface | #fff5de | #3a2e18 | Warnings (status.warning seeds the ref.warning. |
color.warning.border | #efd3ac | #5b3b00 | Decorative tone edges (alerts, badges); not control boundaries, so no contrast minimum |
color.danger.foreground | #b4233a | #ff9bab | Errors; also danger borders |
color.danger.surface | #fff0f2 | #3d202a | Errors; also danger borders |
color.danger.border | #ffc8c1 | #80070d | Decorative tone edges (alerts, badges); not control boundaries, so no contrast minimum |
color.neutral.surfacecolor.info.surfacecolor.success.surfacecolor.warning.surfacecolor.danger.surface
Contrast pairs
The contrast report states which foreground role must reach which minimum against which backgrounds (semantic colour contracts, section 10.4).
124 pairs pass, 0 fail, and 6 are exempt. Method: WCAG 2.2 contrast ratio of the resolved sRGB colours, rounded down to two decimals, for each declared role pair (theming-and-styling.md §10.4).
| Foreground | Background | Light | Dark | Minimum |
|---|---|---|---|---|
color.text.primary | color.canvas | 14.04:1 | 16.08:1 | 4.5:1 (1.4.3) |
color.text.secondary | color.canvas | 5.55:1 | 9.38:1 | 4.5:1 (1.4.3) |
color.text.on-action | color.action.default | 5.48:1 | 7.28:1 | 4.5:1 (1.4.3) |
color.selection.foreground | color.selection.background | 5.48:1 | 7.28:1 | 4.5:1 (1.4.3) |
color.link | color.canvas | 5.02:1 | 8.39:1 | 4.5:1 (1.4.3) |
color.border.strong | color.canvas | 3.18:1 | 4.77:1 | 3:1 (1.4.11) |
color.focus.ring | color.canvas | 5.02:1 | 8.39:1 | 3:1 (1.4.11) |
color.danger.foreground | color.canvas | 5.93:1 | 8.85:1 | 4.5:1 (1.4.3) |
color.neutral.foreground | color.canvas | 5.55:1 | 9.38:1 | 4.5:1 (1.4.3) |
color.info.foreground | color.canvas | 4.57:1 | 6.99:1 | 4.5:1 (1.4.3) |
color.success.foreground | color.canvas | 5.06:1 | 10.46:1 | 4.5:1 (1.4.3) |
color.warning.foreground | color.canvas | 5.48:1 | 10.62:1 | 4.5:1 (1.4.3) |
color.text.disabled | color.surface.sunken | 3.78:1 | 5.03:1 | Exempt (1.4.3 (exception for inactive components)) |