CHROME: title collapse only on phone document pages (never desktop/Calendar); desktop overlays instead of sheets #244

Closed
opened 2026-09-27 16:44:28 +00:00 by kayg · 12 comments
Owner

Owner grill (2026-09-27). Two chrome rules:

1. Large-title collapse: only where it can be explained

Owner: "The problem isn't the animation inherently [it looks quite good]. It just does not fit here. I can't ever explain why the header shrinks."

  • Desktop: never collapse. The large H1 stays its size at every scroll position (the header may still gain its progressive blur when content scrolls under it).
  • Phone: collapse only on document-like pages whose content scrolls under the header: a Settings section, a Note, a Files folder list, similar long lists/documents. The #219 iOS behaviour (large title → compact header title, header follows the active section in Settings) stays there.
  • Never in Calendar (any view, any width): the date title is a control (date picker), and the time grid/month scrolls independently.
  • Implement as an explicit opt-in on ModeHeader (e.g. collapse="document"), default off; audit every ModeHeader user.

2. Desktop uses overlays, phone uses presentation sheets

Owner: "no presentation sheets on desktop please. always overlays instead of presentation sheets on desktop. presentation sheets on mobile."

  • Desktop (pointer: fine, width ≥ the phone breakpoint): every surface that is a bottom presentation sheet today becomes an overlay: an anchored popover when it belongs to a control, otherwise a centred overlay card on the shared OverlaySurface/FloatingSurface (no drag handle, no bottom anchoring).
  • Phone: presentation sheets stay (drag handle, sticky header per #219).
  • One shared primitive decides sheet vs overlay by viewport (reuse gate: no per-screen duplication). The keyboard shortcuts help is handled in #236 (tab bar morph), not here.
  • Audit list: every OverlaySurface/sheet usage; report each with before/after screenshots at 1440 and 390.

Record both rules in docs/DESIGN.md §34 (ASD-STE100) and the chrome rules.

Depends on: #219 (phone chrome, ModeHeader and sheet header) merging first.

Owner grill (2026-09-27). Two chrome rules: ## 1. Large-title collapse: only where it can be explained Owner: "The problem isn't the animation inherently [it looks quite good]. It just does not fit here. I can't ever explain why the header shrinks." - **Desktop: never collapse.** The large H1 stays its size at every scroll position (the header may still gain its progressive blur when content scrolls under it). - **Phone: collapse only on document-like pages** whose content scrolls under the header: a Settings section, a Note, a Files folder list, similar long lists/documents. The #219 iOS behaviour (large title → compact header title, header follows the active section in Settings) stays there. - **Never in Calendar** (any view, any width): the date title is a control (date picker), and the time grid/month scrolls independently. - Implement as an explicit opt-in on ModeHeader (e.g. `collapse="document"`), default off; audit every ModeHeader user. ## 2. Desktop uses overlays, phone uses presentation sheets Owner: "no presentation sheets on desktop please. always overlays instead of presentation sheets on desktop. presentation sheets on mobile." - Desktop (pointer: fine, width ≥ the phone breakpoint): every surface that is a bottom presentation sheet today becomes an overlay: an anchored popover when it belongs to a control, otherwise a centred overlay card on the shared OverlaySurface/FloatingSurface (no drag handle, no bottom anchoring). - Phone: presentation sheets stay (drag handle, sticky header per #219). - One shared primitive decides sheet vs overlay by viewport (reuse gate: no per-screen duplication). The keyboard shortcuts help is handled in #236 (tab bar morph), not here. - Audit list: every OverlaySurface/sheet usage; report each with before/after screenshots at 1440 and 390. Record both rules in docs/DESIGN.md §34 (ASD-STE100) and the chrome rules. **Depends on:** #219 (phone chrome, ModeHeader and sheet header) merging first.
Author
Owner

Owner correction (2026-09-27), supersedes rule 1 above: Phone: keep the large-title collapse on ALL pages, including Calendar ('it looks quite good!'). Desktop: never collapse ('does not fit on the desktop… yet'). So rule 1 becomes a simple viewport rule: collapse on phone widths, off on desktop. No per-page opt-in needed; keep it one switch in ModeHeader so desktop can be revisited later.

Owner correction (2026-09-27), supersedes rule 1 above: **Phone: keep the large-title collapse on ALL pages, including Calendar** ('it looks quite good!'). **Desktop: never collapse ('does not fit on the desktop… yet')**. So rule 1 becomes a simple viewport rule: collapse on phone widths, off on desktop. No per-page opt-in needed; keep it one switch in ModeHeader so desktop can be revisited later.
Author
Owner

Starting #244 on branch job/chrome-rules, based on dev at 976b804f99.

Starting #244 on branch job/chrome-rules, based on dev at 976b804f99188feb300e391c1942836599e2d429.
Author
Owner

Finding: several desktop surfaces still receive OverlaySurface variant=sheet, so they retain phone sheet structure and drag semantics. ConfirmSheet and ShareDialog add per-component wide-screen positioning CSS, while QuickLook and phone action sheets also select sheet variants directly. I will centralize the breakpoint in OverlaySurface and keep control-bound Calendar/Inspector/RangeBar surfaces on their anchored popover path.

Finding: several desktop surfaces still receive OverlaySurface variant=sheet, so they retain phone sheet structure and drag semantics. ConfirmSheet and ShareDialog add per-component wide-screen positioning CSS, while QuickLook and phone action sheets also select sheet variants directly. I will centralize the breakpoint in OverlaySurface and keep control-bound Calendar/Inspector/RangeBar surfaces on their anchored popover path.
Author
Owner

The UI audit found independent viewport checks in the Calendar preview, analytics range picker, Settings, and several overlay callers. I added a shared SurfaceViewport rule for fine-pointer viewports at least 768 px wide and routed OverlaySurface, FloatingSurface, and PopoverSurface through it. Notifications keeps its existing placement below the bell on desktop; its panel or phone sheet now comes from the shared viewport rule.

The UI audit found independent viewport checks in the Calendar preview, analytics range picker, Settings, and several overlay callers. I added a shared SurfaceViewport rule for fine-pointer viewports at least 768 px wide and routed OverlaySurface, FloatingSurface, and PopoverSurface through it. Notifications keeps its existing placement below the bell on desktop; its panel or phone sheet now comes from the shared viewport rule.
Author
Owner

Production build and the focused sheet-use audit are complete. Remaining wide-screen sheet positioning rules in ConfirmSheet, TagEditor, ShareDialog, RecoveryKeySheet, and UnsplashSheet used sheet geometry; those now receive the shared centered desktop dialog and dedicated dialog sizing. Notifications retains its bell-anchored desktop panel, Quick Look retains its desktop dashboard, and file/photo action sheets stay phone-only because desktop exposes those actions in context menus. The production after-capture is running at 1440 and 390.

Production build and the focused sheet-use audit are complete. Remaining wide-screen sheet positioning rules in ConfirmSheet, TagEditor, ShareDialog, RecoveryKeySheet, and UnsplashSheet used sheet geometry; those now receive the shared centered desktop dialog and dedicated dialog sizing. Notifications retains its bell-anchored desktop panel, Quick Look retains its desktop dashboard, and file/photo action sheets stay phone-only because desktop exposes those actions in context menus. The production after-capture is running at 1440 and 390.
Author
Owner

Delivered

  • Phone-width large titles now collapse on every page, including Calendar. One ModeHeader viewport switch controls the behavior; desktop titles remain expanded.
  • Shared SurfaceViewport picks phone sheets or desktop presentation by (min-width: 768px) and (pointer: fine). OverlaySurface, FloatingSurface, and PopoverSurface use it; desktop dialogs become centered cards and anchored surfaces remain popovers.
  • Updated DESIGN §34 and surface-specific styles. No test expectations changed.

Production screenshots

Before → after captures are attached below at 1440 and 390 px. Notifications after captures were refreshed from the merged build. Files and Photos action sheets exist only on phone; desktop uses the existing menu/context-menu interaction.

Surface 1440 px before → after 390 px before → after
Mode chrome before-chrome-shell-light-mesh-1440.png → after-chrome-shell-light-mesh-1440.png before-chrome-shell-light-mesh-390.png → after-chrome-shell-light-mesh-390.png
Calendar before-calendar-preview-light-mesh-1440.png → after-calendar-preview-light-mesh-1440.png before-calendar-preview-light-mesh-390.png → after-calendar-preview-light-mesh-390.png
Inspector before-inspector-light-mesh-1440.png → after-inspector-light-mesh-1440.png before-inspector-light-mesh-390.png → after-inspector-light-mesh-390.png
Search preview before-search-preview-light-mesh-1440.png → after-search-preview-light-mesh-1440.png before-search-preview-light-mesh-390.png → after-search-preview-light-mesh-390.png
Settings before-settings-surface-light-mesh-1440.png → after-settings-surface-light-mesh-1440.png before-settings-surface-light-mesh-390.png → after-settings-surface-light-mesh-390.png
Navigation before-navigation-surface-light-mesh-1440.png → after-navigation-surface-light-mesh-1440.png before-navigation-surface-light-mesh-390.png → after-navigation-surface-light-mesh-390.png
Keyboard shortcuts before-keyboard-shortcuts-light-mesh-1440.png → after-keyboard-shortcuts-light-mesh-1440.png before-keyboard-shortcuts-light-mesh-390.png → after-keyboard-shortcuts-light-mesh-390.png
Notifications before-notifications-light-mesh-1440.png → after-merged-notifications-light-mesh-1440.png before-notifications-light-mesh-390.png → after-merged-notifications-light-mesh-390.png
Quick Look before-quicklook-light-mesh-1440.png → after-quicklook-light-mesh-1440.png before-quicklook-light-mesh-390.png → after-quicklook-light-mesh-390.png
Range picker before-range-picker-light-mesh-1440.png → after-range-picker-light-mesh-1440.png before-range-picker-light-mesh-390.png → after-range-picker-light-mesh-390.png
AI turn panel before-turn-panel-light-mesh-1440.png → after-turn-panel-light-mesh-1440.png before-turn-panel-light-mesh-390.png → after-turn-panel-light-mesh-390.png
Recovery key before-recovery-key-light-mesh-1440.png → after-recovery-key-light-mesh-1440.png before-recovery-key-light-mesh-390.png → after-recovery-key-light-mesh-390.png
Share dialog before-share-dialog-light-mesh-1440.png → after-share-dialog-light-mesh-1440.png before-share-dialog-light-mesh-390.png → after-share-dialog-light-mesh-390.png
Tag editor before-tag-editor-light-mesh-1440.png → after-tag-editor-light-mesh-1440.png before-tag-editor-light-mesh-390.png → after-tag-editor-light-mesh-390.png
Confirmation before-confirm-sheet-light-mesh-1440.png → after-confirm-sheet-light-mesh-1440.png before-confirm-sheet-light-mesh-390.png → after-confirm-sheet-light-mesh-390.png
Photos trash confirmation before-photos-trash-confirm-light-mesh-1440.png → after-photos-trash-confirm-light-mesh-1440.png before-photos-trash-confirm-light-mesh-390.png → after-photos-trash-confirm-light-mesh-390.png
Files actions Desktop menu flow before-files-actions-light-mesh-390.png → after-files-actions-light-mesh-390.png
Photos actions Desktop menu flow before-photos-actions-light-mesh-390.png → after-photos-actions-light-mesh-390.png

The Unsplash surface could not be opened in the isolated environment because unsplash_available was false; the UI correctly hid its entry point.

Files

  • packages/ui/src/components/: ModeHeader.svelte, OverlaySurface.svelte, PopoverSurface.svelte, surfaceViewport.svelte.ts, Inspector.svelte, calendar/CalendarPopover.svelte, menu/FloatingSurface.svelte, viewer/QuickLook.svelte, and index.ts.
  • apps/web/src/lib/: ai/TurnPanel.svelte, components/ConfirmSheet.svelte, components/OverlaySurface.svelte.test.ts, components/TagEditor.svelte, components/analytics/RangeBar.svelte, components/analytics/RangePicker.svelte, files/ShareDialog.svelte, modeHeader.svelte.test.ts, and notifications/InboxPanel.svelte.
  • apps/web/src/routes/: calendar/[view]/[date]/+page.svelte, settings/[...path]/+page.svelte, settings/account/RecoveryKeySheet.svelte, and settings/appearance/UnsplashSheet.svelte.
  • docs/DESIGN.md.

Gates

  • cargo fmt --check: exit 0; no output.
  • cargo clippy --all-targets -- -D warnings: passed. Verbatim final line:
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 5m 47s
    
  • cargo test: passed; 72 suite summaries, 1,342 passed, 0 failed, 12 ignored. Verbatim suite output:
    test result: ok. 486 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.59s
    
  • bun run check: passed. Verbatim output:
    $ svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
    Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/chrome-rules/apps/web
    Getting Svelte diagnostics...
    
    svelte-check found 0 errors and 0 warnings
    
  • bun run test: passed. Verbatim summary:
     Test Files  103 passed (103)
          Tests  673 passed (673)
       Start at  04:17:51
       Duration  52.54s (transform 59%, import 15%, environment 15%, tests 7%, setup 3%)
    

The first Cargo test attempt hit a stale shared sccache temp path before the suites ran. The successful retry unset RUSTC_WRAPPER and used the required cargo environment.

Adversarial round

  • Authorization matrix: 244 OpenAPI operations, 1,079 requests; no reported authorization errors. Search storm: 0 failures. Hostile bytes: ==== HOSTILE BYTES FINDINGS 0.
  • The round reported 13 SLOW latency observations. They were load-only observations.
  • One non-SLOW finding reproduced an undo/redo editor corruption in the Notes editor from the merged dev changes: one undo/redo round-trip inserted ^q02y8b inside a heading. It is filed with evidence on #280; no expectation was changed.

Decisions and remaining gaps

  • The shared desktop query uses 768 px plus a fine pointer so touch devices retain sheets. Existing card sizing was preserved where the sheet had a distinct intent: Confirm 440 px, Recovery Key 480 px, Tag Editor 500 px, Share 580 px, Unsplash 720 px, and Turn Panel about 460 px wide / 82dvh high.
  • Files and Photos action flows remain menu/context-menu interactions on desktop and sheets on phone. The Unsplash screenshot gap is described above.

Branch

  • Merged dev once before final gates. Pushed job/chrome-rules.
  • Head: d7926f80e3f0b13c6cd31da0a05b9f88f1b6ee23.
## Delivered - Phone-width large titles now collapse on every page, including Calendar. One `ModeHeader` viewport switch controls the behavior; desktop titles remain expanded. - Shared `SurfaceViewport` picks phone sheets or desktop presentation by `(min-width: 768px) and (pointer: fine)`. `OverlaySurface`, `FloatingSurface`, and `PopoverSurface` use it; desktop dialogs become centered cards and anchored surfaces remain popovers. - Updated DESIGN §34 and surface-specific styles. No test expectations changed. ## Production screenshots Before → after captures are attached below at 1440 and 390 px. Notifications after captures were refreshed from the merged build. Files and Photos action sheets exist only on phone; desktop uses the existing menu/context-menu interaction. | Surface | 1440 px before → after | 390 px before → after | | --- | --- | --- | | Mode chrome | [before-chrome-shell-light-mesh-1440.png](https://git.kayg.org/attachments/cb39b6cd-ee13-4bb2-a0aa-568a82ec7621) → [after-chrome-shell-light-mesh-1440.png](https://git.kayg.org/attachments/c4b6ce16-0a07-4001-bbd1-c14976286c18) | [before-chrome-shell-light-mesh-390.png](https://git.kayg.org/attachments/b1c936e4-81ff-4b78-adc8-492fd3f7b930) → [after-chrome-shell-light-mesh-390.png](https://git.kayg.org/attachments/1ed1277e-43b0-4c4e-83b2-d5841a7cc55e) | | Calendar | [before-calendar-preview-light-mesh-1440.png](https://git.kayg.org/attachments/084bd33b-089e-4abd-81d9-40301cb74e77) → [after-calendar-preview-light-mesh-1440.png](https://git.kayg.org/attachments/679b5f77-d6d9-4ca4-91a8-c9da06e41e1f) | [before-calendar-preview-light-mesh-390.png](https://git.kayg.org/attachments/59a8b0ae-8e64-4d70-862f-24a4894ad724) → [after-calendar-preview-light-mesh-390.png](https://git.kayg.org/attachments/22cf21fc-2140-42da-8cbd-71b41797b66c) | | Inspector | [before-inspector-light-mesh-1440.png](https://git.kayg.org/attachments/407c2aaf-e757-4b29-bb2c-1877c2f21a86) → [after-inspector-light-mesh-1440.png](https://git.kayg.org/attachments/7ab73d12-7d0a-4dc0-a073-7b134a6305cd) | [before-inspector-light-mesh-390.png](https://git.kayg.org/attachments/8a7b0373-2e39-42d9-9224-97470feb7822) → [after-inspector-light-mesh-390.png](https://git.kayg.org/attachments/90aa3eb6-aa6d-4dbb-9fa3-dab45f4133e2) | | Search preview | [before-search-preview-light-mesh-1440.png](https://git.kayg.org/attachments/202363e0-91f8-43f4-bc32-2fa8a851b022) → [after-search-preview-light-mesh-1440.png](https://git.kayg.org/attachments/2f65536c-b6c4-4430-adfd-d31b44f82ec5) | [before-search-preview-light-mesh-390.png](https://git.kayg.org/attachments/1261a8c4-93a7-44ed-8c0e-d27f3030812d) → [after-search-preview-light-mesh-390.png](https://git.kayg.org/attachments/23b36c3c-75f5-461b-9d7d-f26741ceb42a) | | Settings | [before-settings-surface-light-mesh-1440.png](https://git.kayg.org/attachments/1518d43c-67ca-4990-a5f8-d8d39c9472d2) → [after-settings-surface-light-mesh-1440.png](https://git.kayg.org/attachments/dca4ecaf-3bb2-4f84-8c0d-34cae6b6af78) | [before-settings-surface-light-mesh-390.png](https://git.kayg.org/attachments/363e46e7-55d9-45d3-a68a-948224e2525c) → [after-settings-surface-light-mesh-390.png](https://git.kayg.org/attachments/f7141c3d-13eb-4156-b950-7da8da95e79e) | | Navigation | [before-navigation-surface-light-mesh-1440.png](https://git.kayg.org/attachments/c731b0bf-e4b8-4915-9fe2-c601eea2ebff) → [after-navigation-surface-light-mesh-1440.png](https://git.kayg.org/attachments/9cf7e132-0bf3-4812-ac20-c21f1a119a0c) | [before-navigation-surface-light-mesh-390.png](https://git.kayg.org/attachments/8abf103e-fd89-4907-8819-176ac21314a8) → [after-navigation-surface-light-mesh-390.png](https://git.kayg.org/attachments/a6328e5d-d39d-4a20-aa27-0c9eb48a9aeb) | | Keyboard shortcuts | [before-keyboard-shortcuts-light-mesh-1440.png](https://git.kayg.org/attachments/744286b1-566c-4251-9ec9-3fb343ab94ce) → [after-keyboard-shortcuts-light-mesh-1440.png](https://git.kayg.org/attachments/c1b3861e-08b2-4418-a7dc-dc01d7796918) | [before-keyboard-shortcuts-light-mesh-390.png](https://git.kayg.org/attachments/70c5dbe9-a76a-4257-ab3f-64526d870186) → [after-keyboard-shortcuts-light-mesh-390.png](https://git.kayg.org/attachments/7342bc41-59b6-4efd-9bcb-443b3c812adb) | | Notifications | [before-notifications-light-mesh-1440.png](https://git.kayg.org/attachments/2982e530-b6e8-4296-82ad-e5655e0227c5) → [after-merged-notifications-light-mesh-1440.png](https://git.kayg.org/attachments/e07c24f0-b637-43d0-90bd-294243c899a2) | [before-notifications-light-mesh-390.png](https://git.kayg.org/attachments/623bab4f-3c4c-4db5-9926-5fe1eaa31b22) → [after-merged-notifications-light-mesh-390.png](https://git.kayg.org/attachments/49ead997-0e49-46e2-afcb-fc039d5216c8) | | Quick Look | [before-quicklook-light-mesh-1440.png](https://git.kayg.org/attachments/c6603375-7549-4d40-88e0-c9abaf434300) → [after-quicklook-light-mesh-1440.png](https://git.kayg.org/attachments/7d92bc4e-c7fd-493c-80b5-e478b1450659) | [before-quicklook-light-mesh-390.png](https://git.kayg.org/attachments/3f1a1133-2d0b-4fe8-98e4-ec85f7872893) → [after-quicklook-light-mesh-390.png](https://git.kayg.org/attachments/6b07dca0-a67f-4f0b-8e0a-a75fc01f46d5) | | Range picker | [before-range-picker-light-mesh-1440.png](https://git.kayg.org/attachments/6d722f86-3151-40c4-bb90-b60f95c3bd72) → [after-range-picker-light-mesh-1440.png](https://git.kayg.org/attachments/311d8742-a7a5-4a23-9e4a-8b0300b12034) | [before-range-picker-light-mesh-390.png](https://git.kayg.org/attachments/1dd07ff7-c35c-47cd-9b77-8a3dac904b35) → [after-range-picker-light-mesh-390.png](https://git.kayg.org/attachments/b69bfb10-d022-4e99-a572-09844aa4d5a6) | | AI turn panel | [before-turn-panel-light-mesh-1440.png](https://git.kayg.org/attachments/9462d959-1cb9-4a8f-bc9f-5a259d7abde7) → [after-turn-panel-light-mesh-1440.png](https://git.kayg.org/attachments/4ed02a05-3e07-4bec-9c82-10a67e674ddf) | [before-turn-panel-light-mesh-390.png](https://git.kayg.org/attachments/2e7934e2-8f87-45d9-9f5a-201c44e95a36) → [after-turn-panel-light-mesh-390.png](https://git.kayg.org/attachments/d9e12065-199a-445b-8838-f4a4fe8a7d45) | | Recovery key | [before-recovery-key-light-mesh-1440.png](https://git.kayg.org/attachments/94857d54-62a0-46a0-91ed-0ec410c1666f) → [after-recovery-key-light-mesh-1440.png](https://git.kayg.org/attachments/ac9cc004-37f0-4fee-93a4-45e58bfb9d58) | [before-recovery-key-light-mesh-390.png](https://git.kayg.org/attachments/01d7947a-144c-4537-b197-c2daaeb6cd7e) → [after-recovery-key-light-mesh-390.png](https://git.kayg.org/attachments/8d90ee8c-79b4-4050-99a3-382b807b56a0) | | Share dialog | [before-share-dialog-light-mesh-1440.png](https://git.kayg.org/attachments/01deea80-afbd-4cfa-89d9-80b6de25ca6d) → [after-share-dialog-light-mesh-1440.png](https://git.kayg.org/attachments/33b819b4-f2e3-4027-a9c1-1929fa47c9dd) | [before-share-dialog-light-mesh-390.png](https://git.kayg.org/attachments/4a53243d-3cf7-4abb-b28d-7cca90e25075) → [after-share-dialog-light-mesh-390.png](https://git.kayg.org/attachments/d66cbbc9-da83-4b68-aac5-a64fd27ac2d3) | | Tag editor | [before-tag-editor-light-mesh-1440.png](https://git.kayg.org/attachments/36f09ab5-0cae-4333-b2fa-e8687fc3ac93) → [after-tag-editor-light-mesh-1440.png](https://git.kayg.org/attachments/9cbd8fc8-409e-4ad3-8111-c7699ece3996) | [before-tag-editor-light-mesh-390.png](https://git.kayg.org/attachments/9175fff5-4eaa-4281-abb7-d1aa2d6f04d9) → [after-tag-editor-light-mesh-390.png](https://git.kayg.org/attachments/33456abb-ad25-4deb-819f-51ba3acd63d5) | | Confirmation | [before-confirm-sheet-light-mesh-1440.png](https://git.kayg.org/attachments/bef8cbe1-84ae-4a91-ab5e-aa63e884dbc6) → [after-confirm-sheet-light-mesh-1440.png](https://git.kayg.org/attachments/4ce8a526-00c1-4ad7-befc-77e3cc28c5fa) | [before-confirm-sheet-light-mesh-390.png](https://git.kayg.org/attachments/4c3ef955-43c3-410e-881a-ade7224694c0) → [after-confirm-sheet-light-mesh-390.png](https://git.kayg.org/attachments/880215b9-ca75-4af7-b765-126dcd3f4732) | | Photos trash confirmation | [before-photos-trash-confirm-light-mesh-1440.png](https://git.kayg.org/attachments/5641f0a2-db2e-4562-bf20-3d766148b98a) → [after-photos-trash-confirm-light-mesh-1440.png](https://git.kayg.org/attachments/554305a8-7dad-40e0-95c4-b43589b510f4) | [before-photos-trash-confirm-light-mesh-390.png](https://git.kayg.org/attachments/c1cec1e5-e819-4e07-b924-263a59a9fbca) → [after-photos-trash-confirm-light-mesh-390.png](https://git.kayg.org/attachments/a5858552-186b-4fdc-83eb-da02e560deb7) | | Files actions | Desktop menu flow | [before-files-actions-light-mesh-390.png](https://git.kayg.org/attachments/03decd15-e505-499d-8305-82ace63121fa) → [after-files-actions-light-mesh-390.png](https://git.kayg.org/attachments/e61a338d-b47c-4bbd-a6d4-48756b581c32) | | Photos actions | Desktop menu flow | [before-photos-actions-light-mesh-390.png](https://git.kayg.org/attachments/641f57f3-8922-4277-a90d-c7ddc20b4b98) → [after-photos-actions-light-mesh-390.png](https://git.kayg.org/attachments/8926a07e-3c3e-46c9-ae60-e0f946231fd0) | The Unsplash surface could not be opened in the isolated environment because `unsplash_available` was false; the UI correctly hid its entry point. ## Files - `packages/ui/src/components/`: `ModeHeader.svelte`, `OverlaySurface.svelte`, `PopoverSurface.svelte`, `surfaceViewport.svelte.ts`, `Inspector.svelte`, `calendar/CalendarPopover.svelte`, `menu/FloatingSurface.svelte`, `viewer/QuickLook.svelte`, and `index.ts`. - `apps/web/src/lib/`: `ai/TurnPanel.svelte`, `components/ConfirmSheet.svelte`, `components/OverlaySurface.svelte.test.ts`, `components/TagEditor.svelte`, `components/analytics/RangeBar.svelte`, `components/analytics/RangePicker.svelte`, `files/ShareDialog.svelte`, `modeHeader.svelte.test.ts`, and `notifications/InboxPanel.svelte`. - `apps/web/src/routes/`: `calendar/[view]/[date]/+page.svelte`, `settings/[...path]/+page.svelte`, `settings/account/RecoveryKeySheet.svelte`, and `settings/appearance/UnsplashSheet.svelte`. - `docs/DESIGN.md`. ## Gates - `cargo fmt --check`: exit 0; no output. - `cargo clippy --all-targets -- -D warnings`: passed. Verbatim final line: ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 5m 47s ``` - `cargo test`: passed; 72 suite summaries, 1,342 passed, 0 failed, 12 ignored. Verbatim suite output: ``` test result: ok. 486 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.59s ``` - `bun run check`: passed. Verbatim output: ``` $ svelte-kit sync && svelte-check --tsconfig ./tsconfig.json Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/chrome-rules/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` - `bun run test`: passed. Verbatim summary: ``` Test Files 103 passed (103) Tests 673 passed (673) Start at 04:17:51 Duration 52.54s (transform 59%, import 15%, environment 15%, tests 7%, setup 3%) ``` The first Cargo test attempt hit a stale shared sccache temp path before the suites ran. The successful retry unset `RUSTC_WRAPPER` and used the required cargo environment. ## Adversarial round - Authorization matrix: 244 OpenAPI operations, 1,079 requests; no reported authorization errors. Search storm: 0 failures. Hostile bytes: `==== HOSTILE BYTES FINDINGS 0`. - The round reported 13 SLOW latency observations. They were load-only observations. - One non-SLOW finding reproduced an undo/redo editor corruption in the Notes editor from the merged `dev` changes: one undo/redo round-trip inserted `^q02y8b` inside a heading. It is filed with evidence on [#280](https://git.kayg.org/kayg/calternal/issues/280); no expectation was changed. ## Decisions and remaining gaps - The shared desktop query uses 768 px plus a fine pointer so touch devices retain sheets. Existing card sizing was preserved where the sheet had a distinct intent: Confirm 440 px, Recovery Key 480 px, Tag Editor 500 px, Share 580 px, Unsplash 720 px, and Turn Panel about 460 px wide / 82dvh high. - Files and Photos action flows remain menu/context-menu interactions on desktop and sheets on phone. The Unsplash screenshot gap is described above. ## Branch - Merged `dev` once before final gates. Pushed `job/chrome-rules`. - Head: `d7926f80e3f0b13c6cd31da0a05b9f88f1b6ee23`.
Author
Owner

Starting #244 on branch job/chrome-rules, based on bdcecc42e2b199b92244c05020ce709ac8c97c4a before the existing dev merge in d7926f80e3f0b13c6cd31da0a05b9f88f1b6ee23. I am tracing the missing Share dialog report and adding production e2e coverage for every converted surface at desktop and phone sizes.

Starting #244 on branch `job/chrome-rules`, based on `bdcecc42e2b199b92244c05020ce709ac8c97c4a` before the existing `dev` merge in `d7926f80e3f0b13c6cd31da0a05b9f88f1b6ee23`. I am tracing the missing Share dialog report and adding production e2e coverage for every converted surface at desktop and phone sizes.
Author
Owner

Production e2e evidence: Share opened, was visible, trapped focus, and closed with Escape at 1440 and 390 px. The new full matrix has captured visible Share, Files actions, and Quick Look surfaces at 1440. It then reproduced a Quick Look lifecycle issue: after closing Quick Look with Escape and opening it again, the second instance remains visible after Escape (the same surface still resolves after the 10 s close wait). I am checking focus state on that second open and will fix or report the behavior before finishing the desktop/phone matrix.

Production e2e evidence: Share opened, was visible, trapped focus, and closed with Escape at 1440 and 390 px. The new full matrix has captured visible Share, Files actions, and Quick Look surfaces at 1440. It then reproduced a Quick Look lifecycle issue: after closing Quick Look with Escape and opening it again, the second instance remains visible after Escape (the same surface still resolves after the 10 s close wait). I am checking focus state on that second open and will fix or report the behavior before finishing the desktop/phone matrix.
Author
Owner

The Cancel styling assertion exposed the border source in production. Pill.svelte sets --control-boundary for .pill.btn:not(.primary):not(.quiet), which also overrides a new secondary tone. The confirm screenshot shows the Cancel outline, and computed border color is rgb(92, 96, 99). I am excluding the secondary tone from that generic boundary rule and will re-capture both confirmation surfaces at both viewport sizes.

The Cancel styling assertion exposed the border source in production. Pill.svelte sets `--control-boundary` for `.pill.btn:not(.primary):not(.quiet)`, which also overrides a new secondary tone. The confirm screenshot shows the Cancel outline, and computed border color is `rgb(92, 96, 99)`. I am excluding the secondary tone from that generic boundary rule and will re-capture both confirmation surfaces at both viewport sizes.
Author
Owner

Screenshot review of notifications-light-mesh-390.png found the sheet title colliding with the three trailing toolbar actions. The shared sheet header gives its title only the middle third of the row, while the notification action group is wider than the right third. I am changing the trailing-only header layout to give the title the remaining width, and adding a bounding-box assertion so this cannot recur unnoticed.

Screenshot review of `notifications-light-mesh-390.png` found the sheet title colliding with the three trailing toolbar actions. The shared sheet header gives its title only the middle third of the row, while the notification action group is wider than the right third. I am changing the trailing-only header layout to give the title the remaining width, and adding a bounding-box assertion so this cannot recur unnoticed.
Author
Owner

Completed #244 on job/chrome-rules.

Head: 1c37ed5264bc3f2afad81ba87d399be094475225. Merged dev once before the final gates (b19d0429).

Built:

  • Added bun run test:e2e:chrome-surfaces, a production-build browser matrix for Share dialog, Files/Photos actions, Quick Look, tag editor, notifications, range picker, recovery key, turn panel, keyboard shortcuts, and trash/confirm sheets at 1440×900 and 390×844. Each surface must open visibly, receive focus, trap Tab/Shift+Tab, and close with Escape. Captures are saved only after visibility is confirmed.
  • Fixed the Share capture path, phone notification header overlap, and repeated Quick Look focus timing found by the matrix.
  • Added a filled neutral secondary Pill tone for confirm Cancel, with a transparent border; documented the confirm action styling in DESIGN §34.
  • Attached all 24 final desktop and phone screenshots to this issue. The production matrix ended with: PASS chrome surfaces: all converted surfaces opened at 1440 and 390.

Files: apps/web/e2e/chrome-surfaces.mjs, apps/web/package.json, apps/web/src/lib/components/ConfirmSheet.svelte, packages/ui/src/components/OverlaySurface.svelte, packages/ui/src/components/Pill.svelte, docs/DESIGN.md.

Final gates:

  • cargo fmt --check — exit 0; no output.
  • cargo clippy --all-targets -- -D warnings — exit 0. Final output: Finished \dev` profile [unoptimized + debuginfo] target(s) in 2m 45s`.
  • cargo test — exit 0; every executed test binary reported test result: ok; repository-configured model and benchmark tests remained ignored. Final output:
       Doc-tests calternal_tags
    
    running 0 tests
    
    test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
    
  • bun run check:
    $ svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
    Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/chrome-rules/apps/web
    Getting Svelte diagnostics...
    
    svelte-check found 0 errors and 0 warnings
    
  • bun run test:
     Test Files  103 passed (103)
          Tests  680 passed (680)
       Duration  58.90s (transform 55%, environment 19%, import 13%, tests 9%, setup 3%)
    

Known gaps: none for this change. Existing model/performance-gated Rust tests remain ignored by their repository configuration. Build output was cleaned and the worktree is clean.

Decisions not covered by DESIGN before this change: phone sheet headers with both a title and trailing actions use two columns to prevent overlap while keeping the actions available. The confirm Cancel action uses the filled secondary tone and transparent border; this is now recorded in DESIGN §34.

Completed #244 on `job/chrome-rules`. Head: `1c37ed5264bc3f2afad81ba87d399be094475225`. Merged `dev` once before the final gates (`b19d0429`). Built: - Added `bun run test:e2e:chrome-surfaces`, a production-build browser matrix for Share dialog, Files/Photos actions, Quick Look, tag editor, notifications, range picker, recovery key, turn panel, keyboard shortcuts, and trash/confirm sheets at 1440×900 and 390×844. Each surface must open visibly, receive focus, trap Tab/Shift+Tab, and close with Escape. Captures are saved only after visibility is confirmed. - Fixed the Share capture path, phone notification header overlap, and repeated Quick Look focus timing found by the matrix. - Added a filled neutral secondary Pill tone for confirm Cancel, with a transparent border; documented the confirm action styling in DESIGN §34. - Attached all 24 final desktop and phone screenshots to this issue. The production matrix ended with: `PASS chrome surfaces: all converted surfaces opened at 1440 and 390`. Files: `apps/web/e2e/chrome-surfaces.mjs`, `apps/web/package.json`, `apps/web/src/lib/components/ConfirmSheet.svelte`, `packages/ui/src/components/OverlaySurface.svelte`, `packages/ui/src/components/Pill.svelte`, `docs/DESIGN.md`. Final gates: - `cargo fmt --check` — exit 0; no output. - `cargo clippy --all-targets -- -D warnings` — exit 0. Final output: `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 2m 45s`. - `cargo test` — exit 0; every executed test binary reported `test result: ok`; repository-configured model and benchmark tests remained ignored. Final output: ``` Doc-tests calternal_tags running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` - `bun run check`: ``` $ svelte-kit sync && svelte-check --tsconfig ./tsconfig.json Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/chrome-rules/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` - `bun run test`: ``` Test Files 103 passed (103) Tests 680 passed (680) Duration 58.90s (transform 55%, environment 19%, import 13%, tests 9%, setup 3%) ``` Known gaps: none for this change. Existing model/performance-gated Rust tests remain ignored by their repository configuration. Build output was cleaned and the worktree is clean. Decisions not covered by DESIGN before this change: phone sheet headers with both a title and trailing actions use two columns to prevent overlap while keeping the actions available. The confirm Cancel action uses the filled `secondary` tone and transparent border; this is now recorded in DESIGN §34.
kayg referenced this issue from a commit 2026-09-28 04:13:16 +00:00
Author
Owner

Merged in 561c3eb5 (import conflict with #236 resolved keeping both; svelte-check 0/0, web 701/701). Title collapse phone-only (all pages incl. Calendar), desktop overlays via the shared SurfaceViewport; e2e matrix proves every converted surface opens, traps focus and closes at 1440 and 390.

Merged in 561c3eb5 (import conflict with #236 resolved keeping both; svelte-check 0/0, web 701/701). Title collapse phone-only (all pages incl. Calendar), desktop overlays via the shared SurfaceViewport; e2e matrix proves every converted surface opens, traps focus and closes at 1440 and 390.
kayg closed this issue 2026-09-28 04:13:18 +00:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#244
No description provided.