Focus ring: thick black double ring on popover rows and inputs; one shared focus-visible token everywhere #658

Open
opened 2026-10-02 04:24:18 +00:00 by kayg · 10 comments
Owner

Owner screenshots (2026-10-02)

Keyboard focus shows a thick black double ring with square or near-square corners on several surfaces. In the Calendar "+N" All-day items popover it is a heavy black ring that overlaps the heading above. In the search palette it is a harsh square box around the input (#499). It looks like the browser default outline stacked on our own ring, or a high-contrast ring token used at the wrong strength.

Expected

One shared focus-visible treatment from tokens, used by every interactive element:

  • Shape: rounded to the element's own radius.
  • Colour: the accent colour at the documented focus width with a small offset. It meets WCAG 2.2 focus appearance (≥ 2 px, ≥ 3:1 contrast) in both themes without a black double ring.
  • When: only for keyboard focus (:focus-visible), never after a pointer click.
  • No browser default outline under our ring.
  • Never clipped by, or overlapping, neighbouring headings or text. Use the inset variant inside tight lists.
    Audit every component in packages/ui and the app for local outline/box-shadow focus styles, remove them in favour of the token, and add a guard check (like the type-token guard) that fails on new local focus styles. Screenshots of focus states on: search input, popover rows, menu items, Tab Bar, sidebar rows, buttons, inputs, at 1440 in both themes, zoomed 3x.
## Owner screenshots (2026-10-02) Keyboard focus shows a **thick black double ring with square or near-square corners** on several surfaces. In the Calendar "+N" All-day items popover it is a heavy black ring that overlaps the heading above. In the search palette it is a harsh square box around the input (#499). It looks like the browser default outline stacked on our own ring, or a high-contrast ring token used at the wrong strength. ## Expected One shared focus-visible treatment from tokens, used by every interactive element: - **Shape:** rounded to the element's own radius. - **Colour:** the accent colour at the documented focus width with a small offset. It meets WCAG 2.2 focus appearance (≥ 2 px, ≥ 3:1 contrast) in both themes without a black double ring. - **When:** only for keyboard focus (`:focus-visible`), never after a pointer click. - **No browser default outline** under our ring. - **Never clipped by, or overlapping, neighbouring headings or text.** Use the inset variant inside tight lists. Audit every component in `packages/ui` and the app for local outline/box-shadow focus styles, remove them in favour of the token, and add a guard check (like the type-token guard) that fails on new local focus styles. Screenshots of focus states on: search input, popover rows, menu items, Tab Bar, sidebar rows, buttons, inputs, at 1440 in both themes, zoomed 3x.
Author
Owner

Starting focus-ring audit on job/focus-658, based on dev at c4a61e8cf090170f35b1bed3350d9de20c83ecd5. The worktree is clean. I am tracing the current shared token, global input-modality rules, and local ring overrides before changing the shared treatment and adding the guard. I will leave SearchField.svelte and the Calendar +N popover files to their owners and report their current local ring rules for adoption.

Starting focus-ring audit on `job/focus-658`, based on `dev` at `c4a61e8cf090170f35b1bed3350d9de20c83ecd5`. The worktree is clean. I am tracing the current shared token, global input-modality rules, and local ring overrides before changing the shared treatment and adding the guard. I will leave `SearchField.svelte` and the Calendar +N popover files to their owners and report their current local ring rules for adoption.
Author
Owner

Finding: the shared ring is not shared today. packages/ui/src/tokens.css defines --focus-ring as a paper/accent box-shadow, while apps/web/src/calternal-app.css overrides it with a 2.5 px ink outline and adds a second box-shadow band. Components then add their own offsets and colours, including outline: 2px solid var(--accent) and inset shadows. The new guard currently fails on those local focus declarations as expected. I am collapsing these to one token rule and keeping only the app's root input-modality suppression.

Finding: the shared ring is not shared today. `packages/ui/src/tokens.css` defines `--focus-ring` as a paper/accent box-shadow, while `apps/web/src/calternal-app.css` overrides it with a 2.5 px ink outline and adds a second box-shadow band. Components then add their own offsets and colours, including `outline: 2px solid var(--accent)` and inset shadows. The new guard currently fails on those local focus declarations as expected. I am collapsing these to one token rule and keeping only the app's root input-modality suppression.
Author
Owner

Static review evidence for #658 from rev-consistency (#427), origin/dev at c4a61e8cf090170f35b1bed3350d9de20c83ecd5:

  • packages/ui/src/tokens.css:539 defines --focus-ring as a two-band box-shadow value. apps/web/src/calternal-app.css:526 redefines the same name as an outline shorthand. The primitive has two incompatible contracts.
  • apps/web/src/calternal-app.css:250-255 applies that outline plus another two-band box-shadow to every :focus-visible element. Updating a component outline alone does not remove this shadow.
  • apps/web/src/lib/editor/format/BlockReminderPicker.svelte:351 says outline: 2px solid var(--focus-ring). In the app, substitution yields 2px solid 2.5px solid var(--focus-ring-outer), which is invalid outline syntax. The global rule remains as the fallback.
  • Local rings also remain at apps/web/src/lib/photos/PhotoTimeline.svelte:857-859 (2.5 px accent), apps/web/src/lib/files/PublicLinkPage.svelte:1014-1016 (2 px accent), and apps/web/src/routes/calendar/[view]/[date]/+page.svelte:2365-2368.

Keep these in #658's shared fix. Expected: one token contract and one focus treatment; use a named inset role for tight rows. Test that no token shorthand is used as a colour. After changing the shared role, check keyboard, pointer and reduced-motion focus on the reminder fields, photos and public-link fields, in both themes at 390/820/1440 px. This is source evidence, not a rendered contrast or ring-thickness measurement. No new duplicate issue was filed.

Static review evidence for #658 from rev-consistency (#427), `origin/dev` at `c4a61e8cf090170f35b1bed3350d9de20c83ecd5`: - `packages/ui/src/tokens.css:539` defines `--focus-ring` as a two-band **box-shadow** value. `apps/web/src/calternal-app.css:526` redefines the same name as an **outline** shorthand. The primitive has two incompatible contracts. - `apps/web/src/calternal-app.css:250-255` applies that outline plus another two-band box-shadow to every `:focus-visible` element. Updating a component outline alone does not remove this shadow. - `apps/web/src/lib/editor/format/BlockReminderPicker.svelte:351` says `outline: 2px solid var(--focus-ring)`. In the app, substitution yields `2px solid 2.5px solid var(--focus-ring-outer)`, which is invalid outline syntax. The global rule remains as the fallback. - Local rings also remain at `apps/web/src/lib/photos/PhotoTimeline.svelte:857-859` (2.5 px accent), `apps/web/src/lib/files/PublicLinkPage.svelte:1014-1016` (2 px accent), and `apps/web/src/routes/calendar/[view]/[date]/+page.svelte:2365-2368`. Keep these in #658's shared fix. Expected: one token contract and one focus treatment; use a named inset role for tight rows. Test that no token shorthand is used as a colour. After changing the shared role, check keyboard, pointer and reduced-motion focus on the reminder fields, photos and public-link fields, in both themes at 390/820/1440 px. This is source evidence, not a rendered contrast or ring-thickness measurement. No new duplicate issue was filed.
Author
Owner

Finding: the app's pointer-modality backstop also set box-shadow: none. That hid the old global ring shadow, but it also removed ordinary control shadows when a browser kept :focus-visible after pointer input. The shared ring now uses outline, so pointer suppression clears only that outline. Pill groups and clipped segmented controls now opt into the token's inset offset through data-focus-ring-children="inset".

The guard preserves exact unchanged baselines for the active SearchField and calendar jobs: SearchField .query-input outline reset; GridColumn .block, .more, and .pile focus outlines; TimeGrid .tg-body outline reset and focus shadow, plus .more-item outline. Those components remain untouched for their owners to adopt the token.

Finding: the app's pointer-modality backstop also set `box-shadow: none`. That hid the old global ring shadow, but it also removed ordinary control shadows when a browser kept `:focus-visible` after pointer input. The shared ring now uses `outline`, so pointer suppression clears only that outline. Pill groups and clipped segmented controls now opt into the token's inset offset through `data-focus-ring-children="inset"`. The guard preserves exact unchanged baselines for the active SearchField and calendar jobs: SearchField `.query-input` outline reset; GridColumn `.block`, `.more`, and `.pile` focus outlines; TimeGrid `.tg-body` outline reset and focus shadow, plus `.more-item` outline. Those components remain untouched for their owners to adopt the token.
Author
Owner

Source-audit evidence from rev-a11y, initial origin/dev c4a61e8cf090170f35b1bed3350d9de20c83ecd5. No product changes.

apps/web/src/calternal-app.css:252–257 combines the global outline with two box-shadow bands. The shared package also defines a global outline in packages/ui/src/tokens.css:1487. Local variants include packages/ui/src/components/Select.svelte:107, apps/web/src/lib/photos/TimelineScrubber.svelte:213, packages/ui/src/actions/resizableEdge.ts:94, apps/web/src/lib/components/money/AssignedCell.svelte:130, and apps/web/src/lib/components/analytics/BklitAnalytics.tsx:348.

The guard should test indirect focus paint too: packages/ui/src/components/Checkbox.svelte:181 draws the ring on the indicator next to a transparent native input. A test that checks only the active input will miss that ring. This evidence belongs in #658; no duplicate ring-style issue was filed. No rendered contrast failure is claimed by this source-only audit.

WCAG distinction for acceptance: Focus Visible (2.4.7) and Focus Not Obscured (Minimum) (2.4.11) are AA. Focus Appearance (2.4.13) is AAA; the owner's 2 px/3:1 requirement remains binding as a stronger project rule.

Source-audit evidence from rev-a11y, initial `origin/dev` `c4a61e8cf090170f35b1bed3350d9de20c83ecd5`. No product changes. `apps/web/src/calternal-app.css:252–257` combines the global outline with two box-shadow bands. The shared package also defines a global outline in `packages/ui/src/tokens.css:1487`. Local variants include `packages/ui/src/components/Select.svelte:107`, `apps/web/src/lib/photos/TimelineScrubber.svelte:213`, `packages/ui/src/actions/resizableEdge.ts:94`, `apps/web/src/lib/components/money/AssignedCell.svelte:130`, and `apps/web/src/lib/components/analytics/BklitAnalytics.tsx:348`. The guard should test indirect focus paint too: `packages/ui/src/components/Checkbox.svelte:181` draws the ring on the indicator next to a transparent native input. A test that checks only the active input will miss that ring. This evidence belongs in #658; no duplicate ring-style issue was filed. No rendered contrast failure is claimed by this source-only audit. WCAG distinction for acceptance: Focus Visible (2.4.7) and Focus Not Obscured (Minimum) (2.4.11) are AA. Focus Appearance (2.4.13) is AAA; the owner's 2 px/3:1 requirement remains binding as a stronger project rule.
Author
Owner

Built

  • One shared keyboard focus ring uses --focus-ring: 2px solid var(--accent), a 2px outer offset, and a -2px inset offset for dense rows and active-descendant targets.
  • Removed local outline and focus box-shadow rings across the app, UI and editor. Pointer focus remains suppressed.
  • Added check-focus-tokens.mjs to bun run check; it allows only the exact current SearchField and Calendar overrides owned by #499 and #655/#657.
  • Extended the large-file keyboard profile to assert that a 1,000-file active row uses the shared token.

Files

  • Core: packages/ui/src/tokens.css, apps/web/src/calternal-app.css, apps/web/scripts/check-focus-tokens.mjs, apps/web/package.json, apps/web/src/lib/themes.test.ts.
  • Cleanup: 76 source files in apps/web/src, packages/ui/src and packages/editor/src.
  • Profile: apps/web/e2e/kbd-motion-527.mjs.

UX gaps closed

  • One rounded, 2px accent ring now owns keyboard focus across the shared UI. Dense lists and active-descendant composites use the inset token hook.
  • The pointer modality suppression and keyboard-only focus checks remain in place. The guard catches new local ring styles.
  • Captured 22 production SPA focus crops at device scale factor 3 with macOS platform emulation; the set covers both themes, the issue’s 1440px focus targets and responsive Tab Bar crops at 390px and 820px.

UX gaps left

  • SearchField’s .query-input { outline: none } remains for #499. Calendar’s .block, .more and .pile local outlines in GridColumn.svelte, plus .tg-body reset/ring and .more-item outline in TimeGrid.svelte, remain exact guard baselines for #655/#657 to migrate.
  • The local 1,000-file profile did not reach metric collection. bun bench/kbd-motion-527.mjs --json artifacts/focus-658/performance.json stopped in the existing motion contract at AssertionError: keyboard selection move runs motion on the focused row (kbd-motion-527.mjs:377). Across the nominal 450ms delay and follow-up click, Chromium animation time advanced about 3.2s; host load averages were 114.97, 124.05, 126.26 then and rose above 148 during Vitest. No comparable profile exists in docs/perf/baseline.json.
  • Native macOS rendering was unavailable because the Mac VM is offline. The screenshots emulate macOS as required.

Decisions

  • Where the design text did not specify composite markup, use data-focus-ring='inset' for constrained controls, data-focus-ring-owner / data-focus-ring-target for active-descendant widgets, and data-focus-ring-proxy for hidden native focus owners. This keeps one visual token and leaves ring geometry in tokens.css.
  • Keep only the precise SearchField and Calendar declarations in the guard baseline while their owners finish active work; any drift or new local focus ring fails the guard.

Screenshots

These are attached to #658 (macOS platform emulation, 3×):

Gates and evidence

bun run check:

$ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-focus-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
User browser caches use userStorage; only documented device/public-link exceptions remain.
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.
Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/focus-658/apps/web
Getting Svelte diagnostics...

svelte-check found 0 errors and 0 warnings

bun run test:

 Test Files  8 failed | 124 passed (132)
      Tests  10 failed | 872 passed (882)
     Errors  21 errors
   Start at  17:38:44
   Duration  995.27s (transform 75%, import 11%, environment 9%, tests 3%, setup 2%)
error: script "test" exited with code 1

Nine tests hit their 5s timeout; the follow-on search test reported Search provider already registered: navigation. Vitest also reported 21 worker start/response errors. Host load averaged 143–165 during this run. No test expectation was changed.

bun run build passed before the final gates: ✓ built in 3m 38s. git diff --check HEAD~2..HEAD passed. No Rust source changed. cargo clean output: Removed 1398 files, 624.7MiB total; apps/web/build and the temporary media sandbox were removed.

Head: e35f66ed3485c3a621c5f39b473af62c7c17a09c (job/focus-658). git merge origin/dev reported Already up to date.

## Built - One shared keyboard focus ring uses `--focus-ring: 2px solid var(--accent)`, a 2px outer offset, and a -2px inset offset for dense rows and active-descendant targets. - Removed local outline and focus box-shadow rings across the app, UI and editor. Pointer focus remains suppressed. - Added `check-focus-tokens.mjs` to `bun run check`; it allows only the exact current SearchField and Calendar overrides owned by #499 and #655/#657. - Extended the large-file keyboard profile to assert that a 1,000-file active row uses the shared token. ## Files - Core: `packages/ui/src/tokens.css`, `apps/web/src/calternal-app.css`, `apps/web/scripts/check-focus-tokens.mjs`, `apps/web/package.json`, `apps/web/src/lib/themes.test.ts`. - Cleanup: 76 source files in `apps/web/src`, `packages/ui/src` and `packages/editor/src`. - Profile: `apps/web/e2e/kbd-motion-527.mjs`. ## UX gaps closed - One rounded, 2px accent ring now owns keyboard focus across the shared UI. Dense lists and active-descendant composites use the inset token hook. - The pointer modality suppression and keyboard-only focus checks remain in place. The guard catches new local ring styles. - Captured 22 production SPA focus crops at device scale factor 3 with macOS platform emulation; the set covers both themes, the issue’s 1440px focus targets and responsive Tab Bar crops at 390px and 820px. ## UX gaps left - SearchField’s `.query-input { outline: none }` remains for #499. Calendar’s `.block`, `.more` and `.pile` local outlines in `GridColumn.svelte`, plus `.tg-body` reset/ring and `.more-item` outline in `TimeGrid.svelte`, remain exact guard baselines for #655/#657 to migrate. - The local 1,000-file profile did not reach metric collection. `bun bench/kbd-motion-527.mjs --json artifacts/focus-658/performance.json` stopped in the existing motion contract at `AssertionError: keyboard selection move runs motion on the focused row` (`kbd-motion-527.mjs:377`). Across the nominal 450ms delay and follow-up click, Chromium animation time advanced about 3.2s; host load averages were `114.97, 124.05, 126.26` then and rose above 148 during Vitest. No comparable profile exists in `docs/perf/baseline.json`. - Native macOS rendering was unavailable because the Mac VM is offline. The screenshots emulate macOS as required. ## Decisions - Where the design text did not specify composite markup, use `data-focus-ring='inset'` for constrained controls, `data-focus-ring-owner` / `data-focus-ring-target` for active-descendant widgets, and `data-focus-ring-proxy` for hidden native focus owners. This keeps one visual token and leaves ring geometry in `tokens.css`. - Keep only the precise SearchField and Calendar declarations in the guard baseline while their owners finish active work; any drift or new local focus ring fails the guard. ## Screenshots These are attached to #658 (macOS platform emulation, 3×): - [button-dark-macos-3x](https://git.kayg.org/attachments/9a63f54e-23d5-4959-9eb9-2d5840595368) - [button-light-macos-3x](https://git.kayg.org/attachments/3c62cf05-f623-4213-adb4-afa72bad73c5) - [calendar-more-row-dark-macos-3x](https://git.kayg.org/attachments/4776a5ae-b89e-4e28-9200-2c7fc860cf0c) - [calendar-more-row-light-macos-3x](https://git.kayg.org/attachments/fedcd596-cadf-4aa4-a592-26c179aab2bd) - [mac-shortcut-tip-dark-macos-3x](https://git.kayg.org/attachments/3b7a8331-f8b7-4853-810d-290845c70b14) - [mac-shortcut-tip-light-macos-3x](https://git.kayg.org/attachments/a3377805-df56-4bc7-bdd6-b8020edba585) - [menu-item-dark-macos-3x](https://git.kayg.org/attachments/ab7bebc4-bb1b-4c54-9e94-707bf259d7dd) - [menu-item-light-macos-3x](https://git.kayg.org/attachments/99a725f3-2102-45d6-8ff5-86f7aa1c70da) - [responsive-1440-dark-macos-3x](https://git.kayg.org/attachments/7fb5c0be-184a-4b90-8aad-42aa6baaacf1) - [responsive-1440-light-macos-3x](https://git.kayg.org/attachments/9193878d-a5a4-461d-9882-6e87a57bc108) - [responsive-390-dark-macos-3x](https://git.kayg.org/attachments/538e217f-35f3-4b45-8b12-7cd7cfc386d8) - [responsive-390-light-macos-3x](https://git.kayg.org/attachments/fac792c3-7885-468d-a5c9-a61e036ce06e) - [responsive-820-dark-macos-3x](https://git.kayg.org/attachments/4f660261-92d1-4f94-8c88-3f272a065c8a) - [responsive-820-light-macos-3x](https://git.kayg.org/attachments/b8ef3902-086f-42f5-abf3-6eecc8b34401) - [search-input-dark-macos-3x](https://git.kayg.org/attachments/9d67c92f-1e1c-42c1-b15c-848e18f48a51) - [search-input-light-macos-3x](https://git.kayg.org/attachments/2a9db8e3-f60e-4d4f-869e-8c96899545aa) - [sidebar-row-dark-macos-3x](https://git.kayg.org/attachments/23e7aac7-2bf4-4a04-b571-c343b87f30b8) - [sidebar-row-light-macos-3x](https://git.kayg.org/attachments/08d6d430-6311-4b36-bf79-90808d391bc6) - [tab-bar-dark-macos-3x](https://git.kayg.org/attachments/11bd1890-98e7-41fd-bb90-f353a8c20de8) - [tab-bar-light-macos-3x](https://git.kayg.org/attachments/82406b70-430f-4bc8-8091-1e4a1fe3a798) - [text-input-dark-macos-3x](https://git.kayg.org/attachments/89708efa-acd5-482a-804c-90bc2e22f90c) - [text-input-light-macos-3x](https://git.kayg.org/attachments/a56f500e-cdd3-41e4-89d1-f970e2a82a8e) ## Gates and evidence `bun run check`: ```text $ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-focus-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json User browser caches use userStorage; only documented device/public-link exceptions remain. 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. Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/focus-658/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` `bun run test`: ```text Test Files 8 failed | 124 passed (132) Tests 10 failed | 872 passed (882) Errors 21 errors Start at 17:38:44 Duration 995.27s (transform 75%, import 11%, environment 9%, tests 3%, setup 2%) error: script "test" exited with code 1 ``` Nine tests hit their 5s timeout; the follow-on search test reported `Search provider already registered: navigation`. Vitest also reported 21 worker start/response errors. Host load averaged 143–165 during this run. No test expectation was changed. `bun run build` passed before the final gates: `✓ built in 3m 38s`. `git diff --check HEAD~2..HEAD` passed. No Rust source changed. `cargo clean` output: `Removed 1398 files, 624.7MiB total`; `apps/web/build` and the temporary media sandbox were removed. Head: `e35f66ed3485c3a621c5f39b473af62c7c17a09c` (`job/focus-658`). `git merge origin/dev` reported `Already up to date.`
Author
Owner

Round 2: continuing the shared focus-ring fix on job/focus-658. Starting HEAD is e35f66ed3485c3a621c5f39b473af62c7c17a09c; the worktree is clean. I am refreshing and merging origin/dev before this round of changes.

Round 2: continuing the shared focus-ring fix on `job/focus-658`. Starting HEAD is `e35f66ed3485c3a621c5f39b473af62c7c17a09c`; the worktree is clean. I am refreshing and merging `origin/dev` before this round of changes.
Author
Owner

Finding from artifacts/focus-658/sidebar-row-light-macos-3x.png: .sidebar-scroll clips horizontal overflow and the Week link reaches its edge; the shared 2px ring with a 2px offset paints 4px beyond that edge. The shared inset-descendant rule existed but was not enabled at these reusable clipping boundaries. I enabled it on the app sidebar, Settings rail and menu list, and added an e2e audit that measures visible focusable row rings against their nearest overflow clip. The audit and screenshot recapture are running now.

Finding from `artifacts/focus-658/sidebar-row-light-macos-3x.png`: `.sidebar-scroll` clips horizontal overflow and the Week link reaches its edge; the shared 2px ring with a 2px offset paints 4px beyond that edge. The shared inset-descendant rule existed but was not enabled at these reusable clipping boundaries. I enabled it on the app sidebar, Settings rail and menu list, and added an e2e audit that measures visible focusable row rings against their nearest overflow clip. The audit and screenshot recapture are running now.
Author
Owner

Round 2 progress for job/focus-658 (merged origin/dev at c4faf184d before edits; work began from e35f66e).

The shared focus-ring rule now insets focus-visible descendants in clipped sidebar, Settings navigation, and menu lists. The e2e geometry guard measures the focused row against its nearest overflow clip and covers Calendar sidebar, Files, Notes, Settings navigation, Mail sidebar and rows, Tab Bar, Calendar overflow, and menu rows.

Capture findings fixed:

  • The menu probe asserted the first row after ArrowDown, while keyboard focus had moved to the next row. It now follows the focused menu item and retains the focus-visible/inset assertions.
  • The tested Files context menu uses visible overflow, so it has no clipping edge; the probe still checks its 2px inset ring and checks clip geometry whenever a clipping ancestor exists.
  • The desktop Calendar overflow button locator escaped its period twice and timed out. The regex now matches the rendered +N more all-day items label.

The sidebar-row-light-macos-3x.png crop now shows the Week ring's left and right sides. A fresh full capture run is in progress after the probe fixes. Screenshots and geometry evidence remain under ignored artifacts/focus-658/.

Round 2 progress for `job/focus-658` (merged `origin/dev` at `c4faf184d` before edits; work began from `e35f66e`). The shared focus-ring rule now insets focus-visible descendants in clipped sidebar, Settings navigation, and menu lists. The e2e geometry guard measures the focused row against its nearest overflow clip and covers Calendar sidebar, Files, Notes, Settings navigation, Mail sidebar and rows, Tab Bar, Calendar overflow, and menu rows. Capture findings fixed: - The menu probe asserted the first row after ArrowDown, while keyboard focus had moved to the next row. It now follows the focused menu item and retains the focus-visible/inset assertions. - The tested Files context menu uses visible overflow, so it has no clipping edge; the probe still checks its 2px inset ring and checks clip geometry whenever a clipping ancestor exists. - The desktop Calendar overflow button locator escaped its period twice and timed out. The regex now matches the rendered `+N more all-day items` label. The `sidebar-row-light-macos-3x.png` crop now shows the Week ring's left and right sides. A fresh full capture run is in progress after the probe fixes. Screenshots and geometry evidence remain under ignored `artifacts/focus-658/`.
Author
Owner

Round 2 report

What changed

The shared focus-ring rule now supports container-level inset focus for descendants in clipped scroll areas. The app Sidebar scrollport, reusable Floating Sidebar navigation, and shared menu list opt in to the existing 2 px inset focus token. This keeps the outline inside clipped edges without adding padding or shifting rows.

Added a production-build E2E geometry guard. It checks 62 visible focus states across nine row surfaces, and captures responsive screens at 390, 820, and 1440 px in light and dark themes. The browser emulates macOS shortcut rendering and uses 3× screenshots. It verifies that focus-ring bounds stay inside the nearest clipping ancestor where one exists.

Files

Round 2 implementation and probe:

  • packages/ui/src/tokens.css
  • apps/web/src/lib/components/app-sidebar.svelte
  • packages/ui/src/components/FloatingSidebar.svelte
  • packages/ui/src/components/menu/Menu.svelte
  • apps/web/e2e/focus-ring-clipping-658.mjs

Full tracked branch file inventory relative to origin/dev (81 files):

Show file inventory
  • apps/web/e2e/focus-ring-clipping-658.mjs
  • apps/web/e2e/kbd-motion-527.mjs
  • apps/web/package.json
  • apps/web/scripts/check-focus-tokens.mjs
  • apps/web/src/calternal-app.css
  • apps/web/src/lib/ai/TurnPanel.svelte
  • apps/web/src/lib/auth/components/RecoveryKeyEntry.svelte
  • apps/web/src/lib/components/AppToaster.svelte
  • apps/web/src/lib/components/KeyboardShortcutsCard.svelte
  • apps/web/src/lib/components/TagEditor.svelte
  • apps/web/src/lib/components/analytics/ActivityCard.svelte
  • apps/web/src/lib/components/analytics/BklitAnalytics.tsx
  • apps/web/src/lib/components/analytics/Dashboard.svelte
  • apps/web/src/lib/components/analytics/HabitsCard.svelte
  • apps/web/src/lib/components/analytics/RangePicker.svelte
  • apps/web/src/lib/components/analytics/widgets/StatRow.svelte
  • apps/web/src/lib/components/app-sidebar.svelte
  • apps/web/src/lib/components/money/AssignedCell.svelte
  • apps/web/src/lib/composer/Composer.svelte
  • apps/web/src/lib/editor/format/BlockHoverActions.svelte
  • apps/web/src/lib/editor/format/BlockReminderPicker.svelte
  • apps/web/src/lib/editor/format/FormatButton.svelte
  • apps/web/src/lib/files/FilesSidebar.svelte
  • apps/web/src/lib/files/PublicLinkPage.svelte
  • apps/web/src/lib/files/ShareDialog.svelte
  • apps/web/src/lib/mail/MailView.svelte
  • apps/web/src/lib/notes/NoteEditorSurface.svelte
  • apps/web/src/lib/notes/NoteImageView.svelte
  • apps/web/src/lib/notes/NoteView.svelte
  • apps/web/src/lib/notes/NotesExplorer.svelte
  • apps/web/src/lib/notifications/InboxPanel.svelte
  • apps/web/src/lib/photos/PhotoTimeline.svelte
  • apps/web/src/lib/photos/TimelineScrubber.svelte
  • apps/web/src/lib/search/SearchPreview.svelte
  • apps/web/src/lib/styles/auth-ui.css
  • apps/web/src/lib/themes.test.ts
  • apps/web/src/routes/calendar/[view]/[date]/+page.svelte
  • apps/web/src/routes/layout.css
  • apps/web/src/routes/money/[budget]/[month]/+page.svelte
  • apps/web/src/routes/money/[budget]/accounts/account/+page.svelte
  • apps/web/src/routes/settings/[...path]/+page.svelte
  • apps/web/src/routes/settings/account/AppPasswordsGroup.svelte
  • apps/web/src/routes/settings/account/LocationGroup.svelte
  • apps/web/src/routes/settings/account/PasskeysGroup.svelte
  • apps/web/src/routes/settings/account/RecoveryKeySheet.svelte
  • apps/web/src/routes/settings/admin/BackupsGroup.svelte
  • apps/web/src/routes/settings/admin/ConfigGroup.svelte
  • apps/web/src/routes/settings/appearance/BackgroundGroup.svelte
  • apps/web/src/routes/settings/appearance/ColourPickerButton.svelte
  • apps/web/src/routes/settings/appearance/UnsplashSheet.svelte
  • apps/web/src/routes/settings/calendars/CalendarsSection.svelte
  • apps/web/src/routes/settings/calendars/ExternalCalendarsGroup.svelte
  • apps/web/src/routes/settings/parts/SettingsCard.svelte
  • apps/web/src/routes/settings/parts/SettingsRow.svelte
  • apps/web/src/routes/settings/parts/settings-forms.css
  • packages/editor/src/Editor.svelte
  • packages/editor/src/components/CalloutView.svelte
  • packages/ui/src/actions/resizableEdge.ts
  • packages/ui/src/components/Checkbox.svelte
  • packages/ui/src/components/FloatingSidebar.svelte
  • packages/ui/src/components/ModeHeader.svelte
  • packages/ui/src/components/NoticeBanner.svelte
  • packages/ui/src/components/OverlaySurface.svelte
  • packages/ui/src/components/Pill.svelte
  • packages/ui/src/components/PillGroup.svelte
  • packages/ui/src/components/SegmentedControl.svelte
  • packages/ui/src/components/Select.svelte
  • packages/ui/src/components/Toggle.svelte
  • packages/ui/src/components/calendar/ActivityStack.svelte
  • packages/ui/src/components/calendar/AgendaList.svelte
  • packages/ui/src/components/calendar/AttachmentDeck.svelte
  • packages/ui/src/components/calendar/LogEntryEditor.svelte
  • packages/ui/src/components/composer/DraftStack.svelte
  • packages/ui/src/components/composer/FieldPopover.svelte
  • packages/ui/src/components/files/FileCollection.svelte
  • packages/ui/src/components/menu/Menu.svelte
  • packages/ui/src/components/modeIsland.css
  • packages/ui/src/components/notes/NoteMentionsCard.svelte
  • packages/ui/src/components/notes/NoteProperties.svelte
  • packages/ui/src/components/viewer/QuickLook.svelte
  • packages/ui/src/tokens.css

Head

c3ad0e929c

Gate output

cargo fmt --check completed with exit code 0 and no output.

bun run check:

$ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-focus-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
User browser caches use userStorage; only documented device/public-link exceptions remain.
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.
Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/focus-658/apps/web
Getting Svelte diagnostics...
svelte-check found 0 errors and 0 warnings

Focused Vitest:

 RUN  v5.0.1 /home/kayg/Developer/calternal-wt/focus-658/apps/web


 Test Files  1 passed (1)
      Tests  2 passed (2)
   Start at  02:04:00
   Duration  8.28s (transform 48%, environment 26%, tests 15%, setup 7%, import 4%)

  Transform  |component| transforming modules took 3.84s · 48% 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

Production screenshot E2E output:

Focus ring clipping: checked 62 visible screen states; saved 76 focus crops and responsive screenshots in /home/kayg/Developer/calternal-wt/focus-658/artifacts/focus-658

Rust source did not change, so crate clippy and crate tests were not run in this UI job. bun run test and the full E2E/adversarial suites remain for the merge round.

Keyboard-motion profile

The job-branch run failed at “keyboard selection move runs motion on the focused row” after about 3.2 seconds. Launch load average was 31.71/30.21/39.83. The comparison run on clean origin/dev (c4faf184d) passed the same profile; it recorded 120, 120, 180, and 240 ms transition durations with 1,000 real Files and reported:

  • Average latency: p50 31.69 ms, p95 48.74 ms (20 samples)
  • Burst latency: p50 21.06 ms, p95 55.39 ms (100 selection moves)
  • Browser CPU: 0.59 s average and 2.66 s during burst
  • Browser RSS: 596,713,472 to 606,896,128 bytes; burst peak 643,694,592 bytes
  • Profile load average: 26.56/30.06/37.87

origin/dev output:

PASS keyboard and pointer Tab, selection, and Search actions use the same durations; ? morphs in

Both were local runs on a busy shared host. A quiet-host result is still missing. The branch-only assertion failure needs a merge-round review; it did not reproduce on origin/dev.

UX gaps closed

  • Sidebar and tested menu/list focus rings stay within their clipping edges.
  • Geometry checks cover Calendar Sidebar, Files, Notes, Settings navigation, Mail Sidebar and rows, Tab Bar, Calendar overflow, and menu rows in both themes and all three widths.

UX gaps left

  • The branch keyboard-motion assertion failed under load as described above. It needs a quiet-host follow-up or a decision that the timing assertion is measuring the wrong surface.
  • No other focus-ring geometry failures were found in the 62 checked states.

Decisions

  • Applied the existing inset focus token at shared clipping containers. The issue allowed inset rings or container padding; this choice preserves row layout.
  • The geometry guard checks clip bounds only where the rendered surface has a CSS clipping ancestor. Virtualized active-descendant Files rows and floating menu surfaces are still checked for the shared focus token and visible focus state.

For the merge round

  • bun run test — run the full Vitest suite.
  • bun run test:e2e:overflow-511 && bun run test:e2e:mobile-focus && bun run test:e2e:kbd-motion-527 — check Settings/list clipping, touch-width focus behavior, and keyboard motion. The repository has no single aggregate command for every E2E script.
  • tests/adversarial/run.sh — run the XUser and authorization matrices plus the real-server hostile-input and concurrency probes.
  • Re-run the job-branch keyboard-motion profile on a quiet host and compare against origin/dev; the current local attempts are not quiet-host timings.

Attached screenshots and geometry

Forgejo's issue asset listing confirms all 77 expected Round 2 artifacts are stored (76 PNGs and one geometry JSON). The 22 responsive/core review captures and all 54 row captures are linked below.

Responsive captures, 390/820/1440 px × light/dark (6)
Core focus crops, light/dark (16)
Sidebar and list row captures, nine surfaces × three widths × two themes (54)
Geometry report (1)
## Round 2 report ### What changed The shared focus-ring rule now supports container-level inset focus for descendants in clipped scroll areas. The app Sidebar scrollport, reusable Floating Sidebar navigation, and shared menu list opt in to the existing 2 px inset focus token. This keeps the outline inside clipped edges without adding padding or shifting rows. Added a production-build E2E geometry guard. It checks 62 visible focus states across nine row surfaces, and captures responsive screens at 390, 820, and 1440 px in light and dark themes. The browser emulates macOS shortcut rendering and uses 3× screenshots. It verifies that focus-ring bounds stay inside the nearest clipping ancestor where one exists. ### Files Round 2 implementation and probe: - packages/ui/src/tokens.css - apps/web/src/lib/components/app-sidebar.svelte - packages/ui/src/components/FloatingSidebar.svelte - packages/ui/src/components/menu/Menu.svelte - apps/web/e2e/focus-ring-clipping-658.mjs Full tracked branch file inventory relative to origin/dev (81 files): <details><summary>Show file inventory</summary> - apps/web/e2e/focus-ring-clipping-658.mjs - apps/web/e2e/kbd-motion-527.mjs - apps/web/package.json - apps/web/scripts/check-focus-tokens.mjs - apps/web/src/calternal-app.css - apps/web/src/lib/ai/TurnPanel.svelte - apps/web/src/lib/auth/components/RecoveryKeyEntry.svelte - apps/web/src/lib/components/AppToaster.svelte - apps/web/src/lib/components/KeyboardShortcutsCard.svelte - apps/web/src/lib/components/TagEditor.svelte - apps/web/src/lib/components/analytics/ActivityCard.svelte - apps/web/src/lib/components/analytics/BklitAnalytics.tsx - apps/web/src/lib/components/analytics/Dashboard.svelte - apps/web/src/lib/components/analytics/HabitsCard.svelte - apps/web/src/lib/components/analytics/RangePicker.svelte - apps/web/src/lib/components/analytics/widgets/StatRow.svelte - apps/web/src/lib/components/app-sidebar.svelte - apps/web/src/lib/components/money/AssignedCell.svelte - apps/web/src/lib/composer/Composer.svelte - apps/web/src/lib/editor/format/BlockHoverActions.svelte - apps/web/src/lib/editor/format/BlockReminderPicker.svelte - apps/web/src/lib/editor/format/FormatButton.svelte - apps/web/src/lib/files/FilesSidebar.svelte - apps/web/src/lib/files/PublicLinkPage.svelte - apps/web/src/lib/files/ShareDialog.svelte - apps/web/src/lib/mail/MailView.svelte - apps/web/src/lib/notes/NoteEditorSurface.svelte - apps/web/src/lib/notes/NoteImageView.svelte - apps/web/src/lib/notes/NoteView.svelte - apps/web/src/lib/notes/NotesExplorer.svelte - apps/web/src/lib/notifications/InboxPanel.svelte - apps/web/src/lib/photos/PhotoTimeline.svelte - apps/web/src/lib/photos/TimelineScrubber.svelte - apps/web/src/lib/search/SearchPreview.svelte - apps/web/src/lib/styles/auth-ui.css - apps/web/src/lib/themes.test.ts - apps/web/src/routes/calendar/[view]/[date]/+page.svelte - apps/web/src/routes/layout.css - apps/web/src/routes/money/[budget]/[month]/+page.svelte - apps/web/src/routes/money/[budget]/accounts/[[account]]/+page.svelte - apps/web/src/routes/settings/[...path]/+page.svelte - apps/web/src/routes/settings/account/AppPasswordsGroup.svelte - apps/web/src/routes/settings/account/LocationGroup.svelte - apps/web/src/routes/settings/account/PasskeysGroup.svelte - apps/web/src/routes/settings/account/RecoveryKeySheet.svelte - apps/web/src/routes/settings/admin/BackupsGroup.svelte - apps/web/src/routes/settings/admin/ConfigGroup.svelte - apps/web/src/routes/settings/appearance/BackgroundGroup.svelte - apps/web/src/routes/settings/appearance/ColourPickerButton.svelte - apps/web/src/routes/settings/appearance/UnsplashSheet.svelte - apps/web/src/routes/settings/calendars/CalendarsSection.svelte - apps/web/src/routes/settings/calendars/ExternalCalendarsGroup.svelte - apps/web/src/routes/settings/parts/SettingsCard.svelte - apps/web/src/routes/settings/parts/SettingsRow.svelte - apps/web/src/routes/settings/parts/settings-forms.css - packages/editor/src/Editor.svelte - packages/editor/src/components/CalloutView.svelte - packages/ui/src/actions/resizableEdge.ts - packages/ui/src/components/Checkbox.svelte - packages/ui/src/components/FloatingSidebar.svelte - packages/ui/src/components/ModeHeader.svelte - packages/ui/src/components/NoticeBanner.svelte - packages/ui/src/components/OverlaySurface.svelte - packages/ui/src/components/Pill.svelte - packages/ui/src/components/PillGroup.svelte - packages/ui/src/components/SegmentedControl.svelte - packages/ui/src/components/Select.svelte - packages/ui/src/components/Toggle.svelte - packages/ui/src/components/calendar/ActivityStack.svelte - packages/ui/src/components/calendar/AgendaList.svelte - packages/ui/src/components/calendar/AttachmentDeck.svelte - packages/ui/src/components/calendar/LogEntryEditor.svelte - packages/ui/src/components/composer/DraftStack.svelte - packages/ui/src/components/composer/FieldPopover.svelte - packages/ui/src/components/files/FileCollection.svelte - packages/ui/src/components/menu/Menu.svelte - packages/ui/src/components/modeIsland.css - packages/ui/src/components/notes/NoteMentionsCard.svelte - packages/ui/src/components/notes/NoteProperties.svelte - packages/ui/src/components/viewer/QuickLook.svelte - packages/ui/src/tokens.css </details> ### Head c3ad0e929c57dabd2db90b12f20e32ebe5cb6f4f ### Gate output cargo fmt --check completed with exit code 0 and no output. bun run check: ~~~text $ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-focus-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json User browser caches use userStorage; only documented device/public-link exceptions remain. 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. Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/focus-658/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ~~~ Focused Vitest: ~~~text RUN v5.0.1 /home/kayg/Developer/calternal-wt/focus-658/apps/web Test Files 1 passed (1) Tests 2 passed (2) Start at 02:04:00 Duration 8.28s (transform 48%, environment 26%, tests 15%, setup 7%, import 4%) Transform |component| transforming modules took 3.84s · 48% 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 ~~~ Production screenshot E2E output: ~~~text Focus ring clipping: checked 62 visible screen states; saved 76 focus crops and responsive screenshots in /home/kayg/Developer/calternal-wt/focus-658/artifacts/focus-658 ~~~ Rust source did not change, so crate clippy and crate tests were not run in this UI job. bun run test and the full E2E/adversarial suites remain for the merge round. ### Keyboard-motion profile The job-branch run failed at “keyboard selection move runs motion on the focused row” after about 3.2 seconds. Launch load average was 31.71/30.21/39.83. The comparison run on clean origin/dev (c4faf184d) passed the same profile; it recorded 120, 120, 180, and 240 ms transition durations with 1,000 real Files and reported: - Average latency: p50 31.69 ms, p95 48.74 ms (20 samples) - Burst latency: p50 21.06 ms, p95 55.39 ms (100 selection moves) - Browser CPU: 0.59 s average and 2.66 s during burst - Browser RSS: 596,713,472 to 606,896,128 bytes; burst peak 643,694,592 bytes - Profile load average: 26.56/30.06/37.87 origin/dev output: ~~~text PASS keyboard and pointer Tab, selection, and Search actions use the same durations; ? morphs in ~~~ Both were local runs on a busy shared host. A quiet-host result is still missing. The branch-only assertion failure needs a merge-round review; it did not reproduce on origin/dev. ### UX gaps closed - Sidebar and tested menu/list focus rings stay within their clipping edges. - Geometry checks cover Calendar Sidebar, Files, Notes, Settings navigation, Mail Sidebar and rows, Tab Bar, Calendar overflow, and menu rows in both themes and all three widths. ### UX gaps left - The branch keyboard-motion assertion failed under load as described above. It needs a quiet-host follow-up or a decision that the timing assertion is measuring the wrong surface. - No other focus-ring geometry failures were found in the 62 checked states. ### Decisions - Applied the existing inset focus token at shared clipping containers. The issue allowed inset rings or container padding; this choice preserves row layout. - The geometry guard checks clip bounds only where the rendered surface has a CSS clipping ancestor. Virtualized active-descendant Files rows and floating menu surfaces are still checked for the shared focus token and visible focus state. ### For the merge round - bun run test — run the full Vitest suite. - bun run test:e2e:overflow-511 && bun run test:e2e:mobile-focus && bun run test:e2e:kbd-motion-527 — check Settings/list clipping, touch-width focus behavior, and keyboard motion. The repository has no single aggregate command for every E2E script. - tests/adversarial/run.sh — run the XUser and authorization matrices plus the real-server hostile-input and concurrency probes. - Re-run the job-branch keyboard-motion profile on a quiet host and compare against origin/dev; the current local attempts are not quiet-host timings. ### Attached screenshots and geometry Forgejo's issue asset listing confirms all 77 expected Round 2 artifacts are stored (76 PNGs and one geometry JSON). The 22 responsive/core review captures and all 54 row captures are linked below. <details><summary>Responsive captures, 390/820/1440 px × light/dark (6)</summary> - [responsive-1440-dark-macos-3x.png](https://git.kayg.org/attachments/a75a06d7-5020-4c2c-a120-18459f4f46cf) - [responsive-1440-light-macos-3x.png](https://git.kayg.org/attachments/caeffc4d-4bac-41ec-b6f6-cf20c987cfbc) - [responsive-390-dark-macos-3x.png](https://git.kayg.org/attachments/49e4c35d-f5d3-44d2-875b-3fa1fec98119) - [responsive-390-light-macos-3x.png](https://git.kayg.org/attachments/808b30df-0423-4769-9015-048cc8a8987b) - [responsive-820-dark-macos-3x.png](https://git.kayg.org/attachments/b603216f-01e8-43e2-b3f8-d6bfaf0b114d) - [responsive-820-light-macos-3x.png](https://git.kayg.org/attachments/e54092c3-800a-4562-ac3e-d09b8adf5ac2) </details> <details><summary>Core focus crops, light/dark (16)</summary> - [button-dark-macos-3x.png](https://git.kayg.org/attachments/463e52b1-a543-4752-a320-4a2e89bbee59) - [button-light-macos-3x.png](https://git.kayg.org/attachments/7bfcaecf-bafb-4d2e-9ce0-7302b5265da4) - [calendar-more-row-dark-macos-3x.png](https://git.kayg.org/attachments/6c058bab-080d-4e6b-9455-05c4a151f614) - [calendar-more-row-light-macos-3x.png](https://git.kayg.org/attachments/2e1b5da3-8522-4d56-8e6c-678b48ce0fa3) - [mac-shortcut-tip-dark-macos-3x.png](https://git.kayg.org/attachments/1d2bc4ba-c321-4653-93ff-8e07a35c8b0d) - [mac-shortcut-tip-light-macos-3x.png](https://git.kayg.org/attachments/78ba2683-202a-4711-ac2c-05e26057a93b) - [menu-item-dark-macos-3x.png](https://git.kayg.org/attachments/e55643a1-392c-48fb-accc-4652f597e78b) - [menu-item-light-macos-3x.png](https://git.kayg.org/attachments/920b1fee-c7b9-4ccb-b004-22fcfd6c8a28) - [search-input-dark-macos-3x.png](https://git.kayg.org/attachments/2cd9a8d6-543a-49ee-8f87-a6510ce4ec28) - [search-input-light-macos-3x.png](https://git.kayg.org/attachments/26236b62-8cfc-4854-88c5-8ca5ce02e83c) - [sidebar-row-dark-macos-3x.png](https://git.kayg.org/attachments/548fb368-9159-4c0b-bc70-6af936e53c4c) - [sidebar-row-light-macos-3x.png](https://git.kayg.org/attachments/8cdd521b-f7a5-45b3-bf12-69a2745e5870) - [tab-bar-dark-macos-3x.png](https://git.kayg.org/attachments/469a889a-6463-4bd7-900e-a86ceca6e776) - [tab-bar-light-macos-3x.png](https://git.kayg.org/attachments/976917e3-d0e5-4c2a-b1ae-306fdbf8d032) - [text-input-dark-macos-3x.png](https://git.kayg.org/attachments/534ee28f-1a35-4d47-94f3-f1a766029253) - [text-input-light-macos-3x.png](https://git.kayg.org/attachments/05855a5b-5421-4625-96a8-210372fff253) </details> <details><summary>Sidebar and list row captures, nine surfaces × three widths × two themes (54)</summary> - [row-calendar-overflow-1440-dark-macos-3x.png](https://git.kayg.org/attachments/731e34eb-c6ea-4b54-bedf-2b828bcd4f13) - [row-calendar-overflow-1440-light-macos-3x.png](https://git.kayg.org/attachments/ddee09dc-14c7-470d-9bdc-67ad2536405d) - [row-calendar-overflow-390-dark-macos-3x.png](https://git.kayg.org/attachments/b65d56d8-a419-4585-b1c9-f2dc2903e068) - [row-calendar-overflow-390-light-macos-3x.png](https://git.kayg.org/attachments/b1777284-04f0-42f2-a28f-d4a7ed1f50dd) - [row-calendar-overflow-820-dark-macos-3x.png](https://git.kayg.org/attachments/c563294c-eeca-447b-b088-ee20b7bc34e0) - [row-calendar-overflow-820-light-macos-3x.png](https://git.kayg.org/attachments/fc2fd79f-69dc-429f-ac78-4ffaaf7c3efd) - [row-calendar-sidebar-1440-dark-macos-3x.png](https://git.kayg.org/attachments/bde8f628-fd82-45da-aa61-fbae000b92c5) - [row-calendar-sidebar-1440-light-macos-3x.png](https://git.kayg.org/attachments/06ce2573-cfd4-4812-bead-368ffce203a5) - [row-calendar-sidebar-390-dark-macos-3x.png](https://git.kayg.org/attachments/ef100fab-4240-48f2-bbca-46be7340724c) - [row-calendar-sidebar-390-light-macos-3x.png](https://git.kayg.org/attachments/b6489333-3616-4d2c-9414-28725aee0ba0) - [row-calendar-sidebar-820-dark-macos-3x.png](https://git.kayg.org/attachments/2980d264-380f-4ed2-982f-820db672949e) - [row-calendar-sidebar-820-light-macos-3x.png](https://git.kayg.org/attachments/ce3549b1-2e91-48de-94cc-1bc897abdfaa) - [row-files-list-1440-dark-macos-3x.png](https://git.kayg.org/attachments/3a27163f-0be7-459a-83d8-3774ca91c72a) - [row-files-list-1440-light-macos-3x.png](https://git.kayg.org/attachments/db62e37a-eb64-40c6-9e66-75b756bbc5e7) - [row-files-list-390-dark-macos-3x.png](https://git.kayg.org/attachments/9048a966-89e4-40f5-ae4f-a886dba9fb7e) - [row-files-list-390-light-macos-3x.png](https://git.kayg.org/attachments/2ea6719e-e4b7-4920-83b3-c4cb4f50eb56) - [row-files-list-820-dark-macos-3x.png](https://git.kayg.org/attachments/dec03bfa-9de8-4f03-8f87-c01dd833c0db) - [row-files-list-820-light-macos-3x.png](https://git.kayg.org/attachments/6e17f772-457c-4b30-a9e5-7715556f67da) - [row-mail-list-1440-dark-macos-3x.png](https://git.kayg.org/attachments/bc02135e-f85f-42ff-8d97-cf1758058c8d) - [row-mail-list-1440-light-macos-3x.png](https://git.kayg.org/attachments/90e83422-1f90-4ec9-88c4-8e42b32a47cc) - [row-mail-list-390-dark-macos-3x.png](https://git.kayg.org/attachments/05b440d0-cf0e-4e69-afa5-2975de49536a) - [row-mail-list-390-light-macos-3x.png](https://git.kayg.org/attachments/394e60bf-d478-43d9-8dae-7122212e2261) - [row-mail-list-820-dark-macos-3x.png](https://git.kayg.org/attachments/8a9fa42b-2c31-4bf4-9a78-d06de8631952) - [row-mail-list-820-light-macos-3x.png](https://git.kayg.org/attachments/dd87995f-f4f8-4bff-9d17-bb66210e417a) - [row-mail-sidebar-1440-dark-macos-3x.png](https://git.kayg.org/attachments/1d136e50-5e48-4e0b-be3e-5c367d466730) - [row-mail-sidebar-1440-light-macos-3x.png](https://git.kayg.org/attachments/ad8962ca-d150-44b8-bb55-6fa0d50939df) - [row-mail-sidebar-390-dark-macos-3x.png](https://git.kayg.org/attachments/b07ee082-65b9-4ff4-858a-9016cf7d193d) - [row-mail-sidebar-390-light-macos-3x.png](https://git.kayg.org/attachments/c987d7f7-6152-469c-81e3-d6020daea130) - [row-mail-sidebar-820-dark-macos-3x.png](https://git.kayg.org/attachments/b063ede5-79e1-484c-b469-848b4228197a) - [row-mail-sidebar-820-light-macos-3x.png](https://git.kayg.org/attachments/46084833-d371-456f-86fb-5446bea29c43) - [row-menu-item-1440-dark-macos-3x.png](https://git.kayg.org/attachments/404688b4-4197-4ae0-8364-b9a6f36f52b0) - [row-menu-item-1440-light-macos-3x.png](https://git.kayg.org/attachments/31e5da0f-5251-4811-af06-17154c1f3934) - [row-menu-item-390-dark-macos-3x.png](https://git.kayg.org/attachments/17016e1a-6b02-402a-a50f-df4940e7338d) - [row-menu-item-390-light-macos-3x.png](https://git.kayg.org/attachments/a71587ae-1c06-4c04-b31b-c8d87efafa3a) - [row-menu-item-820-dark-macos-3x.png](https://git.kayg.org/attachments/c4cd1d44-0e90-4e18-8d2a-dd2b9e67ca42) - [row-menu-item-820-light-macos-3x.png](https://git.kayg.org/attachments/c0772b91-6861-4412-ae06-e137ce0b3816) - [row-notes-list-1440-dark-macos-3x.png](https://git.kayg.org/attachments/b6264ccb-5228-4ee1-83e7-fb8870c92903) - [row-notes-list-1440-light-macos-3x.png](https://git.kayg.org/attachments/399b2ec6-3083-48d6-bbe0-20b8ae74c087) - [row-notes-list-390-dark-macos-3x.png](https://git.kayg.org/attachments/6ad1388b-9f7b-4b6b-af50-e2b669003c9a) - [row-notes-list-390-light-macos-3x.png](https://git.kayg.org/attachments/5fb03fac-9dec-4a38-91a4-5644991b509c) - [row-notes-list-820-dark-macos-3x.png](https://git.kayg.org/attachments/5748f1a1-43e8-4031-bae8-972fe0e32074) - [row-notes-list-820-light-macos-3x.png](https://git.kayg.org/attachments/e8d7d9ae-9391-47f7-88d0-1dad1c41e23d) - [row-settings-navigation-1440-dark-macos-3x.png](https://git.kayg.org/attachments/81f5d09e-ac80-43fa-8900-27478d2463d2) - [row-settings-navigation-1440-light-macos-3x.png](https://git.kayg.org/attachments/e89b14ac-1475-41aa-9362-d8c15a1a7e10) - [row-settings-navigation-390-dark-macos-3x.png](https://git.kayg.org/attachments/9be58ca1-92dd-4580-8b3c-cd3892bb2ab3) - [row-settings-navigation-390-light-macos-3x.png](https://git.kayg.org/attachments/60c2f389-266a-48e9-9b83-135b5b745507) - [row-settings-navigation-820-dark-macos-3x.png](https://git.kayg.org/attachments/1d2a7f51-74f1-4d45-b0b3-183dba4cd5f5) - [row-settings-navigation-820-light-macos-3x.png](https://git.kayg.org/attachments/362594de-d423-47cf-94f1-3d3ef98457e5) - [row-tab-bar-1440-dark-macos-3x.png](https://git.kayg.org/attachments/04aa9cd3-c85e-42b4-889a-388a8eccceb8) - [row-tab-bar-1440-light-macos-3x.png](https://git.kayg.org/attachments/aaf7da6c-861e-4414-a392-ebf86efc51d2) - [row-tab-bar-390-dark-macos-3x.png](https://git.kayg.org/attachments/f163686c-3be3-4075-965b-58dad857cb32) - [row-tab-bar-390-light-macos-3x.png](https://git.kayg.org/attachments/309082ac-a2b6-48e1-b2cf-6689299fbaab) - [row-tab-bar-820-dark-macos-3x.png](https://git.kayg.org/attachments/01ec1694-63e2-4ab9-a4c0-4b56f9a2c221) - [row-tab-bar-820-light-macos-3x.png](https://git.kayg.org/attachments/26b4d8ad-0d70-47a7-8eb7-a8fbdcdde7d0) </details> <details><summary>Geometry report (1)</summary> - [focus-ring-clipping-geometry.json](https://git.kayg.org/attachments/077bae2e-0c7f-4281-9697-616d32427d8c) </details>
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#658
No description provided.