docs: add .agents workspace and the Astro refactor plan
Adds the agent-facing workspace and a 20-task plan for migrating the site to Astro. Nothing here implements the refactor; these are briefs, rules and templates that the task agents read. - .agents/ holds context, rules, checklists, skills, specialist agents, component/page/config templates and gate scripts. It is vendor-neutral so MiniMax, Gemini and Codex can all read it; CLAUDE.md just points at AGENTS.md. - .husky/ plus .lintstagedrc.json wire the three gate tiers. gate.sh locks on the shared git-common-dir so parallel worktrees serialise, and guards the assertion count in scripts/verify.mjs against a coverage drop. - plans/astro-refactor/ carries the phase graph, per-task briefs and the model-routing recommendation. These files must be tracked before fanning out: a worktree only checks out tracked files, so an untracked plan is invisible to every agent working in one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
# Rule: accessibility
|
||||
|
||||
## The gate is a keyboard, not a scanner
|
||||
|
||||
Automated tooling catches roughly **57%** of accessibility defects, and the
|
||||
misses cluster exactly where usability is decided: focus visibility, focus
|
||||
obscured by sticky elements, target size, and drag alternatives. Run axe, then
|
||||
do the manual sweep anyway.
|
||||
|
||||
**Manual sweep, every interactive component:**
|
||||
|
||||
1. Tab through it. Every control reachable, in a sensible order.
|
||||
2. Focus ring visible at every stop — this site uses
|
||||
`outline: 3px solid #a7483f; outline-offset: 2px`. Keep it.
|
||||
3. Operate it with Enter and Space. Escape closes anything that opened.
|
||||
4. Nothing is reachable only by hover or only by pointer.
|
||||
5. Zoom to 200%. Nothing clipped, nothing overlapping.
|
||||
|
||||
## Semantics
|
||||
|
||||
- Native elements first. `<button>` for actions, `<a>` for navigation. A `<div>`
|
||||
with a click handler is a defect, not a style choice.
|
||||
- ARIA only when HTML cannot express it. The current code does this well —
|
||||
`role="tablist"`, `aria-pressed`, `aria-current="page"`, `aria-label` on
|
||||
regions. Preserve every one during migration; they are asserted in
|
||||
`verify.mjs`.
|
||||
- One `<h1>` per page. Heading levels never skip.
|
||||
- Every image needs `alt`. Decorative images get `alt=""`.
|
||||
|
||||
## State
|
||||
|
||||
Interactive state must be exposed, not just painted:
|
||||
|
||||
```html
|
||||
<!-- wrong: only colour says it is selected -->
|
||||
<button class="active">Improved draft</button>
|
||||
<!-- right -->
|
||||
<button class="active" aria-pressed="true">Improved draft</button>
|
||||
```
|
||||
|
||||
The vote widget and preview switcher already do this. Match them.
|
||||
|
||||
## Contrast
|
||||
|
||||
Body text ≥ 4.5:1, large text ≥ 3:1, UI boundaries ≥ 3:1. Check any new
|
||||
combination against the token palette — `--muted` on `--paper` is the pair most
|
||||
likely to fail; verify before shipping.
|
||||
|
||||
## Bilingual content
|
||||
|
||||
`<html lang>` must change with the language toggle, not just the text. Screen
|
||||
readers pick pronunciation from it. This already works today — do not regress it.
|
||||
Reference in New Issue
Block a user