Written 2026-08-12. Measurement pass only — no product code was written or changed.
This document is numbers. Where a reference figure is an estimate it says so. Where a previous
claim turned out to be wrong, it says that too.
---
The dashboard could not be used. [internal service]/ returns HTTP 200 but serves
<title>Oracle OS — Sign In</title> — the login wall (CC_CONTROL_TOKEN is set;
command-center-server.mjs mints a cc_session cookie only after POST [internal endpoint]).
Authenticating was out of scope, so the page was loaded another way.
Electron is not installed anywhere under [local path] (checked all six node_modules trees).
The substitute is Puppeteer 25.2.1 driving its own Chrome 150.0.7871.24 headless-shell
([local path]) — same Blink engine family as the
CEF that Big Picture itself runs in. Launched with deviceScaleFactor: 1, --hide-scrollbars,
--mute-audio, --force-device-scale-factor=1.
Harness: a read-only static server (scratchpad/serve.js) over [local path] on
[internal service], serving the *real on-disk* oracle.html and its real assets. /api/* returns
a stub JSON body. Every request to any other host is aborted, so the CDN three.js / katex /
Google-Fonts tags cannot stall the load — none of them are reachable from the Game Center.
Entry into the hub: window.GC.booted = true then GC.renderView() (this skips the
oracle-arcade.js boot splash and paints the library directly), then a 3.4 s settle before any
measurement.
Nothing here was modified by this pass. The only file this run created is
[local path]. SHA-1 of the shipped files, measured immediately before the probe run,
and again immediately after this document was written:
oracle-games.js | d20c02f893c6f199e9abe4051b0a6b8a05b3ae0d | 839b0cba187bfef995b37dc92e72cfc14d782ac8 | changed by the parallel workflow |oracle.css | f0ac22763dbb1217aabfa0896530b260e6249e0e | f0ac22763dbb1217aabfa0896530b260e6249e0e | unchanged |oracle.html | ec0ab839622925fe9be8ca0f5785cd1025b1ab9a | 0330e52f9ced9840e729bf6feed20b908e956d3c | changed by the parallel workflow |oracle-games-pack.js | 17229816cc39436ed0253d5e5d4fef850a9e2c27 | f4bb838980aa4f70154d52f2d4652784169820f1 | changed by the parallel workflow |> ⚠ Every number below is pinned to the "before" column. Three of those four files were
> edited by the concurrent workflow *while this document was being written* — none of it by this
> pass (git status shows only ?? BIGPICTURE-GAP.md as this run's output). The CSS, which owns
> almost all of the geometry reported here, is byte-identical; the JS that builds the DOM is not.
> Re-run scratchpad/probe.js and confirm before acting on any single figure.
Scripts and screenshots (scratchpad, not in the repo):
serve.js, probe.js, probe2.js, probe3.js, pixels.js, show.js, wash.js, out/*.json,
out/*.png.
---
Driven with real keydown events through the CDP input pipe, not synthesised JS events:
.gcbp-on index | label | metadata line | wash changed |Tic-Tac-Toe ↻ NEVER PLAYED | — |Connect Four ↻ NEVER PLAYED | yes |Reversi ↻ NEVER PLAYED | yes |Gomoku ↻ NEVER PLAYED | yes |Hex ↻ NEVER PLAYED | yes |Nine Men's Morris ↻ NEVER PLAYED | yes |Reversi ↻ NEVER PLAYED | yes |.gcbp-on count is exactly 1 at every sample..gcbp-meta-on count is exactly 1, and it migrates to the shelf that owns focus.--gcbp-w follows the focused game: #22d9e6 → #f59e0b → #4ade80 → #a78bfa → #f472b6 → #c084fc.The wash's inline SVG data-URI hash changed on 6 of 6 moves (lengths 5606–6073).
.gcbp count 0, stage element present, #gcbp-barremoved). Escape returns.
Correction to a prior claim: the accent tint does *not* make every game's background look the
same. It is per-game and it changes on every focus move.
.oa-shell has overflow: hidden but scrollWidth 2117 > clientWidth 1907, because the rail's
14 tiles overflow their layout box (.gcbp-rail is overflow-x: visible). The focus scroller
calls scrollIntoView, and Chromium scrolls hidden-overflow containers.
Measured, at 1907×1075, pressing → twelve times:
.oa-shell scrollLeft | hero x | heading x | tab strip x | bottom bar x | status x |210 px is the clamp (2117 − 1907). It stays there for the rest of horizontal navigation and only
unwinds after four ↓ presses (210 → 210 → 159 → 159 → 1 → 0).
Visible result: a 210 px black dead band down the right edge, the search field sliced off the
left, and ORACLE pushed off the bottom-left of the persistent bar.
Evidence: out/deep-desktop-8right.png, out/p3-desktop-12right.png.
Mobile does not have this bug. At 375×812, .oa-shell scrollWidth 416 vs clientWidth 375,
scrollLeft clamps at 1 px, hero x stays 13–14, and the rail translates properly, holding the
focused tile at x ≈ 133 for all 12 presses.
---
Reference column = the owner's screenshot geometry, cross-checked against Valve's published
capsule ratios. Items marked *(est)* have no published source.
[A-Za-z]{3,}) | none | ✅ match |background: transparent, border: 0, padding: 0 | none | ✅ match |Items: 🔍 44×44 · 👥0 47.13×40 · 📶 40×40 · 07:05 53.02×40 (12 px/700/ls 0.6 px) · 🕹 32×32.
Host is .oa-shell-top (0,0,1907,65) with justify-content: space-between, so the cluster
occupies the middle slot between "ORACLE ARCADE" and "EXIT". That is why it is centred.
No battery/globe equivalent.
Game Center · solo · vs AI · online | Recent Games | — |Left margin 40 px = 2.098 % of 1907 — the reference tiles also start at 40 px. **Exact match.
Do not move it.**
The row's own label is a separate element: Start here, 10 px, uppercase, ls 2.2 px, at
x = 869.88 (shoved right of the hero). Every other shelf heading is 10 px at x = 40.
.gc-hero)flex: 0 0 44%, min-height: 290px, radius 14px | — | — |linear-gradient(120deg,#0a0f1b,rgba(9,14,24,.85)) | game art | not art |It is a split card, not a capsule. Two children:
.gc-hero-art — 368.86 × 304, aspect 1.213 — this is the only "art", and it is an emojiglyph on a gradient. It is 45.9 % of the hero's width.
.gc-hero-b — 399.02 × 304 — SPOTLIGHT / Dots & Boxes / blurb / SOLO VS AI ONLINE / ▶ Play / How to play.
So the *artwork* aspect in our landscape slot is 1.213 : 1, against a reference of
2.128 : 1 — 57 % of the target. The overall box width being within 0.7 % is coincidence.
It is also a flex sibling of the rail, not cell #1 of the row: .gcbp-top is
display:flex; gap:26px; align-items:stretch, hero then rail. There is no mixed-aspect row.
aspect-ratio: 2/3 on .gcbp-art) | 0.661 | ✅ correct — keep |The cover source art is already big enough. Decoded, each cover's SVG is intrinsically
300 × 450 — 1.97× the 152 px it is displayed at. Growing the row to 250 × 375 requires no new
art authoring.
.gcbp-meta.gcbp-meta-on at x 869.88, y 419, 997.13 × 38 | under the row | ✅ in kind |b | 21 px / 800 / ls 0.42 px / uppercase | ~30 px *(est)* | 70 % |span | 10.5 px / 600 / ls 1.68 px / JetBrains Mono / #6b7a90 | ~12 px *(est)* | 88 % |The small-caps mono treatment itself is right; the stacking is not. There are 7 .gcbp-meta
elements in the document, one per shelf; exactly one carries .gcbp-meta-on.
justify-content: center; centreOffset 0.00, itemsCentreOffset 0.00 | centred | ✅ exact |border-radius: 999px, active fill rgb(34,217,230), 44 px tall, padding 0 17px, 11.5 px | filled pill | ✅ in kind |Items: ALL 34 (active) · BOARD & STRATEGY 9 · ARCADE 7 · PUZZLE 10 · WORD & TRIVIA 2 ·
REFLEX & SKILL 6 · sep · ANY MODE (active) · SOLO · VS AI · ONLINE.
The count badges the reference shows on FRIENDS are present on ours. .gcbp-tabs-anchor exists
but measures 0 × 0 at (0,0).
The reference has a row of ~430 px cards: eyebrow (NEWS, MAJOR UPDATE) above the art, then
art, then POSTED <date>, then title, bleeding off the right edge.
What is at that position instead:
.gc-head | 44 | 4.1 % |.gcbp-top (hero + rail + meta) | 306 | 28.5 % |.gc-chips.gcbp-tabs | 64 | 6.0 % |.gc-prog-host — XP bar, daily challenge, "closest achievements" list | 475.75 | 44.3 % |The largest single element on the first screen is a stats panel.
The 34 .gc-card tiles do exist, but they start at y = 2787.75 — 2.59 screens below the fold.
They are 166.5 × 249.75 (aspect 0.667), have no eyebrow element (.gc-card-kick /
.gc-kick / .gcbp-kick / .gc-card-eyebrow all return null), child order is
.gcbp-art → .gc-card-ico → .gc-card-b → .gc-card-help, and they wrap instead of bleeding
(last right edge 760 of 1907; 0 sliced).
position: absolute; bottom: 0 | y ≈ 1050 |linear-gradient(rgba(4,7,13,.68), rgba(4,7,13,.95)), border-top: 1px rgba(255,255,255,.07), z-index: 30 | — |.gcbp-brand ORACLE │ + MENU button, x 14, w 193.44 | STEAM │ MENU |.gcbp-hints x 1613.36, w 279.64, h 23, 13 px, gap 22 px | OPTIONS / (A) SELECT / (B) BACK |M MENU · ↵ SELECT · ESC BACK | — |≡ MENU · Ⓐ SELECT · Ⓑ BACK | ✅ same convention |.oa-shell-body scrollTop 2850; bottomInset stays 0 | yes |Missing versus the reference: an OPTIONS entry.
Note the horizontal pan in §1b moves this bar to x = −210 along with everything else.
#gcbp-wash)blur(46px) saturate(1.3) | grayscale(1) contrast(1) — opposite sign on chroma |scale(1.22) static | 25 s slow zoom, ease 0s 1 alternate |linear-gradient(#000 0%, rgba(0,0,0,.62) 34%, rgba(0,0,0,0) 72%) | radial 75% 83% at 50% 18%, on two nested wrappers |::after = radial-gradient(120% 80% at 50% 0%, var(--gcbp-w), transparent 62%) @ 0.22 | none |none | 25 s zoom |opacity 0.45s | 0.3 s fade-in |<img>, 0 <canvas> — inline SVG data-URI on background-image | <img> |Four measured differences: we saturate where Steam desaturates; our mask is linear
(fades downward only, so colour runs hard into the left and right edges) where Steam's is a
radial ellipse (lets the whole perimeter go black); we add an accent tint Steam does not
have; we have no zoom.
.gcbp-on .gcbp-art | unfocused .gcbp-art |matrix(1.055, 0, 0, 1.055, 0, 0) — measured 160.36 / 152.00 = 1.0550 | none |2px solid #fff | 1px solid rgba(255,255,255,.1) |rgba(0,0,0,.98) 0 22px 46px -18px, rgb(34,217,230) 0 0 30px -6px | rgba(0,0,0,.96) 0 10px 26px -16px |transform .17s cubic-bezier(.2,.8,.3,1), box-shadow .17s, outline-color .17s | same |The treatment is on the art, not the tile — the tile itself measures transform: none,
outline-style: none, box-shadow: none. 1.055 sits inside the cross-platform band
(Android TV 1.025 / 1.05 / 1.1; tvOS 1.05–1.1) and equals Steam's translateZ(15px) at a 288 px
perspective. Focus scale is not a problem.
Two things are missing:
1. Row-level focus. .gpfocuswithin = 0, :focus-within = 0, and
[class*="within"], [class*="row-on"], [class*="shelf-on"] matches 0 elements. Steam has
two states (.gpfocus on one item, .gpfocuswithin on every card in the owning row); we have
one.
2. Real DOM focus. document.activeElement is BODY at every sample, on both viewports. The
model is a CSS class plus a document-level capturing keydown listener. Nothing is
focus-focused, so :focus-visible never fires and there is no accessibility tree signal.
navigator.getGamepads present; 0 pads attached in the harness.gamepadconnected event flips the legend from M MENU / ↵ SELECT / ESC BACK to ≡ MENU / Ⓐ SELECT / Ⓑ BACK. The (A) SELECT / (B) BACK line is literally true, not decor.
navigator.getGamepads called 75 times in 1200 ms = 62.5 Hz(rAF-paced). It does not poll before a pad connects — correct, no idle cost.
They render.
Each is decoded from a data:image/svg+xml URI (5606–15937 chars, distinct per game) into a
152 × 228 canvas and read back with getImageData over 34,656 pixels.
Pixel differential, clean load, no key input, clip (866, 171, 160 × 241):
visibility: hidden on .gcbp-art → PNG 18,753 bytes (44.5 %)They are deterministic. Two independent page loads, 40 covers compared by their full
background-image string: 40 / 40 identical, 0 differing, 0 label mismatches.
---
The reference has no phone spec; these are our numbers plus the arithmetic that a
reference-faithful phone layout would require.
.gc-head | 347 × 98 at y 77 (search field + 5 tool buttons + volume slider) = 12.1 % of the screen before any content |.gcbp-top | flex-direction: column, gap 12 px |justify-content: flex-start; items span 1216.39 px in a 361 px box → scrolls; itemsCentreOffset 434.70 |The reference row geometry is arithmetically impossible at 375 px. A 34.9 vh row on an 812 px
screen is 283 px tall; a 2.128 : 1 landscape cell at that height is **602 px wide — 1.61× the
entire viewport**. There is no clamp that makes this work; it has to be an explicit decision.
---
.oa-shell-body (html/body are overflow: hidden, scrollHeight 1075) | same |Big Picture is one screen of rows. Ours is a scrolling page wearing console chrome. Contents:
.gc-head | 44 | — |.gcbp-top (hero + "Start here" rail) | 306 | 14 |.gc-chips.gcbp-tabs | 64 | — |.gc-prog-host | 475.75 | — |.gc-shelf Board & Strategy | 306 | 9 |.gc-shelf Arcade | 306 | 7 |.gc-shelf Puzzle | 306 | 10 |.gc-shelf Word & Trivia | 306 | 2 |.gc-shelf Reflex & Skill | 306 | 6 |.gc-lobby | 61 | — |.gc-shelf.gcbp-gridwrap (All games) | 1121 | 34 cards |Every shelf heading is 10 px. Every shelf tile is 152 × 228.
The rail also carries mouse affordances Big Picture has none of:
.gc-shelf-nav.gc-shelf-prev at x 864, 44 px wide, and .gc-shelf-next at x 1829, 44 px wide.
When focus scrolls past the top band, the metadata line goes with it —
at .oa-shell-body scrollTop 2850 the bar, status cluster and wash are all still visible, but
.gcbp-meta-on and the hero are off-screen.
---
1. Poster aspect 0.667. aspect-ratio: 2/3 on .gcbp-art, held exactly on all 48 tiles at
both viewports. Matches Valve's 600 × 900 Library Capsule.
2. Left gutter 40 px = 2.098 %. Identical to the reference. TV-platform figures
(Android TV 5–6 %, tvOS 80 pt, Smashing 80 px) would make this worse.
3. Tab strip centring. centreOffset 0.00 and itemsCentreOffset 0.00. Exact.
4. Right-edge bleed on the row. 1 sliced tile, last tile right edge 3179.88 vs viewport 1907.
5. Icons-only status cluster with no container chrome. 0 of 5 items carry a text label.
6. Persistent bottom bar with a glyph+LABEL legend that switches to Ⓐ/Ⓑ on gamepad connect.
7. Focus scale 1.0550, transition .17s cubic-bezier(.2,.8,.3,1).
8. The focus model itself — single focus, metadata follows, background follows, Enter opens.
9. Deterministic drawn covers, 40/40 stable across loads, 300 × 450 intrinsic.
---
.oa-shell-body 3860 / 1010 | 1.00 |.gc-prog-host 475.75 px | a content row |blur(46px) saturate(1.3), linear 180°, ::after @ .22, animation: none | grayscale(1) contrast(1), radial 75% 83% at 50% 18%, no tint, 25 s zoom |.gpfocuswithin = 0 | .gpfocus + .gpfocuswithin |activeElement = BODY at every sample | — |---
These have no published source — Valve publishes no typography or spacing spec for Big
Picture at all:
Recent Games heading size (~28 px);OPTIONS item;perspective value behind translateZ(15px);LAST TWO WEEKS.Everything else in this document is a measured number from a live render, or a Valve-published
capsule ratio.