Mobile: sheet top band is back; needs iOS presentation sheet header with dynamic title and progressive blur #1084

Open
opened 2026-10-05 03:23:53 +00:00 by kayg · 5 comments
Owner

Owner report (2026-10-05 08:44–08:49 IST, iPhone, production 269b1b51b, dark theme). Screenshots: owner's four phone captures (Day view during horizontal swipe, Day view at rest, Settings → Account sheet, Agenda).

"Top band is back even though we discussed iOS presentation sheet aesthetic with dynamic headers and progressive blur at the top with motion. The font disparity especially is annoying."

Settings → Account on the phone opens as a sheet with an opaque grey top band holding a back button and a link button, then a separate large "Account" title below. Wanted (decided earlier, see DESIGN sheet/chrome rules and Honcho): an iOS presentation sheet. The header is transparent with a progressive blur that appears as content scrolls under it; the large title collapses into the inline header title with motion (shared spring); the back and link buttons sit in a glass pill group. One rem type scale, so the header title and the page title come from the same scale with no jarring size jump.

## Owner report (2026-10-05 08:44–08:49 IST, iPhone, production 269b1b51b, dark theme). Screenshots: owner's four phone captures (Day view during horizontal swipe, Day view at rest, Settings → Account sheet, Agenda). "Top band is back even though we discussed iOS presentation sheet aesthetic with dynamic headers and progressive blur at the top with motion. The font disparity especially is annoying." Settings → Account on the phone opens as a sheet with an opaque grey top band holding a back button and a link button, then a separate large "Account" title below. Wanted (decided earlier, see DESIGN sheet/chrome rules and Honcho): an iOS presentation sheet. The header is transparent with a progressive blur that appears as content scrolls under it; the large title collapses into the inline header title with motion (shared spring); the back and link buttons sit in a glass pill group. One rem type scale, so the header title and the page title come from the same scale with no jarring size jump.
Author
Owner

Starting mchrome-1084 on job/mchrome-1084 at 269b1b51b (origin/dev / production). I will read the three issue briefs and mobile guidance, then implement the shared presentation-sheet header and toolbar/tab-bar fixes with focused screenshots and gates.

Starting mchrome-1084 on job/mchrome-1084 at 269b1b51b (origin/dev / production). I will read the three issue briefs and mobile guidance, then implement the shared presentation-sheet header and toolbar/tab-bar fixes with focused screenshots and gates.
Author
Owner

Finding: OverlaySurface already follows the active large heading, but its sheet chrome paints an opaque static band and the blur is active even at rest. Settings also supplies Back and Copy link in separate header slots. I am making the shared sheet header transparent, showing its progressive blur only while scrolled, and using the shared spring response for the matching title dissolve.

Finding: OverlaySurface already follows the active large heading, but its sheet chrome paints an opaque static band and the blur is active even at rest. Settings also supplies Back and Copy link in separate header slots. I am making the shared sheet header transparent, showing its progressive blur only while scrolled, and using the shared spring response for the matching title dissolve.
Author
Owner

Final report

Implemented on job/mchrome-1084, based on dev at 269b1b51b. Head: 689069950b89b02768ea19c203e452184f16478d.

Built

  • The phone presentation sheet header is transparent at rest. Its top progressive blur appears after scroll starts. Large and inline titles use the shared cascadeOverdamped spring, with reduced motion respected.
  • Settings Back and Copy link controls share one glass pill group.
  • Notes New, Copy link and More controls share the Notes sidebar action group. The duplicate inline Notes Copy link is hidden.
  • Calendar horizontal movement keeps the Tab Bar progressive blur live. The moving lane is clipped to the time gutter and the gutter uses the opaque --surface role.

Files: packages/ui/src/components/OverlaySurface.svelte, packages/ui/src/components/LinkedHeading.svelte, packages/ui/src/components/SidebarSectionHeader.svelte, packages/ui/src/tokens.css, apps/web/src/routes/settings/[...path]/+page.svelte, apps/web/src/lib/notes/NotesExplorer.svelte, the two matching component test files, apps/web/e2e/mchrome-1084.mjs, both affected bench/ profiles, contracts/perf/exceptions.json, docs/perf/README.md, and docs/perf/mchrome-1084.md.

UX gaps closed

  • The Settings header now groups navigation and Copy link in one reachable action island.
  • The Notes section has one Copy link action, next to New and More in its action island.
  • Keyboard, touch-sized action targets, accessible names and stable links use the existing shared components.

UX gaps left

  • The WebKit calendar-day-mid-swipe captures show the scrolling paint state after the state marker was enabled. Headless WebKit stalled while painting the large virtual Day track during a true movement capture, so those captures are not mid-motion frames. The locked Chrome wheel/touch profile below exercised real gestures.

Decisions

  • DESIGN.md §34 already specifies the presentation sheet header, so the implementation follows it. The gutter uses the shared semantic --surface token and CSS clipping; it adds no runtime layout measurement.
  • The Honcho connector was unavailable in this session. The binding §34 sheet and chrome rules were present in DESIGN.md and were followed.

Gates

bun run check (passed; four pre-existing Svelte warnings outside changed files):

perf-lint: PASS; 0 violations; 18996 scoped exceptions
User browser caches use userStorage; only documented device/public-link exceptions remain.
Glass alpha, blur and backdrop-filter roles use packages/ui/src/tokens.css.
Text sizes and UI shape values use shared role tokens.
Keyboard focus rings use the shared focus tokens.
UI transitions and animation options use shared motion tokens or documented exceptions.
svelte-check found 0 errors and 4 warnings in 3 files

Focused Vitest (passed):

Test Files  2 passed (2)
Tests  25 passed (25)

Production WebKit review (passed):

PASS WebKit production review after: 4 widths × 2 themes

No Rust source changed, so Rust crate gates were not applicable. The full bun run test and merge-round E2E suite remain for the merge round.

Performance

The locked perf-VM Notes run measured 20 empty-Home opens at p50/p95 644 / 798.6 ms, browser CPU 31.53 s, mean/peak RSS 607,542,126 / 629,837,824 bytes. With 500 real Notes and 50 opens it measured p50/p95 601.9 / 742.1 ms, CPU 80.62 s, mean/peak RSS 658,972,672 / 702,558,208 bytes. The repository has no baseline for this action, so these values are a feature reference only.

The locked Calendar profile used 650 Daily notes and 7,200 Logs. Its 60-day wheel run measured p50/p95 frame latency 50.0 / 133.3 ms, CPU 11.64 s, RSS 808 → 910 MiB, and 16 long tasks (longest 271 ms); the existing 50 ms p95 guard failed. The baseline server differs (cb1b3f6e7 vs bff78498f...), so this is not a causal comparison. I reported the numbers and mismatch on existing issue #1026. Performance is not a merge gate.

Production screenshots

Before/after real production WebKit captures use macOS platform emulation, 390, 430, 820 and 1440 px, in light and dark. The Settings captures also include collapsed-title states. All captures are attached here.

Capture Before After
settings-account-1440-dark before after
settings-account-1440-light before after
settings-account-390-dark before after
settings-account-390-light before after
settings-account-430-dark before after
settings-account-430-light before after
settings-account-820-dark before after
settings-account-820-light before after
settings-account-collapsed-390-dark before after
settings-account-collapsed-390-light before after
settings-account-collapsed-430-dark before after
settings-account-collapsed-430-light before after
settings-account-collapsed-820-dark before after
settings-account-collapsed-820-light before after

READY FOR MERGE: yes — focused gates pass; the performance guard finding is tracked on #1026. No push, deploy or merge was done.

## Final report Implemented on `job/mchrome-1084`, based on `dev` at `269b1b51b`. Head: `689069950b89b02768ea19c203e452184f16478d`. ### Built - The phone presentation sheet header is transparent at rest. Its top progressive blur appears after scroll starts. Large and inline titles use the shared `cascadeOverdamped` spring, with reduced motion respected. - Settings Back and Copy link controls share one glass pill group. - Notes New, Copy link and More controls share the Notes sidebar action group. The duplicate inline Notes Copy link is hidden. - Calendar horizontal movement keeps the Tab Bar progressive blur live. The moving lane is clipped to the time gutter and the gutter uses the opaque `--surface` role. Files: `packages/ui/src/components/OverlaySurface.svelte`, `packages/ui/src/components/LinkedHeading.svelte`, `packages/ui/src/components/SidebarSectionHeader.svelte`, `packages/ui/src/tokens.css`, `apps/web/src/routes/settings/[...path]/+page.svelte`, `apps/web/src/lib/notes/NotesExplorer.svelte`, the two matching component test files, `apps/web/e2e/mchrome-1084.mjs`, both affected `bench/` profiles, `contracts/perf/exceptions.json`, `docs/perf/README.md`, and `docs/perf/mchrome-1084.md`. ### UX gaps closed - The Settings header now groups navigation and Copy link in one reachable action island. - The Notes section has one Copy link action, next to New and More in its action island. - Keyboard, touch-sized action targets, accessible names and stable links use the existing shared components. ### UX gaps left - The WebKit `calendar-day-mid-swipe` captures show the scrolling paint state after the state marker was enabled. Headless WebKit stalled while painting the large virtual Day track during a true movement capture, so those captures are not mid-motion frames. The locked Chrome wheel/touch profile below exercised real gestures. ### Decisions - `DESIGN.md` §34 already specifies the presentation sheet header, so the implementation follows it. The gutter uses the shared semantic `--surface` token and CSS clipping; it adds no runtime layout measurement. - The Honcho connector was unavailable in this session. The binding §34 sheet and chrome rules were present in `DESIGN.md` and were followed. ### Gates `bun run check` (passed; four pre-existing Svelte warnings outside changed files): ```text perf-lint: PASS; 0 violations; 18996 scoped exceptions User browser caches use userStorage; only documented device/public-link exceptions remain. Glass alpha, blur and backdrop-filter roles use packages/ui/src/tokens.css. Text sizes and UI shape values use shared role tokens. Keyboard focus rings use the shared focus tokens. UI transitions and animation options use shared motion tokens or documented exceptions. svelte-check found 0 errors and 4 warnings in 3 files ``` Focused Vitest (passed): ```text Test Files 2 passed (2) Tests 25 passed (25) ``` Production WebKit review (passed): ```text PASS WebKit production review after: 4 widths × 2 themes ``` No Rust source changed, so Rust crate gates were not applicable. The full `bun run test` and merge-round E2E suite remain for the merge round. ### Performance The locked perf-VM Notes run measured 20 empty-Home opens at p50/p95 `644 / 798.6 ms`, browser CPU `31.53 s`, mean/peak RSS `607,542,126 / 629,837,824 bytes`. With 500 real Notes and 50 opens it measured p50/p95 `601.9 / 742.1 ms`, CPU `80.62 s`, mean/peak RSS `658,972,672 / 702,558,208 bytes`. The repository has no baseline for this action, so these values are a feature reference only. The locked Calendar profile used 650 Daily notes and 7,200 Logs. Its 60-day wheel run measured p50/p95 frame latency `50.0 / 133.3 ms`, CPU `11.64 s`, RSS `808 → 910 MiB`, and 16 long tasks (longest `271 ms`); the existing 50 ms p95 guard failed. The baseline server differs (`cb1b3f6e7` vs `bff78498f...`), so this is not a causal comparison. I reported the numbers and mismatch on existing issue #1026. Performance is not a merge gate. ### Production screenshots Before/after real production WebKit captures use macOS platform emulation, 390, 430, 820 and 1440 px, in light and dark. The Settings captures also include collapsed-title states. All captures are attached here. | Capture | Before | After | | --- | --- | --- | | `settings-account-1440-dark` | [before](https://git.kayg.org/attachments/425b6f42-babf-4a18-b2f1-71b5c55dc77e) | [after](https://git.kayg.org/attachments/42e560e9-294a-48cb-82b4-77ac293b2f73) | | `settings-account-1440-light` | [before](https://git.kayg.org/attachments/89f487ef-9393-4c94-ad44-3d990aba22ad) | [after](https://git.kayg.org/attachments/4921a1e2-ab9a-41a1-8b59-271ac5afe165) | | `settings-account-390-dark` | [before](https://git.kayg.org/attachments/03827257-a713-41d7-89fe-0265ebf306a2) | [after](https://git.kayg.org/attachments/5e918aa5-67bf-41fa-8e25-6b3437952e46) | | `settings-account-390-light` | [before](https://git.kayg.org/attachments/a0ba276b-467f-41d8-821e-be3b9a6dede8) | [after](https://git.kayg.org/attachments/7baee7c8-5c05-4e8b-88a1-e7e467083aaf) | | `settings-account-430-dark` | [before](https://git.kayg.org/attachments/adc1260f-5c24-4e9f-8b16-dac4f630f314) | [after](https://git.kayg.org/attachments/8caf95d5-8d8a-4f74-be1c-2581357b4eec) | | `settings-account-430-light` | [before](https://git.kayg.org/attachments/0eb2fc0c-5d91-46fc-a42a-78342e55c248) | [after](https://git.kayg.org/attachments/f504d09f-1961-4fbb-9488-ab2c020eeba1) | | `settings-account-820-dark` | [before](https://git.kayg.org/attachments/c0c398d0-0139-492f-9cf6-69495672f7b6) | [after](https://git.kayg.org/attachments/d4e5697d-d395-48ed-92a8-cbcd60a7e376) | | `settings-account-820-light` | [before](https://git.kayg.org/attachments/d671c0f3-3f96-4c5d-b036-ed39068f1b2f) | [after](https://git.kayg.org/attachments/a16cd594-97c5-4f1f-a83e-7cc6d875ba9a) | | `settings-account-collapsed-390-dark` | [before](https://git.kayg.org/attachments/4a819b96-699f-4e05-b56a-48cd17d3e194) | [after](https://git.kayg.org/attachments/8a66e618-6fbc-499f-9814-940a6a6a4348) | | `settings-account-collapsed-390-light` | [before](https://git.kayg.org/attachments/535a6d53-1718-4cb2-b575-124e26942795) | [after](https://git.kayg.org/attachments/9e7067c0-5875-4a73-8791-5370db5e774c) | | `settings-account-collapsed-430-dark` | [before](https://git.kayg.org/attachments/427dce42-fa0b-4670-bf17-a171505de7df) | [after](https://git.kayg.org/attachments/78d59310-6257-4abf-9b5f-ab3c727c1cef) | | `settings-account-collapsed-430-light` | [before](https://git.kayg.org/attachments/03204f35-6733-4324-8d1f-40679828e92e) | [after](https://git.kayg.org/attachments/92d7ee00-d0aa-471c-bc72-1bf361d017c7) | | `settings-account-collapsed-820-dark` | [before](https://git.kayg.org/attachments/f3169a0c-3f14-40c0-b6fc-0b75d53b4700) | [after](https://git.kayg.org/attachments/f69242d4-2d6a-4c51-80ac-cb9f365b3ac7) | | `settings-account-collapsed-820-light` | [before](https://git.kayg.org/attachments/19172f9a-ec77-43a3-8efc-b7f993ea7b43) | [after](https://git.kayg.org/attachments/4c8e6b5e-4930-4302-ac6f-981a1ca161f0) | **READY FOR MERGE: yes** — focused gates pass; the performance guard finding is tracked on #1026. No push, deploy or merge was done.
Author
Owner

Final report update

Final head: 4cae714b169302faebfe0030f72e8c24794d24d1 on job/mchrome-1084. The initial report on this issue contains the behavior, performance results, screenshot matrix and full file list. A final #1085 scope audit added the shared Inspector Copy link/Close action island in packages/ui/src/components/Inspector.svelte, with component and production WebKit coverage. The Settings sheet header and Calendar changes remain as reported.

The full current production WebKit matrix passed at four widths and two themes. The Day mid-swipe images still capture the CSS state marker rather than a true movement frame because headless WebKit stalled painting the virtual Day track; the locked Chrome profile did exercise real wheel and touch gestures. The Calendar 60-day p95 result and server-baseline mismatch were reported on existing #1026.

Final gates

bun run check:

perf-lint: PASS; 0 violations; 18996 scoped exceptions
User browser caches use userStorage; only documented device/public-link exceptions remain.
Glass alpha, blur and backdrop-filter roles use packages/ui/src/tokens.css.
Text sizes and UI shape values use shared role tokens.
Keyboard focus rings use the shared focus tokens.
UI transitions and animation options use shared motion tokens or documented exceptions.
svelte-check found 0 errors and 4 warnings in 3 files

Focused Vitest:

Test Files  2 passed (2)
      Tests  26 passed (26)

Production build:

Compressed 534 static variants; saved 9833416 bytes.

Production WebKit review (Mac platform emulation, 390/430/820/1440 px, light/dark):

PASS WebKit production review inspector-after: 4 widths × 2 themes

No Rust source changed, so Rust gates did not apply. cargo clean completed with Removed 0 files.

DESIGN.md §34 already defines the sheet header, so the existing implementation follows that decision. No Rust source changed. READY FOR MERGE: yes.

## Final report update Final head: `4cae714b169302faebfe0030f72e8c24794d24d1` on `job/mchrome-1084`. The initial report on this issue contains the behavior, performance results, screenshot matrix and full file list. A final #1085 scope audit added the shared Inspector Copy link/Close action island in `packages/ui/src/components/Inspector.svelte`, with component and production WebKit coverage. The Settings sheet header and Calendar changes remain as reported. The full current production WebKit matrix passed at four widths and two themes. The Day mid-swipe images still capture the CSS state marker rather than a true movement frame because headless WebKit stalled painting the virtual Day track; the locked Chrome profile did exercise real wheel and touch gestures. The Calendar 60-day p95 result and server-baseline mismatch were reported on existing #1026. ### Final gates `bun run check`: ```text perf-lint: PASS; 0 violations; 18996 scoped exceptions User browser caches use userStorage; only documented device/public-link exceptions remain. Glass alpha, blur and backdrop-filter roles use packages/ui/src/tokens.css. Text sizes and UI shape values use shared role tokens. Keyboard focus rings use the shared focus tokens. UI transitions and animation options use shared motion tokens or documented exceptions. svelte-check found 0 errors and 4 warnings in 3 files ``` Focused Vitest: ```text Test Files 2 passed (2) Tests 26 passed (26) ``` Production build: ```text Compressed 534 static variants; saved 9833416 bytes. ``` Production WebKit review (Mac platform emulation, 390/430/820/1440 px, light/dark): ```text PASS WebKit production review inspector-after: 4 widths × 2 themes ``` No Rust source changed, so Rust gates did not apply. `cargo clean` completed with `Removed 0 files`. `DESIGN.md` §34 already defines the sheet header, so the existing implementation follows that decision. No Rust source changed. **READY FOR MERGE: yes.**
Author
Owner

Deployed to production 2026-10-05 09:42 CEST in fix batch 1 (d1b8371f5).

Deployed to production 2026-10-05 09:42 CEST in fix batch 1 (d1b8371f5).
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#1084
No description provided.