docs(ui-theme): spec, design tokens, shared contract

This commit is contained in:
Joseph Doherty
2026-06-01 05:11:43 -04:00
parent 46ce627ea5
commit 95975d0754
4 changed files with 626 additions and 0 deletions
+123
View File
@@ -0,0 +1,123 @@
# UI Theme — Design Tokens
Canonical reference for every CSS custom property declared in `theme.css`. This is the
human-readable index of the Technical-Light design system. The authoritative source is
`ZB.MOM.WW.Theme/src/ZB.MOM.WW.Theme/wwwroot/css/theme.css` (verified 2026-06-01,
379 lines). Analogous to [`../auth/spec/CANONICAL-ROLES.md`](../../auth/spec/CANONICAL-ROLES.md)
for the auth component.
The token block lives in `:root` (lines 3977). Components reference these tokens —
**no hardcoded hex values** appear in component markup or CSS. The only per-app override
is `--accent` on the `ThemeShell` root element via the `Accent` parameter.
---
## Surface tokens
| Token | Value | Role |
|---|---|---|
| `--paper` | `#f4f4f1` | Page background — warm off-white, never pure white |
| `--card` | `#ffffff` | Raised surfaces: cards, panel headers, table heads |
---
## Ink (text) tokens
| Token | Value | Role |
|---|---|---|
| `--ink` | `#1b1d21` | Primary text |
| `--ink-soft` | `#5a6066` | Secondary text, form labels |
| `--ink-faint` | `#8b9097` | Tertiary text, captions, units, nav eyebrow labels |
---
## Structure tokens
| Token | Value | Role |
|---|---|---|
| `--rule` | `#e4e4df` | Hairline borders, row dividers |
| `--rule-strong` | `#d2d2cb` | Emphasised hairlines: bar underlines, pill borders |
---
## Accent tokens
| Token | Value | Role |
|---|---|---|
| `--accent` | `#2f5fd0` | Links, sort arrows, primary actions, active nav indicator |
| `--accent-deep` | `#1e3f99` | Hover / pressed accent; raw-value emphasis |
> `--accent` is the **only token overridden per-app**. Pass it as `ThemeShell`'s
> `Accent` parameter: `<ThemeShell Accent="#2f855a">` → emits
> `style="--accent: #2f855a"` on the shell root, scoping the override to that subtree.
---
## Status tokens — foreground
| Token | Value | Role |
|---|---|---|
| `--ok` | `#2f9e44` | Success / healthy / connected state text + icon color |
| `--warn` | `#e8920c` | Warning / degraded state text + icon color |
| `--bad` | `#e03131` | Error / faulted / disconnected state text + icon color |
| `--idle` | `#868e96` | Unknown / offline / neutral state text + icon color |
---
## Status tokens — tinted backgrounds
Pair each with the matching foreground token above (e.g. `--ok-bg` background with `--ok`
foreground text). Used by `.chip-ok`, `.chip-warn`, `.chip-bad`, `.chip-idle` classes.
| Token | Value | Role |
|---|---|---|
| `--ok-bg` | `#e9f6ec` | Success tinted background |
| `--warn-bg` | `#fdf1dd` | Warning tinted background |
| `--bad-bg` | `#fceaea` | Error tinted background |
| `--idle-bg` | `#eef0f2` | Idle/neutral tinted background |
> The `Info` status variant (`StatusState.Info`, `chip-info`) is defined in `layout.css`
> (not `theme.css`) and uses `--accent-deep` foreground on `#e7ecfb` background.
---
## Typography tokens
| Token | Value | Role |
|---|---|---|
| `--mono` | `'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace` | Monospaced stack — numeric / code values; tabular figures via `font-variant-numeric: tabular-nums` |
| `--sans` | `'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif` | UI body text stack — all prose, labels, nav |
IBM Plex fonts are vendored (three `.woff2` in `wwwroot/fonts/`) — graceful system-font
fallback operates if the fonts are unreachable.
---
## Bootstrap 5 override tokens
These tokens override Bootstrap 5's `--bs-*` custom properties so Bootstrap components
inherit the Technical-Light aesthetic. They are **harmless if Bootstrap is absent**.
| Token | Value | Role |
|---|---|---|
| `--bs-body-bg` | `var(--paper)` | Bootstrap body background → paper |
| `--bs-body-color` | `var(--ink)` | Bootstrap body text → primary ink |
| `--bs-body-font-family` | `var(--sans)` | Bootstrap body font → IBM Plex Sans |
| `--bs-body-font-size` | `0.9rem` | Bootstrap body size — slightly compact |
| `--bs-primary` | `var(--accent)` | Bootstrap primary color → accent |
| `--bs-border-color` | `var(--rule)` | Bootstrap border → hairline rule |
| `--bs-emphasis-color` | `var(--ink)` | Bootstrap emphasis text → primary ink |
---
## Usage rules
1. **Never hand-pick hex values in feature CSS.** Use the tokens above or the utility
classes (`.s-ok`, `.s-warn`, `.s-bad`, `.s-idle`, `.chip-*`, `.kv .v.*`).
2. **One per-app override only.** Override `--accent` via `ThemeShell`'s `Accent`
parameter. Do not override other tokens per-app.
3. **Status is colour, not iconography.** The status palette (`--ok`, `--warn`, `--bad`,
`--idle`) is the canonical way to communicate state. Use `StatusPill` for chips; use
`.s-*` utility classes for inline text.
4. **Token changes are breaking.** Renaming or removing a token requires a SemVer major
bump of `ZB.MOM.WW.Theme` and a coordinated update in every consumer app.