Shortcut caps look bad: glyphs tiny and faint, cramped in menus #1134

Open
opened 2026-10-05 09:51:32 +00:00 by kayg · 10 comments
Owner

Owner report (2026-10-05)

"Why do shortcuts look so bad in the screenshot? Don't we have a decided shortcut style?"

Screenshot: Notes sidebar row menu (Open / Share ⇧⌘S / Copy link / Delete ⌘⌫), Tokyo Night, 1440 px wide.

The decided style (keep it)

#710 and DESIGN §34/§57: one shared Kbd cap (packages/ui/src/components/Kbd.svelte) per full combination, everywhere (menus, tooltips, palette, ? card, Settings → Shortcuts). Mac shows joined glyphs in one cap (⇧⌘S); other systems show one "Ctrl+Shift+S" cap. Menus show one shortcut, read from the registry, in a right-aligned column. Do not change this decision.

What is wrong (render quality of that one primitive)

  • The glyphs (⇧ ⌘ ⌫) render tiny and faint: caption-size text in --muted on --glass-chrome-bg. "⇧⌘S" is barely legible. ⌫ looks like a smudge.
  • The cap looks cramped against the menu's right edge and does not share a vertical centre with the label.
  • Contrast between cap text and the cap fill is too low in dark themes.

Fix (shared primitive only; every surface inherits it)

  • Make the cap legible and calm: glyph optical size matches the row label cap height (Apple's menus draw shortcut glyphs at label size, in secondary colour). Use a font stack that has proper ⌘⇧⌥⌃⌫↩ glyphs (system-ui on Apple, then the UI font), or size modifier glyphs up so they read at the same visual weight as letters.
  • Cap text contrast ≥ 4.5:1 against the cap fill in every theme (light, dark, Tokyo Night, and others). Use tokens only: no numeric literals (guard check).
  • Even right gap in menus, matching the leading icon gap; cap vertically centred on the label.
  • Check every consumer: menus, warm tooltip, search palette footer and action pills, ? card, Settings → Shortcuts.

Evidence required

Screenshots of a real production build at 1x AND 2x DPR, light + dark + Tokyo Night, of: a row menu with Share and Delete, a tooltip with a shortcut, the palette footer, the ? card. Also one real Safari render on the macOS VM (system font glyphs). Zoom crops of each cap next to its label. Attach to this issue.

## Owner report (2026-10-05) "Why do shortcuts look so bad in the screenshot? Don't we have a decided shortcut style?" Screenshot: Notes sidebar row menu (Open / Share ⇧⌘S / Copy link / Delete ⌘⌫), Tokyo Night, 1440 px wide. ## The decided style (keep it) #710 and DESIGN §34/§57: one shared `Kbd` cap (`packages/ui/src/components/Kbd.svelte`) per full combination, everywhere (menus, tooltips, palette, ? card, Settings → Shortcuts). Mac shows joined glyphs in one cap (⇧⌘S); other systems show one "Ctrl+Shift+S" cap. Menus show one shortcut, read from the registry, in a right-aligned column. Do not change this decision. ## What is wrong (render quality of that one primitive) - The glyphs (⇧ ⌘ ⌫) render tiny and faint: caption-size text in `--muted` on `--glass-chrome-bg`. "⇧⌘S" is barely legible. ⌫ looks like a smudge. - The cap looks cramped against the menu's right edge and does not share a vertical centre with the label. - Contrast between cap text and the cap fill is too low in dark themes. ## Fix (shared primitive only; every surface inherits it) - Make the cap legible and calm: glyph optical size matches the row label cap height (Apple's menus draw shortcut glyphs at label size, in secondary colour). Use a font stack that has proper ⌘⇧⌥⌃⌫↩ glyphs (system-ui on Apple, then the UI font), or size modifier glyphs up so they read at the same visual weight as letters. - Cap text contrast ≥ 4.5:1 against the cap fill in every theme (light, dark, Tokyo Night, and others). Use tokens only: no numeric literals (guard check). - Even right gap in menus, matching the leading icon gap; cap vertically centred on the label. - Check every consumer: menus, warm tooltip, search palette footer and action pills, ? card, Settings → Shortcuts. ## Evidence required Screenshots of a real production build at 1x AND 2x DPR, light + dark + Tokyo Night, of: a row menu with Share and Delete, a tooltip with a shortcut, the palette footer, the ? card. Also one real Safari render on the macOS VM (system font glyphs). Zoom crops of each cap next to its label. Attach to this issue.
Author
Owner

Starting kbd-1134 on job/kbd-1134 from base 570e084c86. I am tracing the shared Kbd primitive and its consumers, then I will update the primitive, capture the requested production screenshots and run focused web checks.

Starting kbd-1134 on job/kbd-1134 from base 570e084c8691a76b9bec904f47151f4ff5701298. I am tracing the shared Kbd primitive and its consumers, then I will update the primitive, capture the requested production screenshots and run focused web checks.
Author
Owner

Finding from the first web check at commit bae18f619 (before the required origin/dev merge): bun run check exited 2 at perf-lint with INVALID: ('render.bound', 'apps/web/src/lib/components/app-sidebar.svelte', 'apps/web/src/lib/components/app-sidebar.svelte#each:10a1aaf3137a2426:1'): unused or changed exception. Focused Kbd, menu and all-theme contrast tests passed. I have merged origin/dev; the final web check is pending against the merged tree.

Finding from the first web check at commit `bae18f619` (before the required origin/dev merge): `bun run check` exited 2 at perf-lint with `INVALID: ('render.bound', 'apps/web/src/lib/components/app-sidebar.svelte', 'apps/web/src/lib/components/app-sidebar.svelte#each:10a1aaf3137a2426:1'): unused or changed exception`. Focused Kbd, menu and all-theme contrast tests passed. I have merged `origin/dev`; the final web check is pending against the merged tree.
Author
Owner

Finding after merging origin/dev: bun run check exits at perf-lint before Svelte checks. The same over-ceiling counts are present with the screenshot runner moved outside the scanner. No performance ledger files changed in this branch.

Exact output:

perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.blocked-network: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; contract.dom-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.model-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.row-identity: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.snapshot: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.profile: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.readiness: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; io.unresolved-call: 16191 exceptions exceed the ratchet ceiling 16190; fix the new violation instead; render.blaze-adapter: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_byte_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_row_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; total: ledger has 21977 exceptions; ratchet total is 21964

This looks like a merged origin/dev ledger/ratchet mismatch; I have not edited unrelated performance policy files. I will report the final gate result with the commit SHA.

Finding after merging `origin/dev`: `bun run check` exits at `perf-lint` before Svelte checks. The same over-ceiling counts are present with the screenshot runner moved outside the scanner. No performance ledger files changed in this branch. Exact output: ```text perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.blocked-network: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; contract.dom-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.model-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.row-identity: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.snapshot: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.profile: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.readiness: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; io.unresolved-call: 16191 exceptions exceed the ratchet ceiling 16190; fix the new violation instead; render.blaze-adapter: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_byte_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_row_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; total: ledger has 21977 exceptions; ratchet total is 21964 ``` This looks like a merged `origin/dev` ledger/ratchet mismatch; I have not edited unrelated performance policy files. I will report the final gate result with the commit SHA.
Author
Owner

Completed — #1134

Improved the shared Kbd cap while keeping the decided #710 / DESIGN §§34, 57 shortcut format. Modifier glyphs now use the system UI font stack at the menu label size. Caps use the existing readable secondary text and paper/raised surface tokens, and active menu caps follow the selected row foreground. A theme contract checks AA text contrast across all 36 themes.

UX gaps closed

  • Shortcut glyphs now match the menu label scale and use system glyphs on macOS.
  • Light and dark cap fills use existing theme tokens; the theme test checks at least 4.5:1 contrast.
  • Caps remain vertically centred in their 24 px box. Menu spacing continues to use the shared row padding and icon-gap tokens.
  • Menus, tooltips, the search palette, the ? card, and Settings → Shortcuts all inherit the shared primitive.

UX gaps left

None identified in scope. The attached screenshots are ready for the required visual review.

Screenshot evidence

Attached 113 production-build screenshots: the row menu, warm tooltip, palette footer, ? card, and Settings → Shortcuts at 1440 px in 1× and 2× DPR with Paper, Midnight, and Tokyo Night themes; cap crops; 820 px tablet and 390 px phone views; and one real Safari render on the macOS VM.

Download the screenshot archive

Files

  • packages/ui/src/components/Kbd.svelte
  • apps/web/src/lib/components/Kbd.svelte.test.ts
  • apps/web/src/lib/themes.test.ts

Decisions

DESIGN §§34 and 57 already decide the shortcut style; I made no design change. For the cap material, I used the existing --glass-text-muted, --paper-2, and --raised tokens, with system-ui, var(--font-ui) so macOS supplies its menu glyphs.

Verification

  • cargo fmt --check: exit 0; stdout was empty.

  • cargo clippy and cargo test: not run because no Rust code changed.

  • bun run build: passed (exit 0). Build output included: Compressed 883 static variants; saved 20872017 bytes.

  • Focused Vitest command: bunx vitest run src/lib/components/Kbd.svelte.test.ts src/lib/menu/MenuItem.svelte.test.ts src/lib/themes.test.ts --maxWorkers=2

     Test Files  3 passed (3)
          Tests  90 passed (90)
       Start at  15:16:32
       Duration  39.26s (transform 75%, tests 12%, environment 5%, import 5%, setup 3%)
    
      Transform  |component| transforming modules took 26.54s · 78% 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: blocked before Svelte checks by the perf-lint exception ratchet. Exact output:

    perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.blocked-network: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; contract.dom-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.model-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.row-identity: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.snapshot: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.profile: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.readiness: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; io.unresolved-call: 16191 exceptions exceed the ratchet ceiling 16190; fix the new violation instead; render.blaze-adapter: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_byte_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_row_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; total: ledger has 21977 exceptions; ratchet total is 21964
    
  • The real API server and production screenshot runner passed. No API route changed, so no adversarial endpoint probe was needed for this issue.

  • cargo clean completed: Removed 8626 files, 7.2GiB total. Removed apps/web/build and .svelte-kit/output; the screenshot archive remains attached.

The bun run check ratchet mismatch is the known gate gap; no performance ledger files changed in this job.

Feature commit: bae18f619f911ead8d20695984f59a8fcade5199
Head after required origin/dev merge: d864ec0441414f3d88b64359dbb3b998067b8d00

## Completed — #1134 Improved the shared `Kbd` cap while keeping the decided #710 / DESIGN §§34, 57 shortcut format. Modifier glyphs now use the system UI font stack at the menu label size. Caps use the existing readable secondary text and paper/raised surface tokens, and active menu caps follow the selected row foreground. A theme contract checks AA text contrast across all 36 themes. ### UX gaps closed - Shortcut glyphs now match the menu label scale and use system glyphs on macOS. - Light and dark cap fills use existing theme tokens; the theme test checks at least 4.5:1 contrast. - Caps remain vertically centred in their 24 px box. Menu spacing continues to use the shared row padding and icon-gap tokens. - Menus, tooltips, the search palette, the ? card, and Settings → Shortcuts all inherit the shared primitive. ### UX gaps left None identified in scope. The attached screenshots are ready for the required visual review. ### Screenshot evidence Attached 113 production-build screenshots: the row menu, warm tooltip, palette footer, ? card, and Settings → Shortcuts at 1440 px in 1× and 2× DPR with Paper, Midnight, and Tokyo Night themes; cap crops; 820 px tablet and 390 px phone views; and one real Safari render on the macOS VM. [Download the screenshot archive](https://git.kayg.org/attachments/21ea6f77-9ad7-406f-9554-100a20fc7eea) ### Files - `packages/ui/src/components/Kbd.svelte` - `apps/web/src/lib/components/Kbd.svelte.test.ts` - `apps/web/src/lib/themes.test.ts` ### Decisions DESIGN §§34 and 57 already decide the shortcut style; I made no design change. For the cap material, I used the existing `--glass-text-muted`, `--paper-2`, and `--raised` tokens, with `system-ui, var(--font-ui)` so macOS supplies its menu glyphs. ### Verification - `cargo fmt --check`: exit 0; stdout was empty. - `cargo clippy` and `cargo test`: not run because no Rust code changed. - `bun run build`: passed (exit 0). Build output included: `Compressed 883 static variants; saved 20872017 bytes.` - Focused Vitest command: `bunx vitest run src/lib/components/Kbd.svelte.test.ts src/lib/menu/MenuItem.svelte.test.ts src/lib/themes.test.ts --maxWorkers=2` ```text Test Files 3 passed (3) Tests 90 passed (90) Start at 15:16:32 Duration 39.26s (transform 75%, tests 12%, environment 5%, import 5%, setup 3%) Transform |component| transforming modules took 26.54s · 78% 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`: blocked before Svelte checks by the perf-lint exception ratchet. Exact output: ```text perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.blocked-network: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; contract.dom-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.model-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.row-identity: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.snapshot: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.profile: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.readiness: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; io.unresolved-call: 16191 exceptions exceed the ratchet ceiling 16190; fix the new violation instead; render.blaze-adapter: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_byte_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_row_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; total: ledger has 21977 exceptions; ratchet total is 21964 ``` - The real API server and production screenshot runner passed. No API route changed, so no adversarial endpoint probe was needed for this issue. - `cargo clean` completed: `Removed 8626 files, 7.2GiB total`. Removed `apps/web/build` and `.svelte-kit/output`; the screenshot archive remains attached. The `bun run check` ratchet mismatch is the known gate gap; no performance ledger files changed in this job. Feature commit: `bae18f619f911ead8d20695984f59a8fcade5199` Head after required `origin/dev` merge: `d864ec0441414f3d88b64359dbb3b998067b8d00`
Author
Owner

Orchestrator review of artifacts/kbd-1134 (head d864ec044): menus are good. One defect to fix before merge:

  • Glyphs sit high inside the cap. palette-footer-desktop-1440-2x-paper-3x.png: "↩", "⌘↩" and "⌘K" are visibly above the cap's vertical centre (more space below than above); the menu "⌘⌫" cap shows the same, slightly. Centre the glyph run optically in the cap at every size: use the font's cap-height/ascent metrics (e.g. text-box: trim-both cap alphabetic where supported, with a line-height/padding fallback), not a fixed padding nudge. Symbols (⌘ ⇧ ⌥ ⌃ ↩ ⌫) and letters must share one optical centre line with the label beside the cap.
  • Light themes: the cap fill on Paper is very faint; keep text contrast ≥ 4.5:1 and make the cap edge visible (hairline token) without adding weight.

Add a geometry assertion: for each cap, |glyph-box centre − cap centre| ≤ 0.5 px and |cap centre − adjacent label x-height centre| ≤ 1 px, in Chromium and WebKit. Retake the 3x crops (palette footer, row menu, tooltip, ? card) in Paper and Tokyo Night. Commit; comment on #1134 with head SHA. Do not push.

Orchestrator review of artifacts/kbd-1134 (head d864ec044): menus are good. One defect to fix before merge: - **Glyphs sit high inside the cap.** palette-footer-desktop-1440-2x-paper-3x.png: "↩", "⌘↩" and "⌘K" are visibly above the cap's vertical centre (more space below than above); the menu "⌘⌫" cap shows the same, slightly. Centre the glyph run optically in the cap at every size: use the font's cap-height/ascent metrics (e.g. `text-box: trim-both cap alphabetic` where supported, with a line-height/padding fallback), not a fixed padding nudge. Symbols (⌘ ⇧ ⌥ ⌃ ↩ ⌫) and letters must share one optical centre line with the label beside the cap. - Light themes: the cap fill on Paper is very faint; keep text contrast ≥ 4.5:1 and make the cap edge visible (hairline token) without adding weight. Add a geometry assertion: for each cap, |glyph-box centre − cap centre| ≤ 0.5 px and |cap centre − adjacent label x-height centre| ≤ 1 px, in Chromium and WebKit. Retake the 3x crops (palette footer, row menu, tooltip, ? card) in Paper and Tokyo Night. Commit; comment on #1134 with head SHA. Do not push.
Author
Owner

Starting the optical-centering follow-up on branch job/kbd-1134. Review head: d864ec0441414f3d88b64359dbb3b998067b8d00; merge-base with the current local origin/dev: 04afb0043c559c59084e4ec12609bb9fe679cbf6. I will add the cap geometry coverage, retake the requested 3x crops, run the focused web gates, and report the resulting head SHA.

Starting the optical-centering follow-up on branch `job/kbd-1134`. Review head: `d864ec0441414f3d88b64359dbb3b998067b8d00`; merge-base with the current local `origin/dev`: `04afb0043c559c59084e4ec12609bb9fe679cbf6`. I will add the cap geometry coverage, retake the requested 3x crops, run the focused web gates, and report the resulting head SHA.
Author
Owner

Finding: the cap element was centered as a flex box, but its text kept the full single-line leading, so the box centre did not represent the font cap-to-baseline centre. Paper also used the translucent glass border token for the cap edge. The shared component now wraps the glyph run for cap-height trimming and uses the theme hairline tokens; focused Kbd and theme tests pass (86 tests).

Finding: the cap element was centered as a flex box, but its text kept the full single-line leading, so the box centre did not represent the font cap-to-baseline centre. Paper also used the translucent glass border token for the cap edge. The shared component now wraps the glyph run for cap-height trimming and uses the theme hairline tokens; focused Kbd and theme tests pass (86 tests).
Author
Owner

Found one additional geometry defect while extending #1134 coverage to the narrow ? card: at 390 px, its shortcut cap sat 3 px below the primary label because the mobile row aligned the cap against the label-plus-hint block. Updated ShortcutList to place the label, cap, and action in one grid row, with the hint below. The production run now passes in Chromium and WebKit at 390, 820, and 1440 px in Paper and Tokyo Night: glyph-to-cap offset is at most 0.008 px, cap-to-label x-height offset is at most 0.5 px in Chromium and 1 px in WebKit. Refreshed the exact perf-lint syntax pins for the changed component; exception count is unchanged.

Found one additional geometry defect while extending #1134 coverage to the narrow `?` card: at 390 px, its shortcut cap sat 3 px below the primary label because the mobile row aligned the cap against the label-plus-hint block. Updated `ShortcutList` to place the label, cap, and action in one grid row, with the hint below. The production run now passes in Chromium and WebKit at 390, 820, and 1440 px in Paper and Tokyo Night: glyph-to-cap offset is at most 0.008 px, cap-to-label x-height offset is at most 0.5 px in Chromium and 1 px in WebKit. Refreshed the exact perf-lint syntax pins for the changed component; exception count is unchanged.
Author
Owner

Completed — #1134 optical alignment follow-up

Committed on job/kbd-1134: 7f8e87300d642afa0b68fa1b8af62546d5db0460. The required origin/dev merge is included. No push was made.

What changed

The shared Kbd cap now centers its joined glyph run using cap-to-alphabetic text-box metrics where supported, with a line-height fallback. Its hairline border makes the edge visible, and the Paper/Tokyo Night fills retain AA text contrast. ShortcutList now keeps each cap in the primary label row when the label wraps on a phone; the hint sits below. The production browser check asserts glyph-box-to-cap center ≤ 0.5 px and cap-to-label x-height center ≤ 1 px in Chromium and WebKit.

UX gaps closed

  • Glyph and adjacent label alignment passes at 390, 820, and 1440 px.
  • Paper and Tokyo Night cap text contrast measured 7.37:1 and 7.00:1.
  • Captured the palette footer, row menu, tooltip, and ? card in both themes at all three widths, with macOS platform emulation.

UX gaps left

None found within this correction. The existing web check reports four warnings in three files: two empty rulesets in calendar UI and two unused selectors in the Notes route.

Screenshot evidence

All 24 new 3× crops are attached to this issue:

Files

  • packages/ui/src/components/Kbd.svelte
  • apps/web/src/lib/components/ShortcutList.svelte
  • apps/web/src/lib/components/Kbd.svelte.test.ts
  • apps/web/src/lib/themes.test.ts
  • apps/web/e2e/kbd-1134.mjs
  • apps/web/package.json
  • contracts/perf/exceptions.json

Decisions

DESIGN does not specify the narrow layout for shortcut rows with a wrapped label and hint. I use a three-column grid so the cap shares the primary label row and the hint occupies the next row. Unsupported text-box implementations keep the single-line centered fallback.

Verification

  • cargo fmt --check: exit 0; stdout empty.

  • cargo clippy and cargo test: not run; this correction changed no Rust source.

  • bun run check passed. Exact summaries:

    perf-lint: PASS; 0 violations; 22115 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
    
  • bunx --silent vitest run src/lib/components/Kbd.svelte.test.ts src/lib/components/ShortcutList.svelte.test.ts src/lib/themes.test.ts --maxWorkers=2:

     Test Files  3 passed (3)
          Tests  87 passed (87)
       Start at  22:14:54
       Duration  53.08s (transform 65%, environment 20%, tests 7%, setup 5%, import 4%)
    
  • CALTERNAL_SERVER_BIN=/home/kayg/build/targets/kbd2-1134/debug/calternal-server TMPDIR=/home/kayg/Developer/calternal-wt/kbd-1134/target/tmp bun run test:e2e:kbd-1134 passed. Chromium max offsets: glyph 0.008 px, label x-height 0.500 px. WebKit max offsets: glyph 0.008 px, label x-height 1.000 px. Paper and Tokyo Night contrast: 7.37:1 and 7.00:1.

    PASS #1134: chromium and webkit geometry checked at 390, 820 and 1440px; Paper and Tokyo Night 3x crops saved under /home/kayg/Developer/calternal-wt/kbd-1134/artifacts/kbd-1134
    
  • cargo clean: Removed 8744 files, 8.2GiB total. Web build output was removed. The worktree is clean.

## Completed — #1134 optical alignment follow-up Committed on `job/kbd-1134`: `7f8e87300d642afa0b68fa1b8af62546d5db0460`. The required `origin/dev` merge is included. No push was made. ### What changed The shared Kbd cap now centers its joined glyph run using cap-to-alphabetic text-box metrics where supported, with a line-height fallback. Its hairline border makes the edge visible, and the Paper/Tokyo Night fills retain AA text contrast. `ShortcutList` now keeps each cap in the primary label row when the label wraps on a phone; the hint sits below. The production browser check asserts glyph-box-to-cap center ≤ 0.5 px and cap-to-label x-height center ≤ 1 px in Chromium and WebKit. ### UX gaps closed - Glyph and adjacent label alignment passes at 390, 820, and 1440 px. - Paper and Tokyo Night cap text contrast measured 7.37:1 and 7.00:1. - Captured the palette footer, row menu, tooltip, and ? card in both themes at all three widths, with macOS platform emulation. ### UX gaps left None found within this correction. The existing web check reports four warnings in three files: two empty rulesets in calendar UI and two unused selectors in the Notes route. ### Screenshot evidence All 24 new 3× crops are attached to this issue: - Palette footer: [mobile Paper](https://git.kayg.org/attachments/3bc57cfa-f5f6-425a-b4d8-8cd9fda0a7ef), [mobile Tokyo Night](https://git.kayg.org/attachments/484e7eb4-c528-438b-85a7-b0f9621cdd7f), [tablet Paper](https://git.kayg.org/attachments/8a6fd91a-b040-42c4-94e0-2d060afdce0d), [tablet Tokyo Night](https://git.kayg.org/attachments/e552b094-ff19-4821-8bdb-80a5de6b0f72), [desktop Paper](https://git.kayg.org/attachments/21e998b7-b774-4fbd-b338-adb59a2ce25a), [desktop Tokyo Night](https://git.kayg.org/attachments/791c8e62-b51d-47dd-aa57-a0b8f962c39f). - Row menu: [mobile Paper](https://git.kayg.org/attachments/14d27408-969a-43b5-bae6-bcd48ee29599), [mobile Tokyo Night](https://git.kayg.org/attachments/831f4932-56dd-4b7b-b134-7cc9b126e0cc), [tablet Paper](https://git.kayg.org/attachments/15644757-286f-49a0-b734-e439fd987d9f), [tablet Tokyo Night](https://git.kayg.org/attachments/3ff0c2fd-52dc-4d99-94c3-353d5f94d3d4), [desktop Paper](https://git.kayg.org/attachments/3e89dcbf-ffba-4c09-9601-6c64e81ed58f), [desktop Tokyo Night](https://git.kayg.org/attachments/47a6002f-ef8d-43d3-9287-2235d7897bf7). - Tooltip: [mobile Paper](https://git.kayg.org/attachments/2f4ef302-d79f-4d05-98d0-4fd3fdb7e401), [mobile Tokyo Night](https://git.kayg.org/attachments/7d1aa59b-0d29-45e2-b9d0-0d66dbd06f41), [tablet Paper](https://git.kayg.org/attachments/6cbcaf77-d150-4e59-9078-d17b04f309ea), [tablet Tokyo Night](https://git.kayg.org/attachments/4e1ee0d3-ec90-4288-ad0c-f0a963114b59), [desktop Paper](https://git.kayg.org/attachments/1487d80e-4236-4530-a8df-dcbd3ee6fccd), [desktop Tokyo Night](https://git.kayg.org/attachments/8d6d20f1-8ae1-4c6b-a457-277d3091c283). - ? card: [mobile Paper](https://git.kayg.org/attachments/244d3932-5c57-461a-a613-0b10d27da35d), [mobile Tokyo Night](https://git.kayg.org/attachments/dcac7a5c-9e3b-4117-b8a1-ee1e03e219fb), [tablet Paper](https://git.kayg.org/attachments/25e2a8a1-9ecb-4caf-af4a-fc5f1c36dac1), [tablet Tokyo Night](https://git.kayg.org/attachments/284aa9c2-c7f5-4461-a480-ca89ec729eb5), [desktop Paper](https://git.kayg.org/attachments/f35dda7b-3b9c-4f1e-9f22-2e718a9a2832), [desktop Tokyo Night](https://git.kayg.org/attachments/548a51a9-c8c2-4e15-9cd4-0d59b8cfa5e9). ### Files - `packages/ui/src/components/Kbd.svelte` - `apps/web/src/lib/components/ShortcutList.svelte` - `apps/web/src/lib/components/Kbd.svelte.test.ts` - `apps/web/src/lib/themes.test.ts` - `apps/web/e2e/kbd-1134.mjs` - `apps/web/package.json` - `contracts/perf/exceptions.json` ### Decisions DESIGN does not specify the narrow layout for shortcut rows with a wrapped label and hint. I use a three-column grid so the cap shares the primary label row and the hint occupies the next row. Unsupported `text-box` implementations keep the single-line centered fallback. ### Verification - `cargo fmt --check`: exit 0; stdout empty. - `cargo clippy` and `cargo test`: not run; this correction changed no Rust source. - `bun run check` passed. Exact summaries: ```text perf-lint: PASS; 0 violations; 22115 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 ``` - `bunx --silent vitest run src/lib/components/Kbd.svelte.test.ts src/lib/components/ShortcutList.svelte.test.ts src/lib/themes.test.ts --maxWorkers=2`: ```text Test Files 3 passed (3) Tests 87 passed (87) Start at 22:14:54 Duration 53.08s (transform 65%, environment 20%, tests 7%, setup 5%, import 4%) ``` - `CALTERNAL_SERVER_BIN=/home/kayg/build/targets/kbd2-1134/debug/calternal-server TMPDIR=/home/kayg/Developer/calternal-wt/kbd-1134/target/tmp bun run test:e2e:kbd-1134` passed. Chromium max offsets: glyph 0.008 px, label x-height 0.500 px. WebKit max offsets: glyph 0.008 px, label x-height 1.000 px. Paper and Tokyo Night contrast: 7.37:1 and 7.00:1. ```text PASS #1134: chromium and webkit geometry checked at 390, 820 and 1440px; Paper and Tokyo Night 3x crops saved under /home/kayg/Developer/calternal-wt/kbd-1134/artifacts/kbd-1134 ``` - `cargo clean`: `Removed 8744 files, 8.2GiB total`. Web build output was removed. The worktree is clean.
Author
Owner

Correction to the screenshot index in my final report: the Palette footer, mobile Tokyo Night crop is attached at https://git.kayg.org/attachments/484e7eb4-c528-438b-85b1-4500e2267dfe. The other 23 links are valid.

Correction to the screenshot index in my final report: the Palette footer, mobile Tokyo Night crop is attached at https://git.kayg.org/attachments/484e7eb4-c528-438b-85b1-4500e2267dfe. The other 23 links are valid.
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#1134
No description provided.