feat: living tab title and favicon follow the drive
@@ -79,3 +79,11 @@ Run: `npm run build:preview` then serve `dist` (dev server shows a blank page).
|
||||
- **Verdict: SHIP** (Fable, hardware GL 1440x900 high tier, wheel-driven passes, frames every ~100 ms): the deck is big, reads as a concrete overpass (parapet, soffit, piers, three strips) and the plate is legible from mid-distance; the sign/deck hand-off is clean (the deck holds in the haze until the sign has passed, and on a brisk approach it sits behind the sign, never through it); the shade beat is one slow dip and release with no step over 22/255 in frame mean (sky band <= 45) at any of Start->Profile, Profile->Experience, Infra->Builds, Builds->Additional, Toolkit->Contact; reverse scroll re-emerges under the same deck (shade latches again, 1 s apart); brisk and nav-jump passes get the structure and no shade/sound; reduced motion renders the static poster with nothing; 1024x700 (medium) shades, 390x844 (low) shows deck+strips only; rAF p50 16.7 / p95 16.7-16.8 ms in every serial run, 0-1 frames over 34 ms, no console errors. Fixes made during review: (1) DECK_PASS_Z 30 -> 25 (the chase camera's z): the deck had gone overhead ~5% of the gap (~1 s at a slow scroll) before the HUD cut, now the cut lands ~0.5 s after 'under' sets, in the deck's shadow; (2) STRIP_GLOW 2.4 -> 1.3 and POOL_GAIN 1.6 -> 1.1: the strips crossed the 0.85 bloom threshold and washed the frame then dropped (sky band 146 -> 32 in one step at Contact), now the strips read as sodium tubes without a flash; (3) plate 11x2.75 -> 16x4.2 over the deck face + parapet, 168 px type, 14 px accent bars: 'EXIT 0N' is readable at z ~ -100 instead of only in the last 30 m; (4) pier shader: 2.6 m form lines, grime at the base and the sodium pool bouncing up the lower faces, so the close pier is poured concrete, not a flat slab.
|
||||
- **Known weaknesses:** the pier at x 16 crosses the left edge of the Selected-builds billboard (stilt at x 17) in front of it for ~6 m of travel, and one expressway lamp head pokes past the right pier at Infra->Builds (both brief, both read as foreground structure); the Contact deck is lit by the dawn sun and reads paler than the night decks (intentional, but less massive); a moderate approach walk can set data-underpass for ~50 ms once before the real pass (hidden by the 0.3 s HUD colour transition, no visible effect); the low tier never shades, so phones get the structure without the beat; `portfolio-underpass-frame` events only exist in test builds, so the review read html[data-underpass] and screencast frames instead.
|
||||
- Screenshots: docs/overnight/round9/ (01 EXIT 02 rising behind the docked sign, 02 under the deck with strips and piers, 03 EXIT 03 overhead at the cut with the amber HUD label, 04 EXIT 08 at dawn into Contact, 05 EXIT 05 pier against the Selected-builds billboard, 06 phone 390x844 low tier, 07 contact sheet of the Profile->Experience pass 20.5-25.5 s).
|
||||
|
||||
## Round 10: PARKING LIGHTS (living tab title + favicon)
|
||||
- **What:** the browser tab is part of the drive. After mount, document.title follows the route in 5% steps ("ROUTE 45% · INFRASTRUCTURE", "ARRIVED · CONTACT"), reads "PARKED · 45% · INFRASTRUCTURE" while the tab is hidden, keeps the metadata title through the ignition opening and while the scene is still coming up, hands the title to the dashcam while it is open and resumes on close. The favicon is a lazy SVG data URI: the index.html plate and 'L' plus two headlight beams that lengthen and brighten with the route in the chapter accent (SIGN_ACCENTS), two amber parking lights when the tab is hidden, gold on peach at html[data-dawn='day']. Writes are rate-limited to one per 400 ms (visibility, dashcam hand-back and the scene settling write at once). Reduced motion / static: live title, one fixed lit icon. SSR output and index.html unchanged.
|
||||
- **Why:** the drive had no presence outside the viewport; a juror with twelve tabs open sees the route resume in the tab strip, and the parked state is the last thing the site says when they look away.
|
||||
- **Build:** journey/tab-feed.ts (pure, initial chunk: title + 5% quantiser), journey/tab-icon.ts (lazy chunk, 0.67 KB gz), composables/useLivingTab.ts, AppShell.vue (one call), bundle-budgets.mjs (tab-icon chunk class). 894 tests (77 files, +22), initial JS 119.07 KB gz (+0.04 KB; **0.9 KB left**), CSS 26.78 KB gz, scene chunk unchanged.
|
||||
- **Verdict: SHIP with fixes** (Fable, hardware GL 1440x900, fresh contexts; title and link[rel=icon] observed with MutationObservers over a full drive, park/return at Contact and Infrastructure, reverse scroll, dashcam open/close, brisk 40% scroll, reduced motion, nav jumps, #contact deep link, return visit): the title steps per chapter exactly as the HUD does (5% → 90%, ARRIVED at Contact), the metadata title holds until html[data-ignition] is removed (+4.5 s on first visit, ~3.9 s on the short form), the deep link holds the metadata title until the scene is running then writes ARRIVED · CONTACT; the dashcam owns the title ("DASHCAM · 27% · INFRASTRUCTURE · 03:12") and the route title is back within the same tick the frame unmounts (no stale title after close, scroll after close steps normally); max 3 title/icon writes in any 1 s window on a brisk scroll (2.5 Hz cap holds); rAF p50 16.7 / p95 16.7-16.8 ms with 0 frames over 34 ms during the drive and the brisk scroll; no console errors or warnings, no hydration warnings. Fixes made during review: (1) **parked title read 0%**: useScrollDrive resets its snapshot to route 0 on visibilitychange (before this composable hears it) and keeps 0 for one frame after return, so the hidden tab said "PARKED · 0% · INFRASTRUCTURE" and briefly "ROUTE 0%" on return; the composable now freezes the route while hidden and re-syncs two frames after return (unit test added, two tests that had encoded the old behaviour corrected); (2) **beams invisible at tab size** in the first chapters: at 16 px the 0-20% beams were 2-4 px dots at 35-45% opacity; floor raised (beamMin 2 → 4 px, glowMin 0.35 → 0.55; max unchanged at 14 px / 0.95) so the icon reads as "lamps on" from the first write and still grows x3.5 to Contact. Judged at 16/24/32/128 px in light and dark tab strips: the 'L' reads at every size and state (dark plate on a light strip is a strong silhouette), the parked amber dots are unmistakable, the day plate is the one state that reads as a different icon at a glance (intended), chapter accents are distinct at 32 px and still tellable at 16 px for cyan vs violet vs coral (pink vs coral is a near miss at 16 px).
|
||||
- **Known weaknesses:** at 16 px the accent is a tint on a 4-14 px smear, so the chapter colour is a subliminal cue rather than a readable signal; the dashcam title shows the raw percentage (27%) while the tab shows the quantised one (25%), two vocabularies for two seconds; pink is shared by Start/Profile/Additional work (SIGN_ACCENTS), so those chapters are told apart only by the beam length; headless Chromium cannot hide a tab, so the parked states were driven by dispatching visibilitychange with document.visibilityState overridden (the unit test does the same); under that emulation the scene loop paused and did not resume (html[data-dawn] stayed 'day' through the reverse drive in the timeline sheet), which a run without the emulation does not show (dawn rewinds to night at Infrastructure in ~1.6 s) — a real tab switch should be checked once by hand; under reduced motion SceneCanvas rewrites html[data-dawn] every frame (pre-existing), which fires this composable's MutationObserver at 60 Hz for a cheap no-op; return visits open at route 0 with the short ignition (route memory does not restore the scroll position, pre-existing).
|
||||
- Screenshots: docs/overnight/round10/ (00-05 favicon contact sheets from the build; 06 favicon states at 128/32/24/16 px in light and dark tab strips; 07 observed title + favicon timeline over the 35 s review drive, every title write with the icon it shipped with; 09 ignition with the metadata title and the index.html icon held; 11 tab hidden at Infrastructure, "PARKED · 25%" with amber lights; 12 dashcam owning the title; 13 END OF SHIFT, gold on peach).
|
||||
|
||||
BIN
docs/overnight/round10/00-contact-sheet.webp
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
docs/overnight/round10/01-route-0-start.webp
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
docs/overnight/round10/02-route-50-infrastructure.webp
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
docs/overnight/round10/03-route-100-contact.webp
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
docs/overnight/round10/04-parked-50.webp
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
docs/overnight/round10/05-dawn-arrived.webp
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
docs/overnight/round10/06-favicon-states-tab-size.webp
Normal file
|
After Width: | Height: | Size: 143 KiB |
BIN
docs/overnight/round10/07-title-timeline-drive.webp
Normal file
|
After Width: | Height: | Size: 276 KiB |
BIN
docs/overnight/round10/09-ignition-metadata-title.webp
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
docs/overnight/round10/11-parked-infrastructure.webp
Normal file
|
After Width: | Height: | Size: 158 KiB |
BIN
docs/overnight/round10/12-dashcam-owns-title.webp
Normal file
|
After Width: | Height: | Size: 158 KiB |
BIN
docs/overnight/round10/13-dawn-arrived-gold-on-peach.webp
Normal file
|
After Width: | Height: | Size: 134 KiB |