Resolve the second design-review batch and drop the face carousel

Rulings written in place: the drop settle yields to the system drag session
(fly-to-slot deferred to WISHLIST #7) and the held proposal's home is the
app-wide DragSession — rendering the arrangement means rendering the card at
release (03, 02); folder drops refuse at hover with loss-row reporting, created
cards land positionally, N shadows, header resolves topmost, shadow-only
feedback (04); the banner vocabulary gains the warning-tone loss row class
(02); all user-initiated creation clears the search (04); loose files beside a
card's index.md relocate into attachments/ with notice — files-only carve-out,
paste normalizes at the boundary, the agent guide teaches it (01, 04, 08);
dropping a card on the shown trash deletes it, shadow pinned topmost (04);
query-emptied lanes keep their slot, the out-transition stays reachable, an
open rename survives the filter, pasteboard staleness accepted (04).

The face carousel does not carry over: the pathfinder's selection-keyed dual
presentation proved undesirable — one presentation per card, selection changes
styling never geometry; the attachment chip and the card window are the whole
media story (03, 01, 10, 11; the same-day carousel settlements superseded on
their Resolved cards).

Claude-Session: https://claude.ai/code/session_01CqjXB7ASoWtbyoGod68k97
This commit is contained in:
2026-07-28 07:22:48 -04:00
parent bf18512abc
commit 88364b20c0
8 changed files with 19 additions and 14 deletions
+2 -2
View File
@@ -26,7 +26,7 @@ Toolbars are **pure enhancement**: every function they host already has a menu i
- Leading icon + title. The only face chip in scope is **attachments** (a quiet indicator when the card has files — the title dominates). Metadata chips (labels/assignees/due) went to the enhanced schema with their fields — out of scope.
- **No body excerpt** (settled): the face stays title-only — the old "iterate on the card face later" item is closed with no growth.
- **Titles are optional at every level.** On cards and lanes, a missing `title` renders as a quiet placeholder ("Untitled", secondary styling) wherever the title would appear. On boards, the fallback is the folder name (sans extension), never "Untitled" — see 01-storage-format.md's board-naming rule; window title and welcome recents show `title` when present, folder name otherwise.
- Attachments: **the sole selected card** shows the paged media carousel when it has attachments (the pathfinder's selection-keyed in-place expansion, minus its body blurb — no body excerpt, above). Single selection only: multi-selections and unselected cards stay compact, and the expansion animates under the selection-keyed transaction (Motion below). QuickLook thumbnails for anything previewable, Finder icon fallback, page dots on a glass underlay, paged by trackpad pan / dot click / scroll wheel.
- Attachments on the face: **the chip only — there is no face carousel** (resettled 2026-07-28, reversing the carry-over): the pathfinder's selection-keyed in-place expansion — compact unselected, media carousel when sole-selected — **proved undesirable and does not carry over**. A card has **one presentation**: selection changes styling (the selection treatment), never geometry, so the masonry never reflows on click and a card face is the same object whatever the selection state. The attachment chip above is the face's whole attachment story; viewing media is the card window's job (⌘↩ / double-click — the attachments section and QuickLook, 05-card-window.md). The earlier 2026-07-28 carousel settlements (metrics, tick paging, clamp, dots, marquee suppression, trash exclusion) are superseded with it — recorded on their Resolved cards.
## Styling
@@ -101,7 +101,7 @@ The pathfinder's animation behavior carries over as the committed motion languag
- **Equivalent operations share one dialect.** Paste animates exactly like a drop commit (same curve, same duration) so the clipboard's move story *feels* like drag landing; keyboard one-slot moves slide for the same reason a drop does — an item that teleports is harder to follow than one that slides; cut dims the card in place, Finder-style, until paste moves it (04-interactions.md).
- **Appear/disappear is scale + fade** (cards scale from ~0.8, lanes ~0.9, combined with opacity). A restore that moves a card across lanes flies it from old frame to new via matched geometry. Search-hiding rides the same structural transition — hiding is removal, not a special fade.
- **Some things deliberately never animate**: the rubber-band marquee tracks the cursor 1:1 (an eased band visibly lags the mouse), and the selection highlight rides whatever transaction is active rather than easing on its own.
- **Animated transactions are keyed narrowly** — on the sole-selected card (carousel expansion), on the search query (filter reflow), on the drag's **drop proposal** (the reflow-to-make-room above animates under it, ~0.18 s) — never on broad state like the selection set. What stays animation-free by construction rather than by suppression: the drag replica's tracking and the marquee rectangle (1:1 cursor following — animating input echo would be lag), and multi-select churn. **The replica's bracketing transitions do animate** (settled): the pickup lift (scale + shadow as it detaches from the card) and the release — fly-to-slot on drop, fly-back on cancel — are ordinary structural-voice springs; only the tracking between them is verbatim input echo. **The settle holds the drop proposal until the echo lands** (settled — the one-way flow means the write is still in flight at release, and a snapshot-order re-render would glide the dragged item back before the reload animates it forward again): the proposal survives release as overlay state in TransientBoardState (02-architecture.md — the placeholder's kin), the board keeps rendering the proposed arrangement, the replica flies to the slot the proposal holds open, and the proposal discards itself when the bracket's echo reload lands — positions already match, so the handoff moves nothing. A **failed write discards the proposal** and the board animates back to snapshot order with the ordinary one-shot banner — the width-drag rollback posture (the action visibly doesn't happen); a foreign reload that vanishes the dragged item discards it too (02-architecture.md's constraint rule).
- **Animated transactions are keyed narrowly** — on the search query (filter reflow) and on the drag's **drop proposal** (the reflow-to-make-room above animates under it, ~0.18 s) — never on broad state like the selection set (selection changes styling only, never geometry — Card face above, the no-carousel resettlement). What stays animation-free by construction rather than by suppression: the drag replica's tracking and the marquee rectangle (1:1 cursor following — animating input echo would be lag), and multi-select churn. **The replica's bracketing transitions do animate** (settled): the pickup lift (scale + shadow as it detaches from the card) and the cancel fly-back are the system drag session's own behaviors and match the spec verbatim; only the tracking between them is verbatim input echo. **The drop settle is the board's, not the replica's** (resettled 2026-07-28 — drags are system `NSItemProvider` sessions, required for cross-board transfer and the copy badge, and a successful drop's drag image has no fly-to-slot hook, only AppKit's brief fade): at release the held overlay (below) renders the dropped arrangement instantly while the system fade dissolves the drag image over it — the item is in its slot the moment the mouse releases, which is the promise that matters. A custom fly-to-slot animator (shadow-window replica, masked system fade) remains a deliberate later upgrade, not a commitment (WISHLIST). **The settle holds the drop proposal until the echo lands** (settled — the one-way flow means the write is still in flight at release, and a snapshot-order re-render would glide the dragged item back before the reload animates it forward again): the proposal survives release as overlay state in the app-wide DragSession (02-architecture.md — the placeholder's kin in semantics; app-wide in home because a drag crosses boards), the board keeps rendering the proposed arrangement under the system fade (the drop settle above) — and **rendering the arrangement means rendering the card**: at release the shadow is replaced by the dropped card(s) drawn in place immediately, the appear never waiting for the echo (a lingering shadow over a hidden card is the hold failing its one job) — and the proposal discards itself when the bracket's echo reload lands — positions already match, so the handoff moves nothing. A **failed write discards the proposal** and the board animates back to snapshot order with the ordinary one-shot banner — the width-drag rollback posture (the action visibly doesn't happen); a foreign reload that vanishes the dragged item discards it too (02-architecture.md's constraint rule).
- **Motion never feeds back into logic** (the pathfinder's animation-proof-inputs rule, kept as a hard constraint): drop-proposal math reads analytically computed resting zones, the physical mouse position, and item sizes frozen at drag start — never mid-flight measured frames, which are garbage precisely during the ~0.2 s reflow they trigger.
- **Reduce Motion is a rewrite obligation, not an inheritance**: the pathfinder ships zero reduced variants; 10-accessibility.md's commitments (crossfade or instant for reflow, search animate-out, the drag replica's lift and settle, the lane-resize rubber-band feedback, trash) are new work.