accessibility-firstlisted
Install: claude install-skill voidcorp-core/void-harness
# accessibility-first — voidcorp craftsman edition
A11y is not a launch-time audit. It is the default at every interactive surface. Radix handles the hard parts; we honor the rules. Mobile-first dual-quality means both viewports ship at first-class quality.
**Attribution**: see `.source`. Foundation: WCAG 2.2 AA + Radix UI + Apple HIG + WAI-ARIA APG + Folpe mobile-first dual-quality.
---
## The floor
WCAG 2.2 AA is the minimum. Not the goal — the floor. Specific projects (regulated, public-sector) may target AAA via `voidcorp.config.json` `wcag_level: 'AAA'`.
---
## Interactive primitives — wrap Radix
```tsx
// banned
<div onClick={handleClick} role="button" tabIndex={0}>
Submit
</div>
// allowed (Radix base)
<button onClick={handleClick}>Submit</button>
// preferred (shadcn-style via @repo/ui, wraps Radix)
import { Button } from '@repo/ui';
<Button onClick={handleClick}>Submit</Button>
```
Radix provides focus management, keyboard nav, ARIA wiring. Hand-rolling these is the #1 source of subtle a11y bugs.
For composite widgets (dropdown, dialog, popover, tooltip, tabs, accordion, slider, switch, toggle group, navigation menu) — use the Radix primitive. Period.
The companion `code-review` flag catches raw `<div onClick>` / `<span onClick>` on interactive surfaces.
---
## Semantic HTML over ARIA
```tsx
// banned
<div role="navigation">...</div>
<div role="heading" aria-level={2}>Title</div>
// allowed
<nav>...</nav>
<h2>Title</h2>
```
ARIA is the escape hatc