# Proof audit, pass 1 — Custom snooze width

## Findings

1. **No visual proof exists yet.** The supplied overflow observation is lead-reported, not independently captured in this pass. The source change is exactly `DialogPopup className="sm:max-w-sm"` → `"sm:max-w-md"`; no behavioral changes or additional changed files were found. Source inspection cannot establish that the footer now fits.
2. **The same footer appears in both modes.** Capture Date and time and Duration with DejaVu Sans Mono. A default-font-only screenshot would miss the reported defect. Include the icon, entire ghost button, both action buttons, and the popup borders in every keyframe.
3. **The breakpoint is material.** At `sm` and above, the footer is a nonwrapping row of shrink-0 buttons and the fields use two columns. Below it, the popup is a full-width bottom sheet with a reversed vertical footer and single-column fields. Only the former receives the changed max-width.
4. **Interface size scales root rems.** At size 16, the intended width limit changes from 24rem/384px to 28rem/448px. At size 20, it changes from 480px to 560px, subject to viewport constraints. Size alone does not reproduce the intrinsic font-width mismatch at an unconstrained viewport. The 640px / 20px boundary checks available space and vertical clipping instead.
5. **No caller-specific dialog layout exists.** Four request call sites converge on the root host and pass no title, selection count, preset list, thread, provider, or environment data into the dialog. They need a reachability inventory, not a Cartesian screenshot matrix.

## Scope and evidence provenance

Issue: [#33740](https://git.cafe/pingdotgg/t3code/issues/33740) ([GitHub mirror #33740](https://github.com/pingdotgg/t3code/issues/33740)). PR has not been opened.

Read-only worktree: `/home/user/wt/issue-33740`, branch `fix/issue-33740`, clean working tree when inspected. Compared the specified base [4c361199f4](https://github.com/pingdotgg/t3code/commit/4c361199f47f6ea32a2c14835df392640d0f7c63) to local head [b5b9a154b4](https://github.com/pingdotgg/t3code/commit/b5b9a154b43e0fc72e821d41df26de314f585f24), using those revisions directly, not local main. Commit links identify the revisions; remote availability of the local head was not checked.

No app/browser was driven, tests run, server started, repository file modified, push made, or forge comment posted. This is a source-derived capture brief, not a capture report. All written artifacts are under `/tmp/issue-lead-33740-r1/proof-audit-1/`. Free space was 109 GB at the initial check. Public attribution, if needed: AI-assisted; verified with the tests and tools listed above.

## Render paths and input-space collapse

Source locations below refer to the inspected local head.

| Path | Conditions and real-app entry | Dialog layout result / collapse |
| --- | --- | --- |
| `routes/__root.tsx:193` → `CustomSnoozeDialogHost` | Mounted with authenticated/hosted app hosts; no pending request renders null. A request mounts the no-props dialog. Host unmount resolves null. | One host for web and desktop. No separate settings dialog instance. Absent state is F16. |
| `hooks/useThreadActionMenu.ts:169`, called by `components/chat/ChatHeader.tsx:199` | Open a persisted thread; breadcrumb button `Thread actions for <title>` → Snooze → Custom…. Requires available thread/config, snooze capability and operate permission. | Primary capture route. Title, path, share/find flags and runtime do not enter the dialog. |
| `components/sidebar/SidebarThreadRow.tsx:422` (`SnoozeMenuButton`) | Hover an eligible sidebar row → `Snooze thread` clock button → Custom…. Button requires operate permission, snooze support and `canSnooze`. | Same F01/F02; preset count changes only the menu outside the dialog. |
| `components/Sidebar.tsx:2667` | Right-click one sidebar thread → Snooze → Custom…. Unsupported/permission-gated cases prevent reaching this path. | Same F01/F02. Native Electron menu vs web fallback changes the launcher, not the popup. |
| `components/Sidebar.tsx:2396` | Select two eligible persisted sidebar threads with Ctrl-click on Linux / Cmd-click on macOS, right-click a selected row → Snooze (2) → Custom…. All selected threads must support snoozing and operations. | Same F01/F02, including plural selection: dialog always says “snoozed threads” and receives no count. Create a second stopped thread through normal UI only if checking this launcher. Not needed for minimum width captures. |
| No other request callers | Repository search for `requestCustomSnooze` and `CustomSnoozeDialogHost`. | No direct command-palette, keybinding, Settings, RPC or MCP entry to this dialog found. Settings is its outgoing navigation target, not another caller. |

`CustomSnoozeDialog.tsx:65–263` has no external props. Layout inputs are mode (`date` initially), date/time (initially now + 1h), calendar open state, amount (`"2"` initially), unit (`hours` initially), error (null initially), interface font family/size, viewport and theme. Fixed strings and icons do not vary with data. There are no list counts, loading spinners, async submit/disabled states, or server error branches inside this dialog. RPC failure toasts occur after it has closed and are unchanged.

- **Date mode:** locale-formatted month/day/year date button, calendar icon, and native required time input. Calendar is single-select/required, with dates before local today disabled, selected date/default month from state. Selecting a day closes it and clears errors. Locale and date/month lengths change text; calendar months can have different week counts. F05 uses a six-row month and a two-digit day. Fix browser locale to en-US and timezone to UTC for paired comparisons; retain the actual selected values in metadata. Calendar locale/week-start details derive from `timestampFormat.ts` / the browser, not thread presets.
- **Duration mode:** required number input, min 0, arbitrary step, decrement/increment; units Minutes/Hours/Days. Zero reaches the custom error; empty required values can be stopped by native validation first. Minutes is the longest fixed unit label; digit length stays within a min-w-0 number input. F02 exercises numeric controls, F06 the menu; F14 inventories empty input without adding a mandatory typography test.
- **Errors:** submitting a complete past date/time adds “Choose a valid date and time in the future.”; zero duration adds “Enter a positive duration.”. These have distinct wrapping/height, F03/F04. Switching mode, choosing a date, editing time, changing amount or unit clears errors. No special error state is passed from any caller.
- **Clock:** `useNowMinute` updates the calendar's minimum day across local midnight; no visible countdown or pending state exists. F15 lists a controlled-clock recording, outside the minimum set for a max-width-only fix.
- **Theme:** inherited dialog glass/border/footer/button tokens differ in light/dark, while the changed component has no theme branch. Distribute light and dark across sessions instead of multiplying every row by theme. Custom theme enumeration is not required for this geometry change.
- **Width/height:** `ui/dialog.tsx` uses 1rem viewport padding at sm+, a centered full-width popup, max height, and a scroll-area panel. At max-sm it removes side padding, adds top clearance, removes side/bottom borders, and makes a bottom sheet. `DialogFooter` is `flex-col-reverse` with `sm:flex-row sm:justify-end`; the Edit button adds `sm:mr-auto`. Buttons are `shrink-0 whitespace-nowrap` with icon gap/padding. At size 16, sm is the normal 640 CSS px media-query boundary. See F09–F12.
- **Platform/connection:** desktop wraps this same web component. Desktop's launcher can be native, and `type=time` is browser/OS native, but no Electron-specific popup layout branch exists. A narrow web viewport is a mobile-web fixture, not a native mobile app capture. Native mobile uses separate `CustomSnoozeSheet` / Android implementation and is unaffected. Local, hosted, remote, relay and tunnel connections, all providers and snoozed/unsnoozed source threads resolve to the same popup once opened. No extra provider turns, native simulator or remote environment fixtures are required.
- **Lifecycle/interactions:** open, Date↔Duration toggle, calendar open/close and previous/next month/selection, time edit/native validation, amount typing and +/- / arrow-key controls, unit open/select, invalid submit, correction/error clear, valid submit, Cancel, Close X, Escape, backdrop dismissal, Edit snooze options navigation and reopen. They are sequenced in the recordings below; they do not each need an additional layout row. Cancellation and Edit resolve null, valid submit resolves a future ISO string, and reopening starts a fresh Date state. Replacing a pending request / unmount also resolves null; neither adds a distinct visible width layout or warrants a harness here.

## Common seed and capture protocol

The capturer should use the lead's isolated app state and dev server. Do not start a second server as this review sub-agent, touch live userdata, or change the reviewed worktree for evidence. The brief says the isolated fresh database already has project `server` and a persisted `New thread`; this is sufficient. Wait for config to load, select that thread, and use the breadcrumb entry above. No real provider turn or customer data is needed. Settings → Appearance controls Interface font, its size select (12–20, default 16), and theme. Return to the thread after each setting change. Reset font to the default value to obtain the normal Linux stack (Inter Variable expected; verify the font actually used).

All F01–F15 rows are **recording**: their state requires interaction or controlled time. Stills alone do not satisfy those rows. For this visual bug also export matched before/after still keyframes at the settled states. Pair the specified base and head with identical viewport, device scale, browser, browser zoom 100%, locale/timezone, font family and interface size. Do not fake the base by changing CSS in devtools. Let the lead provide the two revision builds without editing this worktree. Do not crop away popup borders, title, footer or relevant overlays.

A screenshot with “DejaVu Sans Mono” selected but a fallback font rendered is not proof: verify installation and actual rendered/computed font, record root font size and popup/button DOM rectangles. The lead-reported base values at 1280×800 are popup left 448px and Edit button left 438px (10px protrusion); treat those as reproduction clues, not audited measurements. Check all three footer button rectangles, their labels/icons, left/right popup borders, and viewport horizontal overflow. At 16px the new popup limit should be 448px, but the actual measured layout is authoritative.

## Fixture matrix

Status **MISSING / required** means no capture exists and the row belongs to the minimum set. **Scoped out / unchanged** means inventoried behavior without an additional mandatory capture for this one-class fix. “Indirect” means the popup width changes the layout available to the row, while its logic/overlay CSS is untouched.

| ID / named fixture | Required data and exact real-app seed / drive | Diff affects? | Minimum viewport × theme × typography | Evidence / status |
| --- | --- | --- | --- | --- |
| F01 — wide-font date, clean | One eligible persisted thread. Set Interface font DejaVu Sans Mono, size 16; open Custom…. Keep the valid initial date/time, calendar closed. | Yes, popup/row/footer width | 1280×800 × dark × Mono 16 | recording A + paired keyframes; MISSING / required |
| F02 — wide-font duration, clean | From F01 click Duration; amount 2, Hours. Exercise +/- and restore 2. | Yes, same footer and two-column body | 1280×800 × dark × Mono 16 | recording A + paired keyframes; MISSING / required |
| F03 — wide-font date error | Date mode, choose today and a complete earlier UTC time (e.g. 00:00 when already past it); submit. If currently at midnight, advance the browser clock or choose a later test start. Both required fields must be complete to bypass native empty validation. | Indirect, long alert wrapping/height | 1280×800 × dark × Mono 16 | recording A, show error then edit time to clear; paired error keyframes; MISSING / required |
| F04 — wide-font duration error | Duration mode, set amount 0 and submit; expect “Enter a positive duration.”. Correct to 2 or change unit to clear. | Indirect, shorter alert wrapping/height | 1280×800 × dark × Mono 16 | recording A + paired error keyframes; MISSING / required |
| F05 — wide-font calendar open | Date mode; open date button. Navigate to January 2027 (six calendar rows with Sunday week start), select Jan 31, reopen; use another future six-row month if capturing after Jan 2027. Show disabled past days in the current month before navigating. Set time 15:30 after selection if needed. | Indirect, moved/resized anchor; calendar width itself unchanged | 1280×800 × dark × Mono 16, en-US / UTC | recording A, include open overlay and selection/close; paired open keyframes; MISSING / required |
| F06 — wide-font unit menu open | Duration mode, amount 2, open Unit; show all Minutes/Hours/Days, select Minutes (longest fixed label), then Days. | Indirect, wider anchor/trigger and portal positioning | 1280×800 × dark × Mono 16 | recording A + paired open-menu and selected-Minutes keyframes; MISSING / required |
| F07 — default-font date | Reset Interface font to default, size 16; open Date and time with complete future values. | Yes, intended wider popup must still look coherent | 1280×800 × light × default 16 | recording B + paired keyframes; MISSING / required |
| F08 — default-font duration | From F07 select Duration, amount 2 Hours. | Yes, normal-font second body layout | 1280×800 × light × default 16 | recording B + paired keyframes; MISSING / required |
| F09 — desktop breakpoint date at maximum size | Set Mono 20; viewport exactly 640×600; open Date and time. Include clean state, then F03 error as an extra keyframe in the same run; inspect panel scrolling if constrained. | Yes, sm row/two columns and 560px new cap near viewport/height constraints | 640×600 × dark × Mono 20 | recording C + paired clean/error keyframes; MISSING / required |
| F10 — desktop breakpoint duration at maximum size | Same viewport/settings, select Duration; 2 Minutes. Include F04 zero error then correction in same run. | Yes, same horizontal footer with different controls | 640×600 × dark × Mono 20 | recording C + paired clean/error keyframes; MISSING / required |
| F11 — bottom-sheet date | Set Mono 16; open Date and time in narrow web viewport. Record 390×844 then resize to 639×844 while keeping dialog open. Expect full width, one-column date/time and stacked footer (Snooze, Cancel, Edit visually top-to-bottom). | No below sm; responsive regression guard | 390×844 and 639×844 × light × Mono 16 | recording D + paired keyframes at both widths; MISSING / required |
| F12 — bottom-sheet duration | Same as F11; switch Duration, amount 2 Minutes at each viewport. Check labels/number controls/footer fit. | No below sm; second sheet body | 390×844 and 639×844 × light × Mono 16 | recording D + paired keyframes at both widths; MISSING / required |
| F13 — empty native time | Date mode, clear required time and attempt submit. Browser-native validity UI may appear; custom alert should not be assumed. | Native validation unchanged; surrounding popup wider at sm+ | Optional 1280×800 × dark × Mono 16 | recording if collected; Scoped out / unchanged, real app reachable |
| F14 — empty native duration | Duration mode, clear required number and attempt submit; type a long numeric value, then restore 2. Required/native validity and field scrolling are distinct from zero custom error. | Native validation/input behavior unchanged | Optional 1280×800 × dark × Mono 16 | recording if collected; Scoped out / unchanged, real app reachable |
| F15 — midnight rollover calendar | Browser-driver clock installed before app load at local 23:59 in isolated context, open current-month calendar, advance clock/timers through 00:00. Yesterday becomes disabled; do not change the host clock or wait overnight. This can run against the real app with controlled browser time; if that driver is unavailable, only a clearly labelled clock harness can substitute, not a claimed integrated capture. | Clock logic and calendar dimensions unchanged | Optional 1280×800 × dark × Mono 16 | recording, controlled time mandatory; Scoped out / unchanged |
| F16 — no request / dismissed | Before launcher or after Cancel, X, Escape, backdrop click, valid submit, Edit settings navigation, or host unmount: request absent, no popup. | No rendered popup to receive changed width | Covered as endpoints of A–D, no standalone still | recording endpoints; Scoped out / no standalone capture |

## Minimum capture sessions and acceptance

Four matched before/after recording sessions (eight clips total), with the keyframes listed above; they are not twelve separate app seeds. Keep each run in a new timestamped evidence directory owned by the capturer. Record exact revision and settings beside clips. A single long recording may contain multiple labelled viewport/theme segments if they remain unambiguous; retain the per-row mapping.

| Session | Exact viewport × theme | Required rows | Interaction coverage that can share the session |
| --- | --- | --- | --- |
| A | 1280×800 × dark, Mono 16 | F01–F06 | Launch through breadcrumb; switch tabs both ways; calendar open/navigation/select/close; time edit; amount typing/+/-; unit menu/select; both invalid submissions and error clearing. Finish with valid duration submit, observe dialog close and the thread snoozed, then unsnooze through the normal UI so it is reusable. Do not wait for actual scheduled wakeup. |
| B | 1280×800 × light, default 16 | F07–F08 | Show both modes; Edit snooze options → `/settings/threads#snooze-options`, demonstrate correct destination and no snooze, then return and reopen. The fragment may scroll; keep navigation on recording. |
| C | 640×600 × dark, Mono 20 | F09–F10 | Both bodies/alerts fit within popup and viewport, footer remains reachable. Use keyboard focus traversal; Enter submits a valid future date, then unsnooze/reopen as needed. End a separate reopen with Escape. |
| D | 390×844 then 639×844 × light, Mono 16 | F11–F12 at each width | Record responsive layout while resizing and switching modes. Cancel, X and backdrop dismissal can be exercised across reopens in this session; each reopen resets to Date. |

All four caller launchers are source-traced equivalents. The minimum records the reproducible breadcrumb entry; optionally use sidebar clock or single/bulk context menu on a later reopen, without adding another copy of the matrix. No native Electron or native mobile capture is required by this diff.

Acceptance: at both affected modes the entire Edit button/icon/label and both action buttons stay inside the popup borders without overlap or clipping, and the body, header and errors remain readable. The base must visibly reproduce the wide-font overflow before claiming the before/after fixes this issue. The head must eliminate it under F01/F02, retain coherent normal-font layout, fit at the sm boundary, and preserve the unchanged bottom sheet. Do not call the proof sufficient on metadata or DOM rectangles alone; inspect the actual clips/keyframes. F13–F15 do not block this width-only proof unless capture reveals a related regression or scope expands. No captures were reviewed in pass 1.

FRICTION: none

VERDICT: INSUFFICIENT F01–F12 to capture (sessions A–D, matched base/head recordings and keyframes)
