Build the card window shell and lifecycle

The m4 scene plumbing was already honest — one WindowGroup value per
CardWindowRef enforces one-window-per-card, and CardWindowFate's
ancestor walk answered dismissal — so this card fills the window: a
two-column shell whose body column takes all resize flex and whose
sidebar width derives once from font metrics (26 characters of average
body advance plus em gutters), the five 05-ordered section headers as
placeholders, and the card body as selectable plain text until Preview
mode lands. The fate walk now returns a CardPlacement (card + lane), so
one pass answers both liveness and the live board › lane subtitle; a
board rename lands for free through displayName. Card windows remember
their frames per card in the board record (case-folded id keys,
unchanged-writes-nothing), restoring instead of cascading; only
unremembered cards take the last-used size and cascade. Store
acquisition stays gated on liveStore — a card window never opens a
board — and the close-flush hook stands with nothing to flush until the
Edit-session card.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
2026-07-28 09:27:01 -04:00
parent af1860debf
commit 1e65b7c986
8 changed files with 706 additions and 34 deletions
+5
View File
@@ -113,6 +113,11 @@ struct KanbanApp: App {
}
.restorationBehavior(.disabled)
.defaultLaunchBehavior(.suppressed)
// The **first** card window's size, and only that one: every later window opens at the
// last-used size or at its card's remembered frame, both applied by the host as the window
// attaches (05-card-window.md Window). Derived from font metrics like every other
// measurement in that window rather than written down in points.
.defaultSize(CardWindowMetrics.defaultSize(bodyPointSize: CardWindowMetrics.bodyPointSize))
Settings {
SettingsView()