---
version: alpha
name: Radix Accessible Primitives Interface
description: "A component-primitive design system for React product surfaces inspired by Radix Primitives, Radix Themes, and Radix Colors. It uses quiet neutral surfaces, a single indigo interaction accent, 12-step color-role mapping, explicit data-state styling, portal-aware overlays, low-to-medium radius, compact typography, and state matrices for dialogs, dropdowns, tabs, forms, popovers, and command-like workflows."

colors:
  primary: "#3e63dd"
  primary-hover: "#3358d4"
  on-primary: "#ffffff"
  canvas: "#fbfcfd"
  surface: "#ffffff"
  surface-card: "#ffffff"
  surface-soft: "#f8f9fa"
  surface-hover: "#f1f3f5"
  surface-selected: "#edf2fe"
  ink: "#1c2024"
  body: "#3b3f45"
  muted: "#60646c"
  subtle: "#8b9099"
  hairline: "#dfe3e6"
  hairline-strong: "#c1c8cd"
  focus: "#3e63dd"
  success: "#218358"
  success-surface: "#e6f6eb"
  warning: "#ad5700"
  warning-surface: "#fff7c2"
  danger: "#cd2b31"
  danger-surface: "#ffefef"
  inverse-canvas: "#111113"
  inverse-surface: "#18191b"
  inverse-ink: "#f9f9fb"

typography:
  display-xl:
    fontFamily: "Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif"
    fontSize: 52px
    fontWeight: 650
    lineHeight: 1.04
    letterSpacing: 0
  heading-lg:
    fontFamily: "Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif"
    fontSize: 30px
    fontWeight: 650
    lineHeight: 1.16
    letterSpacing: 0
  heading-md:
    fontFamily: "Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif"
    fontSize: 20px
    fontWeight: 650
    lineHeight: 1.25
    letterSpacing: 0
  heading-sm:
    fontFamily: "Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif"
    fontSize: 15px
    fontWeight: 650
    lineHeight: 1.35
    letterSpacing: 0
  body:
    fontFamily: "Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif"
    fontSize: 14px
    fontWeight: 420
    lineHeight: 1.5
    letterSpacing: 0
  body-sm:
    fontFamily: "Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif"
    fontSize: 12px
    fontWeight: 430
    lineHeight: 1.4
    letterSpacing: 0
  caption:
    fontFamily: "Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif"
    fontSize: 11px
    fontWeight: 700
    lineHeight: 1.32
    letterSpacing: 0
  mono:
    fontFamily: "JetBrains Mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace"
    fontSize: 12px
    fontWeight: 500
    lineHeight: 1.55
    letterSpacing: 0

rounded:
  none: 0px
  xs: 3px
  sm: 4px
  md: 6px
  lg: 10px
  xl: 14px
  pill: 9999px

spacing:
  base: 4px
  none: 0px
  xxs: 2px
  xs: 4px
  sm: 8px
  md: 12px
  lg: 16px
  xl: 24px
  xxl: 32px
  section: 72px

components:
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.body}"
    rounded: "{rounded.md}"
    padding: 9px 13px
  button-soft:
    backgroundColor: "{colors.surface-selected}"
    textColor: "{colors.primary}"
    typography: "{typography.body}"
    rounded: "{rounded.md}"
    padding: 9px 13px
  primitive-card:
    backgroundColor: "{colors.surface-card}"
    textColor: "{colors.body}"
    typography: "{typography.body}"
    rounded: "{rounded.lg}"
    padding: 16px
    borderColor: "{colors.hairline}"
  state-chip:
    backgroundColor: "{colors.surface-soft}"
    textColor: "{colors.muted}"
    typography: "{typography.caption}"
    rounded: "{rounded.sm}"
    padding: 3px 7px
  dialog-panel:
    backgroundColor: "{colors.surface-card}"
    textColor: "{colors.body}"
    typography: "{typography.body}"
    rounded: "{rounded.xl}"
    padding: 18px
    borderColor: "{colors.hairline}"
  menu-item:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.body}"
    typography: "{typography.body-sm}"
    rounded: "{rounded.sm}"
    padding: 7px 9px
  input-field:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink}"
    typography: "{typography.body}"
    rounded: "{rounded.md}"
    padding: 9px 10px
    borderColor: "{colors.hairline-strong}"

layout:
  shell: "A component-system workbench with a navigation rail, primitive preview surface, state matrix, and implementation notes."
  grid: "Use 4px micro spacing inside controls and 8/12/16/24px spacing between primitive groups. Desktop uses a 12-column grid; mobile stacks preview, contract, and state matrix."
  density: "Medium density. Components are compact enough for product software but leave room for focus rings, descriptions, validation, and touch targets."
  interaction: "Every interactive primitive needs visible data-state, keyboard state, disabled state, focus-visible outline, and portal/focus-management notes."

guidance:
  do:
    - "Choose the primitive from behavior first: dialog, alert dialog, popover, dropdown menu, select, tabs, accordion, tooltip, or checkbox."
    - "Style from data-state, data-disabled, data-highlighted, aria-expanded, aria-selected, and focus-visible."
    - "Map Radix Colors-style steps into semantic tokens before using them in components."
    - "Document portal, focus trap, escape key, arrow navigation, typeahead, and outside-click behavior."
    - "Use Theme-like controls for accent, gray, radius, scaling, and appearance, not one-off component props everywhere."
  dont:
    - "Do not treat Radix as a finished visual brand; primitives are behavior contracts."
    - "Do not remove labels, descriptions, focus guards, or portal behavior to simplify styling."
    - "Do not hardcode business copy or fixed dimensions into reusable primitives."
    - "Do not express selected, checked, disabled, error, or focus state through color alone."

caseStudy:
  source: "Radix Primitives, Radix Themes, Radix Colors, and Radix GitHub repositories"
  urls:
    - "https://www.radix-ui.com/primitives"
    - "https://www.radix-ui.com/primitives/docs/overview/introduction"
    - "https://www.radix-ui.com/themes/docs/theme/overview"
    - "https://www.radix-ui.com/themes/docs/theme/color"
    - "https://www.radix-ui.com/colors/docs/palette-composition/understanding-the-scale"
    - "https://www.radix-ui.com/themes/docs/theme/radius"
    - "https://github.com/radix-ui"
  analysis: "Radix Primitives describes itself as unstyled, accessible, open-source React primitives for design systems. Its introduction positions primitives as a low-level layer focused on accessibility, customization, and developer experience. Radix Themes shows a minimal configuration surface for accentColor, grayColor, panelBackground, scaling, and radius, with variants for hierarchy. Radix Colors assigns 12 palette steps to backgrounds, component states, borders, solid fills, and text. The reusable lesson is to separate behavior primitives from visual tokens: agents should pick a primitive by interaction contract, then map state attributes and color steps into the local Interface system."
---

# Radix Accessible Primitives Interface

Use this system for React product surfaces, internal tools, SaaS dashboards, settings panels, command interfaces, forms, overlays, and design-system documentation where the main risk is broken interaction rather than decorative styling.

The posture is primitive-first. The interface should feel precise, inspectable, and easy to implement. Visual polish comes after behavior contracts: focus, keyboard path, portal behavior, state attributes, labeling, validation, and token mapping.

## Overview

Radix Accessible Primitives is a design-system interface for building local components from behavior primitives. It does not prescribe a brand identity. It defines how a page should expose component structure, state, token roles, and implementation contracts so another agent can safely turn a design into React.

The first viewport should show a real component workbench: a primitive preview, state matrix, theme controls, and implementation notes. Avoid pure marketing composition. The value is knowing which primitive to use, what states it owns, and which tokens style each state.

## Colors

### Brand & Accent

Use indigo (`primary` #3e63dd) as the single interactive accent. It is allowed for primary buttons, links, focus-visible outlines, selected tabs, active segmented controls, and highlighted documentation callouts. It is not a generic decoration color.

### Surface

Use `canvas` (#fbfcfd) for the app background, `surface-card` (#ffffff) for panels, `surface-soft` (#f8f9fa) for grouped regions, `surface-hover` (#f1f3f5) for hovered items, and `surface-selected` (#edf2fe) for selected or soft accent backgrounds.

### Text

Use `ink` (#1c2024) for titles and important labels, `body` (#3b3f45) for reading, `muted` (#60646c) for helper text, and `subtle` (#8b9099) for metadata. Tiny component text must remain readable and never be used as the only status signal.

### Hairlines & Borders

Use `hairline` (#dfe3e6) for ordinary panel borders and separators. Use `hairline-strong` (#c1c8cd) for inputs and focus-adjacent boundaries. Focus rings use `focus` and should remain visible on both light and dark surfaces.

### Semantic

Map semantic states independently from the accent scale. Success, warning, and danger colors only describe actual status. Pair each semantic color with text, icon, aria state, or explicit label.

## Typography

### Font Family

Use Inter or system UI. This system is UI-dense and implementation-facing, so clarity matters more than personality. Mono is reserved for package names, data attributes, keyboard shortcuts, and token names.

### Hierarchy

Use 52px display only for documentation hero or major system pages. Product work surfaces use 30px page titles, 20px section headings, 15px card headings, 14px body text, and 12px metadata.

### Principles

Controls should use body or body-sm tokens, not display typography. State chips and data-attribute labels use caption or mono. Keep letter spacing at 0 so long token names and attribute names do not become harder to read.

### Note on Font Substitutes

System UI is acceptable. Preserve line height and font weights before chasing exact metrics. If using a mono font, ensure it does not widen compact chips enough to break toolbars.

## Layout

### Spacing System

Use a 4px base unit inside components. Most control padding uses 8px to 12px. Primitive groups use 16px to 24px. Page sections use 72px only in documentation pages; product screens stay denser.

### Grid & Container

Use a workbench grid: preview surface, state matrix, token panel, and implementation notes. Component demos should show adjacent states, not isolated pretty examples. Keep overlays and popovers near their triggers so collision and placement can be evaluated.

### Whitespace Philosophy

Whitespace should make behavior inspectable. Do not stretch the layout to feel premium. Use space to separate trigger, content, description, validation, and state metadata.

## Elevation & Depth

Most components are flat with hairline borders. Elevation is reserved for portal content: dropdown menus, popovers, dialogs, tooltips, hover cards, select content, and command results. Use small shadows only where stacking order matters.

Backdrop layers should be obvious enough for modal context but not heavy. Non-modal popovers need clear collision boundaries and focus visibility.

## Shapes

Use contextual radius. Buttons and inputs use 6px. Cards use 10px. Dialogs and popovers can use 14px. Full radius is reserved for avatar chips, small count pills, or intentionally pill-shaped theme settings. Do not make checkboxes circular or radios square; shape must preserve control meaning.

## Components

### Buttons

Primary buttons use solid indigo. Soft buttons use selected accent surfaces. Neutral buttons use surface-soft. Disabled buttons require opacity, cursor, aria-disabled/disabled, and non-color state.

### Cards & Containers

Primitive cards show the behavior contract: primitive name, package hint, required labels/descriptions, states, and token mapping. Cards should not nest other decorative cards. Use sections and dividers instead.

### Inputs & Forms

Inputs need visible labels, descriptions, error text, disabled state, and focus-visible outline. If using Select, Combobox, or Popover-based fields, document portal content, keyboard navigation, and screen-reader announcements.

### Navigation

Tabs, tab nav, accordion, and segmented controls must show selected state through `aria-selected`, `data-state`, and visual treatment. Do not use links, tabs, and buttons interchangeably; choose by navigation or action semantics.

### Signature Components

The signature components are the primitive matrix, data-state chips, portal stack preview, and token mapping table. These make the resource useful to implementation agents.

## Do's and Don'ts

Do:

- Select primitives by interaction contract before styling.
- Preserve focus management, labels, descriptions, portals, escape handling, and keyboard navigation.
- Style state through data attributes and ARIA state.
- Map 12-step color scales into semantic tokens.
- Include light, dark, disabled, selected, hovered, pressed, open, closed, checked, unchecked, invalid, loading, and reduced-motion states.

Don't:

- Do not copy a Radix demo and call it a design system.
- Do not remove invisible accessibility utilities just because they do not affect screenshots.
- Do not use hover-only affordances for essential inspection.
- Do not use accent color for success, warning, danger, or validation.
- Do not animate overlays in a way that breaks focus return or Escape behavior.

## Responsive Behavior

### Breakpoints

Below 720px, stack the workbench into preview, state matrix, and implementation notes. Keep the active primitive name and primary action visible. Move side navigation into a sheet only when the trigger has a clear accessible name.

### Touch Targets

Touch controls should be at least 40px tall. Compact 32px controls are acceptable in desktop dense toolbars when labels, focus, and hit areas remain clear.

### Collapsing Strategy

State matrices become horizontally scrollable tables or grouped cards. Dialog and popover demos should fit inside the viewport with safe max-height and internal scroll areas. Menus should not overflow off-screen.

### Image Behavior

Use screenshots only to show component states or documentation examples. Prefer live primitive previews, token tables, and state chips over decorative imagery.

## Iteration Guide

1. Name the primitive and interaction contract before drawing.
2. List required states, ARIA attributes, data attributes, keyboard path, and portal behavior.
3. Map theme controls: accent, gray, radius, scaling, panel background, and appearance.
4. Style the primitive from semantic tokens and data attributes.
5. Add examples for open/closed, hover, selected, disabled, error, loading, and reduced-motion states.
6. Verify keyboard navigation, focus return, screen-reader naming, mobile collision, and dark mode.

## Known Gaps

- This resource abstracts public Radix documentation and does not bundle Radix packages or exact component source.
- Exact Radix Themes internal CSS variable values can change; use official packages when building Radix-based applications.
- Radix Primitives are React-oriented; other frameworks need equivalent headless primitives or custom implementations.
- Licensing is MIT for the referenced Radix open-source repositories, but product teams must still check dependency versions and notices before shipping.
