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.