Accessibility

Built and tested to WCAG 2.2 AA.

Every colour pair in the kit is measured in light and dark for both brands. Every interactive component has a visible focus state, and small controls carry a 24 px target. This page lists what we checked, how, and what still depends on how your team uses the parts.

124/124colour pairs pass AA
2+2px focus ring, 3:1 or better
24px minimum targets
29A and AA criteria covered below
What we claim

AA-ready parts, not a certificate.

WCAG conformance is claimed for a whole page of a finished product, by the team that ships it. A kit cannot make that claim for you, because the result depends on your copy, your content and how parts are combined.

What Propel does claim: the colours, components and templates meet the WCAG 2.2 A and AA criteria that a design kit can meet on its own, and they are tested. Where a criterion depends on your product, the table below says so and the skill pack carries the guidance.

WCAG 2.2 is the current version of the standard. It adds criteria for focus that is not hidden by sticky bars, minimum target size, dragging alternatives, consistent help, not asking for the same information twice, and sign-in without memory tests.

What the kit does

Contrast in every mode

Text pairs meet 4.5:1 and control boundaries and focus indicators meet 3:1, in Light and Dark for Signal and Teal. Form controls use color/border/control for a 3:1 edge.

Focus you can see

Every interactive Figma component has a focused variant: a 2 px surface gap and a 2 px ring in color/border/focus. Code uses the same --propel-shadow-focus-ring.

Targets that are easy to hit

Checkboxes, radios, switches and close buttons that draw smaller than 24 px carry a 24 × 24 target layer. Phone layouts use 44 px.

Status is never colour alone

Every status pairs a shape with a word: ● ready, ■ error, ◐ processing, ▲ at risk, ○ queued. It reads in greyscale and for colour-blind users.

Motion that can stop

Durations are tokens, so a reduced-motion setting can bring them to zero in one place. Nothing in the kit flashes.

Patterns for the hard parts

Dialogs, menus, tabs and toasts in the React library follow the WAI-ARIA Authoring Practices patterns for roles, keyboard and focus return.

Criterion by criterion

WCAG 2.2, A and AA.

The criteria a design kit can affect. Criteria about captions, audio and page-level content are entirely your product's and are not listed.

How each criterion is handled
CriterionLevelIn the Figma kitIn the codeStays your job
1.1.1 Non-text contentAIcon-only buttons are paired with a tooltip naming the action.Icon-only components take a required label; decorative icons are hidden from assistive tech.Alt text for your images and a text summary for charts.
1.3.1 Info and relationshipsAFields, table headers, section headers and groups are real parts with their own text styles.Semantic elements: labels tied to inputs, table headers with scope, fieldsets for groups.Keep headings in order on your pages.
1.3.5 Identify input purposeAA—Inputs pass autocomplete through.Set autocomplete on personal-data fields.
1.4.1 Use of colourAStatus is always shape + word, so it reads in greyscale.Status renders the glyph and the word.Don't rely on colour alone in your own content and charts.
1.4.3 Contrast (minimum)AA124 colour pairs pass in Light and Dark for both brands.Tokens are generated from the same variables and re-audited on export.Use the brand generator for new colours; check text on photos.
1.4.4 Resize textAAParts use auto layout, so text can grow.Text follows browser zoom to 200%; no fixed-height text containers.Test your pages at 200% zoom.
1.4.10 ReflowAAPhone layouts at 390 wide; tables re-flow to record cards, panels to bottom sheets.Components fit 320 CSS px without sideways scrolling.Very wide data tables may scroll inside their own container.
1.4.11 Non-text contrastAAForm-control boundaries use color/border/control; focus rings reach 3:1.The same tokens drive borders, switch tracks and rings.Keep custom icons and chart marks at 3:1.
1.4.12 Text spacingAA—No clipping when line, letter and word spacing are increased.—
1.4.13 Content on hover or focusAA—Tooltips close with Escape and stay open while the pointer is on them.—
2.1.1 KeyboardAEvery interactive component has a focused variant to design the keyboard path.Controls work with Tab, arrows, Enter, Space and Escape.Custom widgets you add.
2.1.2 No keyboard trapA—Focus is held only inside modal dialogs and released on close.—
2.2.1 Timing adjustableA—Toasts pause on hover and focus.Session time-outs and auto-dismiss timing in your product.
2.3.1 Three flashesANothing in the kit flashes.Nothing flashes.Your media content.
2.4.3 Focus orderA—DOM order matches visual order; focus returns to the trigger when overlays close.Keep the order when you rearrange layouts.
2.4.6 Headings and labelsAATemplates use real, descriptive copy as the model to follow.—Write descriptive labels and headings.
2.4.7 Focus visibleAA2 px gap + 2 px ring on every interactive component.:focus-visible ring from the focus token.Don't remove focus outlines in your own CSS.
2.4.11 Focus not obscured (minimum)AAGuidance in the skill pack.Menus, tooltips and toasts never cover the focused element: 0 obscured in the audit.Keep sticky headers and toasts off the focused element.
2.5.3 Label in nameAVisible labels are part of each field.Accessible names start with the visible text.—
2.5.7 Dragging movementsAAGuidance: pair every drag with a menu action.No component needs dragging to operate.Add a click alternative, like “Move to”, to anything you make draggable.
2.5.8 Target size (minimum)AACheckboxes, radios, switches and small close buttons carry a 24 × 24 target; phone targets are 44.Hit areas of at least 24 × 24 CSS px.Spacing between your own small links.
3.2.6 Consistent helpAGuidance in the skill pack.—Keep help in the same place across pages.
3.3.1 Error identificationAError variants show an icon and a message, not only a red border.Error text is linked to its field.Write messages that say what went wrong.
3.3.2 Labels or instructionsAFields have a label and help-text slot.Form components require a label.Fill them in.
3.3.3 Error suggestionAA——Suggest the fix in your error messages.
3.3.7 Redundant entryAGuidance in the skill pack.Inputs support autocomplete.Don't ask for the same information twice in a flow.
3.3.8 Accessible authentication (minimum)AA—Inputs never block paste or autofill.Avoid puzzles and memory tests at sign-in.
4.1.2 Name, role, valueA—Native elements first; ARIA roles and states where needed.Custom widgets you add.
4.1.3 Status messagesAA—Toasts announce in a polite live region; banners can be live (status or alert) without moving focus.—

“In the code” describes the React library and its tests. A dash means the part has no say in that criterion; it depends on your content or flow.

Tests

How the code is tested.

Each React component goes through unit, keyboard and axe tests, then a real-browser audit in every colour mode. Last run 28 Oct 2026.

Test results, @thepropel/react 0.1
CheckScopeResult
Token contrast124 text and non-text pairs, Light/Dark × Signal/Teal124 / 124 pass
Unit, keyboard and axe tests19 tests covering all 34 components: names, roles, states, arrow keys, Esc and focus return19 / 19 pass
Browser axe auditWCAG 2.0, 2.1, 2.2 A + AA with contrast on; 4 colour modes × 2 widths; at rest and with menu, tooltip, toasts and dialog open0 violations in 40 runs
Focus visible and not obscured89 keyboard tab stops, light and dark89 / 89
Target size57 interactive elements, Dense density0 under 24 px
Reflow and text spacing320 px viewport with WCAG spacing overridesNo horizontal scroll, no clipped text
Contrast record

All 124 colour pairs.

Measured from the Figma variables with the WCAG relative-luminance formula. Text needs 4.5:1; focus indicators and control boundaries need 3:1.

Light · Signal — 31 of 31 pass
Light Signal contrast
ForegroundBackgroundRatioNeedsResult
color/text/primarycolor/bg/canvas16.87:14.5:1Pass
color/text/primarycolor/bg/surface18.08:14.5:1Pass
color/text/secondarycolor/bg/surface7.59:14.5:1Pass
color/text/secondarycolor/bg/subtle7.26:14.5:1Pass
color/text/tertiarycolor/bg/surface5.05:14.5:1Pass
color/text/tertiarycolor/bg/subtle4.83:14.5:1Pass
color/text/on-accentcolor/bg/accent4.87:14.5:1Pass
color/text/accentcolor/bg/surface4.87:14.5:1Pass
color/text/primarycolor/bg/selected16.97:14.5:1Pass
color/text/on-inversecolor/bg/inverse18.08:14.5:1Pass
color/status/success-fgcolor/status/success-bg4.78:14.5:1Pass
color/status/danger-fgcolor/status/danger-bg5.10:14.5:1Pass
color/status/warning-fgcolor/status/warning-bg4.92:14.5:1Pass
color/status/info-fgcolor/status/info-bg5.50:14.5:1Pass
color/status/ai-fgcolor/status/ai-bg4.94:14.5:1Pass
color/status/danger-fgcolor/bg/surface5.81:14.5:1Pass
color/status/warning-fgcolor/bg/surface5.37:14.5:1Pass
color/border/focuscolor/bg/surface4.87:13.0:1Pass
color/bg/accentcolor/bg/surface4.87:13.0:1Pass
color/border/strongcolor/bg/surface3.04:13.0:1Pass
color/chart/labelcolor/bg/surface5.05:14.5:1Pass
color/border/controlcolor/bg/surface3.38:13.0:1Pass
color/border/controlcolor/bg/subtle3.23:13.0:1Pass
color/text/tertiarycolor/bg/canvas4.71:14.5:1Pass
color/text/secondarycolor/bg/canvas7.08:14.5:1Pass
color/status/success-fgcolor/bg/surface5.36:14.5:1Pass
color/status/info-fgcolor/bg/surface6.28:14.5:1Pass
color/status/ai-fgcolor/bg/surface5.49:14.5:1Pass
color/text/accentcolor/bg/selected4.57:14.5:1Pass
color/text/on-accentcolor/bg/accent-hover6.81:14.5:1Pass
color/border/focuscolor/bg/canvas4.54:13.0:1Pass
Light · Teal — 31 of 31 pass
Light Teal contrast
ForegroundBackgroundRatioNeedsResult
color/text/primarycolor/bg/canvas16.87:14.5:1Pass
color/text/primarycolor/bg/surface18.08:14.5:1Pass
color/text/secondarycolor/bg/surface7.59:14.5:1Pass
color/text/secondarycolor/bg/subtle7.26:14.5:1Pass
color/text/tertiarycolor/bg/surface5.05:14.5:1Pass
color/text/tertiarycolor/bg/subtle4.83:14.5:1Pass
color/text/on-accentcolor/bg/accent4.87:14.5:1Pass
color/text/accentcolor/bg/surface4.87:14.5:1Pass
color/text/primarycolor/bg/selected17.04:14.5:1Pass
color/text/on-inversecolor/bg/inverse18.08:14.5:1Pass
color/status/success-fgcolor/status/success-bg4.78:14.5:1Pass
color/status/danger-fgcolor/status/danger-bg5.10:14.5:1Pass
color/status/warning-fgcolor/status/warning-bg4.92:14.5:1Pass
color/status/info-fgcolor/status/info-bg5.50:14.5:1Pass
color/status/ai-fgcolor/status/ai-bg4.94:14.5:1Pass
color/status/danger-fgcolor/bg/surface5.81:14.5:1Pass
color/status/warning-fgcolor/bg/surface5.37:14.5:1Pass
color/border/focuscolor/bg/surface4.87:13.0:1Pass
color/bg/accentcolor/bg/surface4.87:13.0:1Pass
color/border/strongcolor/bg/surface3.04:13.0:1Pass
color/chart/labelcolor/bg/surface5.05:14.5:1Pass
color/border/controlcolor/bg/surface3.38:13.0:1Pass
color/border/controlcolor/bg/subtle3.23:13.0:1Pass
color/text/tertiarycolor/bg/canvas4.71:14.5:1Pass
color/text/secondarycolor/bg/canvas7.08:14.5:1Pass
color/status/success-fgcolor/bg/surface5.36:14.5:1Pass
color/status/info-fgcolor/bg/surface6.28:14.5:1Pass
color/status/ai-fgcolor/bg/surface5.49:14.5:1Pass
color/text/accentcolor/bg/selected4.59:14.5:1Pass
color/text/on-accentcolor/bg/accent-hover6.72:14.5:1Pass
color/border/focuscolor/bg/canvas4.54:13.0:1Pass
Dark · Signal — 31 of 31 pass
Dark Signal contrast
ForegroundBackgroundRatioNeedsResult
color/text/primarycolor/bg/canvas18.46:14.5:1Pass
color/text/primarycolor/bg/surface17.31:14.5:1Pass
color/text/secondarycolor/bg/surface10.75:14.5:1Pass
color/text/secondarycolor/bg/subtle9.80:14.5:1Pass
color/text/tertiarycolor/bg/surface5.94:14.5:1Pass
color/text/tertiarycolor/bg/subtle5.41:14.5:1Pass
color/text/on-accentcolor/bg/accent6.24:14.5:1Pass
color/text/accentcolor/bg/surface8.64:14.5:1Pass
color/text/primarycolor/bg/selected17.03:14.5:1Pass
color/text/on-inversecolor/bg/inverse17.31:14.5:1Pass
color/status/success-fgcolor/status/success-bg8.27:14.5:1Pass
color/status/danger-fgcolor/status/danger-bg7.59:14.5:1Pass
color/status/warning-fgcolor/status/warning-bg8.36:14.5:1Pass
color/status/info-fgcolor/status/info-bg7.19:14.5:1Pass
color/status/ai-fgcolor/status/ai-bg7.58:14.5:1Pass
color/status/danger-fgcolor/bg/surface8.68:14.5:1Pass
color/status/warning-fgcolor/bg/surface10.49:14.5:1Pass
color/border/focuscolor/bg/surface8.64:13.0:1Pass
color/bg/accentcolor/bg/surface5.85:13.0:1Pass
color/border/strongcolor/bg/surface3.58:13.0:1Pass
color/chart/labelcolor/bg/surface5.94:14.5:1Pass
color/border/controlcolor/bg/surface3.58:13.0:1Pass
color/border/controlcolor/bg/subtle3.27:13.0:1Pass
color/text/tertiarycolor/bg/canvas6.34:14.5:1Pass
color/text/secondarycolor/bg/canvas11.47:14.5:1Pass
color/status/success-fgcolor/bg/surface9.94:14.5:1Pass
color/status/info-fgcolor/bg/surface8.50:14.5:1Pass
color/status/ai-fgcolor/bg/surface9.93:14.5:1Pass
color/text/accentcolor/bg/selected8.50:14.5:1Pass
color/text/on-accentcolor/bg/accent-hover9.21:14.5:1Pass
color/border/focuscolor/bg/canvas9.21:13.0:1Pass
Dark · Teal — 31 of 31 pass
Dark Teal contrast
ForegroundBackgroundRatioNeedsResult
color/text/primarycolor/bg/canvas18.46:14.5:1Pass
color/text/primarycolor/bg/surface17.31:14.5:1Pass
color/text/secondarycolor/bg/surface10.75:14.5:1Pass
color/text/secondarycolor/bg/subtle9.80:14.5:1Pass
color/text/tertiarycolor/bg/surface5.94:14.5:1Pass
color/text/tertiarycolor/bg/subtle5.41:14.5:1Pass
color/text/on-accentcolor/bg/accent7.37:14.5:1Pass
color/text/accentcolor/bg/surface11.32:14.5:1Pass
color/text/primarycolor/bg/selected14.95:14.5:1Pass
color/text/on-inversecolor/bg/inverse17.31:14.5:1Pass
color/status/success-fgcolor/status/success-bg8.27:14.5:1Pass
color/status/danger-fgcolor/status/danger-bg7.59:14.5:1Pass
color/status/warning-fgcolor/status/warning-bg8.36:14.5:1Pass
color/status/info-fgcolor/status/info-bg7.19:14.5:1Pass
color/status/ai-fgcolor/status/ai-bg7.58:14.5:1Pass
color/status/danger-fgcolor/bg/surface8.68:14.5:1Pass
color/status/warning-fgcolor/bg/surface10.49:14.5:1Pass
color/border/focuscolor/bg/surface11.32:13.0:1Pass
color/bg/accentcolor/bg/surface6.91:13.0:1Pass
color/border/strongcolor/bg/surface3.58:13.0:1Pass
color/chart/labelcolor/bg/surface5.94:14.5:1Pass
color/border/controlcolor/bg/surface3.58:13.0:1Pass
color/border/controlcolor/bg/subtle3.27:13.0:1Pass
color/text/tertiarycolor/bg/canvas6.34:14.5:1Pass
color/text/secondarycolor/bg/canvas11.47:14.5:1Pass
color/status/success-fgcolor/bg/surface9.94:14.5:1Pass
color/status/info-fgcolor/bg/surface8.50:14.5:1Pass
color/status/ai-fgcolor/bg/surface9.93:14.5:1Pass
color/text/accentcolor/bg/selected9.77:14.5:1Pass
color/text/on-accentcolor/bg/accent-hover12.07:14.5:1Pass
color/border/focuscolor/bg/canvas12.07:13.0:1Pass
Your part

Keeping your product AA.

  • Write labels, link text and error messages that say what they do. The kit gives every input a label slot; fill it.
  • Add alternative text to your images and a short text summary to every chart.
  • If you add a brand colour, use the generator. It keeps button and link text at 4.5:1 or better and tells you when it can't.
  • Keep sticky headers and toasts from covering the focused element, for example with scroll-padding-top.
  • Give every drag-and-drop a single-click alternative, such as a “Move to” item in the card's menu.
  • Test your shipped pages with a screen reader and a keyboard. Automated checks find about a third of real issues.