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

Research direction

Start by reading the listed TypeScript/TSX files and the referenced app-shell spec, then get maintainer decisions for each visual, content, or product question. Work only on findings with an agreed direction; done means the selected WCAG failures are resolved and any noted spec changes are updated.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
accessibility, frontend
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.