Accessibility
Accessibility is a build requirement here, not an afterthought. Every installable component, block, and page is verified to meet WCAG 2.2 AA — and a catalog-wide automated sweep keeps it that way. When you copy an item into your app, you inherit that baseline.
346
components verified
431
blocks verified
65
pages verified
What's guaranteed
Every preview is scanned with axe-core and asserted to have zero critical or serious violations, across the full matrix of:
- Light and dark colour schemes.
- The customer and admin brand surfaces.
- Both desktop and mobile viewports (for layout / overflow).
That covers contrast, ARIA roles/attributes/names, label associations, keyboard focusability, nested-interactive controls, list/landmark structure, and more. Nothing is exempt except a short, documented list of genuinely decorative cases (e.g. a faint brand watermark, or the contrast-checker demo whose whole point is to show failing swatches).
Colour & contrast
Components never ship raw colour utilities or inline hsl() — they use
semantic tokens (bg-primary, text-muted-foreground,
border-input, …). The token palette is tuned so text and accents meet 4.5:1 in
both light and dark, both as text on a surface and as a fill with its foreground. If you
re-theme, keep that contrast: the theme tools
include a live WCAG checker.
Keyboard & focus
Interactive elements are reachable and operable by keyboard, expose a visible
focus-visible ring built from the ring token, and carry correct roles
and accessible names. Scrollable regions are focusable so keyboard users can scroll them;
collapsed panels are inert so hidden controls leave the tab order.
Motion
Animation respects prefers-reduced-motion. Decorative and looping motion is gated
with motion-safe: / motion-reduce: (and the equivalent
@media (prefers-reduced-motion) guard inside component <style>
blocks), so users who ask for less motion get a still, readable interface.
RTL & semantics
Every primitive uses logical properties (ms-*, text-start,
inset-inline-*) so it mirrors correctly under dir="rtl", and exposes a
stable data-slot attribute for styling and scripting hooks. See the
RTL guide.
Performance
The handful of WebGL components that need it (blob, mesh-gradient)
load three.js lazily via a
dynamic import('three'), so it's split into its own chunk — pages that don't use one
never pay the ~600 KB cost. Canvas effects like globe use the 2D canvas API
and ship no extra library.
How it's verified
Two self-maintaining browser sweeps walk every component, block, and page preview: an axe-core accessibility sweep (the matrix above) and a render-health sweep (no blank renders, no horizontal overflow). They run in CI and can be run locally:
cd apps/docs-registry && npm run test:a11y
The hand-written guard suite adds per-component checks — token usage, RTL mirroring, and interactive a11y — so regressions fail loudly at build time too.
Keeping it accessible in your app
The generated code is accessible out of the box — to keep it that way:
- Pass a real label where a component asks for one (icon-only buttons, inputs, charts, maps).
- Keep the semantic tokens; if you change them, re-check contrast in light and dark.
- Don't remove
aria-*, roles, orfocus-visiblestyles when restyling. - Provide meaningful
alttext for your own images and an accessible name for your own controls.