Implement M1.5 visual design foundation: tokens, IBM Plex, theme toggle, chart themes

This commit is contained in:
2026-06-05 01:29:10 +03:00
parent 547edb85e4
commit 22f0556ef8
31 changed files with 713 additions and 136 deletions
+22 -5
View File
@@ -46,7 +46,7 @@ doc before implementing.
|---|-----------|---------|------|
| **M0** | Skeleton ✅ | Repo builds, tests run, empty shell renders | — |
| **M1** | **MVP core loop** | Author a Vega-Lite snippet, see it render live, it persists | §02, §03AC, §04, §09A |
| **M1.5** | Visual design foundation | Apply the design language: tokens, IBM Plex, restyled M1 surfaces, chart theme | [arch 09](architecture/09-visual-design.md) |
| **M1.5** | Visual design foundation | Apply the design language: tokens, IBM Plex, restyled M1 surfaces, chart theme | [arch 09](architecture/09-visual-design.md) |
| **M2** | Editor robustness | Draft/Published, validation, schema autocomplete, fit modes | §03DE, §04, §07(editor) |
| **M3** | Datasets | Named reusable data + reference resolution in preview | §05, §03F, §09B |
| **M4** | Chart Builder | No-JSON chart composition from a dataset | §06 |
@@ -113,7 +113,7 @@ preview, and have it survive reload. Single source kind: inline-data specs only
---
## M1.5 · Visual design foundation → *make the MVP look like itself*
## M1.5 · Visual design foundation ✅ (done) → *make the MVP look like itself*
**Goal:** apply our design language so the running MVP looks deliberate, and every
later milestone builds on settled tokens instead of placeholders. The expensive part
@@ -134,6 +134,11 @@ and the companion `visual-specimen.html`.
raw hexes, no hardcoded hues in components.
- Establish the reusable component conventions (buttons, fields, list rows, status,
focus ring) that M2M6 reuse.
- **Header theme toggle** (pulled forward from M5): a one-click light⇄dark control,
persisted via the `ui.theme` settings key (a minimal forward-compatible
`settings-store` adapter the full M5 UserSettings store will absorb). Hydrated
before first paint (no FOUC). Justified: the theme system was already complete,
so dogfooding dark mode through M2M4 beat waiting for the Settings modal.
**Core**
- Align `src/core/vega-themes.ts`: chart `Config` per theme + a categorical
@@ -148,6 +153,15 @@ and the companion `visual-specimen.html`.
- Keyboard focus ring visible; text/UI contrast passes AA in light and dark.
- No placeholder styling remains on the M1 surfaces.
**Verified:** `typecheck` + `test` (61 passing, incl. `vega-themes.test.ts`) +
`build` (Plex woff2, all script subsets, bundled & precached via the PWA
`globPatterns`). Both themes screenshotted via the real
app (chrome + Monaco + chart all repaint on theme flip); focus ring visible.
Notes from the build-out: the placeholder `'experimental'` theme was renamed to
`'dark'` (the settled name); the swappable `[data-accent]` layer landed with
indigo as the robust default (no switcher UI until M5); Monaco's `fontFamily` is
set to Plex Mono explicitly since it can't read the CSS token.
---
## M2 · Editor robustness
@@ -260,12 +274,15 @@ the reference.
- `export-envelope.ts` — build the `{version, exportedAt, exportedBy, snippets, datasets}` envelope.
**Infrastructure**
- `settings-store.ts` (localStorage); `ux-prefs` for sort + panel layout (§09D).
- `settings-store.ts` (localStorage): **extend** the minimal M1.5 adapter (which
already persists `ui.theme`) to the full UserSettings record; `ux-prefs` for sort
+ panel layout (§09D).
**App**
- Settings **modal** (Appearance/Editor/Performance/Formatting), Apply/Cancel/Reset,
dirty indicator; wire render-debounce + theme + date-format through to the app
(the themes themselves already exist from M1.5 — this adds the switcher UI).
dirty indicator; wire render-debounce + theme + date-format through to the app.
Theme already switches (M1.5 header toggle + chart/editor themes) — M5 surfaces
it inside the modal too (sharing the same `ui.theme`) and wires the rest.
- Header **Import**/**Export** (direct file dialog / download, no modal).
- Date formatting util (smart/iso/custom) used by the library list.