# BIGPICTURE-GAP.md — what the Oracle Arcade hub actually renders, measured

**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.

---

## 0. How these numbers were obtained (so they can be reproduced or disputed)

**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:

| file | before (what was measured) | after | |
|---|---|---|---|
| `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`.

---

## 1. Headline: the two things a screenshot comparison would never have caught

### 1a. The focus model is real and it is good. Stop rebuilding it.

Driven with real `keydown` events through the CDP input pipe, not synthesised JS events:

| key | `.gcbp-on` index | label | metadata line | wash changed |
|---|---|---|---|---|
| start | 0 | Tic-Tac-Toe | `Tic-Tac-Toe ↻ NEVER PLAYED` | — |
| → | 1 | Connect Four | `Connect Four ↻ NEVER PLAYED` | yes |
| → | 2 | Reversi | `Reversi ↻ NEVER PLAYED` | yes |
| → | 3 | Gomoku | `Gomoku ↻ NEVER PLAYED` | yes |
| ↓ | 22 | Hex | `Hex ↻ NEVER PLAYED` | yes |
| ← | 21 | Nine Men's Morris | `Nine Men's Morris ↻ NEVER PLAYED` | yes |
| ↑ | 2 | Reversi | `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).
* **Enter opens a game** (after Enter: `.gcbp` count 0, stage element present, `#gcbp-bar`
  removed). 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.

### 1b. On desktop, the first arrow-key press pans the entire console screen 210 px left, and it never comes back

`.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:

| press | `.oa-shell` scrollLeft | hero x | heading x | tab strip x | bottom bar x | status x |
|---|---|---|---|---|---|---|
| (start) | 0 | **40** | **40** | **40** | **0** | 889.94 |
| 1 | 158 | −118 | −118 | −118 | −158 | 731.94 |
| 2 | **210** | **−170** | **−170** | **−170** | **−210** | 679.94 |
| 3–12 | 210 | −170 | −170 | −170 | −210 | 679.94 |

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.

---

## 2. Element-by-element, desktop 1907×1075

Reference column = the owner's screenshot geometry, cross-checked against Valve's published
capsule ratios. Items marked *(est)* have no published source.

### Status cluster

| | ours | reference | delta |
|---|---|---|---|
| box | x 889.94, y 10, 228.14 × 44 | right-aligned, y ≈ 28 | — |
| right inset | **788.92 px (41.4 % of viewport)** | ~40 px | not right-aligned |
| items | 5 | 6 | −1 |
| labels on icons | **none** (all 5 fail `[A-Za-z]{3,}`) | none | ✅ match |
| container chrome | `background: transparent`, `border: 0`, `padding: 0` | none | ✅ match |
| gap | 3 px | — | — |

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.

### Section heading

| | ours | reference | delta |
|---|---|---|---|
| text | `Game Center · solo · vs AI · online` | `Recent Games` | — |
| position | x **40**, y **99.5** | x ≈ 48, y ≈ 96 | ✅ within 8 px / 3.5 px |
| font-size | **13 px** | ~28 px *(est)* | **46 %** |
| style | 600, ls 1.82 px, **uppercase**, opacity 0.7, Outfit | large, sentence case *(est)* | wrong kind |

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.

### The big landscape tile (`.gc-hero`)

| | ours | reference | delta |
|---|---|---|---|
| box | 803.88 × 306 | 798 × 375 | w **+0.7 %**, h **81.6 %** |
| aspect | **2.627** | 2.128 (Library Header 920×430) | **+23.4 %** |
| CSS | `flex: 0 0 44%`, `min-height: 290px`, `radius 14px` | — | — |
| background | `linear-gradient(120deg,#0a0f1b,rgba(9,14,24,.85))` | game art | not art |
| text on it | **104 characters** | **0** | — |
| canvases / SVGs | 0 / 0 | — | — |

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 emoji
  glyph 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.

### Cover tiles — the row

| | ours | reference | delta |
|---|---|---|---|
| tile size | **152.00 × 228.00** | 248 × 375 | w **61.3 %**, h **60.8 %** |
| aspect | **0.667** (`aspect-ratio: 2/3` on `.gcbp-art`) | 0.661 | ✅ **correct — keep** |
| row height | **228 px = 21.21 vh** | 375 px = 34.88 vh | **60.8 %** |
| gap | 14 px | 10 px | **+40 %** |
| pitch | 166 px | 258 px | 64.3 % |
| first tile left | 869.88 | 848 | +21.9 |
| tiles across the rail band | **6.01** (997.13 / 166) | **4.10** (1059 / 258) | **1.47× denser** |
| fully visible | 6 | ~4 | — |
| sliced at right edge | **1** | 1 | ✅ match |
| last tile right edge | 3179.88 (viewport 1907) | off-screen | ✅ bleeds |
| heights uniform | **true — all 14 are 228** | mixed-aspect at one height | no mixed row |

**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.

### Focused-item title and metadata

| | ours | reference | delta |
|---|---|---|---|
| container | `.gcbp-meta.gcbp-meta-on` at x 869.88, y 419, 997.13 × 38 | under the row | ✅ in kind |
| title `b` | **21 px** / 800 / ls 0.42 px / uppercase | ~30 px *(est)* | **70 %** |
| metadata `span` | **10.5 px** / 600 / ls 1.68 px / JetBrains Mono / `#6b7a90` | ~12 px *(est)* | 88 % |
| **layout** | **side by side on one line** — span starts 165.42 px right of the title's left edge; vertical top delta only **11 px** | **stacked** — title y ≈ 535, metadata y ≈ 562, **27 px below** | **wrong structure** |

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`.

### Tab strip

| | ours | reference | delta |
|---|---|---|---|
| centred? | `justify-content: center`; **centreOffset 0.00**, itemsCentreOffset **0.00** | centred | ✅ **exact** |
| pill shape | `border-radius: 999px`, active fill `rgb(34,217,230)`, 44 px tall, padding 0 17px, 11.5 px | filled pill | ✅ in kind |
| items | **10**, spanning **1305.84 px** | 3 | **3.3×** |
| function | filtering (6 categories + 1px separator + 4 modes) | section switching | different job |

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 content row below the tabs — **does not exist**

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:

| y | element | height | % of the 1075 screen |
|---|---|---|---|
| 85 | `.gc-head` | 44 | 4.1 % |
| 151 | `.gcbp-top` (hero + rail + meta) | 306 | 28.5 % |
| 481 | `.gc-chips.gcbp-tabs` | 64 | 6.0 % |
| **567** | **`.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).

### Bottom bar

| | ours | reference |
|---|---|---|
| box | x 0, y 1019, 1907 × 56, `position: absolute; bottom: 0` | y ≈ 1050 |
| background | `linear-gradient(rgba(4,7,13,.68), rgba(4,7,13,.95))`, `border-top: 1px rgba(255,255,255,.07)`, `z-index: 30` | — |
| left | `.gcbp-brand` `ORACLE │` + `MENU` button, x 14, w 193.44 | `STEAM │ MENU` |
| right | `.gcbp-hints` x 1613.36, w 279.64, h 23, 13 px, gap 22 px | `OPTIONS / (A) SELECT / (B) BACK` |
| legend, keyboard | `M MENU` · `↵ SELECT` · `ESC BACK` | — |
| legend, gamepad | **`≡ MENU` · `Ⓐ SELECT` · `Ⓑ BACK`** | ✅ same convention |
| persistent? | **yes** — survives `.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.

### Background wash (`#gcbp-wash`)

| property | ours | reference (Deck-Shelves CDP capture of SteamOS 3.8) |
|---|---|---|
| box | x −209.77, y 0, 2326.54 × 1311.5 | — |
| filter | **`blur(46px) saturate(1.3)`** | **`grayscale(1) contrast(1)`** — opposite sign on chroma |
| transform | `scale(1.22)` static | 25 s slow zoom, `ease 0s 1 alternate` |
| opacity | 0.40 | — |
| mask | **`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** |
| tint layer | `::after` = `radial-gradient(120% 80% at 50% 0%, var(--gcbp-w), transparent 62%)` @ **0.22** | **none** |
| animation | **`none`** | 25 s zoom |
| transition | `opacity 0.45s` | 0.3 s fade-in |
| children | 0 `<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**.

### Focus treatment

| | `.gcbp-on .gcbp-art` | unfocused `.gcbp-art` |
|---|---|---|
| transform | `matrix(1.055, 0, 0, 1.055, 0, 0)` — measured 160.36 / 152.00 = **1.0550** | `none` |
| outline | `2px solid #fff` | `1px solid rgba(255,255,255,.1)` |
| box-shadow | `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` |
| transition | `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.

### Gamepad

* `navigator.getGamepads` present; 0 pads attached in the harness.
* Dispatching a `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.
* After that event a poll runs: `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.

### Covers — do they render, and are they stable?

**They render.**

| game | intrinsic | opaque px | distinct colours (6-bit buckets) | mean luminance |
|---|---|---|---|---|
| Tic-Tac-Toe | 300 × 450 | 100.0 % | 3346 | 69 |
| Connect Four | 300 × 450 | 100.0 % | 2199 | 77 |
| Reversi | 300 × 450 | 100.0 % | 1798 | 76 |
| Gomoku | 300 × 450 | 100.0 % | 1999 | 88 |
| Nim | 300 × 450 | 100.0 % | 2421 | 78 |
| Dots & Boxes | 300 × 450 | 100.0 % | 2119 | 81 |

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)`:

* cover visible → PNG **42,112 bytes**
* `visibility: hidden` on `.gcbp-art` → PNG **18,753 bytes** (**44.5 %**)
* byte-identical: **false**

**They are deterministic.** Two independent page loads, 40 covers compared by their full
`background-image` string: **40 / 40 identical, 0 differing, 0 label mismatches.**

---

## 3. Mobile 375×812

The reference has no phone spec; these are our numbers plus the arithmetic that a
reference-faithful phone layout would require.

| | value |
|---|---|
| status cluster | x 101.89, 136.14 × 40. 🔍 and 📶 collapse to **0 × 0** — 3 visible items |
| `.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 |
| hero | 347 × 305.19, aspect **1.14**; its art panel is 345 × 108 = **3.19 : 1** |
| **first cover top edge** | **y = 531.19 — 65.4 % of the way down the screen** |
| tiles | **108.75 × 163.13**, aspect 0.667 |
| row height | **163.13 px = 20.09 vh** (reference 34.88 vh → **57.6 %**) |
| gap / pitch | 9 px / 117.75 px |
| visible | 3 full + 1 sliced |
| metadata | title **15 px**, span **9.5 px**, at y 708.31 = **87.2 %** down the screen |
| tab strip | `justify-content: flex-start`; items span **1216.39 px** in a 361 px box → scrolls; itemsCentreOffset 434.70 |
| bottom bar | 375 × 54 at y 758; brand w 104.72, hints w 178.16, gap 11 px |
| focus / meta / wash | all still follow arrow keys ✅ |
| shell pan bug | **absent** ✅ |

**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.

---

## 4. Page shape — the structural finding

|  | desktop 1907×1075 | mobile 375×812 |
|---|---|---|
| scroller | `.oa-shell-body` (`html`/`body` are `overflow: hidden`, `scrollHeight` 1075) | same |
| scrollHeight / clientHeight | 3860 / 1010 = **3.82 screens** | 4908 / 747 = **6.57 screens** |

Big Picture is one screen of rows. Ours is a scrolling page wearing console chrome. Contents:

| y | element | height | tiles |
|---|---|---|---|
| 85 | `.gc-head` | 44 | — |
| 151 | `.gcbp-top` (hero + "Start here" rail) | 306 | 14 |
| 481 | `.gc-chips.gcbp-tabs` | 64 | — |
| 567 | `.gc-prog-host` | 475.75 | — |
| 1064.75 | `.gc-shelf` Board & Strategy | 306 | 9 |
| 1392.75 | `.gc-shelf` Arcade | 306 | 7 |
| 1720.75 | `.gc-shelf` Puzzle | 306 | 10 |
| 2048.75 | `.gc-shelf` Word & Trivia | 306 | 2 |
| 2376.75 | `.gc-shelf` Reflex & Skill | 306 | 6 |
| 2704.75 | `.gc-lobby` | 61 | — |
| 2787.75 | `.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**.

---

## 5. What is already right — do not "fix" these

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.

---

## 6. Gaps, ranked by measured magnitude

| # | gap | measured | reference |
|---|---|---|---|
| 1 | **Desktop shell pans 210 px on the first →** and stays there | hero x 40 → −170, bar x 0 → −210 | 0 |
| 2 | **Row is 39 % too short and 1.47× too dense** | 228 px / 21.21 vh, 6.01 across the band | 375 px / 34.88 vh, 4.10 |
| 3 | **The screen is 3.82 screens tall** | `.oa-shell-body` 3860 / 1010 | 1.00 |
| 4 | **The landscape tile's art is 1.213 : 1 and it carries 104 chars of text** | art 368.86 × 304 = 45.9 % of the hero | 2.128 : 1, 0 chars, 100 % |
| 5 | **The 44.3 % of the first screen below the tabs is a stats panel** | `.gc-prog-host` 475.75 px | a content row |
| 6 | **Wash: saturate instead of desaturate, linear mask instead of radial, extra accent tint, no zoom** | `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 |
| 7 | **Section heading is 46 % of size and the wrong kind** | 13 px uppercase ls 1.82 px opacity .7 | ~28 px sentence case *(est)* |
| 8 | **Title/metadata sit side by side, not stacked** | 11 px top delta, span 165.42 px to the right | 27 px below |
| 9 | **Focused title 70 % of size** | 21 px | ~30 px *(est)* |
| 10 | **No row-level focus state** | `.gpfocuswithin` = 0 | `.gpfocus` + `.gpfocuswithin` |
| 11 | **No real DOM focus** | `activeElement` = `BODY` at every sample | — |
| 12 | **Tab strip carries 10 items, not 3** | span 1305.84 px | 3 pills |
| 13 | **Mobile row is 57.6 % of reference and starts 65.4 % down the screen** | 163.13 px at y 531.19 | — |
| 14 | Gap 14 px | +40 % | 10 px |
| 15 | Metadata 10.5 px | 88 % | ~12 px *(est)* |
| 16 | Status cluster 788.92 px from the right edge, 5 items | — | right-aligned, 6 |

---

## 7. Estimates, flagged so they do not harden into facts

These have **no published source** — Valve publishes no typography or spacing spec for Big
Picture at all:

* the reference focused-title size (~30 px) and metadata size (~12 px);
* the `Recent Games` heading size (~28 px);
* the ~430 px news-card width;
* the footer glyph metrics and the `OPTIONS` item;
* Steam's `perspective` value behind `translateZ(15px)`;
* the green glyph before `LAST TWO WEEKS`.

Everything else in this document is a measured number from a live render, or a Valve-published
capsule ratio.
