5.0 KiB
CSS design tokens — typography, spacing, and full colour migration
Context
src/styles/tokens.css already defines semantic colour/radius/shadow tokens for
two themes (classic, cockpit). But:
- there are no font or spacing tokens: ~25 distinct font-sizes (7px…40px, px and rem mixed), 9 font-family declarations, ~25 distinct padding/margin/gap values;
- about half the stylesheets still hardcode colours (
#667eea×88,#333×42 …), so those screens ignore the theme — they stay light undercockpit; UserManager.jsxstyles itself entirely with inlinestyle={{}}.
Goal: every UI value (colour, font, size, weight, spacing) comes from a token, so the look is changed in one file. Report output keeps fixed values.
What stays fixed (not tokenised)
Printed/rendered report output must look identical regardless of screen theme:
ReportEditor/a4/a4Elements.css,a4/print/print.css,ReportEditor/print/print.css,ReportEditor/elements.css(text-mode report elements on the page)- colours in A4 element JSX (
a4/elements/*),calibrationReport.js,sampleData.js, tests - the "paper" surface itself (white page in
A4Canvas.css/EditorCanvas.css)
The report editor chrome around it (toolbar, inspectors, config panel, character palette, kind chooser, page setup, selection handles/guides) does get tokens.
Also left alone: components/concepts/ScalesAppCyberpunk.css (standalone mockup
with its own private vars). DataDisplay.jsx/.css is not imported anywhere — dead
code, flagged, not touched.
New tokens (in :root only — theme-independent, both themes share them)
/* Type */
--font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--font-mono: 'Courier New', Consolas, monospace;
--fs-xs: 11px; --fs-sm: 12px; --fs-base: 13px; --fs-md: 14px;
--fs-lg: 16px; --fs-xl: 18px; --fs-2xl: 22px; --fs-3xl: 28px;
--fs-display: 32px; /* big figures: the weight reading etc. */
--fw-regular: 400; --fw-medium: 500; --fw-semibold: 600; --fw-bold: 700;
/* Spacing — 4px grid with the half-steps this UI actually uses a lot (6, 10) */
--space-0-5: 2px; --space-1: 4px; --space-1-5: 6px; --space-2: 8px;
--space-2-5: 10px; --space-3: 12px; --space-4: 16px; --space-5: 20px;
--space-6: 24px; --space-8: 32px; --space-10: 40px;
A theme may later override any of these (e.g. a larger --fs-display for cockpit).
Snapping rule: off-scale values snap to the nearest step (5→4/6, 7→6/8,
14→12/16, 15/17→16, 20→22 for font, rem values converted at 16px). Expect ≤2px
drift in places — that's the consistency we're buying. Values that are
geometry rather than rhythm (1px borders, icon/checkbox sizes, fixed widths,
letter-spacing) stay literal.
Colour mapping for stray literals (add a token only if nothing fits):
#667eea→--accent, #764ba2 gradients→--accent-gradient,
#333/#2c3e50→--text, #555/#666/#888/#999→--text-muted,
#ddd/#e0e0e0/#dee2e6→--border, #f5f5f5/#fafafa/#f0f0f0→--surface-sunken/--surface-hover,
white/#fff→--surface, #fee/#c33→--danger-soft/--danger, greens/oranges→--success*/--warning*.
Likely one new token: --backdrop (modal overlay dim).
Phases (one commit each; done via /dispatch → react-expert-dev)
- Tokens — add the block above to
tokens.css;index.cssbody uses--font-sans,codeuses--font-mono. - Screens already on colour tokens — swap font/spacing literals:
Main.css,ScaleMonitor.css,Header.css,History.css,ExtraCombinationsTable.css,App.css,ReportPreviewModal.css. - Hardcoded screens — colours + fonts + spacing:
NomenclatureManager.css,NomenclatureUI/*.css(ManagementOverlay, EntryForm, Dropdown, FormOverlay),LicenseManager.css,Login.css,ChangePasswordOverlay.css.UserManager.jsx: move inline styles into a newUserManager.css(reuse existing Main.css classes like.extra-field,.vehicle-form-actionswhere they already fit). - Report editor chrome —
ReportEditor.css,Toolbar.css,ObjectInspector.css,ConfigPanel.css,CharacterPalette.css,EditorCanvas.css(non-paper parts),a4/A4Canvas.css(non-paper),A4Inspector.css,A4PageSetup.css,A4KindChooser.css,A4ReportEditor.css; chrome colours inA4Canvas.jsx/A4Inspector.jsx/ObjectInspector.jsx(guides, handles) →var(--…).
Verification
- After each phase: grep for
#[0-9a-f]{3,6},font-size: *[0-9], px spacing in the touched files → only allowed literals remain. - End state: hex colours exist only in
tokens.css, the "fixed" report files, and the concept page. npm run buildpasses.- Visual: screenshots (Playwright, saved to
.claude/screenshots/) of main screen, nomenclature manager, login, licence, user manager, both report editors — inclassicandcockpit, before and after. Classic should look the same (±snapping); cockpit should now be dark on the previously-light screens. - Test suite only when you say "ready for testing".