# [#19909](https://git.cafe/pingdotgg/t3code/pulls/19909) — completed Linux/browser capture matrix

Updated capture provenance: actual Linux Electron and real browser capture completed on 2026-10-24. Review checkout: /home/ubuntu/wt/pr-19909, takeover/pr-19909. Baseline mergebase [3cc31ed27c](https://git.cafe/pingdotgg/t3code/commit/3cc31ed27c8956b36cee35a50509fb7c6869592b); capture head [9a5d15e3c6](https://git.cafe/pingdotgg/t3code/commit/9a5d15e3c6c0c217ddd1fb3265a6bfe746e381a9) (updated after main merge; same three changed files). Original PR remains at [d0c7c3a8d5](https://git.cafe/pingdotgg/t3code/commit/d0c7c3a8d58e686fea7ffaba15dcd72c5661ca0f): existing PR-body evidence is historical, not proof of this takeover head.

## Route and fixture derivation

Production route: session-logic.ts htmlRenderFromToolItem → HtmlRenderTimelineRow (TimelineAssistantRows.tsx) → HtmlRenderFrame → Open full screen → HtmlRenderDialog → HtmlRenderDocument iframe. Sole direct production dialog caller is HtmlRenderFrame. BrowserDocumentFrame's HTML/file/PDF branches do not instantiate this dialog; nested image requests use ExpandedImageDialog, not this branch. No Settings, palette, or dedicated fullscreen HTML keybinding caller found. Escape dismisses via Dialog; explicit Close calls onClose. Web at local/remote/tunnel origins shares the component; desktop embeds that web path. Native mobile does not render this React component. Providers only supply the same HTML reference, so no provider cross-product is needed.

Props: src (signed attachment URL), title (toolbar text), optional threadRef (environment/link/keybinding routing), onClose. The sole caller supplies its threadRef; absence does not alter dialog geometry. Loading/error/URL-refresh failure stays inline or displays a toast before opening. HTML content, refreshed URL, and nested image viewer do not select another outer-height class. Theme changes iframe and surrounding colors but not height. Zoom 50–200% changes inner content only; footer and Close must remain accessible. Long title truncates beside fixed controls: use one long title for narrow coverage rather than adding another fixture.

Changed branch: height=min(.86*(H-T), H-T-160), with native titlebar T from env(titlebar-area-height,0px). H-T <1142.86 selects subtraction branch; greater selects proportional branch. Use H=800 and H=1200 (native T=40) to exercise both. Linux/Windows configure a real Electron overlay at 40px; macOS uses hiddenInset and the zero-height fallback. A CSS override to 52px is synthetic regression coverage, never native evidence. Height at H=800 is 640 baseline / 600 native head. At H=1200 it is 1032 baseline / 997.6 native head. Browser T=0 must match baseline exactly.

## Fresh real-app seed (shared by every row)

Capture owner alone starts its one integrated app pass. All state, profile, and artifacts stay under /tmp/ev-19909; use an explicit fresh home there with --no-seed and T3CODE_DEV_SEED=0. Never read/copy ~/.t3 data, secrets, or settings. Never change auth/permissions/modes/trust/MCP configuration. Use only the isolated app's existing normal access.

Create a project rooted in a disposable directory under /tmp/ev-19909 and a stopped fixture thread via the app's normal project/thread flow. Publish one self-contained HTML attachment into THAT isolated thread through its existing html_render tool/service path (title: "Fullscreen HTML clearance — a deliberately long fixture title"; height: 600). HTML: theme-aware background/text, a visible heading and top/bottom labeled markers, a 1200px tall content area to permit scrolling, no network assets or scripts needed. If invoking tools is unavailable in the fresh instance, an external seed driver may call the actual HtmlRender.publish service plus normal thread/event APIs against the isolated state before startup; preserve resulting html-render timeline reference and attachment. Do not fabricate a screenshot or direct-mount the dialog as primary proof. Record exactly which supported seed API/driver was used. If real-app seeding fails, report the exact blocker; a component harness is supplemental only and does not meet Linux Electron proof.

For each row below, reuse this same seeded thread and attachment; choose appearance in the actual app, open inline HTML's Open full screen button, and wait for settled frame and dialog. Use identical fixture on baseline/head. No seed or driver files are committed. Capture native window decorations using headless-desktop desktop/window screenshots, not renderer-only screenshots.

## Minimum capture matrix

Default standard: 100% app/browser zoom, device scale 1, unmodified font scale; light AND dark. Dimensions below are CSS content viewport sizes; record actual content and outer-window bounds. Every before/after pair uses the same dimensions and theme.

| ID | Surface / fixture | Affected? | Viewport × theme | Real app row seed / action | Required evidence and acceptance |
| --- | --- | --- | --- | --- | --- |
| L800 | Actual Linux Electron under headless-desktop; native controls visible | Yes, subtraction branch | 1440×800 × light,dark | Shared seed; open fullscreen HTML | Before/after settled stills including real minimize/maximize/close controls; measure native T, Close rect, toolbar rect. Head Close.top>=T, toolbar.bottom<=H; report baseline overlap or clearance honestly. 4 stills. |
| L1200 | Same Linux Electron; tall dialog | Yes, proportional branch | 1440×1200 × light,dark | Same seed/open | Before/after native stills and geometry as above. 4 stills. |
| W800 | Plain browser, no desktop bridge/overlay | No, T=0 control | 1440×800 × light,dark | Same isolated server/thread via browser; open fullscreen | Baseline/head stills + matching bounds (allow rasterization tolerance only). 4 stills. |
| N800 | Narrow plain browser; long title and scrollable HTML | No, T=0 control | 390×800 × light,dark | Same seed; viewport resize then open | Baseline/head stills; Close/footer visible, title truncation, no horizontal clipping of controls, unchanged geometry. 4 stills. |
| I-L | Linux native interaction | Affected controls | 1440×800 × dark | Same seed; open → zoom in → reset → scroll → Close → reopen → Escape | Before/after recording, not stills. Show pointer successfully activating HTML Close independently of native controls, percentage update/reset, footer visibility, both dismissal paths and reopening. 2 recordings. |
| I-N | Narrow browser interaction | Control, narrow hit targets | 390×800 × light | Same seed; same interaction sequence | Before/after recordings; controls remain usable with long title and content scroll. 2 recordings. |
| L390 | Linux Electron at requested 390px | Affected, constrained | 390×800 × light,dark | Same seed, only if an actual 390px native content viewport can be obtained | DesktopWindow.ts sets minWidth=840. Do not claim a 390 screenshot by resizing renderer alone or scaling an 840 image. If capture owner can temporarily lower minimum size through its owned Electron test driver without source/config changes, capture native before/after pairs (4 more stills); document override as supplemental unsupported-width coverage. Otherwise report blocked by product minWidth, with N800 covering supported narrow web. |
| WIN | Actual Windows Electron | Affected, specifically unverified | Not executable on this Linux host | Same seed recipe on Windows when available | Explicitly unverified; synthetic CSS is not Windows proof. Not a hard stop for the web-path audit. |

Minimum supported set: 4 static fixtures × 2 themes × 2 revisions = 16 stills; 2 interaction fixtures × 2 revisions = 4 recordings. Conditional native L390 adds 4 stills, total 20 + 4 recordings if feasible. Windows remains unverified. No scale reductions. If desktop screen cannot accommodate 1440×1200, enlarge the owned headless display rather than scaling the app. Do not replace real overlay with CSS simulation.

## Proof checks and audit findings

No functional defect identified by static inspection of this one-class change: zero-titlebar expression is algebraically identical, native height follows the established ExpandedImageDialog formula, and shared media viewport already adds titlebar padding. Comment-only ZoomableImage diff has no runtime effect.

Capture owner completed the supported minimum: 16 settled stills, 16 difference images, and 4 timestamp-captioned interaction recordings. All 16 stability companion frames matched exactly at 500ms separation. Existing new browser test mocks the document and supplies synthetic 52px titlebar; it verifies neither native overlay paint nor plain-browser unchanged behavior nor the tall branch. It is a new test file against this mergebase, despite the original brief describing an existing test. User explicitly authorizes the real geometry regression test, and both reviewers accepted it. Retain the test; the earlier deletion recommendation is superseded. Capture work makes no implementation changes.

Record exact baseline/head identities, app/Electron version, computed T, CSS viewport, scale, appearance, Close/toolbar rectangles and media asset names alongside captures. If native baseline does not actually overlap at T=40, describe improved clearance, not a reproduced collision. The earlier audit did not launch servers; this capture pass did, using only fresh isolated state.

FRICTION: scope | Electron minWidth=840 conflicts with a requested 390px native viewport | distinguish narrow web coverage from supplemental Electron minimum-size override before capture.
FRICTION: evidence | historical PR-body claims and original test-file description do not match the takeover mergebase | bind proof and file expectations to exact reviewed head and mergebase.

## Correction round 2 outcome (supersedes previous capture outcome)

All 16 primary stills, 16 stability companions, 16 differences and 4 interaction recordings were freshly captured at the exact base/head named above. All primary stills and differences were opened in full. Every recording step was inspected in newly extracted step frames, with full-resolution native Close/Escape frames checked separately. The complete native backdrop and dismissed state are clean.

Historical proof-audit-pass2.md correctly rejected all 8 native stills and both native recordings for an unrelated project/Git panel already present behind the dialog. It was the persistent thread details panel, so Escape alone did not close it. This round closes it with the ordinary toolbar toggle after app hydration, before opening fullscreen; assertions after Close and Escape only verify absence, without hiding anything. No implementation change. This new evidence supersedes that insufficient evidence, while the historical audit remains retained.

L800 native T=40: Close.top 42→62, zoom.bottom 758→738. L1200: Close.top 46→63.203125, zoom.bottom 1154→1136.796875. Both themes match. Baseline already clears native controls; this proves improved clearance, not a reproduced collision. Native window controls and horizontal geometry remain fixed; pane size, Close/footer, content position, shadows/rings/gradient edges and exposed background change as expected. No unrelated changing region identified.

All four browser pairs now match exactly at threshold zero; geometry unchanged (W800 Close.top=22, zoom.bottom=738; N800 Close.top=20, zoom.bottom=740). An initial W800-light attempt had 34 background pixels differing by only 1/255 in the dimmed composer; one repeated pair under the same settled browser state eliminated that raster variation. Those initial attempts remain locally in round2-history and are not delivered as final proof.

All 16 stability pairs are pixel-identical. All four recordings pass open→125%→100%→bottom marker→Close→reopen→Escape; clean dismissed states are visible. Native input uses actual X11 XTest clicks, recording uses ffmpeg x11grab, captions sit below unchanged app pixels. Browser recording outer=500×900, emulated content=390×800; unused white strip is disclosed and unscaled.

Linux Electron/Chromium/browser versions, scale=1, fixed clock, reduced-motion, real T=40 and supported sizes remain as documented in environment.json. L390 remains unavailable at product minWidth=840; Windows remains unverified. No synthetic titlebar override was used. Mobile/macOS/remote/tunnel were not executed. Fixture route, ordinary thread/project APIs, real HtmlRender.publish attachment and stopped projection-row seed are unchanged; this is visual UI proof, not provider execution/event-history proof.

Capture owner reran rebuild-one.sh at the latest head: fresh L800-dark image is pixel-identical AND independently inspected clean, including its dismissed state. This is a self-check, not the required next independent audit. Retained isolated state and current REBUILD.md enable the next auditor to rebuild a new image. No code edits, commits, push, PR writes, fork actions or watch.

FRICTION: evidence | historical native proof retained an unrelated details panel | close it after hydration before opening fullscreen, then inspect the complete dismissed screen.
FRICTION: tooling | reload briefly aborted and an early panel check ran before hydration | await the real fixture and network idle before dismissing the panel.
FRICTION: communication | normal isolated pairing was unnecessarily re-clarified | interpret the auth restriction as applying to code/settings, while using the documented normal pairing flow.
