# Accessibility Report — RC A11Y-01 WCAG 2.1 AA audit + fixes across the whole application: Storefront, Builder (Project Editor), Backoffice (Admin). No redesign, no layout changes, no route/business-logic changes. Three sequential commits on branch `B2B` (not pushed): | Commit | Scope | |---|---| | `fb1afb7` | Storefront | | `a03260e` | Builder | | `565fd9b` | Backoffice | `npm run build` verified green after every commit. `npx tsc --noEmit` clean throughout. This audit goes deeper than the prior composition pass (`docs/UI-COMPOSITION-REVIEW.md` — skeletons/empty-states/`scope="col"`) into categories that pass didn't cover: skip links, keyboard-operable drag-and-drop, dialog focus management, color contrast ratios, form label association, live-region announcements, and combobox/tablist ARIA patterns. ## Fixes by area ### Storefront (`fb1afb7`) - **Skip link** — didn't exist anywhere in the app. Added as the first focusable element (`app.html`), targeting a new `#main-content` landmark. Single most commonly-missing WCAG 2.4.1 fix, present nowhere before this. - **Keyboard/focus traps** — header mobile menu kept its items tabbable/screen-reader-reachable while visually collapsed; fixed via `visibility` + delayed transition. Header's search input had no keyboard activation path. - **Dialog accessibility** — cart's custom payment/bank-payment modals had *no* focus-trap, Escape handling, or return-focus, despite prior docs assuming `app-dialog` coverage — they're custom, not `app-dialog`. Ported the confirmed-correct `app-dialog` pattern directly onto them. - **Screen-reader announcements** — payment status screens (creating/waiting/success/error/timeout) got `role="status"`/`role="alert"` + `aria-live`. - **Search combobox** — added `role="combobox"`/`aria-autocomplete`/`aria-controls`/`aria-activedescendant` so the existing arrow-key navigation is actually announced to screen readers (previously silent). - **Tabs** — product tabs had `role="tab"` with no `tablist`/`tabpanel` wrapper; completed the pattern. - **Forms** — review-form errors now `aria-describedby` + `role="alert"`; `aria-required` on review textarea and delivery select. - **Icons** — `app-icon` (shared, app-wide) claimed "decorative by default" in its own contract but never actually applied `aria-hidden` — fixed for real, affects every icon usage across the app. - **Contrast** — `--text-light` measured 3.39:1 (dexar theme) / 2.54:1 (lavero/novo) against the 4.5:1 requirement. Switched the 2 in-scope usages to `--text-secondary` (7.56:1 / 4.55:1). ### Builder (`a03260e`) - **Skip link** — Builder routes render outside the storefront app-shell entirely (bare ``), so the storefront fix didn't cover it. Added separately with its own `#builder-main-content` landmark. - **Keyboard-operable drag-and-drop (WCAG 2.1.1)** — Homepage section's block list and Footer section's columns/links use Angular CDK drag-drop with zero keyboard equivalent. Added move-up/move-down button fallbacks (Navigation and Widgets sections already had this from an earlier sprint). - **Undefined `--color-primary` token** — same bug class as the prior composition pass, missed there: 7 usages across 3 files silently fell back to hardcoded hex, never responding to tenant theming. Remapped to the real `--primary-color` token. - **Forms** — color-picker's `` swatches (8 instances) had no accessible name; new-locale input relied on placeholder text alone (invisible to screen readers once a value is typed). - **Screen-reader announcements** — save-bar status/draft-restored notice and media-picker upload errors had no `aria-live`/`role`. ### Backoffice (`565fd9b`) - **Sidebar nav mislabeled** — `