Accessibility
Accessibility overrides exact visual imitation whenever the two conflict. This is a stated design principle, not an afterthought.
Baseline, built into components
- Semantic HTML first. Use real
button,nav,table,labelelements before ARIA - Every interactive element is keyboard-operable and shows a visible focus ring (
:focus-visible) - Icon-only controls (IconButton, close buttons) require an explicit
aria-labelat the type level - Overlays (Dialog, Drawer, AlertDialog, Menu) trap and restore focus and close on Escape via Base UI
FormFieldwiresaria-describedbyanddata-invalidautomatically between label, description, error, and control- Color never carries meaning alone. Status uses icon + label + color together (see
StatusIndicator) - Active navigation items carry
aria-current="page", and Navbar, BottomNavigation and Sidebar name their landmarks, so a page with several does not announce identical "navigation" entries - Sortable DataTable headers expose
aria-sortand say the sort direction in their name, and a loading table body isaria-busy - A chart is a single tab stop with arrow-key navigation between points and series, and every chart renders a visually hidden table of its real values
- Calendar days are named with the full date, and today carries
aria-current="date"and a dot as well as a color
Reduced motion & transparency
prefers-reduced-motion: reduce zeroes every Fuji UI transition duration globally. No per-component opt-out is needed. prefers-reduced-transparency: reduce flattens the glass material to opaque surfaces (see Theming).
Contrast
Text tokens (foreground, foreground-muted, foreground-subtle) are tuned per theme to meet WCAG AA (4.5:1) against their paired surface. Glass follows the active theme's text colors, dark on light glass and light on dark glass, and its surface tints are set so card text stays above AA rather than the low-contrast text common in glassmorphism references.
How this is verified
Everything above is a claim, so here is what stands behind it - including where the coverage stops. These numbers were measured against v0.5.0 and are stated rather than rounded up.
- Automated axe checks. 25 of the 86 components assert
jest-axehas no violations, on top of their behavioural tests. Those are the components where ARIA carries the meaning - overlays, form controls, composite widgets. The remainder are covered by behavioural tests but not yet by an axe assertion. - Cross-component contracts. A separate suite asserts the rules that apply across families rather than to one component: state that is only a color is not state, one landmark per role needs a name, a chart is a single tab stop. A rule enforced in eight separate files drifts; this one is enforced in a list that is harder to forget.
- Keyboard and focus. Interaction tests drive components through
user-eventrather than synthetic events, so tab order, arrow-key navigation, Escape handling, and focus restoration are exercised as a person would. - Rendered-page sweeps. Every Storybook story is loaded in a real browser under three appearances and checked for things a unit test cannot see: the resolved appearance attributes, a page background that disagrees with its surfaces, horizontal overflow, zero-size text boxes, and browser default styles leaking through where the package ships no CSS reset.
- Contrast. Token pairings are measured against their surfaces, including every stop of the glass atmosphere, and the measurements are recorded beside the token values.
What is not verified
- No full screen-reader pass with VoiceOver, NVDA, or JAWS
- No axe assertion on the 61 components listed above as behaviour-tested only
- Not every route, browser, and appearance combination in every pairing
- RTL beyond layout: directional icon affordances are still unmirrored, as noted in the section above
An accessibility problem in a shipped component is a bug like any other. Report one on GitHub.
RTL
Layout uses logical Tailwind utilities where direction matters (flex and grid gap rather than hardcoded left/right margins in most places), so most components adapt to a dir="rtl" ancestor without extra work. Directional icon affordances such as Breadcrumb and Carousel chevrons currently render left-to-right and are not yet mirrored under RTL.
