101 KiB
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 legacyhdr-back,hdr-search,footer,sort-filterpops whilewp.c1ais on (nothing in the toolbar row or the ornament pops); ownsframe.menu: materialliquid(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'smain.modeskeyed on C1a'sdata-lgs-glass.device/rt/20-shell.js: the ornament plate node#Footer > .lgs-orn-plateat the capsule rect (data-lgs-nopopalways; liquid plateshell-ornamentonly as a capsule, none for the quiet legend);shell-back/shell-searchliquid plates onwindowlessroutes (REQ C2a->C1a #2, insets 10 / 8); the two.lgs-tabcapcover nodes in the frame menu; all removed byremove().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 menuonly_visible_with_laser: falsebehindtabBarAlways(depth stays P7'stabBarDepthrule).theme/sg/20-winbar.jsonbehindwinbarMove: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-upandtips-belowprovisional (P7's sg.md values) until AT-17.- Native check (
native-session, pre pusheswp.c1a,wp.p3and pops them in the last step; 09:05):sgcheck --route /library/tab/AllGames: no R1 (no pop over the ornament'sdata-lgs-nopopbox), nohdr-*/footer/sort-filterpop; the only failures are R2 on the legacytabs,tab-arrow,cardpops (4.43 / 2.95 mm, owners C2c/C2a/C5a/C1b, reporter §3.5).hv c1a_native_ag --lookviewed, 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 (tabBarAlwaysis 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 legacyhdr-*,footer,sort-filterpops); then AT-0b native part, AT-7 (withtabBarAlways), AT-17, AT-20 underglass.py native-session. Before that, whenever an area lands its padding: re-runc1a/t_at2.js(guard) andglass.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 of30-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:#headerand the page layout stay 40 whatever--basicui-header-heightandHeaderStoresay (AT-2), solgs-hdr-40ships andhdr108only 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 forwindow-full, none forwindowless); bottom corners rounded at the glass edge; P4's E3 hook on%{BasicUiRoot}::beforeends at the glass bottom; content is clipped to the glass shape (clip-pathon%{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::beforeis the 124 px scroll-edge band.--lgs-hdr-pad(68px; 0 withlgs-hdr-108),--lgs-guard-top(124px) and--lgs-guard-bottom(612px) are defined on everyhtml.lgs-on. Areas: pad your page roots withpadding-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:
#Footer92 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'sraisedhook), label 22 Semibold mixed case first, Steam's glyph as a 30 px badge after it (white .16 disc), badges collapse underdata-lgs-vr-mode="laser". Rules for T2'sdata-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), pitchvar(--lgs-tab-pitch, 52px), current route = .18 circle with its arc behind the glyph, focus/hover from P4'snavhook. theme/vr/10-systemui.css§0 deleted (P4's REQ, done; every--lgs-vr-*resolves fromvr/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-addto .32 (PLAN §1.4 allows .28–.32, set once from G-FOCUS). Why: PLAN-1a-2 (G-FOCUS on the tab bar) onp2_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.pngstrip 3 measured 139 before C1a's workaround), above PLAN §1.6's 55–110 and 70–90 under text. Cause:--lgk-target-luma: .38forliquidplus its white .12 sheen, andadapt()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-tabcapand.wn-orn.lgk-glass("glass tone under text" inwindow-nav-shared.css). P4 (2026-10-07): done: liquid--lgk-target-luma.38 → .30 and the adaptation floor ×0.42 → ×0.30 inkit.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 flagquietBacking: "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
windowroutes 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 flagquietBacking(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 (achievementswindowvswindow-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'slibFixedSlots(R2-2); O1: achievements staywindow(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 inwp/coordinator.md.
- Coordinator (2026-10-07, round R2): the dim band is adopted into PLAN §1.10 with S27 (
-
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-quietwithdata-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 usedata-inglass(no blur, P-45).- C1b (2026-10-07, R2 fix pass): done.
window-nav-search.htmlusesdata-wn="ornament" data-mode="laser" data-legends="A:Open|B:Back"(the inline.wn-quietand its recipe lines are gone from both C1b mockups); re-rendered asshots/p2_c1b_mock_search_r2.png(the frozenp2_window-nav_search.pngis 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.
- C1b (2026-10-07, R2 fix pass): done.
-
REQ C1a->C1c: please re-render
window-nav-menu.html,-power.html,-alert.html,-sheet.html,-sort.html. Your static.wn-orn.quietmarkup now gets the dim band from the shared CSS (checked on a scratch render ofwindow-nav-alert.html: "Select" 1.2–1.4 : 1 before, 4.8–5.2 : 1 after). Switching todata-wn="ornament"is optional;data-modalon 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.quietmarkup stays for now.
- C1c (2026-10-07 07:30): done. All five re-rendered with
-
REQ C1a->C5a:
game-pages.css.gp-foot.quietdraws the quiet legend in the margin as on-room text (white .92 + shadow). WN §3.4.1 (C1a, flagquietBacking) puts a dim band behind quiet labels onwindowroutes, labels white .82 (on-room text alone measures 1.3–1.5 : 1 over a bright room). Please adopt the band (.wn-orn.quiet.bandor the builder) onwindowroutes; inside the glass (window-full) keep white .70. — C5a: adopted (C1a draws the legend and itsquietBackingband; C5a-D6, wp/C5a.md). -
REQ C1a->C6a:
settings.cssdraws 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"(plusdata-mode="laser"for labels only) renders WN §3.4.1's quiet legend with the dim band in the margin ofwindowroutes (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 by60-settings.css). The mockups switch todata-wn="ornament"at C6a's M0 re-render, which is still open (review R2 appendix M8); until thensettings.csskeeps its copy of the band. -
REQ C1a->C7:
social-media.css.sm-quiet.room(white .96 on the room): onwindowroutes (for example/chator Downloads when the legend holds only A and B) use WN §3.4.1's dim band (.wn-orn.quiet.bandor the builder); on/account(window-full) the quiet legend stays inside the glass at white .70, associal-media-account.htmldraws it. -
REQ C1a->C2c: the shell's T1 is live (session 3): toolbar row in the CQ1 fallback,
--lgs-hdr-pad(68px, 0 withhtml.lgs-hdr-108),--lgs-guard-top124px /--lgs-guard-bottom612px,#Footer92 px with the capsule at y 628–712. Please (1) pad the library page root withpadding-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) setscroll-padding-top/-bottomon%{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 insideGamepadTabbedPage, 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-padhonoured). (2) still open:c1a/t_at2.json 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 addscroll-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.pngshows 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, andscroll-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 behindwp.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}hasscroll-padding-top/-bottomfrom--lgs-hdr-padand--lgs-guard-bottomplus 8 px for Steam's x1.053 focus growth, andpadding-bottom116 px, so the last row (and the Collections tab's second row, which could not scroll) scrolls above 612 (review C2c R2 Q5; evidence inwp/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.
- C1a (2026-10-07 19:28, session 6): (1) done by C2c (the tab row now at y 108-188,
-
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 of30-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!importantdark colour andbackground-clip: textneeded a more specific override in 20-shell.css). The floating footer stays yours: the shell's#Footerrules 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!importantdark Active colour orbackground-clip: texton the menu label any more); the floating footer stays in35-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 yourtheme/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.cssand%{GamepadSearch}dropped from §1's clear list.
- C1a (2026-10-07, R2 fix pass): C1b took the rules (REQ C1b->C1a #9); §6 deleted from
-
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 into22-presentations.cssand tell me, then I delete it. The route-transition wrappers (%{TopLevelTransitionSwitch},%{ContentWrapper}%{TopLevelTransition},%{AbsoluteDiv}) stay cleared in 20-shell.css §1 (backgrounds only; your23-transitions.cssowns their motion). Also for your modal rules:#Footeris now 92 px (Steam's--gamepadui-current-footer-height92), soModalPosition.FooterVisibleends 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 alsobackdrop-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-height92 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-themePASS, synced.
- C1c (2026-10-07 07:35): taken.
-
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/systemtoday the sidebar's first row (y 40–83) sits under the Back control at (24, 24)–(84, 84). Scrollers:scroll-paddingfrom--lgs-guard-top/--lgs-guard-bottom(window y). C6a (R2 fix 1, 2026-10-07): done in session 1: sidebar listpadding-top: calc(var(--lgs-hdr-pad, 68px) + 40px)(first row at y 108), contentcalc(var(--lgs-hdr-pad, 68px) + 48px)(y 116); both scrollers takescroll-paddingfrom--lgs-guard-top/--lgs-guard-bottom. Gates on/settings/systempass 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.
- C1a (2026-10-07 08:14, session 4): still visible (
-
REQ C1a->C7: the shell's T1 is live: please pad your page roots (
/library/downloads,/media/*,/chat,/account) withpadding-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 ondata-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)
gatesOUTLINE no longer measures the main window's top edge: the window's tint is now%{BasicUiRoot}'s sizedbackground-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-edgeis 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 bybackground-sizeare 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-edgeis 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 andbackground-sizeare not modelled. contracts/lab.md §4.
- P10 (2026-10-07 06:35): done. OUTLINE treats an element whose computed
-
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). Todaygates frame.menufails 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). AlsoE-BACKfor#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-TABadded as given; each exempt item is checked against its criterion (height ≥ 52, abutting the next item: gap ≤ 2) and listed under SIZEexemptwithpass/why; a failing criterion fails G-SIZE. E-BACK is read from the attribute (criterion: aria-label set, centre hit own).
- P10 (2026-10-07 06:35): done:
-
REQ C1a->P1:
device/lgs_core.jscacheswindow.__LGS_INDEXonce 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 everyrt.selfailed;shellinstall failed on%{BasicUiRoot}), andlgs on/reloadkept reusing it. Please rebuild when the cached index is implausibly small (for examplesize < 100; the healthy value today is 550) or when a token the core itself needs (BasicUiRoot) does not resolve, and report it instatus. C1a cleared it by hand (delete window.__LGS_INDEX, thenglass.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 byoff+on.lgs onfirst 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 statusreportsindex: {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.
- 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
-
REQ C1a->P10:
lab/lab_helpers.jscaptureswindow.__LGS_INDEXat install (const index = …), so after a bad index the helpers keep it even when the core rebuilds (every%{…}inL.q,outline,classesfailed until__LGS_LABwas dropped). Please readwindow.__LGS_INDEXat call time, or reinstall the helpers when the index object changes.- P10 (2026-10-07 08:15): done: the helpers read
window.__LGS_INDEXat call time (IX()inlab_helpers.js;L.indexis now a getter), so a rebuilt index is used at once (live:L.index.selectorpresent after the change).
- P10 (2026-10-07 08:15): done: the helpers read
-
REQ C1a->P10: two lab false positives on Steam's
#headerthat V2 would record against the shell (review R2 m9): (1) P-82 on/settings/system(pad) reads#header'sinnerText, 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, whicharia-labelcarries); (2) G-SIZE P-80/P-08 on/controller/calibration/0measures%{Profile>Header}(1280 × 40) as a control:#headerispointer-events: none, a nav container whose children take the clicks; please skip containers withpointer-events: none(and no click handler of their own) as targets. -
REQ C1a->P6:
theme/layers/00-base.jsonframe.menuislaserOnly: true; with C1a'stabBarAlways(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 letlaserOnlyfollow the frame menu's live visibility (or thetabBarAlwaysflag). C1a's fragment ownsframe.menubut cannot key one field on a second flag. Not urgent:tabBarAlwaysstays off until AT-7/AT-20 pass. -
REQ C1a->P10:
glass.py cmpcannot take a live shot of avr:surface: an entry with"surface": "vr:systemui"(C1a-cmp.jsonwindow-nav-chrome-row) fails with "lab: no CEF target for surface 'vr'" because the live step's--capture SURF:NAMEis split at the first colon (lab_p2cmd.pycmp_rects). C1a ran it offline (ashot vr:systemuiplus rects read withjs --in vr:systemuiinto--live-rects). Please split at the last colon (or pass the surface separately). Also,hvmeasures only the auto rect unless--rectis given before the frame is seen; a--lookstep 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 rantools/p2/hv_metrics.pyon 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 readingscroll-padding-bottomon that step; please check which element scrolls on a gamepad move in the grid and keep the focused row's bottom ≤ 612 (your 116 pxpadding-bottomlets the last row get there, but the rows above stop lower). -
REQ C1a->Coordinator: (1)
/tmp/lgs/flags.jsonhas held a session flagwp.c1a: truesince at least 18:46 with no lab step record of its own (not set by C1a; details in session 6, "Device left"); every module behindwp.c1aruns for everyone untillgs 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.jsclones every:hoverrule of the page with its wholecssTextinto#lgs-vr-zoo-style, SteamVR's own:activebutton rule included (transition-duration .04s); because the sheet's id starts withlgs-,gates vr:systemui --pre sys_zoo.jsthen fails MOTION ("transition-duration 0.04s (not a token)") for every SteamVR area (C5b's reviewer, N1, found the same innp_states.js). Please clone the declarations withouttransition*(C1a'ssys_hover.jsnow 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→ nodocs/phase2/wp/directory yet; no requests. - No device steps this session (M0 is documents and mockups only).
- Work (in checkpoint
f5190bb):window-nav.mdrevision 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 theglassMode/refreshGlasshooks (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 thequietBackingrow, 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
windowroutes (flagquietBacking, 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'sdata-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-selectedwithout 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; thewindow-fullquiet 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-selectedarc 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.quietmarkup (not only the builder's.band), so C1c's five mockups get it without edits; scratch render ofwindow-nav-alert.html(not saved toshots/): "Select" 4.8–5.2 : 1, was 1.2–1.4.ornamentre-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 inwp/P4.md(below). theme/20-shell.cssrewritten (Phase 1 copy kept in the scratchpad asc1a/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/ firstbackground-imagestop over the room: a window tint drawn on a pseudo-element made every text onmainread as bare room (CONTRAST 6.3 → 1.5 on Back and the legend labels). The tint is therefore%{BasicUiRoot}'s ownbackground-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). #Footeris 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}::afterfor its divider, so Back's light is drawn on its own::beforefill (not P4's::afterhook). - 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 (!importantdark 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.
- P10's AUD contrast model composites only ancestors'
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-scale1.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
geomis live onrt.bridge(r 1,Hm0.5535,frameMenu.mpMm0.847 at 07:12); P10'sfocus(live) andcmpare live now. - Tab bar, live pitch (T2, WN §3.3.2):
20-shell.jsreads P8'sgeom(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-placeon the frame-menu document's root (removed with the module). Today n = 9 (Console off), r 1,mpMm0.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). SincempMmis measured from the live overlay (DumpLaserOverlaysheight × 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}rulewidth: 54px; transition: width 300ms). WN §3.3.1 asks 12 px at the sides, so the collapsed width is nowd + 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 isd/2 + 12(concentric with the circles). Shotsshots/p2_c1a_tabbar_p66.png(collapsed) andp2_c1a_tabbar_p66_hover.png(real CDP hover on Media: expanded, the light spot only), viewed againstp2_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
#Footerwith 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 ownonMenuActionDescription(what Steam's ≡ legend would say for it, "Options"), else the last ≡ legend Steam rendered, else Steam's token#LibraryHome_GameCarousel_ContextMenu(LocalizationManagerprobe: 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 firstpointeroverinside#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.modalUpreads main'sm_ModalManager.m_rgModalsand context menus. - Back reveal (T2, WN §3.2):
rt.attendon 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 (noentries), 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.
hdr108stays 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 keeppadding-top: var(--lgs-hdr-pad, 68px)and the guard variables; no area should write rules forhtml.lgs-hdr-108now. | 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), mapdocs/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(pusheswp.c1aandhdr108itself, mounts a mock row host, dwells, enters#Footer, hovers Back, setslgs-modal; then pops) | PASS: on: route/glass/search/back attributes, 3data-lgs-btn, the T2 Options member (data-lgs-t2), Large Title + Options + More nodes,lgs-hdr-40(the trial reverted),--lgs-tab-pitch66px on the frame menu,lgs-modalmirrored there; off: none of them on main or the frame menu, Back'saria-labelback to none,HeaderStore40 as before, modulesshell,more,pointeroff | scratchc1a/t_at22b.out| 2026-10-07 08:02 | 11094443 | | AT-21 (C1a part) |<c1a/t_at21.js> --flags wp.p3,wp.c1a --mode laserand--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 | scratchc1a/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/AllGamesand/settings/system, both modes;c1a/gsum2.pylists 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) | scratchc1a/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 padover 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 onhero); 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 (flagsearchCircleoff, 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#headerand one#Footeron every route, the ornament at y 628, capsule ≤ 869 wide, quiet where only A/B | scratchc1a/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
gapafter Steam's empty spacer; the spacer now hasmargin-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's30-bar.cssstill wait on their owners. -
Generic scroll guard:
%{ScrollPanel}%{ScrollY}now also getsscroll-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.pyon the Frame (onelab.Lockstep,wp.p3,wp.c1a, laser; CDPInput.dispatchMouseEventon 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 scratchc1a/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
windowlessroutes); 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).