Three curated symbol vocabularies — boards, lanes, and cards each pick from their own shelf
`CuratedSymbols` was one flat ~65-glyph list serving every style-editor target alike. It is now three level-specific sets — `boards` (project/container/identity), `lanes` (workflow/stage/status), `cards` (work-item/content) — each ~30-40 entries, seeded from the original list and `SymbolPickerCatalog.defaultSet`, reorganized by which level a glyph actually reads as being about. Overlap is kept where a glyph genuinely fits everywhere (`flag`, `star`). Wiring: - `BoardInfoPopover`'s board-glyph `SymbolPicker` now passes `CuratedSymbols.availableBoards` instead of the picker's domain-agnostic default. - The card sidebar's `SymbolPicker` (`CardSidebarSections`) now passes `CuratedSymbols.availableCards` instead of the old flat `available`. - The style editor's own curated grid (`StyleEditorView`, the Style… popover's only remaining anchor) reads `CuratedSymbols.availableForStyleEditor(level:spansLevels:)`: a homogeneous target reads its own level's set, and a target that somehow spans more than one level (today unreachable — 04-interactions.md's cards-XOR-lanes rule keeps a live selection homogeneous) reads the three combined, via a new `BoardStore.styleTargetSpansLevels` seam that asks the question `styleLevel(of:)` deliberately collapses. - `CuratedSymbols.combined` (the three sets' stable-order union) also replaces the old `.all` in `SymbolPickerCatalog`'s full-catalog fallback. - `SymbolPickerCatalog.defaultSet` is kept as the fallback for a caller naming no level (a future saved-search picker, say) rather than retired. DESIGN/03-board-ui.md and DESIGN/05-card-window.md's Styling/sidebar prose amended minimally where they named "the curated set" as a single list. Tests: three new/rewritten suites in KanbanTests/StyleModelTests.swift (set shape, availability, overlap, `combined`, the style-editor level/span decision, the board-anchor width tripwire), one new test in KanbanTests/StyleWriteTests.swift (`styleTargetSpansLevels`), and the old single-list-pinning tests in KanbanTests/SymbolPickerTests.swift and KanbanTests/CardSidebarTests.swift updated to the new set names. 2834 tests, 487 suites green (KanbanTests, arm64); one unrelated flaky failure (RootRecoveryTests.vanishAndReturn under full-suite load) passed clean in isolation. Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
@@ -43,10 +43,10 @@ Toolbars are **pure enhancement**: every function they host already has a menu i
|
||||
|
||||
### 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 `CuratedSymbols` grid, 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 symbol grid**: a hand-picked set (roughly five dozen kanban-relevant SF Symbols); 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 (~30–40 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.)
|
||||
- **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.
|
||||
- **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.
|
||||
|
||||
Reference in New Issue
Block a user