Tokens
Every value in the system, as CSS variables. Roles follow the source colour and the theme; variants only add material.
Colour
39 roles, light and dark. Consume the role, never a hard-coded value.
| Role | Light | Dark | Usage | |
|---|---|---|---|---|
--surface |
#fef7ff |
#141218 |
Page background. On the portfolio it carries the dot grid. |
|
--scl |
#f7f2fa |
#1d1b20 |
Surface container low: calm areas, navigation rail at rest, Do / Avoid block backgrounds. | |
--sc |
#f3edf7 |
#211f26 |
Surface container: default card background (.card, MetricCard). No shadow: tint is enough. |
|
--sch |
#ece6f0 |
#2b2930 |
Surface container high: dialogs, row separators (.row border-top), rail border. |
|
--schh |
#e6e0e9 |
#36343b |
Surface container highest: pill search bar, off switch track. | |
--scc |
#ffffff |
#0f0d13 |
Surface container lowest: code chips and logs background. | |
--primary |
#6750a4 |
#d0bcff |
Primary action: filled button, switch on, links, focus ring. One dominant primary element per screen. | |
--on-primary |
#ffffff |
#381e72 |
Text and icons on primary. |
|
--pc |
#eaddff |
#4f378b |
Primary container: section badges (cookie), logo, streak card, FAB. | |
--on-pc |
#21005d |
#eaddff |
Text on pc. |
|
--secc |
#e8def8 |
#4a4458 |
Secondary container: tonal button, active navigation indicator, full chips, inactive slider track. | |
--on-secc |
#1d192b |
#e8def8 |
Text on secc. |
|
--tertiary |
#7d5260 |
#efb8c8 |
Rare tertiary accent: secondary emphasis, chart series outside status. | |
--on-tertiary |
#ffffff |
#492532 |
Text on tertiary. Active dot and Chrome variant switch. |
|
--tc |
#ffd8e4 |
#633b48 |
Tertiary container: decorative accent shapes (MetricCard), favourite tiles. | |
--on-tc |
#31111d |
#ffd8e4 |
Text on tc. |
|
--error |
#b3261e |
#f2b8b5 |
Error and destructive action (.btn-danger). |
|
--on-error |
#ffffff |
#601410 |
Text on error. |
|
--ec |
#f9dedc |
#8c1d18 |
Error container: error snackbar, Stabilité SOS banner. | |
--on-ec |
#410e0b |
#f9dedc |
Text on ec. |
|
--on-surface |
#1d1b20 |
#e6e0e9 |
Main text on surface, scl, sc, sch, schh. |
|
--on-sv |
#49454f |
#cac4d0 |
Secondary text, labels, icons at rest, on every container surface. | |
--outline |
#79747e |
#938f99 |
Control borders: outlined button, text field, off switch. 3:1 on surfaces. | |
--outline-v |
#cac4d0 |
#49454f |
Outline variant: decorative borders, outline chips, section heading rule, progress rail. Never alone to signal a state. | |
--dot |
rgba(73, 69, 79, 0.18) |
rgba(202, 196, 208, 0.16) |
30px dot grid on the page background (portfolio). Decor only. | |
--ok |
#2e7d32 |
#8fd694 |
OK status (running service, running container). Always paired with a word or icon. | |
--on-ok |
#ffffff |
#0b3a12 |
Text on ok. |
|
--warn |
#8a5a00 |
#f6c177 |
Warning status (disk almost full, update available). | |
--on-warn |
#ffffff |
#3a2600 |
Text on warn. |
|
--bad |
#b3261e |
#f2b8b5 |
Down or stopped status. Same value as error, distinct semantic role. |
|
--on-bad |
#ffffff |
#601410 |
Text on bad. |
|
--series-1 |
#6750a4 |
#9478e8 |
Chart series 1 (CPU). Colour-blind validated on surface. |
|
--series-2 |
#008a73 |
#1e9e81 |
Chart series 2 (RAM). | |
--hero-on |
#e6e0e9 |
#e6e0e9 |
Text on the dark hero photo (portfolio), identical in both themes. | |
--hero-primary |
#d0bcff |
#d0bcff |
Main hero button on a dark photo. | |
--hero-on-primary |
#381e72 |
#381e72 |
Text on hero-primary. |
|
--gloss-hi |
rgba(255, 255, 255, 0.75) |
rgba(255, 255, 255, 0.10) |
Plaza / Chrome variant: top highlight of a bubble, laid as a gradient over a surface role (scl, sc). Tint-free, so Material You compatible. |
|
--gloss-edge |
rgba(255, 255, 255, 0.95) |
rgba(255, 255, 255, 0.16) |
Variant: 1px inner light rim at the top of bubbles and chrome. | |
--shade |
rgba(0, 0, 0, 0.14) |
rgba(0, 0, 0, 0.45) |
Variant: inner shadow of fields and recessed tracks, soft shadow under bubbles. |
Typography
Four families, fifteen styles. Headings at weight 500, labels at 600.
M3 · Display
displayName on the cover (GitHub README card). One per page.
metricMetricCard value. 34px in compact. Tabular figures.
section-titlePortfolio section heading, clamp(28px, 4vw, 36px), preceded by the numbered cookie badge.
brandApp name in spaced capitals in the top bar.
page-titlePage title (h1) of an app.
M3 · Text
dialog-titleDialog title.
card-titleCard title (.card-head h2).
bodyBody text.
labelButton label, weight 600.
smallSubtext, metadata, captions.
chipChip text and navigation label (500).
M3 · Code
codeCommands and technical values, in an scc chip.
Variant · Plaza (Wii U / 3DS)
plaza-titleVariant. Bold rounded headings, in the spirit of the Wii U menu.
plaza-bodyVariant. Plaza body text.
Variant · Chrome (Y2K)
y2k-displayVariant. Stretched display, in capitals, headings and buttons only. Body text stays in sans.
Spacing
Nine steps, from 4px to 48px.
| Name | Value | Usage |
|---|---|---|
--space-1 | 4px | Navigation icon and label gap, progress track gap. |
--space-1-5 | 6px | Gap between rail items, vertical chip padding. |
--space-2 | 8px | Gap inside buttons and between dialog footer buttons. |
--space-3 | 12px | Card header gap, top bar gap, vertical row padding. |
--space-4 | 16px | Gap between cards on a page, minimum mobile gutter. |
--space-5 | 20px | Vertical card padding, dialog padding, gap under the top bar. |
--space-6 | 24px | Horizontal dialog padding, portfolio button padding. |
--space-8 | 32px | Horizontal padding of the main column (desktop). |
--space-12 | 48px | Breathing room at the bottom of a page. |
Radius
Nine radii. An inner radius is always smaller than its parent.
| Name | Value | Usage |
|---|---|---|
--radius-xs | 3px | Checkbox. |
--radius-sm | 6px | Tooltip, code chip. |
--radius-chip | 8px | Chips (rounded rectangle, never a pill). |
--radius-md | 12px | Outlined text field, snackbar. |
--radius-lg | 16px | 56×32 navigation indicator, image tiles. |
--radius-btn | 20px | 40px button (half the height: pill). |
--radius-xl | 24px | 48px button, compact MetricCard, Stabilité cards. |
--radius-card | 28px | Cards, dialogs, 56px search bar. |
--radius-hero | 36px | Large cover card (GitHub README). |
Shadow
Elevation comes from tint. Shadows are reserved for floating elements and variants.
| Name | Value | Usage |
|---|---|---|
--shadow-float | 0 6px 20px rgba(0, 0, 0, 0.35) | Snackbar and floating elements only. |
--shadow-plaza | inset 0 1px 0 rgba(255, 255, 255, 0.95), 0 1px 0 rgba(0, 0, 0, 0.08), 0 6px 14px rgba(0, 0, 0, 0.12) / inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 1px 0 rgba(0, 0, 0, 0.4), 0 6px 14px rgba(0, 0, 0, 0.4) | Plaza variant: volume of a bubble. Neutral; the tint comes from the surface role underneath. |
--shadow-chrome | inset 0 1px 0 rgba(255, 255, 255, 0.7), inset 0 -1px 0 rgba(0, 0, 0, 0.25), 0 2px 6px rgba(0, 0, 0, 0.3) | Chrome variant: metal bevel. Neutral. |
Opacity
The state layer uses currentColor.
| Name | Value | Usage |
|---|---|---|
--state-hover | 0.08 | State layer on hover, colour = currentColor. |
--state-press | 0.12 | State layer on press. |
--state-ripple | 0.16 | Ripple on click. |
--state-disabled | 0.5 | Disabled control. |