Accessibility · WCAG 2.1 AA, with the system's real values
Accessibility
01
Contrast — the measured floor
Every text/background pair is verified, not eyeballed. Body ≥4.5:1, large text ≥3.0:1. The system's darkened -ink token variants exist specifically so small text clears the bar — raw accents don't.
Pair
Ratio
Verdict
ink on paper
15.99
Body ✓
ink-soft on paper
8.00
Body ✓
teal-ink on paper
4.44
Body ✓*
yellow-ink on paper
4.71
Body ✓
green-ink on paper
5.07
Body ✓
white on teal button
2.57
Large only
white on indigo button
6.29
Body ✓
Contrast
The floor
Body ≥ 4.5:1
Large (≥24px / ≥18.66px bold) ≥ 3.0:1
Non-text (borders, icons) ≥ 3.0:1
Small UI text → use the darkened -ink token, never the raw accent.
*teal-ink 4.44 is a hair under 4.5 — fine for large/medium, use ink-soft for dense small body.
02
The white-on-accent trap
White on teal is only 2.57:1 — it fails for body text and passes only because buttons use large bold type. The rule this forces: white-on-accent is a large-text-only move. Small white text on a bright accent is a real failure.
Start free →
✓ large bold white on teal — passes (large-text bar)
✕ small teal text like this on paper fails at 13px
✓ darkened teal-ink at the same size passes
White-on-accent
Large only
White on a bright accent passes only at large sizes. It is not a general-purpose pairing.
Button labels are ≥17px bold on purpose — that's what makes white-on-teal legal.
Small badge on accent? Darken the field or switch to ink text.
03
Focus — always visible
Keyboard users need to see where they are. Every interactive element gets a visible focus ring: 3px indigo, offset so it clears the shape. Tab through these — the ring only shows for keyboard, not mouse, via :focus-visible.
Motion can trigger nausea and migraines for people with vestibular conditions. The system honors prefers-reduced-motion everywhere, and every animation has a still state that loses no meaning. (Full detail lives in the Motion styleguide.)
The contract:
One media query disables all animation and transition. No motion is ever the sole carrier of information — a drawn line shows complete, a walking figure stands still, a counter shows its final value. Freezing the page loses delight, never meaning.
Motion policy
Not optional
Vestibular safety, not preference. Honored system-wide.
Meaning survives frozen — see the Motion styleguide's reduced-motion table.
On touch screens, a target smaller than about 44×44px is a miss-tap waiting to happen. A control can look small but must have a 44px hit area via padding.
✓ 44×44 — comfortable✕ 26×26 — too small to reliably tap
Touch targets
44 × 44 floor
Every tappable control clears 44px, padding out a small glyph if needed.
Small icon? Keep the glyph small, pad the hit area to 44px.
min-width:44px;
min-height:44px;
06
Color is never the only signal
Roughly 1 in 12 men can't reliably tell red from green. So color never carries meaning alone — it's always backed by an icon, a label, or a shape. Red-with-an-✕ and green-with-a-✓, not just red and green.
✓ Passed — icon + label + colour
✕ Failed — icon + label + colour
Even in greyscale, the ✓/✕ and the words carry it. Colour is reinforcement, not the message.
Redundant coding
Never color alone
Every color signal is backed by icon, text, or shape.
Test: does it still read in greyscale? The wrong/right cards, statuses, and charts all must.
07
Semantics first, ARIA to fill gaps
A real <button> is accessible for free; a <div> pretending to be one is work. Use native HTML for its built-in semantics, and reach for ARIA only where HTML genuinely falls short — icon-only buttons, live regions, decorative SVGs.
Situation
The right move
A clickable thing
<button> / <a>, not a div
Icon-only control
aria-label="Add"
Meaningful illustration
role="img" + aria-label
Decorative illustration
aria-hidden="true"
Page structure
h1→h2→h3 in order, nav/main
Form field
<label for> tied to input
Semantics & ARIA
HTML does the work
Native elements first; ARIA only for real gaps.
First rule of ARIA: don't use ARIA if HTML already conveys it.
SVGs: role="img"+label if meaningful, aria-hidden if decorative.
Created for you, with ❤️ by Robert Evans· The AI Design Architect