fix: recover covered-card opacity on focus + active (#49)
Addresses code review on #47: with the cubic floor at 0.10 opacity,
heavily covered cards become unreadable for keyboard and touch users
who can't trigger :hover.
The reviewer suggested adding focus-within and tabIndex={0} to the
LumeCard div. Both would be wrong here:
- focus-within only matches when the element or a descendant is focused.
LumeCard's children (interest dot, text, chips, % badge) are not
focusable, so focus-within would never fire from normal Tab navigation.
- Adding tabIndex={0} to LumeCard creates a double-tab problem: Tab once
focuses the wrapping <Link>, Tab again focuses the LumeCard div which
navigates nowhere. Screen readers also announce the same target twice.
Right fix: make the wrapping <Link> drive a named group, then use
group-hover/card, group-focus-visible/card, and group-active/card on the
LumeCard. The Link is naturally focusable (the focus ring goes there),
and visual recovery on the child LumeCard propagates from the group
state. No double-tab, no dead focus-within.
Changes:
- ScoredTalksGrid Link: add `group/card block` and a focus-visible
outline (the previous outline lived on LumeCard, where it was inert
because LumeCard was never the focus target).
- LumeCard: add group-hover/card / group-focus-visible/card / group-
active/card variants alongside the existing :hover modifiers. Direct
:hover stays for callers that don't wrap LumeCard in a focusable
ancestor.
- LumeCard: drop the dead focus-visible:outline-* (Link handles it now).
- Score detail strip: add sm:group-hover/card and sm:group-focus-visible
/card so keyboard tab also reveals the strip on desktop. Mobile
behavior (always visible) unchanged.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>