--- name: Accessibility description: | WCAG 2.2 AA accessibility standards for the Exceptionless frontend. Semantic HTML, keyboard navigation, ARIA patterns, focus management, and form accessibility. Keywords: WCAG, accessibility, a11y, ARIA, semantic HTML, keyboard navigation, focus management, screen reader, alt text, aria-label, aria-describedby, skip links, focus trap --- # Accessibility (WCAG 2.2 AA) ## Core Principles - Semantic HTML elements and ARIA landmarks - Keyboard-first navigation with visible focus states - Skip links for main content in layouts - Inclusive, people-first language ## Semantic HTML ```svelte

Page Title

Section Title

...
``` ## Skip Links ```svelte Skip to main content ``` ## Form Accessibility ### Label Every Control ```svelte ``` ### Required Fields ```svelte ``` ### Error Messages ```svelte {#if hasError}

Please enter a valid email address

{/if} ``` ### Validation Behavior - On validation failure: focus first invalid input - Never disable submit just to block validation - Show inline errors linked via `aria-describedby` ## Keyboard Navigation ### Focus Order ```svelte ``` ### Focus Management in Dialogs ```typescript // When dialog opens, focus first interactive element $effect(() => { if (open) { dialogRef?.querySelector('input, button')?.focus(); } }); // When dialog closes, return focus to trigger const triggerRef = document.activeElement; // ... on close triggerRef?.focus(); ``` ### Keyboard Shortcuts ```svelte ``` ## Images and Icons ### Informative Images ```svelte {`Profile ``` ### Decorative Images ```svelte ``` ### Icon Buttons ```svelte ``` ### Icons with Text ```svelte ``` ## ARIA Patterns ### Live Regions ```svelte
{#if loading} Loading events... {/if}
Error: Failed to save changes
``` ### Expandable Content ```svelte ``` ### Tabs ```svelte
Tab content
``` ## Color and Contrast - Minimum contrast ratio: 4.5:1 for normal text - 3:1 for large text and UI components - Don't rely on color alone to convey information ```svelte Invalid input ``` ## Testing Accessibility ```bash # Run axe-playwright audits in E2E tests npm run test:e2e ``` ```typescript // In Playwright tests import AxeBuilder from '@axe-core/playwright'; test('page is accessible', async ({ page }) => { await page.goto('/dashboard'); const results = await new AxeBuilder({ page }).analyze(); expect(results.violations).toEqual([]); }); ```