fix(next): keep compact picker harness icons visible
Fixes the compact model picker rail clipping the final harness mark at narrow widths.
What changed
- Wrap harness targets into uniform density-token slots with 4px gaps, preserving 16px AgentMark rendering and keeping every target within the popup.
- Resolve unknown or unrecognized family marks to the family initial instead of an empty reserved span.
- Bound the rail to three complete rows in short panes; keyboard navigation scrolls the selected harness into view.
- Add real-browser regressions for 10-harness visible wrap, unknown-mark hit target, 40-harness short-pane scrolling, last-harness selection, and x/y bounds.
Root cause
QuickModelMenu.tsx rendered <AgentMark agent={undefined} reserve /> when a family had no recognized mark; AgentMark intentionally returned an empty span. The rail remained a single horizontal flex row, so at a 320px viewport its measured scrollWidth exceeded its 297.83px client width (10 targets at 28px plus nine 4px gaps and 12px padding = 328px). The last mark was clipped and the unknown slot was blank.
Gallery evidence
Compared wrap, horizontal-scroll, and wider-popup variants in the existing gallery fixture. Wrap is selected: the 10-harness view wraps evenly with all targets accessible; scroll and wide are retained as gallery-only comparison variants. The 40-harness stress fixture at 320x300 has rail scrollHeight=168, clientHeight=103; keyboard ArrowLeft selects Harness 40 and leaves its 28x28 box wholly inside the 104px rail. Exact screenshots/recording are retained on GCP under /tmp/nx-picker-evidence/: icons-after-stress-320x300.png, icons-after-stress-last-320x300.png, icons-receipt.json, and icons-video/page@74741ed959ae23504d8130548450c8cd.webm.
The visual reference is cmux-design-references/apps/claude/live/model-picker-open.png plus T3 live/composer-provider-picker.png: quiet 16px provider marks, no new boxes or motion. The design-reference checkout is on Big Red at /home/leo/Projects/checkouts/cmux-design-references/refs-tesseract-omp; it was not modified.
Verification
- Fresh Astra gpt-6-astra xhigh review: SHIP, exact head
6ca53031b6906b58fa5dbfc7adda8be2d913e3b6. - Browser: 9 pass / 126 expectations (
/tmp/nx-picker-icons-green40-keyboard.log). - Production suites: 36 pass / 154 expectations (
/tmp/nx-picker-icons-production-final.log). - Type check:
vp check --no-fmt --no-lintpassed on 2,817 files. prepush-gate.py --base e6525bd5f1710e9df4310baef3c1d24ebbbe0627 --head 6ca53031b6906b58fa5dbfc7adda8be2d913e3b6passed;git diff --checkpassed.- Combined compact JSDOM suite retains the pre-existing optional Effort-slider focus failure; exact base reproduction is in prior picker evidence.
No model/account behavior changed.
Agent session: agent session