Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelogApp ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbarAnchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree ViewAccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual ListActivity HeatmapAnimated NumberBadgeBar ListChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveformBlockquoteCode BlockCode GroupGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriterButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerField ListFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree SelectAlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip
ARC UIARC Radiant Components
v4.9DocsComponentsTokensSynthesizer
Getting StartedFrameworksServer RenderingDesign TokensThemingTheme SynthesizerTypographyUtilitiesAll ComponentsAccessibilityBrowser SupportChangelogContributingStatsApp ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbarAnchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree ViewAccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual ListActivity HeatmapAnimated NumberBadgeBar ListChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveformBlockquoteCode BlockCode GroupGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriterButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerField ListFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree SelectAlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip

Accessibility

ARC UI targets WCAG 2.1 Level AA. Components ship with semantic HTML, keyboard support, and ARIA attributes built in. This site is the test bed.

Automated Audit

Claims are cheap, so we audit. Every component documentation page, live demos included, is checked with axe-coreagainst the fully rendered DOM, shadow roots included, in both themes. CI fails on any serious or critical violation, color contrast included. No exclusions.

187Pages audited
2Themes audited (dark + light)
0Violations, any severity

Last audit: 2026-09-30 · axe-core 4.13.0 · run it yourself withpnpm audit:a11y

ARIA Attributes

Roles are set automatically: arc-dialog is a role="dialog"managing aria-modal; arc-tabs wires uptablist/tab/tabpanel. Anything extra passes through from the host element:

Keyboard Navigation

Every interactive component is fully keyboard-driven. Don't take our word for it. This one is live. Tab to it and drive it from the keyboard:

Arrow Left and Arrow Right move between tabs; the panel follows focus.
ComponentKeysAction
ButtonEnter / SpaceActivate
ModalEscapeClose
TabsArrow Left/Right, Home / EndSwitch tab
AccordionEnter / SpaceToggle panel
SelectArrow Up/DownNavigate options
SelectEnterSelect option
SelectEscapeClose dropdown
ToggleSpaceToggle on/off
CheckboxSpaceToggle checked
DrawerEscapeClose
TooltipEscapeDismiss

Focus Management

ARC UI ships two focus indicator styles as design tokens. Tab through these to compare them:

Focus shows only on keyboard navigation (:focus-visible), never on mouse clicks. Click the cards above and nothing appears. Overlays like arc-dialogand arc-drawer trap focus while open.

Screen Readers

Shadow DOM can complicate screen reader access; ARC UI's patterns avoid the traps:

  • Slotted content stays in the light DOM, where screen readers reach it directly.
  • ARIA attributes set on the host element are reflected into the shadow root where needed.
  • Form elements take a label attribute, so they are always announced.

Color & Contrast

The audit above measures actual rendered ratios in both themes. These are results, not targets:

  • --text-primary on --bg-deep exceeds 15:1.
  • --text-muted and --text-ghost meet the 4.5:1 ratio for normal text in both themes.
  • The feedback colors (--color-success, --color-warning,--color-error, --color-info) pass in both dark and light modes.
When customizing themes, verify that your color overrides maintain sufficient contrast ratios. Use the Theme Synthesizer to preview and test your custom themes for accessibility.

Reduced Motion

With prefers-reduced-motion set, every transition and animation collapses. Functionality is unchanged; only the motion goes:

The same rule reaches your own components if they adopt tokenStyles, and it has one consequence worth designing for. A collapsed animation runs once, at once, and then the element shows its un-animated styles. Whatever the base styles say is what a reduced-motion user sees. So put the resting state there, and let the keyframes move away from it. A two-frame sprite that swaps layers by opacity shows both frames stacked if both are visible by default. Hide the second frame in the base styles, and the keyframes that reveal it never get time to:

Without JavaScript

Web Components need JavaScript to upgrade. Until that happens (a failed script, a slow network, JS disabled), a custom element is an unknown tag rendering only its light DOM. What you put inside the element is what everyone sees first.

This matters most for links. An href on the custom element itselfcannot produce a working link without JavaScript: the attribute sits on the element, and the real <a> only exists in a shadow root that is never created. Slot a real anchor instead and the link is ordinary HTML from the first byte:

On upgrade the component adopts that anchor as its control rather than rendering a second one, so there is only ever one link in the accessibility tree. Thehref form stays fully supported. Prefer it inside app shells where JavaScript is guaranteed, and the slotted form on anything public, indexed, or first-load critical. This applies to arc-button,arc-icon-button, arc-link, arc-card,arc-nav-item, arc-breadcrumb-item, andarc-sidebar-link.

The stylesheet hides components only until they upgrade, and that hide is gated on scripting being available, so with JS disabled your content stays visible rather than being hidden forever waiting for an upgrade that never comes:

Components whose content comes from properties rather than slots, such asarc-feature-card (which renders from heading anddescription), have no light DOM to fall back to and stay blank without JavaScript. Author their content as slotted markup, treat them as enhancement-only, or server-render them.

See Also