docs: record the round 5 review pass, evidence and test results

This commit is contained in:
2026-10-11 00:13:05 +03:00
parent 2cbf42f7f8
commit 4ff42288a8
11 changed files with 206 additions and 0 deletions

View File

@@ -143,3 +143,209 @@ preview build on a headed GPU Chromium. They are in `docs/redesign/round5/`.
| --- | --- | --- | --- | --- | --- |
| Before | 70.1 | 82.6 | 83.8 | 81.8 | 87.2 |
| After | 68.7 | 83.5 | 79.7 | 83.7 | 95.1 |
## Design review pass (Fable)
A design consultant reviewed the first pass. Its calls were adopted, except
where noted under "Deviations". Evidence is in `docs/redesign/round5/`.
### The sign interlude (items 5, 6)
- **Sequence.**
- The reading plates step aside: 260 ms in-quart, rising 24 px. Headings
fade only.
- The road and the sign then have the frame to themselves. The sign
hangs from a 3D gantry truss, about 600 px wide in the upper third.
- It lifts off the truss and arcs into the window, landing within 2 px
(unit tested). The truss passes overhead as it docks.
- The plates rise back with a 90 ms stagger (720 ms out-expo).
- The whole sequence is driven by `html[data-interlude]` (`on`, then
`rise`), which the scene loop owns.
- **Window.**
- At 1280 px and wider it is 320x72, with an 8 px bulge in the beam.
- The rails sit at 40%.
- An amber cone of light falls below the window.
- **Docked.**
- The 3D face hands off in 200 ms to a flat 2D plate. The plate mirrors
the face: tab, label fitted like the canvas, and lane rule. So the
handoff lands in place (`window-handoff-1440.webp`).
- Hover brings back the 3D twin, which leans at most about 4 degrees,
with a "DRIVE TO EXIT NN →" label (`window-hover-1440.webp`).
- **Skips.**
- Fast scrolling: brisk latches skip the interlude.
- A hash load or back/forward lands docked without replaying.
- Reduced motion: no scene and no interlude. The plates simply change.
- **Measured at 1440 (nav click).**
- Plates hidden from 340 to 1246 ms, rise until 2355 ms, idle at 3388 ms.
- About 1.9 s with the rise, against the brief's ~1.4 s. This was kept
so the arc stays readable.
- A wheel crossing triggers the interlude.
- A 2500 px jump shows no sign.
### Top bar and controls (items 4, 8)
- **Layout.** Brand | exits 01–04 | window | exits 05–08 | bay.
- **Window plate.**
- It shows the current exit tab in the sign colour, the chapter, a route
rule, and a chevron breathing at 0.5 Hz.
- At the destination the chevron reads "AGAIN ↺", and the window drives
back to the start.
- **Exit lamps.**
- The current exit lamp carries an 18 px ghost swatch in the sign colour.
- The NEXT EXIT plaques and the RESUME chip are retired. Resume now lives
in the window ("RESUME EXIT NN →").
- **Bay.**
- Two lilac tiles: the soundtrack, with a three-bar equaliser that moves
at most 1 Hz while playing, and settings.
- Settings opens a popover: 240 ms out-expo, Esc closes it, focus is
trapped, and it becomes a bottom sheet on phones. Volume and Pause
motion moved into it.
- The active state is amber.
- Tooltips hang from the button's right edge, are hidden while a popover
is open or on touch, and are kept out of the accessible name.
- **Title stack.** The chapter title is smaller (5.6vw, up to 100 px), with
a tighter gap, so the body starts about 50 px higher at 1440.
### Cards (items 9, 10)
- **One rule.** A single `.plate` with panel, record and grid variants.
- **Motion.**
- Arrivals ease out-expo, departures in-quart.
- Durations are 160, 320 and 720 ms.
- **Entrance.** A 28 px rise plus a top-down `clip-path` unmask over
`view()` entry 0–55%. Firefox and other browsers without
`animation-timeline` get an IntersectionObserver fallback
(`useCardEntrances`).
- **Why `translate`.** Entrances animate `translate`, not `transform`. A
filled animation overrides `transform`, which had silently disabled the
hover lift.
- **Focus.** Focus-visible gets the hover accent edge plus an outline.
- **chapter-settle removed.** It is dropped because the interlude now owns
the chapter change ("one timeline owns the chapter change").
### Outro: Engine off (item 1)
- **Car and scene.** On arrival the drive winds down to a stop: travel,
traffic and wheel spin. The tail and running lamps drop to parking level,
the sky darkens 10%, stars rise about 80%, and the grid fades.
- **Sound.** The engine and road noise take a 1.2 s low-pass sweep to idle
when the final exit is reached. Driving away restores them.
- **Letterbox.**
- Each bar stays within 8vh.
- The credit, built from real identity facts, types into the lower bar
in mono. It cannot go in the upper bar, which the contact avatar
shares.
- The Email CTA and the END OF ROUTE plaque stay clear at 1440 and 390.
- **Reduced motion.** Bars and poster dimming only; the credit simply
appears.
### Found on the way
- **The mouse wheel did not scroll at all.**
- Cause: `overscroll-behavior: none` on the script-scrolled,
overflow-hidden reading viewport, introduced in 71959f7, swallowed
wheel events.
- Removed. The wheel now scrolls and wheel crossings raise signs.
- **The docked plate's root was a fragment.** A template comment made it
one, which dropped `aria-hidden` from the HUD in tests. The comment was
moved into the script.
- **Grey slabs on the road.** These are the existing Blender district
billboards and gantries, not the new truss. They were left as authored.
### Deviations from the review
- **Bay targets.** The buttons stay 44 px targets with a 36 px drawn tile.
The keyboard and pointer-target tests require 44x44.
- **A third recovery button.** It stays in the bay while motion is paused
or static ("Enable motion"). Reduced-motion users must reach it without
opening settings.
- **Interlude length.** It runs about 1.9 s rather than 1.4 s; see above.
- **The 2D crossfade under reduced motion.** It is a plain swap: with
reduced motion the scene never starts, so there is no 3D sign to
crossfade from.
### Risks checked
- **mask-composite with backdrop-filter:** no backdrop-filter is used
anywhere.
- **No `animation-timeline` (Firefox):** covered by the IntersectionObserver
fallback.
- **will-change:** none added.
- **Scene cost:** the engine-off and interlude scene work is uniform writes
only. It is free on every tier.
- **Adaptive tiers:** the low tier keeps the CSS bars and plates.
### Verification after the review pass
- **Title stack (1440x900, Experience).** Below the 72 px beam, the section
starts at 100 px, the h2 at 148–245 px, and the chapter body at 268 px.
Evidence: `round5/title-stack-1440.webp`.
- **Interlude sequencing.** A CDP screencast of a Start → Experience click
showed the Profile chapter flashing past during the smooth scroll, before
the sign's approach hid the plates. A long navigator jump (more than 0.6
viewport) now pre-arms `data-interlude="on"` at click time, while the
scene runs. The loop takes the attribute over when the interlude starts,
and a 1.4 s timeout lets the plates rise if no interlude follows.
Evidence: `round5/interlude-prearm-1440-sequence.webp`.
- **Found by the browser suite.**
- The volume `<output>` was an implicit second live region. It is now an
`aria-hidden` readout, and the slider carries `aria-valuetext`.
- The bay tiles lost their outline in forced colours, because the
gradients are dropped. They now get a `ButtonText` border.
### Playwright against the round-4 baseline
The baseline is 63 failures. The final full run gave 147 passed, 88
failed and 55 skipped. Of the 27 failures new against the baseline, 25
were coupled or fixed and re-run:
- **Coupled to Volume and Pause moving into settings:** audio-controls
×3, bfcache, scene-controls and visual-regression audio. These tests
were updated.
- **Coupled to the gantry:** title-navigation ×2, and journey-integration
×4, where the window pre-draws the resting "Start" twin. These tests
were updated.
- **Real regressions, fixed:** forced colours (bay borders) and the
scene-controls status (the `<output>` live region).
- **Flaky under full-suite load:** contact-refinements reading mask. It
passes on a re-run.
Two remain on both projects and were left as is:
- journey-integration "carries a departed sign past the car"
- journey-integration "keeps the readable Profile face outside its
destination panel"
Both assert the retired roadside choreography: the sign now hands off to
the window plate. Seven siblings already fail in the baseline. Rewriting
the geometry oracle is out of scope.
Fixed against the baseline: accessibility-keyboard "explicit keyboard
navigation" (desktop) and audio-controls compact panels (mobile).
### Test edits (intentional behaviour changes)
- **Unit, `tests/unit/sign-rendering.test.ts`.**
- The fade test now uses relative texture counts, and the docked face
is hidden after the handoff.
- "closes in over the road in the upper third, then arcs up into the
window".
- "leaves the window to the flat plate as it departs".
- The tilt applies only on hover.
- **Unit, `tests/unit/SceneCanvas.test.ts`.** Volume and Pause motion are
checked inside the open settings panel.
- **Browser, settings.**
- `audio-controls.spec.ts`: opens Drive settings for volume and pause.
The volume stays visible beside Quality after Static. The interruption
test lifts its synthetic state before Resume, because Resume and Mute
now share one slot.
- `bfcache-lifecycle.spec.ts`, `scene-controls.spec.ts` and
`visual-regression.spec.ts`: open Drive settings before Pause motion
or volume.
- `tests/performance/drive-trace.spec.ts`: Drive settings instead of
Sound volume. Not run.
- **Browser, gantry.**
- `title-navigation.spec.ts`: the gantry is docked and unscaled from the
first frame. The current exit is its lane lamp or a rounded inset.
- `journey-integration.spec.ts`: `roadsideLabels()` leaves out the
resting "Start" twin texture from the roadside label checks.

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB