Parent: #125
Priority: P1
Problem
Keyboard focus can land on transcript message actions without a visible focus indicator.
During a read-only Playwright accessibility audit of the current built-from-scratch branch, tabbing to Copy message produced:
- the button was correctly keyboard reachable
:focus-visible matched true
- the control had an accessible name
- but its computed focus presentation had no meaningful visible treatment: transparent background/border, no outline, and effectively zero-width focus box-shadow
This means keyboard users can move focus onto a message action and lose track of where focus is.
Source context
The shared primitive is:
apps/web/src/components/chat/MessageActionButton.tsx
Its shared class currently includes:
while the base presentation is also intentionally quiet:
rounded-none border-0 bg-transparent shadow-none
So the standard focus ring is disabled without an equivalent replacement.
Related consumers include message copy and other compact transcript/footer actions that use MessageActionButton.
Objective
Give all shared message action buttons a clear, restrained keyboard-focus treatment that fits Forkara's visual language without making the footer noisy at rest.
Required work
- Add a visible
focus-visible treatment to MessageActionButton or the narrowest shared primitive that owns these controls.
- Ensure the focus treatment is visible in both light and dark themes.
- Preserve the current quiet hover/rest styling.
- Verify disabled buttons do not present misleading focus/active affordances.
- Audit the consumers of
MessageActionButton to confirm the shared fix does not create clipping or layout shift.
- Add focused browser/component coverage for keyboard focus visibility.
Acceptance criteria
- Tabbing to
Copy message produces an unmistakable visible focus indicator without requiring hover.
- Other controls using
MessageActionButton receive the same appropriate focus treatment.
- The indicator remains visible against supported light and dark chat surfaces.
- Focus styling does not change the button's dimensions or cause transcript/footer layout shift.
- Mouse interaction does not show the keyboard-only focus treatment unless
:focus-visible applies.
- Existing accessible names, tooltips, click behavior, pressed states, and disabled behavior remain unchanged.
Suggested validation
- Add/update a focused browser test around
MessageActionButton or a representative consumer.
- Keyboard-tab through a populated transcript and verify focus location remains visually obvious.
- Check light and dark appearance.
- Run focused web tests plus typecheck/lint validation for touched paths.
Guardrails
- Do not add persistent borders/backgrounds to every message action at rest.
- Do not solve this only for
Copy message; fix the shared primitive unless evidence shows a consumer-specific exception is required.
- Do not remove tooltips or accessible labels.
Why this is agent-ready
The root cause is localized, the shared source file is known, the expected behavior is concrete, and the change can be validated with a focused browser test.
Parent: #125
Priority: P1
Problem
Keyboard focus can land on transcript message actions without a visible focus indicator.
During a read-only Playwright accessibility audit of the current
built-from-scratchbranch, tabbing toCopy messageproduced::focus-visiblematchedtrueThis means keyboard users can move focus onto a message action and lose track of where focus is.
Source context
The shared primitive is:
apps/web/src/components/chat/MessageActionButton.tsxIts shared class currently includes:
while the base presentation is also intentionally quiet:
So the standard focus ring is disabled without an equivalent replacement.
Related consumers include message copy and other compact transcript/footer actions that use
MessageActionButton.Objective
Give all shared message action buttons a clear, restrained keyboard-focus treatment that fits Forkara's visual language without making the footer noisy at rest.
Required work
focus-visibletreatment toMessageActionButtonor the narrowest shared primitive that owns these controls.MessageActionButtonto confirm the shared fix does not create clipping or layout shift.Acceptance criteria
Copy messageproduces an unmistakable visible focus indicator without requiring hover.MessageActionButtonreceive the same appropriate focus treatment.:focus-visibleapplies.Suggested validation
MessageActionButtonor a representative consumer.Guardrails
Copy message; fix the shared primitive unless evidence shows a consumer-specific exception is required.Why this is agent-ready
The root cause is localized, the shared source file is known, the expected behavior is concrete, and the change can be validated with a focused browser test.