Accessibility

Generated from DESIGN_SYSTEM.md

Rules

WCAG 2.2 Level AA is the mandatory baseline on every platform โ€” web, iOS, Android, and the browser extension. We additionally claim a small AAA "stretch" set we already meet; we do not pursue full AAA. This section governs: where an older rule in this doc conflicts (notably any "40โ€“50% opacity" text tier โ€” in Philosophy, Typography, Data Source Attribution, etc.), the contrast floors here win.

Level commitment

  • AA 2.2 โ€” required. Aligns with KR (KWCAG 2.2 / ์žฅ์ฐจ๋ฒ•), US (Section 508 / ADA โ†’ WCAG AA), and EU (EN 301 549 โ†’ 2.1 AA).
  • AAA stretch โ€” only these (already met or near-free): 2.5.5 Target Size 44px (we already mandate 44/48); 2.3.3 animation-from-interaction (reduced-motion respected); 1.4.6 7:1 contrast aspired for primary body text. All other AAA is out of scope.

Perceivable

Contrast floors โ€” these replace the opacity tiers. Text tone is limited to contrast-validated tokens; never lower text below its floor with opacity. The 40โ€“50% muted/caption tier is removed โ€” captions differ by size/weight.

WhatAA floorSource
Body / caption text (< 18.66px bold, < 24px)4.5:11.4.3 โ€” text-primary (aim 7:1), text-secondary
Large text (โ‰ฅ 18.66px bold, โ‰ฅ 24px)3:11.4.3
UI components, meaningful icons, sole control/state boundaries, focus ring, graphs that convey meaning3:11.4.11 (non-text)
Purely decorative (a border-subtle separator that isn't the only signal; disabled controls)exempt1.4.3 / 1.4.11
  • Color is never the only signal (1.4.1). Active/status/error states pair color with icon, text, shape, or weight โ€” never color alone.
  • Meaningful images carry alt text / labels (1.1.1).

Operable

  • Full keyboard (2.1.1 / 2.1.2). Every action reachable and operable by keyboard, no traps. (The "every navigation is a real anchor" rule already serves this on web.)
  • Focus visible + unobscured (2.4.7 / 2.4.11 / 2.4.13). Every interactive element shows a focus indicator โ‰ฅ 3:1 vs. adjacent colors; never outline: none without a stronger replacement. Sticky chrome (top glass bar, FAB, bottom nav) must not cover the focused element โ€” use scroll-padding / offsets so focus stays on screen.
  • Target size 44pt+ (exceeds AA's 24px 2.5.8; meets AAA 2.5.5).
  • Dragging alternative (2.5.7). Any reorder/drag offers a non-drag path (menu / buttons).
  • Reduced motion โ€” every non-essential animation respects prefers-reduced-motion / Reduce Motion.

Understandable

  • Labels above fields, never placeholder-only (3.3.2); errors inline + specific, not page-level only (3.3.1 / 3.3.3).
  • Accessible Authentication (3.3.8). Login / PIN / OTP fields allow paste + password managers; no transcription, memorization, or puzzle step. Applies to the PIN gate and the extension OAuth sign-in.
  • Predictable navigation + consistent help location (3.2.3 / 3.2.6); no redundant re-entry of known info (3.3.7).

Robust

  • Native components / valid semantic markup; name-role-value exposed (4.1.2). Web: aria-* + roles, status line aria-live. iOS: accessibilityLabel/Traits + Dynamic Type. Android: contentDescription + TalkBack + sp units.
  • Reflow at 320px (1.4.10 โ€” already mobile-first) and text resize to 200% (1.4.4 โ€” rem / Dynamic Type / sp; never fixed-px text).

Per-platform a11y API

ConcernWebiOSAndroid
Labelaria-label / <label>accessibilityLabelcontentDescription
Live regionaria-liveaccessibility announcementliveRegion
Resize / scalerem + browser zoomDynamic Typesp units
Focus:focus-visible ringaccessibility element + traitsdefault focus + traversal
Reduced motionprefers-reduced-motionisReduceMotionEnabledanimator duration scale

Live specimens

Contrast floorsHierarchy comes from size and weight, never opacity. Each ratio is measured live in this theme.

Every screen has one clear focal point

label-primary ยท Floor 4.5:1, aim 7:1

Every screen has one clear focal point

label-secondary ยท Floor 4.5:1

Visible focusPress Tab: each control shows a ring of at least 3:1.
Touch targets44px on every tap target. The checkbox draws 18px but answers across the dashed 44px square.
btn-icon ยท 44px
w-11 h-11 ยท 44px