# Floating preview resize evidence

For [#22999](https://github.com/pingdotgg/t3code/pull/22999), GitCafe [#23002](https://git.cafe/pingdotgg/t3code/pulls/23002). Compared before [680152e27b](https://github.com/pingdotgg/t3code/commit/680152e27b2a961686389ca69a1557cbb2c55f08) with after [db94329f89](https://github.com/pingdotgg/t3code/commit/db94329f8965c9893796d82bb78a92c93764ef5f). Both worktrees are clean; only the four PR files differ. No PR body, comment, push or forge mutation was made.

[Approved capture matrix](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/d062c0e98b079ed9/pr-22999-matrix-final.md): eight recording pairs + one static pair. All nine rows captured.

## Seed and input protocol

Each revision runs its own `vp run dev` server against its worktree `.t3`. Seeds were byte-identical (SHA256 `73e25323f88ca30a81ddf29ee4a11745dd63a44d1fde7c41ef97695fd8e181c7`) before startup; each client then created an empty local New thread. No provider turn ran. A local static page at loopback port 18555 is open in a real server Browser tab, floated over chat with the details card open on desktop and the main sidebar closed. Source viewport starts at 1280×800; floating frame is 320×200 at (900,412) desktop, 260×163 at (60,332) narrow. The narrow client is responsive web with mouse input.

R1/R2/R7/R8 use native `preview_drag` from the real resize handle to a temporary invisible target 20px outward (NW: −20,−12; E: +20,0), staying above the minimum size, followed by injected buttonless motion. R3–R6 start a native drag on the real handle and confirm native pointer capture is true. A temporary invisible release target delays native release while the scripted PointerEvents run. Native capture methods are never replaced. R3 injects window blur, then further held-button moves (buttons=1) so the blur handler is isolated; R4 injects buttons=0 without a release. R5/R6 request a supported source viewport change to 1280×960 immediately after native pointerdown, before moving. These prove deterministic lifecycle/source-update behavior, not physical OS outside-window release. After final rest, an injected cleanup pointerup ends the old baseline gesture before the native automation releases; that cleanup is not a second resize.

Narration times below are decoded MP4 presentation timestamps from clip start, specifically the first decoded frame showing each phase label. The smaller burned timestamps are browser script-clock values and differ because stream/encoding delivery is delayed. Do not use the burned clock as video seek time. All clips begin with their own Rest label. Sparse variable-frame-rate capture establishes sampled displacement and termination, not high-frame-rate smoothness. The annotation only reports steps; it never changes player geometry. Geometry below is measured from the mounted section. Source resizing intentionally changes displayed aspect ratio in both revisions. R5/R6 do not satisfy the matrix’s frozen rendered-ratio expectation: they record a limitation rather than prove a fix for it.

## Rows

| Row | Evidence |
| --- | --- |
| [R1 — NW normal — 1440×900 / light](#r1) | Before/after recordings |
| [R2 — E normal — 1440×900 / dark](#r2) | Before/after recordings |
| [R3 — NW blur + missing release — 1440×900 / dark](#r3) | Before/after recordings |
| [R4 — E missing release — 390×844 / light](#r4) | Before/after recordings |
| [R5 — NW source sizing transition — 1440×900 / light](#r5) | Before/after recordings |
| [R6 — E source sizing transition — 390×844 / dark](#r6) | Before/after recordings |
| [R7 — NW normal — 390×844 / dark](#r7) | Before/after recordings |
| [R8 — E normal — 390×844 / light](#r8) | Before/after recordings |
| [S1 — Resting frame — 1440×900 / light](#s1) | Static pair + two diff images |

<a id="r1"></a>
## R1 — NW normal — 1440×900 / light

**Script and timestamps (before / after):**

- **Before:** 0.000s Rest → 1.896s Native NW grow -20,-12 → 2.515s Released; buttonless motion → 3.637s Final rest.
- **After:** 0.000s Rest → 2.187s Native NW grow -20,-12 → 3.279s Released; buttonless motion → 4.186s Final rest.

| Before | After |
| --- | --- |
| [R1-before.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/585d136a1f6eaa53/R1-before.mp4) | [R1-after.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b60761928ab34c30/R1-after.mp4) |
| [680152e27b](https://github.com/pingdotgg/t3code/commit/680152e27b2a961686389ca69a1557cbb2c55f08) | [db94329f89](https://github.com/pingdotgg/t3code/commit/db94329f8965c9893796d82bb78a92c93764ef5f) |

**Before result:** (900,412) 320×200 → (880,400) 340×213. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 1440×900, light; UTC 2026-10-21T20:33:16.760Z. MP4 raster 2880×1800.
**After result:** (900,412) 320×200 → (880,400) 340×213. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 1440×900, light; UTC 2026-10-21T20:33:10.801Z. MP4 raster 2880×1800.

**Comparison:** both revisions retain the expected normal-release behavior for this sample; no new regression is claimed.

<a id="r2"></a>
## R2 — E normal — 1440×900 / dark

**Script and timestamps (before / after):**

- **Before:** 0.000s Rest → 1.614s Native E grow +20,0 → 2.149s Released; buttonless motion → 3.347s Final rest.
- **After:** 0.000s Rest → 1.701s Native E grow +20,0 → 2.237s Released; buttonless motion → 3.410s Final rest.

| Before | After |
| --- | --- |
| [R2-before.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/89974fac9c13ea07/R2-before.mp4) | [R2-after.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/70b6765e7c82cd57/R2-after.mp4) |
| [680152e27b](https://github.com/pingdotgg/t3code/commit/680152e27b2a961686389ca69a1557cbb2c55f08) | [db94329f89](https://github.com/pingdotgg/t3code/commit/db94329f8965c9893796d82bb78a92c93764ef5f) |

**Before result:** (900,412) 320×200 → (900,412) 340×213. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 1440×900, dark; UTC 2026-10-21T20:33:28.471Z. MP4 raster 2880×1800.
**After result:** (900,412) 320×200 → (900,412) 340×213. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 1440×900, dark; UTC 2026-10-21T20:33:22.754Z. MP4 raster 2880×1800.

**Comparison:** both revisions retain the expected normal-release behavior for this sample; no new regression is claimed.

<a id="r3"></a>
## R3 — NW blur + missing release — 1440×900 / dark

**Script and timestamps (before / after):**

- **Before:** 0.000s Rest → 1.244s Native pointerdown; capture=true → 2.123s Injected held move -30,-30 → 3.221s Injected blur; native button still held → 3.990s After blur: held buttons=1 move -120,-120; capture=true → 5.707s Final rest.
- **After:** 0.000s Rest → 1.203s Native pointerdown; capture=true → 2.092s Injected held move -30,-30 → 3.259s Injected blur; native button still held → 4.083s After blur: held buttons=1 move -120,-120; capture=false → 5.723s Final rest.

| Before | After |
| --- | --- |
| [R3-before.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a4fe88a44daf7879/R3-before.mp4) | [R3-after.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/8bf8ccfe0acb41f4/R3-after.mp4) |
| [680152e27b](https://github.com/pingdotgg/t3code/commit/680152e27b2a961686389ca69a1557cbb2c55f08) | [db94329f89](https://github.com/pingdotgg/t3code/commit/db94329f8965c9893796d82bb78a92c93764ef5f) |

**Before result:** (900,412) 320×200 → (760,324) 460×288. Native capture confirmed true. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 1440×900, dark; UTC 2026-10-21T20:37:47.026Z. MP4 raster 2880×1800.
**After result:** (900,412) 320×200 → (865,390) 355×222. Native capture confirmed true. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 1440×900, dark; UTC 2026-10-21T20:37:55.903Z. MP4 raster 2880×1800.

**Change visible:** before retains capture after blur and keeps resizing on held buttons=1 movement to 460×288; after capture is false after blur and stays 355×222. Post-native-release geometry is unchanged in both.

<a id="r4"></a>
## R4 — E missing release — 390×844 / light

**Script and timestamps (before / after):**

- **Before:** 0.000s Rest → 0.593s Native pointerdown; capture=true → 1.495s Injected held E move +20,0 → 2.377s Omit release; injected buttons=0 move +60 → 4.091s Final rest.
- **After:** 0.000s Rest → 0.519s Native pointerdown; capture=true → 1.415s Injected held E move +20,0 → 2.276s Omit release; injected buttons=0 move +60 → 3.831s Final rest.

| Before | After |
| --- | --- |
| [R4-before.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/69934e497a472f76/R4-before.mp4) | [R4-after.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/ce4d6a6956961ffc/R4-after.mp4) |
| [680152e27b](https://github.com/pingdotgg/t3code/commit/680152e27b2a961686389ca69a1557cbb2c55f08) | [db94329f89](https://github.com/pingdotgg/t3code/commit/db94329f8965c9893796d82bb78a92c93764ef5f) |

**Before result:** (60,332) 260×163 → (60,332) 318×199. Native capture confirmed true. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 390×844, light; UTC 2026-10-21T20:34:33.106Z. MP4 raster 780×1688.
**After result:** (60,332) 260×163 → (60,332) 280×175. Native capture confirmed true. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 390×844, light; UTC 2026-10-21T20:34:26.597Z. MP4 raster 780×1688.

**Change visible:** before grows to 318×199 after the missing release; after stays 280×175.

<a id="r5"></a>
## R5 — NW source sizing transition — 1440×900 / light

**Script and timestamps (before / after):**

- **Before:** 0.000s Rest → 0.963s Native capture=true; source 1280x800 -> 1280x960 → 1.772s Injected held NW move -30,-30 → 2.914s Injected pointerup → 3.512s Injected buttonless motion → 4.711s Final rest.
- **After:** 0.000s Rest → 1.109s Native capture=true; source 1280x800 -> 1280x960 → 1.922s Injected held NW move -30,-30 → 3.068s Injected pointerup → 3.629s Injected buttonless motion → 4.838s Final rest.

| Before | After |
| --- | --- |
| [R5-before.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f617704ed37e8e29/R5-before.mp4) | [R5-after.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/6678e476ea603ce1/R5-after.mp4) |
| [680152e27b](https://github.com/pingdotgg/t3code/commit/680152e27b2a961686389ca69a1557cbb2c55f08) | [db94329f89](https://github.com/pingdotgg/t3code/commit/db94329f8965c9893796d82bb78a92c93764ef5f) |

**Before result:** (900,412) 320×200 → (886,361) 334×251. Native capture confirmed true. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 1440×900, light; UTC 2026-10-21T20:34:47.793Z. MP4 raster 2880×1800.
**After result:** (900,412) 320×200 → (865,390) 355×266. Native capture confirmed true. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 1440×900, light; UTC 2026-10-21T20:34:40.335Z. MP4 raster 2880×1800.

**Observed limitation / maintainer finding:** before ends (886,361), 334×251, bottom=612; after ends (865,390), 355×266, bottom=656. The opposite bottom edge therefore drifts 44px after. Rendered aspect ratio changes from 1.6 to about 1.335; the matrix’s stable rendered-ratio expectation is NOT met. The controller freezes the movement baseline while the shell follows the live source ratio. This is evidence of a possible regression, not a passing transition claim. The frame remains reachable in this sample; near-bottom overflow was not tested.

<a id="r6"></a>
## R6 — E source sizing transition — 390×844 / dark

**Script and timestamps (before / after):**

- **Before:** 0.000s Rest → 0.559s Native capture=true; source 1280x800 -> 1280x960 → 1.368s Injected held E move +20,0 → 2.275s Injected pointerup → 2.828s Injected buttonless motion → 4.051s Final rest.
- **After:** 0.000s Rest → 0.700s Native capture=true; source 1280x800 -> 1280x960 → 1.523s Injected held E move +20,0 → 2.380s Injected pointerup → 3.007s Injected buttonless motion → 4.213s Final rest.

| Before | After |
| --- | --- |
| [R6-before.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/dd60322168fc607e/R6-before.mp4) | [R6-after.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/5f2c3d02b32ae986/R6-after.mp4) |
| [680152e27b](https://github.com/pingdotgg/t3code/commit/680152e27b2a961686389ca69a1557cbb2c55f08) | [db94329f89](https://github.com/pingdotgg/t3code/commit/db94329f8965c9893796d82bb78a92c93764ef5f) |

**Before result:** (60,332) 260×163 → (60,332) 280×210. Native capture confirmed true. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 390×844, dark; UTC 2026-10-21T20:35:02.468Z. MP4 raster 780×1688.
**After result:** (60,332) 260×163 → (60,332) 280×210. Native capture confirmed true. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 390×844, dark; UTC 2026-10-21T20:34:55.299Z. MP4 raster 780×1688.

**Observed limitation:** both end 280×210 after source sizing; rendered ratio changes from about 1.595 to 1.333. Normal release stops resizing, but frozen rendered ratio is not demonstrated.

<a id="r7"></a>
## R7 — NW normal — 390×844 / dark

**Script and timestamps (before / after):**

- **Before:** 0.000s Rest → 1.225s Native NW grow -20,-12 → 1.683s Released; buttonless motion → 2.897s Final rest.
- **After:** 0.000s Rest → 1.230s Native NW grow -20,-12 → 1.664s Released; buttonless motion → 2.894s Final rest.

| Before | After |
| --- | --- |
| [R7-before.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f90dc3462cece06c/R7-before.mp4) | [R7-after.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/c30163cd5d56c966/R7-after.mp4) |
| [680152e27b](https://github.com/pingdotgg/t3code/commit/680152e27b2a961686389ca69a1557cbb2c55f08) | [db94329f89](https://github.com/pingdotgg/t3code/commit/db94329f8965c9893796d82bb78a92c93764ef5f) |

**Before result:** (60,332) 260×163 → (40,320) 280×175. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 390×844, dark; UTC 2026-10-21T20:33:39.056Z. MP4 raster 780×1688.
**After result:** (60,332) 260×163 → (40,320) 280×175. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 390×844, dark; UTC 2026-10-21T20:33:33.793Z. MP4 raster 780×1688.

**Comparison:** both revisions retain the expected normal-release behavior for this sample; no new regression is claimed.

<a id="r8"></a>
## R8 — E normal — 390×844 / light

**Script and timestamps (before / after):**

- **Before:** 0.000s Rest → 1.236s Native E grow +20,0 → 1.682s Released; buttonless motion → 2.885s Final rest.
- **After:** 0.000s Rest → 1.249s Native E grow +20,0 → 1.708s Released; buttonless motion → 2.930s Final rest.

| Before | After |
| --- | --- |
| [R8-before.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/88c73dfc2655d343/R8-before.mp4) | [R8-after.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/5970a3e7bd9c8812/R8-after.mp4) |
| [680152e27b](https://github.com/pingdotgg/t3code/commit/680152e27b2a961686389ca69a1557cbb2c55f08) | [db94329f89](https://github.com/pingdotgg/t3code/commit/db94329f8965c9893796d82bb78a92c93764ef5f) |

**Before result:** (60,332) 260×163 → (60,332) 280×175. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 390×844, light; UTC 2026-10-21T20:33:49.305Z. MP4 raster 780×1688.
**After result:** (60,332) 260×163 → (60,332) 280×175. Environment: Chromium 154 / Linux x86_64, DPR 2, loaded system UI sans-serif; CSS viewport 390×844, light; UTC 2026-10-21T20:33:44.129Z. MP4 raster 780×1688.

**Comparison:** both revisions retain the expected normal-release behavior for this sample; no new regression is claimed.

<a id="s1"></a>
## S1 — Resting frame — 1440×900 / light

No interaction: same resting frame, source and client layout. Whole 1440×900 CSS surface; Browser snapshot exports a downsampled 1280×800 PNG (not a crop).

| Before | After |
| --- | --- |
| ![S1-before.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/eb4c9465859b4189/S1-before.png) | ![S1-after.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/916d41a9d18018fb/S1-after.png) |
| [680152e27b](https://github.com/pingdotgg/t3code/commit/680152e27b2a961686389ca69a1557cbb2c55f08) | [db94329f89](https://github.com/pingdotgg/t3code/commit/db94329f8965c9893796d82bb78a92c93764ef5f) |

Before environment: Chromium 154 / Linux x86_64; DPR 2; loaded system UI sans-serif; CSS 1440×900/light; UTC 2026-10-21T20:21:56.281Z; frame (900,412) 320×200.
After environment: Chromium 154 / Linux x86_64; DPR 2; loaded system UI sans-serif; CSS 1440×900/light; UTC 2026-10-21T20:21:54.271Z; frame (900,412) 320×200.

Unmasked RGB absolute diff at PNG resolution: 10,760/1,024,000 pixels nonzero (1.0508%); 962 pixels have maximum channel delta >16 (0.0939%); maximum channel delta 71/255; mean absolute channel delta 0.04269922/255. Differences are in the streamed fixture's text/grid raster, not outer frame geometry. No masks, alignment shifts or pixel suppression.

Zero threshold, absolute RGB delta amplified ×8 (clipped at 255):

![S1-diff-zero-amplified8.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a2441c7c38b9403b/S1-diff-zero-amplified8.png)

Stated threshold: max(|ΔR|,|ΔG|,|ΔB|) >16/255, changed pixels magenta on white:

![S1-diff-threshold16.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/d6ab50daf95898f5/S1-diff-threshold16.png)

[static-diff.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/141892f35f373891/static-diff.json)

## Audit response and status

The [first proof audit](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b516fcde00d38904/pr-22999-proof-audit-pass2.md) rejected six rows in the superseded index. This index replaces all sixteen clips, uses short above-minimum native drags, isolates blur with buttons=1, logs capture after blur, includes all per-capture environment/drag/post-release records, begins with clean labels, and uses decoded video PTS. R5’s corner drift is explicitly retained as an adverse finding. Evidence completeness does not imply all behavioral expectations passed. Static files are unchanged and were independently recomputed exactly by that audit.

## What else changed

- The PR extracts pointer lifecycle/geometry into `previewMiniPlayerGesture.ts`, wires blur/lost-capture termination into the shared MiniPlayerShell, adds focused controller tests, and makes the empty-obstacles constant module-private.
- No styles, placement policy, composer/details-card insets, transport, contracts, providers or backend behavior changed in this diff.
- Visible fixture differences: per-revision stream text/grid antialiasing/compression, and annotation text/timing. Independent local thread/environment/tab IDs differ. Normal-release samples have matching final geometry; source-resize samples deliberately change the source ratio.
- The source fixture is synthetic public test content; the selected thread is empty. Nothing here proves populated-history rendering.

## Metadata

[Capture metadata](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b073e26f2246db3d/capture-metadata-final.json) includes script-clock logs, native capture state, environment and post-release geometry.

## Explicit out of scope

Other handle/termination/theme/viewport combinations, drag/pill taps, pointercancel/lostcapture as separate samples, secondary pointers and reopen actions are excluded because the shared controller is sampled within eight pairs. Physical outside-window release and touch require OS/native input evidence; injection does not establish them. Native Electron surfaces, device/PDF streams and native mobile need separate assets/environments and their backing renderers are unchanged. Provider, relay/tunnel, multi-environment and backend behavior are unchanged by this local gesture diff. Exhaustive performance testing is outside this evidence task.

Capture: Codex gpt-6.1-sol; proof audit: Claude Opus 5.5
