Files
scalesApp/.claude/plans/css-design-tokens.md

5.0 KiB
Raw Permalink Blame History

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 under cockpit;
  • UserManager.jsx styles itself entirely with inline style={{}}.

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)

  1. Tokens — add the block above to tokens.css; index.css body uses --font-sans, code uses --font-mono.
  2. Screens already on colour tokens — swap font/spacing literals: Main.css, ScaleMonitor.css, Header.css, History.css, ExtraCombinationsTable.css, App.css, ReportPreviewModal.css.
  3. 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 new UserManager.css (reuse existing Main.css classes like .extra-field, .vehicle-form-actions where they already fit).
  4. 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 in A4Canvas.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 build passes.
  • Visual: screenshots (Playwright, saved to .claude/screenshots/) of main screen, nomenclature manager, login, licence, user manager, both report editors — in classic and cockpit, 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".