.cursor/skills/accessibility/SKILL.md
Accessibility (A11y) guidelines for WOD Brains UI - WCAG 2.1 AA compliance. Use when making any UI changes.
npx skillsauth add jdconley/wodbrains accessibilityInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
All UI changes must maintain WCAG 2.1 AA compliance. This skill defines the accessibility patterns and requirements for the WOD Brains app.
Minimum contrast ratios (WCAG AA):
Current color system (verified):
--text: #ffffff; /* 19.6:1 on --bg-deep - PASS */
--text-muted: #9a9a9a; /* 5.7:1 on --bg-deep - PASS */
--accent: #ff10f0; /* 6.3:1 on --bg-deep - PASS */
--danger: #ff3b3b; /* 5.8:1 on --bg-deep - PASS */
Never use:
--text-muted for small critical text (use --text instead)Always add aria-label and hide the SVG:
<button type="button" aria-label="Close dialog">
<svg aria-hidden="true">...</svg>
</button>
All inputs need accessible labels:
<!-- Option 1: aria-label -->
<input type="text" aria-label="Workout title" placeholder="Title" />
<!-- Option 2: Associated label -->
<label for="title">Title</label>
<input id="title" type="text" />
Use live regions for dynamic content:
<div role="status" aria-live="polite" id="status"></div>
aria-live="polite" for non-urgent updatesaria-live="assertive" for critical alerts (e.g., errors, countdowns)<div role="dialog" aria-modal="true" aria-labelledby="dialogTitle">
<h2 id="dialogTitle">Dialog Title</h2>
...
</div>
<div role="list" aria-label="Workout steps">
<div role="listitem">Step 1</div>
<div role="listitem">Step 2</div>
</div>
element.addEventListener('keydown', (e) => {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault();
handleAction();
}
});
Global styles are defined in style.css:
:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
:focus:not(:focus-visible) {
outline: none;
}
A skip link is provided in index.html:
<a href="#main-content" class="SkipLink">Skip to main content</a>
Each page's main content area should have id="main-content".
WCAG Requirements:
CSS Patterns:
/* Ensure tap targets are accessible */
.MyButton {
min-width: 44px;
min-height: 44px;
}
/* Prevent text overflow */
.LargeText {
overflow-wrap: break-word;
word-break: break-word;
}
/* Ensure overlays scroll */
.MyOverlay {
overflow: auto;
max-height: 90vh;
}
Support users who prefer reduced motion:
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
Before submitting UI changes, verify:
aria-label, SVGs have aria-hidden="true"aria-labelrole="status" and aria-liverole="dialog", aria-modal, aria-labelledbyid="main-content" for skip linkManual Testing:
Automated Testing:
Key accessibility implementations:
apps/web/src/style.css - Focus styles, skip link, reduced motion, zoom supportapps/web/index.html - Skip link elementapps/web/src/components/header.ts - Accessible header with back buttonapps/web/src/pages/*.ts - Page-level ARIA attributesdocumentation
UI design guidelines for WOD Brains app - mobile-first, app-like design with consistent patterns. Use when making UI changes.
testing
Always create and run tests affected by changes, including Playwright for UI changes. Use when modifying Wodbrains features or UI.
development
Run Wodbrains worker parse evals and live Gemini tests locally using Wrangler `.dev.vars` keys. Use when you need to run `parse.evals.test.ts` / `parse.gemini.test.ts` against the real model (RUN_LIVE_AI_TESTS=1).
documentation
Regenerate README screenshots and the demo video for WOD Brains.