feat(design): the scheme set, the colour contract and the token utilities (E28 S3a)
Four schemes (Midnight; Forest cyan, Slate fuchsia, Matrix lime), YouTube and Starship retired with no data migration: normalizeTheme maps a stored retired scheme to Midnight. A vitest contract measures every scheme x mode (text 4.5:1, control edge 3:1, status text, the accent's 30-degree hue gap); it caught light-mode danger at 4.43:1, now red-700. The state layers, the strong edge, the touch target and the fades are index.css tokens and utilities the lab now reads. Backdrops recoloured to the new accents, with a grey overlay grain that actually breaks the banding (longest flat run 15-26px -> 4-8px). The glass tuner is retired.
This commit is contained in:
@@ -77,10 +77,22 @@ style guide.
|
||||
`--danger`, `--warn` and `--success`, and passes 4.5:1 both as text on `--bg` and under `--accent-fg` on
|
||||
the fill, in dark and light. A primary button must never read as a destructive one. A new scheme is
|
||||
measured against this before it ships (the lab's B2 tiles do the arithmetic). [WCAG 1.4.1, 1.4.3]
|
||||
- **Held in code:** `frontend/src/lib/theme.contract.test.ts` measures every scheme × mode in `index.css`
|
||||
against the two rules above (text 4.5:1, a control edge 3:1, the status colours as text, the accent's hue
|
||||
gap). A scheme or a retuned colour that breaks them does not pass the gate.
|
||||
- **No per-user colour tuning.** The schemes are the only colour choice; the old floating glass tuner was
|
||||
retired (E28), because free tuning is exactly the drift these rules exist to stop.
|
||||
- **Backdrops:** one per scheme and mode (`public/backdrops/`), soft pools in the accent's family, with a
|
||||
grey `overlay` grain that breaks the gradient banding (measured by pixel-scanning a canvas, never a
|
||||
screenshot, which rescales).
|
||||
- **State layers (B3):** hover and pressed are a layer, not a colour swap: the text colour mixed at **10%**
|
||||
(hover) / **16%** (pressed) over whatever the control sits on, so it reads on the page, a card and glass
|
||||
alike. A filled control mixes its own text colour into its fill at 14% / 24%. Opacity dimming and
|
||||
`bg-card` hovers are violations (invisible on a light card). Selected stays the solid accent.
|
||||
- **Tokens as utilities:** the decided values live once in `index.css` — `--hover` / `--press`,
|
||||
`--edge-strong`, `--touch-target`, and the utilities `state-layer`, `state-filled`, `state-danger`,
|
||||
`edge-strong`, `fade-below`, `fade-below-panel`, `fade-above-panel`, `fade-edges-x`. A primitive or a lab
|
||||
rendering uses them; restating one as an arbitrary class is a violation.
|
||||
- **Type and size:** everything is rem-derived off `--font-scale` (the Settings text-size slider), so a
|
||||
px font size or a px-frozen box is an eslint error.
|
||||
- **Radius:** chips and segmented controls `rounded-full`; tabs `rounded-lg`. Buttons, icon buttons and
|
||||
@@ -289,3 +301,4 @@ Wherever there is text, the user can select it and copy it, and no click action
|
||||
| 2026-09-24 | C3 Players on touch | Tap = show the controls; 44px seek hit area; 44 buttons; the YT description behind ⓘ | Today (tap also pauses; 7.5px seek bar) | Measured live: you couldn't reach the seek bar without pausing, and the hover-only description never opened on a tap |
|
||||
| 2026-09-24 | C4 Dialogs | Focus by purpose; a pinned footer | Focus on Close; the footer scrolls | A form starts in its first field, and Save stays on screen with the keyboard up |
|
||||
| 2026-09-24 | C5 Plex player controls | The owner's lean set: no Stop / Restart / ±10 s buttons, Back by position, Next only with a next item, Resume + From the start on the card, touch double-tap ±10 s | Every control in one row (it ran off-screen below 1024); Back by a press counter; ±10 s keyboard-only | The row fits a portrait tablet; the decision to restart is made on the card; a tablet keeps the 10 s skip |
|
||||
| 2026-09-24 | Glass tuner | Retired; the schemes are the only colour choice | Keep it with ranges clamped to the rules | Free tuning is the drift the constitution exists to stop (owner) |
|
||||
|
||||
Reference in New Issue
Block a user