Accessibility
Project-specific a11y patterns. WCAG criteria are universal — this page covers how this project applies them: skip-link target, focus-trap convention, screen-reader-only utility, semantic landmarks.
Skip link
The first focusable element on every page jumps to #main. Tab once on any page to reveal it.
<a href="#main" class="skip-link">Skip to main content</a> <main id="main"> … </main>
Screen-reader-only text
Use the .sr-only utility for content that screen readers should hear but sighted users don't need to see.
<button> <svg aria-hidden="true">…</svg> <span class="sr-only">Open menu</span> </button>
Semantic landmarks
Every page MUST have one <main>, one <h1>. Nav inside <nav aria-label="…">, complementary content inside <aside>.
<header>…</header> <nav aria-label="Primary">…</nav> <main id="main"> <h1>Page title</h1> … </main> <aside>…</aside> <footer>…</footer>
Focus trap (modals)
Modal dialogs use role="dialog" aria-modal="true" and trap Tab focus inside. Esc closes. After close, focus returns to the trigger.
ARIA live regions
Use aria-live="polite" on status updates (notifications, count badges that change). Use aria-live="assertive" only for true emergencies (form errors blocking submit).
Focus indicators
Every focusable element has a visible focus indicator via :focus-visible — see foundations/focus. Never outline: none without a replacement.