The site follows WCAG 2.1 AA guidelines and WAI-ARIA 1.1 authoring practices. All patterns below are fully implemented.
Skip link (bypass navigation): SkipLink component renders a visually hidden 'Skip to main content' link above the sticky header. CSS translateY hides it until keyboard focus; z-[100] ensures it appears above navigation. Target: id=main-content on the <main> element.
Active navigation indication (aria-current): TopNav uses usePathname() to set aria-current='page' on the active link at render time — applied to desktop links, mobile links, and dropdown items.
WAI-ARIA 1.1 tab panel (Labs Tabs): role=tablist on the container; role=tab, aria-selected, aria-controls, and id on each tab button. Inactive tabs use tabIndex=-1; focus managed programmatically. ArrowRight/ArrowLeft cycle tabs; Home/End jump to first/last.
Focus trap (modal containment): useFocusTrap hook (hooks/useFocusTrap.ts, zero-dependency) constrains Tab/Shift-Tab to focusable elements inside an open dialog. requestAnimationFrame moves initial focus after paint. Stores and restores document.activeElement on close. Respects aria-hidden subtrees.
Dialog ARIA contract: all modal overlays set role=dialog, aria-modal=true, aria-labelledby pointing to the visible title element. ESC key handler closes modals; guards busy/loading state to prevent premature close. Confirm buttons expose aria-busy during async operations.
ARIA live regions (chat): message list uses aria-live=polite so tokens are announced after streaming completes. Form carries aria-busy={isLoading}. Error messages use an always-rendered role=alert paragraph to avoid DOM insertion timing issues.
F) Focus Trap + Modal Lifecycle
```mermaid
sequenceDiagram
participant U as User (keyboard)
participant T as Trigger button
participant M as Modal dialog
participant H as useFocusTrap hook
U->>T: Enter / Space / Click
T->>M: open = true
M->>H: activate trap (enabled=true)
H->>H: store document.activeElement
H->>M: rAF → focus first focusable element
U->>M: Tab / Shift+Tab
H->>H: constrain to first↔last focusable
U->>M: Escape key
M->>M: open = false
H->>H: cleanup listener
H->>T: restore focus to trigger button
```