Skip to content
Brand & UX guide
Quality

Accessibility

The bar every screen has to clear: contrast, keyboard, focus, motion, and meaning that never depends on color.

#The standard

Every text and background pairing meets WCAG 2.2 AA (4.5:1 for text) in light and dark. The full measured table is on Color, and this site’s build fails if a pairing falls below it.

#What to check on every screen

AreaRequirement
ContrastUse only the pairings in the contrast table. Re-check any new one, in both themes.
Not color aloneStatus has words, an arrow, or a dot with a label. A delta’s direction is in its arrow.
KeyboardEvery control is reachable by Tab in reading order, and works with Enter or Space. No keyboard traps, except inside an open modal.
FocusA visible 2px ring on every interactive element. Never remove it.
NamesEvery input has a label tied by for/id. Icon-only buttons have aria-label. Icons are aria-hidden.
StructureOne h1 per page, headings in order, one nav landmark for the app, a main.
ChartsSparklines have role="img" and an aria-label. The numbers are in text beside them.
Errorsrole="alert", plain words, and focus stays where the person can act.
Motion120 to 200ms and only to confirm. prefers-reduced-motion is honored globally.
Zoom and reflowUsable at 200% zoom and at 390px wide with no horizontal scroll.
TargetsButtons and inputs are at least 40px tall.

#Patterns that work

#Label and hint

A field done right
We send your weekly pack here.
Code
<div class="field">
  <label for="a11y-email">Email</label>
  <input id="a11y-email" type="email" aria-describedby="a11y-hint" autocomplete="email" />
  <div class="field-hint" id="a11y-hint">We send your weekly pack here.</div>
</div>

#Status that does not rely on color

Word plus tone
● ConnectedWaiting for first reportFailed
Code
<div class="btn-row"><span class="pill pill-accent">● Connected</span><span class="pill pill-warn">Waiting for first report</span><span class="pill pill-danger">Failed</span></div>

#Dialog

  • Use role="dialog" and aria-modal="true" with an accessible name from its heading.
  • Move focus into the dialog on open. Return it to the trigger on close. Escape closes it.

#How to test

  1. Tab through it with no mouse. Can you do everything, and always see where you are?
  2. Flip the theme using the toggle in this guide’s top bar, or the Light and Dark buttons on any specimen.
  3. Squint test: view in grayscale. Is every status still readable?
  4. Phone width: 390px, no horizontal scroll.
  5. Screen reader: headings and landmarks read in a sensible order, and every control has a name.
  6. Reduced motion: turn it on in your OS. Nothing should depend on animation.
Weekwright brand & UX guide v1.0.0 Components rendered from app @ bd6c1f4 · build d2e1ef8