Grid layout transitions — v4 sketch (continuity) (Firewatch Camera Grid)

**Note** from Bead: Firewatch Camera Grid · [canonical source](https://redfish.acequia.io/guerin/.agents/65783732-7907-4a36-983a-3b015e75e80b/2026-06-23/notes/05-grid-layout-v4-sketch.md) · session 2026-06-23 · discussion: Talk: Firewatch Camera Grid

Sketched by Debbie (senior UX/UI). v4 builds directly on the [v3 sketch](./04-grid-layout-v3-sketch.md) — every ratified behavior is kept — and cures the one disease Stephen named in his critique. Still in the sketch-ux house style (rendered HTML/SVG, "✎ SKETCH" marker, replay-able transition, answer card → `request/` dock). **Rendered sketch:** https://redfish.acequia.io/guerin/.agents/65783732-7907-4a36-983a-3b015e75e80b/2026-06-23/artifacts/sketches/grid-layout-transitions-v4.html *(build stamp `2026-06-23` is in the top bar — freshness marker, house convention.)*

## Critique of v3 (the continuity failure, named precisely) Stephen: *"The transition slides a panel and the viewer loses continuity from the camera on the map to its position in the grid."* He is exactly right, and it is a **perceptual-identity** failure, not a layout bug: 1. **The morph slides whole panes as a block.** `layout()` moves `mapPane` and `gridPane` as rigid rectangles — the map exits left (`l: -W`) while the grid fills the stage. The eye is given a *page-turn*, not a *correspondence*. Nothing in a block-slide says "the dot in the NW of the map **is** the card in slot #1." 2. **The flyer clones help mid-flight, then vanish.** v3's `flyToGrid` does animate a clone from each frustum to its tile — but it `.remove()`s every flyer the instant the flight ends. The link exists *only during the 0.6 s of motion* and is destroyed on arrival. 3. **Once in the grid, identity is unrecoverable.** After landing there is no standing affordance that ties a card back to a map position. You cannot tell which card is which camera's viewpoint, nor where it sits in real space. **Spatial identity is lost in the cut.** That is the disease v4 must cure: preserve **perceptual continuity of each camera's identity and map-position through AND after the transition.**

## What's new in v4 - **No more block-slide for the cameras.** Cards are never carried by a sliding pane. In every fork they travel **per-card** from origin to destination (see fork A), so the motion itself encodes the correspondence. - **A standing tether overlay** (`#tether`, a full-stage SVG above both panes) that can draw a curved leader-line from each grid card to its map dot — **during and after** the morph, not just mid-flight. - **Linked-brushing both directions** — hover a card → its map dot + frustum pulse and its tether lights solid; hover a map dot (in the main map or the rail) → its card pulses. Continuity is **recoverable any time**, the cure for v3 failure #3. - **A persistent per-camera identity color** (the `hue` on each camera) shown as a ring on the map dot **and** a chip on the card **and** the tether color — so the map→card link survives even with every tether hidden (a quiet, always-on backstop). - **A live map rail** (`#maprail`) — an optional docked mini-map so you never fully leave the map (fork C). - **Motion-trails** on the deal/return flights so the path each card took stays briefly legible. - The fork picker is **live**: choosing a fork actually changes the transition + grid behavior, so Stephen can re-run ▶ and *feel* each one.

## The central question (foregrounded, answerable in-sketch) > **How is each camera's map→card identity preserved through the transition — and recoverable > afterward?** Three genuine forks, each a *transition* (not a static frame), selectable as a radio that rewires the live behavior; the answer card PUTs the choice to the handler `request/` dock as a `sketch-answer` (carrying the v3 resolutions forward in `resolved`): - **Fork A — Deal-from-position (origin-preserving motion).** The panel never slides as a block. Each card is **born at its camera's on-screen map dot** and travels a visible, staggered arc (with a fading motion-trail) to its grid slot; it reverses on the way back. *Transition:* select on 3D map → cards deal out one-by-one from their dots → land in slots. *Trade-off:* strongest at the **moment** of transition (the eye tracks origin→destination), but the link is implicit once motion stops — needs a recovery affordance to persist. - **Fork B — Standing tether / linked-brushing.** A faint hue-colored leader-line connects each card to its map dot during the morph **and stays available after**. Hover either end → the twin pulses and the tether goes bright/solid. *Transition:* morph with tethers drawn, then hover-to-recover indefinitely. *Trade-off:* continuity is **recoverable any time**, but a thicket of standing lines can get noisy at high card counts (mitigated: faint-by-default, bright-on-brush; toggle to hide all-but-brushed). - **Fork C — Always-visible map rail (co-presence).** Never fully leave the map: a thin live map strip stays docked beside the grid, and the brushed/focused card draws a live tether to its dot **in the rail**. *Transition:* grid view keeps the rail docked; brushing spans card→rail-dot. *Trade-off:* continuity by sheer co-presence (no memory load), but it **costs permanent screen real estate** and shrinks the grid.

## First-cut recommendation (posed as a fork, not a verdict) **A + B together.** Deal-from-position carries the correspondence *through* the cut (the moment of transition), and the standing tether + linked-brushing makes it *recoverable after* the cut (the resting state). They cover the two halves of Stephen's complaint — "through" and "afterward" — without either's weakness. **C (the map rail) is the heavier fallback** for dense grids where neither motion nor on-demand tethers are enough and you want permanent co-presence; it's wired live so it can be felt, but it spends real estate. The ▶ tour plays **A+B end-to-end** (deal → brush-to-recover → drag/re-flow with tethers riding along → fullscreen ⇄ panel with tethers spanning the seam → deal back to 3D); switch the live fork in the right rail to feel each alone. This is a fork to ratify, not a decision already made — the answer card sends your pick to the dock.

## Reused from v3 / the app (not regressed) - **All v3 ratified machinery:** 180°-aware auto-order + re-flow-the-rest around pinned anchors (`reflowAroundPins`), per-card un-pin via the `✋#` badge, OrientedMap glyph vocabulary on both map and tile face, the **tie-point red cast-ray read-through** onto the card, real 3D oblique selection and **return-to-3D**, segmented `Grid | 3D | Map`, fullscreen ⇄ panel modes, preserved selection + the **persistent amber TIME cursor**. - **House style** (`plume.html` / `styles.css`): dark palette `#06080d` / amber `#ffd24a` / blue `#39c0ff` / green `#2ee06a` / red `#ff2d2d`, the `✎ SKETCH` mark, segmented toggle, time strip, the `request/`-dock answer card (reused `sendAnswer()` machinery, retargeted to `grid-layout-v4` with the new continuity question/forks and the carried-forward `resolved`).

## Status First-cut (continuity fork open; v3's behaviors closed and reused, not re-litigated). The cure is *demonstrated*, not merely posed: the ▶ tour visibly preserves each camera's identity through and after the morph. Awaiting Stephen's continuity-fork choice via the `request/` dock.