LC-565: a11y regression pass - composer focus ring + phantom danger token (redesign P5) #533

Merged
longjacksonle merged 1 commit from fix/LC-565-a11y-regression-pass into main 2026-07-09 21:59:34 +02:00

Visual / accessibility regression pass over the redesign (LC-UI-12). Two concrete fixes, plus the audit that the pass exists to produce.

Fixes in this PR

1. Composer keyboard focus ring. The composer icon buttons (.lc-fmt-btn / .lc-composer-btn / .lc-composer-send) had no :focus-visible rule, so keyboard focus fell back to the UA default outline, inconsistent with the app-wide idiom (.lc-set-tab / .lc-cbtn / .lc-switch all draw box-shadow: 0 0 0 2px var(--ring)). Added the matching ring. --ring is defined in all four themes.

2. Phantom text-danger-surface-content token (latent bug, 12 files). The danger family has no -surface-content token (LC-215: danger copy uses --danger), yet 12 hand-rolled danger boxes across admin / settings / enclave referenced text-danger-surface-content, so their error copy rendered with no explicit color (inherited --content instead of danger red). Swapped every occurrence to text-danger - the correct foreground on bg-danger-surface, already the pattern in settings/page.html's DND badge. Uniform token swap, no shape change, zero layout risk.

Audit results

Checklist item Verdict
Light / Dark themes Pass - redesign surfaces reuse existing tuned tokens
HC-light / HC-dark AAA Pass - content 21:1 (#000/#fff), accent nudged to blue-800 (hc-light) / blue-300 (hc-dark), sidebar pure black/white, status chips reuse the AAA-tuned .alert-* token pairs
Comfortable / Compact density Pass - composer card margin is density-independent; data-lc-density-tight still governs padding
Mobile drawer Pass - .lc-sidebar token-scoping (LC-560) rides the same #sidebar container the drawer toggles
Keyboard-only nav Fixed here - composer focus ring added
Reduced motion Pass - 8 prefers-reduced-motion blocks; the redesign added no new animation
Focus-visible coverage Fixed here for the composer; otherwise broad

Deferred (needs responsive visual iteration)

Interactive icon buttons sit below the 44px touch target (.lc-fmt-btn 28px, .lc-composer-btn / .lc-composer-send 36px) and there is no @media (pointer: coarse) bump. The composer bottom row is densely packed (~10 controls + textarea on one line), so widening each to 44px risks horizontal overflow on narrow screens - it needs a real device/emulator check, out of scope for a headless pass. Recommendation: a pointer: coarse rule raising min tap size, likely paired with allowing the composer toolbar to wrap.

Also out of scope (separate Priority-3 admin migration): fully replacing the 12 hand-rolled danger boxes with the .alert alert-danger component.

Verify

  • just build-css -> clean.
  • dev/cargo test --test routes_admin_bridges -> 10/10 (renders the bridges error banner + status chips).
  • dev/cargo test --test routes_enclave -> 19/19 (renders enclave settings / branding error surfaces).

🤖 Generated with Claude Code

https://claude.ai/code/session_011jXpZXXwpB36MvTr6JrGXN

Visual / accessibility regression pass over the redesign (LC-UI-12). Two concrete fixes, plus the audit that the pass exists to produce. ## Fixes in this PR **1. Composer keyboard focus ring.** The composer icon buttons (`.lc-fmt-btn` / `.lc-composer-btn` / `.lc-composer-send`) had no `:focus-visible` rule, so keyboard focus fell back to the UA default outline, inconsistent with the app-wide idiom (`.lc-set-tab` / `.lc-cbtn` / `.lc-switch` all draw `box-shadow: 0 0 0 2px var(--ring)`). Added the matching ring. `--ring` is defined in all four themes. **2. Phantom `text-danger-surface-content` token (latent bug, 12 files).** The danger family has no `-surface-content` token (LC-215: danger copy uses `--danger`), yet 12 hand-rolled danger boxes across admin / settings / enclave referenced `text-danger-surface-content`, so their error copy rendered with no explicit color (inherited `--content` instead of danger red). Swapped every occurrence to `text-danger` - the correct foreground on `bg-danger-surface`, already the pattern in `settings/page.html`'s DND badge. Uniform token swap, no shape change, zero layout risk. ## Audit results | Checklist item | Verdict | | --- | --- | | Light / Dark themes | Pass - redesign surfaces reuse existing tuned tokens | | HC-light / HC-dark **AAA** | Pass - content 21:1 (`#000`/`#fff`), accent nudged to blue-800 (hc-light) / blue-300 (hc-dark), sidebar pure black/white, status chips reuse the AAA-tuned `.alert-*` token pairs | | Comfortable / Compact density | Pass - composer card margin is density-independent; `data-lc-density-tight` still governs padding | | Mobile drawer | Pass - `.lc-sidebar` token-scoping (LC-560) rides the same `#sidebar` container the drawer toggles | | Keyboard-only nav | **Fixed here** - composer focus ring added | | Reduced motion | Pass - 8 `prefers-reduced-motion` blocks; the redesign added no new animation | | Focus-visible coverage | **Fixed here** for the composer; otherwise broad | ## Deferred (needs responsive visual iteration) Interactive icon buttons sit below the 44px touch target (`.lc-fmt-btn` 28px, `.lc-composer-btn` / `.lc-composer-send` 36px) and there is no `@media (pointer: coarse)` bump. The composer bottom row is densely packed (~10 controls + textarea on one line), so widening each to 44px risks horizontal overflow on narrow screens - it needs a real device/emulator check, out of scope for a headless pass. Recommendation: a `pointer: coarse` rule raising min tap size, likely paired with allowing the composer toolbar to wrap. Also out of scope (separate Priority-3 admin migration): fully replacing the 12 hand-rolled danger boxes with the `.alert alert-danger` component. ## Verify - `just build-css` -> clean. - `dev/cargo test --test routes_admin_bridges` -> **10/10** (renders the bridges error banner + status chips). - `dev/cargo test --test routes_enclave` -> **19/19** (renders enclave settings / branding error surfaces). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_011jXpZXXwpB36MvTr6JrGXN
fix(a11y): composer focus ring + fix phantom danger-surface-content token (LC-565 / LC-UI-12)
All checks were successful
check-secrets / TruffleHog (push) Successful in 4s
check-secrets / Nosey parker (push) Successful in 4s
check-secrets / Kingfisher (push) Successful in 5s
check-secrets / Nosey parker (pull_request) Successful in 7s
check-secrets / Kingfisher (pull_request) Successful in 9s
check-secrets / TruffleHog (pull_request) Successful in 10s
Check / clippy + fmt + tests (pull_request) Successful in 6m21s
Create release / Create release from merged PR (pull_request) Has been skipped
eda0b36fcd
Visual / accessibility regression pass over the redesign. Two concrete fixes plus a documented audit.

1. Composer keyboard focus. The composer icon buttons (.lc-fmt-btn / .lc-composer-btn / .lc-composer-send) had no :focus-visible rule and fell back to the UA default outline, inconsistent with the app-wide focus-ring idiom (.lc-set-tab / .lc-cbtn / .lc-switch all draw box-shadow 0 0 0 2px var(--ring)). Added the matching ring so keyboard traversal of the composer is clearly indicated in every theme.

2. Phantom token. text-danger-surface-content was used by 12 hand-rolled danger boxes across admin / settings / enclave templates, but the danger family has no -surface-content token (LC-215: danger copy uses --danger), so the error text rendered with no explicit color (inherited). Swapped every occurrence to text-danger, the correct foreground on bg-danger-surface (already the pattern in settings/page.html's DND badge). Uniform token swap, no shape change, zero layout risk. Fully migrating these boxes to the .alert component is a separate Priority-3 admin-migration follow-up.

Audit findings (see PR body): the redesign's new surfaces reuse already-tuned token pairs, so they add no new contrast regressions - hc-light/hc-dark stay AAA (content 21:1, accent nudged to blue-800/blue-300, sidebar pure black/white); reduced-motion and focus-visible are broadly covered. One gap left open: interactive icon buttons are below the 44px touch target and there is no pointer:coarse bump; bumping the dense composer row needs responsive visual iteration, deferred with a recommendation.

Verified: routes_admin_bridges 10/10 + routes_enclave 19/19; just build-css clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011jXpZXXwpB36MvTr6JrGXN
longjacksonle scheduled this pull request to auto merge when all checks succeed 2026-07-09 21:57:38 +02:00
longjacksonle deleted branch fix/LC-565-a11y-regression-pass 2026-07-09 21:59:35 +02:00
Sign in to join this conversation.
No reviewers
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
psa-systems/lets-chat!533
No description provided.