124 lines
4.8 KiB
Markdown
124 lines
4.8 KiB
Markdown
# 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 39–77). 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.
|