From il
IL frontend a11y audit — WCAG 2.1 AA, semantic HTML, ARIA, keyboard nav, focus, color contrast.
How this skill is triggered — by the user, by Claude, or both
Slash command
/il:audit-accessibilityThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Evaluates the accessibility posture of generated or modified frontend code. Checks for WCAG 2.1 AA compliance, semantic HTML, ARIA correctness, keyboard navigation, focus management, and color contrast — calibrated to Imagine Learning's ed-tech requirements where students with disabilities are a core user population.
Evaluates the accessibility posture of generated or modified frontend code. Checks for WCAG 2.1 AA compliance, semantic HTML, ARIA correctness, keyboard navigation, focus management, and color contrast — calibrated to Imagine Learning's ed-tech requirements where students with disabilities are a core user population.
A high score means the UI is usable by people with diverse abilities; a low score means barriers exist that prevent or degrade access.
Context: This audit runs against newly generated code changes (the git diff + new/modified files) that contain frontend components, pages, or templates. If the changeset contains no frontend code, this audit should return a score of 10 with a note that no frontend code was present.
Applicability: Skip this audit entirely (return score 10, confidence High, zero findings, summary "No frontend code in changeset") if the changeset contains zero .tsx, .jsx, .vue, .svelte, .html, or template files.
div/span with ARIA roles bolted on.button, a, select, input, dialog, nav, main, header, footer, section, article) rather than div with onClick or role="button".
<button onClick={...}>, <nav>, <main>, <dialog>, <ul> for lists, <table> for tabular data<div onClick={...}>, <span role="button">, <div class="nav">, custom dropdown built entirely from divsdiv/span elements without proper roles caps the score at 5 maximum.aria-label on icon-only buttons, aria-expanded on disclosure widgets, aria-live on dynamic content regions, aria-describedby linking errors to inputsaria-label duplicating visible text, invalid ARIA roles, aria-hidden="true" on focusable elements, missing aria-expanded on toggles, redundant ARIA on native elements (role="button" on <button>)aria-hidden="true" is set on a focusable/interactive element (makes it invisible to screen readers but still focusable — a trap); MAJOR for missing ARIA on custom widgets; MINOR for redundant/unnecessary ARIAtabIndex={0} with onKeyDown handlers for custom widgets, focus order follows visual order, no tabIndex values greater than 0tabIndex={-1} on elements that should be in the tab order, positive tabIndex values disrupting natural order, mouse-only interactions (hover to reveal, drag without keyboard alternative)<dialog> element where possible — it provides focus trapping and restoration for free.<img, <Image, <svg, <video, <audio elements and verify accessibility attributes.
alt text, decorative images have alt="", SVG icons have aria-hidden="true" or aria-label, videos have captions/transcriptsalt attributes, decorative images with meaningless alt text ("image", "icon"), SVG icons without any label, auto-playing media without controlsalt=""); CRITICAL for auto-playing audio/video without controls<label> with matching htmlFor/id, errors linked via aria-describedby, aria-invalid set on errored fields, error summary announced via aria-live="polite" regionaria-required or incomplete error announcementsoutline: none) without replacement, custom colors that bypass the design systemDomain-specific scoring applies: more than 3 clickable div/span elements caps the score at 5 maximum.
Your default assumption should be that the generated code has accessibility gaps. Most AI-generated frontend code defaults to divs with click handlers and skips focus management.
aria-describedby on an error message)aria-hidden on a focusable modal.tsx, .jsx, .vue, .svelte, .html files in the changesetdiv.*onClick, span.*onClick, div.*role= to find non-semantic interactive patterns<img, <Image, <svg and check for alt or aria-label attributes<input, <select, <textarea and verify <label> associationsoutline: none, outline: 0 to find removed focus indicatorsaria-hidden and verify it's not on focusable elementstabIndex usage and flag positive valuesReturn results as structured JSON:
{
"category": "accessibility",
"score": 5,
"confidence": "High",
"findings": [
{
"severity": "MAJOR",
"criterion": "semantic-html",
"description": "3 clickable div elements used instead of button — score capped at 5",
"location": "src/components/ActionBar.tsx:24,31,47",
"recommendation": "Replace <div onClick={...}> with <button onClick={...}> — native buttons provide keyboard access, focus management, and screen reader semantics for free"
},
{
"severity": "MAJOR",
"criterion": "focus-management",
"description": "ConfirmDialog component has no focus trap — users can tab behind the dialog to page content",
"location": "src/components/ConfirmDialog.tsx:18",
"recommendation": "Use the native <dialog> element or add a focus trap (e.g., focus-trap-react) and return focus to the trigger on close"
}
],
"top_recommendations": [
"Replace clickable divs with native button elements across ActionBar component",
"Add focus trap and focus restoration to ConfirmDialog",
"Add aria-describedby linking error messages to their form inputs in StudentForm"
],
"summary": "Moderate accessibility gaps -- non-semantic interactive elements and missing focus management in modal dialogs"
}
npx claudepluginhub imaginelearning/dp-claude-plugin --plugin ilCreates bite-sized, testable implementation plans from specs or requirements, with file structure and task decomposition. Activates before coding multi-step tasks.