Build the full-visibility lane layout

The lane strip replaces the placeholder board: window width divides
across the lanes' width units (no horizontal scroll, no minimum width,
degenerate compression accepted), a lane of n units flowing its cards
into n round-robin masonry columns via a measurement-cached Layout.
Width has two deliberately opposite controls, both landing here: the
right-edge drag (ported verbatim from the pathfinder's ColumnResize)
freezes the 1x standard at drag start, snaps between integer widths
with the asymmetric shadow-leads tick and 10pt re-entry, grows the
window one standard width per snap so siblings keep their exact
pixels, and rubber-bands at the screen's visible frame — uncapped
otherwise; the Increase/Decrease Lane Width items (new Board menu,
Cmd-Opt-arrows) are the stepper's keyboard face and re-divide the
existing window width instead, never touching the window. Width
changes write through the new .resize WriteOperation ("Couldn't
resize…" in the banner vocabulary, which grows with the surfaces by
design); malformed width values render as one unit and stay untouched
on disk. 27 new tests port the pathfinder's resize-math suite onto
the uncapped range and pin the write path's fidelity.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
2026-07-27 08:16:14 -04:00
parent fccdf56cf4
commit ff3ba298f0
15 changed files with 1427 additions and 56 deletions
+8 -1
View File
@@ -99,7 +99,7 @@ struct KanbanApp: App {
}
}
/// The two menu items this milestone owns.
/// The menu items the app has built so far.
///
/// **The titles are API** (04-interactions.md Configurable bindings): macOS's App Shortcuts
/// mechanism remaps menu items *by title*, so these strings are the keys a user's custom binding
@@ -114,6 +114,13 @@ struct KanbanApp: App {
.keyboardShortcut("o", modifiers: .command)
}
// The Board menu (11-command-nexus.md). Its items act on the frontmost board window, which
// they reach through the focus system rather than through the app model see
// `LaneWidthCommands`, which also owns their validation.
CommandMenu("Board") {
LaneWidthCommands()
}
CommandGroup(after: .windowList) {
// No default chord " (no default)" in the Nexus is deliberate, not a gap; it remaps
// like any other item.