+- **The camera view is a plan, like the storage and printer boards.** Cameras are placed by hand on a surface you pan and zoom instead of flowing in a grid, and they are RESIZED FREELY by a corner grip — the ½× / 1× / 2× presets are gone, three answers to a question the user can now answer exactly. A camera's width travels with its position (`camWallPlan: {x, y, z, w}`, its own field because the printer board's camera widget already owns `camPlan` and the two are placed independently); only the width is stored, since the picture is 16:9 and the head is fixed, so one number describes the card. It has an **Arrange mode**: the storage plan's own 24 px mesh scaled by the zoom, a card's HEAD as a handle in both modes (it is the part that is not the picture, so taking hold of it can never be read as a click on the video), and arranging extends the handle to the whole card while giving the LEFT BUTTON to the rubber band — sweeping and panning both start on empty surface, so one has to yield, and arranging is precisely when you mean to pick cards rather than travel; the wheel button pans in both modes, so the view is never trapped. Its plan bar is the other plans' bar to the character — same classes, same order, same numeric field with its own `%` beside it — and its zoom is their zoom down to the arithmetic: same bounds, same round-ten ladder, the point under the cursor held still, wheel with no modifier, stray notches from a held-down wheel ignored. Dragging uses the storage plan's magnetism and its guides, the grabbed card being the one the magnetism speaks for while the rest of a group follow at their own offsets; the mesh appears the moment anything is taken or resized, in or out of Arrange, because outside it nothing else says a gesture has become an edit. A card taken in the hand comes to the FRONT and dropped last stays on top — depth is written inline by the layout, which no stylesheet rule can outrank, so the lift is done on the element and restored from the record on release. A swept selection is ringed in the accent, 2 px at the boards' offset, written as one ordered block carrying the view's id because the plain border arranging draws also carries it and silently outranked the selection at lower weight. Moving a camera no longer opens its machine's side panel: arranging suppresses it outright, and outside it the guard goes up the instant the gesture becomes a move — raised on release it was raised after the writes were awaited, and the click following a release fires long before a round-trip to Firestore resolves. Widths are applied in their own pass before any position is computed, since the free-spot search MEASURES a card to find room for it and a card not yet given its width measures whatever the stylesheet last left it. ONE RULE GOVERNS IT: a card holds a live stream, so it is never recreated, only moved — every path positions existing elements, the drag writes the element and only the release touches the record. The drag-to-reorder went with the grid it served; `camSortIndex` now only orders cameras that have never been placed, on their first render. **A placed camera keeps its place when its machine goes quiet** — same spot, same size, dimmed and empty, still movable and resizable; only a camera never placed is absent, there being nothing of it to preserve — `renderer/inventory.js`, `renderer/css/40-printers.css`.
0 commit comments