Skip to content
menumenu tanreiexpand_morecontrasttranslate
tanreiexpand_more
Getting startedWebReactSwiftUIJetpack ComposeFlutterReact NativePresetsYour own design systemUsing Tanrei with AI agentsBrandDesign tokensDesign systems and customizationTheme StudioColorTypographyIconsShapeElevationMotionInteraction statesBehaviourLayoutAccessibilityWordsColor tokensTypescale tokensShape tokensElevation tokensMotion tokensState tokensSpace and measure tokensComponentsButtonMain action buttonSegmented buttonButton groupButton with menuToolbarCopy buttonCheckboxRadio buttonSwitchChipMenuSliderSlider fieldCalendarDateTimePickerField groupRadio groupCheckbox groupSelectSelect fieldMenubarFile uploadFile picker AdvancedDrop zoneText input AdvancedText fieldChip fieldFieldCombobox AdvancedCombobox fieldNumber input AdvancedNumber fieldColor input AdvancedColor fieldOne-time-code input AdvancedOne-time-code fieldEmbedded text input AdvancedChat composerCardDividerModal layer AdvancedDialogListList rowBottom sheetSide sheetCarouselCode blockTablePopoverStepsAccordionDescription listFigureApp shellPage headerTree viewTimelineImage previewHandleResizable frameScroll areaBadgeProgress indicatorMeterNumber tickerLoading indicatorSnackbarTooltipKeyboard shortcutTagInline codeCalloutAvatarEmpty stateTag groupSkeletonFile itemSwatchMarquee textTabsTab viewApp barNavigation barNavigation drawerSearchLinkPaginationPrevious and next linksStepperBreadcrumbsTable of contentsLink cardFAB menuStatusHow Tanrei is builtContributingLicense and attribution
HomeFoundationsAccessibility

Accessibility

The accessibility requirements Tanrei builds into tokens and component specs, and the checks that enforce them.

content_copyView as Markdown

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.

Contrast

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.

Enforced invariants

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;
  • outline is at least 3:1 against every surface role;
  • in the default system at medium and high contrast, outline-variant is at least 3:1 and 4.5:1 against every surface role, and outline stays stronger;
  • focus-ring is at least 3:1 against surfaces.

Project rules forbid loosening a threshold to make a check pass.

Target size

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.

Focus

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.

Keyboard

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.

Text scaling

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.

Reduced motion

When the system asks for reduced motion, spatial animation is removed or replaced by a brief fade and nothing loops. See Motion.

Semantics

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.

How it is tested

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.