Accessibility

The WCAG 2.2 AA rules the kit holds for screens, the contrast tokens, the keys that hold everywhere, and three pre-release checks.

Rules

The bar is WCAG 2.2 AA and the whole admin is operable from the keyboard. That is not only an obligation: shop-floor staff work faster by key than by mouse. Most rules are held by the components themselves — which is why screens are assembled from them and not from copied classes, where the bar quietly drops.

  • Everything works from the keyboard and focus is always visible — the ring is never turned off.
  • Colour never carries meaning alone: a state is accompanied by text or shape. “Overdue” is spelled out, not left to a red dot. The same holds for charts and operation colour dots.
  • Headings go level by level without skipping — screen readers navigate by them.

Contrast

Contrast is not judged by eye — the palette is measured for it, so it is enough to reach for the right token. A colour outside the tokens carries no such guarantee.

  • Text at least 4.5 : 1. --ink, --ink-2 and --ink-3 hold AA on white and on --surface-2 alike, in the light and the dark theme.
  • --ink-4 is for disabled states and decoration only, never for readable content — it does not reach AA and is not meant to.
  • Non-text elements need at least 3 : 1: the outline of an input, a switch and a checkbox therefore take --border-strong, not --border. With the ordinary outline the edge of a field would vanish on a light surface.

Focus and keyboard

The focus ring is 2px of --accent with a 2px offset. An input adds a soft 3px ring in --accent-bg, so the field stays legible on a raised surface. outline: none without a replacement is never used — it is the fastest way to close a screen to keyboard users.

Click here and walk both elements with Tab — the ring has to show on both.

Five keys hold across the whole admin. A screen does not redefine them — a relearned key costs the user more than a missing one.

Keyboard shortcuts
KeyBehaviour
TabThe order matches the visual order; hidden elements drop out of it.
EscCloses the side panel, the modal and an expanded menu; focus returns to the element that opened it.
↑ ↓Movement inside a list and an expanded menu; focus does not escape the component.
Cmd/Ctrl KGlobal search from anywhere.
EnterSubmits a form; in a table it opens the detail of the highlighted row.

Semantics and assistive technology

A screen reader does not see the layout — it reads role, name and state. Whatever a screen says by shape has to be said by those too.

  • An icon button always carries an aria-label with a verb; a decorative icon is hidden from screen readers.
  • A modal and a side panel carry role="dialog", aria-modal="true" and a trapped focus; the rest of the page beneath them is marked inert so it cannot be tabbed into.
  • Notifications and validation go to aria-live="polite"; assertive is reserved for a critical error, because it interrupts whatever the screen reader is reading.
  • A table has real header cells with scope, otherwise a screen reader cannot tell which column a cell belongs to; a selected row carries aria-selected.
  • A field error is tied to its field through aria-describedby — not by the border colour alone, which a screen reader never reads.
  • Clickable area at least 32 × 32 px in dense tables, and 44 × 44 px on touch.
  • prefers-reduced-motion turns off shifts and animation; only the colour change remains.

The pre-release check

Three quick checks before a screen ships. They do not measure everything — but what fails them fails everything else too.

  1. Walk the screen with the Tab key alone: every element is reachable, focus is visible, and nothing loops.
  2. Zoom to 200 %: nothing overflows, nothing overlaps, no text is cut off, the table scrolls horizontally and the top bar does not fall apart.
  3. Picture the screen in greyscale: every state must be recognisable without colour.