Accessibility
The accessibility requirements Tanrei builds into tokens and component specs, and the checks that enforce them.
Accessibility in Tanrei is a set of constraints on the system itself. The token build refuses to produce a scheme that fails contrast, and a component spec is not valid without its role, keyboard table and target guarantee.
The token build measures every scheme, light and dark at standard, medium and high contrast, against these thresholds, and fails when a pair falls short:
| Content | Standard and medium contrast | High contrast |
|---|---|---|
| Text, and icons drawn in a content color | 4.5:1 | 7:1 |
| A status’s mark on its own tonal container | 3:1 | 3:1 |
| Boundaries and graphics needed to identify or operate a control | 3:1 | 3:1 |
| The focus ring against adjacent surfaces | 3:1 | 3:1 |
Large text has no lower threshold. WCAG accepts less contrast for text of about 24px regular, or 19px bold, and up, but the build holds every text role at 4.5:1, and at 7:1 at high contrast: a color role does not know the size it will be set in.
Disabled elements and pure decoration are exempt, and so is the outline-variant hairline at standard contrast. That exemption is why a border which is the only sign of a control must use outline, not outline-variant.
These hold for every theme at every contrast level, six permutations in all, and the build fails otherwise:
- each
(X, on-X)role pair, and each text role (on-surface,on-surface-variant,link, an intent’s color) on every surface role, is at least 4.5:1, and at least 7:1 in the two high-contrast schemes; - each status color is at least 3:1 against its own tonal container;
outlineis at least 3:1 against every surface role;- in the default system at medium and high contrast,
outline-variantis at least 3:1 and 4.5:1 against every surface role, andoutlinestays stronger; focus-ringis at least 3:1 against surfaces.
Project rules forbid loosening a threshold to make a check pass.
The least sizes of what a person presses. minimum is the least height (and, for an icon-only control, width) anything pressable is drawn at; touch and pointer are the least hit areas, which a control reaches past what it draws where it stands alone.
| Token | Value | Preview |
|---|---|---|
--tanrei-sys-target-minimum | 32px | |
--tanrei-sys-target-pointer | 44px | |
--tanrei-sys-target-spacing | 8px | |
--tanrei-sys-target-touch | 48px |
Generated from design/tokens/tanrei.light.tokens.json, tokens/sys/measure.tokens.json
Visual size is not hit area. A small Tanrei button is 32 units tall, which suits a dense toolbar, but it still responds across at least 48 units for touch and 44 for a pointer. Components extend their hit area invisibly and keep at least 8 units between neighbouring targets. Every spec declares this guarantee, and every platform tests it.
Every interactive component shows the gap-then-ring focus indicator for keyboard and assistive-technology focus, immediately and without animation. Focus order follows reading order. Disabled components leave the focus order.
Each component spec contains a table of keys and actions, shown on its documentation page under Accessibility. Platforms with hardware keyboard support implement the table exactly.
Interfaces must remain usable with text at 200%. Containers grow with their text, labels wrap before they truncate, and nothing relies on a fixed height to fit a line of text. Native implementations use each platform’s scalable text mechanism.
When the system asks for reduced motion, spatial animation is removed or replaced by a brief fade and nothing loops. See Motion.
A spec names the component’s WAI-ARIA role and how its accessible name is formed. Each platform maps the role to its native equivalent: accessibility traits in SwiftUI, semantics properties in Compose and Flutter, accessibilityRole in React Native. On the web, Tanrei prefers native elements inside the shadow root, so that browsers and testing tools see real semantics.
| Platform | Automated check |
|---|---|
| Web | axe-core in Playwright |
| SwiftUI | XCTest accessibility audit |
| Compose | Accessibility Test Framework checks |
| Flutter | meetsGuideline matchers |
| React Native | role and label assertions, plus native audits through the gallery app |
Note
Automated checks catch a minority of real problems. They are a floor. Use a screen reader and a keyboard on anything you build with these components.