Sidebar header icons are blurred on Calendar #1208

Open
opened 2026-10-06 16:24:49 +00:00 by kayg · 3 comments
Owner

Owner report (2026-10-06, production ff53d7b8b, desktop dark): "why is there blur on the calendar tab top left sidebar top?"

Screenshot: ~/calternal-private/reference/owner-sidebar-blur.webp. On the Calendar Tab the sidebar's top row (search / notifications / account icon group and the sidebar toggle) renders BLURRED — the icons are smeared, as if a progressive-blur/scroll-edge layer sits on top of the sidebar header instead of under it, or the header itself is inside a blurred layer.

Do (fix, not redesign):

  1. On a production build, open Calendar at 1440 (sidebar open), and use document.elementsFromPoint at the header icons to find which element paints the blur (scroll-edge mask, ProgressiveBlur, the mini-month card's backdrop, a sticky header veil, the Calendar header's own blur band extending under the sidebar, or the #1158 margin toggle layer). Report the culprit with evidence.
  2. Fix it at the source so the sidebar header is always crisp; the scroll-edge fade applies only to content scrolling UNDER the header. Check every Tab (the owner saw it on Calendar) at 1440 and 1024, light + dark, scrolled and unscrolled.
  3. Add a design-rule e2e: sidebar header controls have no ancestor or overlapping element with a backdrop-filter/filter/mask at their own position (except the sidebar's own glass surface).
    Screenshots at ACTUAL size before/after. Merge origin/dev; bun run check + bun run test pass. Commit; comment with head SHA. Do not push.
## Owner report (2026-10-06, production ff53d7b8b, desktop dark): "why is there blur on the calendar tab top left sidebar top?" Screenshot: ~/calternal-private/reference/owner-sidebar-blur.webp. On the Calendar Tab the sidebar's top row (search / notifications / account icon group and the sidebar toggle) renders BLURRED — the icons are smeared, as if a progressive-blur/scroll-edge layer sits on top of the sidebar header instead of under it, or the header itself is inside a blurred layer. Do (fix, not redesign): 1. On a production build, open Calendar at 1440 (sidebar open), and use `document.elementsFromPoint` at the header icons to find which element paints the blur (scroll-edge mask, ProgressiveBlur, the mini-month card's backdrop, a sticky header veil, the Calendar header's own blur band extending under the sidebar, or the #1158 margin toggle layer). Report the culprit with evidence. 2. Fix it at the source so the sidebar header is always crisp; the scroll-edge fade applies only to content scrolling UNDER the header. Check every Tab (the owner saw it on Calendar) at 1440 and 1024, light + dark, scrolled and unscrolled. 3. Add a design-rule e2e: sidebar header controls have no ancestor or overlapping element with a backdrop-filter/filter/mask at their own position (except the sidebar's own glass surface). Screenshots at ACTUAL size before/after. Merge origin/dev; bun run check + bun run test pass. Commit; comment with head SHA. Do not push.
Author
Owner

Started sidebar blur investigation on job/sidebarblur-1208, based on ff53d7b8b4 (origin/dev at start). I am tracing the production stacking at the reported controls before changing the blur source.

Started sidebar blur investigation on job/sidebarblur-1208, based on ff53d7b8b4da5a21f862d57dcc3496f8c019f647 (origin/dev at start). I am tracing the production stacking at the reported controls before changing the blur source.
Author
Owner

Production finding for #1208: at Calendar, 1440 px, dark, unscrolled, the Search, Notifications, Account and Hide sidebar icon centers were at x=48.2, 78.2, 108.2 and 238.8; all were at y=45.2. document.elementsFromPoint placed each sidebar control above the sidebar shell. A computed-style and bounds scan found five overlapping masked layers with backdrop-filter: blur(1px/2px/4px/8px/16px) at every icon center. These are the shared ProgressiveBlur spans from ModeHeader, whose band currently spans the full app-main grid area across the sidebar. This reproduces the blur in the production SPA with the real local server. I am fixing the band bounds at ModeHeader and will attach actual-size before/after captures with the final report.

Production finding for #1208: at Calendar, 1440 px, dark, unscrolled, the Search, Notifications, Account and Hide sidebar icon centers were at x=48.2, 78.2, 108.2 and 238.8; all were at y=45.2. `document.elementsFromPoint` placed each sidebar control above the sidebar shell. A computed-style and bounds scan found five overlapping masked layers with `backdrop-filter: blur(1px/2px/4px/8px/16px)` at every icon center. These are the shared `ProgressiveBlur` spans from `ModeHeader`, whose band currently spans the full `app-main` grid area across the sidebar. This reproduces the blur in the production SPA with the real local server. I am fixing the band bounds at `ModeHeader` and will attach actual-size before/after captures with the final report.
Author
Owner

Result

Fixed #1208. The blur came from the shared ProgressiveBlur in ModeHeader: app-main spans both desktop grid tracks, so its five masked blur layers overlapped the persistent Sidebar header. In the production 1440 px dark Calendar capture, the Search, Notifications, Account, and Sidebar toggle centers were at x=48.2, 78.2, 108.2, and 238.8 (y=45.2). The paint-order/style scan found the five blur layers over every center (blur(1px/2px/4px/8px/16px)).

ModeHeader now bounds the blur to the centered route column and its leading content inset. While the phone Sidebar sheet is open, the page blur is not mounted over the sheet controls. The content still scrolls under the desktop header.

Screenshots

All PNGs are full-size captures from the production build with macOS platform emulation. The archive contains the complete 98-image matrix (8 enabled Tabs; 1440, 1024, and 820 px; light/dark; scrolled/unscrolled, plus both 390 px phone themes): complete screenshot set.

Before, Calendar dark at 1440 px:

Before: Calendar dark, 1440 px, unscrolled
Before: Calendar dark, 1440 px, scrolled

After, Calendar dark at 1440 px:

After: Calendar dark, 1440 px, unscrolled
After: Calendar dark, 1440 px, scrolled

Additional after captures: 1024 px light, 820 px dark, 390 px phone sheet.

Changes

  • packages/ui/src/components/ModeHeader.svelte: constrain the shared blur at its source and keep phone sheet controls clear.
  • apps/web/e2e/sidebar-header-blur-1208.mjs: add a production design-rule sweep that checks control paint order, filtered/masked ancestors and overlaps for every enabled Tab, theme, viewport, and scroll state.
  • apps/web/package.json: add the focused e2e command.
  • contracts/perf/adoption-1058.json, contracts/perf/exceptions.json: refresh exact source pins for the modified shared component; no limits or ratchets changed.

UX gaps closed

The persistent desktop Sidebar header stays crisp while content scrolls. Phone sheet controls remain clear. The sweep also opens each available Tab; it closes Money's first-use import sheet and checks the actual empty route.

UX gaps left

None found in the requested states.

Decisions

DESIGN §34 says the Sidebar header stays clear and the page content scrolls under it. I used the existing centered-column and content-inset tokens to bound the blur. The page blur is omitted while the phone Sidebar sheet is open because its app controls occupy that sheet. This visual fix adds no data operation or route.

Gates

cargo fmt --check — exit 0, no output.

cd apps/web && bun run check — exit 0. Verbatim success summaries:

PASS production dependency licences: 759 locked package releases across apps/web, apps/docs and packages
perf-lint: PASS; 0 violations; 22615 scoped exceptions
svelte-check found 0 errors and 2 warnings in 2 files

The two warnings are existing empty CSS rulesets in AttachmentDeck.svelte:1055:3 and AgendaList.svelte:1277:3.

cd apps/web && bun run test — exit 0. Verbatim final Vitest summary:

 Test Files  282 passed (282)
      Tests  1978 passed (1978)
   Start at  21:16:49
   Duration  371.07s (environment 27%, transform 26%, import 24%, tests 17%, setup 6%)

TMPDIR="$PWD/../../target/tmp" bun run test:e2e:sidebar-header-blur-1208 — exit 0:

PASS sidebar header blur design-rule matrix: 98 screenshots, 8 enabled Tabs

No Rust source changed, so Rust clippy/test gates did not apply. No route or API changed, so adversarial API testing did not apply. This is a visual geometry fix; it adds no operation hot path or benchmark profile.

Commits

  • 7f2df8765639b4c6e8c754c8c2e90dc55621182d — fix(ui): keep sidebar header clear of mode blur
  • 283f91d673a713c8e2349158f8b08f21479791a2 — perf: refresh exact ModeHeader pins after blur fix

Head SHA: 283f91d673a713c8e2349158f8b08f21479791a2. Fetched and merged origin/dev before final gates; it was already up to date. No push or merge was made.

## Result Fixed #1208. The blur came from the shared `ProgressiveBlur` in `ModeHeader`: `app-main` spans both desktop grid tracks, so its five masked blur layers overlapped the persistent Sidebar header. In the production 1440 px dark Calendar capture, the Search, Notifications, Account, and Sidebar toggle centers were at x=48.2, 78.2, 108.2, and 238.8 (y=45.2). The paint-order/style scan found the five blur layers over every center (`blur(1px/2px/4px/8px/16px)`). `ModeHeader` now bounds the blur to the centered route column and its leading content inset. While the phone Sidebar sheet is open, the page blur is not mounted over the sheet controls. The content still scrolls under the desktop header. ### Screenshots All PNGs are full-size captures from the production build with macOS platform emulation. The archive contains the complete 98-image matrix (8 enabled Tabs; 1440, 1024, and 820 px; light/dark; scrolled/unscrolled, plus both 390 px phone themes): [complete screenshot set](https://git.kayg.org/attachments/994d3299-7669-4247-a387-d0a347424e7a). Before, Calendar dark at 1440 px: ![Before: Calendar dark, 1440 px, unscrolled](https://git.kayg.org/attachments/8d4e9869-b97c-4838-8fdb-cc47cd5b4165) ![Before: Calendar dark, 1440 px, scrolled](https://git.kayg.org/attachments/5039f385-5fe8-446e-a043-09cfd2eece4b) After, Calendar dark at 1440 px: ![After: Calendar dark, 1440 px, unscrolled](https://git.kayg.org/attachments/4e89ec42-24b8-4b62-aa5f-d153a4ea7b5f) ![After: Calendar dark, 1440 px, scrolled](https://git.kayg.org/attachments/7e6f057d-feb5-4200-a8b5-a6615dccb57e) Additional after captures: [1024 px light](https://git.kayg.org/attachments/fa96fa93-9733-4ba3-a1b9-f1a83a7376e1), [820 px dark](https://git.kayg.org/attachments/93ee9b4d-3ce4-453e-b846-db56a0f80301), [390 px phone sheet](https://git.kayg.org/attachments/dc235ca0-7f23-4ffa-847c-8e0043e07f6b). ### Changes - `packages/ui/src/components/ModeHeader.svelte`: constrain the shared blur at its source and keep phone sheet controls clear. - `apps/web/e2e/sidebar-header-blur-1208.mjs`: add a production design-rule sweep that checks control paint order, filtered/masked ancestors and overlaps for every enabled Tab, theme, viewport, and scroll state. - `apps/web/package.json`: add the focused e2e command. - `contracts/perf/adoption-1058.json`, `contracts/perf/exceptions.json`: refresh exact source pins for the modified shared component; no limits or ratchets changed. ### UX gaps closed The persistent desktop Sidebar header stays crisp while content scrolls. Phone sheet controls remain clear. The sweep also opens each available Tab; it closes Money's first-use import sheet and checks the actual empty route. ### UX gaps left None found in the requested states. ### Decisions DESIGN §34 says the Sidebar header stays clear and the page content scrolls under it. I used the existing centered-column and content-inset tokens to bound the blur. The page blur is omitted while the phone Sidebar sheet is open because its app controls occupy that sheet. This visual fix adds no data operation or route. ### Gates `cargo fmt --check` — exit 0, no output. `cd apps/web && bun run check` — exit 0. Verbatim success summaries: ```text PASS production dependency licences: 759 locked package releases across apps/web, apps/docs and packages perf-lint: PASS; 0 violations; 22615 scoped exceptions svelte-check found 0 errors and 2 warnings in 2 files ``` The two warnings are existing empty CSS rulesets in `AttachmentDeck.svelte:1055:3` and `AgendaList.svelte:1277:3`. `cd apps/web && bun run test` — exit 0. Verbatim final Vitest summary: ```text Test Files 282 passed (282) Tests 1978 passed (1978) Start at 21:16:49 Duration 371.07s (environment 27%, transform 26%, import 24%, tests 17%, setup 6%) ``` `TMPDIR="$PWD/../../target/tmp" bun run test:e2e:sidebar-header-blur-1208` — exit 0: ```text PASS sidebar header blur design-rule matrix: 98 screenshots, 8 enabled Tabs ``` No Rust source changed, so Rust clippy/test gates did not apply. No route or API changed, so adversarial API testing did not apply. This is a visual geometry fix; it adds no operation hot path or benchmark profile. ### Commits - `7f2df8765639b4c6e8c754c8c2e90dc55621182d` — fix(ui): keep sidebar header clear of mode blur - `283f91d673a713c8e2349158f8b08f21479791a2` — perf: refresh exact ModeHeader pins after blur fix Head SHA: `283f91d673a713c8e2349158f8b08f21479791a2`. Fetched and merged `origin/dev` before final gates; it was already up to date. No push or merge was made.
Commenting is not possible because the repository is archived.
No labels
No milestone
No project
No assignees
1 participant
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-v0#1208
No description provided.