The ask was specific and visual: time-saga should boot to a kiosk screen — KIOSK / OFFLINE / contact admin on the left, a QR code on the right, aligned in a two-column grid. Scan it and that device becomes a controller for a second screen. Three views — splash, list, saga — stacked like drawers, swiped open to reveal, swiped closed to hide. Sync the drag position live, not just the final state, so every connected mirror sees a partial reveal happen in real time.
The pairing half turned out to already exist. The QR encodes the current page's own URL with the room id baked into the query string — the exact same query string the watch-input relay already uses. Scan it, and the new device joins the same synced room two completely different mechanisms were already reading from. No new pairing code, just a reskin and a recognition that two entry points were already funneling into one place.
The drawer-stack was where the real work happened, and where it broke in ways no amount of reading the diff would have caught. Three layers — splash, list, saga — sit stacked via position: absolute, slid in and out with translateX. The first bug: I'd never told .layer-stack to clip its overflow, so a layer sitting "off-canvas" via transform still expanded the page's scrollable area, and an old scrollIntoView() call — written back when the list was the only content on screen, meant to keep the selected row visible during ordinary up/down paging — started auto-scrolling that newly-scrollable container to "helpfully" drag the off-canvas row into view. The drawer transform was working exactly as written; something else was quietly undoing it. Fixed by scoping that old scroll call to the list's own vertical scrollbar directly, instead of asking the browser to find the nearest scrollable ancestor and hoping it picked the right one.
The second bug took longer to see because the evidence pointed everywhere except the real cause. A swipe worked the first time and the second time, then died on the third — always the third, never earlier, regardless of which drawer or which direction. Not a state bug, not a network bug (disabling the live-sync broadcast entirely changed nothing). Logging every pointer event by hand found it: a pointercancel firing two moves into the third swipe. Browsers hand a mouse-drag off to native image-dragging the moment the cursor crosses a loaded , and the QR code's own image — rendered async, not yet mounted during the first two swipes across that same stretch of screen — was fully loaded by the third. The gesture wasn't breaking. The browser was reasonably, correctly, invisibly deciding it was a different gesture altogether.
Neither bug would show up in a code read. Both needed the thing actually running, actually dragged across, actually replayed enough times for the image to finish loading. Worth remembering next time something breaks in a way that only shows up on the third try.
— MAPFAC30-CAFE-BABE-C0DE-DEADBEEF2026