100 KiB
C2c Library catalogue: evidence log
Package card: docs/phase2/PLAN.md §2.4 "C2c Library catalogue". Concept: docs/phase2/concepts/home-apps.md (HA) §7, §8, §9, §12.2–§12.6, which C2a owns; C2c changes that text only through the requests below. Steam build at the time of writing: 11094443 (no device step was needed in this session).
C2c owns: theme/40-library.css, device/rt/40-library.js, theme/layers/40-library.json, docs/phase2/mockups/home-apps-library.html, home-apps-library-pad.html, home-apps-filter.html, docs/phase2/mockups/fetch-library-refs.py, this log and docs/phase2/wp/C2c-cmp.json (written in session 3). Sessions 2 and 3 ran on the device; Steam build 11094443.
Status
Session 3 (2026-10-07): review R2 fix pass 1 done. Not READY. Fixed and verified on the device in both input modes (R2F rows): Q1-Q5, Q7, R2-2 (check PASS in both modes), M14-M18, m1, m2, m4, m5, m8; Q6 built (P-15 / P-16 readings with the coordinator and P10, REQ-13 / REQ-17); Q8 C2c share only (the route stays 0.707 against stock, outside C2c); Q9 partly (scrubber and capsules built; the count badge and collapsed sections are not). Still blocking: M20 (laser sgcheck FAIL on legacy card 2.95 mm, P6, REQ-12), M9 / M13 (C1a, P10), the route's G-PERF. Device left as found (theme on, CSS-only, no flags, native off).
Session 2 status, kept for the record: milestone M3 (T1, T2) plus the T4 layer fragment, 2026-10-07 session 2 (Steam build 11094443). M0 was session 1 (below). Session 2 said "READY: wp.c2c"; review R2 found 9 majors (wp/C2c-review-R2.md).
- Built and live (synced to the Frame):
theme/40-library.css(T1), rewritten for the catalogue only; every Home rule is gone (C2a's REQ #6). The header rows sit below C1a's toolbar row (--lgs-hdr-pad), with the scroll guard on Steam's grid scroller. The tab row is a segmented control (64 track, contiguous 60/80 segments, 22 Semibold in Steam's case), with 60 px ‹ › circles. The VR sub-filter is the same control in Steam's place. Posters keep Steam's geometry; Steam's outline, focus pulse and shine are gone, and the attention target lifts (gamepad: Steam's focus transform; laser: x1.05 after the dwell, P4's--lgs-lift) with the +15 mm shadow and glow. Also restyled: the filter notice, section headers, fast scroll, collection tiles (radius 30, empties dimmed by T2), and Library Filters (T1 fallback: the card in C1c's sheet look, compat rows 80, platters, 80 px check rows).- D-C2c-12 (new): Steam's laser Sort & Filter pill is now the toolbar row's trailing group (top right, y 24–84), not ornament slot 1. C1a's window clip cuts page content at y 656, so the pill (a page node) could neither show nor take clicks in the ornament. The ornament hugs Steam's legends in Steam's order (no empty slots when Steam drops X/Y/≡). PLAN §1.10's five fixed 880 px slots are kept behind the flag
libFixedSlots(off). device/rt/40-library.js(T2,wp.c2c, depsshell,more):- registers posters with C1a's More circle (direct laser path to the tile menu);
- copies Steam's sort name onto the Y legend, so slot 1 reads "Sort By · Alphabetical" (Steam's own string; no new string);
- tags the tab segments E-SEG and tags empty collections;
- when
libFixedSlotsis on, registers the fixed slots. - Install and remove are clean (no attribute left after the flags pop; checked).
theme/layers/40-library.json(T4): the attended poster and collection tile pop at +15 mm (liquid slab, non-interactive). It supersedes the legacysort-filterandtab-arrowrules whilewp.c2cis on. The tab track moved to%{TabRow}::before, so legacytabsno longer pops it.
- Not built (open; nothing is lost without them):
- the letter scrubber (T3,
libScrubber); - the T3 Filters re-render (the T1 fallback ships);
- the filter-count badge;
C2c-cmp.json, so PLAN-2c-2'scmpwas not run;- anchored menus (C1c's).
- PLAN-2c-1 (880 ± 1) holds only with
libFixedSlots(D-C2c-12; REQ-8 to the coordinator).
- the letter scrubber (T3,
- Native: P7 reports M1, not M3. The user asked for native glass work anyway, so two
native-sessionruns went on AllGames:- sgcheck: the laser-dwelt poster pops at 15.0 mm; the first run's only R2 failures were legacy
tab-arrowpops at 4.43 mm (now superseded); - with the poster focused by the gamepad, sgcheck PASSES (one pop, 15 mm);
- with the Filters sheet open, only C1c's legacy
filterspop (11 mm, REQ-10) fails; - one hv look: native glass window, segmented tabs, the toolbar pill, the ornament;
- the frame was deleted on both machines, and the session returned to CSS only. See S2-N1 and S2-N2.
- sgcheck: the laser-dwelt poster pops at 15.0 mm; the first run's only R2 failures were legacy
Review R2 findings: what fix pass 1 did
Review: docs/phase2/wp/C2c-review-R2.md (Q1-Q9 counted; M- and m- items from its Appendix A). Evidence ids are the R2F rows under Evidence.
| Id | Finding | Fix (session 3) | Evidence | State |
|---|---|---|---|---|
| Q1 | Y legend cut mid-word | Steam's label is a flex box, which never draws an ellipsis; on the Y legend it is now one line box (display: block), capped at 334 px, the sort name after thin spaces (D-C2c-19). "Sort By · Alphabetical" shows whole; longer names end in "…" |
R2F-S1 (pad shot), R2F-G1 | fixed |
| Q2 | Close circle on the Filters title | The sheet is a column: a pinned 60 px title row (the circle's row, title centred, 96 px clear each side) and a scrolling body | R2F-S2, R2F-M3 | fixed |
| Q3 | Default gamepad focus hidden below the card | T2 listens for Steam's vgp_onfocus inside the sheet and scrolls the focused row into the body's view ('nearest', a wheel-equivalent); on open the All Games row is shown |
R2F-F2 | fixed |
| Q4 | Sort pill illegible while its menu is open | C2c's background: none now skips [data-lgs-menu-source]; the source shows C1c's white .94 with the dark label, as a 60 px capsule in its 80 px box |
R2F-G4 (no CONTRAST), R2F-S3 | fixed |
| Q5 | Focus under the ornament; Collections row cut | The scroller's end padding is 116 px (720 − 612 + 8) and its scroll padding counts Steam's x1.053 focus growth (8 px), so every row, the last one included, scrolls inside 124-612 | R2F-P23 | fixed |
| Q6 | Focus invisible on a selected segment | D-C2c-16 (tvOS segment focus) | R2F-F1 | fixed; P-15 reading asked (REQ-13 (1)) |
| Q7 | Collection tiles: Steam's blue laser hover, no dwell | Tiles are dwell hosts (data-lgs-dwell, P3's global dwell); Steam's light-blue hover and focus fill go; the dwell lifts the tile like a poster; the native rule pops it |
R2F-S4, R2F-N1 | fixed |
| Q8 | G-PERF 0.70 on AllGames | C2c's share measured and fixed: the CSS costs nothing, the module without the scrubber nothing, the scrubber about 5 % after two fixes (D-C2c-18). The route's gap to stock is outside C2c's files | R2F-P1 to R2F-P6 | C2c's share fixed; route verdict reported to the coordinator (REQ-13 (3)) |
| Q9 | Scrubber, T3 Filters and count badge not built | Built: the letter scrubber (T3, libScrubber) and the toggle-capsule sheet (T3 props patch, libFilterChips; 5,809 → about 3,530 px). Not built: HA §9's collapsed sections and pop-up row (they would take Steam's nodes out of the page: REQ-13 (2)) and the filter-count badge (below) |
R2F-T1, R2F-T2, R2F-T3 | partly fixed |
| R2-2 check 2 | Pill 6 px from the search capsule | Group capped at 336 (section roots) and 276 (collection pages), padding 18 / gap 8 so "Alphabetical" fits whole (330 wide, x 926-1256); 20 px left of the account-alert circle when it shows | R2F-R22 | fixed |
| M20 | Legacy card pops a stale-focus poster at 2.95 mm |
Not C2c's file: REQ-12 to P6 (an exclude keyed on C2c's new data-lgs-lib mark) |
R2F-N1 | waiting on P6 |
| M7 | "ALL · VR · NON-VR" in capitals | Steam's own strings (#Library_FilterCollection_VRSubtabs_* are uppercase); no mixed-case Steam string exists (PLAN §1.15), so nothing is drawn over them; REQ-17 (2) asks P10 to make P-84 see literal capitals |
— | open (not counted by the review) |
| M9 | Laser AUD GONE "SELECT" |
C1a's Options member shifts Steam's legend paths; REQ-15 (2), REQ-17 (1) | R2F-G1..G5 | waiting on C1a / P10 |
| M10 | More circle's hit over square posters (Soundtracks) | Re-measured: R2F-G3 | R2F-G3 | see the row |
| M12 | 100 ms transition on the poster as the sheet takes focus | Re-filmed: R2F-M2 | R2F-M2 | see the row |
| M13 | More circle outlives wp.c2c |
C1a's helper (REQ-15 (1)); C2c's own marks, scrubber and patch are removed (R2F-R1) | R2F-R1 | waiting on C1a |
| M14 | 4 Hz poll | Gone: the module runs on Steam's history, four narrow MutationObservers on library routes, vgp_onfocus in the sheet and scrollend; nothing at idle |
R2F-R1 (scans count) | fixed |
| M15-M18 | Build list, evidence, mockups, REQs | Scrubber and capsules built; C2c-cmp.json written and cmp run; mockups re-rendered for R2-2 / R2-5 (Cancel 60) and the as-built sheet; REQs to C2c marked [x] where filed; R2-2 text sent to C2a (REQ-14) |
R2F-M1..M3 | fixed |
| m1 | .gpfocus resets without an input-mode scope |
Every C2c .gpfocus selector now names a mode |
static | fixed |
| m2 | Glass on glass in the tag results | A recessed list (--lgs-fill-thick), no blur |
static | fixed |
| m4 | Uneven compatibility rows | The row is a grid: label and icons on line 1, the description across the row on line 2 | R2F-S2 | fixed |
| m5 | Log numbers | D-C2c-7 (.30) and D-C2c-13 (x1.053) corrected | — | fixed |
| m6 | ‹ › circles at 45.8 / 1174.2 | Not changed (geometry of Steam's tab row; minor) | — | open |
| m7 | Empty band on tabs without the sub-filter | Tried and reverted: with the grid under the tab row the second row sat with 19 % of its hit band under the ornament and failed P-08 on the VR collection (gates 19:33); the band keeps rows where the obscured rule skips them | R2F-G2 | kept by design |
| m8 | Radio wells invisible | The radio is the trailing blue check of a single-choice row (empty when not chosen) | R2F-S2 | fixed |
| Count badge | HA §7.1's number on the X legend | Not built: Steam's own X legend already names the state ("Filter: Advanced", or the compatibility icons), and the count needs Steam's advanced filter spec (collectionsAppFilterGamepad), whose groups' meaning cannot be checked without setting a filter (never-list) |
— | open |
Requests
- REQ-1 REQ C2c->C2a: home-apps.md, apply C2c's PLAN §1 conformance text for the library catalogue. It covers HA §0.1 (three mockup rows), §1.2 item 6, §1.3 "Library Filters" row, §7 (with §7.1 and §7.2), §8, §9, the library rows of §10.4 and §11, §12.2, §12.3 T1 and T7, §12.4, §12.5 C1, §12.9 SN-F1, the library rows of §13, the library parts of §14 AT-6 and AT-7, AT-14, AT-15, §15 #12 and §16 row 4. The full replacement text is in "Proposed text for home-apps.md" below. Why: this is M0 for C2c's sections, and C2a owns the file. C2a, 2026-10-07: done: merged into HA §0.2, §1.2, §1.3, §7–§9, §10.4, §11, §12, §13, §14 (library AT-6/AT-7 as their own rows, AT-14, AT-15), §15, §16, keeping §12's Owner/Test columns; the count is 60 functions, not 59 (details in
docs/phase2/wp/C2a.md). - REQ-2 REQ C2c->C2a: home-apps.css. C2c's mockups no longer use the
hl-*block,.ha-poster.is-liftor.hl-cap/.hl-hit/.hl-menu: their styles now live inline in C2c's three mockups (prefixlc-). You may delete them. C2c still uses.ha-poster(base rule) and home-apps.js's[data-app]poster fill, so please keep those names stable. C2a, 2026-10-07: done:hl-*and.ha-poster.is-liftremoved fromhome-apps.css;.ha-poster(base,img.port,.is-titlecard) andhome-apps.js's[data-app]fill kept. - REQ-3 REQ C2c->C1a: frozen target in library slot 3. On library routes your T2 Options member sits in C2c's fixed 156 px slot (PLAN §1.10; PLAN-2c-1 requires 880 ± 1 px in both modes), so the "· " suffix cannot fit. Please omit the suffix there, for example when
#Footercarries an attribute that C2c's T2 sets (tell me its name). Instead, keep the More circle on the frozen target while the pointer is inside#Footer, so the target stays visible on its own poster (p2_home-apps_library.pngshows the circle on its source). C1a answer (2026-10-07, session 2): adopted (WN §3.4.3 item 4, §3.4.4): on fixed-slot routes there is no name suffix, and the More circle stays on the frozen target while the pointer is inside#Footer. The attribute is set by the shell from your registration (REQ-5):#Footer[data-lgs-orn-fixed="library"]; C2c's T2 sets nothing for it. - REQ-4 REQ C2c->C1a: Options member. In gamepad mode, on routes with registered More hosts, show it disabled whenever Steam renders no ≡ legend (focus on the tab row), so the library's slot 3 never empties. Disable it (no dispatch) while any modal is open, in both modes, so it cannot stack a second menu. C1a answer: adopted (WN §3.4.2 slot 2): on fixed-slot routes the Options member never leaves its slot; in gamepad mode with no ≡ legend from Steam it shows disabled. In both modes it is disabled (.38, no dispatch) while main's ModalManager holds any modal or context menu.
- REQ-5 REQ C2c->C1a: ornament backing on library routes. Let an area fix the capsule's rect instead of measuring the members' union: C2c needs x 200, width 880, the slots 300 · 130 · 156 · 134 · 120, gap 4, padding 12. Otherwise the capsule changes width when Steam drops a legend (≡ while no poster is focused) or when the input mode flips. A registration call such as
__LGS_RT.shell.ornamentSlots({widths, gap, padding}), or a CSS variable C2c may set on#Footer, would do. Also, during alerts and sheets in laser mode, darken the capsule with the tab bar's black .35 layer (WN §3.3.4) while A and B stay lit (p2_home-apps_filter.png). Please answer with the API name. C1a answer: API__LGS_RT.shell.ornamentSlots('library', {widths: [300, 130, 156, 134, 120], gap: 4, padding: 12})→{remove()}(WN §3.4.1); the backing stays at x 200–1080 and never re-measures; you place the members in the slots with your T1 rules. During alerts and sheets (C1c'shtml.lgs-modal) slot 1, Options and the area slot recede under black .35 and stay clickable; A, B and the dialog's legends stay lit (WN §3.4.2). The capsule glass itself is not darkened. - REQ-6 REQ C2c->C1c: menu anchoring and sheet frame.
- (1) Keep slabs placed beside or above a source at least 12 px clear of the ornament's top (bottom ≤ 616), as the tile menu in
p2_home-apps_library.pngis (400 × 506 at (421, 110)). At 628 they touch the capsule. - (2) C2c's Filters content assumes your sheet frame from
window-nav-sheet.html(960 × 488 at (160, 128), close circle at (24, 24), a trailing capsule at the 24 px inset). - (3) VP P-35 asks for sheets centred on the glass ±24 px (glass centre y 328; this frame's centre is 372, centred in the 108–628 modal box instead). Your call; tell me if the frame moves.
- C1c answer (2026-10-07, session 2): (1) done in T1:
theme/22-presentations.csspads Steam's menu box to y 108–616 onmain(bottom ≤ 616 in every layout, measured live: tile menu 400 × 496 at y 107–603); C1c's T2 anchoring (M3) clamps to the same box. (2) and (3): the frame moves up to y 108 (top-aligned under the toolbar row, D7): ≤ 960 wide, centred horizontally (x 160–1120), at most 488 tall onwindowroutes (552 onwindow-full), so its centre stays within 24 px of the glass centre (P-35); live on ZOO('Scroll Panel Test'): 958 × 487 at (161, 109).ModalPosition's own padding does it, so a%{DialogWrapper}(your Filters scroller) is held to that box and scrolls inside. Close circle (24, 24) and the trailing capsule at the 24 px inset as drawn; the circle is C1c's T2 (M3).
- (1) Keep slabs placed beside or above a source at least 12 px clear of the ornament's top (bottom ≤ 616), as the tile menu in
- REQ-7 REQ C2c->Coordinator: PLAN §1.7 contradicts itself. The table row "Source card while its menu is open: it keeps +15 if it was the focused card" conflicts with admission rule 6 ("while a modal … is open, only the modal itself pops"). P6's reporter implements rule 6 (
contracts/reporter.md, admission step 6,modal: truerules). C2c follows rule 6: the source poster goes to 0 with a CSS glow, and the menu at +10 is then in front of it. A +15 source beside a +10 menu would also put the source in front of its own menu. Please amend the row, or confirm it.- Coordinator (2026-10-07, round R2): row amended to rule 6: the source card is at 0 with a CSS glow in both input modes and both profiles; the control that opened the menu is white .94 (PLAN §1.7; §1.19 R2-3). No change needed in C2c's files.
- REQ-8 REQ C2c->Coordinator: PLAN §1.10 and PLAN-2c-1 (five fixed slots, 880 ± 1 px in both modes, Steam's laser Sort/Filter in slot 1) cannot hold on device. (1) C1a's window clip (
clip-pathat--lgs-c1a-gh, y 656) cuts every page node below the glass. Steam's laser pill is a page node, so in the ornament (y 628–712) it is half hidden and takes no clicks (elementFromPointreturns#MainNavMenu-Rest, session 2). (2) Steam drops its X / Y / ≡ legends whenever focus is on the header rows, and in laser mode, so a fixed 880 capsule shows 434 px of empty slots. C2c ships D-C2c-12: the pill is the toolbar row's trailing group, and the ornament hugs Steam's legends. The fixed slots stay available behindlibFixedSlots(off). Please amend §1.10 and PLAN-2c-1, or rule otherwise.- Coordinator (2026-10-07, round R2): D-C2c-12 adopted: the library ornament hugs its members, the laser pill is the toolbar row's trailing group, the fixed slots stay behind
libFixedSlots(off, S28); PLAN-2c-1 is replaced by R2-2's three checks, which add ≥ 20 px clear of the search capsule (6–8 px today: REQ Coordinator->C2c inwp/coordinator.md) (PLAN §1.10, §2.4; §1.19 R2-2).
- Coordinator (2026-10-07, round R2): D-C2c-12 adopted: the library ornament hugs its members, the laser pill is the toolbar row's trailing group, the fixed slots stay behind
- REQ-9 REQ C2c->C1a: on library routes, Steam's laser Sort & Filter pill now sits at the toolbar row's trailing edge: right-aligned 24 px from the glass edge, y 14–94 hit (24–84 visible), at most 420 wide. On section roots it starts at x ≈ 908, right of the 520 search capsule; with the sort "Alphabetical" it is x 906–1256. Please keep that area free of shell items on
libraryroutes, or tell me where it should go. Also:libFixedSlotsis off, soornamentSlots('library')is not registered by default, and your capsule hugs the legends. Your fixed-slot CSS and API stay in use behind the flag.- C1a answer (2026-10-07, R2 fix pass): answered (with the coordinator's R2-2): the area right of the search capsule is yours on
libraryroutes and stays free of shell items (WN §3.2, new "Trailing group" row). The search capsule is visible x 380–900, its hit box 372–908; with PLAN §1.10's ≥ 20 px your group's visible left is ≥ 920 and its hit box starts ≥ 910, so the 2 px hit overlap measured in review R2 goes once the group is capped (your width cap).
- C1a answer (2026-10-07, R2 fix pass): answered (with the coordinator's R2-2): the area right of the search capsule is yours on
- REQ-10 REQ C2c->C1c: the Library Filters card (Steam's
%{DialogWrapper}scroller, 660 × ≤ 488 at x 310, inside your modal box) is not a directdiv.Panelchild ofModalPosition, so your sheet rule does not give it glass. C2c gives it your look in40-library.css(%{DialogWrapper}:has(> %{DialogWrapper>CompatFilterDialog}): thick material, radius 44,lgs-sheet-in). Two findings: (a) Steam's modal layer acts as the backdrop root, sobackdrop-filtercannot reach the page and the sheet needs a denser tint (C2c adds black-blue .62 under--lgs-mat-thick-bg); (b) a gradient listed aftervar(--lgs-mat-thick-bg)makes the wholebackgroundinvalid, because the token ends in a colour layer. If you cover the scroller in your rule, tell me and I will remove my copy. (c) In native mode the legacyfilterslayer rule still pops this sheet at 11.07 mm, outside PLAN §1.7's set (sgcheck R2, S2-N2); retiring it is yours (reporter.md §3.5).- C1c (2026-10-07 20:25): (a)/(b) noted; keep your copy in
40-library.css(C1c does not cover the scroller this round). (c) accepted: retiring the legacyfilterslayer rule moves with C1c's next native session; tracked as open in C1c's Status. - C2c (2026-10-07, session 3): (c) is resolved: review R2's native session (sgcheck with the Filters sheet open, 15:59) shows one pop, the sheet at 10.0 mm,
modal ['c1c-sheet'], and no legacyfilterspop. Since session 3 the card is 960 wide with a pinned title row and a scrolling body (C2c's CSS, HA §9); (a) and (b) stand.
- C1c (2026-10-07 20:25): (a)/(b) noted; keep your copy in
- REQ-11 REQ C2c->C2a: FYI.
theme/layers/40-library.jsonsupersedes the legacytab-arrowrule whilewp.c2cis on. That rule matches only the library's and Steam's own Home tab rows, and pops the ‹ › circles at 4.43 mm, outside PLAN §1.7's set (sgcheck R2). Steam's Home arrows (/library/lgs/steamhome) then stay on the window plane. Your track on%{TabHeaderRowWrapper}::afteris still popped by the legacytabsrule; C2c moved its own track to%{TabRow}::beforeto escape it.- C2a (2026-10-07, R2 fix pass): done. What's New's track moved to
%{RecentSection} ~ %{TabbedContent} %{TabRow}::before(the wrapper's::afteriscontent: none, so the legacytabsrule matches nothing there;tabsstays for C1b's search), and41-home.jsonsupersedestab-arrow(and the legacycard, 2.95 mm, which also popped on a stale.gpfocusin laser mode) behindwp.c2a. Native session 20:00 (wp.c2a,wp.p3,wp.c1a): sgcheck on/library/lgs/steamhomePASS in pad (one pop, the attended shelf capsule at 15 mm) and laser (no pop). Note: withwp.c2aon, the library's posters no longer get the legacy 2.95 mm lift; yourlibrary-posterrule (behindwp.c2c) is their only pop.
- C2a (2026-10-07, R2 fix pass): done. What's New's track moved to
- REQ-12 REQ C2c->P6: retire Phase 1's legacy
cardpop on library posters whilewp.c2cis on (review C2c R2 M20, G-DEPTH): in laser mode Steam leaves a stale.gpfocuson a poster, and99-legacy.json's admission-offcardrule pops it at 2.95 mm (a depth outside PLAN §1.7's set) beside the dwelt poster's 15 mm (native session 15:59,FAIL R2 main/card). C2c cannot supersedecardfor the library alone (it also serves Home and search, reporter.md §3.5), and an earlier library rule only drops it by overlap when both pick the same poster. Since session 340-library.jsmarks the library rootdata-lgs-lib="c2c"whilewp.c2cis on (gone with the flag). Please add to the legacycardrule"exclude": "[data-lgs-lib] %{LibraryItemBox}, [data-lgs-lib] %{Collection}": withwp.c2coff the mark is absent and the legacy pop comes back unchanged. (Alternative, yours to choose: have admission-off rules ignore.gpfocusin theirselwhilehtml.lgs-input-laser, as reporter.md §3.3 already does forwhen: attended.) - REQ-13 REQ C2c->Coordinator: four items from the R2 fix pass.
- (1) P-15 on segmented controls with a white selection (review C2c R2 Q6, C1b review R2 M2). PLAN §1.4's state recipe cannot pass P-15 there: the selected segment is white .94, so a focused-unselected segment cannot be 15 L brighter than it on a bright room (255 against 250). C2c ships the tvOS rule (D-C2c-16): the focused segment is opaque white with the white glow at spread 14 / alpha .70, and while focus is inside the control its selected-unfocused segment recedes to the navigation-selected look (white .18 + arc). C2c scores P-15 in one view (focused VR against the selected ALL beside it, focus in the control), which is what P-15 protects ("a user sees which is focused and which is selected"); the reviewer's pair (selected ALL measured with focus in the grid) cannot pass on a bright room by construction. Measured values are in C2c's evidence (R2F-F1). Please rule: adopt the one-view reading for segmented controls with a white selection (and P-15b judged by P-16's band there), or name the look you want; C4a's segmented primitive and C1b's search tabs have the same problem.
- (2) HA §9's T3 sheet (review C2c R2 Q9). Built in session 3: the Filters sheet keeps Steam's dialog (every node, handler and string) and draws each section's options as wrapping toggle capsules, with the section's D-pad made spatial by a P2 props patch (flow-children "grid", D-C2c-17): 5,809 px of content became about 3,530 px (body scrollHeight). HA's collapsed sections and the compatibility pop-up row are not built: collapsing a section takes Steam's own option nodes out of the page, which G-AUD reads as GONE (and AT-15 (b) asks for 0 GONE). To reach HA's ≤ 1,400 px the plan needs one of: (a) an AUD rule that matches a T3 twin bound to the same setter (HA AT-15 (b)'s wording) so collapsed rows are not GONE, or (b) accepting the capsule sheet as HA §9's T1/T3 floor. Please rule.
- (3) G-PERF on
/library/tab/AllGames(REQ Coordinator->C2c (3), answered there): C2c's share was measured with in-step A/B probes (R2F-P1 to R2F-P5):40-library.csscosts nothing measurable (without it 56.5 fps, with it 58.7), thelibrarymodule without the scrubber costs nothing (64.65 against 64.7 without the module), and the scrubber costs about 5 % (62.8 against 66.45) after two fixes (a per-frame layout read, 13 %; a fixed node over the scroller). The route's remaining gap to stock (about 81 → 66 fps with no C2c code at all) is outside C2c's files;perf --ab stockwith C2c on is recorded as R2F-P6. - (4) Default-on sub-flags.
libScrubberandlibFilterChipsare on wheneverwp.c2cis on unless a layer sets them false (the module reads an unset flag as on). V1 may list them indefaults.jsonfor visibility; nothing else is needed.
- REQ-14 REQ C2c->C2a:
home-apps.md, round R2 text for C2c's sections (your REQ Coordinator->C2a asks for the same; review C2c R2 M17). Please apply:- §7.1: the ornament hugs Steam's legends in Steam's order on library routes (PLAN §1.10, R2-2); the five fixed slots are the
libFixedSlotsvariant (off). Laser mode: Steam renders no X / Y / ≡ legends; the ornament is the shell's Options member plus quiet Select and Back; Steam's Sort & Filter pill is the toolbar row's trailing group (one 60 px capsule, visible y 24-84, right edge 1256, ≤ 336 wide on section roots and ≤ 276 on collection pages so it stays ≥ 20 px clear of the search capsule, the sort name ellipsizing first; 20 px left of Steam's account-alert circle when that shows). Gamepad mode: X Filter, Y "Sort By · " (thin spaces round the dot; at most 334 px, ellipsized with "…"), ≡ Options, A Select, B Back. - §7 "Letter scrubber": as built (D-C2c-18): a 60 × 340 recessed capsule in an 80 px column at x 1186-1266, y 270-610, docked in a zero-height sticky wrapper at the end of Steam's grid scroller; 27 letters ("#", A-Z) shown every third with a 6 px dot between when they do not fit at 20 px; laser click or drag scrolls the letter's first row to y 270 and moves Steam's focus there with the mouse source when Steam had a focus in the grid; gamepad: passive (the current letter follows the focused poster); shown only for Alphabetical with 4 rows or more; the grid's columns step in by 72 px while it is mounted. Flag
libScrubber(on withwp.c2c). - §9: as built (D-C2c-17): the sheet is 960 × 488 from y 108; a pinned title row (the close circle at (24, 24), Steam's "Library Filters" centred, 96 px clear of each side); the body scrolls under it with 12 / 56 px edge fades; the compatibility rows are 80 px single-choice rows in one platter (Steam's icons, a trailing blue check, the description across the row); each section is a platter; with
libFilterChips(T3) its options are toggle capsules (60 visible, 80 hit, ≥ 168 wide, a faint disc off, Steam's check on white .94 on); Reset and Save at the end; on open the gamepad's default row is scrolled into view. The pop-up row and the collapsed sections stay HA's target, pending REQ-13 (2). - §14 AT-14 (c): "the row holding the first title that starts with M is the first fully visible row" (rows of 6: the row may begin with titles of the letter before); (d): the three R2-2 checks replace "880 ± 1".
- §7.1: the ornament hugs Steam's legends in Steam's order on library routes (PLAN §1.10, R2-2); the five fixed slots are the
- REQ-15 REQ C2c->C1a: seven items seen on library routes (review C2c R2 O3, O4, O6, O7, O8; session 3 gates).
- (1) The More circle outlives its host (M13, O4): after
wp.c2cturns off, or after a laser dwell on AllGames and a route change to Collections,.lgs-morestays shown and clickable over the first collection tile: gates/library/tab/Collections --mode laser(19:32) failed P-08 on "DS ( 0 )" with "39 % other (lgs-more lgs-more-show "Options")".more.register(...).remove()should hide a circle shown on one of its hosts, and a route change should hide it. - (2) AUD keys on DOM paths (M9, O6, with P10): your T2 Options member inserted among Steam's legends shifts their paths, so laser-mode AUD reports
GONE text "SELECT"on Non-Steam, Soundtracks, the VR collection and with the Sort menu or Filters sheet open (session 3 gates 19:33-19:41), while Select is present, visible and hit. Appending the member after Steam's legends (or P10 matching by text) would end it. - (3) An animation at rest:
lgs-fade-instill running on.lgs-opt-label1 s after the route settles (gates/library/tab/DesktopApps --mode laser, 19:34, MOTION atRest). - (4) O7: with a real laser hover on a poster the ornament showed only "Options · Back" (review R2; stock shows Select too).
- (5) O3: the Large Title read "Sort By" while the Sort menu was open (review R2; not checked against stock).
- (6) O8 (native): the pointer proxy's 1.5 px ring fails P-43.
- (7) FYI: on library routes C2c's Y legend widens after your compact measurement runs (C2c's attribute changes after Steam's footer mutation); it is capped at 334 px so the regular capsule stays ≤ 960 (957 measured); if you re-measure on attribute changes of
[data-lgs-lib-sort], C2c can lift the cap.
- (1) The More circle outlives its host (M13, O4): after
- REQ-16 REQ C2c->C1c: three items seen on library routes (review C2c R2 O1, O2, O5). (1) The compact tile menu's header (the game's name) has no width limit and runs past the slab (
p2_c2crev_tile_laser.png). (2) E-MENU Cancel still fails its own line in the tile menu and the Sort menu: "fill 188 x 56 on a 192 x 60 element" (session 3 gates 19:41,g_sort_laser,g_tile_pad). (3) P-53: the toolbar row (Back, search, title) scales to 0.97 while the sheet opens (review R2 R-T2).- C1c (2026-10-07 20:25): (1) done: the menu title is one line with an ellipsis, padded to the slab on both sides (
22-presentations.css). (2) done: Cancel 60 visible; tile menu gates pad/laser give the Cancel line PASS (Sort is your route: please re-run it). (3) the toolbar row scaling is not C1c's rule (C1c only animates the sheet and its content); please check C1a/C2c's toolbar transition.
- C1c (2026-10-07 20:25): (1) done: the menu title is one line with an ellipsis, padded to the slab on both sides (
- REQ-17 REQ C2c->P10: (1) AUD keys on DOM paths (REQ-15 (2)); (2) P-84 on literal uppercase strings: Steam's own sub-filter strings are uppercase ("ALL", "NON-VR":
#Library_FilterCollection_VRSubtabs_*), sotext-transform: nonecannot help and TYPE passes them; C2c keeps Steam's strings (PLAN §1.15: no mixed-case Steam string exists for them); a check would make the deviation visible; (3) the P-16 band is measured outside the element's box, so a control with a transparent 10 px border is judged 18-26 px from its visible fill; measuring from the painted fill (or recording both) would match VP's intent.
Requests to C2c, handled
- 2026-10-07, start of session 1:
grep -n "REQ [A-Za-z0-9]*->C2c:" docs/phase2/wp/*.mdreturned nothing (nodocs/phase2/wp/directory existed yet). - 2026-10-07, session 2 (three found):
- REQ C1a->C2c (
C1a.md):- (1) Done. The header rows move below the toolbar row by
--lgs-hdr-pad(%{TabHeaderRowWrapper}top; Steam's grid scroller is padded to match), so the tab row is at y 108–188 and no longer under the search capsule. G-SIZE has no P-08 failure on tabs or the sub-filter. - (2) Done.
scroll-padding-top/-bottomon%{TabContentsScroll}come from--lgs-hdr-padand--lgs-guard-bottom. - (3) Not possible as asked: your window clip cuts the pill in the ornament. It is placed at the toolbar's trailing edge instead (D-C2c-12; REQ-8, REQ-9).
- (1) Done. The header rows move below the toolbar row by
- REQ C1c->C2c (
C1c.md; mockups): done in session 1 (M0). The three mockups have menus at +10, layout by count, Cancel as a 56 px quiet capsule, laser hover + .08, the source at 0 with a glow (rule 6, REQ-7) and the sheet ≤ 960 at +10. - REQ C2a->C2c #6 (
C2a.md): done.theme/40-library.csswas rewritten without any%{RecentSection}rule. The file now holds only library-catalogue rules under%{GamepadLibrary}, the pill, the ornament's library rules and Library Filters.
- REQ C1a->C2c (
- 2026-10-07, end of session 2: the same grep returns only these three (all handled above). The
theme/_wipanddevice/rt/_wipcopies were identical to the landed files and are removed. - 2026-10-07, session 3 (review R2 fix pass 1):
grep -n "REQ [A-Za-z0-9-]*->C2c" docs/phase2/wp/*.mdfound four open lines:- REQ C1a->C2c (
C1a.md), REQ C1c->C2c (C1c.md) and REQ C2a->C2c #6 (C2a.md): handled in sessions 1-2 but never marked where they were filed (review R2 M18). Marked- [x]there with the answers above, updated for R2 (the scroll guard now counts Steam's focus growth and gives the last row room; Cancel 60 in the re-rendered mockups). - REQ Coordinator->C2c (
coordinator.md, items 1-4): answered there, marked- [x](1: the group's caps 336 / 276 and the alert-circle rule; 2: R2-2's three checks, R2F-R22; 3: G-PERF share, R2F-P1..P6 and REQ-13 (3); 4: the mockups re-rendered with Cancel 60).
- REQ C1a->C2c (
Evidence
| Test | Command | Result | Files | Date | Steam build |
|---|---|---|---|---|---|
| M0-R1 | python tools/mockshot.py docs/phase2/mockups/home-apps-library.html shots/p2_home-apps_library.png |
Rendered; viewed. Verdict: matches §7, §7.1 and §8 as proposed (details below) | shots/p2_home-apps_library.png |
2026-10-07 | n/a (mockup) |
| M0-R2 | python tools/mockshot.py docs/phase2/mockups/home-apps-library-pad.html shots/p2_home-apps_library-pad.png |
Rendered; viewed. Verdict: matches §7 and §7.1 (gamepad) | shots/p2_home-apps_library-pad.png |
2026-10-07 | n/a |
| M0-R3 | python tools/mockshot.py docs/phase2/mockups/home-apps-filter.html shots/p2_home-apps_filter.png |
Rendered; viewed. Verdict: matches §9 and §7.1 "while a modal is open" | shots/p2_home-apps_filter.png |
2026-10-07 | n/a |
| M0-G1 | Rect dump of every data-id (and of .lc-seg > span, .lc-orn > *, .lc-menu > *, .lc-chips > *) with a scratch Playwright script against the same headless Chrome (not a repo tool; P10's mockshot.py --rects will replace it) |
Ornament 880 × 84 at (200, 628); slots 300/130/156/134/120 × 60 at x 212, 516, 650, 810, 948 in both modes. Tabs and sub-filter: segments 60 tall, contiguous, ≥ 140 wide (sub-filter 3 × 140 = 424 at x 428). Tile menu 400 × 506 at (421, 110), rows 60 on a 64 pitch, Cancel 56. More circle 60 × 60 at (335, 280) inside the source poster (233–405), and at (719, 274) inside the lifted poster (608.7–789.3 × 263.5–534.4). Scrubber 60 × 340 at (1196, 270). Sheet 960 × 488 at (160, 128). Toggle capsules 60 tall, one row per section (Players ends at x 1003, Play state at 972, inside the 912 px body x 184–1096). Text: 19 px (menu label) is the smallest | stdout only | 2026-10-07 | n/a |
| S2-G1 | python glass.py gates main --route /library/tab/AllGames --mode laser --flags wp.p3,wp.c1a,wp.c2c |
PASS (native off): AUD 0 issues (21 exempt), SIZE 0 fails (8 E-SEG: 5 tabs, 3 sub-filter segments, all pass), TYPE 0, OUTLINE 0 (8 probes), MOTION 0 at rest and no non-token durations | stdout | 2026-10-07 10:10 | 11094443 |
| S2-G2 | the same with --mode pad |
PASS (native off): AUD 0, SIZE 0, TYPE 0, OUTLINE 0, MOTION 0 | stdout | 2026-10-07 10:12 | 11094443 |
| S2-G3 | gates main --route /library/tab/AllGames --mode pad --pre <Filter snippet, INV-L §0.3; + DialogWrapper.scrollTop 0 / 2000 / 4200> --flags wp.p3,wp.c1a,wp.c2c |
PASS at 0 and 4200 (sheet open: SIZE 0 over 25–40 checked, TYPE 0, OUTLINE 0, AUD 0). At 2000: AUD 1 (CONTRAST of the focused compat row's description, fixed afterwards: it turns white on focus). Earlier runs found 16 px compat labels, 38 px check lines and 14 px check labels, all fixed | stdout | 2026-10-07 09:40–09:55 | 11094443 |
| S2-G4 | gates … --pre <Sort snippet> (--only aud,size,type), pad |
AUD 0, TYPE 0. SIZE: the only failures are 11 E-MENU rows 284 wide in C1c's two-column Sort slab (E-MENU's ≥ 320 rule, C1c's open REQ to the coordinator), none of them C2c's | stdout | 2026-10-07 09:58 | 11094443 |
| S2-G5 | gates main --route /library/tab/Collections, laser and pad |
SIZE 0 (it had 18 failures before D-C2c-15), TYPE 0, OUTLINE 0 (13 hairline borders on the display case removed), MOTION 0. AUD 1, the same in both modes: "SHRUNK text NINTENDO SWITCH - YUZU 145x76 -> 143x50". This is a reflow (two lines in mixed case instead of three in Steam's uppercase), not a loss | stdout | 2026-10-07 10:16 | 11094443 |
| S2-G6 | gates main --route /library/collection/<VR collection id>, laser and pad |
PASS in both modes, after the nested-search fix (the pill had overlapped the 640 search capsule: P-08 72 %) | stdout | 2026-10-07 10:27 | 11094443 |
| S2-G7 | gates main --route /library/tab/DesktopApps, laser and pad |
pad PASS. Laser: AUD "GONE text SELECT" only with wp.c2c on. A live probe in the same mode shows Select present and visible (OK:Select:624,628,112,84:flex:visible:1). The cause: once C2c registers posters as More hosts, C1a's T2 Options member is inserted before A and B, which shifts the DOM path the audit keys on (lab.md: AUD keys are DOM paths). Not a lost function; C1a's audits on fixed-slot routes have the same shape. The same gate with wp.p3,wp.c1a only: PASS |
stdout | 2026-10-07 10:31 | 11094443 |
| S2-P1 | pad-bfs --route /library/tab/AllGames --mode pad --flags wp.p3,wp.c1a,wp.c2c |
4 nodes, 0 irreversible, 0 untested; Left from the first poster is exit:none, after which the tool cannot take focus ("untakeable"). This is the known sweep limit (REQ C2a->P10 #14; C1a measured the same 4-node baseline on stock). Manual D-pad replacement (L.pad, below) |
stdout | 2026-10-07 09:20 | 11094443 |
| S2-P2 | js with L.root() then L.pad (up, up, down, down, right ×2, down ×2, up ×4, left, down), --mode pad --flags wp.p3,wp.c1a,wp.c2c |
grid → sub-filter "ALL" → tab "All Games" → back down to the sub-filter and the grid; Right moves along the row; Down / Up keep the focused row inside the guard (y 256–340 after Steam's scroll); Left on the first tab wraps to Soundtracks and switches tab (Steam's own behaviour); every move reversible | stdout | 2026-10-07 09:25 | 11094443 |
| S2-S1 | shots c2c_t2_laser, c2c_laser_hover (--hover %{CSSGrid} %{LibraryItemBox},900), c2c_filter_pad, c2c_coll2, c2c_collpage |
Viewed: segmented tabs and sub-filter under the toolbar; the toolbar's trailing Sort & Filter group; the ornament reads "Filter · Sort By · Alphabetical · Options · Select · Back"; the dwelt poster lifts with the More circle at its top right; the Filters card is a glass sheet; collections have rounded tiles with labels in Steam's case | shots/c2c_*.png |
2026-10-07 | 11094443 |
| S2-N1 | native-session --step "sgcheck … --mode pad" --step "sgcheck … --mode laser --hover <poster>" --step "hv c2c_lib_native --look" --flags wp.p3,wp.c1a,wp.c2c |
Laser dwell: main pops 0 / 4.5 / 15.0 mm; the poster pops at 15. R2 failed only on the legacy tab-arrow (4.43 mm), which is now superseded behind wp.c2c. hv look (viewed, then deleted on the PC with hv --clean; none left in the Frame's /tmp/lgs): native glass window, segmented tabs, sub-filter, posters, the toolbar pill, quiet Select / Back. Doubling 0.39, not doubled. Back to CSS only: yes |
stdout | 2026-10-07 10:03 | 11094443 |
| S2-N2 | native-session with sgcheck (pad, poster focused with L.gpTake) and sgcheck (pad, Filters sheet open) --flags wp.p3,wp.c1a,wp.c2c |
Poster focused: PASS, main pops [0, 15.0] mm, one pop. Sheet open: the poster is not popped (rule 6); the only pop is the legacy filters rule at 11.07 mm (R2 FAIL). That rule is C1c's to retire (reporter.md §3.5; REQ-10). Back to CSS only: yes |
stdout | 2026-10-07 10:06 | 11094443 |
| S2-R1 | js after the flags popped |
library module off; no data-lgs-lib-sort, data-lgs-empty or data-lgs-exempt="E-SEG" left; no [data-lgs-orn-fixed]. With the flags on, the runtime log holds only "defined" and "installed in 2 ms" (no warning or error) |
stdout | 2026-10-07 10:35 | 11094443 |
| R2F-G1 | gates main --route /library/tab/AllGames --flags wp.p3,wp.c1a,wp.c2c --mode laser --shot p2_c2cfix_g_ag_laser, and --mode pad --shot p2_c2cfix_g_ag_pad |
PASS in both modes, native off: AUD 0, SIZE 0, TYPE 0, OUTLINE 0, MOTION 0. Pad shot: the Y legend reads "Sort By · Alphabetical" whole (Q1), the capsule 950 wide and centred; the focused poster lifts with its More circle; the scrubber shows "#" | shots/p2_c2cfix_g_ag_{laser,pad}.png |
2026-10-07 19:31 | 11094443 |
| R2F-G2 | gates on /library/tab/Collections, /library/collection/uc-QEu45ND5z53u (VR), /library/tab/DesktopApps, /library/tab/Soundtracks, both modes, same flags |
Collections laser PASS (19:43), pad PASS (19:32); VR collection laser PASS (19:45), pad PASS (19:47); Non-Steam pad PASS (19:57), laser: only GONE text "SELECT" (20:23; C1a's Options member shifts Steam's legend paths, M9, REQ-15 (2)); Soundtracks pad PASS (19:35), laser: only GONE "SELECT" (M9). Runs taken while another agent's native session was on (step line native=on) were discarded and re-run CSS-only. The m7 attempt (grid under the tab row) failed P-08 on the VR collection's second row at 19:33 and was reverted before these runs |
shots/p2_c2cfix_g_{coll,vrcoll}_{laser,pad}.png |
2026-10-07 19:32-20:2x | 11094443 |
| R2F-G3 | gates … --pre <X on the first poster> --flags wp.p3,wp.c1a,wp.c1c,wp.c2c: pad and laser at the sheet's open position, and pad with the body scrolled to 1400 (--shot p2_c2cfix_g_filter_deep_pad) |
Deep pad PASS (20:04, native off: the capsules and the Language pop-up pass SIZE, TYPE and AUD; an earlier run had the capsules SHRUNK on short labels and the pop-up unstyled, both fixed: capsules ≥ 168 wide, C4a's primitives kept). Open position: pad PASS; laser only GONE "SELECT" (M9) | shots/p2_c2cfix_g_filter_{pad,laser,deep_pad}.png |
2026-10-07 20:04 | 11094443 |
| R2F-G4 | gates … --pre <click the pill's Sort> --mode laser and --pre <≡ on the first poster> --mode pad, wp.c1c on |
Sort (laser): no CONTRAST on "ALPHABETICAL" (review 1.1 : 1; Q4 fixed); left: GONE "SELECT" (M9, C1a) and E-MENU's Cancel line ("fill 188 x 56", C1c, REQ-16 (2)). Tile menu (pad): AUD 0; only the same Cancel line |
shots/p2_c2cfix_g_sort_laser.png, _g_tile_pad.png |
2026-10-07 19:41 | 11094443 |
| R2F-P23 | js <p23b.js> (the reviewer's script: AllGames' last row, the VR collection walked down, the Collections tab's second row, Soundtracks), --mode pad |
With the 8 px margin (20:07): AllGames last row 339-611, Collections second row 414-609 (it scrolls now; review 468-663), Soundtracks 427-609; the VR collection landed 610-620 (two moves 4 and 8 px past 612). Margin raised to 16 px: every position inside 124-612 on all four routes, the VR collection included | stdout | 2026-10-07 20:07 | 11094443 |
| R2F-R22 | js <r22.js> (PLAN-2c-1 = R2-2's three checks) on AllGames and the VR collection, focus in the grid and on the tab row, --mode laser and --mode pad |
PASS in both modes on both routes and both focus places: capsule spans its members (0 / 0), centre 640, gaps 4; pill x 926-1256 on AllGames (26 px clear of search), 1018-1256 on collections; both buttons take their centre hit; no hidden nodes | stdout | 2026-10-07 20:44-20:46 | 11094443 |
| R2F-F1 | focus main --route /library/tab/AllGames --pairs pairs_c2c.json --mode pad --keep p2_c2cfix_focus (P-14 VR focus vs rest; P-15 in one view and the reviewer's pair; P-15b; P-16 bands on the All Games tab and the ALL segment) |
P-14 +188; P-15 in one view +149, the reviewer's pair +11.6 (fail; REQ-13 (1)); P-15b +30; P-16 tab +10.2, segment +15.7 (fail, band measured on the 80 px box: REQ-17 (3)) (a first run at 20:09 measured nothing: the states' gpTake did not land without L.root(); the states now root first) |
shots/p2_c2cfix_focus_*.png |
2026-10-07 20:3x | 11094443 |
| R2F-F2 | js <p2b.js> (Filters opened with X, gamepad; then Down ×6) |
On open the body scrolls the default row ("All Games", y 440-540) into view (body scrollTop 112-131) under the pinned title; each Down lands on the next section with it in view (Steam's own scroll). Stock compared (--stock): the same section-by-section D-pad (sections are focusable groups on stock too) |
shots/p2_c2cfix_filter_pad_open.png, _down1.png |
2026-10-07 18:25-18:35 | 11094443 |
| R2F-B1 | pad-bfs --route /library/tab/AllGames --max 40 --budget 200, pad |
47 nodes; 9 exits (Left at a row start, all back by overlay); 1 irreversible (Up from a poster to the sub-filter, Down back to another poster: the review's stock sweeps show the same kind); unreached: posters past the budget, the search box, the fast-scroll overlay; not focusable on stock either: ‹ › and the laser-only pill |
stdout | 2026-10-07 20:13 | 11094443 |
| R2F-R1 | js <remove.js> --flags wp.p3,wp.c1a (pushes wp.c2c inside the step, reads, pops, reads) |
With the flag: library root marked, 9 tiles dwell hosts (8 empty), 6 tabs E-SEG, the Y label's sort, the scrubber (dock, node, grid mark), the P2 patch registered. After the pop: every count 0, the patch gone, module off, on AllGames and Collections. (C1a's More circle is outside C2c's removal: REQ-15 (1).) Nothing runs at idle: the module's scans are event-driven (no interval) |
stdout | 2026-10-07 20:15 | 11094443 |
| R2F-M1 | cmp docs/phase2/mockups/home-apps-library.html --id C2c --mode laser (map docs/phase2/wp/C2c-cmp.json; pre: dwell on the second poster, click its More circle) |
Rects: poster-source and tile-menu PASS; every other delta is a hit box against a visible fill (back, search, members, the More circle, the scrubber: ±8-12 / +16-24), the VR sub-filter's 604 px group against its 424 px segments, BasicUiRoot's 720 against the 656 glass, the pill 330 against the kit's 295 (C1a's kit draws 20 px labels, the theme 22), and the ‹ › circles (m6, open). Viewer's verdict: the live page matches the mockup: the toolbar group, the tile menu grown from the white More circle with Install blue and Cancel, the hugging ornament "Options · Select · Back", the scrubber | shots/p2_cmp_c2c_home-apps-library.png |
2026-10-07 20:17 | 11094443 |
| R2F-M2 | cmp …-library-pad.html --mode pad (pre: focus the fourth poster) |
poster-focus PASS (dx −0.4, dy +3.7); the rest are the same by-design deltas; the ornament 950 against the kit's 915. Viewer's verdict: matches (lifted poster with its More circle and Steam's badge, badged legends with "Sort By · Alphabetical", the passive scrubber) | shots/p2_cmp_c2c_home-apps-library-pad.png |
2026-10-07 20:19 | 11094443 |
| R2F-M3 | cmp …-filter.html --mode laser (pre: X, body scrolled to 224) |
sheet and sheet-close PASS (0 / 0); the title row maps the mockup's row against the live text span; the body's box includes its 24 px padding; rows sit 18-23 px lower because Steam's description is longer than the mockup's. Viewer's verdict: matches (pinned title, the compatibility platter with the blue check, the capsules) | shots/p2_cmp_c2c_home-apps-filter.png |
2026-10-07 20:20 | 11094443 |
| R2F-P1 | In-step A/B, js <perfab2.js> (--flags wp.p3,wp.c1a): the theme sheet's text with and without 40-library.css's chunk (restored in a finally, restored: true), rAF-driven scroll of AllGames, 3 rounds × 2.5 s |
median fps 58.7 with C2c's CSS, 56.5 without: C2c's CSS costs nothing measurable | stdout | 2026-10-07 session 3 | 11094443 |
| R2F-P2 | js <perfab4.js>: the library module on (with and without the scrubber) and off, flags pushed in the step, 4 rounds × 3 s |
before the fix: 47.5 (scrubber) / 57.8 / 58.3 (off) | stdout | 2026-10-07 session 3 | 11094443 |
| R2F-P3 | the same after moving the letter's follow to scrollend (no per-frame layout read) |
59.95 / 63.6 / 66.3 | stdout | 2026-10-07 session 3 | 11094443 |
| R2F-P4 | js <perfab6.js> / <perfab7.js>: the scrubber's node hidden, its padding removed, its shadows or layer hints removed, moved to the body |
the node's presence is what remains (hidden: 64.9-66.3; padding, shadows, layer hints: no change; in the body: worse) | stdout | 2026-10-07 session 3 | 11094443 |
| R2F-P5 | perfab6.js after docking the scrubber in a sticky wrapper inside the scroller |
without the module 66.45, module without scrubber 67.1, with the scrubber 62.8: the scrubber costs about 5 % of the synthetic scroll rate, the rest of the module 0 | stdout | 2026-10-07 session 3 | 11094443 |
| R2F-P6 | perf main --route /library/tab/AllGames --ab stock --rounds 1 --flags wp.p3,wp.c1a,wp.c2c --mode laser |
FAIL: stock 85.3 fps, themed 60.3 (0.707), extra long frames 10.5 (A/A spread 1); 8 runs pooled, all native off. C2c's measured share is the scrubber's ~5 %; the rest is outside C2c's files (REQ-13 (3)) | @@perfab line |
2026-10-07 20:22 | 11094443 |
| R2F-T1 | Scrubber: js with __LGS_RT.use('library').scrubTo(letter) (the click path's code) on AllGames, laser; the click path itself with synthetic pointer events (p20.js) |
mounted at x 1186-1266, y 270-610 (80 × 340); 27 letters drawn "# · C · F · I · L · O · R · U · X · Z"; M → scrollTop 8404, the row 28 (index 168, starting "Little Nightmares"; the first "m" title at index 171) at y 270; C → 2704; T → 15304; with Steam's focus in the grid the view no longer drifts after a jump (focus follows with the mouse source; input mode stays laser). Grid after the padding: 6 columns, posters x 44-1164 | stdout | 2026-10-07 19:2x | 11094443 |
| R2F-T2 | Toggle capsules: js <p22.js> (X, pad) |
P2 patch c2c.filterSection: 1 component (kind fn), 10 sections carry lgs-lib-chips, the section's nav layout 5 (grid); body scrollHeight 5,611 → 3,531 |
stdout | 2026-10-07 19:1x | 11094443 |
| R2F-T3 | Capsule D-pad: js <p24.js> (focus given to Play state's first capsule with BTakeFocus; Right, Right, Down, Up, Left, Left, Up, Down; no A) |
spatial D-pad across the capsules: Right / Left along the row, Down / Up between rows, no exit, nothing toggled | stdout | 2026-10-07 20:2x | 11094443 |
| R2F-N1 | native-session --flags wp.p3,wp.c1a,wp.c1c,wp.c2c with sgcheck ×5 (AllGames pad focus, laser dwell, laser dwell with a stale pad focus; Collections laser dwell, pad focus) |
AllGames pad PASS (15 mm lift); Collections laser and pad PASS (tile lifts 15 mm, Q7); both AllGames laser runs FAIL only on R2 main/card dz 2.95 mm, the legacy card rule (M20, P6, REQ-12). The session hit the 590 s wall before the two hv looks, so none were taken; hv --clean run, native off after |
stdout | 2026-10-07 20:5x | 11094443 |
Visual verdicts (looked at each render next to the §7–§9 text):
p2_home-apps_library.png(laser):- the tile menu grows to the right of its source, in the compact layout, with Install as the blue whole fill and Cancel as the quiet capsule;
- the source poster sits flat with its glow, and its More circle is white;
- the ornament keeps its 880 px; Steam's Sort and Filter are in slots 1–2, Options is disabled while the menu is open, and Select and Back show as labels only;
- the scrubber shows "#" (digits) as current, which is right for the first row (11-11 …, 112 …, 12 …, 140, 3dSen, 3dSenVR); revision 2 wrongly showed "A".
- Fixed during review:
- the sub-filter segments were 188 px wide because of content-box sizing, now 140;
- the menu touched the ornament, now 12 px clear;
- the laser dot sat on the label text, now at the row's trailing area.
p2_home-apps_library-pad.png:- exactly one focus look (the "140" poster, lifted, with the More circle and Steam's Verified badge inside it);
- the selected tab and the selected sub-filter segment are white, which is selection, not focus;
- the glyph badges show (gamepad mode);
- no window-bar row (SteamVR hides it without the laser).
p2_home-apps_filter.png:- the first view shows the compatibility pop-up, both option rows, and the first collapsed row peeking under the 56 px scroll-edge fade;
- the window, the tab bar and the ornament recede, with Select and Back lit;
- no outline on any glass.
- Fixed during review:
- the laser pointed at the wrong control;
- the receded Sort and Filter labels floated without a capsule, so they were replaced by the receded capsule;
- section spacing was tightened so a collapsed row peeks.
M0 conformance map (PLAN §1 → the library)
| PLAN | What it changes for C2c | Where |
|---|---|---|
| §1.1 | WN (C1a) owns the window, the toolbar, the ornament contract, the More helper and the frozen target. C1c owns the menu and sheet frames. C2c fills the library slots, registers posters and owns the Filters content | §7, §7.1, §7.2, §8, §9 |
| §1.2 | Library routes are window: 1280 × 656, radius 54, 64 px ornament margin; the CSS-only tint is WN §8.4's |
§7 routes |
| §1.3 | Segments: 64 track, 60 contiguous, ≥ 140 (tabs, sub-filter). Icon buttons 60 / 80 (tab arrows). Text buttons 60, padding 24, 24 Semibold (Reset, Save, toggle capsules). Rows in a platter 80 (Filters). Menu rows per §1.12. Ornament 84, members 60. More circle 60 / 80. Glyph badge 30 / 16 Bold | mockups; §7, §9 |
| §1.4 | Laser looks key on :hover; poster lift, scale and depth only after the 80 ms dwell; attention moves the More circle; selected segment white .94; glyph badges only in gamepad mode; rows and tabs never scale; only posters lift (×1.05) |
§7, §7.1; laser and pad mockups |
| §1.5 | MO tokens only. Tab switch is C1c's 23-transitions.css; menus morph (C1c); the sheet uses sheet-in/sheet-out (C1c). Nothing runs at rest, so Steam's capsule focus pulse, grow and shine sweep must go |
§11 |
| §1.6 | Ornament liquid with an inset slab; menus and sheet thick; the More circle is clear over the art (black .38 + 10 px blur); posters are content; no border, outline or 1 px ring (Steam's capsule outline, the section-header and filter-header rules removed) |
§7, §9; mockups |
| §1.7 | Poster +15 mm non-interactive (the click-safe cap may lower it to +10); menus +10; sheet +10; the source poster 0 while its menu is open (rule 6, REQ-7); at most 4 distinct dz on the route (0, +10, +15, +25 tab bar); lift shadow per P-48 | §10.4; mockups' data-dz |
| §1.8 | Menus: no scrim. Sheet: Steam's overlay restyled to .35, no t1 tint (revision 2 used t1) |
§9, §10.4 |
| §1.9 | Search 520 capsule on section roots (Library tabs), 640 on /library/collection/*; area rules keyed only on html.lgs-hdr-108 / lgs-hdr-40 |
§7 |
| §1.10 | Five fixed slots, 880 px in both modes; A and B quiet trailing in both modes; legend nodes never hidden; the laser-mode Sort/Filter in slot 1; depth 0 with an inset slab | §7.1; both library mockups |
| §1.11 | One More circle per document (C1a's 20-more.js), registered on %{LibraryItemBox}; capture-phase isolation; the host's onMenuButton, fallback vgp_onmenu. Revision 2's one-span-per-poster plus MutationObserver is withdrawn |
§7.2; AT-14a/b |
| §1.12 | Tile menu (6 actions here) → compact 60 / 64, 400 wide, inline label; Sort (10) → two columns, 592; ≤ 5 → 72 rows; Cancel a 56 px quiet capsule; GP §3.4 placement; destructive rule by count; anchoring gated (WN AT-11, GP AT-MENU, SET CQ10) | §8; laser mockup |
| §1.13 | No tooltips (every library control has a visible label except the ‹ › arrows and the More circle, which take P3's tooltip with Steam's own strings, 0.8 s). The scrubber's letter change and the toggle capsules call rt.sound with Steam's ENavSound for the same event (P-74). Haptics off |
§7, §9 |
| §1.15 | Every string is Steam's (tab and sort names, "Options", "Library Filters", options, "Reset", "Save as … Dynamic Collection", "Any language"). Scrubber letters come from the titles. Revision 2's "N More" chip, "Y Reset" legend and "Showing all N games" footer are dropped. No new strings | §7, §9 |
| §1.16 | E-SEG (tabs, sub-filter), E-MENU (menus). No other exemption is needed | AT-7 |
| §1.17 | S2 (interactivePops) off: every library crop is non-interactive. S11 (ornament pop) off: ornament at 0. S14 (More circle on every host) on |
§10.4 |
| §1.18 | P4's DESIGN2 amendments; nothing to apply in C2c files | — |
Decisions taken without the user (PLAN §1.17 rule: safe default, flag, note)
| Id | Decision | Safe default and flag | Why |
|---|---|---|---|
| D-C2c-1 | The source poster drops to 0 mm (with a CSS glow) while its menu is open | Rule 6, enforced by P6's reporter; no flag (REQ-7 asks the coordinator) | Rule 6 and visual order: the menu must be in front of its source |
| D-C2c-2 | The scrubber's column is reserved with padding-inline-end: 72px on %{GridWithControls}, only while the scrubber is mounted |
Flag libScrubber (default on once wp.c2c is on). The module checks Steam's grid after the padding (6 columns, gap ≥ 16) and otherwise unmounts and removes the padding |
Steam's geometry leaves only 44 px right of the posters, and a 60 px control (P-80) does not fit over them without colliding with the More circle of column 6 |
| D-C2c-3 | The scrubber shows in both modes: interactive under the laser, passive in gamepad mode (no focusable; the current letter follows focus) | Under libScrubber |
Grid geometry stays the same across mode flips. Gamepad users gain the position cue LA B.1–B.4 asked for |
| D-C2c-4 | The compatibility filter is a pop-up row in T3, not a segmented control; T1 keeps Steam's four rows as single-choice rows | Under wp.c2c (the T3 re-render) |
CTL §8.3 excludes segmented controls for labels over 16 characters ("Verified, Playable, and Untested") |
| D-C2c-5 | Filter options use the text-button vocabulary as toggle capsules (24 Semibold, 60 visible, 80 hit abutting); Play state shows all five options, with no "N More" chip | Under wp.c2c |
PLAN §1.3 has one text-button spec; dropping the chip removes a new string |
| D-C2c-6 | Reset is the sheet's trailing capsule; Save is at the end of the content; no Y Reset legend | Under wp.c2c |
Steam's dialog has only A Select and B Back legends (library_filter_dialog.png) |
| D-C2c-7 | The poster lift shadow is P4's --lgs-shadow-15mm (0 6px 18px, black .30; P-48 at +15 mm) plus a soft white glow, not D2 §7.8's 0 18px 44px (corrected in session 3: the log said .50, the token is .30; review R2 m5) |
Always | P-48 is a "must" gated by G-DEPTH |
| D-C2c-8 | During modals on library routes: in laser mode the capsule stays and recedes (.35) with A and B lit; in gamepad mode the quiet legend stays in its slots; Options is disabled | C1a's T2 (REQ-4, REQ-5) | The ornament's geometry stays stable and follows C1a's member-based capsule/quiet rule |
| D-C2c-9 | Anchored menus stay 12 px clear of the ornament (bottom ≤ 616) | C1c's anchoring (REQ-6); centred fallback unchanged | Avoids a slab that touches the capsule |
| D-C2c-10 | No frozen-target name suffix in the library's slot 3; the More circle marks the target instead | C1a (REQ-3) | Keeps PLAN-2c-1's 880 px |
| D-C2c-11 | Steam's uppercase chrome (tab labels, section headers, collection labels, sub-filter, legends) is shown in Steam's own case with no tracking (text-transform: none, letter-spacing: 0) |
Always, T1 | P-84 |
| D-C2c-12 | Steam's laser Sort & Filter pill is the toolbar row's trailing group (top right, 60 px capsule, 80 hits), and the ornament hugs Steam's legends in Steam's order. Slot 1 still carries the sort ("Sort By · Alphabetical") in gamepad mode | Flag libFixedSlots (off) brings back PLAN §1.10's fixed 880 px slots |
The window clip cuts the pill in the ornament (it was half visible and unclickable), and fixed slots show empty space whenever Steam drops X / Y / ≡ (REQ-8) |
| D-C2c-13 | Gamepad focus keeps Steam's own focus transform (x1.053 measured: 181.1 / 172; the log said "about x1.07" until session 3, review R2 m5); C2c's x1.05 scale applies only to the laser's dwell. The scroll guard counts its growth (8 px, --lgs-lib-lift-room) |
Always | Two scales stacked to x1.105, beyond PLAN §1.4's x1.05 |
| D-C2c-14 | The tab row is tagged E-SEG by T2 (data-lgs-exempt); with 22 px labels its six tabs need about 1,140 px against 1,048, so it keeps Steam's horizontal scroll and arrows |
wp.c2c |
E-SEG is the card's own exemption for these segments; a partly visible segment at the scroller's edge is otherwise judged by the 80 × 80 box |
| D-C2c-15 | Steam's 20 px collection count (a focusable tooltip source) is spread over the whole tile, with its text kept under the name, so every point of the tile takes the laser. Empty collections dim only their face, not the label | Always (T1) | P-08 / P-80 failed on the count in stock Steam too; dimming the whole tile dropped the label below 4.5 : 1 |
| D-C2c-16 | Gamepad focus on a segment (tabs, VR sub-filter) is the tvOS look: the focused segment is opaque white with a dark label and the white glow at spread 14 / alpha .70; while focus is inside the sub-filter its selected-unfocused segment recedes to the navigation-selected look (white .18 + arc). Laser hover is unchanged (+ .08 and the spot) | Always (T1) | PLAN §1.4's additive focus cannot beat a white .94 selection (P-15), and the old look showed focus on a selected segment only as a faint halo (review R2 Q6). REQ-13 (1) asks the coordinator to confirm the one-view reading of P-15 |
| D-C2c-17 | Library Filters as built: a 960-wide sheet with a pinned title row (Q2), a scrolling body with edge fades, 80 px compatibility rows in one platter, sections as platters; with libFilterChips (T3, default on) a P2 props patch gives each section flow-children: grid and the class lgs-lib-chips, and CSS draws its options as wrapping toggle capsules (≥ 168 wide, so G-AUD's SHRUNK holds). The gamepad's default row is scrolled into view on open (Q3). HA §9's pop-up row and collapsed sections are not built (REQ-13 (2)) |
libFilterChips (on with wp.c2c; off or no P2: the T1 rows) |
Every Steam node, handler and string stays; the D-pad follows what is drawn (D2 §12); 5,809 px of scroll became about 3,530 |
| D-C2c-18 | The letter scrubber is docked in a zero-height sticky wrapper appended to Steam's grid scroller (not a fixed node over it); its current letter updates on scrollend, never per scroll frame; a pick moves Steam's focus to the letter's first poster with the mouse source when Steam had a focus in the grid; 27 letters are drawn every third with dots |
libScrubber (on with wp.c2c) |
G-PERF: a per-frame layout read cost 13 % of the scroll rate and a fixed node over the scroller about 5 % (R2F-P3, R2F-P4); without the refocus, Steam re-focused a poster after the jump and scrolled 24 rows away |
| D-C2c-19 | The Y legend ("Sort By · ", thin spaces round the dot) is at most 334 px and its label is a single line box, so the sort name ellipsizes with "…" and the regular capsule stays ≤ 960 (957 with "Alphabetical") | Always (T1 + T2) | Q1; C1a's compact switch measures before C2c's attribute lands (REQ-15 (7)) |
New strings (PLAN §1.15)
None. Every text C2c draws or restyles is Steam's own (found by source text at M3 with GP's game-pages-locgrep.sh method where T2/T3 draws it: the sort names in slot 1's state span, "Options", and the filter dialog's labels in the T3 re-render). Scrubber letters are data.
Proposed text for home-apps.md (for C2a: REQ-1)
Each block replaces the named part of docs/phase2/concepts/home-apps.md. Section numbers are HA's.
HA §0.1, the three library rows
| Mockup | Render | Shows |
|---|---|---|
home-apps-library.html |
p2_home-apps_library.png |
Library, laser mode (owner C2c). Steam's tile menu grows from the white More circle of its source poster: compact layout, +10 mm. The source is flat with its glow. The laser-mode ornament: Steam's Sort and Filter in slots 1–2, the shell's Options member disabled while the menu is open, Select and Back as labels only. The letter scrubber |
home-apps-library-pad.html |
p2_home-apps_library-pad.png |
Library, gamepad mode (owner C2c). The focused poster is lifted (+15 mm) with the More circle and Steam's compatibility badge. Steam's legends sit in the same five slots with glyph badges. The scrubber is a passive position cue |
home-apps-filter.html |
p2_home-apps_filter.png |
Library Filters in C1c's sheet frame (owner C2c): Steam's real options as a compatibility pop-up, toggle capsules and collapsed sections. The ornament recedes, with Select and Back lit |
HA §1.2, item 6
- Browsing stays a window. All Games (or the Library tab) opens window-nav's glass window. It holds:
- posters;
- a More circle on the poster you look at or focus, the laser's direct path to a game's menu;
- a letter scrubber;
- one bottom ornament of five fixed slots that shows the current sort in both input modes.
HA §1.3, the "Library Filters" row
| Library Filters | Worst screen | 47 rows of 0.86°, 0.49° checkboxes, 3.8 window heights of scroll (LA B.1) | A sheet with a compatibility pop-up, toggle capsules and collapsed sections: about 1,280 px of content (3.3 sheet heights) against Steam's 2,742 px (§9) |
HA §7 Library catalogue (replaces §7, §7.1 and §7.2)
Owner: C2c (PLAN §2.4).
Routes. /library/tab/<id> and /library/collection/<id> (Steam's) are glass mode window (PLAN §1.2), in window-nav's window:
- glass 1280 × 656, radius 54;
- toolbar row 108 (
html.lgs-hdr-108; underlgs-hdr-40WN §3.2's fallback rules move every row below); - bottom ornament 628–712 (WN §3.1–§3.4).
CSS-only look: WN §8.4's tint. Area rules key only on C1a's classes and variables (lgs-hdr-*, --lgs-guard-top / --lgs-guard-bottom, data-lgs-glass).
| Element | px [pt] | Material / fill | Tier |
|---|---|---|---|
| Toolbar row | window-nav's. Back circle: borderless on the library tabs (section roots), white .10 on /library/collection/<id>. Large Title "Library" at x 100 on section roots. Search 520 × 64 on section roots, 640 × 64 on collection pages (PLAN §1.9) |
WN | C1a |
| Tabs | Steam's tab row as a segmented control (CTL §8.3, E-SEG). Track 64 [48] at y 116, padding 2. Segments contiguous (hit boxes abut), 60 tall, ≥ 140 wide; the visible fill is inset 2 px. Labels 22 px Semibold in Steam's text without its uppercase and tracking; counts Medium white .70 (dark .55 on the white segment). States: selected white .94 with a dark label; gamepad focus + white .28, a spot of .16 and the arc (on the selected segment: the outer glow, P-16); laser hover + .08 and the light spot. Steam's horizontal scroller keeps its 28 px edge fades. Steam's ‹ › arrows: 60 px plain circles at x 24 and 1196, y 118, 80 hit | Recessed track on glass | T1 (the row keeps its horizontal handlers, D2 §12) |
| VR sub-filter | Steam's %{VRSubTabFilterContainer} in its stock position, centred under the tabs at y 192: the same segmented control, 3 × 140 = 424 wide. Labels "All · VR · Non-VR"; Ready To Play: "All · Standalone · Remote PC" |
Recessed track on glass | T1. Not moved: its nav position sits between the tabs and the grid |
| Grid | Steam's geometry: 172 × 258 posters, 6 per row, row pitch 300 (gap 42), radius 20, first row at y 270. Steam spreads the columns across its scroller (pitch 204 today). While the scrubber is mounted (T3 class on the grid), T1 adds padding-inline-end: 72px to %{GridWithControls}. Steam's grid then keeps 6 columns at a 189.7 px pitch (x 44–1164), and x 1196–1256 is free for the scrubber. Optional T3: 200 × 300, 5 columns (LQ2) |
Content | T1 (styles only, D2 §12; the padding only with the scrubber) |
| Scroll guard | Steam's grid scroller gets a scroll-padding-top that keeps a focused poster below the pinned tab and sub-filter rows (y ≥ 270 with CQ1), and a scroll-padding-bottom that keeps it above --lgs-guard-bottom (612) (VP P-23) |
— | T1 |
The attention target (gamepad focus; laser after 80 ms of dwell, .lgs-dwell:hover) |
Lift: scale: 1.05 (the independent property; Steam's transform is untouched); shadow 0 6px 18px black .50 (P-48 for +15 mm); white glow 30 px .16; the diagonal sheen (P4's --lgs-ill: card). Timing: under the laser, brightness changes at once; scale, shadow and depth start after the dwell (P-06). Removed: Steam's 2 px outline, its focus pulse (1.2 s × 20) and its shine sweep (P-42, P-52). Badge: Steam's compatibility badge, which Steam shows on hover and focus only, becomes a 36 px circle at the bottom right, inset 10. No caption: Steam shows none, and its 42 px row gap cannot hold one |
Content; native: a +15 mm non-interactive crop over the window cover | T1 + T4 |
| The source of an open menu | Flat (0 mm) while its menu is open (PLAN §1.7 rule 6). It is marked by a CSS glow 0 0 26px 2px white .18 and by its white More circle |
Content | T1 + T4 |
| More circle | The shell's one-per-document helper (PLAN §1.11, WN §3.4.4). C2c registers posters: __LGS_RT.more.register('%{LibraryItemBox}', {placement: 'card'}). Size: 60 [45] visible, 80 hit, inside the poster's top right (inset 10). Look: black .38 with a 10 px blur, white .94 while its menu is open. It follows the attention target, so it shows on gamepad focus and after the laser's dwell (parity, P-89), and it rides the poster's crop (no pop of its own) |
Clear over the art | T2 (C1a's helper) |
| Letter scrubber | A 60 × 340 [45 × 255] recessed capsule (black .14) at x 1196, y 270–610. Letters 20 px Semibold white .70, condensed with 6 px dots; they are the first characters of the titles in the current sort (digits as "#"), so no string is added. The current letter sits in a 40 px white circle; hit 80 wide. Laser: a click or drag maps y to a letter and sets the grid scroller's scrollTop to that letter's first row (a wheel-equivalent; Steam's virtualizer renders the rows). Gamepad: passive (no focusable), the current letter follows the focused poster, and Steam's fast-scroll stays the pad path. Shown only for Alphabetical. A letter change plays Steam's own scroll sound through rt.sound (P-74) |
Fill on glass | T3 behind libScrubber (default on with wp.c2c). It unmounts, and the padding goes, if Steam's grid does not keep 6 columns with gaps ≥ 16 |
| Bottom ornament | §7.1 | liquid (inset slab), depth 0 |
T1 + T2 |
| "N apps hidden" notice | Steam's %{AppGridFilterHeader} with Steam's own text, as a 60 px quiet capsule (white .08, Callout 22 Medium white .70) above the grid. The button variant (…AsButton, clears the filter) is a 60 px text button (24 Semibold) with an 80 hit. Steam's two 1 px rules go (P-43) |
Fill | T1 |
| Section headers (non-alphabetical sorts) | Steam's %{AppGridSectionHeader}: Title 3 28 px Semibold, Steam's text without its uppercase and tracking. Its 1 px rule goes; its sticky background becomes the toolbar's scroll-edge band |
— | T1 |
| Missing art | Steam's title card restyled: a gradient tile with the title 22 px Bold | Content | T1 |
| Collections tab | Steam's collection tiles, radius 30. Label 20 px Semibold without uppercase or tracking; the count Medium white .70. Empty collections are tagged by T2 from Steam's collection data (data-lgs-empty) and dimmed to .62 by T1. Steam's 3D display case and order are kept |
Content / fills | T1 + T2 |
7.1 The ornament in each input mode
Steam renders different controls per mode (INV-L §1.3, §6.1):
- Laser mode (
data-lgs-vr-mode="laser"): the%{SortAndFilterContainer}pill (Sort with the current sort, Filter), plus the legend's Select and Back. - Gamepad mode: the legend shows X Filter, Y Sort By, ≡ Options (only while a poster is focused), A Select and B Back.
Five fixed slots (PLAN §1.10, inside WN's contract):
- widths 300 · 130 · 156 · 134 · 120 px, gap 4, padding 12, so 880 px in both modes, centred at x 200–1080;
- members 60 tall at y 640–700;
- each slot's hit box takes its 2 px share of the gaps, so neighbours abut (P-07);
- the capsule's backing is the fixed slot rect, not the measured union of members, so its width never changes when Steam switches modes or drops a legend (C1a's API, REQ-5);
- A and B are quiet trailing members in both modes;
- glyph badges show only in gamepad mode (P-26).
| Slot | Laser mode (p2_home-apps_library.png) |
Gamepad mode (p2_home-apps_library-pad.png) |
|---|---|---|
| 1 Sort (300) | Steam's %{SortAndFilterButton} (sort), moved by T1 into slot 1 (WN §3.4.2): sort glyph and the current sort ("Alphabetical") |
Steam's legend "Sort By", then C2c's T2 state span " · Alphabetical", then the Y badge. The span uses Steam's sort name from AppGridDisplaySettings and ellipsizes inside the slot; the longest name is "% of Achievements" |
| 2 Filter (130) | Steam's Filter button: filter glyph and Steam's "Filter" ("Filter: [icons]" when active) | Steam's legend "Filter" and the X badge. When advanced filters are active, C2c's T2 adds a count badge (a number) |
| 3 Options (156) | The shell's T2 Options member (C1a, WN §3.4.2): ⋯ glyph and "Options" (Steam's legend string). It acts on the frozen target (WN §3.4.3) with the More circle's dispatch, and is disabled (.38) without a target. There is no name suffix in this fixed slot: the More circle stays on the frozen target while the pointer is in the ornament, so the target is shown on its own poster | Steam's legend "Options" and the ≡ badge while a poster is focused. When none is (focus on the tab row), the shell's Options member shows disabled in its place, so the slot never empties |
| 4 Select (134) | Steam's legend "Select", quiet, label only | Steam's legend "Select" and the A badge, quiet |
| 5 Back (120) | Steam's legend "Back", quiet, label only | Steam's legend "Back" and the B badge, quiet |
- While a modal is open (Sort or tile menu, the Filters sheet, an alert):
- In laser mode, Steam's pill stays a member, so the ornament stays the 880 capsule. During alerts and sheets it recedes with the window: a black .35 layer, as on the tab bar (WN §3.3.4). Steam's A and B legends, which now act on the modal, stay lit above it (
p2_home-apps_filter.png). The Options member is disabled during any modal. - In gamepad mode, Steam's footer holds only A and B, so the ornament is the quiet legend (PLAN §1.10), its items keeping their slot 4–5 places.
- In laser mode, Steam's pill stays a member, so the ornament stays the 880 capsule. During alerts and sheets it recedes with the window: a black .35 layer, as on the tab bar (WN §3.3.4). Steam's A and B legends, which now act on the modal, stay lit above it (
- Source of an open menu: slot 1 (Sort) or slot 3 (Options) turns white .94 while its menu shows (WN §3.4.2).
- Input mode: read only through P3's accessor (
__LGS_RT.input,data-lgs-vr-mode). Tests stub it withrt.input.stub(P10's--mode), never through Steam's getter (AT-14d).
7.2 The More circle on posters
The circle is the shell's helper (PLAN §1.11, WN §3.4.4). C2c only registers posters and owns the poster's lift and depth.
- Node. One decorative node per document. It is moved to the current attention target (gamepad focus, or the laser's dwell) and sits inside its
%{LibraryItemBox}at the top right, inset 10. It is not focusable, so the gamepad keeps ≡. - Click. A capture-phase listener stops
pointerdown,mousedown,mouseupandclick, so the poster never opens. The helper then calls the poster's ownonMenuButtonfrom itsFocusablefiber props, falling back to Steam'svgp_onmenu(button 14) on the%{LibraryItemBox}(INV-L §0.3) [dispatch PROVEN]. - Recycling. Nothing is attached per poster, so the virtualized grid's recycling cannot duplicate the circle. If the target's node is recycled for another app, the helper hides until the next attention event (AT-14b).
- Fallback: the ornament's slot 3.
HA §8 Menus: Sort and the tile menu (replaces §8)
Owner: C2c for the library's content; the frames are C1c's (WN §5.1, PLAN §1.12).
Both are Steam's context menus (BasicUIContextMenu, INV-L §6.2, §7). Anchoring (T2 translate) is gated on WN AT-11, GP AT-MENU and SET CQ10: a click outside must still dismiss, and the D-pad must be unchanged. Until those pass, the menus stay centred and still morph from their source.
| Sort | Tile menu | |
|---|---|---|
| Items | 10 actionable sorts, plus Cancel | Install or Play (primary), Add to Favorites, Add to ›, Manage ›, Developer › (developer mode only), Properties..., plus Cancel. That is 6 actions on this device, 5 without developer mode |
| Layout (PLAN §1.12) | ≥ 8: two columns, column-major in Steam's order, rows 72 px 6 apart, a 40 px header row, 592 wide, about 508 tall | 6–7: compact, 60 px visible on a contiguous 64 px pitch, the game's name as an inline label (19 px Semibold), 400 wide, about 506 tall (p2_home-apps_library.png). ≤ 5: one column of 72 px rows with a 40 px header |
| Content | Steam's 10 sorts in Steam's groups; the current sort carries a white check (Steam's .menuChecked) |
The primary row takes its semantic whole fill (Play green; Install and Update blue; Stop red). Submenus open beside the menu (8 px gap) and choose their own layout. Destructive rows follow the count rule (red label for ≤ 2, red glyph for more; red fill on focus); Steam's order and default focus are unchanged |
| Cancel | Steam's row as a 56 px quiet capsule, centred under the rows (HA-11) | Same |
| Source and placement (T2) | Slot 1 (laser: Steam's Sort button; gamepad: the Y legend), white while open. The slab grows upward from the ornament with its bottom ≥ 12 px above it (y ≤ 616), clamped to the modal box | The More circle (white while open), the focused poster (≡), or slot 3. GP §3.4's order for sources in a page row: above; else right, 16 px from the poster; else left; else centred. Vertically centred on the poster and clamped to y 108–616 |
| Depth (PLAN §1.7) | +10 mm, non-interactive, appearing with the materialize (0 → +10 on depth); wearer profile +30 |
Same. The source poster goes to 0 while its menu is open (rule 6) |
| Motion | morph-open 607 ms from the source's rect (clip-path, ≤ 600 × 600); morph-close 441 ms (glassd); no scrim |
Same |
HA §9 Library Filters (replaces §9)
Owner: C2c for the content; the sheet frame is C1c's (WN §5.4, PLAN §1.12).
Frame:
- ≤ 960 wide inside the 108–628 modal box (960 × 488 at (160, 128) in the mockup), radius 44,
thick; - a 60 px close circle at (24, 24), and Title 2 "Library Filters" (Steam's string) centred;
- the scrim is Steam's overlay restyled to black .35 (PLAN §1.8);
- depth +10 mm, non-interactive (+30 → +50 in the wearer profile);
- the ornament shows Steam's footer for the dialog, Select and Back (§7.1, "While a modal is open"). Steam has no Reset legend.
Content (T3: C2c's re-render of Steam's filter dialog, bound to Steam's own filter setters; every string is Steam's):
| Element | px [pt] | Notes |
|---|---|---|
| Reset | A 60 px text capsule at the sheet's trailing 24 px inset (WN §5.4 trailing action) | Steam's Reset handler |
| Compatibility | A grouped row (80, platter black .14, radius 30). "Steam Frame Compatibility" (Body 24 Medium) on the left; on the right a pop-up button (CTL §8.1: a 60 px capsule, value 22 Medium, Steam's caret) showing Steam's four compatibility icons for the chosen level and its name ("All Games") | Its value menu holds Steam's 4 options with their icons, the current one checked (CTL §8.2): ≤ 5 options, so one column of 72 px rows, anchored below or above the button. Not a segmented control: CTL §8.3 rules them out for labels over 16 characters ("Verified, Playable, and Untested" has 31) |
| Players, Play state | A section label 22 px Semibold white .70 (CTL §10). Below it, the options as toggle capsules: text buttons (PLAN §1.3), 60 visible, padding 24, 24 px Semibold, 12 px apart, with 80 px hit boxes that abut across the gaps (P-08). On = white .94, a dark label and a leading check. One row each: Players (4 options) and Play state (5, "Private" included, so there is no "N More" chip) | Steam's options |
| Collapsed sections | A platter of 80 px rows with 2 px separators (CTL §10): Hardware support, Features, Language, Genre, Store tags, Friends, Gameplay, Visual, Camera Comfort, Audio, Input. Each row shows its current value at the trailing edge, then a chevron. The value is Steam's names of the chosen options, or the dropdown's value ("Any language"), or nothing when none is chosen. A or a click expands the section in place: | Steam's sections and order |
| • its options as toggle capsules, wrapping if needed; | ||
| • its dropdown as a pop-up row: Gamepad Support has 5 options (one column), Language about 29 (CTL C-D19's scrolling column); | ||
| • Store tags and Friends as 64 px text fields (CTL §9; the keyboard opens on activation only). | ||
| Save as Dynamic Collection | Steam's "Save as ⚡ Dynamic Collection" as a 60 px capsule at the end of the content | Steam's handler |
| Scroll | About 1,280 px of content in a 384 px viewport (3.3 sheet heights), against Steam's 2,742 px dialog (5.3 heights of its 520 px box). The 56 px scroll-edge fade sits at the sheet's bottom edge | — |
T1 fallback (the type swap fails): Steam's dialog in C1c's sheet frame, restyled.
- The 4 compatibility radio rows become single-choice rows of 80 px in a platter, with a trailing blue check and Steam's icons.
- Each FilterBucket becomes a platter with its section header.
- Checkbox rows become 80 px rows with a trailing 40 px check circle (CTL §6.2, E-CHECK).
- Dropdowns become pop-up rows, and fields are 64 px.
- Reset and Save become 60 px capsules at the end, in Steam's order.
The scroll is longer; nothing is lost.
HA §10.4, the library rows (replace the library and menu/sheet rows)
| Element | mm | Scene units (r = 1) | Paired cue | Mechanism |
|---|---|---|---|---|
| Library window, ornament | 0 | 0 | — | window-nav (cover; ornament inset slab, WN D-7) |
| Library attention-target poster (and its More circle) | +15 (the reporter's click-safe cap may lower it to +10) | 0.041 | 0 6px 18px /.50 (P-48) |
Non-interactive crop over the window cover; interactive only in the wearer profile |
| Source poster while its menu is open | 0 | 0 | CSS glow | PLAN §1.7 rule 6 |
| Sort and tile menus | +10 (wearer +30) | 0.027 (0.081) | Slab shadow 4 / 12 px | Non-interactive crop + thick slab |
| Filters sheet | +10 (wearer +30 → +50) | 0.027 (0.081 → 0.136) | Scrim .35 (Steam's overlay, PLAN §1.8; no t1 tint) |
Non-interactive crop + thick slab |
HA §11, the library rows (replace "Menus", "Filter sheet", "Library tab switch"; add the rest)
| Interaction | Token(s) | Notes |
|---|---|---|
| Library tab switch | C1c's 23-transitions.css: ±16 px + fade on page, replacing Steam's ±40 % slide |
Timing only |
| Poster lift | In hover-in 294 ms, out fade 441 ms; laser after 80 ms of dwell; depth on depth (P7) |
Rows and tabs never scale |
| More circle | P5's lgs-mat-*: materialize 250 ms, dematerialize 350 ms |
— |
| Scrubber | Current letter on snappy; appears with the materialize |
— |
| Menus | morph-open 607 / morph-close 441 (C1c) |
— |
| Filters sheet | sheet-in 735 / sheet-out 514; scrim on fade (C1c) |
— |
HA §12.2 Library tabs and grid (LA A.2), replacement
| # | Function | New place | Laser | Gamepad |
|---|---|---|---|---|
| L1 | Switch tab (All Games, Great On Frame, Ready To Play, Collections, Non-Steam, Soundtracks, conditional tabs) | Steam's tab row as a segmented control; the same sets as the Home › Collections folders | Click a segment or a ‹ › circle | LB / RB; or Up to the row + Left/Right |
| L2 | VR sub-filter All / VR / Non-VR (Ready To Play: All / Standalone / Remote PC) | Steam's control in its stock position, as a 64 px segmented control [T1] | Click a segment | Up from the grid + Left/Right + A (stock) |
| L3 | Browse the grid | Steam's virtualized grid, restyled; the attention target lifts | Wheel/drag scroll; an 80 ms dwell lifts | D-pad; Steam scrolls focus into view (guard 124–612) |
| L4 | Fast scroll by letter | Steam's fast-scroll overlay (unchanged) + the letter scrubber [T3] | Click/drag the scrubber (new) | Steam's fast-scroll; the scrubber shows the position (passive) |
| L5 | Open a game | Poster activation | Click | A |
| L6 | Sort (10 options, persisted) | Ornament slot 1, the current sort shown in both modes → Steam's Sort menu as the two-column grid, the current sort checked | Click slot 1 (Steam's laser-mode Sort button) | Y |
| L7 | Filter | Ornament slot 2 → the Library Filters sheet (§9) | Click slot 2 (Steam's laser-mode Filter button) | X |
| L8 | Tile menu | The More circle on the attention target [T2, C1a's helper]; ornament slot 3 Options [T2, C1a] | Click the More circle (new direct path) or slot 3 (frozen target) | ≡ |
| L9 | "N apps hidden due to filter" (the button variant clears) | Steam's notice as a 60 px capsule above the grid | Click | Focus + A |
| L10 | Back | Toolbar Back circle (WN) | Click | B |
HA §12.3, rows T1 and T7 (replacement; T2–T6 and T8 unchanged)
| # | Function | New place | Laser | Gamepad |
|---|---|---|---|---|
| T1 | Primary action Play / Install / Launch / Download / Update | First menu row with its semantic whole fill (compact or one-column layout by count); the Home card's Play capsule; search X (S-C) | Click | ≡ → A; X on a Home cell or a search item |
| T7 | Cancel | A 56 px quiet capsule under the rows; click outside (Steam's dismiss) | Click | B |
HA §12.4 Library Filters (LA A.4), replacement
| # | Function | New place | Laser | Gamepad |
|---|---|---|---|---|
| F1 | Frame compatibility level (4, persisted) | A pop-up row at the top of the sheet → its 4-option value menu [T3]; single-choice rows of 80 px [T1] | Click the pop-up, then an option [T3]; click a row [T1] | A, then D-pad + A [T3]; Up/Down + A [T1] |
| F2 | 47 checkboxes in 11 sections + the Gamepad Support and Language dropdowns | Players and Play state as toggle capsules; the other sections as collapsed rows that expand in place into capsules and pop-up rows [T3]; Steam's rows at 80 px with check circles and pop-up rows [T1] | Click | D-pad + A |
| F3 | Store tags / Friends text search | 64 px fields inside their expanded rows | Click → keyboard | Focus + A → keyboard |
| F4 | Reset | The sheet's trailing capsule [T3]; Steam's button at the end [T1] | Click | D-pad Up to the header + A [T3]; D-pad + A [T1] |
| F5 | Save as Dynamic Collection | A 60 px capsule at the end of the content | Click | D-pad + A |
| F6 | Close | The sheet's close circle (C1c) | Click | B |
HA §12.5, row C1 (replacement; the other rows unchanged)
| # | Function | New place | Laser | Gamepad |
|---|---|---|---|---|
| C1 | Browse collections | Home › Collections folders (empties grouped); the Library Collections tab (rounded tiles, empties dimmed through a T2 tag) | Click | D-pad + A |
HA §12.9, row SN-F1 (replacement)
| # | Function | New place | Laser | Gamepad |
|---|---|---|---|---|
| SN-F1 | Footer legend actions (X Filter, Y Sort By, ≡ Options, A Select, B Back) | window-nav's bottom ornament; library routes: the five fixed slots per input mode (§7.1) | Click the slot: Steam's laser-mode Sort and Filter, the shell's Options member, Steam's Select and Back legends | The physical button |
The count stays 59 functions, all mapped, none dropped.
HA §13, the library rows (replace "Library ornament slots", "More circle in posters", "Letter scrubber", "Anchored menus", "Filter sheet with chips")
| Element | Tier | Evidence | Status | Fallback |
|---|---|---|---|---|
| Library ornament slots | T1 + T2 | WN §3.4 (ornament from #Footer); the laser pill is laser-only, so moving it cannot change D-pad order (INV-L §6.1); fixed backing through C1a's API |
PLAUSIBLE | Steam's pill and legend restyled in place, in the capsule material (WN's no-T2 fallback) |
| More circle on posters | T2 (C1a's helper) | The host's onMenuButton (SM-D15); the vgp_onmenu dispatch opens the capsule menu (INV-L §0.3) |
Dispatch PROVEN; capture-phase isolation PLAUSIBLE | Ornament slot 3 |
| Letter scrubber | T3 + a T1 padding | scrollTop on Steam's grid scroller (a wheel-equivalent); the 6-column check after the padding |
PLAUSIBLE | Steam's fast-scroll; wheel and drag |
| Anchored menus | T2 | WN AT-11, GP AT-MENU, SET CQ10 | UNPROVEN | Centred menus that still morph from the source |
| Filters content | T3 | Type swap of Steam's filter dialog component (SR §3.4 technique) | PLAUSIBLE | T1 restyle of Steam's dialog (§9) |
HA §14, acceptance tests (the library parts)
General rules as HA §14. In addition:
- Filter state: filters and sorts are persisted (
AppGridDisplaySettings,collectionsAppFilterVR, the compatibility level). Tests never select a sort, a filter option, Reset or Save. Activation goes through P2's action logger or a spy on Steam's setter, which logs{fn, arg}and does not run (never-list). - Input mode: switched only with P10's
--mode laser|pad(P3'srt.input.stub).
| ID | What | How | Pass |
|---|---|---|---|
| AT-6 (library part, C2c) | No functional loss | glass.py audit main --route /library/tab/AllGames with --mode laser and --mode pad; the same on /library/tab/Collections, /library/tab/DesktopApps and /library/collection/<VR id>; and on AllGames with --pre the Sort snippet, the capsule-menu snippet (vgp_onmenu) and the Filter snippet (INV-L §0.3), each in both modes, with wp.c2c off and on |
0 GONE / HIDDEN / SHRUNK / UNCLICKABLE / CONTRAST, apart from §1.16's E-SEG and E-MENU. No legend node has display: none. The laser-mode glyph collapse is not counted (WN §3.4.2) |
| AT-7 (library part, C2c) | Sizes, type, outlines | glass.py gates main --route /library/tab/AllGames in both modes, bare and with each of the three --pre snippets |
G-SIZE: every focusable ≥ 80 × 80 or its exemption (segments: E-SEG, ≥ 60 × 140 and contiguous; menu rows: E-MENU). The More circle is 60 visible with an 80 hit, fully inside its poster (WN AT-26). The scrubber is 60 visible with an 80 hit. Ornament members are 60 tall with abutting hit boxes. Toggle capsules are 60 visible with an 80 hit. Filter rows are 80. G-TYPE: no text under 18 px, no weight under 500, no uppercase, tracking > .01 em or italics in chrome (tab labels, the sub-filter, section headers, collection labels, legends). G-OUTLINE: no outline or 1 px ring on posters, tabs, the ornament, menus or the sheet |
| AT-14 | Library | (a) More circle: under --mode laser, L.click on the More circle over a poster. (b) Recycling: scroll the grid 2,000 px and back (scrollTop, a wheel-equivalent). (c) Scrubber: under --mode laser, click "M"; under --mode pad, 5 × L.pad Down. (d) Both modes: --mode laser, then --mode pad, on /library/tab/AllGames: shot and audit each; click every slot through the action logger and spies (Sort and Filter open Steam's menu or dialog, which is then closed with B; Options logs its dispatch; A and B log Steam's legend dispatch). (e) Depth (M4, in glass.py native-session): glass.py sgcheck with a poster focused (pad) and dwelt (laser), then with the tile menu open, then with the Filters sheet open. (f) Sort label: open the Sort menu (look only) |
(a) The route is unchanged; the menu's labels equal those ≡ opens on the same poster; the log shows the host's onMenuButton (or the vgp_onmenu fallback); the menu is closed with B, never by an item. (b) At most one More node in the document; it is hidden or inside the current target's %{LibraryItemBox} (same appid), never on another poster. (c) Laser: the first fully visible poster's title starts with the first letter ≥ "M" that exists. Pad: the scrubber has no focusable, and its current letter equals the focused poster title's first letter. (d) The ornament is 880 ± 1 px wide in both modes (PLAN-2c-1); all 5 slots are present; every slot's click is handled. (e) One pop at +15 mm (0.041 ± 0.005 u at r = 1; +10 if the click-safe cap applies) with interactive: false. With the menu open: the menu at 0.027 u and the source poster not popped (rule 6). With the sheet open: the sheet at 0.027 u and nothing else. ≤ 4 distinct dz on the route. Each lift's shadow within P-48. (f) The checked row equals slot 1's label in both modes |
| AT-15 | Filters | (a) The Filter snippet in both modes, then L.pad through every control of the sheet, T3 and T1. (b) glass.py audit main --pre <Filter snippet> in both modes, T3 and T1. (c) The sheet's crop (M4). (d) Spies: activate each toggle capsule, pop-up option, Reset and Save through the action logger. (e) Rect scan of the sheet |
(a) Every control is reachable; Down-Up returns; B closes the sheet and focus returns to its source (slot 2, P-21). (b) 0 GONE / HIDDEN / SHRUNK / UNCLICKABLE / CONTRAST; in T3 every Steam filter control has a twin bound to the same setter: the compatibility level, the 47 options, 2 dropdowns, 2 text fields, Reset, Save. (c) The sheet at +10 mm (0.027 u), interactive: false, and no other pop. (d) Every call equals Steam's own row's setter and arguments (identity check), logged, not run. (e) The sheet is ≤ 960 wide inside 108–628; the close circle is at (24, 24) of the card; toggle capsules are 60 visible with 80 hits; rows are 80; text ≥ 18 px; the T3 content is ≤ 1,400 px tall |
The card's own tests also stay: PLAN-2c-1 (ornament 880 ± 1 in both modes), PLAN-2c-2 (glass.py cmp against home-apps-library.html, -library-pad.html and -filter.html, with docs/phase2/wp/C2c-cmp.json), and G-PAD on AllGames, including Up to the sub-filter and the tab row and back.
HA §15, row 12 (replacement)
| 12 | window-nav's laser-mode ornament dropped the A/B legends that Steam renders in laser mode | Resolved by PLAN §1.10: A and B are never hidden; the library keeps them in slots 4–5 in both modes |
HA §16, row 4 (replacement)
| window-nav | Library routes: the five fixed slots per input mode (§7.1) inside WN's ornament contract; the More circle is WN's helper registered on posters (§7.2); the Filters content inside WN's sheet frame (§9) | §7.1, §7.2, §9; WN §3.4.6 |
Log
2026-10-07, session 1: M0 conformance
- Start-of-session request check: none (see "Requests to C2c, handled").
- Read: PLAN §0, §1, §2.1, §2.3, §2.4, §2.6, §4, §7; HA (all); XC; WN §3–§5 (the revision-3 text C1a is writing); CTL §4, §5, §8, §10; VP §6; D2 §6.7, §7.8, §10.4, §12; INV-L §1.3, §1.4, §3, §4, §6, §7; LA A.2–A.5. Contracts:
interaction.md(P3),tokens.md(P4),reporter.md(P6),lab.md(P10). Logs: C1a (ornament, More and frozen-target interface), C1c. - Reference shots looked at:
library_tab_allgames.png(Steam's grid geometry: 172 × 258 at a 204 px column pitch, x 44–1236, rows at a 300 pitch),library_capsule_menu.png(tile menu items; footer Select and Back with a menu open),library_filter_dialog*.png(real options; footer Select and Back only). - Rebuilt
home-apps-library.html,home-apps-library-pad.htmlandhome-apps-filter.html: library styles inline (lc-prefix), real data fromdocs/refs/library/(unchanged;fetch-library-refs.pynot re-run, since nothing new was needed), anddata-ids for G-MOCK. - Re-rendered
shots/p2_home-apps_library.png,_library-pad.pngand_filter.png. These are the renders of C2c's own mockups, re-rendered as M0 requires; the PLAN §2.6 freeze of earliershots/p2_*covers inputs, not an owner's own re-renders. - No device steps (M0 is documents and mockups only); the device was not touched.
- End-of-session request check: none.
2026-10-07, session 2: M2 (T1), M3 (T2), the T4 fragment, verification
- Start-of-session request check: three requests to C2c (C1a, C1c, C2a), all handled (see "Requests to C2c, handled").
- Read: card, Status, C1a's and C4a's announced interfaces,
contracts/tokens.md(names),runtime.md§1–§3,reporter.md§3–§4, §9,lab.md§1, §4 (gates, pad-bfs, sgcheck, hv, native-session), §6; C1a's footer CSS andornamentSlots/more.registercode; C2a's Home tab and poster rules (to share the look). - Built
theme/40-library.css(T1, from scratch; the Phase 1 file is replaced),device/rt/40-library.js(T2,wp.c2c),theme/layers/40-library.json(T4). Work in progress lived intheme/_wip/40-library.cssanddevice/rt/_wip/40-library.js; each copy intotheme//device/rt/passedcheck-themebeforesync. - Device findings that changed the plan:
- (a) C1a's glass clip cuts the laser pill in the ornament; it became D-C2c-12.
- (b) Steam pins the tab header with
position: absolutein the tabbed page (y 40). The header moves bytopand the grid by its scroller'spadding-top, and the page root keeps Steam's height, so the scroller still ends at y 720. - (c) The legacy layer rules
tabsandtab-arrowpopped C2c's recessed track and arrows at 4.43 mm: the track moved to%{TabRow}::beforeandtab-arrowis superseded. - (d) Steam's tab scroller has a 2 px gap, which broke E-SEG contiguity (fixed:
gap: 0). - (e) Steam's 300 ms poster transform transition beat C2c's tokens on specificity (fixed with
!important). - (f) Steam's Filters card is the
%{DialogWrapper}scroller, which C1c's sheet rule does not reach (REQ-10). - (g) Steam's checkbox lines in the Filters were 38 tall with 14 px labels (fixed: fill the 80 px row, 24 px label).
- (h) Collection counts are 20 px focusable tooltip sources (D-C2c-15).
- Native: P7 is at M1, not M3. The user's request this round was "still do native glass work", so the fragment was written and checked in two
native-sessionruns (S2-N1, S2-N2). Onehv --lookframe was viewed and deleted at once on both machines (hv --clean;/tmp/lgsholds nohv-*). - Device left as found: theme on in CSS-only mode (each native session ended "back to CSS only: yes"), route
/library/tab/AllGames, no menu or dialog open, every flag per-step (popped at lock exit; checked:librarymoduleoff, nodata-lgs-lib-sort/data-lgs-exempt/data-lgs-emptyattribute left).
2026-10-07, session 3: review R2 fix pass 1
- Start-of-session request check: four open REQ lines to C2c (C1a, C1c, C2a, coordinator); see "Requests to C2c, handled".
- Read: the review (
wp/C2c-review-R2.md, with Appendix A), PLAN §1 (all), §1.19 R2-2, R2-5, R2-6, R2-7, R2-11, R2-13, §2.1, §2.4 C2c, §4, §7;contracts/lab.md§1-§6,interaction.md§2 (the dwell selector),reporter.md§3-§4,react.md(patches),tokens.md§1-§3,runtime.md§3; C1a's footer code (20-shell.jscompact switch), C1c's sheet and menu-source rules, C4a's check-circle primitive. - Work in progress lived in
theme/_wip/40-library.cssanddevice/rt/_wip/40-library.js; each landing ranfontkit.py --hooks(new--lgs-illhosts: the compatibility rows, the sections, the capsules),check-theme(PASS every time),syncandglass.py reload(the sync alone does not re-inject; the first verification run read the old bundle and was discarded). - Device findings that shaped the fixes:
- (a) Steam's legend label is a flex box:
text-overflownever draws in it (Q1). - (b) The Filters card is the scroller and the title scrolls with it; Steam scrolls focus on moves (
SetDOMFocusAndScroll) but not for the default focus at mount (Q3). Each filter section is itself a focusable group (focusable: true,flow-children: column): the D-pad moves section to section on stock too. - (c) Steam's collection tile is a
role=linkdiv that P3's default dwell selector skips; Steam's own:hoverpaints it rgb(98 120 163) (Q7). - (d) Steam's grid wrapper carries
appOverviewsalready sorted for display (0 mismatches over 54 rendered posters at scrollTop 0 and 8400) andeSortBy; ESortBy values come from module 11726 (1 Alphabetical … 11 Steam Review) and the names from module 71395's switch. - (e) G-PERF attribution (in-step A/B, theme sheet text swapped and restored, flags pushed and popped): 40-library.css 0 %; the module without the scrubber 0 %; the scrubber 13 % with a per-frame layout read, about 5 % after that fix and the dock.
- (f) A scrubber jump unmounts the poster that holds Steam's focus; Steam re-focused another one and scrolled 24 rows away, so the pick moves Steam's focus too (mouse source).
- (g) m7 (grid under the tab row on tabs without the sub-filter) failed P-08 on the VR collection's second row and was reverted.
- (h) A poster without art used a translucent tile; with another agent's native session on, its title read 1.4 : 1 over the room. It is opaque now.
- (a) Steam's legend label is a flex box:
- Native: one batched
native-session(R2F-N1), after the CSS-only runs.