Mode tray: Calendar icon shows today's date number #1095

Open
opened 2026-10-05 06:00:03 +00:00 by kayg · 9 comments
Owner

Owner request (2026-10-05)

"The calendar icon should show the current date number?"

The Calendar Tab icon in the mode tray (and the sidebar/menus where the Calendar mode icon appears) shows today's day number inside the calendar glyph, like a platform calendar app icon: drawn as our own icon in the existing icon stroke style, number rendered as text (tabular figures, scales at every size), updates at midnight and on resume, readable at 20–24 px, both themes. Accessible name stays "Calendar".

## Owner request (2026-10-05) "The calendar icon should show the current date number?" The Calendar Tab icon in the mode tray (and the sidebar/menus where the Calendar mode icon appears) shows today's day number inside the calendar glyph, like a platform calendar app icon: drawn as our own icon in the existing icon stroke style, number rendered as text (tabular figures, scales at every size), updates at midnight and on resume, readable at 20–24 px, both themes. Accessible name stays "Calendar".
Author
Owner

Started #1095, #1096, and #1097 on branch job/trayicons-1095, based on df92d4da129bfead879d417aef6e0514fc56ee96 from dev.

The shared mode metadata is in apps/web/src/lib/navigation.ts, but the Tab Bar reads path strings while navigation rows use separate Lucide components. I’m consolidating the Calendar, Tasks, and Notes glyphs behind one live icon component for the Tab Bar, navigation rows, and Settings → Tabs.

Started #1095, #1096, and #1097 on branch `job/trayicons-1095`, based on `df92d4da129bfead879d417aef6e0514fc56ee96` from `dev`. The shared mode metadata is in `apps/web/src/lib/navigation.ts`, but the Tab Bar reads path strings while navigation rows use separate Lucide components. I’m consolidating the Calendar, Tasks, and Notes glyphs behind one live icon component for the Tab Bar, navigation rows, and Settings → Tabs.
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).
Author
Owner

Shipped in fix batch 1 and broke the mode tray on production: owner screenshot shows the Calendar glyph oversized with the label clipped to "Cale", and every other mode icon rendered as a tiny dot. Reverted (hotfix 4a8e22609). Redo with the tray verified in a real production build at 390/820/1440, light and dark, selected and unselected, before READY.

Shipped in fix batch 1 and broke the mode tray on production: owner screenshot shows the Calendar glyph oversized with the label clipped to "Cale", and every other mode icon rendered as a tiny dot. Reverted (hotfix 4a8e22609). Redo with the tray verified in a real production build at 390/820/1440, light and dark, selected and unselected, before READY.
Author
Owner

Starting the tray icon fixes on job/trayicons-1095.

The worktree started at 3845841b4; I fetched and fast-forwarded it to origin/dev at d1b8371f577ecff6d6b499e24c8c147e300ff71a before editing. The supplied production screenshot confirms the Calendar glyph is oversized and clipped, while the remaining Tab icons render as dots. I am tracing the shared glyph renderer, its size classes, and the Calendar date layer, then will verify screenshots and geometry tests.

Starting the tray icon fixes on `job/trayicons-1095`. The worktree started at `3845841b4`; I fetched and fast-forwarded it to `origin/dev` at `d1b8371f577ecff6d6b499e24c8c147e300ff71a` before editing. The supplied production screenshot confirms the Calendar glyph is oversized and clipped, while the remaining Tab icons render as dots. I am tracing the shared glyph renderer, its size classes, and the Calendar date layer, then will verify screenshots and geometry tests.
Author
Owner

Finding across #1095–#1097: the shared glyph renderer has a 24×24 viewBox, but its root SVG has no intrinsic width/height and no global size-icon class. The Tab Bar and sidebar depend on scoped descendant selectors such as .seg-btn svg and .item svg; those selectors do not reliably style an SVG at a child component boundary. The browser's default SVG box then participates in flex sizing: the selected Calendar glyph expands and clips its label while inactive glyphs shrink to dots. The Calendar date also uses the UI text-size token as SVG text, so it is scaled as viewBox content instead of as an icon-sized number.

I have merged the explicit revert at 4a8e22609. I am restoring the shared glyphs on that base with intrinsic dimensions, the global icon-size token on the SVG itself, and a date number sized in viewBox units. The Tasks check box and Notes pad remain in the shared glyph path table so all render sites use the same artwork.

Finding across #1095–#1097: the shared glyph renderer has a 24×24 `viewBox`, but its root SVG has no intrinsic width/height and no global `size-icon` class. The Tab Bar and sidebar depend on scoped descendant selectors such as `.seg-btn svg` and `.item svg`; those selectors do not reliably style an SVG at a child component boundary. The browser's default SVG box then participates in flex sizing: the selected Calendar glyph expands and clips its label while inactive glyphs shrink to dots. The Calendar date also uses the UI text-size token as SVG text, so it is scaled as viewBox content instead of as an icon-sized number. I have merged the explicit revert at `4a8e22609`. I am restoring the shared glyphs on that base with intrinsic dimensions, the global icon-size token on the SVG itself, and a date number sized in viewBox units. The Tasks check box and Notes pad remain in the shared glyph path table so all render sites use the same artwork.
Author
Owner

Final report — #1095/#1096/#1097

Branch: job/trayicons-1095
Head: 7ee080f23d1f3a74132954ea8b0e418257cbfd7c

Built

Fixed the shared mode glyph renderer and used it in the Tab Bar, pinned App Sidebar rows, search Navigate rows, and Settings navigation. The renderer now keeps the global size-icon class and an explicit 24×24 SVG box with a 24-unit viewBox. The Calendar date is drawn at 9 viewBox units, so it scales with the glyph instead of using font metrics to size the SVG. One shared local-day clock refreshes Calendar glyphs at midnight and when a background page resumes.

Root cause: the shared renderer dropped the global icon-size class and the SVG had no intrinsic width or height. Scoped styles in parent components could not size the child SVG, so flex layout enlarged the Calendar glyph and collapsed other paths. The Calendar date text also used font sizing outside the SVG geometry. Commit 3845841b4 refreshed CSS scopes and exposed the issue; the sizing defect was in the shared renderer.

UX gaps closed

  • The geometry test checks every Tab glyph against the resolved --icon token and confirms the selected label fits its button.
  • Production screenshots cover Calendar, Tasks, Notes, Files, Photos and Mail at 390, 820 and 1440 px, in light and dark, with macOS platform signals.
  • The run also checks pinned App Sidebar and palette Navigate glyphs. The screenshot archive contains 36 tray views, 12 four-times crops, 2 sidebar views and 2 palette views.
  • No sample content was added. Sidebar pins are real per-User preferences in the isolated review account.

Screenshot attachment: https://git.kayg.org/attachments/ca39a6e3-0257-4ee2-a12f-c418442df781

Verification

Production screenshot and geometry run:

PASS Tab Bar geometry and production screenshots: 6 Tabs × 3 widths (390, 820, 1440px) × 2 themes; 12 four-times crops; macOS platform; App Sidebar and Core palette Navigate glyphs (/home/kayg/Developer/calternal-wt/trayicons-1095/artifacts/trayicons-1095)

Focused Vitest (4 files, 49 tests):

 RUN  v5.0.1 /home/kayg/Developer/calternal-wt/trayicons-1095/apps/web

 Test Files  4 passed (4)
      Tests  49 passed (49)
   Start at  11:18:19
   Duration  26.70s (transform 66%, environment 18%, import 6%, tests 5%, setup 4%)

  Transform  |component| transforming modules took 24.59s · 63% of tracked time, re-done on every run
             persist transforms across runs with fsModuleCache: true
             learn more: https://vitest.dev/guide/improving-performance#caching-between-reruns

bun run check (from apps/web) fails in perf-lint. Verbatim findings and gate result:

coverage.surfaces packages/ui/src/components/calendar/ItemPreview.svelte:345 packages/ui/src/components/calendar/ItemPreview.svelte#each:e5e7ae29d145f79e:1 actual='unregistered' required=one exact registry record
io.unresolved-call crates/plugins/notes/src/tasks_api.rs:1036 by_day:by_day:1f9fccd2cec4b519 actual='out.push' required=resolved capability or projection counter test
io.unresolved-call crates/plugins/notes/src/tasks_api.rs:1099 by_day:calendar_task_day_view:c04706b76c0be3bd actual='TaskStatus::Todo.as_word().into' required=resolved capability or projection counter test
io.unresolved-call crates/plugins/notes/src/tasks_api.rs:1099 by_day:calendar_task_day_view:be042d92271a211d actual='TaskStatus::Todo.as_word' required=resolved capability or projection counter test
perf-lint: FAIL; 4 violations; 21964 scoped exceptions
error: script "check" exited with code 1

These findings are in merged dev files outside this change. bun run check stops at perf-lint, so its later checks did not run. The full web suite and perf measurements are left to the merge round.

Decisions

Used a 24×24 viewBox because the shared icon token is the contract for these glyphs. Set the Calendar day text to 9 viewBox units to keep two-digit dates inside the page artwork. The E2E review account pins /today and /notes to exercise the real sidebar without fixture content.

Known gaps

Visual judgement of the attached screenshots remains for the orchestrator. bun run check is still red for the four merged-dev perf-lint findings above.

Ready for merge: no — the required bun run check gate is red.

## Final report — #1095/#1096/#1097 Branch: `job/trayicons-1095` Head: `7ee080f23d1f3a74132954ea8b0e418257cbfd7c` ### Built Fixed the shared mode glyph renderer and used it in the Tab Bar, pinned App Sidebar rows, search Navigate rows, and Settings navigation. The renderer now keeps the global `size-icon` class and an explicit 24×24 SVG box with a 24-unit viewBox. The Calendar date is drawn at 9 viewBox units, so it scales with the glyph instead of using font metrics to size the SVG. One shared local-day clock refreshes Calendar glyphs at midnight and when a background page resumes. Root cause: the shared renderer dropped the global icon-size class and the SVG had no intrinsic width or height. Scoped styles in parent components could not size the child SVG, so flex layout enlarged the Calendar glyph and collapsed other paths. The Calendar date text also used font sizing outside the SVG geometry. Commit `3845841b4` refreshed CSS scopes and exposed the issue; the sizing defect was in the shared renderer. ### UX gaps closed - The geometry test checks every Tab glyph against the resolved `--icon` token and confirms the selected label fits its button. - Production screenshots cover Calendar, Tasks, Notes, Files, Photos and Mail at 390, 820 and 1440 px, in light and dark, with macOS platform signals. - The run also checks pinned App Sidebar and palette Navigate glyphs. The screenshot archive contains 36 tray views, 12 four-times crops, 2 sidebar views and 2 palette views. - No sample content was added. Sidebar pins are real per-User preferences in the isolated review account. Screenshot attachment: https://git.kayg.org/attachments/ca39a6e3-0257-4ee2-a12f-c418442df781 ### Verification Production screenshot and geometry run: ``` PASS Tab Bar geometry and production screenshots: 6 Tabs × 3 widths (390, 820, 1440px) × 2 themes; 12 four-times crops; macOS platform; App Sidebar and Core palette Navigate glyphs (/home/kayg/Developer/calternal-wt/trayicons-1095/artifacts/trayicons-1095) ``` Focused Vitest (`4` files, `49` tests): ``` RUN v5.0.1 /home/kayg/Developer/calternal-wt/trayicons-1095/apps/web Test Files 4 passed (4) Tests 49 passed (49) Start at 11:18:19 Duration 26.70s (transform 66%, environment 18%, import 6%, tests 5%, setup 4%) Transform |component| transforming modules took 24.59s · 63% of tracked time, re-done on every run persist transforms across runs with fsModuleCache: true learn more: https://vitest.dev/guide/improving-performance#caching-between-reruns ``` `bun run check` (from `apps/web`) fails in `perf-lint`. Verbatim findings and gate result: ``` coverage.surfaces packages/ui/src/components/calendar/ItemPreview.svelte:345 packages/ui/src/components/calendar/ItemPreview.svelte#each:e5e7ae29d145f79e:1 actual='unregistered' required=one exact registry record io.unresolved-call crates/plugins/notes/src/tasks_api.rs:1036 by_day:by_day:1f9fccd2cec4b519 actual='out.push' required=resolved capability or projection counter test io.unresolved-call crates/plugins/notes/src/tasks_api.rs:1099 by_day:calendar_task_day_view:c04706b76c0be3bd actual='TaskStatus::Todo.as_word().into' required=resolved capability or projection counter test io.unresolved-call crates/plugins/notes/src/tasks_api.rs:1099 by_day:calendar_task_day_view:be042d92271a211d actual='TaskStatus::Todo.as_word' required=resolved capability or projection counter test perf-lint: FAIL; 4 violations; 21964 scoped exceptions error: script "check" exited with code 1 ``` These findings are in merged `dev` files outside this change. `bun run check` stops at perf-lint, so its later checks did not run. The full web suite and perf measurements are left to the merge round. ### Decisions Used a 24×24 viewBox because the shared icon token is the contract for these glyphs. Set the Calendar day text to 9 viewBox units to keep two-digit dates inside the page artwork. The E2E review account pins `/today` and `/notes` to exercise the real sidebar without fixture content. ### Known gaps Visual judgement of the attached screenshots remains for the orchestrator. `bun run check` is still red for the four merged-dev perf-lint findings above. **Ready for merge: no** — the required `bun run check` gate is red.
Author
Owner

Root-cause source check: the pre-revert ModeIcon.svelte at 3845841b4 used class={className} and viewBox="0 0 24 24" only; the root had no explicit width or height and did not apply size-icon. The Calendar <text> also relied on font-size: var(--type-tick-size) instead of a size inside the SVG viewBox. The scope refresh commit itself only updates generated perf scope records; it left that renderer state in place. The fix now applies size-icon on the shared SVG, sets its width and height to 24, and draws the date at 9 viewBox units.

Root-cause source check: the pre-revert `ModeIcon.svelte` at `3845841b4` used `class={className}` and `viewBox="0 0 24 24"` only; the root had no explicit width or height and did not apply `size-icon`. The Calendar `<text>` also relied on `font-size: var(--type-tick-size)` instead of a size inside the SVG viewBox. The scope refresh commit itself only updates generated perf scope records; it left that renderer state in place. The fix now applies `size-icon` on the shared SVG, sets its width and height to 24, and draws the date at 9 viewBox units.
Author
Owner

Bench note: bench/tab-switch.mjs now includes Tasks and Notes switches in the ordinary hot-path profile. I did not run a perf measurement because the current verification policy limits those runs to performance issues; this issue is a visual regression.

Bench note: `bench/tab-switch.mjs` now includes Tasks and Notes switches in the ordinary hot-path profile. I did not run a perf measurement because the current verification policy limits those runs to performance issues; this issue is a visual regression.
Author
Owner

Final acceptance update — supersedes the earlier head and screenshot archive.

Head: 3b918b2e1 (test(e2e): verify Settings mode glyph geometry). The Settings navigation now has production geometry and screenshot coverage at 390, 820 and 1440 px in light and dark, with macOS platform signals. The final archive has 58 PNGs: 36 Tab Bar views, 12 four-times crops, 2 App Sidebar views, 2 palette Navigate views and 6 Settings sidebar views.

Final production run output:

PASS Tab Bar and Settings sidebar geometry with production screenshots: 6 Tabs × 3 widths (390, 820, 1440px) × 2 themes; 12 four-times crops; macOS platform; App Sidebar and Core palette Navigate glyphs (/home/kayg/Developer/calternal-wt/trayicons-1095/artifacts/trayicons-1095)

Final screenshot archive: https://git.kayg.org/attachments/c8b7a80e-c4a1-4794-b4fd-0847b3fd61fb

The source search found no menu surface that renders ModeIcon; mode glyph surfaces are the Tab Bar, App and Settings sidebars, search result/navigation rows and Settings navigation. The previous #1095 comments record the root-cause evidence and gate output. bun run check remains red on the four merged-dev perf-lint findings, so Ready for merge: no.

Final acceptance update — supersedes the earlier head and screenshot archive. Head: `3b918b2e1` (`test(e2e): verify Settings mode glyph geometry`). The Settings navigation now has production geometry and screenshot coverage at 390, 820 and 1440 px in light and dark, with macOS platform signals. The final archive has 58 PNGs: 36 Tab Bar views, 12 four-times crops, 2 App Sidebar views, 2 palette Navigate views and 6 Settings sidebar views. Final production run output: ``` PASS Tab Bar and Settings sidebar geometry with production screenshots: 6 Tabs × 3 widths (390, 820, 1440px) × 2 themes; 12 four-times crops; macOS platform; App Sidebar and Core palette Navigate glyphs (/home/kayg/Developer/calternal-wt/trayicons-1095/artifacts/trayicons-1095) ``` Final screenshot archive: https://git.kayg.org/attachments/c8b7a80e-c4a1-4794-b4fd-0847b3fd61fb The source search found no menu surface that renders `ModeIcon`; mode glyph surfaces are the Tab Bar, App and Settings sidebars, search result/navigation rows and Settings navigation. The previous #1095 comments record the root-cause evidence and gate output. `bun run check` remains red on the four merged-dev perf-lint findings, so **Ready for merge: no**.
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#1095
No description provided.