DESIGN
This is a community-generated DESIGN.md derived from Radix Themes' public documentation. It is not an official document published by WorkOS or the Radix team.
colors: accent: indigo accent-solid: "#3E63DD" accent-solid-hover: "#3358D4" accent-text: "#3451B2" accent-subtle: "#EEF2FF" accent-surface: "#F5F8FF" accent-contrast: "#FFFFFF" gray: slate background: "#FFFFFF" panel-solid: "#FFFFFF" panel-translucent: "rgba(255,255,255,0.85)" surface: "#FFFFFF" overlay: "rgba(0,0,0,0.5)"
typography: font-family: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-family-heading: inherit font-family-code: "'Menlo', 'Consolas', monospace" font-family-em: "'Times New Roman', Times, serif" scale: 1: { size: "12px", line-height: "16px", letter-spacing: "0.0025em" } 2: { size: "14px", line-height: "20px", letter-spacing: "0em" } 3: { size: "16px", line-height: "24px", letter-spacing: "0em" } 4: { size: "18px", line-height: "26px", letter-spacing: "-0.0025em" } 5: { size: "20px", line-height: "28px", letter-spacing: "-0.005em" } 6: { size: "24px", line-height: "30px", letter-spacing: "-0.00625em" } 7: { size: "28px", line-height: "36px", letter-spacing: "-0.0075em" } 8: { size: "35px", line-height: "40px", letter-spacing: "-0.01em" } 9: { size: "60px", line-height: "60px", letter-spacing: "-0.025em" } weights: light: 300 regular: 400 medium: 500 bold: 700
spacing: 1: "4px" 2: "8px" 3: "12px" 4: "16px" 5: "24px" 6: "32px" 7: "40px" 8: "48px" 9: "64px"
radius: theme-default: medium none: "0px" small: "~2–4px contextual" medium: "~4–8px contextual" large: "~8–16px contextual" full: "9999px (pill)" tokens: radius-1: "var(--radius-1)" radius-2: "var(--radius-2)" radius-3: "var(--radius-3)" radius-4: "var(--radius-4)" radius-5: "var(--radius-5)" radius-6: "var(--radius-6)"
components: button-solid: background: "var(--accent-9)" color: "var(--accent-contrast)" border-radius: "var(--radius-2)" button-soft: background: "var(--accent-3)" color: "var(--accent-11)" border-radius: "var(--radius-2)" button-ghost: background: "transparent" color: "var(--accent-11)" border-radius: "var(--radius-2)" button-surface: background: "var(--color-surface)" color: "var(--accent-11)" border: "1px solid var(--accent-7)" border-radius: "var(--radius-2)" button-outline: background: "transparent" color: "var(--accent-11)" border: "1px solid var(--accent-8)" border-radius: "var(--radius-2)"
Overview
Radix Themes is a pre-styled React component library built on Radix Primitives. The visual language is config-first: the entire theme is derived from a small set of props on the <Theme> component rather than manually specified tokens. All values are CSS custom properties scoped to .radix-themes, making them accessible for custom component styling.
The default theme uses Indigo as the accent with Slate as the gray — a clean, neutral palette suited to productivity applications, dashboards, and developer tools. The system font stack is used by default (no custom font loading required).
Colors
Two-axis color model: accent color × gray color. Setting accentColor and grayColor on the <Theme> component drives the full palette.
Each color is a 12-step scale with documented step semantics:
- Steps 1–2: Page and component backgrounds
- Steps 3–5: Interactive backgrounds (hover, active states)
- Steps 6–8: Borders and separators
- Steps 9–10: Solid fills — the primary brand steps (buttons, badges)
- Steps 11–12: Accessible text
--accent-contrast: foreground for text on step-9 backgrounds
Every step has an alpha variant (e.g. --indigo-a9) for use over non-white surfaces. Alpha colors are used automatically within Radix Themes components.
Semantic surface tokens:
--color-background: page background--color-panel-solid/--color-panel-translucent: card and popup surfaces--color-surface: form component backgrounds--color-overlay: dialog/modal overlays
Focus colors: --focus-1 through --focus-12 — automatically matched to the component's active accent. Most components use --focus-8 for focus outlines.
Dark mode: appearance="dark" on <Theme> — all Radix Colors scales include dark values; no separate stylesheet needed.
Typography
9-step size scale from 12px to 60px. Each step pairs a font size with coordinated line height and letter spacing. Larger sizes use negative letter-spacing to compensate for optical spread at display scale.
Default font families by role:
- Text: OS system font stack (no loading latency)
- Code:
'Menlo', 'Consolas'monospace stack - Em / Quote:
'Times New Roman', serif
Custom fonts are applied by overriding --default-font-family and role-specific variables (--heading-font-family, --code-font-family, --strong-font-family, --em-font-family, --quote-font-family) via CSS after the Radix stylesheet.
For next/font integration: use the variable option to define a CSS variable, then map it to --default-font-family in CSS.
Font weights are customizable via CSS: --font-weight-light, --font-weight-regular, --font-weight-medium, --font-weight-bold.
Advanced heading tokens available: --heading-font-size-adjust, --heading-leading-trim-start, --heading-leading-trim-end, --heading-letter-spacing.
Layout
9-step spacing scale from 4px to 64px on a 4px base grid. Applied via layout component props (m, p, gap) rather than CSS classes. All layout components (Box, Flex, Grid, Container, Section) accept responsive breakpoint values on all props.
Breakpoints: initial (mobile-first), xs, sm, md, lg, xl.
The scaling prop ("90%" to "110%") applies a global multiplier to spacing, font size, and line height — the primary mechanism for UI density control. Custom components can participate via calc(Npx * var(--scaling)).
Elevation & Depth
Panels use --color-panel-translucent by default for subtle surface hierarchy without explicit shadows. Shadow tokens (--shadow-1 through --shadow-6) are available for custom elevation. Dialog overlays use --color-overlay.
Shapes
Radius configured globally via the radius prop on <Theme>: none, small, medium (default), large, full. All components derive their corner radius from --radius-1 through --radius-6 CSS variables, which are recalculated when the prop changes. The resulting radius is contextual per component — full makes buttons pill-shaped but leaves checkboxes with moderate rounding.
--radius-factor, --radius-full, and --radius-thumb are also available for custom component use.
Many components expose a per-instance radius prop for local overrides; panel components (Card, Dialog, Popover) inherit from the theme only.
Components
All Radix Themes components share a consistent variant vocabulary:
classic— most prominent, elevated treatmentsolid— solid accent fill, high emphasis (use--accent-9/--accent-contrast)soft— tinted background (accent-3), medium emphasissurface— white/panel background with borderoutline— transparent with borderghost— no background or border, lowest emphasis
This system enables a consistent hierarchy across all component types using a single variant prop.
Do's and Don'ts
Do:
- Use
<Theme>props as the primary configuration surface — avoid per-component overrides when a theme prop achieves the same result - Use
--accent-9for solid brand fills and--accent-contrastfor text on those fills - Use
--accent-11/--accent-12for accessible text colors — not step 9 - Use the
highContrastprop for emphasis rather than manually picking darker token steps - Apply custom styles after
@radix-ui/themes/styles.cssso overrides take precedence - Use CSS variable overrides for custom colors so dark mode and scaling remain consistent
- Use
var(--space-N)tokens andvar(--radius-N)tokens in custom components so they respond to theme scaling and radius settings
Don't:
- Don't hardcode hex values in component styles — always reference CSS variables so the theme system stays coherent
- Don't use
--accent-9for text — it is designed for solid fills, not legibility - Don't use
ThemePanelin production - Don't skip the CSS import — without
@radix-ui/themes/styles.css, no styles apply - Don't override spacing or radius with hardcoded values in custom components when CSS variable tokens are available