# Overnight log Branch `redesign/overnight`, forked from `redesign/award-worthy` (96ef776, frozen). Deadline 09:00 UTC 2026-10-11. Rules: one substantial move per round, commit per round, don't revisit a topic touched in the last 3 rounds. Run: `npm run build:preview` then serve `dist` (dev server shows a blank page). Node 22.22.1. ## Baseline - 688 vitest tests pass at fork. ## Round 1: The 03:12 Window (Infrastructure) - **What:** scroll-driven maintenance window across the Infrastructure chapter. HUD sub-line ("MAINTENANCE WINDOW · 03:12" -> BACKUP -> CONVERT · TRANSFER -> VERIFY -> "CUTOVER OK · 03:51", "ROLLBACK CHECKPOINT" on reverse scroll), storm sky tint, soft capped lightning (<=0.31 Hz, >=2.8 s apart), district power-down/relight, amber backup packets to a far "offsite" block, rain on the lens (LensFinishPass uRain), diagram nodes 01-04 lighting per step. Progress is scroll-driven, so scrolling back is a rollback. - **Why:** makes the "night shift" idea literal and dramatises the real Nextcloud migration (backups, convert, transfer, verify, cutover) with no invented copy. Closes the gaps "Infrastructure has no world beat" and "no rain / sky event". - **Build:** src/journey/maintenance-progress.ts, src/scene/world/maintenance-window.ts, useMaintenanceWindow.ts, maintenance.css; edits in environment, districts, palette, cinematic-grade, JourneyHud, AppShell. Reduced motion/static: no scene, diagram and sub-line still step. Low tier: dim/relight only. - **Verdict: KEEP with fixes** (Fable review on hardware GL, 1440 and 390): storm tint and lightning strengthened, clock holds 03:51 to end of chapter, phone sub-line fits. 709 tests green (+21), budgets clean (initial JS 111.7 KB gz, scene chunk +6.9 KB). - **Known weakness:** the reading panel covers the scene during p 0.1-0.75, so district power-down, packets and offsite are barely visible; relight uses the normal accent so the payoff reads as "back to normal". Audio rain bed skipped. Do not revisit before round 5. - Screenshots: docs/overnight/round1/ (before-* vs p*-1440/390). ## Round 2: High Beam (hero, road, plates) - **What:** the cursor steers the headlights. Fine-pointer hero name first paints as an outline, a 1.6 s sweep lights it, then a pointer-following halo lights the letters, plate edges and sparks; in the world the road cones yaw, terrain/districts catch the light, a warm SpotLight rakes the truss (high/medium), and a haze cone shows in the gaps between chapters. Click hero/gantry window flashes (rate-limited). Idle 4 s returns to centre. Touch/low tier: slow sway and tap flash only. Reduced motion: no effect, name stays lit. - **Why:** first thing a juror does is move the mouse; the hero had no pointer response and the scene none at all (direction.md signature moment 3, never built). Lives where round 1 said drama should: hero, gaps, panel edges. - **Build:** src/journey/headlight-beam.ts, useHeadlightBeam.ts, scene/world/headlights.ts, styles/headlight.css; beam terms in road, districts, terrain shaders. Initial JS +1.3 KB gz (113.0), 732 tests green. - **Verdict: KEEP with fixes.** Fable found the DOM half dead on delivery (NaN sentinel), fixed it, removed a drop-shadow rectangle artefact, raised the resting level. Frame times unchanged (p95 16.7 ms on hardware GL). - **Known weaknesses:** the outline-to-lit sweep beat is short (~300 ms visible); haze cone slightly flat/white; spark boost barely perceptible. - Screenshots: docs/overnight/round2/. ## Round 3: End of Shift (Contact daybreak finale) - **What:** arriving at Contact turns the night into dawn over 7 s: sky mauve/peach, stars drain, sun lifts and becomes a solid gold disc, warm rim light on road/terrain/districts, warm grade and bloom, bars warm, credit types at sunrise, HUD "END OF SHIFT · 05:48" (the joke: round 1's window ended 03:51), and a synthesized four-voice dawn pad (new mixer `dawnInput`) swells. Scrolling back rewinds in ~1.6 s. html[data-dawn] steps night/first-light/sunrise/day. Reduced motion/static: CSS-only daybreak gradient. - **Why:** the ending was engine-off but still night with a sun that never moved; the finale is the last impression, and the plumbing (sun, meteors, outroProgress, palette) was already there. - **Build:** src/journey/dawn.ts, scene/world/dawn-light.ts, audio/dawn-resolve.ts; edits in palette, environment, sun, atmosphere, horizon-air, road/terrain/districts, cinematic-grade, post-processing, adaptive-mixer, soundtrack-engine, world.css. 746 tests green, initial JS +0.7 KB gz, scene chunk +1.2 KB, outro frame times unchanged on hardware GL. - **Verdict: KEEP with fixes** (Fable): the sun/halo stack washed out to a white blob, so the sun is now gold with a smaller halo; the "DESTINATION" eyebrow was invisible on the peach sky, darkened at sunrise. - **Known weaknesses:** the "SHIFT OVER" label swap is invisible (HUD arrival label collapsed); the bottom credit is mostly hidden by the Contact panel (pre-existing); horizon still bright at full day; reduced-motion version reads as dusk rather than sunrise; audio checked by code review only. - Screenshots: docs/overnight/round3/. ## Round 4: Mile Markers (Profile + Experience) - **What:** the gantry HUD subline becomes a scroll-driven ROUTE LOG odometer ("LOG 02/04 · JUN 2025 → AUG 2025 · CCF", digit roll, " · REWIND" on reverse), and lit kilometre posts with accent plates and warm light pools come down the free shoulder, one per role/fact, flashing as their plate crosses the activation line. - **Why:** Profile and Experience were the only chapters with no world beat and left half the viewport empty. Career dates are real content, parsed from the JSON, nothing invented. - **Build:** src/journey/route-log.ts, useRouteLog.ts, scene/world/milestones.ts, styles/route-log.css; generalised maintenance-progress helpers. 766 tests green, initial JS +1.25 KB gz (115.9 of 120 - **budget nearly spent, keep DOM-side additions tiny**). - **Verdict: KEEP with fixes** (Fable): the delivered 0.18 x 2.6 m posts were 25 px specks at 80 m, so they were scaled to the ~2.3x world (0.4 x 6.4 m, 2.2 x 1.0 m plate), the pass point moved to z -12 to coincide with the tick, additive light pools added, and the phone subline overflow fixed. - **Known weaknesses:** the free side is narrow because of the camera frame shift, so the big pass is brief; plates read mostly white under tonemapping; no lit number glyphs on the plates. - Screenshots: docs/overnight/round4/. ## Round 5: Drive-In (Selected builds billboard) - **What:** a floodlit roadside billboard (22 x 15 m, right shoulder) carries the case-study media in the world: medication tracker triptych, opinion-dynamics chart pair, footy-tracker typographic plate. Floods relight per project as scroll passes each case study (reverse runs backwards), light spill on the shoulder, hover on a gallery image zooms that shot onto the board, floods breathe with the bass pulse. Reduced motion/static: CSS flood gradient on the active gallery. - **Why:** Selected builds hold the only real proof and had no world beat; DOM evidence and scene now share one object. - **Build:** scene/world/billboard.ts, journey/billboard-progress.ts + billboard-feed.ts, useBillboard.ts, billboard.css. 786 tests, initial JS 116.5 KB gz (**3.5 KB left**), scene chunk ~210 KB. - **Verdict: KEEP with fixes** (Fable, hardware GL): the delivered board was an 80 px speck, so it was rebuilt at 2.4x, moved to x 24, lit at chapter entry, floods widened, charts dimmed so bloom does not blow them out; narrow-viewport placement added. - **Known weaknesses:** the 92%-wide panel hides the board while reading (visible at chapter entry, in gaps between case studies and at exit); phone screenshots read dim; ~140 px on phones; test-only telemetry. - Screenshots: docs/overnight/round5/.