Skip to content

Commit d2cbdfe

Browse files
committed
docs(v9): UX redesign plan + spec + style guide
VisualBuilderPlan-v9.md — 10 U-epics (U01..U10) covering remaining visual surface work after the post-V8 operator feedback cycle: - U01 Draft tabs strip in TopBar - U02 Floating canvas toolbar (vertical icon-strip) - U03 Mass hex-literal migration (592 -> <=150) - U04 Theme tokens v2 (layered surfaces + elevation) - U05 Sidebar tab strip overflow grouping - U06 Empty-state contracts for tab panels - U07 BrickNode unified styling (Palette == canvas chip) - U08 TopBar responsive collapse < 1024px - U09 Help icon catalogue audit - U10 Keyboard shortcuts overlay (? key) Section 1 explicitly lists already-shipped UX#0..#8 with commit refs so future agents don't re-open closed work. VisualBuilderSpec-v9.md — technical contracts: layout grid ASCII, theme tokens v2 (CSS + TS), component primitive interfaces (DraftTabsStrip, CanvasToolbar, EmptyState, BrickChip, KeyboardShortcutsOverlay), testid conventions, state-persistence keys, Playwright canonical walk-through. vbgui/STYLE.md — single source of truth for visual decisions: - §1 colour rule + token catalogue + semantic mapping - §2 typography - §3 spacing scale (4-px grid) - §4 radius - §5 elevation - §6 layout primitives (grid + z-index) - §7 testid conventions - §8 component primitives roadmap - §9 forbidden patterns (no hex literals, no backdrop-blur over canvas, no fixed modals without portal, etc.) - §10 migration policy bd hierarchy: epic cppmega-mlx-zozw [epic] V9 -> 10 U-epics -> 26 sub-tickets (U01.1..U10.3).
1 parent 93152e0 commit d2cbdfe

3 files changed

Lines changed: 741 additions & 0 deletions

File tree

VisualBuilderPlan-v9.md

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
# VisualBuilderPlan-v9 — UX Polish & Visual System Closure
2+
3+
**Status**: planned 2026-05-24 (epic `cppmega-mlx-v9` — to be created)
4+
5+
**Driver**: post-V8 operator-feedback cycle. V8 closed the
6+
gallery→train round trip (R01-R12). V9 closes the *visual surface*
7+
the operator interacts with every minute: canvas chrome, sidebar
8+
ergonomics, theme consistency, and discoverability.
9+
10+
> "Цвета, фонты, ux — куча компонентов и непонятно зачем. mtp это не
11+
> компонент? зачем оно тут банером? memory bar длиннюща, как ты это
12+
> покажешь на h100:8? ckpt path виден когда idle. parallel/insert/
13+
> transplant — ugly full-width strips. draft 1 + new draft — для
14+
> чего? TopBar 18 элементов, цвета непоследовательны."
15+
16+
## bd ticket ID mapping
17+
18+
| U# | scope | priority | depends on |
19+
|------|------------------------------------------------------------|----------|------------|
20+
| U01 | Draft tabs strip (browser-tab style) in TopBar left group | P2 | - |
21+
| U02 | Floating canvas toolbar (vertical 32px icon-strip) | P2 | - |
22+
| U03 | Mass hex-literal migration — 592 → ≤ 150 across `vbgui/src/components` | P3 | UX#8 ratchet |
23+
| U04 | Theme tokens v2 — layered surfaces + elevation scale | P3 | U03 |
24+
| U05 | Sidebar tab strip — collapse 10 tabs into grouped accordion | P2 | - |
25+
| U06 | Empty-state contracts for Loss/Optim/Memory/Gotchas tabs | P3 | - |
26+
| U07 | BrickNode unified styling — Palette item == canvas chip | P3 | U04 |
27+
| U08 | TopBar responsive collapse — groups stack < 1024px | P3 | UX#7 |
28+
| U09 | Help icon catalogue audit — every topic has content or 404 | P2 | - |
29+
| U10 | Keyboard shortcuts overlay (? key) | P3 | - |
30+
31+
## 1. Already done (do NOT re-open)
32+
33+
The operator-feedback redesign sprint closed these between
34+
2026-05-23 and 2026-05-24 (commits `23bb694`, `7908932`, `6fe5518`,
35+
`7bc0b43`, `5a4e314`, `7e1a031`):
36+
37+
| # | Title | Commit |
38+
|---|---|---|
39+
| #0 | HelpModal Portal — escape transformed ancestor (`position:fixed` containing-block trap) | `S3615` |
40+
| #1 | FeatureInjectionBar dedupe → chip with `×N` count + per-chip remove | `6fe5518` |
41+
| #2 | DimEnvEditor relocated to right Sidebar `Dimensions` tab | `7bc0b43` |
42+
| #3 | TrainOptionsPanel + RunHistoryPicker → new `TrainOps` Sidebar tab | `7bc0b43` |
43+
| #4 | TrainLiveControls conditional `{trainInFlight && ...}` | `7bc0b43` |
44+
| #5 (interim) | Parallel / Insert / Transplant bars removed from canvas, hosted in TrainOps tab | `7bc0b43` |
45+
| #6 | MemoryBar compact (100×18 pill) + topology-aware N-rank mini-bars | `23bb694` |
46+
| #7 | TopBar 3 flex groups (left/center/right) + single Precision dropdown | `5a4e314` |
47+
| #8 (ratchet) | `HexColorRatchet.test.ts` + per-file baseline + DimensionsTab migration | `7e1a031` |
48+
49+
## 2. Why v9 exists
50+
51+
V8 delivered the *journey*. V9 delivers the *finish*:
52+
- discoverability (Draft tabs, keyboard shortcuts, help catalogue)
53+
- visual consistency (theme tokens, BrickNode unity, mass hex
54+
migration ratcheted down from 592 to ≤ 150)
55+
- canvas chrome (floating toolbar instead of buried sidebar splicing
56+
section; responsive TopBar)
57+
- empty-state polish (so first-time operators see prompts instead of
58+
white space)
59+
60+
## 3. Goal
61+
62+
Operator opens the GUI cold. Without reading docs they can:
63+
1. Recognise every clickable region from visual weight alone.
64+
2. Find every action through ≤ 2 clicks (TopBar + Sidebar grouped).
65+
3. Use `?` overlay to discover all keyboard shortcuts.
66+
4. Switch between concurrent specs via Draft tabs.
67+
5. Splice graphs (parallel/insert/transplant) from a fixed-position
68+
floating toolbar instead of scrolling a tab.
69+
70+
## 4. Stages — 10 U-epics × 1-4 sub-tasks ≈ 26 sub-tickets
71+
72+
### U01 — Draft tabs strip in TopBar (P2, 3 subs)
73+
74+
**Why**: operator currently sees `[Draft 1] [+ New Draft]` with no
75+
visual taxonomy. Should be browser-tab-style strip wedged into
76+
TopBar left group, right of `project-name`.
77+
78+
**Subs**:
79+
- U01.1 `vbgui/src/components/DraftTabsStrip.tsx`: render N tabs
80+
`[Untitled] [Draft 1] [Draft 2 ×] [+]`. Active tab highlighted.
81+
Close button (×) only on inactive tabs.
82+
- U01.2 `vbgui/src/state/drafts.ts`: `useDrafts()` hook persists
83+
drafts to `localStorage` under `vbgui_drafts_v1` (array of full
84+
spec snapshots + name + timestamp).
85+
- U01.3 Vitest: switching draft swaps `nodes` + `edges` + `spec`
86+
on canvas; closing draft does NOT lose data of OTHER drafts.
87+
88+
### U02 — Floating canvas toolbar (P2, 4 subs)
89+
90+
**Why**: Parallel / Insert / Transplant currently live in
91+
`TrainOpsTab` (a hidden tab). They should be a fixed-position
92+
vertical strip 32px wide, left edge of canvas, between Palette
93+
and FlowCanvas.
94+
95+
**Subs**:
96+
- U02.1 `vbgui/src/components/CanvasToolbar.tsx`: vertical icon
97+
strip with three icons. Each icon opens a popover (positioned to
98+
the right of the icon) that contains the existing
99+
`ParallelComposeBar` / `InsertIntoEdgeBar` / `TransplantBar`.
100+
- U02.2 Remove the splicing section from `TrainOpsTab` (revert
101+
linter's interim placement). Update test
102+
`tests/TrainOpsTab.test.tsx` to drop the splicing assertions.
103+
- U02.3 Popovers close on click-outside and on Esc; icons show
104+
active-state ring while popover is open.
105+
- U02.4 Vitest: 3 icons render; opening one closes any other
106+
already-open popover; ParallelComposeBar still fires `onCompose`.
107+
108+
### U03 — Mass hex-literal migration (P3, 4 subs)
109+
110+
**Why**: `tests/HexColorRatchet.test.ts` locks in baseline 592. The
111+
target is ≤ 150 by end of V9 (75% reduction). High-frequency
112+
literals: `#6b7280` (55), `#374151` (36), `#94a3b8` (30),
113+
`#e5e7eb` (29).
114+
115+
**Subs**:
116+
- U03.1 Map every hex literal to the closest semantic token in
117+
`src/theme.ts` — produce `vbgui/MIGRATION_TABLE.md` with rows
118+
`hex → T.token category notes`.
119+
- U03.2 Migrate `Sidebar.tsx` + every file under `src/components/sidebar/`
120+
(target: sidebar drops to ≤ 10 hex total).
121+
- U03.3 Migrate `BrickContextPanel.tsx` (currently 32 hex —
122+
highest single offender after TrainLiveControls).
123+
- U03.4 Migrate `TrainLiveControls.tsx` (46 hex — relocate its
124+
ad-hoc colour table into `T.live*` extension if any unique values
125+
remain after migration).
126+
127+
### U04 — Theme tokens v2 — layered surfaces + elevation (P3, 2 subs)
128+
129+
**Why**: existing tokens (`T.surface`, `T.surface2`, `T.surface3`)
130+
are flat — there's no notion of "card on card" or "modal vs
131+
popover" depth. Adding `T.surfaceLayered{1,2,3}` and `T.elevation*`
132+
gives the migration target enough semantic vocabulary.
133+
134+
**Subs**:
135+
- U04.1 Extend `vbgui/src/theme.css` + `theme.ts` with:
136+
`surfaceLayered1/2/3` (each a darker variant of `surface` with a
137+
hairline border); `elevationLow/Mid/High` (box-shadow tokens);
138+
`liveAccent`, `liveAccentSoft` (semantic for live-train UI).
139+
- U04.2 Pin the additions in `vbgui/STYLE.md` (see Spec §2).
140+
141+
### U05 — Sidebar tab strip overflow (P2, 3 subs)
142+
143+
**Why**: Sidebar now has 10 tabs (Loss, Optim, Rewriters, Side
144+
Ch., Sharding, Gotchas, Dimensions, Train Ops, Ablations, Memory).
145+
At width 320px with `flex: 1 0 33%` they wrap to 4 rows of 3 — eats
146+
sidebar headroom.
147+
148+
**Subs**:
149+
- U05.1 Group tabs into 3 sections (Spec / Diagnostics / Train) —
150+
visible header per section, tabs underneath as smaller chips.
151+
- U05.2 OR: dropdown picker for less-used tabs (Ablations,
152+
Memory). A/B both, pick one with screenshots.
153+
- U05.3 Vitest: every existing `sidebar-tab-{name}` testid still
154+
resolves (back-compat).
155+
156+
### U06 — Empty-state contracts (P3, 2 subs)
157+
158+
**Why**: opening LossTab / MemoryMatrixTab / GotchasTab cold gives
159+
blank panels. Operator can't tell whether the tab is broken or
160+
empty.
161+
162+
**Subs**:
163+
- U06.1 Each of {LossTab, MemoryMatrixTab, GotchasTab,
164+
AblationsTab} renders an empty-state block when its data array
165+
is `[]`. Block = icon + headline + 1-sentence prompt + CTA.
166+
Example for GotchasTab: "✓ No issues yet — run Smoke to populate".
167+
- U06.2 Vitest: each tab in empty state has
168+
`data-testid="<tab>-empty-state"` and renders the CTA text.
169+
170+
### U07 — BrickNode unified styling (P3, 2 subs)
171+
172+
**Why**: Palette items (left dock) and canvas nodes use different
173+
chrome — Palette is white-bg + grey border, canvas is dark + accent
174+
glow. Single brick should *look the same* in both places (different
175+
backgrounds, identical typography + accent treatment).
176+
177+
**Subs**:
178+
- U07.1 Extract shared `BrickChip` primitive used by both
179+
`Palette` items and `BrickNode` canvas nodes.
180+
- U07.2 Vitest: Palette item and BrickNode for the same kind have
181+
same `data-brick-kind` + same `--vb-node-accent` CSS variable.
182+
183+
### U08 — TopBar responsive collapse (P3, 2 subs)
184+
185+
**Why**: UX#7 split into 3 flex groups. Below 1024px width they
186+
overflow horizontally — need to stack groups onto 2 rows when
187+
viewport is narrow.
188+
189+
**Subs**:
190+
- U08.1 `@container` or `min-width` media query — when
191+
`< 1024px` stack the center group below left+right.
192+
- U08.2 Vitest with jsdom-resize: at 800px width
193+
`top-bar-group-center.style.flexDirection === "column"` OR a
194+
wrap container.
195+
196+
### U09 — Help icon catalogue audit (P2, 3 subs)
197+
198+
**Why**: `HelpIcon topic="..."` references ~80 topics. Many may
199+
have drifted (renames, broken slugs) — operator clicks `?` and
200+
sees "missing" modal. Need a programmatic audit + autofix path.
201+
202+
**Subs**:
203+
- U09.1 vitest scans every `<HelpIcon topic="X">` use, every
204+
`Tooltip name="X">`, and every `ExplainModal name="X">` in
205+
`vbgui/src/components/**/*.tsx`. For each, asserts the topic
206+
exists in `HELP_TOPICS` map OR a `catalog.explain` RPC response.
207+
Failing topics listed.
208+
- U09.2 Add missing topics to `HelpIcon.tsx` HELP_TOPICS map (one
209+
paragraph each) OR remove the reference if the surface is dead.
210+
- U09.3 Add `topic` autocomplete TS type so future references type-check.
211+
212+
### U10 — Keyboard shortcuts overlay (P3, 3 subs)
213+
214+
**Why**: power users want `?` to bring up a list of all shortcuts.
215+
Currently only Cmd/Ctrl+Z (undo) + Shift+Cmd/Ctrl+Z (redo) are
216+
hinted in button titles.
217+
218+
**Subs**:
219+
- U10.1 `vbgui/src/components/KeyboardShortcutsOverlay.tsx`:
220+
modal triggered by `?` (and dismissed by `?` or Esc) listing
221+
every registered shortcut grouped by section (Canvas / Sidebar
222+
/ Train / Help).
223+
- U10.2 `vbgui/src/state/shortcuts.ts`: central registry — every
224+
bound shortcut registers `{key, label, section, handler}` so the
225+
overlay is generated, not hand-edited.
226+
- U10.3 Vitest: pressing `?` opens overlay; overlay lists ≥ 1
227+
shortcut per section.
228+
229+
## 5. Workflow per epic (same as v5/v6/v7/v8)
230+
231+
1. Read `VisualBuilderSpec-v9.md` for the relevant U-section.
232+
2. Create files per spec, with the listed data-testids.
233+
3. Write vitest tests first (TDD); they should fail.
234+
4. Wire the component; tests pass.
235+
5. Run full `npx vitest run` from `vbgui/` to confirm zero regression.
236+
6. Commit with `UX-U0#: <title>` message; close the bd ticket.
237+
7. Push to main.
238+
239+
## 6. Acceptance counters (mirrors §4)
240+
241+
- 10 U-epics → 26 sub-tickets created in bd as
242+
`cppmega-mlx-v9/U01..U10` (one parent + 10 child epics).
243+
- Each sub-ticket has acceptance criteria copied from §4.
244+
- New vitest count: ≥ 25 (across all U-stages).
245+
- `HexColorRatchet.test.ts` baseline drops from 592 to ≤ 150 by end
246+
of U03 (≥ 75% reduction).
247+
248+
## 7. Out of scope (V10+)
249+
250+
- True theming (user-switchable light/dark/contrast).
251+
- Drag-to-reorder canvas nodes (current ELK auto-align only).
252+
- Multi-user collaboration (CRDT spec sync).
253+
- Mobile/tablet viewports (focused on ≥ 1024px desktop).
254+
- Internationalisation (English-only UI text).
255+
256+
## 8. Done definition
257+
258+
V9 is done when:
259+
- All 10 U-epics closed in bd (sub-tickets either closed or
260+
deferred to V10 with explicit reason).
261+
- `npx vitest run` from `vbgui/`: 0 failures (counting only
262+
V9-relevant test files; pre-existing HelpModal/Palette/Backward
263+
failures are tracked separately).
264+
- `HexColorRatchet` baseline ≤ 150.
265+
- `VisualBuilderPlan-v9.md` + `VisualBuilderSpec-v9.md` + `vbgui/STYLE.md`
266+
shipped on `main`.
267+
- A 5-min screen-recording captures Draft tabs + Canvas toolbar +
268+
empty states + `?` overlay (UAT footage).

0 commit comments

Comments
 (0)