Problem
The ct-card component — specifically the ct-card--interactive variant — is semantically underspecified and encourages accessibility anti-patterns.
1. Interactive variant has no semantic guidance
ct-card--interactive adds cursor: pointer and :focus-visible styles, but gives no indication of what HTML element should be used. This makes it trivially easy to create a clickable <div>, which is a WCAG failure (no keyboard activation, no role, no accessible name). The CSS should either scope the interactive styles to a.ct-card--interactive / button.ct-card--interactive, or the pattern needs strong documentation.
2. No ARIA state selectors
The interactive card has no styles for common states:
- No
aria-selected (for selectable card grids)
- No
aria-expanded (for cards that toggle content)
- No
data-state (for active/loading/disabled states)
Other components handle this well — Toggle Group uses aria-pressed, Tabs uses aria-selected, Chip uses aria-pressed.
3. No aria-labelledby pattern
A card rendered as <section> needs an accessible name. The merge conflict in CardAndTable.stories.js exposes this gap: the stricter version requires aria-labelledby referencing the card heading, while the current version doesn't enforce it at all. Without this, screen reader users get an unnamed region landmark.
4. Missing prefers-reduced-motion
The interactive card has transition: box-shadow, border-color but no @media (prefers-reduced-motion: reduce) block. This is inconsistent with Accordion, Toast, Dropdown, Sidebar, and Datepicker which all respect this.
5. No disabled state
Unlike Button, FormControls, and ToggleGroup, the interactive card has no :disabled or [aria-disabled="true"] styling. An interactive element without a disabled state is incomplete.
Expected behavior
- Add
[aria-disabled="true"] styles (opacity, pointer-events, cursor)
- Add
[aria-selected="true"] styles for card-grid selection patterns
- Add
@media (prefers-reduced-motion: reduce) to disable transitions
- Document that interactive cards must use
<a> or <button> (or have role + tabindex)
- Enforce
aria-labelledby on <section> cards in the story/tests
Files
components/components.css lines 466–522
stories/CardAndTable.stories.js (has unresolved merge conflict)
Problem
The
ct-cardcomponent — specifically thect-card--interactivevariant — is semantically underspecified and encourages accessibility anti-patterns.1. Interactive variant has no semantic guidance
ct-card--interactiveaddscursor: pointerand:focus-visiblestyles, but gives no indication of what HTML element should be used. This makes it trivially easy to create a clickable<div>, which is a WCAG failure (no keyboard activation, no role, no accessible name). The CSS should either scope the interactive styles toa.ct-card--interactive/button.ct-card--interactive, or the pattern needs strong documentation.2. No ARIA state selectors
The interactive card has no styles for common states:
aria-selected(for selectable card grids)aria-expanded(for cards that toggle content)data-state(for active/loading/disabled states)Other components handle this well — Toggle Group uses
aria-pressed, Tabs usesaria-selected, Chip usesaria-pressed.3. No
aria-labelledbypatternA card rendered as
<section>needs an accessible name. The merge conflict inCardAndTable.stories.jsexposes this gap: the stricter version requiresaria-labelledbyreferencing the card heading, while the current version doesn't enforce it at all. Without this, screen reader users get an unnamed region landmark.4. Missing
prefers-reduced-motionThe interactive card has
transition: box-shadow, border-colorbut no@media (prefers-reduced-motion: reduce)block. This is inconsistent with Accordion, Toast, Dropdown, Sidebar, and Datepicker which all respect this.5. No disabled state
Unlike Button, FormControls, and ToggleGroup, the interactive card has no
:disabledor[aria-disabled="true"]styling. An interactive element without a disabled state is incomplete.Expected behavior
[aria-disabled="true"]styles (opacity, pointer-events, cursor)[aria-selected="true"]styles for card-grid selection patterns@media (prefers-reduced-motion: reduce)to disable transitions<a>or<button>(or haverole+tabindex)aria-labelledbyon<section>cards in the story/testsFiles
components/components.csslines 466–522stories/CardAndTable.stories.js(has unresolved merge conflict)