Grid layout transitions — sketch (firewatch-camera-grid) (Firewatch Camera Grid)

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

Sketched by Debbie (senior UX/UI). Per Buxton, interaction design lives in the *transition*, not the static frames — so for a layout-morph feature the animated before → action → after **is** the deliverable. This is a deliberately low-fidelity, rendered sketch (house style, "✎ SKETCH" marker): engage the questions, don't nitpick pixels. **Rendered sketch:** https://redfish.acequia.io/guerin/.agents/65783732-7907-4a36-983a-3b015e75e80b/2026-06-22/artifacts/sketches/grid-layout-transitions.html It runs a single morphing "stage" with a segmented **Grid | 3D | Map** toggle, a **▶ tour** that plays the full arc (A→B→C→B→D→B→A) both directions, and a shared time-cursor on a timeline strip that survives every transition. Each design question on the right rail morphs the stage to demonstrate its fork, then PUTs your choice to `request/`.

## The four states - **A — split:** camera grid on the LEFT; 3D world (top) + 2D map (bottom) on the right. - **B — fullscreen grid:** grid expands to fill the stage; the two right panes park offstage. - **C — 3D engine:** the 3D world fills the stage showing camera **poses** — blue frustum wedges, green dashed centerlines, a red projection ray on the selected camera, white dots (the OrientedMap glyph vocabulary). - **D — 2D map:** the same glyphs flattened top-down fill the stage.

## The design questions (answerable in the sketch) 1. **Transition style — spatial morph vs cross-fade.** Forks: *Spatial morph* / *Cross-fade*. Transition shown: A→B→C with panes either resizing/sliding (object continuity) or snapping with only opacity tweening. Least-action: the spatial-morph fork is the existing grid⇄map flex-collapse (`map-closed`/`panel-closed`) generalized to four panes — reuses what the app already does. 2. **Fullscreen grid — distinct mode vs collapsed split.** Forks: *Distinct mode* / *Collapsed split*. Transition: A→B. Least-action: "collapsed split" is literally today's `mapToggle`/`mapReopen` (right column width→0, `.grid-panel` to 100%); no new mode machinery. 3. **Grid → 3D — fly the tile into its frustum vs cross-fade the scene.** Forks: *Fly tile→frustum* / *Cross-fade scene*. Transition: a shared-element clone of the selected tile flies from the grid onto its frustum apex in the 3D world (tilts into perspective, fades). This is the one transition that *ties grid↔3D into one object* and reuses the OrientedMap pose for the landing target — the most expressive and the one I'd protect. 4. **What triggers the switch — segmented toggle vs click-a-tile vs gesture.** Forks: *Segmented toggle* / *Click a tile* / *Gesture*. Transition: clicking a tile dives straight into 3D (combines with Q3's fly); the toggle is the explicit, discoverable path. Least-action: the segmented control is the same pattern as the existing panel toggles; "click a tile" reuses the tile selection that already exists. 5. **State on "back" — preserve vs reset.** Forks: *Preserve* / *Reset*. Transition: C→A, either keeping the selected camera + time-cursor or snapping back to defaults. Least-action: the shared time-cursor and `selId` are already single sources of truth; "preserve" is the cheaper, more coherent default and keeps continuity with the timeline.

## Which to prototype first **Q3 (fly tile → frustum), in the spatial-morph idiom (Q1).** It is the load-bearing idea — it makes the grid and the 3D world feel like one space rather than two viewers, and it directly exercises the OrientedMap pose glyphs the app already renders. Settle Q1=morph and Q3=fly first; Q2/Q4/Q5 then fall out as cheap reuses of existing collapse/toggle/selection behavior. The questions are answerable inside the sketch and post to `request/`.

## Decisions **Ratified by Stephen 2026-06-23** — drained from the `request/` dock by Debbie (a bead-step); `response/<id>` acks written; logged in the [sketch-log](https://redfish.acequia.io/skills/sketch-ux/sketch-log.md). | Q | Decision | Notes (Stephen, verbatim where quoted) | |---|---|---| | 1 · Transition style | **Spatial morph** | *"start from 2d and 3d map where i select some cameras with mouse and touch and then the camera frustums transition to their place in the grid and returns again back to 2d or 3d. also being able to rearrange the grid cards."* → expands the fly into a **select-on-map → assemble-grid → return** loop, plus **rearrangeable cards**. | | 2 · Fullscreen grid | **Distinct mode** | fullscreen = switch between **two full screens (grid ⇄ map), no side panels**; **plus** a transition **to/from panel mode** and back. | | 3 · Grid → 3D | **Fly tile→frustum** | *"definitely fly to."* **3D relative camera geometry can determine grid layout.** Respect the cinematography rule = the **180° rule** (the *axis* / *line of action*; crossing it = "crossing the line"): order grid cards so a fly-to never crosses the axis. | | 4 · Switch trigger | **Segmented toggle** (provisional) | *"button toggle for now. we can play with it for a while and maybe revisit."* click-a-tile / gesture stay forkable later. | | 5 · State on "back" | **Preserve** | selected camera + time-cursor survive every transition (`selId` + master clock = single sources of truth). | ### v2 sketch brief (follows from the decisions) A revised sketch should show: **2D/3D map → select cameras (mouse + touch) → their frustums fly into a grid → return to map**, with **rearrangeable grid cards**, **grid⇄map fullscreen** + **to/from panel mode**, a **segmented toggle**, **preserved** selection/time, and **grid ordering that respects the 180° rule** (derived from the cameras' relative 3D geometry). Open sub-question for Stephen: should card order be *auto-derived* from the 3D axis, *manually rearrangeable*, or both (auto, then hand-tweak)?