The corpus catches up with the wave — sixteen colors, a symbol browser, a hideable sidebar, and the context menu's four groups

Amendments the worktree agents owed but could not write: 03's palette
counts and the symbol full-browser reversal (CoreGlyphs-derived catalog),
05's sidebar visibility ruling, 11's Show Sidebar row and the card
context-menu row reshaped to the four-group structure with its two
flagged gaps (style pre-focus, the disabled Navigation pair).

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
2026-08-09 09:48:39 -04:00
parent 72ca22251b
commit 546fd2840f
3 changed files with 6 additions and 5 deletions
+3 -3
View File
@@ -39,14 +39,14 @@ Toolbars are **pure enhancement**: every function they host already has a menu i
- **The standard chrome is the pathfinder's surface stack** (settled 2026-08-06): the window keeps the neutral system background; every lane wears a quiet quaternary-wash plate (the trash plate's own figure — translucent, so a board-chosen color shows through and the board-level ink rule keeps its premise; opaque under Reduce Transparency, the trash precedent); every card sits on an opaque `controlBackgroundColor` plate — white over the washed lane in light appearance, a step *darker* than the window in dark. One plate value for every face a card draws (resting, replicas, placeholder, arriving), so a card is the same object wherever it renders. - **The standard chrome is the pathfinder's surface stack** (settled 2026-08-06): the window keeps the neutral system background; every lane wears a quiet quaternary-wash plate (the trash plate's own figure — translucent, so a board-chosen color shows through and the board-level ink rule keeps its premise; opaque under Reduce Transparency, the trash precedent); every card sits on an opaque `controlBackgroundColor` plate — white over the washed lane in light appearance, a step *darker* than the window in dark. One plate value for every face a card draws (resting, replicas, placeholder, arriving), so a card is the same object wherever it renders.
- **`icon`**: SF Symbol per item with per-level defaults (board `rectangle.split.3x1`, lane `square.stack`, card `doc.text`). - **`icon`**: SF Symbol per item with per-level defaults (board `rectangle.split.3x1`, lane `square.stack`, card `doc.text`).
- **`iconColor`**: resolved — **schema yes, control no**. The field renders when hand-written (tint palette name or hex); the app offers no control for it (Controls below). - **`iconColor`**: resolved — **schema yes, control no**. The field renders when hand-written (tint palette name or hex); the app offers no control for it (Controls below).
- The pathfinder's palettes (12 icon tints, 12 backgrounds) carry over as the starting point. **The 12+12 split is a picker split, not a name split** (settled): color resolution searches foregrounds then backgrounds, so a hand-written `background: carnation` (an icon-tint name) resolves and paints — the split governs what the grids offer, never what a name means. - The pathfinder's palettes (12 icon tints, 12 backgrounds; grown to 16+16 on 2026-08-09 — the hue ring's four widest gaps filled at lime 64°, jade 158°, indigo 238°, magenta 312°, S/B set per table's own statistics) carry over as the starting point. **The 12+12 split is a picker split, not a name split** (settled): color resolution searches foregrounds then backgrounds, so a hand-written `background: carnation` (an icon-tint name) resolves and paints — the split governs what the grids offer, never what a name means.
### Controls (settled) ### Controls (settled)
One **style editor** component — a background palette grid and a curated symbol grid — presented as a **popover** opened by Style… from a card/lane context menu or the menu bar (Board ▸ Style…, ⌥⌘S — 11-command-nexus.md; selection-aware: it styles the selected cards or lane, and with nothing selected, the board). One component, one behavior — replacing the pathfinder's swatch-row-plus-Style-popover split, whose functions were right and whose form wasn't. **The card window sidebar now styles through the compact `SymbolPicker` instead of this component** (2026-08-06 anchor-ownership rule for the background half; the symbol half followed the same way on 2026-08-08): the sidebar pairs the **color combo** (below) — standing in for the background half, the narrow context the combo was built for — with the picker's own well and popover-hosted grid, fed `CuratedSymbols`' card-level set, so this component now has exactly one anchor left, the Style… popover, which alone carries both grids in full. (The board popover was briefly a third anchor — the background half embedded in its Theme tab — until the 2026-08-07 Theme rework made that tab preset-only; Style… with nothing selected is the board's manual grid now, and the popover's symbol picker beside the rename field still owns the board glyph — the same `SymbolPicker` the card sidebar now uses.) One **style editor** component — a background palette grid and a curated symbol grid — presented as a **popover** opened by Style… from a card/lane context menu or the menu bar (Board ▸ Style…, ⌥⌘S — 11-command-nexus.md; selection-aware: it styles the selected cards or lane, and with nothing selected, the board). One component, one behavior — replacing the pathfinder's swatch-row-plus-Style-popover split, whose functions were right and whose form wasn't. **The card window sidebar now styles through the compact `SymbolPicker` instead of this component** (2026-08-06 anchor-ownership rule for the background half; the symbol half followed the same way on 2026-08-08): the sidebar pairs the **color combo** (below) — standing in for the background half, the narrow context the combo was built for — with the picker's own well and popover-hosted grid, fed `CuratedSymbols`' card-level set, so this component now has exactly one anchor left, the Style… popover, which alone carries both grids in full. (The board popover was briefly a third anchor — the background half embedded in its Theme tab — until the 2026-08-07 Theme rework made that tab preset-only; Style… with nothing selected is the board's manual grid now, and the popover's symbol picker beside the rename field still owns the board glyph — the same `SymbolPicker` the card sidebar now uses.)
- **Curated-first, panel-backed** (re-ratified 2026-08-06, reversing 2026-07-29's palette-only ruling): the background grid offers the 12 palette colors — every one AA-verified through one code path (ratified 2026-07-29: palette names route through the same runtime ink-selection seam as hand-written hex — the appearance flip picks the readable label vocabulary — and PaletteContrastTests pins that the chosen ink meets AA in both appearances for all 12 backgrounds, so palette drift can never silently break it) — plus a leading **None** well that removes the `background` key. Beside the grid the vocabulary now has a second, compact form: the **color combo** — a swatch-faced popup listing None, the role's twelve, the current off-palette value verbatim when there is one, and **Other…**, which opens the system Colors panel. The panel is the in-app escape hatch the 2026-07-29 ruling withheld: a pick landing exactly on a palette color stores the *name* (so a re-pick never drifts to a hex spelling), anything else stores the hex — the same unlimited vocabulary hand-editing always had, now pickable. An arbitrary pick changes no contrast story (it lands on the identical runtime ink computation hand-written hex already gets — 10-accessibility.md), and the quick-style recents stay palette-vocabulary: a panel pick never enters them. - **Curated-first, panel-backed** (re-ratified 2026-08-06, reversing 2026-07-29's palette-only ruling): the background grid offers the 16 palette colors (12 until 2026-08-09) — every one AA-verified through one code path (ratified 2026-07-29: palette names route through the same runtime ink-selection seam as hand-written hex — the appearance flip picks the readable label vocabulary — and PaletteContrastTests pins that the chosen ink meets AA in both appearances for all 16 backgrounds, so palette drift can never silently break it) — plus a leading **None** well that removes the `background` key. Beside the grid the vocabulary now has a second, compact form: the **color combo** — a swatch-faced popup listing None, the role's twelve, the current off-palette value verbatim when there is one, and **Other…**, which opens the system Colors panel. The panel is the in-app escape hatch the 2026-07-29 ruling withheld: a pick landing exactly on a palette color stores the *name* (so a re-pick never drifts to a hex spelling), anything else stores the hex — the same unlimited vocabulary hand-editing always had, now pickable. An arbitrary pick changes no contrast story (it lands on the identical runtime ink computation hand-written hex already gets — 10-accessibility.md), and the quick-style recents stay palette-vocabulary: a panel pick never enters them.
- **Curated symbol grid**: three hand-picked, level-specific sets (~3040 SF Symbols each, one for boards, one for lanes, one for cards — split 2026-08-09 from an original single ~65-entry list); the grid draws from whichever set matches the target's level, or the three combined for a target spanning more than one (unreachable today under 04-interactions.md's cards-XOR-lanes rule, kept as a real fallback rather than an assumption). Its leading well is the level's default symbol and removes the `icon` key. Any other SF Symbol name works written by hand — named symbols the running OS knows, that is: inventories grow per macOS release, so a newer-OS name renders the level default on an older Mac, value preserved on disk — the palette stance again. No full-browser escape hatch in-app; the raw file is the escape hatch. (Symbols keep this stance deliberately — the 2026-08-06 color-panel reversal above is colors only: the system offers a Colors panel worth deferring to, and no symbol browser of equal standing.) - **Curated symbol grid**: three hand-picked, level-specific sets (~3040 SF Symbols each, one for boards, one for lanes, one for cards — split 2026-08-09 from an original single ~65-entry list); the grid draws from whichever set matches the target's level, or the three combined for a target spanning more than one (unreachable today under 04-interactions.md's cards-XOR-lanes rule, kept as a real fallback rather than an assumption). Its leading well is the level's default symbol and removes the `icon` key. Any other SF Symbol name works written by hand — named symbols the running OS knows, that is: inventories grow per macOS release, so a newer-OS name renders the level default on an older Mac, value preserved on disk — the palette stance again. **The full-browser stance reversed 2026-08-09** (Pipeline card 5004c540 — the pickers-rhyme pass): the symbol combo's face opens a standalone searchable, categorized browser panel — the Colors-panel move, made for symbols, once the browser could be *derived* rather than hand-curated: the catalog reads the OS's own `CoreGlyphs` plists (categories, order, search terms, restrictions), so it inventories exactly what the running OS renders, drops trademark-restricted glyphs, and grows per macOS release with no app-side list to maintain. The raw file remains the escape hatch for names the browser doesn't surface.
- **Off-palette values display leniently**: a hand-written hex background or uncurated symbol shows as the current value in the editor (labeled verbatim, outside the grids); choosing any well replaces it. - **Off-palette values display leniently**: a hand-written hex background or uncurated symbol shows as the current value in the editor (labeled verbatim, outside the grids); choosing any well replaces it.
- **Batch edits**: a multi-selection shows per-dimension mixed state (no well selected, "—" where a value would read); choosing a well applies to the whole selection — one gesture, one commit on git boards. - **Batch edits**: a multi-selection shows per-dimension mixed state (no well selected, "—" where a value would read); choosing a well applies to the whole selection — one gesture, one commit on git boards.
- **The Style… popover tracks its target set live and dismisses when it empties** (settled): its target is the selection, re-resolved across reloads by 02-architecture.md's UUID rule — a member that vanishes or flips liveness leaves the set and the mixed-state display recomputes; a set emptied by a foreign reload dismisses the popover (the inline-rename discard applied here) — it never silently retargets to the board, and nothing writes into a vanished folder (a member moved to the trash leaves the set like any other departure). **The read-only lock instead disables its wells in place** (settled): a popover open when the lock lands stays open, content disabled — the banner names why, and the lock never yanks a surface (the Edit buffer's keeps-its-place posture). The embedded anchors need no rule of their own: the card sidebar dismisses with its card's window, and the board popover's target is the board itself. - **The Style… popover tracks its target set live and dismisses when it empties** (settled): its target is the selection, re-resolved across reloads by 02-architecture.md's UUID rule — a member that vanishes or flips liveness leaves the set and the mixed-state display recomputes; a set emptied by a foreign reload dismisses the popover (the inline-rename discard applied here) — it never silently retargets to the board, and nothing writes into a vanished folder (a member moved to the trash leaves the set like any other departure). **The read-only lock instead disables its wells in place** (settled): a popover open when the lock lands stays open, content disabled — the banner names why, and the lock never yanks a surface (the Edit buffer's keeps-its-place posture). The embedded anchors need no rule of their own: the card sidebar dismisses with its card's window, and the board popover's target is the board itself.
+1 -1
View File
@@ -9,7 +9,7 @@ The standalone per-card window. Opened by fast double-click, ⌘↩, or the cont
Three **componentized panes** (re-composed 2026-07-29, comments design): a wide **body pane** (leading), the **comments pane** (middle, when shown — The comments column below), and the narrow **attributes sidebar** (trailing) — each an independent component with its own scroll, arranged by the window's layout rather than wired to each other; componentization is the rule, so the comments pane mounts beside the body or below it (the layout option, next) without either pane knowing which. Visual reference: [assets/card-sidebar-reference.png](assets/card-sidebar-reference.png) — a GitLab-style issue pane; its *pattern* (stacked small-caps sections, quiet read-first rows, actions at the bottom) is what carries over, not its enhanced-schema content. Three **componentized panes** (re-composed 2026-07-29, comments design): a wide **body pane** (leading), the **comments pane** (middle, when shown — The comments column below), and the narrow **attributes sidebar** (trailing) — each an independent component with its own scroll, arranged by the window's layout rather than wired to each other; componentization is the rule, so the comments pane mounts beside the body or below it (the layout option, next) without either pane knowing which. Visual reference: [assets/card-sidebar-reference.png](assets/card-sidebar-reference.png) — a GitLab-style issue pane; its *pattern* (stacked small-caps sections, quiet read-first rows, actions at the bottom) is what carries over, not its enhanced-schema content.
- **Body column, top to bottom**: the **title field** — large, borderless; edits write through to frontmatter on commit (Return or focus loss); clearing it removes the `title` key (titles are optional — the untitled placeholder shows here as on the face); Return commits and moves focus into the body. **Escape abandons** (settled — the board inline rename's abandon, applied here): the field reverts to the on-disk title and focus moves into the body, never a commit. The Edit-mode collision resolves by focus, 06-history-undo.md's first-responder rule: while the title field is focused, Escape is the title abandon even with the body in Edit; with the body editor focused, Escape is the Edit→Preview flip as specified. Beneath it, a **quiet created/modified line** ("Created ⟨date⟩ · Modified ⟨date⟩ · by ⟨modified-by⟩", secondary styling, omitting whichever keys are absent — the "by" segment renders only when the self-reported provenance stamp is present, 01-storage-format.md; this is provenance made visible where git history may not exist) — the read-only readout the pathfinder dropped with its inspector, back where the mockup puts it. Then the **body** (Preview/Edit, below). - **Body column, top to bottom**: the **title field** — large, borderless; edits write through to frontmatter on commit (Return or focus loss); clearing it removes the `title` key (titles are optional — the untitled placeholder shows here as on the face); Return commits and moves focus into the body. **Escape abandons** (settled — the board inline rename's abandon, applied here): the field reverts to the on-disk title and focus moves into the body, never a commit. The Edit-mode collision resolves by focus, 06-history-undo.md's first-responder rule: while the title field is focused, Escape is the title abandon even with the body in Edit; with the body editor focused, Escape is the Edit→Preview flip as specified. Beneath it, a **quiet created/modified line** ("Created ⟨date⟩ · Modified ⟨date⟩ · by ⟨modified-by⟩", secondary styling, omitting whichever keys are absent — the "by" segment renders only when the self-reported provenance stamp is present, 01-storage-format.md; this is provenance made visible where git history may not exist) — the read-only readout the pathfinder dropped with its inspector, back where the mockup puts it. Then the **body** (Preview/Edit, below).
- **Attributes sidebar**: everything about the card that isn't the body — sections below. Fixed narrow width derived from font metrics (full relative scaling, 10-accessibility.md); the window's resize flex goes to the body. - **Attributes sidebar**: everything about the card that isn't the body — sections below. Fixed narrow width derived from font metrics (full relative scaling, 10-accessibility.md); the window's resize flex goes to the body. **The sidebar can be hidden** (2026-08-09, Pipeline card 1d2d1c77): View ▸ Show Sidebar and a toolbar toggle (`sidebar.right`, fourth default item) — app-wide, persisted, default on, Show Comments' shape; the window minimum shrinks with it and the reflow animates in the structural voice (crossfade under Reduce Motion).
- **Body/comments layout is an option** (ruled 2026-07-29 — componentized panes make it cheap): side-by-side is the default; **View ▸ Comments Beside Body** unchecked stacks them — body pane above, comments pane below at a fixed ≈3:2 split, each keeping its own scroll — for narrow displays. App-wide, persisted. The panes are identical in both mounts, and the thread stays visible through body **Edit** in either (Edit swaps only the body pane's content — the sidebar's own precedent); the window's minimum width grows only while the column is shown side-by-side, and resize flex always goes to the body, never the fixed panes. - **Body/comments layout is an option** (ruled 2026-07-29 — componentized panes make it cheap): side-by-side is the default; **View ▸ Comments Beside Body** unchecked stacks them — body pane above, comments pane below at a fixed ≈3:2 split, each keeping its own scroll — for narrow displays. App-wide, persisted. The panes are identical in both mounts, and the thread stays visible through body **Edit** in either (Edit swaps only the body pane's content — the sidebar's own precedent); the window's minimum width grows only while the column is shown side-by-side, and resize flex always goes to the body, never the fixed panes.
(The pathfinder's compositions are both gone: the metadata bar — labels, assignees, due — left with those fields' move to the enhanced schema, and the horizontal attachments strip dissolves into the sidebar.) (The pathfinder's compositions are both gone: the metadata bar — labels, assignees, due — left with those fields' move to the enhanced schema, and the horizontal attachments strip dissolves into the sidebar.)
+2 -1
View File
@@ -59,6 +59,7 @@ The single source of truth for **every command and action the app can perform**
| View | Actual Size | ⌘0 | Board window; returns to 100%, where the strip renders exactly what it rendered before zoom existed. Disabled when already there, and under the same guard. The level is app-wide and persisted across restarts (the Show Comments precedent) — a zoom is a viewing comfort, not a property of any one board | | View | Actual Size | ⌘0 | Board window; returns to 100%, where the strip renders exactly what it rendered before zoom existed. Disabled when already there, and under the same guard. The level is app-wide and persisted across restarts (the Show Comments precedent) — a zoom is a viewing comfort, not a property of any one board |
| View | Edit Body (checkmark toggle) | ⌘E | Card window; disabled while Raw Source is active | | View | Edit Body (checkmark toggle) | ⌘E | Card window; disabled while Raw Source is active |
| View | Show Comments (checkmark toggle) | — (no default) | Card window; app-wide, persisted across restarts (re-ruled 2026-07-29 — no content-derived auto-show; 05 ▸ The comments column) | | View | Show Comments (checkmark toggle) | — (no default) | Card window; app-wide, persisted across restarts (re-ruled 2026-07-29 — no content-derived auto-show; 05 ▸ The comments column) |
| View | Show Sidebar (checkmark toggle) | — (no default) | Card window; app-wide, persisted, default on (2026-08-09 — 05 ▸ The attributes sidebar); twin of the card toolbar's `sidebar.right` item, the fourth default beside Edit Body / Raw Source / Add Attachment |
| View | Comments Beside Body (checkmark toggle) | — (no default) | Card window; checked = side-by-side (default), unchecked = body over comments; app-wide, persisted (05 ▸ Composition) | | View | Comments Beside Body (checkmark toggle) | — (no default) | Card window; checked = side-by-side (default), unchecked = body over comments; app-wide, persisted (05 ▸ Composition) |
| View | Raw Source (checkmark toggle; toggling off = Apply) | ⌥⌘E | Card window | | View | Raw Source (checkmark toggle; toggling off = Apply) | ⌥⌘E | Card window |
| View | History | — (no default) | Card window; focuses the sidebar History section (05); git boards only — section absent, item disabled on mode none / repo-nested | | View | History | — (no default) | Card window; focuses the sidebar History section (05); git boards only — section absent, item disabled on mode none / repo-nested |
@@ -105,7 +106,7 @@ Context menus are the per-item action inventory VoiceOver reads (10 ▸ The boar
| Surface | Entries | | Surface | Entries |
|---|---| |---|---|
| Card | Open, Copy Link (folder link to the pasteboard — twin of Board ▸ Copy Link, 2026-08-09), Rename, Style…, quick-style recents row (03), Delete (the ⌥-alternate Delete Immediately row retired with the command, 2026-07-30) | | Card | Four groups, separators between (reshaped 2026-08-09, Pipeline card fe66c461): **1** Open, Copy Link (kept — same-day feature, 2026-08-09), Rename, Style ▸ Symbol / Color (both open the Style… popover; no per-section focus yet — flagged); **2** Copy, Cut, Paste, Paste Special ▸ Paste Image into Card (enabled when the pasteboard carries an image); **3** Navigation ▸ Move Left / Move Right (wired but disabled — no per-card cross-lane move exists yet; follow-up Pipeline card 06322636); **4** Send to Trash (the board-side word for the staged `.trash/` move — "Delete" stays the trash lane's). The quick-style recents row left this menu in the reshape (flagged for review; the ⌥-alternate Delete Immediately row had already retired with its command, 2026-07-30) |
| Lane | One menu, invoked on the header or lane empty space (settled — a full lane still has its header): Rename, Style…, quick-style recents row (03), Width control (stepper — menu twins Increase/Decrease Lane Width), Delete | | Lane | One menu, invoked on the header or lane empty space (settled — a full lane still has its header): Rename, Style…, quick-style recents row (03), Width control (stepper — menu twins Increase/Decrease Lane Width), Delete |
| Trash selection | Delete (permanent — 03's recoverability confirm), Reveal in Finder (inspection before a purge; twin of File ▸ Reveal in Finder, not edit-shaped, enabled on trash selections — 04 ▸ The trash) | | Trash selection | Delete (permanent — 03's recoverability confirm), Reveal in Finder (inspection before a purge; twin of File ▸ Reveal in Finder, not edit-shaped, enabled on trash selections — 04 ▸ The trash) |
| Attachment row | Open, Remove (system Trash) — twins of the focused section's grammar keys (Return / ⌫ — 05); Reveal in Finder — twin of File ▸ Reveal in Finder in its attachments-focused context; **Set as Hero / Remove Hero** (2026-08-09 — 03 ▸ Card face ▸ Hero image) — one slot with two words, present on image rows only and absent rather than greyed where neither applies; twins of the two File rows below, which address the section's *selected* row | | Attachment row | Open, Remove (system Trash) — twins of the focused section's grammar keys (Return / ⌫ — 05); Reveal in Finder — twin of File ▸ Reveal in Finder in its attachments-focused context; **Set as Hero / Remove Hero** (2026-08-09 — 03 ▸ Card face ▸ Hero image) — one slot with two words, present on image rows only and absent rather than greyed where neither applies; twins of the two File rows below, which address the section's *selected* row |