CodeForPhilly / CodeForPhilly/codeforphilly-ng

Accessibility: audit findings needing design or product decisions

Open
#156 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
1
Forks
1
Avg merge
5d 3h
Merged PRs (30d)
9

Description

A full accessibility pass over `apps/web` (every source file read; WCAG 2.1 AA + ARIA APG) produced 62 findings. The ARIA-correctness layer is already addressed in PR #154 and PR #155, and a follow-up PR covers the mechanical remainder. This issue holds the findings that are real WCAG failures but carry a **visual, content, or product dimension** that shouldn't be decided unilaterally by a volunteer — each needs a maintainer call (and, per the specops workflow, a spec touch where noted).

---

### 1. Green Volunteer CTA fails contrast — **Serious** (WCAG 1.4.3)
White on `green-600` (#16a34a) ≈ **3.05:1**; normal-size text needs 4.5:1. It's the site's primary CTA in three places. `green-700` is borderline (≈ 4.5:1); `green-800` passes comfortably. A one-class change — but it's the brand green, and there's no `success` button variant or green token, so this magic color is also a design-system gap.
`AppHeader.tsx` · `Home.tsx:92` · `Volunteer.tsx:37`

### 2. Links distinguished by color alone, and the colors are nearly identical — **Serious** (WCAG 1.4.1)
`--primary` and `--foreground` are both near-black neutrals (≈ 1.4:1 against each other vs the 3:1 required when color is the only differentiator). Some screens add `underline`, many don't. Either underline inline links by default or give `--primary` a real hue — a theme decision.
`index.css:53,58` · ~20 screens

### 3. Every route shares one document title — **Serious** (WCAG 2.4.2)
Nothing sets `document.title` per route; every page is "Code for Philly" to screen readers and tab-switchers. Needs a small per-route title convention (and a spec touch, since screens are spec-governed).
`index.html:8` · `App.tsx`

### 4. Hero slideshow auto-advances with no pause control — **Serious** (WCAG 2.2.2)
`aria-hidden` hides it from AT, but the criterion is about motion in the viewport: auto-advancing (8s crossfades) needs a visible pause/stop affordance.
`HeroSlideshow.tsx`

### 5. Whole pages have no headings because `CardTitle` is a `

` — **Serious** (WCAG 1.3.1 / 2.4.6)
All account-claim and password-reset pages are built from cards only, so they render zero headings and no `

`. Fix is per-page heading placement (or a heading-level prop pattern), not necessarily changing the shadcn primitive.
`ui/card.tsx:36` · `pages/AccountClaim*.tsx` · `PasswordReset*.tsx`

### 6. Blog/buzz images are unconditionally `alt=\"\"` — **Serious** (WCAG 1.1.1)
Authors have no way to supply alt text for featured images. Needs a content-model decision: an alt field on posts/updates, or an explicit editorial policy that featured images are decorative.
`BlogDetail.tsx:36` · `BlogIndex.tsx:124` · `ActivityCard.tsx:80`

### 7. Client-side navigation never moves focus or announces the new page — **Moderate** (WCAG 2.4.3)
`` exists but nothing focuses it on route change. A small router-level focus/announce hook — worth pairing with the document-title work (item 3).
`AppShell.tsx:24` · `App.tsx`

### 8. Filter/search result updates are silent — **Moderate** (WCAG 4.1.3)
Index screens re-render their lists after the debounce with no status announcement. A shared "N results" `role=\"status\"` line would cover them; copy and placement are design calls.
`ProjectsIndex` · `PeopleIndex` · `HelpWantedIndex` · `TagsNamespace`

### 9. Reduced-motion honored only by the hero's Ken Burns pan — **Moderate**
Spinners, sheet/dialog transitions, and `scrollTo({behavior:'smooth'})` run regardless of `prefers-reduced-motion`. The `usePrefersReducedMotion` hook exists and is under-applied; a global `@media (prefers-reduced-motion: reduce)` block is the usual fix.
`index.css` · 5 screens' scrollTo · `HeroSlideshow.tsx:70`

### 10. Network-error banner says "Retry" but only dismisses — **Moderate** (spec↔code contradiction)
The spec (`specs/behaviors/app-shell.md:162`) prescribes `[Retry]`, and the button's handler only calls `clearError()`. Surfaced during the ARIA pass and recorded in `plans/aria-correctness.md` follow-ups. Either the button should refetch or the spec's label should change — both need a spec edit first, so it's parked here rather than patched.
`NetworkErrorBanner.tsx` · `specs/behaviors/app-shell.md:162`

---

Happy to implement any of these once there's a direction — most are small once the decision is made.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.