ワンクリックで
audit-accessibility
Audit for accessibility — keyboard navigation, ARIA labels, contrast, focus indicators
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Audit for accessibility — keyboard navigation, ARIA labels, contrast, focus indicators
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
Fill missing type, title, and description frontmatter on documents using structured AI output
Download a web page by URL and save it as clean markdown with images
Produce a full dependency health report (SBOM, vulnerabilities, staleness, upgrades, licenses)
Audit error handling UX — error boundaries, silent failures, loading states, empty states
Audit for unnecessary re-renders — Zustand subscriptions, missing memoization, inline callbacks
Audit test coverage — inventory tests by type, find critical untested paths
SOC 職業分類に基づく
| name | audit-accessibility |
| description | Audit for accessibility — keyboard navigation, ARIA labels, contrast, focus indicators |
| user-invocable | true |
Audit for basic accessibility compliance (WCAG AA). This is a research-only audit — do not modify any code.
<div onClick> or <span onClick> without role, tabIndex, and onKeyDown — these are invisible to keyboard users.Dialog, Popover, and AlertDialog provide this automatically — verify they are not overridden.TreeOverlay (src/components/sidebar/quiet/TreeOverlay.tsx), AgentOrb popover (src/components/activity/AgentOrb.tsx), and Focus Mode (src/hooks/useFocusMode.ts).focus() on open and previousFocus.focus() on close.document.body or nowhere visible as Medium severity.aria-label or aria-labelledby.
title-only is NOT sufficient — VoiceOver on macOS announces title only after a 5-second hover delay and not at all during keyboard navigation. Flag any <Button size="icon"> or <button> that has title but no aria-label.size="icon" combined with title= but no aria-label=<label> elements or aria-label.
placeholder is NOT a label substitute — it disappears on input and is not announced reliably by all screen readers. Flag any <input> or <textarea> that has placeholder but no aria-label, id+<label htmlFor>, or aria-labelledby.<input or <textarea without aria-label or htmlFor/id pairing nearby.role="combobox" inputs: Any element with role="combobox" is an interactive control and requires an accessible name via aria-label or aria-labelledby. placeholder alone is insufficient (VoiceOver reads "text area" on programmatic focus). Grep:
grep -rn 'role="combobox"' src/components/ --include="*.tsx" | grep -v "aria-label\|aria-labelledby"
Flag any hit as High severity if it is a primary interaction surface (the chat bar, search inputs). The FloatingCommandBar textarea (src/components/cmd/FloatingCommandBar.tsx) was the confirmed violation in the 2026-06-03 audit.aria-live attributes?This project's design system mandates that every <Tooltip> must live inside a <TooltipProvider> ancestor. Radix Tooltip reads its config from the provider's React context — without it, Radix throws Tooltip must be used within TooltipProvider at render time and the editor's ErrorBoundary catches the crash, blanking the entire editor surface.
The portal problem: Radix <PopoverContent>, <DropdownMenuContent>, <DialogContent>, and <SelectContent> all render via React portals to document.body. Any <TooltipProvider> that wraps the component outside the portal does NOT reach inside it. Inner tooltips crash even when outer tooltips work fine.
How to audit:
Find every <Tooltip> usage in the codebase:
grep -rn "<Tooltip" src/components/ --include="*.tsx" | grep -v "TooltipProvider\|TooltipTrigger\|TooltipContent"
For each <Tooltip> found, check whether it renders inside a Radix portal surface (PopoverContent, DropdownMenuContent, DialogContent, SelectContent, CommandList, SheetContent).
If yes: verify there is a <TooltipProvider> inside that same portal render, not merely in the parent component tree.
Flag any violation as HIGH severity — it is a guaranteed runtime crash for users who trigger that UI path. (e.g. TextColorPopover.tsx, HighlightPopover.tsx, and TableToolbar.tsx + TableToolsPopover.tsx were the confirmed violations in the 2026-06-03 audit.)
Known safe pattern (copy from src/components/editor/StatusTray.tsx):
<PopoverContent ...>
<TooltipProvider delayDuration={300}>
{/* tooltips here are safe */}
</TooltipProvider>
</PopoverContent>
Components with safe self-contained providers (reference list):
src/components/activity/AgentOrb.tsxsrc/components/cmd/FloatingCommandBar.tsxsrc/components/editor/StatusBar.tsxsrc/components/editor/StatusTray.tsxsrc/components/editor/Toolbar.tsx (has providers, but they do NOT reach inside portaled PopoverContent)<h1>-<h6>) used for structure, not just styling?<ul>/<li> or have role="tree"/role="treeitem"?aria-label describing what's loading?aria-describedby?Check text/background combinations against WCAG AA (4.5:1 for normal text, 3:1 for large text)
Pay special attention to:
text-muted-foreground) on both light and dark backgroundsDesign-system color token compliance: This project prohibits hardcoded chromatic colors in UI components — all color must flow through CSS variables defined in globals.css. Hardcoded Tailwind chromatic classes (bg-green-500, bg-amber-500, bg-red-500, text-blue-*, etc.) bypass the contrast audit tooling (pnpm audit:contrast) and break theme switching.
Grep for violations:
grep -rn "bg-\(green\|amber\|yellow\|blue\|indigo\|violet\|teal\|cyan\|pink\|rose\|orange\)-[0-9]" src/components/ --include="*.tsx"
grep -rn "text-\(green\|amber\|yellow\|blue\|indigo\|violet\|teal\|cyan\|pink\|rose\|orange\)-[0-9]" src/components/ --include="*.tsx"
Allowed exceptions: bg-destructive / text-destructive (mapped to --color-destructive) and bg-[var(--color-accent-primary)] (the single opt-in accent token). Every other chromatic class is a violation. (e.g. StatusBar.tsx used bg-green-500 / bg-amber-500 / bg-red-500 in the 2026-06-03 audit.)
Flag as Medium severity (breaks the theme system and makes contrast unauditable).
WCAG 2.3.3 (AAA) and the design system both require that animations can be suppressed when the user has enabled "Reduce Motion" in macOS System Preferences.
What to audit:
animate-pulse without a guard — this is the most common violation. Every animate-pulse must have either:
motion-reduce:animate-none modifier, ORuseReducedMotion() from src/hooks/useReducedMotion.tsGrep:
grep -rn "animate-pulse" src/components/ --include="*.tsx" | grep -v "motion-reduce"
Any hit that also lacks useReducedMotion in the same component is a violation.
animate-spin on loaders — same rule. Loader2 spinners and RefreshCw rotate animations should respect reduced-motion.
grep -rn "animate-spin" src/components/ --include="*.tsx" | grep -v "motion-reduce"
CSS keyframe animations in globals.css — custom keyframes (e.g., @keyframes orb-pulse) must have a @media (prefers-reduced-motion: reduce) guard that zeroes or removes the animation. Check src/styles/globals.css.
Transition durations on layout-affecting properties — transition-all, transition-transform, and transition-height in large containers should use motion-reduce:transition-none or be conditional.
Correct patterns (copy from these):
useReducedMotion() hook: src/hooks/useReducedMotion.ts@media guard: src/styles/globals.css (.orb-pulsing block)src/components/editor/StatusTray.tsxSeverity guide:
LinkPreviewCard): Low (brief)For each finding:
### <SEVERITY>: <Short title>
**File:** `<path>:<line>`
<What accessibility barrier exists and who it affects.>
**Fix:** <Remediation with code example.>
End with a ### Confirmed Good Patterns section.
File: src/components/editor/Toolbar.tsx:145-180
The formatting toolbar has 15+ icon-only buttons (bold, italic, undo, etc.) rendered as <Button size="icon"> without aria-label. Screen readers announce these as "button" with no indication of what they do.
Fix: Add aria-label to each icon button:
<Button size="icon" aria-label="Bold" onClick={toggleBold}>
<Bold className="h-4 w-4" />
</Button>