cellajs/cella/a11y-review
Claude Code and agent skill by cellajs/cella
- community
Checking that the SKILL.md file is still in the repository.
Run the WCAG audit, fix what it finds, check each fix in the running app, and review the criteria the audit leaves open, recording every decision with its evidence in the conformance ledger.
Install
npx vskill@latest install cellajs/cella/a11y-reviewSKILL.md
The accessibility audit loop
pnpm a11y:run decides what tools can prove and writes the ledger, json/accessibility-conformance.json. The rest it leaves open, with a packet per page for a reviewer. This skill is the procedure around it: run, fix, check the fix, rerun, review, record. The a11y README owns the audit: its commands, partial runs, failed visits, what an app lists in scope-config.ts, and why an agent's decision stays provisional until a person confirms it. Agents also report failures that are not there, so the rules below lean toward leaving a row open.
Run
Run pnpm a11y:run --keep for the fix loop, so the stack stays up between partial runs.
- A run with skipped visits writes no ledger. Fix the cause (a state's opener that no longer finds its button, a redirect) and run again. Read the visit's
failure-<mode>.pngand.jsonfirst: a step often fails on what an earlier one left behind, such as a page that fell into its error boundary. - A probe that fails once and passes on a rerun was a timing miss; rerun before recording it.
Patterns for app UI
The template's accessibility fixes arrive through synced files only. An app's own components need the same patterns, and the audit reports what is missing once the scope lists their pages:
- Names (1.1.1, 4.1.2): an icon-only button, toggle or link has a translated
aria-label; a custom control states its role and state. - Focus (2.4.7): a custom focus target carries
focus-effect. Never remove the ring (focus-visible:outline-hidden,ring-0) without another visible indicator. - Dragging (2.5.7): every drag (reorder, resize, move) has a button or key that does the same. A reorder moves through
ReorderHandle, which has both. - Character keys (2.1.4): every hotkey needs Ctrl, Alt or Meta (
Mod), as inapp-nav.tsx. There is no switch to turn shortcuts off, so a character alone or with Shift is never registered. - Motion (2.2.2): animation follows the reduced-motion preference:
motion-reduce:on CSS transitions and animations,<MotionConfig reducedMotion="user">oruseReducedMotion()formotioncomponents. - Dimmed text (1.4.3): dim text with a text step (
text-muted-foreground,text-faint-foreground), never with opacity:opacity-*or/70lowers its contrast below what the token was measured at.
The fix loop
- Read the failures in
a11y/results/manual-pass.mdanda11y/results/axe.json(every failing element per rule and state). - Fix the cause in the component, not the instance: a token, a primitive in
frontend/src/modules/ui, a shared form field. - Check the fix in the running app before trusting it. Drive the kept stack with a short Playwright script:
startSession(a11y/src/session.ts) signs in,openState(session, '<id>')(a11y/src/drive.ts) opens a state of the scope, also as a phone, a zoomed desktop or with motion allowed. Run it with the kept stack'sDEV_PORT_OFFSETandNODE_ENV=development. Check the state the fix is about and one neighbor that shares the component. - Changes that alter data (a reorder, a mute) are put back before the next run: the audit opens the first organization the audit user administers, and a changed order changes which one that is.
- Rerun the full audit. Rows the audit decides move by themselves.
- A row a reviewer decided keeps its decision and its remark, which now describes the old code: decide it again once step 3 showed the fix holds.
Do not script what the tools already measure: contrast the audit takes from the pixels and token contrast in pnpm style (How a row is decided).
Reviewing the open criteria
Use this part after a full audit, when pnpm -C a11y report lists open criteria.
Preconditions
- A fresh
pnpm a11y:runwith no skipped visits. - Packets in
a11y/results/review/<state>/:screenshot.png,tree.yml(the accessibility tree a screen reader works from),facts.json(headings, landmarks, images, fields, label against name, other languages) andtab-order.json. - The open rows and the tools' notes:
a11y/results/manual-pass.md.
Rules
- Evidence first. Every finding names the state and the element: "org-members: the grid's sort buttons are named only 'button'". A decision without it is refused.
- Cover the scope. Supports means every state the criterion applies to was looked at. Say how many in the evidence.
- Verify a failure in the live page before recording it: open the state, find the element, confirm in the DOM or the tree. A screenshot alone misleads (text in an image, an element below the fold).
- When unsure, record `open` with what was seen. A wrong Supports reaches a published report; an open row costs a person a minute.
- Stay inside the criterion. Read its text in WCAG 2.2 Understanding first; note other problems for the row they belong to.
- Do not decide what needs assistive technology. 4.1.2 and 4.1.3 get findings from the tree, never Supports: only a screen reader shows what is announced.
- Ignore development-only UI: the debug menu, devtools and the "Testing credentials" banner.
- A row that failed before becomes Supports only after its fix was driven in the running app. Reading the diff is not evidence; say in the evidence what you did and what happened.
What to check
From the packets alone:
| Criterion | Look at | Passes when | Common false alarm | |
|---|---|---|---|---|
| 1.1.1 Non-text Content | facts.images, icon buttons in tree.yml, the screenshot | Each informative image and icon control has a name that serves the same purpose; decoration is hidden | An avatar next to the person's name is decoration | |
| 1.3.1 Info and Relationships | Screenshot against tree.yml | What looks like a heading, list, table, group or label is one in the tree | A visual card grid needs no list role | |
| 1.3.2 Meaningful Sequence | Order in tree.yml against reading order in the screenshot | The tree reads in an order that makes sense | Sidebars before main content | |
| 1.3.3 Sensory Characteristics | Instructions in the text | None relies on shape, color, size, position or sound alone | "Above" and "below" with a named target | |
| 1.4.1 Use of Color | Links in text, states, errors, badges, charts | Each also differs by text, icon, underline or shape | Decorative color | |
| 1.4.5 Images of Text | Screenshot, facts.images | Text is text; logos are exempt | Screenshots shown as content | |
| 2.4.1 Bypass Blocks | facts.landmarks | A main landmark or skip link on each page; an open overlay holds focus, so it needs none | ||
| 2.4.3 Focus Order | tab-order.json positions against the screenshot | Focus follows the visual and logical order | A grid moves by arrow keys; sticky headers come first | |
| 2.4.4 Link Purpose | Links in tree.yml | Each name, with its sentence or cell, tells where it goes | Repeated "Edit" inside a named row | |
| 2.4.5 Multiple Ways | Navigation, search and links across states | Each page is reachable in two ways; steps in a process are exempt | ||
| 2.4.6 Headings and Labels | facts.headings, facts.fields | Each describes its topic or purpose | ||
| 2.5.3 Label in Name | facts.labelNotInName | Every entry's name contains its visible text | A count badge beside the label | |
| 3.1.2 Language of Parts | facts.otherLanguages, text in another language | Such passages carry lang; names and technical terms are exempt | ||
| 3.2.3, 3.2.4, 3.2.6 | Navigation, repeated controls and help across states | Same order, same names, help in the same place | ||
| 3.3.2 Labels or Instructions | facts.fields | Each field has a visible label; required and format are stated | A search field with a labelled button |
From the source, with the tools' notes as the starting point: 1.2.1 to 1.2.5 and 1.4.2 (does the app publish media, or only play what users upload?), 2.2.1 (time limits: the session lifetime, sign-in challenges, toasts that close by themselves), 2.2.2 (motion that starts by itself), 2.5.1 and 2.5.7 (is there a button for every gesture and drag?), 2.5.2 (do actions fire on release?).
By driving the browser (the verify skill explains how to launch, sign in and drive): 3.2.2 (change each kind of field, nothing navigates), 3.3.3 (do error messages say how to fix the input?), 3.3.4 (can destructive actions be confirmed or undone?), 3.3.7 (multi-step flows), 2.1.1 (each function by keyboard: menus, dialogs, the grid, the editor, uploads), 1.4.11 (the audit measures the edge of form controls; measure icons that carry meaning and focus indicators at 3:1), 1.4.13 (hover a tooltip or card, press Escape: it closes, and the sheet or dialog around it stays), 2.5.8 (targets axe could not decide).
Record
Write the decisions to a JSON file and record them in one go. A decision that the evidence cannot carry is refused, and then nothing is written.
remarks go into the published report: plain words for someone who uses the product, what does not work and how to get around it. evidence is for whoever checks the decision.
With sub-agents
Split by the three groups above, not by state: each sub-agent reads the packets once for its criteria. Sub-agents return decisions as JSON and record nothing. The orchestrator verifies every failure in the live page, drops what it cannot reproduce, and records the rest in one decide call.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingcella/skills/a11y-review/SKILL.md
Popularity
- 7-day trend score
- 0
Refreshed 25 Oct 2026, 6 days ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/cellajs/cella/a11y-review)