SCRUM-246 — AdminUI design system¶
Plan ref: UI-1 (docs/11-admin-plane-plan.md).
What exists¶
| Piece | Notes |
|---|---|
src/theme/tokens.css |
the only file with colour values: --ds-* roles (bg, surface, border, text, accent, status ok/warn/danger/info/neutral + -soft), 4 px spacing scale, type scale, radii, elevation, mono font; light on :root, dark via prefers-color-scheme and Ionic's dark-palette class; mapped onto Ionic's --ion-* variables |
src/components/ui/ |
PageHeader, Toolbar, Grid, Panel, DataTable (generic, cell slots, sticky header, scrolls inside its own box), StatTile, StatusDot (label always rendered unless compact), EmptyState (moved here), ErrorPanel (COM-5/ApiError, request id), CopyableId |
| Views | every view, the shell and the JSON editor rebuilt on the primitives; behaviour, text and test ids unchanged. The namespace name in the Config list is now a real link (keyboard reachable); a row click still opens it |
| Guard rail | tests/unit/design-tokens.spec.ts fails on any colour literal outside tokens.css and on any var(--ds-…) that tokens.css does not define |
| CodeMirror | syntax colours come from tokens via @codemirror/language + @lezer/highlight, now declared dependencies (same versions the lockfile already had) and pre-bundled in dev (optimizeDeps.include) |
How to verify¶
cd services/adminui
npm ci
npm run typecheck && npm run lint && npm run format:check && npx vitest run && npm run build
npx playwright test # mock API; run twice with `rm -rf node_modules/.vite` first
npm run dev:mock # look at /admin/dashboard, /admin/config in light and dark, at 1280 and 400 px
Results at time of writing¶
- typecheck, lint (0 warnings), prettier, vitest (215 tests), build: pass.
- Playwright sign-in suite: 5/5, including from a cold Vite cache.
- Screenshots checked: dashboard at 1280 and 400 px (no horizontal scroll), config list in dark mode.
How it was built¶
DeepSeek run scoped (Landlock) to services/adminui (389 s, ~67k output tokens,
reasoning effort low). Claude review:
- the Playwright sign-in test failed: the namespace names were no longer headings
(now a table), and on a cold dev server Vite discovered the new CodeMirror imports
late and reloaded mid-navigation. Fixed by making the name a link (test asserts the
link) and pre-bundling the three packages;
- declared @codemirror/language and @lezer/highlight, which the editor now imports
directly, instead of relying on them being transitive.