Accessibility

Accessibility is a default, not a feature. Every Justin component ships with it.

Contrast

  • All text passes WCAG AA at default sizes in both light and dark themes.
  • Token pairs are designed as background/foreground pairs (Primary / OnPrimary). Swap them both when theming — never mix across pairs.

Keyboard

  • Every interactive component is reachable by keyboard.
  • Focus order follows DOM order on web, declaration order on Compose.
  • Focus indicators are visible (no outline: none without an equivalent).
  • Escape dismisses overlays (dialog, bottom sheet).

Semantics

  • Use the correct role: buttons are buttons, links are links, headings build the document outline.
  • Provide contentDescription for every interactive icon-only control in KMP.
  • Use semantics { } blocks when aggregating custom UI into a single accessible unit.

Motion

  • Animations respect prefers-reduced-motion. When reduced, transitions are disabled or made instant.
  • No parallax, no auto-playing motion.

Screen readers

  • Components expose role, state, and value correctly.
  • Live regions (snackbar, toast, alert) announce politely unless the content is critical.

Touch targets

  • Minimum target size 48×48 dp on mobile (M3 guidance).
  • Hit targets can exceed visual size via padding — visual size may be smaller.

Color alone

  • Never use color as the sole carrier of meaning (e.g. error state uses icon + text, not just red).

Testing checklist

  • Navigate the screen using only Tab/Shift+Tab.
  • Turn on TalkBack / VoiceOver and confirm every label is meaningful.
  • Toggle prefers-reduced-motion and verify no motion plays.
  • Verify both light and dark themes (drawer toggle in the top bar).