Files

101 KiB
Raw Permalink Blame History

C1a Shell chrome: evidence log

Package card: docs/phase2/PLAN.md §2.4 "C1a Shell chrome". Concept: docs/phase2/concepts/window-nav.md (WN, owned by C1a). Steam build at the time of writing: 11094443.

Status

Session 6 (2026-10-07 17:00-19:40 EDT, build 11094443): review R2 fix pass, complete. Every major of wp/C1a-review-R2.md (M1-M8) is fixed and re-verified live, in both input modes, CSS-only and in three native sessions; minors m1-m4, m6-m8, m10-m12 fixed; m5 and m9 handed to their owners (REQ C1a->P6, REQ C1a->P10); m13 disputed (below). Every REQ addressed to C1a is answered (C5b's and C6b's after the live vr:systemui gates). Fixes found by this session's own live checks: the Back reveal's attention registration went stale whenever P3's attention module was installed again (the reveal silently stopped; now renewed), the reveal's label popped in over the Large Title, the ornament's glyph badges painted an opaque dark disc on the translucent capsule, the More circle jumped between cards, the tab bar's E3 rim read as a line down its tall sides, the gamepad-mode pill was uppercase, the window bar was a 3.6 mm hairline. Details: "Session 6" below.

READY: wp.c1a (with the built-in defaults quietBacking: "window", pointerProxy: "native"), and winbarMove for V1 (AT-17 passed: the three overrides applied, sizes unchanged, one row under the window in the headset). Not ready: tabBarAlways (AT-7's request and pitch pass, but "visible without the laser" needs the physical laser off, which no agent controls; P6's laserOnly, REQ C1a->P6), hdr108, searchCircle (trial switches, stay off). The tab bar's +25 mm is P7's own flag tabBarDepth (WN §3.3.6). Evidence (session 6 tables below): gates on main (AllGames, /settings/system, Downloads, windowless Home, a game page, /account, /controller/calibration/0, /search/tab/All, CONFIRM, MENU, POWER), frame.menu and vr:systemui (with C3a's static zoo) in both modes: no finding on the shell's nodes; High Contrast and Reduce Motion clean; native: covers, plates and pointer proxy acked and correct, sgcheck clean but for the legacy pops of C2c/C2a/C5a, G-HV PASS with explicit rects (AllGames 80.1, settings 71.1); RT-7 ratio 1.022; removal clean; pad-bfs equals stock. Still blocked outside C1a: AT-2's bottom scroll guard on AllGames (C2c's scroller, REQ C1a->C2c (2)).

Milestone reached: M4 (native fragments), 2026-10-07 09:08 EDT (session 5). Written, check-theme PASS, synced, live:

  • theme/layers/20-shell.json: supersedes the legacy hdr-back, hdr-search, footer, sort-filter pops while wp.c1a is on (nothing in the toolbar row or the ornament pops); owns frame.menu: material liquid (PLAN §1.6) and its cover = the tab bar's two capsules (T2 nodes .lgs-tabcap), falling back to the menu box without the runtime. The window cover stays 00-base's main.modes keyed on C1a's data-lgs-glass.
  • device/rt/20-shell.js: the ornament plate node #Footer > .lgs-orn-plate at the capsule rect (data-lgs-nopop always; liquid plate shell-ornament only as a capsule, none for the quiet legend); shell-back / shell-search liquid plates on windowless routes (REQ C2a->C1a #2, insets 10 / 8); the two .lgs-tabcap cover nodes in the frame menu; all removed by remove().
  • theme/20-shell.css: geometry for those nodes (§3, §4) and §4c native rules (acked ornament plate: the CSS capsule and its E3 hook go; acked Back plate: rest fill goes; covered tab bar: the row slices stop painting).
  • theme/popups/20-shell.json: frame menu only_visible_with_laser: false behind tabBarAlways (depth stays P7's tabBarDepth rule). theme/sg/20-winbar.json behind winbarMove: fc-left −231.5 mm (measured: frame controls 488 × 107 systemui px = 283 mm, centred, 15 mm under the window; right edge 20 mm left of the 140 mm pill), grab-up and tips-below provisional (P7's sg.md values) until AT-17.
  • Native check (native-session, pre pushes wp.c1a,wp.p3 and pops them in the last step; 09:05): sgcheck --route /library/tab/AllGames: no R1 (no pop over the ornament's data-lgs-nopop box), no hdr-*/footer/sort-filter pop; the only failures are R2 on the legacy tabs, tab-arrow, card pops (4.43 / 2.95 mm, owners C2c/C2a/C5a/C1b, reporter §3.5). hv c1a_native_ag --look viewed, then deleted: window cover glass with a visible top edge (profile pass, doubling 0.47 < 0.6, not doubled), the tab bar as two separate liquid capsules (sections, then Settings / VR Settings / Power) with the room between them instead of one dark rectangle, the ornament at the glass edge; G-HV verdict withheld (auto rect). Back to CSS only.
  • Still open then, closed in session 6: AT-7 (request and pitch), AT-17, AT-20, AT-0b in native mode, the ornament plate's ack (read live: data-lgs-plate-ack, the CSS capsule and its E3 hook dropped), G-HV with explicit rects (M4 is reached by PLAN §2.1's definition on today's tree, after P7's B1 fix).

Milestone reached: M3 (T2), 2026-10-07 08:14 EDT (session 4). M2 (T1) was reached at 07:45 (session 3, clock about 45 min ahead). Every T2 build of the card is in, behind wp.c1a (off by default until V2 accepts): route glass modes and hooks, the CQ1 header trial with its fallback class (settled: the fallback ships), the Large Title and the Back reveal, the ornament's member tags, quiet/capsule state, fixed slots and the T2 Options member, the frozen target with its re-focus on entering #Footer, the More helper, the pointer proxy, and the tab bar's live pitch from P8's geom. The package's own tests pass in both input modes (session 4 table), except the parts blocked by other packages listed below. Session 1–2 work (M0) is in checkpoint f5190bb; sessions 3–4 are in the working tree.

  • M3 evidence (session 4 log): AT-1, AT-3, AT-5, AT-6 (now centred ± 0), AT-8 (D-pad path), AT-8b = PLAN-1a-2 (G-FOCUS on the live tab bar over two rooms: +51.0 / +34.8 / +15.7 lounge, first frame 100 %), AT-21, AT-22 (removal with every T2 piece live), AT-24 (shell parts), AT-25 (a)–(d), AT-26, AT-27, AT-28, AT-29, PLAN-1a-1, PLAN-1a-3 (cmp for anatomy, tabbar, ornament, chrome with docs/phase2/wp/C1a-cmp.json; every shell delta explained, verdict recorded), AT-0b (CSS-only part), the Back reveal (laser), the tab pitch (p 66 for 9 items at r 1). Gates with T2 on: no finding on the shell's nodes on Downloads (with the Options member and the More circle live), AllGames and /settings/system, both modes.
  • Blocked outside C1a (recorded, with owners): AT-2's scroll guard on AllGames (C2c: library root padding + %{TabContentsScroll} scroll padding, REQ C1a->C2c (1)–(2)); AT-24's Sort/Filter in slot 1 (C2c's fixed-slot T1, REQ (3)); AT-8's "B at the root goes to the bar" (Steam's own B: the lab's history is never empty, B navigates back or toggles the tab row); AT-7's always-visible part (tabBarAlways is T4, popups/20-shell.json, M4) and resize-following (needs r ≠ 1, a user resize). The library tab row and the settings sidebar still sit under the toolbar until C2c and C6a pad their roots (visible today; cmp evidence in the log).
  • (Superseded by session 5: the three fragments below are written and live.) Earlier plan: theme/popups/20-shell.json (tab bar +15 mm, tabBarAlways), theme/sg/20-winbar.json (winbarMove), theme/layers/20-shell.json (window cover; supersede the legacy hdr-*, footer, sort-filter pops); then AT-0b native part, AT-7 (with tabBarAlways), AT-17, AT-20 under glass.py native-session. Before that, whenever an area lands its padding: re-run c1a/t_at2.js (guard) and glass.py cmp … --id C1a (anatomy).
  • Two-step moves: §5 done (C1c took the app-details scrim; deleted 08:13). Waiting: C1b copies §6 (search route) into 21-search.css; C3a removes the frame-menu parts of 30-bar.css §3. Then C1a deletes §6.
  • Decisions (PLAN §1.17 rule, safe default behind a flag): search circle variant behind searchCircle (G-AUD SHRUNK; the capsule is PLAN §1.9's fallback); CQ1 settled: #header and the page layout stay 40 whatever --basicui-header-height and HeaderStore say (AT-2), so lgs-hdr-40 ships and hdr108 only re-runs the trial; T1 keeps Steam's "Back" text as a capsule until T2's E-BACK; the quiet legend's dim band (quietBacking); the tab bar's collapsed width = circle + 24 (Steam's fixed 54 is narrower than the live circle).
  • Incident (session 3, about 06:51–07:00): the shared class index was cached with 3 CSS modules (theme broken for everyone); fixed by hand; REQ C1a->P1 and C1a->P10 still open.

Live on the device since 2026-10-07 06:05 (session 3), theme/20-shell.css rewritten (T1):

  • Window glass by route mode: the tint is %{BasicUiRoot}'s own background, sized to the glass (656 by default, 720 for window-full, none for windowless); bottom corners rounded at the glass edge; P4's E3 hook on %{BasicUiRoot}::before ends at the glass bottom; content is clipped to the glass shape (clip-path on %{BasicHome}) so nothing floats in the 64 px ornament margin.
  • Toolbar row, CQ1 fallback (no lgs-hdr-* class yet = fallback): Back in an 80 × 80 box at (14, 14) with its 60 px control at (24, 24) (T1 keeps "‹ Back" as a capsule; T2's E-BACK tag makes it the circle); search capsule 520 × 64 centred at (640, 54) in a 536 × 80 box (the input fills the box); Title mode centred; #header::before is the 124 px scroll-edge band. --lgs-hdr-pad (68px; 0 with lgs-hdr-108), --lgs-guard-top (124px) and --lgs-guard-bottom (612px) are defined on every html.lgs-on. Areas: pad your page roots with padding-top: var(--lgs-hdr-pad, 68px) now (until you do, your top row sits under the toolbar controls, e.g. the library tab row under the search capsule).
  • Bottom ornament: #Footer 92 px (pages and modals end at 628); capsule 84 at y 628–712, centred, anchored to the first and last member (radius 42, padding 12, gap 4), liquid glass over the page and tinted over the room; members 84 px hit / 60 px light (P4's raised hook), label 22 Semibold mixed case first, Steam's glyph as a 30 px badge after it (white .16 disc), badges collapse under data-lgs-vr-mode="laser". Rules for T2's data-lgs-orn, data-lgs-btn, data-lgs-orn-fixed / --lgs-orn-x / --lgs-orn-w, the quiet legend and its dim band are in place (inert until T2).
  • Tab bar (%{DashboardMenu}%{Variant_FrameMenu} only): two capsules of slices (sections, then system with the 10 px gap), pitch var(--lgs-tab-pitch, 52px), current route = .18 circle with its arc behind the glyph, focus/hover from P4's nav hook.
  • theme/vr/10-systemui.css §0 deleted (P4's REQ, done; every --lgs-vr-* resolves from vr/00-vr-tokens.css).
  • Gates so far (glass.py gates main --route /library/tab/AllGames --mode pad|laser): no SIZE, TYPE, OUTLINE or AUD finding on the shell's nodes (header, Back, search, #Footer, legends); the remaining findings there are C2c's tab row (unpadded, under the search capsule) and tab type.

Earlier (M0, sessions 1–2): window-nav.md revision 3 conformed to PLAN §1; seven owned mockups re-rendered; the quiet legend's dim band decided (flag quietBacking). Open requests owned by others: REQ C1a->P4 ×2, ->V1, ->Coordinator, ->C1b, ->C1c, ->C5a, ->C6a, ->C7 (M0), plus this session's ->C2c, ->C3a, ->C1b, ->C1c, ->C6a, ->C7, ->C5a, ->P1, ->P10.

What remains, in order (after session 6):

Next Needs Then
C2c keeps the focused poster above 612 (scroll-padding-bottom on %{TabContentsScroll}, REQ C1a->C2c (2)) C2c re-run AT-2's guard (c1a/t_at2.js)
V1: winbarMove on (AT-17 passed); tabBarAlways once P6's laserOnly follows it (REQ C1a->P6) and a wearer-free proof of "visible without the laser" exists V1, P6 AT-20 look with the flag from defaults.json
P10: #header false positives (m9), cmp on vr: surfaces, a rect for hv --look P10 re-run AT-4 on calibration, PLAN-1a-3's window-bar row live
Coordinator: rule on m13 (P-73 bottom scroll edge under an ornament) Coordinator —

Interface announced to every area (names are final; code lands at M2/M3)

Areas key only on these. They do not detect anything themselves.

What Name and values Set by Notes
Legend tags (live, M3) #Footer [data-lgs-btn] from each legend's React rgButtons[0]: OK (A, 0), CANCEL (B, 1), SECONDARY (X, 2), OPTIONS (Y, 3), SELECT (View, 10), MENU (≡, 11), else B<n> C1a T2 Probed on build 11094443: Select 0, Back 1, Filter 2, Sort By 3, Options 11
Toolbar row (CQ1) html.lgs-hdr-40 (shipped); html.lgs-hdr-108 only if a later Steam build lets the trial (flag hdr108) hold C1a T2 (device/rt/20-shell.js) Settled on build 11094443: the 108 px header does not hold (AT-2, session 4). No class = runtime off = the same fallback. Areas: pad page roots with --lgs-hdr-pad; no rules for lgs-hdr-108 are needed now
Page top padding in the fallback --lgs-hdr-pad: 0px with lgs-hdr-108, 68px otherwise C1a T1 (theme/20-shell.css) Page roots: padding-top: var(--lgs-hdr-pad, 68px) (WN §3.2 rule 1)
Scroll guard (VP P-23) --lgs-guard-top: 124px, --lgs-guard-bottom: 612px (window y) C1a T1 Focused items stay in y 124–612 on routes with an ornament (628 − 16; A1 moved the ornament from 636 to 628)
Route glass mode (PLAN §1.2) %{BasicUiRoot}[data-lgs-glass="window" | "window-full" | "windowless" | "hero"] C1a T2, from the route map in WN §3.1.1 Set on route change only, never on focus. No attribute (runtime off) = window
Route key %{BasicUiRoot}[data-lgs-route="<key>"], keys listed in WN §3.1.1 C1a T2 For route-scoped area rules (for example /chat, /invites header positions)
Glass-mode hook __LGS_RT.shell.glassMode(routeKey | '*', fn) → {remove()}; fn() returns a mode or null (= the map's fallback); __LGS_RT.shell.refreshGlass() after an area's own view change C1a T2 C2a: 'home' (fallback window-full); C5a: 'app' (title ↔ details); C3b: '*' while CC-M is open. Never evaluated on focus
Toolbar plates (windowless routes) Back circle data-lgs-plate="liquid" + data-lgs-plate-id="shell-back"; search circle "shell-search" C1a T2 Only on windowless routes; areas never tag Steam's toolbar nodes
Glass geometry window: 1280 × 656, radius 54, ornament margin 64. window-full: 1280 × 720. windowless: no window glass (plates only). hero: the art fills the window C1a T1 (CSS tint), P6/C1a T5 (cover) CSS-only tint rgb(20 22 30 / .74) (dial .60–.84) + edge cues (WN §8.4)
Bottom ornament #Footer capsule y 628–712 (84), centred, ≤ 960 wide, members 60, radius 42, padding 0 12, gap 4, 14 between groups; #Footer[data-lgs-orn="capsule" | "quiet"]; members tagged [data-lgs-btn="<Steam button enum>"] C1a T1 + T2 Quiet = only A and B: no capsule material, items 60 tall; labels Medium white .70 inside the glass (window-full); on window routes the labels (white .82) sit on a dim band (black .62, blurred edges, not glass; flag quietBacking, default "window"; WN §3.4.1, O3). Pages end at y 628 (--gamepadui-current-footer-height 92)
Fixed ornament slots __LGS_RT.shell.ornamentSlots(routeKey, {widths, gap, padding}) → {remove()}; #Footer[data-lgs-orn-fixed="<routeKey>"] while it applies C1a T2 The backing stays at the fixed rect (centred) and never follows the members; the Options member keeps its slot (disabled when it has nothing to act on) and has no name suffix; the More circle marks the frozen target instead. The area places members in its slots (C2c: ornamentSlots('library', {widths: [300, 130, 156, 134, 120], gap: 4, padding: 12}) → x 200–1080)
Options member T2 node in #Footer, .lgs-opt[data-lgs-btn="MENU"][data-lgs-t2] with Steam's legend classes, before A/B (the ≡ button; OPTIONS is Steam's Y) C1a T2 (live, session 4) Laser mode on routes whose page holds a registered More host; on fixed-slot routes in both modes; steps aside when Steam renders its own ≡. Disabled (aria-disabled, .38, no dispatch) without a target, while main holds any modal or menu, and in gamepad mode. Label = the target's onMenuActionDescription; laser look = ⋯ glyph + label + · <target> (.lgs-opt-name, not on fixed slots)
Modal recede Keyed on C1c's html.lgs-modal C1a T1 While an alert or sheet is open, slot 1, the Options member and the area slot recede under black .35 (still clickable); A, B and the dialog's legends stay lit
Large Title #header > .lgs-title (T2, aria-hidden); area text via data-lgs-title on the page root C1a T2 Section roots only; never on /search (C1b's snapshot clones it)
Glyph badges Shown only under html[data-lgs-vr-mode="gamepad"] (P3 signal) C1a T1 Steam's own glyph nodes, 30 px circle, 16 px Bold, trailing the label
More circle __LGS_RT.more.register(selector, {placement: 'card' | 'row'}) C1a T2 (device/rt/20-more.js) 60 px visible, 80 px hit, black .38 + 10 px blur (no blur inside another glass container, P-45), white .94 while its menu is open; cards: inside top right, inset 10; rows: trailing, inset 24; stays on the frozen target while the pointer is in #Footer. Dispatches the host's own onMenuButton
Frozen target __LGS_RT.shell.target() (the element), onTarget(fn) C1a T2 Fed by P3's attention (rt.attend, dwell 300 ms or pointerdown)
Tab-bar pitch --lgs-tab-pitch, --lgs-tab-place on the frame-menu document's root (popup px; WN §3.3.2 from P8's geom) C1a T2 (live, session 4) p 66 today (9 items, r 1); 52 when the runtime is off. The collapsed column is d + 24 wide (d = p − 8)
Pointer proxy div.lgs-pointer in each covered document, native mode only (pointerProxy flag, default "native") C1a T2 (device/rt/20-pointer.js) —
Runtime flag wp.c1a (off until V2 accepts); feature flags tabBarAlways, winbarMove, pointerProxy (PLAN §1.17 S9, S10, S16) and quietBacking (C1a, §1.17 rule) V1 device/defaults.json Built-in defaults when absent: tabBarAlways off until V1 turns it on, winbarMove off until V1 (AT-17 passed in session 6), pointerProxy "native", quietBacking "window". The tab bar's +25 mm is P7's own flag tabBarDepth (theme/sg/00-base.json, rule tabbar-depth), independent of tabBarAlways (which needs P6's wp.p6)

M0 checklist

# Step State
1 Requests to C1a merged into window-nav.md (C1b #1, #4; C1c REQ 1; C3a; C2c REQ-3/4/5; C2a #1, #2) or answered done; answers in each requester's log
2 Quiet-legend legibility decided (C1b #3, C1c REQ 4), flag and note done: dim band, quietBacking (WN §3.4.1, §11 O3); 4.9–6.7 : 1 over the sill, 5.1–6.0 over the curtain
3 Shared builder and CSS conformed (C1b #2, C1c REQ 2/3) done (recipe, slots, band, modal recede, More in glass, tone layer, focus .32 pending P4)
4 Owned mockups conformed to §1 and re-rendered, each viewed done: all seven, final pass 05:27 after P4's kit change
5 §13.1 measurements; §13 tests and §9 retention table checked against §1 done (tables validated: column counts consistent)
6 Requests for mockups and files C1a does not own filed done (C1b, C1c, C5a, C6a, C7, P4, V1, Coordinator)
7 P4's REQ (vr/10-systemui.css §0) answered done: accepted, scheduled for the first M2 session

Requests

  • REQ C1a->P4: tune --lgs-focus-add to .32 (PLAN §1.4 allows .28–.32, set once from G-FOCUS). Why: PLAN-1a-2 (G-FOCUS on the tab bar) on p2_window-nav_tabbar.png's state key, glass L ~95, normal compositing as in P4-D5: at .28 focus − rest = +35.2 L and focus − current-route circle = +7.6 L (both FAIL); .30: +39.1 / +11.6 (FAIL); .32: +42.5 / +15.1 (PASS). The .18 selection circle and the .28 pill differ by only .10 of the headroom, so P-15 fails wherever the glass is above about L 85. The shell's mockups use .32 until you decide (window-nav.md §13.1). P4 (2026-10-07): done: --lgs-focus-add = .32, recorded as final (P4-D8, contracts/tokens.md §1.6); kit --lg-focus-add .32 too (parity). Your mockups' .32 now equals the token.

  • REQ C1a->P4: kit.js / kit.css: liquid glass over a bright room renders at L 128–140 (tab-bar capsule and ornament over the curtain; p2_window-nav_ornament.png strip 3 measured 139 before C1a's workaround), above PLAN §1.6's 55–110 and 70–90 under text. Cause: --lgk-target-luma: .38 for liquid plus its white .12 sheen, and adapt() clamping at ×0.42. Suggest a liquid target near .30 for glass that carries labels, or a lower clamp. C1a's shared CSS works around it with a tone layer on .wn-tabcap and .wn-orn.lgk-glass ("glass tone under text" in window-nav-shared.css). P4 (2026-10-07): done: liquid --lgk-target-luma .38 → .30 and the adaptation floor ×0.42 → ×0.30 in kit.js, so label-carrying liquid glass lands in L 70–90 over bright rooms; your tone-layer workaround can go after a re-render.

  • REQ C1a->V1: device/defaults.json: add C1a's flag quietBacking: "window" (values "window" | "off"; WN §3.4.1, §11). The runtime's built-in default is "window", so nothing breaks before you add it. Why: PLAN §1.17's rule (a safe default behind a flag) for the quiet legend's legibility.

  • REQ C1a->Coordinator: PLAN §1.10 says the quiet legend has "no capsule material, labels Medium white .70". On window routes its labels sit in the margin over the room, where that look measures 1.3–1.5 : 1 over a bright room, below the must item VP P-39 (4.5 : 1). C1a ships a dim band behind them (black .62, blurred, not glass, no slab; labels white .82; 4.9–6.7 : 1) behind the flag quietBacking (WN §3.4.1, O3). Please add a note to §1.10, or rule otherwise. Also in §1.10: the library's slots "300 · 130 · 156 · 134 · 120 = 880 px" sum to 840; 880 is the capsule with four 4 px gaps and 12 px padding (WN §3.4.1 says so). WN §11 O1 (achievements window vs window-full), O2 (P-23's bound at 612 after A1) and O4 (= C2c REQ-7) also wait on you.

    • Coordinator (2026-10-07, round R2): the dim band is adopted into PLAN §1.10 with S27 (quietBacking, default "window") (R2-1); the slot sum is corrected (840 px of slots, an 880 capsule) and the library ornament now hugs its members by default, the fixed slots behind C2c's libFixedSlots (R2-2); O1: achievements stay window (R2-10); O2: P-23 is scored at 612 (PLAN §4.4, R2-11); O4: the source card drops to 0 with a glow (R2-3). See PLAN §1.19; WN updates are REQ Coordinator->C1a in wp/coordinator.md.
  • REQ C1a->C1b: window-nav-search.html: the builder now draws the quiet legend (A and B only) with the dim band in the margin; replace the inline .wn-quiet with data-wn="ornament" data-mode="laser" data-legends="A:Open|B:Back" and re-render, so the zero state matches WN §3.4.1 (your REQ #3). For More circles inside the sheet use data-inglass (no blur, P-45).

    • C1b (2026-10-07, R2 fix pass): done. window-nav-search.html uses data-wn="ornament" data-mode="laser" data-legends="A:Open|B:Back" (the inline .wn-quiet and its recipe lines are gone from both C1b mockups); re-rendered as shots/p2_c1b_mock_search_r2.png (the frozen p2_window-nav_search.png is left as it was): Open and Back sit on the dim band. The sheet now follows R2-6 (top 108, 488 tall). No More circle sits in the zero state; the results mockup's Top Hit circle is drawn without blur.
  • REQ C1a->C1c: please re-render window-nav-menu.html, -power.html, -alert.html, -sheet.html, -sort.html. Your static .wn-orn.quiet markup now gets the dim band from the shared CSS (checked on a scratch render of window-nav-alert.html: "Select" 1.2–1.4 : 1 before, 4.8–5.2 : 1 after). Switching to data-wn="ornament" is optional; data-modal on it recedes the page's members during alerts and sheets (WN §3.4.2).

    • C1c (2026-10-07 07:30): done. All five re-rendered with tools/mockshot.py (shots/p2_window-nav_{menu,sort,power,alert,sheet}.png); viewed the alert: "Select" now sits on the dim band and reads clearly. The static .wn-orn.quiet markup stays for now.
  • REQ C1a->C5a: game-pages.css .gp-foot.quiet draws the quiet legend in the margin as on-room text (white .92 + shadow). WN §3.4.1 (C1a, flag quietBacking) puts a dim band behind quiet labels on window routes, labels white .82 (on-room text alone measures 1.3–1.5 : 1 over a bright room). Please adopt the band (.wn-orn.quiet.band or the builder) on window routes; inside the glass (window-full) keep white .70. — C5a: adopted (C1a draws the legend and its quietBacking band; C5a-D6, wp/C5a.md).

  • REQ C1a->C6a: settings.css draws the quiet legend itself ("until window-nav-shared.js has the quiet variant"). The builder now has it: data-wn="ornament" data-legends="A:Select|B:Back" (plus data-mode="laser" for labels only) renders WN §3.4.1's quiet legend with the dim band in the margin of window routes (all settings pages). Please switch, or copy the band (black .62, blurred, labels white .82). C6a (R2 fix 1, 2026-10-07): answered. The live settings pages use your builder (C1a's quiet legend, nothing drawn by 60-settings.css). The mockups switch to data-wn="ornament" at C6a's M0 re-render, which is still open (review R2 appendix M8); until then settings.css keeps its copy of the band.

  • REQ C1a->C7: social-media.css .sm-quiet.room (white .96 on the room): on window routes (for example /chat or Downloads when the legend holds only A and B) use WN §3.4.1's dim band (.wn-orn.quiet.band or the builder); on /account (window-full) the quiet legend stays inside the glass at white .70, as social-media-account.html draws it.

  • REQ C1a->C2c: the shell's T1 is live (session 3): toolbar row in the CQ1 fallback, --lgs-hdr-pad (68px, 0 with html.lgs-hdr-108), --lgs-guard-top 124px / --lgs-guard-bottom 612px, #Footer 92 px with the capsule at y 628–712. Please (1) pad the library page root with padding-top: var(--lgs-hdr-pad, 68px) (today the tab row at y 52–86 sits under the search capsule at y 22–86: G-SIZE P-08 fails on four tabs and the VR sub-filter, "hit … other (%{SearchBox})"), (2) set scroll-padding-top / -bottom on %{TabContentsScroll} from the guard variables (window y, minus the scroller's own top), (3) place the laser-mode %{SortAndFilterContainer} in slot 1 on library routes (the shell has no generic rule: Steam renders it only inside GamepadTabbedPage, which only library routes show with sort/filter).

    • C1a (2026-10-07 19:28, session 6): (1) done by C2c (the tab row now at y 108-188, --lgs-hdr-pad honoured). (2) still open: c1a/t_at2.js on AllGames (pad, --flags wp.c1a,wp.p3): focused poster tops all ≥ 124 now, but three of six Down moves leave the focused poster's bottom at 639, 665 and 711 (> 612, behind the ornament): Steam's own scroll-into-view ignores the bottom bound; please add scroll-padding-bottom: calc(628px - var(--lgs-guard-bottom)) (16 px) on %{TabContentsScroll} or keep the focused row clear another way. (3) superseded by R2-2 (Sort & Filter is the toolbar's trailing group).
    • C1a (2026-10-07 08:14, session 4): still visible on the device: shots/p2_cmp_c1a_window-nav-anatomy.png shows the tab row under the Large Title and the search capsule; AT-2's guard fails on AllGames (focused posters at y 58–117 and bottoms to 881). CQ1 is settled: the 108 px header does not hold, so the padding is the only fix (padding-top: var(--lgs-hdr-pad, 68px) on the library page root, and scroll-padding-top: calc(var(--lgs-guard-top) - 40px), scroll-padding-bottom: calc(628px - var(--lgs-guard-bottom)) on %{TabContentsScroll}). The T2 APIs you build on are live behind wp.c1a: __LGS_RT.shell.ornamentSlots('library', …), __LGS_RT.more.register(…), the Options member (.lgs-opt, place it in slot 3), shell.target().
    • C2c (2026-10-07, R2 fix pass): (1) done since C2c session 2: the library's header rows sit below the toolbar row by --lgs-hdr-pad (tab row y 108-188, sub-filter 188-268, grid from 270). (2) done and corrected in R2: %{TabContentsScroll} has scroll-padding-top / -bottom from --lgs-hdr-pad and --lgs-guard-bottom plus 8 px for Steam's x1.053 focus growth, and padding-bottom 116 px, so the last row (and the Collections tab's second row, which could not scroll) scrolls above 612 (review C2c R2 Q5; evidence in wp/C2c.md). (3) superseded by PLAN R2-2: Steam's laser pill is the toolbar row's trailing group (D-C2c-12), not slot 1.
  • REQ C1a->C3a: PLAN §6 two-step move, step 1 done: the frame-menu rules are in theme/20-shell.css §4, scoped to %{DashboardMenu}%{Variant_FrameMenu} (live since session 3). Please delete or scope to %{Variant_TabMenu} the frame-menu parts of 30-bar.css §3 (the %{Variant_FrameMenu} radius rule and the unscoped %{DashboardMenu} … row rules, which today also reach the frame menu: the Active label's !important dark colour and background-clip: text needed a more specific override in 20-shell.css). The floating footer stays yours: the shell's #Footer rules exclude %{FloatingVRFooter} and %{QuickAccessFooter}. C3a answer (2026-10-07, session 2): step 2 done: 30-bar.css §3 is rewritten and every %{DashboardMenu} rule is scoped to %{Variant_TabMenu} (no unscoped row rules, no %{Variant_FrameMenu} rule, no !important dark Active colour or background-clip: text on the menu label any more); the floating footer stays in 35-hud.css §3.

  • REQ C1a->C1b: PLAN §6 two-step move: please copy Phase 1's search-route rules (theme/20-shell.css §6 "Search route", everything under %{GamepadSearch}) into your theme/21-search.css (or replace them with your M2 rules) and tell me here; I then delete §6. The header field itself (#header %{SearchAndTitleContainer}, all three variants) stays in 20-shell.css (WN §3.2; data-lgs-search="capsule|nested|circle" on %{BasicUiRoot} from the shell's route map; /search* = nested).

    • C1a (2026-10-07, R2 fix pass): C1b took the rules (REQ C1b->C1a #9); §6 deleted from theme/20-shell.css and %{GamepadSearch} dropped from §1's clear list.
  • REQ C1a->C1c: PLAN §6 two-step move: theme/20-shell.css §5 (the app-details overlay scrim, %{PartnerEventOverlayContainer} %{Container>TransitionWrapper} → var(--lgs-scrim)) belongs with your sheets; please take it into 22-presentations.css and tell me, then I delete it. The route-transition wrappers (%{TopLevelTransitionSwitch}, %{ContentWrapper}%{TopLevelTransition}, %{AbsoluteDiv}) stay cleared in 20-shell.css §1 (backgrounds only; your 23-transitions.css owns their motion). Also for your modal rules: #Footer is now 92 px (Steam's --gamepadui-current-footer-height 92), so ModalPosition.FooterVisible ends at y 628.

    • C1c (2026-10-07 07:35): taken. theme/22-presentations.css §7 now carries %{PartnerEventOverlayContainer} %{Container>TransitionWrapper} (scrim colour, and per WN §5.4 also backdrop-filter: none !important, Steam's opacity transition kept); live since the 07:35 sync. You can delete §5. Footer note taken: with --gamepadui-current-footer-height 92 C1c's formulas still give the menu box y 108–616, alerts centred at 328 and sheets ending at 596 (they read Steam's variables, no constant).
    • C1a (2026-10-07 08:13, session 4): step 2 done, §5 deleted from theme/20-shell.css (a one-line pointer to 22-presentations.css §7 stays); check-theme PASS, synced.
  • REQ C1a->C6a: the shell's T1 is live: please pad the settings page root (sidebar and content) with padding-top: var(--lgs-hdr-pad, 68px); on /settings/system today the sidebar's first row (y 40–83) sits under the Back control at (24, 24)–(84, 84). Scrollers: scroll-padding from --lgs-guard-top / --lgs-guard-bottom (window y). C6a (R2 fix 1, 2026-10-07): done in session 1: sidebar list padding-top: calc(var(--lgs-hdr-pad, 68px) + 40px) (first row at y 108), content calc(var(--lgs-hdr-pad, 68px) + 48px) (y 116); both scrollers take scroll-padding from --lgs-guard-top / --lgs-guard-bottom. Gates on /settings/system pass in both modes (review R2, 16:39/16:40).

    • C1a (2026-10-07 08:14, session 4): still visible (shots/p2_cmp_c1a_window-nav-ornament_live.png: the sidebar's "System" row under Back, the page heading under the search capsule). CQ1 is settled: the 108 px header does not hold, so padding with --lgs-hdr-pad (68px) is the fix.
  • REQ C1a->C7: the shell's T1 is live: please pad your page roots (/library/downloads, /media/*, /chat, /account) with padding-top: var(--lgs-hdr-pad, 68px) where your top row would sit under the toolbar controls (Downloads' own header leaves room today; check the others), and use the guard variables for scroll padding.

  • REQ C1a->C5a: the shell's T1 is live: game-page and Properties roots need padding-top: var(--lgs-hdr-pad, 68px) where their top row would sit under the toolbar (hero art may stay full-bleed under it; the Back control becomes clear glass on data-lgs-glass="hero" once the shell's T2 runs). — C5a: done in T1 (hero full-bleed; achievements header at y 108; Properties pane at --lgs-hdr-pad + 48; C5a-D8).

  • REQ C1a->P10: (1) gates OUTLINE no longer measures the main window's top edge: the window's tint is now %{BasicUiRoot}'s sized background-image (so the AUD contrast model, which composites ancestor backgrounds only, still sees it), and its E3 edge is P4's hook on ::before. Please treat an element whose computed --lgs-edge is not empty (P4's hook) as glass and profile its top edge. (2) Note for the AUD model: backgrounds drawn on pseudo-elements or limited by background-size are not composited (the ornament capsule and the window's sheen are pseudo-elements); the shell keeps the window tint on the root for that reason.

    • P10 (2026-10-07 06:35): done. OUTLINE treats an element whose computed --lgs-edge is not empty as glass (and probes its top edge); a plain black tint (r = g = b = 0, alpha < .5) without a backdrop filter or the hook is not glass. (2) noted: AUD composites only ancestor background colours and the first gradient stop; pseudo-elements and background-size are not modelled. contracts/lab.md §4.
  • REQ C1a->P10: lab/exemptions.json: please add "E-TAB": ["%{DashboardMenu}%{Variant_FrameMenu} %{DashboardMenu>Item}"] (PLAN §1.16: tab-bar items, criterion pitch ≥ 52 frame-menu px at the live window size; WN §3.3.2). Today gates frame.menu fails P-80/P-08 on every item ("visible short side 52 < 54", "hit 76 % own … over 72x72"): the rows are contiguous at the live pitch by design (VP P-07), so the 72 × 72 probe always reaches the neighbour. The E-TAB check: each item's height ≥ 52 and the items abut (no gap). Also E-BACK for #header %{BackContainer}[data-lgs-exempt="E-BACK"] comes from the shell's T2 attribute, no file entry needed.

    • P10 (2026-10-07 06:35): done: E-TAB added as given; each exempt item is checked against its criterion (height ≥ 52, abutting the next item: gap ≤ 2) and listed under SIZE exempt with pass/why; a failing criterion fails G-SIZE. E-BACK is read from the attribute (criterion: aria-label set, centre hit own).
  • REQ C1a->P1: device/lgs_core.js caches window.__LGS_INDEX once built. On 2026-10-07 at about 06:51 it was cached with 3 CSS modules (classModules: 3, 735 unresolved tokens: the theme was broken on every Steam window and every rt.sel failed; shell install failed on %{BasicUiRoot}), and lgs on / reload kept reusing it. Please rebuild when the cached index is implausibly small (for example size < 100; the healthy value today is 550) or when a token the core itself needs (BasicUiRoot) does not resolve, and report it in status. C1a cleared it by hand (delete window.__LGS_INDEX, then glass.py reload).

    • P1 (2026-10-07 08:20, review R1 M1): done. The index is cached only when plausible (>= 200 CSS modules, at most half the theme's tokens unresolved) and only while current (same factory count as when built; a new chunk rebuilds it); a bad cached one (also from an older build) is dropped and rebuilt by the next lgs on, and by off + on. lgs on first waits for Steam's UI and a plausible harvest (backoff 2, 4, 8, then 15 s, 120 s), logging each attempt to /tmp/lgs/lgs.log, and changes nothing when it gives up. lgs status reports index: {state, size, factories, current, cached}. Live test RT-I (planted 3-module cache rebuilt; forced short harvest gives up without changes). Contract runtime.md §5.
  • REQ C1a->P10: lab/lab_helpers.js captures window.__LGS_INDEX at install (const index = …), so after a bad index the helpers keep it even when the core rebuilds (every %{…} in L.q, outline, classes failed until __LGS_LAB was dropped). Please read window.__LGS_INDEX at call time, or reinstall the helpers when the index object changes.

    • P10 (2026-10-07 08:15): done: the helpers read window.__LGS_INDEX at call time (IX() in lab_helpers.js; L.index is now a getter), so a rebuilt index is used at once (live: L.index.selector present after the change).
  • REQ C1a->P10: two lab false positives on Steam's #header that V2 would record against the shell (review R2 m9): (1) P-82 on /settings/system (pad) reads #header's innerText, which is E-BACK's hidden Back label (no Large Title on that route): please make P-82 E-BACK-aware (ignore the [data-lgs-exempt="E-BACK"] label, which aria-label carries); (2) G-SIZE P-80/P-08 on /controller/calibration/0 measures %{Profile>Header} (1280 × 40) as a control: #header is pointer-events: none, a nav container whose children take the clicks; please skip containers with pointer-events: none (and no click handler of their own) as targets.

  • REQ C1a->P6: theme/layers/00-base.json frame.menu is laserOnly: true; with C1a's tabBarAlways (popups/20-shell.json, only_visible_with_laser: false) the tab bar shows in gamepad mode too, without a glassd cover (review R2 m5). Please let laserOnly follow the frame menu's live visibility (or the tabBarAlways flag). C1a's fragment owns frame.menu but cannot key one field on a second flag. Not urgent: tabBarAlways stays off until AT-7/AT-20 pass.

  • REQ C1a->P10: glass.py cmp cannot take a live shot of a vr: surface: an entry with "surface": "vr:systemui" (C1a-cmp.json window-nav-chrome-row) fails with "lab: no CEF target for surface 'vr'" because the live step's --capture SURF:NAME is split at the first colon (lab_p2cmd.py cmp_rects). C1a ran it offline (a shot vr:systemui plus rects read with js --in vr:systemui into --live-rects). Please split at the last colon (or pass the surface separately). Also, hv measures only the auto rect unless --rect is given before the frame is seen; a --look step that also accepts a rect afterwards (or prints the metrics for a rect given with the look) would let one look give the G-HV verdict (C1a ran tools/p2/hv_metrics.py on the look file within its 120 s).

  • REQ C1a->C1c (FYI, no change asked of C1a's files): in native mode (session 6, 18:5x, --flags wp.c1a,wp.p3,wp.p6,tabBarAlways --mode pad, AllGames, the window lifted into view with a lab-only P7 override) the headset frames with MENU up and with CONFIRM up show the posters through the menu's and the alert's slabs: the menu labels sit on the page with little backing, and the alert's card reads as clear glass over the posters, with a second curved edge to its right. CSS-only shots of the same states are fine. Worth a look in your native evidence (G-HV for menus and alerts); frames were looked at and deleted.

    • C1c (2026-10-07 20:25): thanks; native menu/alert backing is listed as open in C1c's Status for its next native session (G-HV).
  • REQ C1a->C2c: AT-2's scroll guard still fails on AllGames after your R2 fix (2026-10-07 19:28, js <c1a/t_at2.js> --flags wp.c1a,wp.p3 --mode pad, native=off): six Down moves from the first poster leave the focused poster at y 267-539, 339-611, 339-611, 368-639, 393-665, 339-611, 440-711, so three bottoms pass 612 and sit behind the ornament (tops are all ≥ 124 now). Steam's own move scrolls the grid only as far as it needs, apparently not reading scroll-padding-bottom on that step; please check which element scrolls on a gamepad move in the grid and keep the focused row's bottom ≤ 612 (your 116 px padding-bottom lets the last row get there, but the rows above stop lower).

  • REQ C1a->Coordinator: (1) /tmp/lgs/flags.json has held a session flag wp.c1a: true since at least 18:46 with no lab step record of its own (not set by C1a; details in session 6, "Device left"); every module behind wp.c1a runs for everyone until lgs flags wp.c1a=default. Please clear it when no step is running, or say if it was set on purpose. (2) Review R2 m13 (VP P-73, a should: a scroll edge under the bottom ornament) is disputed in session 6 ("Disputed or deferred"): please rule.

  • REQ C1a->C3a: theme/vr/pre/sys_zoo.js clones every :hover rule of the page with its whole cssText into #lgs-vr-zoo-style, SteamVR's own :active button rule included (transition-duration .04s); because the sheet's id starts with lgs-, gates vr:systemui --pre sys_zoo.js then fails MOTION ("transition-duration 0.04s (not a token)") for every SteamVR area (C5b's reviewer, N1, found the same in np_states.js). Please clone the declarations without transition* (C1a's sys_hover.js now does: Array.from(r.style).filter((p) => !p.startsWith('transition'))). With a scratch copy stripped that way the zoo gate's MOTION is clean (C1a session 6).

Requests to C1a, handled

All answered in the requester's log on 2026-10-07 (session 2); the answer follows each request line there.

Request Answer, in short
C1b #1 (WN §4 and line edits) Merged; §9.1 got an Owner column (H3 tier T1–T3, AT-3 added to H4)
C1b #2 (builder) Done; data-inglass on the More circle; the quiet legend in the builder
C1b #3, C1c REQ 4 (quiet legibility) Dim band on window routes, flag quietBacking, labels white .82; note to the coordinator
C1b #4 (search route map) search, window, no Large Title, the 640 field; Large Title node #header > .lgs-title; the Back reveal names NavigateBack's page
C1c REQ 1 (Appendix A) Merged; the glow row cites P4's --lgs-white-glow; AT-21 and AT-23 split
C1c REQ 2 (recipe into the shared CSS) Adopted, scoped to .wn-menu, .wn-alert, .wn-sheet; a legacy .chk rule kept for mockups not yet moved
C1c REQ 3 (builder: laser A/B, quiet) Done
C2c REQ-3 (no suffix in slot 3) Adopted; #Footer[data-lgs-orn-fixed]; the More circle stays on the target
C2c REQ-4 (Options member) Adopted: keeps its slot; disabled without ≡, without a target, and during any modal
C2c REQ-5 (fixed backing, recede) __LGS_RT.shell.ornamentSlots('library', {widths, gap, padding}); recede on html.lgs-modal
C3a (WN text) Merged (§3.5.3, §5.5, §5.6, §8.1, §8.4, §3.5.2 tooltips thick, AT-18)
C2a #1 (Home's glass mode) windowless only while C2a's glassMode('home') hook answers, else window-full; refreshGlass()
C2a #2 (toolbar plates) The shell tags shell-back and shell-search as liquid plates on every windowless route
P4 (vr/10-systemui.css §0) Accepted, deferred to C1a's first M2 session (M0 is documents only); answered in P4's log
Round R2 (2026-10-07, fix pass; answered in each requester's log)
C1b #9 (delete §6) Done: §6 and %{GamepadSearch} in §1 deleted
C1c (modal-time will-change) No objection; the remaining tab-row isolation is the row's own 3D context (C2c)
C2a-R2 (windowless toolbar) Back and the search field are CSS plates over the room on windowless routes (review R2 M4)
C2c REQ-9 (trailing group) The area right of the search capsule stays free on library routes; WN §3.2 row; ≥ 20 px is C2c's cap
C3b (CC-M tint) --lgs-c1a-tint frozen as an interface name
C5b, C6b (vr:systemui OUTLINE) Fixed (review R2 M1); see session 6
C6a (search over the sidebar) Settings routes centre the capsule at x 840
P4 (High Contrast tint) --lgs-c1a-tint: var(--lgs-mat-window-tint)
P6 (literal paints) Told: the ornament and the windowless toolbar are plates; §4c and P6's ack clear their CSS paint
P7 (frame-menu cover radius) "r": "capsule" on the cover (review R2 M2)
Coordinator (R2-1/2/3/5/10/11) WN and the five mockups updated and re-rendered

Log

2026-10-07, session 1: M0 conformance

  • Start-of-session request check: grep -n "REQ [A-Za-z0-9]*->C1a:" docs/phase2/wp/*.md → no docs/phase2/wp/ directory yet; no requests.
  • No device steps this session (M0 is documents and mockups only).
  • Work (in checkpoint f5190bb): window-nav.md revision 3 (§0 conformance table, route map §3.1.1, CQ1 classes and the scroll guard in §3.2, §3.3.4 states, the §3.4 contract with capsule and quiet legend, the §3.4.4 More helper, §3.6 proxy in native mode only, §3.7 depth plan, §3.8 strings, §11 decisions, §12 status column, §13 AT-24 to AT-28 and PLAN-1a-1 to -3); the shared builder kept A/B in laser mode and drew the quiet legend and compact members; the anatomy and tab-bar mockups re-rendered. The session was cut off before the Status, the request answers and §13.1 were written.

2026-10-07, session 2: M0 completed (05:08 onward)

Steam build 11094443. No device step: M0 is documents and mockups only; the device was not touched.

  • Start-of-session request check: grep -n "REQ [A-Za-z0-9]*->C1a:" docs/phase2/wp/*.md → C1b #1–#4, C1c ×4, C2c REQ-3/4/5, C3a ×1, P4 ×1; C2a #1 and #2 appeared during the session. All handled (table above).
  • Concept text (docs/phase2/concepts/window-nav.md): C1b's §4 and line edits, C1c's Appendix A and C3a's text merged (scripts read the text from the requesters' logs, so it is verbatim). C1a's own changes: §3.1.1 Home's conditional mode and the glassMode / refreshGlass hooks (C2a), the search row (C1b #4); §3.2 the Back reveal's target, the Large Title selector, the windowless toolbar plates (C2a #2); §3.4.1 the fixed-slots API and the dim band; §3.4.2 the Options member's slot, disable and modal rules and the recede during alerts and sheets; §3.4.3 no suffix on fixed slots; §3.4.4 no blur inside glass; §3.7 the source-card conflict (O4); §10 tier rows; §11 the quietBacking row, O3, O4; §13 AT-6, AT-24, AT-25, AT-26 updated, AT-29 new, the C1b, C1c and C3a rows; §13.1 measurements.
  • Decision under PLAN §1.17's rule: the quiet legend's dim band on window routes (flag quietBacking, default "window"). It is the safe default because P-39 is a must item and the band keeps "no capsule material" (it is not glass and has no slab). Note to the coordinator filed.
  • Shared mockup chrome (docs/phase2/mockups/window-nav-shared.css, window-nav-shared.js): C1c's recipe; data-slots; the dim band (.band; data-quiet="bare" for the comparison); data-modal; the More circle's data-inglass; the shell's states on P4's normal compositing with --wn-focus-add: .32 (pending P4); a tone layer that holds the shell's liquid glass at L 70–95; .wn-tab.is-nav-selected without the kit's row arc (after P4's kit change it drew a line across the row). Checks: node -e "new Function(src)" → parse ok; CSS braces 166 / 166.
  • Mockups and renders (each python tools/mockshot.py docs/phase2/mockups/window-nav-<name>.html shots/p2_window-nav_<name>.png --rects <scratchpad>/c1a/rects_<name>.json; final pass at 05:27, after P4's kit change of 05:24; every image viewed):
    • anatomy, anatomy-t1, anatomy-depth: the library's fixed slots, no suffix. Viewed: ornament 880 at (200, 628), the More circle inside the dwelled card, quiet frame controls, edges as §13.1.
    • ornament: rebuilt as five strips (gamepad fixed slots; laser and the frozen target; Downloads with the suffix and a row's More circle; the quiet legend on its dim band beside the bare look; the window-full quiet legend). Fixed after the first renders: a More circle above the clip, the band over a dark wall (the board moved so the legend sits over the bright window), page content under the legend (trimmed to what ends at 628), the row circle's centre (602 → 562).
    • tabbar: G-FOCUS failed at .28 (+35.2 / +7.6) on the kit's bright glass; tone layer added and focus at .32 → PASS (§13.1); a stray row line from the kit's new .is-nav-selected arc removed.
    • tabbar-r863: gamepad mode with the focused card and its More circle; the fixed-slot ornament with glyph badges.
    • chrome: the fixed-slot ornament; a thick tooltip; the More circle white while More Options is open, focus on its first row.
  • Measurements: python docs/phase2/concepts/window-nav-measure.py edge|focus … (values in WN §13.1). Contrast with the scratch script <scratchpad>/c1a/contrast.py (WCAG luminance ratio, the brightest 2.5 % of a label's box against its 60th-percentile background). The worst case comes from a scratch copy of the ornament board with the band over the curtain (<base href> to the mockups folder; not in the tree).
  • Late change: the dim band now also applies to static .wn-orn.quiet markup (not only the builder's .band), so C1c's five mockups get it without edits; scratch render of window-nav-alert.html (not saved to shots/): "Select" 4.8–5.2 : 1, was 1.2–1.4. ornament re-rendered after it (unchanged values).
  • New strings: none this session (the Options member and the More circle use Steam's ≡ legend string; WN §3.8).

2026-10-07, session 3: M2 (T1) on the device (05:32 onward)

Steam build 11094443. Device steps only through python glass.py … (locked); no native session; the device was left with the theme on (CSS-only), stock route /library/home, nothing open.

  • Start-of-session request check: grep -n "REQ [A-Za-z0-9]*->C1a:" docs/phase2/wp/*.md → only P4's (vr/10-systemui.css §0) open; done and marked in wp/P4.md (below).
  • theme/20-shell.css rewritten (Phase 1 copy kept in the scratchpad as c1a/20-shell.phase1.css): §0 interface values, §1 window glass by mode, §2 toolbar row (CQ1 fallback), §3 ornament, §4 tab bar, §5 app-details scrim (held for C1c), §6 Phase 1 search route (held for C1b). Every save: python glass.py check-theme → PASS; python glass.py sync theme.
  • Findings that shaped the CSS:
    • P10's AUD contrast model composites only ancestors' background-color / first background-image stop over the room: a window tint drawn on a pseudo-element made every text on main read as bare room (CONTRAST 6.3 → 1.5 on Back and the legend labels). The tint is therefore %{BasicUiRoot}'s own background-image, sized to the glass height, with four tiles for the rounded bottom corners at y 656; the sheen and E4/E5 shade stay on ::after (z −1). REQ C1a->P10 (gate model notes).
    • #Footer is reused by the floating footer and the Quick Access footer: every ornament rule is %{BasicUiRoot} #Footer%{BasicFooter}:not(%{FloatingVRFooter}, %{QuickAccessFooter}).
    • The legend row is FooterLegend > [%{PopupBody>Spacer}, legend…]; the spacer is collapsed (flex: 0 0 0) so the capsule centres.
    • Steam uses %{BackContainer}::after for its divider, so Back's light is drawn on its own ::before fill (not P4's ::after hook).
    • The frame menu's rows had Steam's 6 px group-end radii (notches at the SectionGap): border-radius: 0 !important, capsule ends !important. C3a's unscoped %{DashboardMenu} Active-label rule (!important dark text, background-clip: text) needed a more specific override (REQ C1a->C3a).
    • Steam zooms the focused tab-bar item (its own transform): the focus pill's side inset is 18 px so it stays inside the capsule.
    • P4's edge hook (03-material.css) is not bundled into SteamVR pages: the frame-control capsule gets E4/E5 + the lit top lip instead.
  • theme/vr/10-systemui.css: §0 deleted (P4's REQ; check: python glass.py js "…" --in vr:systemui → one copy of the block in the live bundle, --lgs-vr-scale 1.45 and every other --lgs-vr-* resolve). Window bar: white .46 pill, soft shadow, no ring, white .92 on hover/drag; no transition of ours (SteamVR's own transform timing). Frame controls (WN §3.5.2): one panel capsule, buttons 107 × 107 (padding 35.5, glyph 36; the panel grows with the DOM, E16), 80 px circles at white .06 (hover +.08, focus +.28 with the spot and arc), glyphs white .70 → white. Tooltips: thick tint .80, 30 px Semibold.
Test Command Result Shots / JSON Date Steam build
AT-1 python glass.py status 0 unresolved, 0 ambiguous (Steam windows and both SteamVR pages) — 2026-10-07 06:02 11094443
G-AUD/SIZE/TYPE/OUTLINE, main AllGames, both modes python glass.py gates main --route /library/tab/AllGames --mode pad|laser --json Shell nodes clean (header, Back, search box 536 × 80, #Footer, legends, glyph badges). Remaining findings are C2c's: tab row and VR sub-filter P-08 (under the search capsule until the library root is padded, REQ C1a->C2c), tab type 12 px uppercase, 9 SHRUNK tab texts. OUTLINE PASS. MOTION (not an M2 gate): one Steam poster animation running; in laser mode another package's lab fixtures left lgs-* animations scratch c1a/g_ag_{pad,laser}.json 2026-10-07 06:12 11094443
Same gates on /library/home, /settings/system, /library/downloads, /media/grid, /library/app/1147940, both modes (--only aud,size,type,outline) as above, per route Shell nodes clean on every route and mode, except one finding that is not the shell's CSS: /settings/system (laser) a settings Field's P-08 hit 23 % on the search box (the settings root is not padded yet, REQ C1a->C6a). Two runs (Home laser, app pad) showed CONTRAST 1.5 on every text of the page, the shell's included: the window tint was absent during that snapshot (another agent's step had the root windowless or the theme mid-reload); reruns clean (/library/app/1147940 --only aud: only C5a's tab SHRUNK; Home pad: only %{SeasonalSale} P-08) scratch c1a/g_*.json 2026-10-07 06:20–06:28 11094443
G-AUD/SIZE/TYPE/OUTLINE, frame.menu, both modes python glass.py gates frame.menu --route /library/downloads --mode pad|laser --json AUD, TYPE, OUTLINE PASS; SIZE 17 findings, all tab-bar items: "visible 52 < 54" and P-08 against the neighbour row: the E-TAB exemption (PLAN §1.16, pitch ≥ 52 at the live window size) is not in lab/exemptions.json yet (REQ C1a->P10). Blocked on P10 for the gate's PASS line; the items meet E-TAB (pitch 52, rows abut) scratch c1a/g_fm_{pad,laser}.json 2026-10-07 06:16 11094443
G-AUD/SIZE/TYPE/OUTLINE, vr:systemui (window-bar row), both modes python glass.py gates vr:systemui --mode pad|laser --json PASS (4 controls at 107 × 107, m 1.33); MOTION's only finding was the grab bar's transform .08s in our transition list, removed (SteamVR's own timing stays) scratch c1a/g_vr_{pad,laser}.json 2026-10-07 06:24 11094443
Same, floatingfooter python glass.py gates floatingfooter --only aud,size,type --json PASS, 0 controls (the hint is empty while the dashboard has focus; its look is C3a's). The full gate's capture times out on the hidden popup scratch c1a/g_ff.json 2026-10-07 06:26 11094443
AT-23 (window, ornament) python glass.py edge <shot over room-studio> 1 120 1800; … 942 560 1360 Window top edge 56, 72, 94, 94, 51, 24, 4, −1 → ratio 0.02 PASS (mockup 45, 61, 80, 82, 43, 17, 1, −3); ornament top edge 43, 52, 56, 95, 36, 7, 3, 1 → 0.03 PASS shots/p2_c1a_allgames_t1.png (+ scratch c1a/ag_room.png) 2026-10-07 06:22 11094443
Live looks (viewed) shot main p2_c1a_allgames_t1 --route /library/tab/AllGames, p2_c1a_settings_t1, p2_c1a_downloads_t1; shot frame.menu p2_c1a_tabbar_rest, p2_c1a_tabbar_focus (pre: L.root(); L.pad('left'); L.pad('up',3)); shot vr:systemui p2_c1a_winbar_rest Glass ends at 656 with rounded corners, content clipped at the glass edge, ornament capsule 628–712 straddling it, badges as white .16 discs; tab bar = two capsules, the current route a .18 circle, the focus pill distinct (Library focused, Downloads current); frame-control capsule quiet at rest. Shots composited over room-lounge.jpg / room-studio.jpg for viewing (scratch c1a/onroom.py) shots/p2_c1a_*.png 2026-10-07 06:05–06:24 11094443

M3 (T2) on the device, session 3 (06:30 onward). New files: device/rt/20-shell.js (module shell), device/rt/20-more.js (module more, deps attention, shell), device/rt/20-pointer.js (module pointer), all behind wp.c1a; node --check and glass.py check-theme PASS before every glass.py sync device + glass.py reload. Probe: the footer legends carry rgButtons in their React props (Select 0, Back 1, Filter 2, Sort By 3, Options 11), read for data-lgs-btn. Test scripts are in the scratchpad (c1a/t_*.js), each run as one locked glass.py js step.

Test Command Result Shots / JSON Date Steam build
Route map (AT-28 attributes), ornament tags glass.py js "<c1a/t_routes.js>" --flags wp.c1a AllGames window/library/capsule, /settings/system window/settings, Home window-full (no hook), Downloads window + Large Title "Downloads", /library/app/1147940 hero, /media/grid window + "Media", a collection window nested; legends tagged (SECONDARY OPTIONS MENU OK CANCEL); lgs-hdr-40; Back aria-label = Steam's text + data-lgs-exempt="E-BACK" — 2026-10-07 06:56 11094443
AT-6 <c1a/t_m3.js> --flags wp.c1a --mode pad and --mode laser PASS both modes: #Footer y 628, 92 tall, --gamepadui-current-footer-height 92px (after removing Steam's 1 px top border), capsule 84 at y 628, centred within 2 px (814 wide in pad, 614 in laser with the badges collapsed; ≤ 960), members 84 hit, data-lgs-orn="capsule". Note: WN asks ±1 for the centre; measured 2 px (sub-pixel member widths) — 2026-10-07 07:05 11094443
AT-28 same step: 10 L.pad moves on AllGames and /settings/system PASS both modes: data-lgs-glass never changes (AllGames one state; on settings data-lgs-orn follows the legends quiet / capsule, the glass stays) — 2026-10-07 07:05 11094443
PLAN-1a-1 same step (+ /account, attributes only, no shot) PASS both modes: AllGames capsule; /settings/system at rest quiet (OK, CANCEL); /account quiet, window-full; no legend with display: none — 2026-10-07 07:05 11094443
Hooks and slots <c1a/t_api.js> --flags wp.c1a PASS: ornamentSlots('library', {widths: [300,130,156,134,120], gap: 4, padding: 12}) → data-lgs-orn-fixed="library", capsule x 200, 880 wide, y 628, 84 tall; removed cleanly; glassMode('home') → windowless, a null or throwing hook → window-full; glassMode('*') wins, its removal restores window — 2026-10-07 07:08 11094443
AT-22 (shell part) <c1a/t_at22.js>: rt.test.flags.push({'wp.c1a': true}), then pop PASS: on → data-lgs-glass/route/search/back on the root, 4 data-lgs-btn, data-lgs-orn, E-BACK, .lgs-title, lgs-hdr-40; off → none of them left, aria-label restored, module off — 2026-10-07 07:10 11094443
AT-0b (CSS-only part) <c1a/t_ptr.js> --flags wp.c1a PASS: CSS-only (no lgs-native) → 0 .lgs-pointer nodes after pointer moves; with pointerProxy=on (test overlay) the ring follows the pointer (centre at the event point, pointer-events: none, hit testing passes through); after the overlay → 0 nodes. The native part waits for M4 — 2026-10-07 07:16 11094443
AT-26 <c1a/t_more.js> --flags wp.p3,wp.c1a --mode laser; <c1a/t_more_pad.js> … --mode pad (a test registration on %{LibraryItemBox}; C2c registers for real) PASS both modes: laser dwell 450 ms on a poster → the circle, 80 box, visible 60 at inset 10 top and right, shell.target() = the poster, backdrop-filter: blur(10px); a click on the circle opened the poster's own menu, route unchanged, the circle white while it is open, 1 node per document. Pad: gamepad focus on a poster → the circle inside the focused card at once; its menu opened. The lab closed the menus. aria-label is empty in laser mode (Steam shows no ≡ legend there, so there is no Steam string on screen to reuse; PLAN §1.15) — 2026-10-07 07:25–07:30 11094443
AT-5 glass.py js (nav Home, AllGames, then L.click('main','%{BackContainer}')) PASS: /library/home — 2026-10-07 07:38 11094443
AT-29 (+ G-AUD with T2) glass.py gates main --route /settings/system --flags wp.c1a --only aud PASS: 0 issues (quiet legend on the dim band: ::after black .62, blur 7, 60 tall, labels white .82; CONTRAST 0). The first run found SHRUNK on the search circle variant (1128 × 40 → 80 × 80): the circle is now behind the flag searchCircle (decision above) scratch c1a/g_at29b.json 2026-10-07 07:44 11094443
Chrome gates with T2, Downloads, both modes glass.py gates main --route /library/downloads --flags wp.c1a --mode pad and --mode laser, --only aud,size,type,outline Shell nodes clean; Back listed as exempt E-BACK (the gate reads T2's attribute); the Large Title passes TYPE. Remaining findings are C7's page scratch c1a/g_t2_dl.*.json 2026-10-07 07:35 11094443

| G-AUD/SIZE/TYPE/OUTLINE, frame.menu, both modes (rerun) | glass.py gates frame.menu --route /library/downloads --mode pad and --mode laser, --only aud,size,type,outline | PASS both modes: SIZE 0 findings, 9 items exempt E-TAB with pass (52 tall, abutting); TYPE, OUTLINE, AUD 0 | scratch c1a/g_fm2_{pad,laser}.json | 2026-10-07 07:52 | 11094443 | | Ledger (REQ P10->C1a) | glass.py ledger --out <scratch> | PASS: 268 of 268 audit functions mapped (WN §9.6's toast row split so the id column reads T1) | scratch c1a/ledger.csv | 2026-10-07 07:50 | — |

New strings (PLAN §1.15): none. The Large Title reuses the frame menu's own localized item labels; Back's aria-label is Steam's Back text read from the node; the More circle's aria-label reuses the ≡ legend's label when Steam shows it.

2026-10-07, session 4: M3 (T2) continued (07:11 EDT onward)

Steam build 11094443. Times in this section are the PC's clock (EDT). The session 3 table's times run about 45 min later than the files' modification times; treat them as approximate. Device steps only through python glass.py … (locked); no native session.

  • Start-of-session request check: grep -n "REQ [A-Za-z0-9]*->C1a:" docs/phase2/wp/*.md → 17 lines, all already [x] (C1b #1–#4, C1c ×4, C2a #1/#2, C2c REQ-3/4/5, C3a, P4, P10 ledger). Nothing open.
  • Dependencies: P1, P2, P3 report M3 (P1, P2 and P3 complete), so M3 work continues. P8's geom is live on rt.bridge (r 1, Hm 0.5535, frameMenu.mpMm 0.847 at 07:12); P10's focus (live) and cmp are live now.
  • Tab bar, live pitch (T2, WN §3.3.2): 20-shell.js reads P8's geom (rt.bridge.on('geom')) and the number of %{DashboardMenu>Item} nodes, applies the rule (G = 656·Hm/720/mp, P = Hm/mp, H(p) = n·p + 44) and writes --lgs-tab-pitch / --lgs-tab-place on the frame-menu document's root (removed with the module). Today n = 9 (Console off), r 1, mpMm 0.847: G 595.4, P 653.5, rule 2, p 66, H 638 (WN's table row "Developer mode off (n = 9), r = 1: p 66, H 638"). The live menu is 638 tall at y 81–719 of the 800 px popup, rows 66 (72 at the capsule ends with their 6 px padding). Since mpMm is measured from the live overlay (DumpLaserOverlays height × S / clip CSS height), the rule holds whether or not the popup follows the user resize; with r = 1 today AT-7 cannot tell which (no resize is allowed; recorded).
  • Tab bar, collapsed width (T1 fix found on the live shot): at p 66 the current-route circle (d = p − 8 = 58) overflowed Steam's fixed 54 px collapsed column (Steam's %{DashboardMenu>Collapsed} rule width: 54px; transition: width 300ms). WN §3.3.1 asks 12 px at the sides, so the collapsed width is now d + 24 (82 at p 66, 68 at p 52; only the value changes, Steam's transition and expanded width stay) and the capsule ends' radius is d/2 + 12 (concentric with the circles). Shots shots/p2_c1a_tabbar_p66.png (collapsed) and p2_c1a_tabbar_p66_hover.png (real CDP hover on Media: expanded, the light spot only), viewed against p2_window-nav_tabbar.png / _anatomy.png: two capsules, circles inside the capsule, ends concentric.
  • Options member (T2, WN §3.4.2–§3.4.3): a T2 node in #Footer with Steam's legend classes (.lgs-opt[data-lgs-btn="MENU"][data-lgs-t2]), placed before the quiet A/B members; laser look = leading ⋯ glyph + label + " · " suffix (the mockup's strip 3). Label: the target's own onMenuActionDescription (what Steam's ≡ legend would say for it, "Options"), else the last ≡ legend Steam rendered, else Steam's token #LibraryHome_GameCarousel_ContextMenu (LocalizationManager probe: no generic footer token exists; the poster's description equals that token's value). The frozen target re-focuses through its own nav node (BTakeFocus(3), mouse source) on the first pointerover inside #Footer; the More circle returns to the target while the pointer is in the ornament; the target clears on a route change and 8 s after the pointer left the window. modalUp reads main's m_ModalManager.m_rgModals and context menus.
  • Back reveal (T2, WN §3.2): rt.attend on Back (600 ms, P3) grows the circle into a capsule naming the previous page's section (Steam's frame-menu label); the Large Title fades while it shows. Steam's main history is a browser history (no entries), so the shell keeps its own stack of paths since install (PUSH, REPLACE, POP to the previous path; any other POP restarts it: no title, no growth).
Test Command Result Shots / JSON Date Steam build
Tab pitch (AT-7 computed part) glass.py js "<c1a/t_tab.js>" --flags wp.c1a PASS: rule 2, p 66 for n 9 at r 1 (WN table), --lgs-tab-pitch 66px, menu 638 tall, centred in the popup; off → 52 again. Not yet: tabBarAlways (V1's flag, only_visible_with_laser), resize-following (needs r ≠ 1) shots/p2_c1a_tabbar_p66.png, _p66_hover.png 2026-10-07 07:15–07:25 11094443
AT-25 (a) glass.py js "<c1a/t_at25.js>" --flags wp.p3,wp.c1a --mode laser --hover "#Footer,300" (C2c's ornamentSlots('library') and a test more.register('%{LibraryItemBox}'), as C2c will register) PASS: dwell 600 ms on poster A, 90 ms across B, pointer into #Footer → target A (not B), the More circle on A, 1 re-focus; Steam then rendered its own ≡ "Options" legend, so the T2 member stood aside (none in the footer); a click on Options opened A's menu (its header is A's title), route unchanged, modals 0 → 1 scratch c1a/t_at25_laser_real.out 2026-10-07 07:30 11094443
AT-25 (b) <c1a/t_at25b.js> --flags wp.p3,wp.c1a --mode laser (Downloads; two mock rows, placement: 'row'; the queue is empty; Steam's focus on Back so Steam shows no ≡, as under the real laser) PASS: before any dwell the member is shown disabled ("Options", no target); after A 600 ms, B 90 ms, into #Footer: "Options · Row A test item", enabled; its click dispatched to row A (vgp_onmenu, the mock has no Steam nav node); route unchanged; the row's More circle trailing, inset 24, centred (Δy 0) shots/p2_c1a_options_laser.png (viewed), scratch c1a/t_at25b.out 2026-10-07 07:35 11094443
AT-25 (c) in t_at25.js (CONFIRM over AllGames, html.lgs-modal set by the step because C1c's T2 is not live) PASS: the Options member present and disabled, its click dispatched nothing (modals 1 → 1, no menu); Options brightness(.65) + .38; A and B filter: none, opacity 1 scratch c1a/t_at25_laser_real.out 2026-10-07 07:30 11094443
AT-25 (d) <c1a/t_at25d.js> --flags wp.p3,wp.c1a --mode pad PASS: focus on a poster: Steam's ≡ "Options", no T2 member; Up to the tab row ("ALL"): Steam drops ≡, the T2 member shows disabled (opacity .38) in the fixed-slot ornament scratch c1a/t_at25d.out 2026-10-07 07:33 11094443
Back reveal <c1a/t_reveal.js> --flags wp.p3,wp.c1a --mode laser (AllGames → Downloads, hover Back) PASS (laser): at 350 ms none; at 1050 ms data-lgs-reveal, text "Library", box 80 → 143 wide (growing on snappy), Large Title opacity 0; after leaving: 80 again, title 1; aria-label stays "Back". Pad: Steam's D-pad never focuses Back (Left from the search field goes to the tab bar's Home; B is Back's gamepad path, WN §3.2), so the gamepad reveal never applies scratch c1a/t_reveal_{laser,pad}.out 2026-10-07 07:38 11094443
AT-2 (CQ1 trial) <c1a/t_at2.js> --flags wp.c1a,hdr108 --mode pad CQ1 settled: the 108 px header does not hold on build 11094443. The trial wrote --basicui-header-height: 108px !important (computed 108px) and HeaderStore.m_flCurrentHeaderHeight = 108 (inst().m_HeaderStore, read back 108), but Steam's #header box stayed 40 tall and the page scroller still starts at y 40 (%{TabContentsScroll} 0, 40, 1280 × 680): Steam lays pages out from its CSS-module constant (HeaderHeightVisible 40px), not from either value. The runtime reverted both writes (store 40, variable 40) and set lgs-hdr-40; exactly one class scratch c1a/t_at2_108.out 2026-10-07 07:45 11094443
AT-2 (fallback) <c1a/t_at2.js> --flags wp.c1a --mode pad Classes PASS (exactly lgs-hdr-40, header 40, --lgs-hdr-pad 68px). Modal and menu tops PASS: CONFIRM card (320, 198) 640 × 261, menu slab top 225 (≥ 108). Scroll guard FAIL, owned by C2c: on AllGames the focused posters reach y 58–117 (under the toolbar) and bottoms 647–881 (past 612), because the library page root is not padded and %{TabContentsScroll} has no scroll padding yet (REQ C1a->C2c (1), (2)); the shell's generic rule covers %{ScrollPanel}%{ScrollY} only scratch c1a/t_at2_40.out 2026-10-07 07:46 11094443
AT-24 <c1a/t_at24.js> --flags wp.p3,wp.c1a --mode pad and --mode laser (a) pad, AllGames: capsule 84 at y 628, 814 wide, 5 legends 84 tall, badges 30, A/B quiet (500, white .70): PASS. (b) laser: badges 0 wide, A/B present and quiet, capsule 614 wide at 628, no legend hidden (display flex, visible, opacity 1): PASS; the class-exact %{SortAndFilterContainer} mock (2 %{SortAndFilterButton}, inside GamepadTabbedPage after %{TabContents}) renders at (1002, 628) 270 × 57, not in slot 1: Steam renders it only on library routes, where slot 1 is C2c's fixed slot (REQ C1a->C2c (3); C2c's T1 is not written yet). (c) /settings/system: data-lgs-orn="quiet", labels white .82 on the band, both modes: PASS scratch c1a/t_at24_{pad,laser}.out 2026-10-07 07:50 11094443
AT-8 <c1a/t_at8.js> --flags wp.c1a --mode pad PASS for the D-pad path: first poster → Left → focus in frame.menu on Home, the menu expanded (281 wide, not Collapsed) → Down 2 → Store → Right → back on the poster in main, the menu collapsed again (82 = d + 24). B at "the root": Steam's own B never put focus in the bar in the lab: on AllGames it toggles poster ↔ tab row, on Downloads and Home it navigates back (the lab's history is never empty). Recorded, not ours to change (B is Steam's) scratch c1a/t_at8.out 2026-10-07 07:52 11094443
AT-8b = PLAN-1a-2 shot frame.menu p2_c1a_at8b_focus --route /library/downloads --flags wp.p3,wp.c1a --mode pad --pre <c1a/pre_at8b_focus.js> (Up to the field, Left into the bar, step to Store); shot frame.menu p2_c1a_at8b_hover … --mode laser --hover "<Media item>,1200"; each composited over the room strip where the bar sits (c1a/barroom.py, as SteamVR shows it in CSS-only mode); glass.py focus --png circles r 34 shot px on the icons (WN §13.1's method) PASS over both rooms. Lounge: focus − rest +51.0 (rows +58.7), focus − current circle +34.8, current circle − hovered +15.7. Studio: +61.4 (+68.8), +42.5, +18.2. Shapes differ (pill vs circle vs spot only). First frame: glass.py motion frame.menu … --name c1a_tabfocus: the pill is at its final contrast at f = 0 (+51.0 at f 0, .15 and 1 = 100 %), only Steam's own focus keyframes run (its fill is cleared by our rule), 0 left after 1 s shots/p2_c1a_at8b_{focus,hover}.png, shots/p2_motion_c1a_tabfocus_strip.png (viewed) 2026-10-07 07:53–07:58 11094443
  • Fix found by AT-8b's shot: Steam zooms the focused tab item 1.1× (its own transform), so with the expanded capsule ending at the popup's edge the focus pill (inset 18) ran 5 px past it and lost its right end. The pill inset is now 24 at the sides (the zoomed pill ends 12 px inside the capsule); re-shot and viewed: the Store pill sits inside the capsule with both ends round.

  • CQ1 decision (coordinator's note "settle CQ1"): the fallback ships. hdr108 stays a trial switch (off by default) whose runtime path writes both values, measures, and reverts both when Steam's header box does not follow (tested above). Areas keep padding-top: var(--lgs-hdr-pad, 68px) and the guard variables; no area should write rules for html.lgs-hdr-108 now. | PLAN-1a-3 (G-MOCK) | glass.py cmp docs/phase2/mockups/window-nav-{anatomy,tabbar,ornament,chrome}.html --id C1a --flags wp.p3,wp.c1a --mode laser (tabbar --mode pad), map docs/phase2/wp/C1a-cmp.json (new) | Rects FAIL by the ±8 rule, every shell delta explained: Back −10, −10, +20, +20 and the More circle +20 / +20 (live = the 80 px hit box, mockup = the 60 px circle inside it); search −8, −8, +16, +16 (the 536 × 80 box around the 520 × 64 capsule); Large Title dy −11, dh +25.7 (the live node is the 80 px row, the text sits on the same line); members dy −12, dh +24 (84 px hit rows, light inset 12); tab bar +8.5 wide, +14 tall (9 items at p 66 today vs the mockup's 10 at p 58, WN §3.3.2); the focused tab +60 wide (Steam's 1.1× zoom on the item). Member x offsets and the More circle's dx −101 come from content, not the shell: Steam's legends in the lab are the gamepad set (Filter, Sort By, Options), C2c has not placed members in its fixed slots yet (the 880 backing is right: x 200–1080), and the library grid has 6 narrower posters per row. Viewer's verdict: the shell matches on toolbar row (Back, Large Title, the recessed 520 capsule, edge of the glass), the ornament capsule and quiet legend, the tab bar's two capsules with pill and circle. The one large visual mismatch is the library page under the toolbar (its tab row at y 52–86 under the search capsule and the Large Title): C2c's page root is not padded yet (REQ C1a->C2c (1), now with this evidence); likewise the settings sidebar's first row under Back (REQ C1a->C6a) | shots/p2_cmp_c1a_window-nav-{anatomy,tabbar,ornament,chrome}.png (+ _live.png, .rects.json, .live.json), all viewed | 2026-10-07 08:00–08:02 | 11094443 | | AT-22 (session 4) | <c1a/t_at22b.js> --flags wp.p3 --mode laser (pushes wp.c1a and hdr108 itself, mounts a mock row host, dwells, enters #Footer, hovers Back, sets lgs-modal; then pops) | PASS: on: route/glass/search/back attributes, 3 data-lgs-btn, the T2 Options member (data-lgs-t2), Large Title + Options + More nodes, lgs-hdr-40 (the trial reverted), --lgs-tab-pitch 66px on the frame menu, lgs-modal mirrored there; off: none of them on main or the frame menu, Back's aria-label back to none, HeaderStore 40 as before, modules shell, more, pointer off | scratch c1a/t_at22b.out | 2026-10-07 08:02 | 11094443 | | AT-21 (C1a part) | <c1a/t_at21.js> --flags wp.p3,wp.c1a --mode laser and --mode pad (Downloads with a mock row: the Options member with its suffix, the Back reveal, the More circle) | PASS both modes: no text under 18 px or 500, no uppercase, tracking or italics in #header, #Footer, the More circle and the frame menu; seen: reveal "Library" 22/600, Large Title 46/700, Options 22/600, suffix 22/500, Select/Back 22/500 | scratch c1a/t_at21_{laser,pad}.out | 2026-10-07 08:03 | 11094443 | | Gates with T2 (M3) | glass.py gates main --route /library/downloads --pre <mock row + dwell + #Footer> --flags wp.p3,wp.c1a --mode laser --only aud,size,type,outline --json; the same without a pre on /library/tab/AllGames and /settings/system, both modes; c1a/gsum2.py lists findings on shell selectors | No finding on the shell's nodes (Back E-BACK exempt, the Options member, the More circle, the Large Title, the search field, #Footer). Findings left are the areas': Downloads (C7: 12 px uppercase labels, the 1 px TopBar line, "Clear All" inset line, one CONTRAST), AllGames (C2c: four tabs whose hit is taken by the search field because the library root is not padded, the tab row's closed rim), settings (C6a) | scratch c1a/g_s4_{dl_laser,ag_pad,ag_laser,set_pad,set_laser}.json | 2026-10-07 08:04–08:08 | 11094443 | | AT-3 + AT-27 | <c1a/t_at3.js> --flags wp.c1a --mode pad over AllGames, Downloads, a collection, /search, a game page, /settings/system, /account, /media/grid, /controller/calibration/0 | PASS (AT-3 as shipped): Back 80 × 80 at (14, 14) on every route (light: none on section roots, white .10 nested, black .32 on hero); field 536 × 80 at x 372 on section roots, 656 × 80 at x 312 on nested routes and /search (both centred at 640); circle routes show the capsule (flag searchCircle off, session 3 decision); title mode 30 px centred at x 640, y 35. Not run: the clear button (needs typed text, which opens search). AT-27: one #header and one #Footer on every route, the ornament at y 628, capsule ≤ 869 wide, quiet where only A/B | scratch c1a/t_at3.out | 2026-10-07 08:11 | 11094443 | | AT-6 (centre) | measure after the fix below, --flags wp.c1a --mode pad, four routes | PASS ±1: capsule centre offset 0.0 on AllGames (233 + 814), Downloads (210 + 861), /settings/system (483 + 315), /media/grid (205 + 869); the members' union is centred too | — | 2026-10-07 08:12 | 11094443 | | AT-1 | glass.py status | PASS: 0 unresolved, 0 ambiguous (546 class modules) | — | 2026-10-07 08:13 | 11094443 |

  • AT-6 fix: the 2 px offset of session 3 was the legend row's 4 px gap after Steam's empty spacer; the spacer now has margin-right: -4px.

  • Two-step move: C1c took §5 (app-details scrim) into 22-presentations.css §7; C1a deleted §5 (08:13). §6 (search route, C1b) and the frame-menu rules in C3a's 30-bar.css still wait on their owners.

  • Generic scroll guard: %{ScrollPanel}%{ScrollY} now also gets scroll-padding-bottom = 720 − footer (92) − 612 = 16 px; areas with their own scrollers apply the guard variables themselves. | More circle, real laser (REQ C1c->C1a) | /tmp/lgs/c1a/c1amore.py on the Frame (one lab.Lock step, wp.p3,wp.c1a, laser; CDP Input.dispatchMouseEvent on main's own target: hover the first %{CSSGrid} %{LibraryItemBox} 700 ms, 4 moves onto the circle, press + release; pointer to (1400, 900) at the end; copy in scratch c1a/c1amore.py) | Before the fix (C1c's run, 07:52): the move onto the circle was a leave of the host, the circle hid, the press reached the poster (game page). After: PASS: on the circle it stayed shown and :hover; the press opened the poster's menu from the circle (first row "Install", circle white), route unchanged; the lab closed the menu | — | 2026-10-07 08:16 | 11094443 |

  • Requests handled this session: REQ C1c->C1a (More circle with the real laser: a 220 ms leave grace, dropped while the pointer is on the circle or back on its host) and REQ C2a->C1a #10 (no scroll-edge band on windowless routes); both answered in the requesters' logs.

2026-10-07, session 5 (08:23-09:10): M4

Session 5 wrote no section of its own (review R2 M7); its work and evidence are the "Milestone reached: M4" bullets in Status above (fragments, the native check of 09:05 with sgcheck and one hv look). Its G-HV verdict was withheld (auto rect) and its look predates P7's B1 fix; both are redone in session 6 below.

2026-10-07, session 6: review R2 fix pass (17:00-19:40 EDT, build 11094443)

Start-of-session request check (grep -n "REQ [A-Za-z0-9-]*->C1a" docs/phase2/wp/*.md): twelve open, answered in the requesters' logs (table "Requests to C1a, handled", round R2); C5b's and C6b's were answered after the live vr:systemui gates (17:49). Device steps only through glass.py (locked steps, three native-sessions) and the ssh helper (md5 of the synced files, the flags file, the daemon's status, all read-only). Every headset frame was looked at and deleted at once on both machines.

The device. The headset dropped off the network at 17:23 and came back at 17:44 after a reboot (uptime 6 min at 17:49; theme on since 21:44Z); the files synced at 17:22 were on it (md5 equal for 20-shell.css, vr/10-systemui.css, layers/20-shell.json, 20-shell.js, 20-more.js, 20-pointer.js). Every later change: check-theme PASS, sync, reload.

Code changes (first sitting 17:00-17:22, then those found by the live checks; fontkit.py --hooks added .lgs-tabcap to P4's generated edge host lists, --hooks-check up to date at the end):

Finding Change
M1, m11 (vr:systemui rims, Phase 1 aliases) theme/vr/10-systemui.css: private recipes --lgs-c1a-vr-* from Phase 2 tokens only; controller card, gamepad-mode pill, §5 panels: --lgs-mat-panel-bg + E4/E5 + the lit top lip (no closed rim); More Options: thick glass (tint .80, --lgs-mat-thick-bg in High Contrast), radius 44, row light as pills 8 px apart, separators transparent, focus as light (+ .32, spot, arc), no ring; room-setup and tour buttons raised fills; no Phase 1 alias left (grep 0). WN's 96 px rows are not applied (row height sizes the quad). Found live: the gamepad-mode pill was SteamVR's uppercase, now mixed case, Semibold, no tracking (WN §3.5.2, P-84); the window bar (SteamVR's 12 px bar, 3.6 mm) is drawn as WN's 9.6 mm pill by a spread of its own colour (its box stays SteamVR's; the soft shadow is a drop-shadow of the whole pill, so the 12 px bar does not show as a stripe)
M2 theme/layers/20-shell.json: frame.menu cover "r": "capsule" (the tab caps and the fallback box)
M3 --lgs-c1a-tint: var(--lgs-mat-window-tint) (.94 in High Contrast)
M4, m6 windowless routes: Back (also as a section root) and the search field are CSS plates (--lgs-mat-plate-bg, E4/E5, lip, contact shadow, hover + .08); native: P6's ack clears --lgs-mat-plate-bg, §4c clears C1a's plate shade, so only the light adds stay in every state
M5 #Footer::after: lgs-mat-glass-in when the legend becomes a capsule; capsule to quiet: the old capsule's glass dematerializes at its old rect (T2 sets data-lgs-orn-leave and --lgs-orn-gl / --lgs-orn-gr; the ghost on #Footer::before, P5's lgs-mat-glass-out, removed only once the animation has ended) while the dim band fades in over 350 ms; a member's new label fades in on fade; a width change slides the capsule's ends (left / right of our own pseudo-elements, Web Animations on snappy: radius and shadow stay whole; it replaced the first sitting's scale FLIP, which stretched the round ends); the swell uses --lgs-maxside: 960 (at most 1.25 %, under P-53's 1.5 %). More circle: P5's glass and content channels; a new host (gamepad focus on the next card) materializes it again instead of jumping. Tab bar: Steam's width transition retimed (snappy out, fade back); the selection circle cross-fades on fade
M6 REQs answered; §6 deleted; settings capsule at x 840; WN updated (coordinator R2 list, and this session's motion, badge and depth text); mockups window-nav-anatomy, -anatomy-t1, -anatomy-depth, -chrome, -ornament updated and re-rendered
M8 Tab items: scale: calc(1 / 1.1) on the current item and, keyed on the input mode (P-01), on .gpfocus (Steam's transform value kept, LAB); Steam's transform transition set to 0 s (timing only); pill inset 4 × 12
m1 teardownDom also clears #header[data-lgs-reveal]
m2 .lgs-tabcap carries --lgs-edge: liquid (whole-capsule E3; off when glassd covers it). Found live: on the 82 px wide, 400 px tall capsule most of the upper sides fall in the key light's bright sector (dL 164 down the left side: a line); --lgs-edge-dim: .45 brings it to 101, the window rim's level
m3 The ornament's hit boxes abut: no row gap; each member's box holds a 2 px share of the 4 px between pills (light inset 12px 2px) and the first quiet member holds the 14 px group gap (padding-left and inset 12); the capsule edges sit 10 px outside the boxes (12 outside the pills, as before). Fixed slots keep C2c's own geometry
m4 More circle: aria-label falls back to the shell's Options text; P3 tooltip registered (text: '@aria-label')
m7 Back reveal: no max-width / padding transition; the chevron keeps its place (padding 26); the Large Title leaves in 150 ms (page-out), the glass grows from the circle (P5's lgs-morph, snappy), the label comes in on fade after the title (an animation: on the first reveal the label node is new, and a new node never transitions; found live, it popped in over the title); leaving: the label goes at once and the glass slides back into the circle on snappy, fading on borderless section roots (data-lgs-unreveal, Web Animations, cancelled in the same task as the attribute goes)
m8 Glyph badges: T2 hands each glyph image's own URL to the CSS (--lgs-c1a-glyph, data-lgs-glyph); the badge lights only the letter Steam's glyph cuts out of its white disc (mask: the box minus the glyph, cut to a circle inside the disc edge; the menu pill: its middle band, drawn 1.5x). The first sitting's overflow: hidden only clipped the spill: the inverted, screened disc still landed as an opaque dark disc with a light ring on the translucent capsule
m10 Search focus ring and hover adds keyed on the input mode (.gpfocuswithin not under the laser, :focus-within and :hover not under the pad)
m12 Pointer proxy: the 1.5 px dark ring is now a 3 px blurred halo
m5, m9 REQ C1a->P6 (laserOnly with tabBarAlways), REQ C1a->P10 (#header false positives)
m13 Disputed (below)
Found live The Back reveal's rt.attend registration died whenever P3's attention module was installed again while the shell stayed (wp.p3 is P3's flag; the shell does not depend on it): the reveal stopped working (motion steps read "reveal false"; a later step showed shell.status().reveal.wires 3 after the fix). The registration is now renewed whenever rt.attention is a new object (checked on every route change and footer or header update)
Lab scripts theme/vr/pre/sys_hover.js clones :hover rules without transition* (the clone of SteamVR's 0.04 s :active rule made MOTION fail, C5b's N1); window-nav-measure.py ring measures within 40 shot px of the pointer (the two captures also differ where the page reacted to the move)

Disputed or deferred. m13 (P-73, a should): WN's bottom ornament is a visionOS ornament straddling the window's edge, not a toolbar inside the window, and visionOS gives an ornament no scroll edge; the content ends at the glass edge with the window's round corners, and the ornament's own liquid glass frosts what lies under its upper 28 px. A 124 px dimming band (D2's --lgs-scroll-band-bottom) would dim focused rows down to y 612 (by up to .19, against P-14/P-15), and a mask on %{BasicHome} would make it a backdrop root (the problem C1c reported). Left for the coordinator to rule; nothing else depends on it.

Live evidence (all native=off unless the row says native; shots composited over room-lounge / room-studio with c1a/onroom.py and c1a/barroom.py, and viewed):

Test Command Result Shots / JSON Date Steam build
M1 / REQ C5b, C6b: G-AUD/SIZE/TYPE/OUTLINE/MOTION on vr:systemui gates vr:systemui --flags wp.c1a --mode pad and --mode laser, --json --shot PASS both modes, all five gates (4 controls; the controller card's ::before no longer a rim) shots/p2_c1a_r2f_vr_{pad,laser}.png (viewed: quiet frame-control capsule, card without an outline) 2026-10-07 17:49 11094443
Same with the on-demand panels (C3a's static zoo: More Options, pills, tooltip, §5 panels) gates vr:systemui --pre <sys_zoo.js> both modes; again with a scratch copy that clones without transition* SIZE, TYPE, OUTLINE, AUD PASS; MOTION only the clone's 0.04 s (REQ C1a->C3a); with the stripped copy all PASS both modes. Viewed: More Options thick glass, focus and hover as pills, no ring or separators; the pill's uppercase (fixed) shots/p2_c1a_r2f_vrzoo_{pad,laser}.png, p2_c1a_r2f_vrzoo2_* 2026-10-07 17:50, 19:05 11094443
Window bar pill (after the change) gates vr:systemui --flags wp.c1a --mode laser and --mode pad, --theme on PASS both modes; viewed: one uniform 9.6 mm pill shots/p2_c1a_r2f_vr3_{laser,pad}.png 2026-10-07 19:22 11094443
M8 tab items js probe on frame.menu (Downloads current); a synthetic .gpfocus class on Store (look test only, removed after 6 s) The current item matrix3d(1.1 ...) and the focused one matrix(1.1, 0, 0, 1.1, 0, 0) with scale: 0.909091: both 82 x 66 like the others (net 1.0). Real gamepad focus could not enter the bar in today's lab state (Left from the search field goes to vr-null-tree, as the R2 reviewer found) scratch c1a6/p_tab*.js 2026-10-07 17:56-17:59 11094443
PLAN-1a-2 G-FOCUS on the tab bar shot frame.menu p2_c1a_r2f_tab_focuscls --pre <synthetic .gpfocus on Store>; focus --png circles r 34 over both rooms PASS (collapsed bar): lounge focus - rest +75.9, focus - current circle +43.2, current - rest +32.7; studio +70.6, +48.5, +22.1 shots/p2_c1a_r2f_tab_focuscls.png 2026-10-07 19:25 11094443
G-AUD/SIZE/TYPE/OUTLINE, frame.menu gates frame.menu --route /library/downloads --flags wp.c1a,wp.p3 --mode pad and --mode laser, --json --shot PASS both modes (MOTION too); E-TAB items pass; tab-cap side profiles: left .007 / .024 (brightest 101 / 78 after --lgs-edge-dim, 164 before), right .243 / .012 shots/p2_c1a_r2f_fm2_{pad,laser}.png 2026-10-07 19:00, 19:05 11094443
AT-23 (C1a part) glass.py edge on p2_c1a_r2f_ag_pad2 over the studio room and on p2_c1a_r2f_fm2_pad over both rooms Window top .02, ornament top .01, tab cap 1 top .01 / .00, tab cap 2 .06 (studio); over the lounge cap 2's apex row (y 750) reads .49 because on a round 82 px cap that row runs along the lit arc itself, 2 px inside .05; the side profiles above pass scratch c1a6/ag2_studio.png, fm2_*.png 2026-10-07 19:24 11094443
Main gates, shell nodes gates main --route <R> --flags wp.c1a,wp.p3 --mode pad and --mode laser, --json --shot, for AllGames, /settings/system, /library/downloads No finding on the shell's nodes in either mode. Others' only: C2c's "Great On Frame" tab P-08; MOTION's two non-token animations were C1b's 21-search.css (gone by 18:09) shots/p2_c1a_r2f_{ag,set,dl}_{pad,laser}.png 2026-10-07 18:01-18:03 11094443
M4 windowless Home gates main --route /library/home --flags wp.c1a,wp.p3,wp.c2a --mode pad and --mode laser SIZE, TYPE, OUTLINE, MOTION PASS; AUD = C2a's T3 view (276 GONE, all C2a's). Viewed: Back a 60 px plate circle and the search field a plate capsule over the room, like C2a's What's New shots/p2_c1a_r2f_home_{pad,laser}.png 2026-10-07 18:07-18:09 11094443
M3 High Contrast (G-A11Y) js probe with --media contrast; gates main --route /library/tab/AllGames --media contrast --mode pad Root tint rgba(11, 13, 16, .94) = --lgs-mat-window-tint, dial 1, the edge ::before 2 px (the HC stroke), ornament and tab fill .94; gates: shell nodes clean, AUD CONTRAST 0 scratch c1a6/p_hc.js, shots/p2_c1a_r2f_ag_hc.png 2026-10-07 18:10 11094443
G-A11Y Reduce Motion gates main --route /library/tab/AllGames --media reduce --mode laser MOTION PASS; shell nodes clean scratch c1a6/g_ag_rm.json 2026-10-07 18:10 11094443
m3, m8 ornament js probe (AllGames, both modes) Member hit boxes abut (gaps 0, 0, 0, 0); the capsule centred (offset 0); legend nodes are kept while gamepad focus moves between posters (0 fresh nodes), so labels fade only for new members. Viewed: the badges a clean white letter on the .16 disc (also the menu glyph) shots/p2_c1a_r2f_ag_pad2.png 2026-10-07 18:05-18:08 11094443
M5 filmstrips (G-MOTION) `motion main --route /library/tab/AllGames --pre <m_orn_quiet.js m_orn_capsule.js> --mode pad; --route /library/downloads --pre <m_reveal.js> --mode laser; --pre <m_more.js> --mode pad` Every lgs animation a token (non-token: only C2c's poster opacity 100 ms). Capsule to quiet: the old capsule's glass held, then dissolving with a 12 px swell while the band fades in; the labels at their place from f 0. Quiet to capsule: lgs-mat-glass-in and the new labels on fade. Back reveal: title out 150 ms, glass from the circle on snappy, label in after it, chevron still. More circle: glass first, the dots sharpening last, at the new card. All four strips viewed shots/p2_motion_c1a_{orn_quiet,orn_capsule,back_reveal,more}_*.png 2026-10-07 18:12-19:35 (orn_capsule's last run with another agent's native session on)
AT-4 (as specified) gates main --only aud,size,type,outline both modes on /library/app/1147940, /account, /controller/calibration/0, CONFIRM, MENU, POWER (look only), /search/tab/All; gates floatingfooter --only aud,size,type No GONE / HIDDEN / UNCLICKABLE / CONTRAST and no finding on the shell's nodes, except the lab's #header SIZE false positive on calibration (laser; m9, REQ C1a->P10). Others' only: /account a dropdown's top edge and P-08s (C7 / C4a), the menus' Cancel E-MENU (C1c), /search C1b's T3 (GONE x 30) and a 16 px label. floatingfooter: VACUOUS (empty while the dashboard has focus; its look is C3a's). Home, AllGames, Downloads, /settings/system, frame.menu: rows above scratch c1a6/at4_*.json 2026-10-07 18:42-18:49 11094443
AT-7 (tabBarAlways) js holding --flags wp.c1a,wp.p3,wp.p6,tabBarAlways --mode pad (popups status, the frame menu's request, the pitch) and js --in vr:systemui with DumpLaserOverlays Computed part and request PASS: P6's wrapper installed, the frame-menu request only_visible_with_laser: false (true without the flag), z_meters 0.01; rule 2, p 66 for n 9 at r 1 (G 595.4, P 653.5, H 638), rows 66 (72 at the capsule ends), Console off (n 9); the overlay 0.188 x 1.465 m, unchanged. Not provable by an agent: "visible without the laser" (the physical laser state); resize-following needs r other than 1 (no user resize) scratch c1a6/p_at7.js, at7_steam.out 2026-10-07 19:08 11094443
AT-17 (winbarMove) js --in vr:systemui --flags winbarMove (polls __LGS_SG.status().overrides, DumpLaserOverlays); hv c1a_r2f_winbar --look --flags wp.c1a,winbarMove --mode laser (CSS-only) PASS: within 2 s the daemon installs the scene graph and applies fc-left (-0.627 units = -231.5 mm), grab-up (+95 mm), tips-below (4 tooltips); sizes unchanged (frame controls 0.768 x 0.168, grab handle 0.667); look: one row under the window, the frame-control capsule left of the window bar, the bar near the window's centre; after the step the scene graph is gone again. The tooltips' flip is shown by the override (n 4), not seen in a frame (frame deleted) 2026-10-07 19:14-19:16 11094443
AT-0b (native) native session 1: shot main p2_c1a_r2f_ptr_with and _without (--pre: a pointermove on a poster, then a pointerleave; --mode laser); window-nav-measure.py ring ... 501 604.5; hv c1a_r2f_ag --look with the pointer on the poster PASS: ring centroid offset 0.5 px, peak 200, spread 9.2 px; in the headset frame the ring is visible on the poster over the cover; DOM: one node per covered document, pointer-events: none, the hit test passes through, off after leave. CSS-only: 0 nodes (session 3 row) shots/p2_c1a_r2f_ptr_{with,without}.png 2026-10-07 18:52 11094443
T5 acks (native) native session 1, js probes (AllGames laser; windowless Home pad, and laser with a real hover on Back) main cover [0, 0, 1920, 984, r 81] acked, sheen gone; plate shell-ornament [500, 942, 920, 126, r 63] liquid acked, #Footer::after and its E3 hook dropped; frame.menu liquid, two capsule shapes r 62, both .lgs-tabcap acked. Windowless Home: shell-back, shell-search acked; with a real hover on Back its ::before is only the + .08 add (m6) and the field paints nothing scratch c1a6/native.log 2026-10-07 18:50-18:52 11094443
M2 (native, default flags) native session 2: js probe and hv c1a_r2f_fmdef2 --look, both with --flags wp.c1a=false --mode laser (a session flag held wp.c1a on, so the step turns it off) frame.menu cover [348, 216, 102, 768, r 51]: a capsule (half its width), acked; look: the tab bar one rounded column of glass, no square corners (frame deleted) 2026-10-07 18:58-19:00 11094443
G-PAD pad-bfs --route /library/downloads --flags wp.c1a,wp.p3 --mode pad and --stock Equal: 2 nodes, the same 3 unreached (Steam's), 0 irreversible, 2 exits, B goes back in both scratch c1a6/bfs_dl*.json 2026-10-07 19:29 11094443
G-DEPTH (native) native session 1: sgcheck AllGames laser and pad, /settings/system pad, /library/home (+ wp.c2a) pad; conformance (native) No R1 over the ornament's nopop box, no hdr-* / footer / sort-filter pop; AllGames fails only R2 on the legacy tab-arrow x 2 (4.43 mm) and card (2.95 mm) of C2c / C2a / C5a; settings and Home PASS. Depth items P-11, P-46, P-47, P-48, P-51 PASS scratch c1a6/native.log 2026-10-07 18:53-18:55 11094443
G-HV (native) native session 3: hv --look AllGames and /settings/system (laser), and 30 degrees off-axis (a lab-only P7 override lifting the window 150 mm and bringing it 200 mm closer, removed after); tools/p2/hv_metrics.py --rect on each look within its 120 s PASS AllGames (rect 100,24,700,330): glass L 80.1, edge none, doubling .484; settings: L 71.1, edge none, doubling .573. Off-axis 30 degrees: L 70.9, edge none, doubling .616 at a 9 px shift on the text rows of the band (no doubled element by eye). Session 1 looks (AllGames, off-axis, Home, tabBarAlways pad, with MENU and with CONFIRM up): the tab bar two liquid capsules, no doubled tab bar or ornament, the windowless Back and search plates; the native MENU and CONFIRM slabs look too clear (C1c's, FYI REQ) (frames deleted) 2026-10-07 18:56-19:00, 19:27-19:31 11094443
PLAN-1a-3 (G-MOCK) cmp window-nav-{anatomy,ornament,chrome}.html --id C1a --flags wp.p3,wp.c1a --mode laser, -tabbar with --mode pad; the window-bar row offline (--name window-nav-chrome-row, a live shot of vr:systemui, rects read with js --in vr:systemui; REQ C1a->P10) Rects as by design before: Back and More hit boxes (+20), the search box (+16), the members' 84 px hit rows (dh +24, now dw +4 with the abutting boxes); content differences: Steam's legends in the lab (Filter, Sort By, Options), C7's empty Downloads queue, the tab bar collapsed (gamepad focus cannot enter it in the lab). Window-bar row: frame controls width 0, dh +8.4 (the 107 px hit row against the mockup's 98.6); window bar dw +169, dh -20 (SteamVR's own bar box; its look is now the 9.6 mm pill). Viewer's verdict: the toolbar row, Large Title, trailing Sort & Filter group, the ornament capsule and the quiet legend, the More circle in its card, the tab bar's capsules and the window-bar row match the design shots/p2_cmp_c1a_window-nav-{anatomy,ornament,chrome,tabbar,chrome-row}.png (viewed) 2026-10-07 19:17-19:20 11094443
RT-7 / G-PERF perf main --route /library/tab/AllGames --ab theme --flags wp.c1a,wp.p3 --mode pad PASS: fps ratio 1.022, extra long frames 0 (A/A spread 1), 8 runs native=off scratch c1a6/perf_ag.out 2026-10-07 19:26 11094443
AT-22 / G-REMOVE js <t_at22c.js> --mode pad (pushes wp.c1a off, then on with every T2 piece live, then pops) PASS: before = after = nothing of the shell (no data-lgs-*, no --lgs-* inline variable, no empty style attribute, store 40, Back's aria-label back to none); on: route, glass, search, back, 3 data-lgs-btn, 2 data-lgs-glyph with their variables, the plate, Options, the Large Title scratch c1a6/t_at22c.js 2026-10-07 19:27 11094443
AT-2 (guard) js <t_at2.js> --flags wp.c1a,wp.p3 --mode pad Classes PASS (lgs-hdr-40, header 40, pad 68); tops at least 124 now (C2c padded the library root); bottoms 639, 665, 711 on three of six Down moves: still blocked on C2c (REQ C1a->C2c (2), updated); the menu slab's top 225 — 2026-10-07 19:28 11094443

Device left (19:40): theme on, CSS only after each of C1a's native sessions ("back to CSS only: yes"; the lab-only window override removed in each; at 19:39 another agent's native session held the lock), status: 0 unresolved, 0 ambiguous; every C1a step's flags popped by the lab, the pointer parked by the laser steps, no menu or dialog of C1a's left open. Not C1a's, left alone: a session flag wp.c1a: true in /tmp/lgs/flags.json (the runtime reports its source as "session"), present since at least 18:46 with no lab step record of its own (other agents' step records list it as their previous value, e.g. C5a 18:54, C1b 19:39). The file was absent at 17:49, C1a never ran lgs flags, and every C1a step went through the lab's recorded push/pop. It was not removed because two other agents' steps were running on top of it; the coordinator's lgs flags wp.c1a=default clears it. Until then shell, more and pointer run for everyone (that is the integrated state V2 would test anyway, but not the shipped default).