fix: make nightdrive signage reliable and legible

This commit is contained in:
2026-09-03 17:07:00 +03:00
parent 4404c07f93
commit b075041918
50 changed files with 4435 additions and 200 deletions

View File

@@ -0,0 +1,118 @@
# Nightdrive sign passing and navigator evidence
Status date: 2026-09-03
This directory records the final bounded Three.js roadside-sign continuation. It supersedes the earlier sign-pass evidence for current navigator triggering, route corridors, live resize behavior, and departure motion. The approved portfolio content, navigation presentation, HUD, controls, car, road, terrain, sun, atmosphere, camera, and forward-travel direction were not redesigned.
## Shared causes found
The remaining defects had related state, projection, and rendering causes:
1. The navigation controller described every link jump only as generic explicit navigation. That correctly suppressed skip links, direct fragments, restoration, and the hero shortcut, but gave the sign controller no way to distinguish an intentional navigator destination.
2. A navigation source persists for several render frames. Consuming that source directly would duplicate a sign, so navigator intent needed a monotonic epoch and a single canonical destination.
3. Passive trigger distance was shared across very different document layouts. In portrait and short landscape, the usable world corridor occurs in a narrower inter-panel interval, so the old threshold could latch while an opaque panel still occupied the sign's dwell region.
4. Placement considered the destination panel but not every opaque panel still visible during a transition. Experience, Additional work, and Contact could therefore clear their incoming card while touching the outgoing Profile, Selected builds, or Toolkit surface.
5. A quality-tier rebuild could reconstruct the renderer with the lifecycle's older responsive profile. The next update then moved a visible sign abruptly. Projection must be owned by the current renderer viewport, with a bounded live reflow.
6. The sign face needed more than a larger bitmap: the source aspect, UVs, font readiness, color space, mipmap path, anisotropy, tone mapping, bloom exposure, and projected dwell size all affected perceived sharpness.
7. Departure changed opacity more than physical pose. It read as a slide-deck fade because the sign neither grew in perspective nor crossed the roadside edge as the car passed it.
8. A full-resolution evidence review exposed one final route-specific issue: the rapid Selected builds reconciliation used the outer-right pose and clipped 13px beyond the viewport in the mobile browser profile. Moving every outer-right sign inward then touched Toolkit before Contact. The final fix assigns Selected builds to the inner-right corridor while retaining Contact's genuinely necessary outer-right placement.
9. Traversal state could race a still-departing sign: a stale completion after returning to Start could disqualify the next Profile traversal, while the new same-label Profile candidate could be dropped behind the old presentation. Visible signs now carry their traversal generation, and only passive same-label work from a newer traversal may become the single pending target. A separate destination-idempotency guard makes another click on the already-active navigator target a no-op even after its first sign has completed.
10. Reverse re-arming originally removed only the immediate candidate from the completion ledger. A multi-section retreat therefore left later routes ineligible, and a still-departing old sign could write its route back after the retreat. A qualifying retreat now advances the traversal generation and re-arms the candidate plus every later route; cooldown state retains its generation so a quick forward return cannot be discarded.
11. A passive portrait sign could already be readable when its matching navigator button was clicked. Keeping the passive pose would place it behind the newly aligned full-width card, while relatching it would duplicate the label. The controller now promotes the existing presentation to a navigator arrival, and the renderer moves it to the portrait-safe pose over the same bounded 320ms pose transition used for resize.
12. Promotion initially preserved the passive dwell clock. Under a slow navigation alignment, part of the guaranteed readable interval could therefore elapse while the sign was still moving into the navigator-safe corridor. Promotion now starts a fresh 1,400ms dwell from the navigator sample while retaining the same object and presentation count.
## Canonical candidacy and placement map
Passive candidates require motion to be enabled, a forward document direction, positive scroll delta, and the next eligible route. The ordinary trigger is at most 0.55 viewport heights from the activation line on wide layouts, 0.23vh on portrait layouts, and 0.38vh on short landscape. Crossing a real section boundary remains authoritative and reconciles directly to the eligible route reached, including large and multi-section jumps.
Navigator buttons add one explicit sign intent to their navigation epoch. That intent selects the canonical destination directly rather than waiting for a passive threshold. Repeated render frames and another click on the same already-active destination cannot duplicate it; after the visitor moves elsewhere, a later navigator return is a new eligible arrival. A navigator target queued behind a readable sign bypasses the passive completed-route filter, and returning to the currently visible label cancels any obsolete queued destination. Start remains ineligible.
| Route target | Face | Marker | Readable corridor | Safe-placement intent |
| --- | --- | ---: | --- | --- |
| `start` | Start | 01 | none | deliberately ineligible |
| `profile` | Profile | 02 | left | opposite the right Profile card |
| `experience` | Experience | 03 | left | clears both the outgoing Profile card and incoming Career surface |
| `infrastructure` | Infrastructure | 04 | outer-right | outside the broad systems-content corridor, with a route-owned 1.6-world-unit inward dwell bias to preserve the viewport edge |
| `selected-builds` | Selected builds | 05 | right | inside the visible right roadside corridor, clear of the large left project card |
| `additional-work` | Additional work | 06 | outer-left | outside the outgoing centered Selected builds surface |
| `toolkit` | Toolkit | 07 | outer-left | outside the wide toolkit content corridor |
| `contact` | Contact | 08 | outer-right | clears the still-visible wide Toolkit surface |
Every eligible route approaches from its corridor's horizon pose, settles at the responsive dwell pose, then travels toward and past the chase camera on the same roadside. Wide, tall, and short pose families are derived from the current renderer viewport. Short landscape receives aspect-bounded lateral relief. A navigator arrival on a narrow portrait viewport uses a compact, terrain-planted near-car pose in the stable gap between the destination and following panels. If navigation promotes an already-readable passive sign, the same object transitions to that safe pose without a label redraw, a second presentation, or a one-frame teleport.
Browser projection tests exercise all seven passive transitions at 1440×900, 390×844, and 844×390. During dwell, the complete face must remain at least 8px inside the viewport, 16px clear of every visible opaque content surface, and 8px clear of navigation, HUD, and controls. Navigator-triggered Profile placement is separately measured at 780×493 and 390×844.
## Lifecycle and retarget contract
| Phase | Duration | Contract |
| --- | ---: | --- |
| Anticipate | 300ms | latch one canonical target; remain concealed at the route horizon |
| Approach | 650–900ms | elapsed-time, frame-rate-independent horizon-to-dwell travel; acceleration can shorten by at most 250ms |
| Dwell | at least 1,400ms | readable from the first actual dwell frame; reverse, target passing, delayed frames, and newer candidates cannot shorten it |
| Depart | 700ms | constant world scale; positive-z movement toward the chase camera plus a roadside sweep; opacity stays full through progress 0.58 and falls off only during the edge pass |
| Cooldown | 350ms | suppress immediate replay while retaining only the latest valid pending destination |
The controller owns one visible sign and one optional pending target. A concealed sign may retarget immediately. A visible sign never changes label. A readable stale sign completes its minimum dwell and departs cleanly; only the latest relevant pending destination follows. If navigation returns to the currently visible target, that intent cancels an obsolete queued destination instead of replaying either label. A presentation may complete only into the traversal generation in which it was latched, so an older departure cannot poison the new traversal's completed-route ledger. Large jumps do not flash or queue obsolete intermediate labels. Reverse document input never reverses physical travel through the car. Live lifecycle sampling continues without new input. Delayed frames enter dwell and start a fresh minimum dwell clock rather than skipping the readable state.
Completed passive routes stay armed-off through small oscillations. Retreat beyond the responsive trigger plus 0.20vh rearm margin starts a new traversal and re-arms that candidate and every later route. A navigator jump to Start, an unrequested explicit jump, or history restoration starts a fresh passive traversal without displaying a suppressed sign or allowing an older departure to re-complete the new ledger.
Initialization, direct fragments, history restoration, skip links, the non-navigator “Explore work” jump, Static mode, reduced motion, and hidden-document resets remain sign-suppressed. Navigator buttons are the sole explicit-navigation path that requests a destination sign.
## Physical departure evidence
At 1440×900, the Profile dwell face measured 211.09px wide. During departure it remained fully opaque while growing to 410.98px at progress 0.500 and sweeping left from 402.91px to 71.74px. At progress 0.643 it crossed the roadside edge (left −342.88px, width 675.49px) and only then began its restrained falloff (opacity 0.920). This produces the visual event of the car overtaking a fixed roadside object instead of fading a card in place.
## Text and runtime-owned geometry
The face is an exact 4:1 plane backed by a 2048×512 sRGB canvas texture, trilinear mipmaps, linear magnification, premultiplied alpha, and up to 8× renderer-supported anisotropy. The bundled Geist Mono marker and label faces are awaited before the first draw. The face bypasses tone mapping and is inset ahead of a separate panel to avoid bloom contamination and z-fighting. Labels redraw and upload only while concealed; there is no per-frame canvas work or texture replacement.
The refined housing uses a clipped beveled body, inset backplate and face panel, rear rails, restrained edge and route accents, two narrow posts, paired braces, fasteners, and separate planted footings. The sign owns 20 renderable parts through 13 geometries, 7 materials, and 1 texture. Those objects are created once per world generation and disposed through the scene resource bag; lifecycle updates do not rebuild the hierarchy or traverse it.
## Measured browser matrix
All recorded dwell frames reported a 2048×512 texture, 8× anisotropy, a browser maximum texture size of 8192, and `fontReadyWhenDrawn: true`.
| Scenario | CSS face width | Renderer ratio | Source texels per rendered face pixel |
| --- | ---: | ---: | ---: |
| 390×844 portrait, device DPR 3 / Low | 162.10px | 1.25 | 10.11 |
| 844×390 short landscape, DPR 1 / High | 151.31px | 1 | 13.54 |
| 768×1024 tablet, DPR 1 / High | 196.67px | 1 | 10.41 |
| 1440×900 desktop, DPR 1 / High | 211.09px | 1 | 9.70 |
| 1440×900 desktop, device DPR 2 / High | 211.07px | 1.5 | 6.47 |
| 1440×900 desktop, DPR 1 / Low | 211.09px | 1 | 9.70 |
| 2560×1440 ultrawide, DPR 1 / High | 337.72px | 1 | 6.06 |
The ratio is the 2,048 source width divided by CSS face width × renderer pixel ratio. It records sampling headroom rather than claiming an unavailable GPU-inspector metric. Low and High retain identical sign typography and geometry. The renderer ratio remains tier-capped independently of the source texture, including device DPR 3.
## Evidence index
- Supplied overlap baseline: [`before/profile-overlap-1280x720-dpr1.25.png`](before/profile-overlap-1280x720-dpr1.25.png)
- Corrected desktop sides: [`after/profile-desktop-1440x900-dpr1-high.png`](after/profile-desktop-1440x900-dpr1-high.png), [`after/experience-desktop-1440x900-dpr1-high.png`](after/experience-desktop-1440x900-dpr1-high.png)
- Navigator arrival: [`after/navigator-profile-780x493-dwell.png`](after/navigator-profile-780x493-dwell.png), [`after/navigator-profile-portrait-390x844-dpr3-dwell.png`](after/navigator-profile-portrait-390x844-dpr3-dwell.png)
- Responsive families: [`after/profile-portrait-390x844-dpr3-low.png`](after/profile-portrait-390x844-dpr3-low.png), [`after/profile-short-844x390-dpr1-high.png`](after/profile-short-844x390-dpr1-high.png), [`after/profile-tablet-768x1024-dpr1-high.png`](after/profile-tablet-768x1024-dpr1-high.png), [`after/profile-ultrawide-2560x1440-dpr1-high.png`](after/profile-ultrawide-2560x1440-dpr1-high.png)
- DPR and quality: [`after/profile-desktop-1440x900-dpr2-high.png`](after/profile-desktop-1440x900-dpr2-high.png), [`after/profile-desktop-1440x900-dpr1-low.png`](after/profile-desktop-1440x900-dpr1-low.png)
- Lifecycle: [`lifecycle/profile-anticipate.png`](lifecycle/profile-anticipate.png), [`lifecycle/profile-approach.png`](lifecycle/profile-approach.png), [`lifecycle/profile-dwell.png`](lifecycle/profile-dwell.png), [`lifecycle/profile-depart-early.png`](lifecycle/profile-depart-early.png), [`lifecycle/profile-depart-passing.png`](lifecycle/profile-depart-passing.png), [`lifecycle/profile-depart-edge.png`](lifecycle/profile-depart-edge.png)
- Adverse input: [`lifecycle/slow-scroll-dwell.png`](lifecycle/slow-scroll-dwell.png), [`lifecycle/repeated-tiny-input-dwell.png`](lifecycle/repeated-tiny-input-dwell.png), [`lifecycle/reverse-during-approach.png`](lifecycle/reverse-during-approach.png), [`lifecycle/reverse-during-dwell.png`](lifecycle/reverse-during-dwell.png), [`lifecycle/rapid-multi-section-reconciliation.png`](lifecycle/rapid-multi-section-reconciliation.png), [`lifecycle/delayed-frame-readable-dwell.png`](lifecycle/delayed-frame-readable-dwell.png), [`lifecycle/keyboard-scroll-dwell.png`](lifecycle/keyboard-scroll-dwell.png)
- Visible resize: [`lifecycle/resize-visible-before-1440x900.png`](lifecycle/resize-visible-before-1440x900.png), [`lifecycle/resize-visible-after-844x390.png`](lifecycle/resize-visible-after-844x390.png)
- Suppressed modes: [`after/static-mode-1440x900.png`](after/static-mode-1440x900.png), [`after/reduced-motion-390x844-dpr3.png`](after/reduced-motion-390x844-dpr3.png)
- Machine-readable results: [`browser-matrix.json`](browser-matrix.json), [`lifecycle/trace.json`](lifecycle/trace.json), [`browser-console.json`](browser-console.json)
The lifecycle trace records candidate/latched target outcomes, phase, opacity, projected bounds, visible duration, active section, direction, navigator intent, multi-section reconciliation, and resize state. The navigator scenario presents Profile exactly once and draws only `Profile`; the rapid scenario reconciles directly to Selected builds in the right corridor, with final bounds 857.27–1056.10px; no visible label mutates.
## Fresh verification record
- `npm run build:preview`: passed asset verification, type checking, 43 unit files / 566 tests, client and SSR builds, prerendering, artifact validation, and the transfer gate.
- Focused controller/navigation/drive/world verification: 4 files / 117 tests passed.
- Focused browser reflow verification: the already-readable portrait navigator promotion passed in 4.5s, and the responsive world-safe-corridor test passed in 16.8s, unchanged and with one worker.
- Complete browser matrix: the first frozen run produced 189 passes, 48 intentional project skips, and one parallel-load Toolkit→Contact margin sample; the second produced 188 passes, the same 48 skips, a different responsive-sampling timeout, and an unrelated hydration sample that caught the transient `Motion: preparing` status. The all-seven-transition test passed in the second parallel run and also passed unchanged alone in 39.9s. The responsive sign test passed unchanged alone in 16.8s, and hydration passed unchanged alone in 1.8s. No assertion or timeout was changed.
- Authenticated runtime gate: passed at High, renderer ratio 1.5, with 5,608,790 texture bytes, 755,916 geometry bytes, 161,344,784 render-target bytes, 33,554,432 runtime-allowance bytes, and 201,263,922 total accounted bytes.
- Transfer gate: passed with 21,499 bytes initial HTML/critical CSS, 80,974 bytes initial application JavaScript, 69,040 bytes initial fonts, and 223,856 bytes first live scene; zero violations.
- Deployment suite: 7/9 passed. Its two failures are the checked-in execution-security evidence expiring before the run date, before sign or portfolio behavior is evaluated.
- Long-drive performance harness: no valid measurement. Desktop reached its fixed 75s timeout while locating the visible Toolkit navigation target; mobile did not leave scene loading before its five-second deadline and correctly selected fallback. No metric is claimed and no harness threshold was changed.
- [`browser-console.json`](browser-console.json): empty error list.
## Blender decision and ownership
Another GLB is not justified. The sign's finite construction is lightweight, while its label, candidacy, lifecycle, projection, responsive pose, and quality behavior must remain runtime-owned. Keeping the whole sign in stable Three.js geometry avoids another asset transfer and keeps dynamic text separate by construction.
The finite authored grand-tourer remains Blender-owned and unchanged. Dynamic text, sign behavior, responsive placement, road, terrain, atmosphere, sun, camera, and motion remain Three.js-owned.

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 990 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

@@ -0,0 +1,113 @@
{
"generatedAt": "2026-09-03T12:01:53.288Z",
"errors": [
{
"scenario": "profile-desktop-1440x900-dpr1-high",
"errors": []
},
{
"scenario": "experience-desktop-1440x900-dpr1-high",
"errors": []
},
{
"scenario": "profile-portrait-390x844-dpr3-low",
"errors": []
},
{
"scenario": "profile-short-844x390-dpr1-high",
"errors": []
},
{
"scenario": "profile-tablet-768x1024-dpr1-high",
"errors": []
},
{
"scenario": "profile-ultrawide-2560x1440-dpr1-high",
"errors": []
},
{
"scenario": "profile-desktop-1440x900-dpr2-high",
"errors": []
},
{
"scenario": "profile-desktop-1440x900-dpr1-low",
"errors": []
},
{
"scenario": "profile-anticipate",
"errors": []
},
{
"scenario": "profile-approach",
"errors": []
},
{
"scenario": "profile-dwell",
"errors": []
},
{
"scenario": "profile-depart-early",
"errors": []
},
{
"scenario": "profile-depart-passing",
"errors": []
},
{
"scenario": "profile-depart-edge",
"errors": []
},
{
"scenario": "lifecycle",
"errors": []
},
{
"scenario": "navigator-click",
"errors": []
},
{
"scenario": "navigator-click-portrait",
"errors": []
},
{
"scenario": "slow-scroll",
"errors": []
},
{
"scenario": "repeated-tiny-input",
"errors": []
},
{
"scenario": "reverse-approach",
"errors": []
},
{
"scenario": "reverse-dwell",
"errors": []
},
{
"scenario": "rapid-jump",
"errors": []
},
{
"scenario": "delayed-frame",
"errors": []
},
{
"scenario": "visible-resize",
"errors": []
},
{
"scenario": "keyboard-scroll",
"errors": []
},
{
"scenario": "static",
"errors": []
},
{
"scenario": "reduced-motion",
"errors": []
}
]
}

View File

@@ -0,0 +1,557 @@
{
"generatedAt": "2026-09-03T12:01:53.287Z",
"scenarios": [
{
"name": "profile-desktop-1440x900-dpr1-high",
"width": 1440,
"height": 900,
"dpr": 1,
"tier": "high",
"targetId": "profile",
"frame": {
"now": 3077.3,
"targetId": "profile",
"phase": "dwell",
"progress": 1,
"opacity": 1,
"viewportProfile": "wide",
"activeSectionId": "start",
"direction": 0,
"visible": true,
"corridor": "left",
"bounds": {
"left": 402.9099204145575,
"top": 418.7729846317115,
"right": 613.9982107225217,
"bottom": 470.8324692196562,
"width": 211.08829030796414,
"height": 52.05948458794472
},
"texture": {
"width": 2048,
"height": 512,
"maximumSize": 8192,
"anisotropy": 8,
"fontReadyWhenDrawn": true
},
"rendererPixelRatio": 1,
"viewport": {
"width": 1440,
"height": 900
}
},
"geometry": {
"panel": {
"left": 777.59375,
"top": 681,
"right": 1382.390625,
"bottom": 1139.28125
},
"fixedZones": [
{
"left": 0,
"top": 0,
"right": 1440,
"bottom": 53
},
{
"left": 12,
"top": 844,
"right": 262.078125,
"bottom": 888
},
{
"left": 1275.5625,
"top": 844,
"right": 1428,
"bottom": 888
}
]
},
"sourceTexelsPerRenderedPixel": 9.702101414588657
},
{
"name": "experience-desktop-1440x900-dpr1-high",
"width": 1440,
"height": 900,
"dpr": 1,
"tier": "high",
"targetId": "experience",
"frame": {
"now": 2511.7,
"targetId": "experience",
"phase": "dwell",
"progress": 1,
"opacity": 1,
"viewportProfile": "wide",
"activeSectionId": "profile",
"direction": 0,
"visible": true,
"corridor": "left",
"bounds": {
"left": 402.9087500447251,
"top": 418.75799808412745,
"right": 613.9986358424793,
"bottom": 470.817578359102,
"width": 211.08988579775422,
"height": 52.059580274974564
},
"texture": {
"width": 2048,
"height": 512,
"maximumSize": 8192,
"anisotropy": 8,
"fontReadyWhenDrawn": true
},
"rendererPixelRatio": 1,
"viewport": {
"width": 1440,
"height": 900
}
},
"geometry": {
"panel": {
"left": 57.59375,
"top": 680.28125,
"right": 719.984375,
"bottom": 1830.875
},
"fixedZones": [
{
"left": 0,
"top": 0,
"right": 1440,
"bottom": 53
},
{
"left": 12,
"top": 844,
"right": 262.078125,
"bottom": 888
},
{
"left": 1251.796875,
"top": 844,
"right": 1428,
"bottom": 888
}
]
},
"sourceTexelsPerRenderedPixel": 9.702028082776994
},
{
"name": "profile-portrait-390x844-dpr3-low",
"width": 390,
"height": 844,
"dpr": 3,
"tier": "low",
"targetId": "profile",
"frame": {
"now": 1811.6,
"targetId": "profile",
"phase": "dwell",
"progress": 1,
"opacity": 1,
"viewportProfile": "tall",
"activeSectionId": "start",
"direction": 0,
"visible": true,
"corridor": "left",
"bounds": {
"left": 36.41235262317512,
"top": 391.66234381308163,
"right": 198.51070849895177,
"bottom": 432.3830059465598,
"width": 162.09835587577666,
"height": 40.720662133478186
},
"texture": {
"width": 2048,
"height": 512,
"maximumSize": 8192,
"anisotropy": 8,
"fontReadyWhenDrawn": true
},
"rendererPixelRatio": 1.25,
"viewport": {
"width": 390,
"height": 844
}
},
"geometry": {
"panel": {
"left": 16,
"top": 461,
"right": 374,
"bottom": 997.109375
},
"fixedZones": [
{
"left": 0,
"top": 0,
"right": 390,
"bottom": 53
},
{
"left": 8,
"top": 792,
"right": 213.890625,
"bottom": 836
},
{
"left": 305.375,
"top": 792,
"right": 382,
"bottom": 836
}
]
},
"sourceTexelsPerRenderedPixel": 10.107443663744379
},
{
"name": "profile-short-844x390-dpr1-high",
"width": 844,
"height": 390,
"dpr": 1,
"tier": "high",
"targetId": "profile",
"frame": {
"now": 1964.2,
"targetId": "profile",
"phase": "dwell",
"progress": 1,
"opacity": 1,
"viewportProfile": "short",
"activeSectionId": "start",
"direction": 0,
"visible": true,
"corridor": "left",
"bounds": {
"left": 83.0504359770391,
"top": 190.7715027229274,
"right": 234.36132780345383,
"bottom": 226.177162894483,
"width": 151.31089182641472,
"height": 35.40566017155558
},
"texture": {
"width": 2048,
"height": 512,
"maximumSize": 8192,
"anisotropy": 8,
"fontReadyWhenDrawn": true
},
"rendererPixelRatio": 1,
"viewport": {
"width": 844,
"height": 390
}
},
"geometry": {
"panel": {
"left": 303.828125,
"top": 259.03125,
"right": 810.21875,
"bottom": 673.40625
},
"fixedZones": [
{
"left": 0,
"top": 0,
"right": 844,
"bottom": 53
},
{
"left": 12,
"top": 8465,
"right": 262.078125,
"bottom": 8509
},
{
"left": 0,
"top": 0,
"right": 0,
"bottom": 0
}
]
},
"sourceTexelsPerRenderedPixel": 13.535046785326498
},
{
"name": "profile-tablet-768x1024-dpr1-high",
"width": 768,
"height": 1024,
"dpr": 1,
"tier": "high",
"targetId": "profile",
"frame": {
"now": 2196,
"targetId": "profile",
"phase": "dwell",
"progress": 1,
"opacity": 1,
"viewportProfile": "tall",
"activeSectionId": "start",
"direction": 0,
"visible": true,
"corridor": "left",
"bounds": {
"left": 191.5893710701102,
"top": 475.18004358029873,
"right": 388.25854417015336,
"bottom": 524.5852618542048,
"width": 196.66917310004317,
"height": 49.40521827390603
},
"texture": {
"width": 2048,
"height": 512,
"maximumSize": 8192,
"anisotropy": 8,
"fontReadyWhenDrawn": true
},
"rendererPixelRatio": 1,
"viewport": {
"width": 768,
"height": 1024
}
},
"geometry": {
"panel": {
"left": 276.46875,
"top": 562.828125,
"right": 737.265625,
"bottom": 1024.640625
},
"fixedZones": [
{
"left": 0,
"top": 0,
"right": 768,
"bottom": 53
},
{
"left": 12,
"top": 968,
"right": 262.078125,
"bottom": 1012
},
{
"left": 603.5625,
"top": 968,
"right": 756,
"bottom": 1012
}
]
},
"sourceTexelsPerRenderedPixel": 10.413426607321972
},
{
"name": "profile-ultrawide-2560x1440-dpr1-high",
"width": 2560,
"height": 1440,
"dpr": 1,
"tier": "high",
"targetId": "profile",
"frame": {
"now": 3528.4,
"targetId": "profile",
"phase": "dwell",
"progress": 1,
"opacity": 1,
"viewportProfile": "wide",
"activeSectionId": "start",
"direction": 0,
"visible": true,
"corridor": "left",
"bounds": {
"left": 772.6710568680685,
"top": 670.2319070306204,
"right": 1110.3915295981597,
"bottom": 753.5258288498234,
"width": 337.72047273009116,
"height": 83.29392181920298
},
"texture": {
"width": 2048,
"height": 512,
"maximumSize": 8192,
"anisotropy": 8,
"fontReadyWhenDrawn": true
},
"rendererPixelRatio": 1,
"viewport": {
"width": 2560,
"height": 1440
}
},
"geometry": {
"panel": {
"left": 1382.390625,
"top": 1107,
"right": 2457.578125,
"bottom": 1510.15625
},
"fixedZones": [
{
"left": 0,
"top": 0,
"right": 2560,
"bottom": 53
},
{
"left": 12,
"top": 1384,
"right": 262.078125,
"bottom": 1428
},
{
"left": 2395.5625,
"top": 1384,
"right": 2548,
"bottom": 1428
}
]
},
"sourceTexelsPerRenderedPixel": 6.064186702820287
},
{
"name": "profile-desktop-1440x900-dpr2-high",
"width": 1440,
"height": 900,
"dpr": 2,
"tier": "high",
"targetId": "profile",
"frame": {
"now": 2904.3,
"targetId": "profile",
"phase": "dwell",
"progress": 1,
"opacity": 1,
"viewportProfile": "wide",
"activeSectionId": "start",
"direction": 0,
"visible": true,
"corridor": "left",
"bounds": {
"left": 402.92090777471464,
"top": 418.91425432105405,
"right": 613.9941436298301,
"bottom": 470.9728306161199,
"width": 211.07323585511546,
"height": 52.05857629506585
},
"texture": {
"width": 2048,
"height": 512,
"maximumSize": 8192,
"anisotropy": 8,
"fontReadyWhenDrawn": true
},
"rendererPixelRatio": 1.5,
"viewport": {
"width": 1440,
"height": 900
}
},
"geometry": {
"panel": {
"left": 777.59375,
"top": 681,
"right": 1382.390625,
"bottom": 1139.28125
},
"fixedZones": [
{
"left": 0,
"top": 0,
"right": 1440,
"bottom": 53
},
{
"left": 12,
"top": 844,
"right": 262.078125,
"bottom": 888
},
{
"left": 1275.5625,
"top": 844,
"right": 1428,
"bottom": 888
}
]
},
"sourceTexelsPerRenderedPixel": 6.468528934054543
},
{
"name": "profile-desktop-1440x900-dpr1-low",
"width": 1440,
"height": 900,
"dpr": 1,
"tier": "low",
"targetId": "profile",
"frame": {
"now": 1915.2,
"targetId": "profile",
"phase": "dwell",
"progress": 1,
"opacity": 1,
"viewportProfile": "wide",
"activeSectionId": "start",
"direction": 0,
"visible": true,
"corridor": "left",
"bounds": {
"left": 402.91180139937455,
"top": 418.79709521769956,
"right": 613.997524232391,
"bottom": 470.8564255936192,
"width": 211.08572283301646,
"height": 52.059330375919615
},
"texture": {
"width": 2048,
"height": 512,
"maximumSize": 8192,
"anisotropy": 8,
"fontReadyWhenDrawn": true
},
"rendererPixelRatio": 1,
"viewport": {
"width": 1440,
"height": 900
}
},
"geometry": {
"panel": {
"left": 777.59375,
"top": 681,
"right": 1382.390625,
"bottom": 1139.28125
},
"fixedZones": [
{
"left": 0,
"top": 0,
"right": 1440,
"bottom": 53
},
{
"left": 12,
"top": 844,
"right": 262.078125,
"bottom": 888
},
{
"left": 1275.5625,
"top": 844,
"right": 1428,
"bottom": 888
}
]
},
"sourceTexelsPerRenderedPixel": 9.702219423054542
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

View File

@@ -141,6 +141,28 @@ The later navigator failure shared one state-ownership cause: explicit, initial,
The focused controller regression failed against the previous implementation because Profile remained `null` after a completed lifecycle and an explicit Contact-to-Start round trip, then passed after the ownership correction. The real-browser regression clicks a section, returns to Start, and verifies that the Profile sign is emitted on the next passive scroll. It passed in both desktop and mobile projects. The final four-worker browser matrix passed 180 checks with 44 deliberate project/capability skips and no failures, including navigation, history, keyboard, accessibility, responsive, Static, reduced-motion, fallback, visual, and flash-safety coverage.
### Sign passing and navigator-trigger continuation
The final 2026-09-03 signs-only continuation supersedes the earlier sign-pass route, navigator, resize, texture, and departure details above. Durable evidence is retained under `docs/reviews/evidence/nightdrive-iteration/sign-passing-refinement/`; its [`README.md`](evidence/nightdrive-iteration/sign-passing-refinement/README.md) is the canonical evidence index and records the complete route/trigger/pose contract. The supplied Profile-overlap baseline remains separate from the corrected viewport, DPR, quality, lifecycle, adverse-input, navigator, Static, reduced-motion, and empty-console evidence.
The investigation found six shared causes. Navigator actions exposed only a generic explicit-navigation source, so preserving skip/direct/history suppression also concealed intentional navigator arrivals. Completed-route state was not generation-bound, allowing an older departure to poison a traversal restarted at Start; reverse hysteresis re-armed only one route; and cooldown discarded legitimate same-label work from a newer traversal. The old desktop placement model did not account for the outgoing opaque panel or route-specific viewport-edge pressure. Perceived face softness came from the combined source aspect, font-readiness, UV, filtering, color-space, tone-mapping, bloom, projection, and DPR path rather than texture dimensions alone. Finally, departure mostly reduced opacity in place, which produced the reported slide-transition effect instead of a physical roadside pass.
The controller now consumes a navigator request exactly once through a monotonic navigation epoch and canonical destination. Start is ineligible; navigator Profile through Contact are eligible. Another click on the same already-active destination is idempotent, including after the first lifecycle completes. A different destination may replace a concealed label immediately or become the sole pending label behind a readable sign; returning to the visible target cancels the obsolete pending label. If a passive portrait sign is already readable when its matching navigator link is activated, the same object is promoted to the safe navigator pose over 320ms—without a redraw, replay, or teleport. Initial positioning, direct fragments, history restoration, skip links, the non-navigator Explore shortcut, Static, reduced motion, and hidden-document reset remain sign-suppressed; the next passive traversal is re-armed where appropriate.
Passive candidacy requires enabled motion, forward document direction, positive input, and the canonical upcoming route. The trigger maxima are 0.55vh for wide layouts, 0.23vh for portrait, and 0.38vh for short landscape; an actual boundary crossing wins and reconciles directly to the route reached. A qualifying reverse retreat beyond the trigger plus 0.20vh starts a new traversal and re-arms that route and every later route. Visible/cooldown state carries the traversal generation, preventing stale completion or same-label cooldown races. The clock contract is 300ms anticipate, 650–900ms approach, at least 1,400ms dwell measured from the first actual readable sample, 700ms pass-by departure, and 350ms cooldown. Delayed frames cannot skip dwell, stopping input cannot freeze a live sign, reverse input cannot move it physically backward, and a visible label never mutates.
The final route corridors are Profile left, Experience left, Infrastructure outer-right with a route-owned 1.6-world-unit inward dwell bias, Selected builds right, Additional work outer-left, Toolkit outer-left, and Contact outer-right. Projection assertions cover all seven passive transitions and require the complete dwell face to stay at least 8px inside the viewport, 16px outside visible opaque content, and 8px outside fixed controls. The responsive renderer—not stale lifecycle metadata—owns the current wide/tall/short pose. Visible resize and passive-to-navigator changes share one bounded pose transition and do not revive, duplicate, or strand the object.
The refined sign remains stable Three.js-owned geometry: one clipped/beveled housing, inset face panel, backplate, rear rails, paired narrow posts and braces, fasteners, and planted footings. It uses 20 renderable parts, 13 geometries, 7 materials, and one texture. The 4:1 face is a 2048×512 sRGB canvas texture with premultiplied alpha, trilinear mipmaps, linear magnification, up to 8× supported anisotropy, awaited Geist Mono fonts, and a non-tone-mapped face material. It redraws/uploads only when a concealed label changes. Recorded source headroom ranged from 6.06 to 13.54 texels per rendered face pixel across 390×844/DPR 3 Low through 2560×1440 High, and every recorded draw reported `fontReadyWhenDrawn: true`.
The new departure keeps constant world scale and moves the planted sign toward the chase camera while sweeping it out through its authored roadside edge. At 1440×900 the Profile face grew in projection from 211.09px at dwell to 410.98px at progress 0.500 while remaining fully opaque and moving left from 402.91px to 71.74px. At progress 0.643 it was already crossing the edge (left −342.88px, width 675.49px) before the restrained opacity falloff began at 0.920. The result reads as the car overtaking a fixed roadside object rather than a card fading in place.
Fresh verification on 2026-09-03 passed type checking, the production preview build, all 43 unit files / 566 tests, and the focused sign/navigation/world set (4 files / 117 tests). The first complete four-worker browser matrix completed 189 passes and 48 intentional project skips; its sole failure was the 1440×900 Toolkit→Contact safety-margin sample under parallel load. A second frozen repeat completed 188 passes and the same 48 skips: the seven-transition assertion passed that time, while a different responsive sign sample timed out during `page.evaluate` and an unrelated hydration test sampled the transient `Motion: preparing` label. The exact unchanged seven-transition test passed with one worker in 39.9s, the responsive sign and navigator-promotion checks passed unchanged with one worker in 16.8s and 4.5s, and the hydration check passed unchanged alone in 1.8s. These are retained as observed load-only matrix flakes rather than hidden by timeout or assertion changes. The authenticated High-tier allocation gate passed at a renderer ratio of 1.5 with 5,608,790 texture bytes, 755,916 geometry bytes, 161,344,784 render-target bytes, a 33,554,432-byte runtime allowance, and 201,263,922 total accounted bytes. The transfer gate passed with 80,974 bytes of initial application JavaScript and 223,856 bytes for the first live scene; it reported no violations. The saved console capture contains no browser errors.
Two pre-existing harness limitations remain explicit. Deployment verification passed 7/9 tests; both failures stop at the repository's expired execution-security-evidence timestamp before portfolio behavior is exercised. The long-drive performance harness did not produce a valid trace: desktop exhausted its fixed 75s timeout while resolving the visible Toolkit navigation target, and mobile stayed in scene loading until the five-second live-scene deadline selected the static fallback. No performance number is inferred from either invalid run, and no timeout, lifecycle assertion, or budget was weakened.
No additional Blender asset was justified. The finite authored car remains Blender-owned and unchanged. Dynamic sign text, candidacy, lifecycle, responsive placement, road, terrain, atmosphere, sun, camera, and motion remain Three.js-owned.
## Direction review checklist
- [x] Information uses near-black opaque panels rather than neon glass.