a11y: RecipesView audit — 6 critical, 8 high, 9 medium (WCAG 2.1 AA + ND-informed) #80
Labels
No labels
accessibility
backlog
beta-feedback
bug
duplicate
enhancement
feature-request
help wanted
invalid
needs-design
needs-triage
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: Circuit-Forge/kiwi#80
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Full accessibility audit of
RecipesView.vueconducted 2026-04-14 covering WCAG 2.1 AA compliance and ND-informed design (ADHD, autism, executive function, depleted states).Two layers audited:
CRITICAL — ADA/WCAG Hard Failures
C1: Level selector buttons missing
aria-pressedLines: 53–66 (also dietary presets ~99–105, cuisine style ~225–230)
Plain
<button>elements with CSS.activeclass only. Screen readers cannot communicate which level is selected.Fix:
:aria-pressed="recipesStore.level === lvl.value"on each level button; same pattern on dietary preset and cuisine style buttons.C2: Filter chips missing
aria-pressed+ unclear clear labelLines: 319–338
Result filter chips use CSS
.activewith no ARIA state.✕ Clearmay be announced as "multiplication sign".Fix:
:aria-pressedon each chip;aria-label="Clear all recipe filters"on clear chip.C3:
<details>/<summary>needaria-expandedfallbackLines: 88–177, 180–246, 459–476
Native
<details>marker suppressed via CSS. Older JAWS+Chrome may lose expanded/collapsed announcement.Fix: Track open state with ref bound to
@toggle; bind:aria-expandedon<summary>.C4: Bookmark/dismiss buttons below minimum touch target
Lines: 368–379
12–14px font, 2px padding — under 24×24px minimum (WCAG 2.5.8).
Fix: Apply
.btn-iconclass (32×32px in theme.css) or increase padding.C5: Loading state has no screen reader announcement
Lines: 255–258, 514–516
Visual spinner only. Screen reader users cannot tell if button worked.
Fix:
aria-busy="true"on results container; updatearia-liveto announce "Finding recipes…"C6: Error div missing
role="alert"Lines: 275–277
.status-errorhas norole="alert". API failures are invisible to screen readers.Fix: Add
role="alert"to the error div.HIGH — Significant Barriers
H1/H2: Contrast failures
--color-text-muted~3.1:1 dark, ~2.9:1 light — fails WCAG 1.4.3 at 11px usage sites--color-success-light: #6aac60~4.3:1 at 11px in dark mode (threshold is 4.5:1)Fix: Darken light muted to
#7a5c2e; bump dark opacity to 0.52; lighten success to#7fc073.H3: Tab activation doesn't move focus to panel
Lines: 583–593
APG pattern requires focus to move to tabpanel.
tabindex="0"missing on panels.Fix:
tabindex="0"on panels;nextTick(() => panelRef.value?.focus())on tab select.H4:
openRecipeByIdsilent failureLines: 603–609
Catch block discards error. User taps a recipe and nothing happens.
Fix: Set error state +
aria-liveannouncement: "Recipe couldn't load. Please try again."H5: Nutrition chips — emoji are the only label
Lines: 400–427
🔥 🧈 💪 etc. announced verbosely and inconsistently across screen readers.
Fix:
aria-hidden="true"on emoji;<span class="sr-only">Calories:</span>alongside each value.H6/H7/H8: Five form inputs with unlinked
<label>elementsLines: 164–175 (Max Missing), 191–215 (4× nutrition filters), 237–243 (Category)
Sibling
<label>elements with nofor/idlinking.Fix: Add matching
for/idpairs to all five.MEDIUM — ND / Calm-UX Policy
Lv1/Lv2filter chips require working memory — use level namesopenRecipeByIdsilent fail (ND dimension of H4)LOW
prefers-reduced-motionblock (belt-and-suspenders)autocomplete="off"on recipe text inputsaria-label="Clear all filters"on ✕ chiptext-warningamber for informational contentWhat Is Already Correct
aria-pressedprefers-reduced-motionguard in theme.css blanket-applied correctlyaria-liveresults region: polite, aria-atomic, .sr-only, clean count formataria-describedbyon wildcard checkbox and constraint/allergy inputslang="en"on<html>aria-labelincludes recipe title (correct disambiguation)aria-pressedcorrectly implementedScope
aria-pressedon level, dietary preset, cuisine style buttonsaria-pressedon filter chips; fix clear labelaria-expandedon collapsible<summary>elementsaria-busy+ loadingaria-liveannouncementrole="alert"on error divopenRecipeByIdaria-hiddenemoji +.sr-onlynutrition labelsfor/idpairs on five form inputsRelated: cf-a11y audit 2026-04-14 ·
circuitforge-plans/kiwi/superpowers/specs/2026-04-14-build-your-own-recipe-tab-design.md