Opus design system
Foundation and components — 19 primitives
Overview
Every component at a glance — select one to jump to its section.
design.md
Raw markdown documentation for the whole system.
# Opus Design System The Opus design system is a white-label UI foundation for the manager dashboard. It is built from a small set of theme drivers, semantic tokens, and reusable React primitives. The source of truth is src/app/globals.css. ## Goals - Keep product UI calm, mostly white, and content-first. - Support tenant theming from a brand color and a canvas color. - Use semantic tokens in components instead of raw hex, Tailwind grays, or one-off CSS. - Keep status colors stable so meaning survives white-label branding. - Make primitives feel consistent across dashboard, builder, docs, and training flows. ## Token Layers 1. Theme drivers — runtime values derived from the two tenant inputs (brand + canvas). 2. Foundation tokens — low-level colors, alpha, radius, shadows, type, status ramps. 3. Semantic tokens — product-facing roles consumed by components. Components should only touch layer 3. Layers 1 and 2 exist for the theme engine. ## Theme Drivers Defaults below are Opus brand #1D82FF on canvas #F9F8F6. --hue: 85 /* neutral surface + text hue (from canvas) */ --c-bg: 0.003 /* neutral surface chroma / tint */ --c-tx: 0.008 /* text + icon chroma tuning constant */ --bg-l: 0.979 /* canvas lightness — anchors the off-white background */ --contrast: 0.84 /* separation between surface / border / text steps */ --brand-h: 257 /* brand hue */ --brand-c: 0.195 /* brand chroma (0 = neutral dark primary) */ --brand-l: 0.62 /* brand lightness */ ## Neutral Ramp (OKLCH) The neutral scale is an OKLCH grayscale tinted by the canvas hue — not a fixed Tailwind gray. Surface steps stay near white and tint with the tenant; text steps use the text chroma constant. --color-gray-0: oklch(1 0 0) /* pure white */ --color-gray-25: oklch(0.992 var(--c-bg) var(--hue)) --color-gray-50: oklch(var(--bg-l) var(--c-bg) var(--hue)) /* canvas */ --color-gray-100: oklch(calc(1 - 0.035 * var(--contrast)) var(--c-bg) var(--hue)) --color-gray-200: oklch(calc(1 - 0.055 * var(--contrast)) var(--c-bg) var(--hue)) --color-gray-300: oklch(calc(1 - 0.09 * var(--contrast)) var(--c-bg) var(--hue)) --color-gray-400: oklch(0.72 var(--c-tx) var(--hue)) --color-gray-500: oklch(0.58 var(--c-tx) var(--hue)) --color-gray-600: oklch(0.45 var(--c-tx) var(--hue)) --color-gray-700: oklch(0.36 var(--c-tx) var(--hue)) --color-gray-800: oklch(0.29 var(--c-tx) var(--hue)) --color-gray-900: oklch(0.22 var(--c-tx) var(--hue)) --color-gray-950: oklch(0.16 var(--c-tx) var(--hue)) ## Alpha Ramp Adaptive overlays for borders, states, and scrims. --color-alpha-dark-2: oklch(0 0 0 / 0.02) --color-alpha-dark-4: oklch(0 0 0 / 0.04) --color-alpha-dark-6: oklch(0 0 0 / 0.06) --color-alpha-dark-8: oklch(0 0 0 / 0.08) --color-alpha-dark-12: oklch(0 0 0 / 0.12) --color-alpha-dark-16: oklch(0 0 0 / 0.16) --color-alpha-light-4: oklch(1 0 0 / 0.04) --color-alpha-light-8: oklch(1 0 0 / 0.08) --color-alpha-light-12: oklch(1 0 0 / 0.12) --color-alpha-light-16: oklch(1 0 0 / 0.16) ## Brand --color-brand-primary: oklch(var(--brand-l) var(--brand-c) var(--brand-h)) --color-brand-hover: oklch(calc(var(--brand-l) - 0.05) var(--brand-c) var(--brand-h)) --color-brand-active: oklch(calc(var(--brand-l) - 0.09) var(--brand-c) var(--brand-h)) --color-brand-bg: oklch(var(--brand-l) var(--brand-c) var(--brand-h) / 0.10) --color-brand-border: oklch(var(--brand-l) var(--brand-c) var(--brand-h) / 0.38) --color-brand-text: oklch(calc(var(--brand-l) - 0.12) var(--brand-c) var(--brand-h)) ## Semantic Colors Backgrounds: bg-bg-canvas -> --color-gray-50 /* lowest app background */ bg-bg-primary -> --color-gray-0 /* primary white surface */ bg-bg-subtle -> --color-gray-25 /* almost-white subtle background */ bg-bg-secondary -> --color-gray-100 /* grouped secondary surface */ bg-bg-tertiary -> --color-gray-200 /* recessed / inset surface */ bg-bg-elevated -> --color-gray-0 /* floating UI */ Text: text-text-primary -> --color-gray-950 text-text-secondary -> --color-gray-600 text-text-tertiary -> --color-gray-500 text-text-disabled -> --color-gray-400 text-text-inverse -> --color-gray-0 Icons: text-icon-primary -> --color-gray-800 text-icon-secondary -> oklch(0.50 var(--c-tx) var(--hue)) text-icon-tertiary -> oklch(0.64 var(--c-tx) var(--hue)) text-icon-disabled -> oklch(0.76 var(--c-tx) var(--hue)) Borders + states: border-border-primary -> --color-alpha-dark-8 border-border-secondary -> --color-alpha-dark-12 border-border-tertiary -> --color-alpha-dark-16 bg-state-hover -> --color-alpha-dark-4 bg-state-pressed -> --color-alpha-dark-8 bg-state-selected -> --color-brand-bg ring-state-focus -> --color-brand-primary overlay scrim -> oklch(0 0 0 / 0.46) Accent: accent-primary -> --color-brand-primary accent-primary-hover -> --color-brand-hover accent-primary-active -> --color-brand-active accent-primary-foreground -> --color-gray-0 action-secondary -> --color-alpha-dark-4 action-secondary-hover -> --color-alpha-dark-8 action-secondary-active -> --color-alpha-dark-12 action-secondary-foreground -> --color-text-primary action-destructive -> --color-status-error-bg action-destructive-hover -> error bg mixed 10% toward error text action-destructive-active -> error bg mixed 16% toward error text action-destructive-foreground -> --color-status-error-text ## Status Colors (fixed, not brand-derived) success bg green-2 text green-11 border green-5 warning bg yellow-2 text yellow-11 border yellow-5 error bg red-2 text red-11 border red-5 info bg teal-2 text teal-11 border teal-5 remediation bg orange-3 text orange-11 border orange-6 ai bg ai-1/10 text ai-1 border ai-1/28 Status is always paired with an icon + label so it survives a red brand. ## Typography Families: --font-sans Inter Variable /* product UI + display */ --font-mono Geist Mono /* code, token names, kbd */ Size tokens (name -> rem / px / line-height): micro 0.6875rem 11px 1.35 mini 0.75rem 12px 1.35 small 0.875rem 14px 1.4 regular 1rem 16px 1.45 /* body default */ large 1.125rem 18px 1.4 title3 1.25rem 20px 1.3 title2 1.5rem 24px 1.25 title1 2.25rem 36px 1.1 Weights: light 300 normal 450 medium 500 semibold 600 bold 700 Composite utilities: title-display opsz 32, 20px, weight 500, -0.015em title-display-bold opsz 32, 24px, weight 700, -0.02em screen-body opsz 32, 18px, weight 450, -0.01em ## Radius --radius: 0.5rem /* 8px base */ --radius-control: 0.625rem /* 10px — compact controls */ rounded-sm -> base - 4px /* 4px */ rounded-md -> base - 2px /* 6px */ rounded-lg -> base /* 8px */ rounded-xl -> base + 4px /* 12px */ rounded-2xl -> base * 1.8 /* ~14px */ rounded-3xl -> base * 2.2 rounded-4xl -> base * 2.6 rounded-full -> 9999px /* pills, tabs, buttons */ ## Elevation Base family (pure shadow): --shadow-bas-sm: 0 4px 12px rgba(25,25,25,.027), 0 1px 2px rgba(25,25,25,.02) --shadow-bas-md: 0 8px 12px rgba(25,25,25,.027), 0 2px 6px rgba(25,25,25,.027) --shadow-bas-lg: 0 20px 24px rgba(25,25,25,.05), 0 5px 8px rgba(25,25,25,.027) --shadow-bas-dif: 0 12px 32px rgba(25,25,25,.027) --shadow-bas-scr: 0 24px 48px rgba(25,25,25,.24), 0 4px 12px rgba(25,25,25,.14) Outlined family (shadow + 1px hairline ring): --shadow-out-sm: 0 2px 4px rgba(0,0,0,.04), 0 0 0 0.5px rgba(42,28,0,.07) --shadow-out-md: 0 8px 12px rgba(25,25,25,.027), 0 0 0 0.5px rgba(42,28,0,.07) --shadow-out-lg: 0 20px 24px rgba(25,25,25,.05), 0 0 0 0.5px rgba(42,28,0,.07) --shadow-out-dif: 0 12px 32px rgba(25,25,25,.027), 0 0 0 0.5px rgba(42,28,0,.07) --shadow-out-scr: 0 24px 48px rgba(25,25,25,.24), 0 0 0 0.5px rgba(42,28,0,.07) Use the smallest shadow that communicates the layer. ## Motion Use motion only when it clarifies a change, never for decoration. Most interactions should feel instant: a duration of `0ms` is often the snappiest and best choice, and the call is context-dependent. When motion genuinely helps, such as revealing or moving an element, keep it short and physical with the easing `cubic-bezier(0.175, 0.885, 0.32, 1.1)`: roughly 150ms for state changes, 200ms for popovers and tooltips, and 300ms for overlays and modals. Avoid long, looping, or attention-grabbing animation, and honor `prefers-reduced-motion` by dropping nonessential motion. ## Components Avatar, Badge, Button, Card, Checkbox, Divider, Label, Progress, Select, Tabs, Text Field, Toggle, Tooltip. Button rule: primary/default buttons must include a visible text label. Do not use the primary/default variant for icon-only buttons; use secondary, outline, ghost, or destructive with an aria-label instead. ## Engineering Rules - Prefer semantic classes over raw CSS variables in component markup. - Do not hardcode hex values in product UI. - Do not use raw Tailwind neutral classes for product surfaces. - Keep shadcn compatibility tokens (--background, --card, etc.) as an adapter layer. - Status colors stay semantic and fixed across tenants. - Components should be reusable without tenant-specific branches.
Colors
Semantic color roles derived from brand and canvas drivers.
Engineer model
The theme starts from two tenant inputs: a brand color and a canvas color. Runtime code decomposes those into OKLCH drivers such as --hue, --c-bg, --bg-l, --contrast, and brand hue/chroma/lightness values.
The neutral scale is not a fixed Tailwind gray. It is an OKLCH grayscale tinted by the canvas hue, so white-label themes can feel warm, cool, or neutral without every component changing classes.
Components should consume semantic roles like bg-bg-secondary. Raw gray steps are foundation tokens used to derive those roles, not the normal product API.
Raw OKLCH gray ramp
gray-0
white
gray-25
near white
gray-50
canvas
gray-100
secondary
gray-200
tertiary
gray-300
soft
gray-400
disabled
gray-500
tertiary text
gray-600
secondary text
gray-700
strong
gray-800
icons
gray-900
darkest
gray-950
primary text
Raw OKLCH red ramp
Fixed crimson status scale at hue 17. Error semantics use red-2 for fill, red-5 for borders, and red-11 for readable text.
--color-red-1
softest
--color-red-2
error fill
--color-red-3
tint
--color-red-4
soft
--color-red-5
error border
--color-red-6
medium
--color-red-7
strong tint
--color-red-8
strong
--color-red-9
solid
--color-red-10
hover solid
--color-red-11
error text
--color-red-12
deep text
Raw OKLCH green ramp
Fixed success scale at hue 145. Success semantics use green-2 for fill, green-5 for borders, and green-11 for readable text.
--color-green-1
softest
--color-green-2
success fill
--color-green-3
tint
--color-green-4
soft
--color-green-5
success border
--color-green-6
medium
--color-green-7
strong tint
--color-green-8
strong
--color-green-9
solid
--color-green-10
hover solid
--color-green-11
success text
--color-green-12
deep text
Raw OKLCH yellow ramp
Fixed warning scale at hue 91. Warning semantics use yellow-2 for fill, yellow-5 for borders, and yellow-11 for readable text.
--color-yellow-1
softest
--color-yellow-2
warning fill
--color-yellow-3
tint
--color-yellow-4
soft
--color-yellow-5
warning border
--color-yellow-6
medium
--color-yellow-7
strong tint
--color-yellow-8
strong
--color-yellow-9
solid
--color-yellow-10
hover solid
--color-yellow-11
warning text
--color-yellow-12
deep text
Raw OKLCH orange ramp
Fixed auxiliary warm scale at hue 55 for orange accents and charts.
--color-orange-1
softest
--color-orange-2
fill
--color-orange-3
tint
--color-orange-4
soft
--color-orange-5
border
--color-orange-6
medium
--color-orange-7
strong tint
--color-orange-8
strong
--color-orange-9
solid
--color-orange-10
hover solid
--color-orange-11
text
--color-orange-12
deep text
Raw OKLCH purple ramp
Fixed purple scale at hue 295 for purple accents and charts.
--color-purple-1
softest
--color-purple-2
fill
--color-purple-3
tint
--color-purple-4
soft
--color-purple-5
border
--color-purple-6
medium
--color-purple-7
strong tint
--color-purple-8
strong
--color-purple-9
solid
--color-purple-10
hover solid
--color-purple-11
text
--color-purple-12
deep text
Raw OKLCH teal ramp
Fixed info scale at hue 180. Info semantics use teal-2 for fill, teal-5 for borders, and teal-11 for readable text.
--color-teal-1
softest
--color-teal-2
info fill
--color-teal-3
tint
--color-teal-4
soft
--color-teal-5
info border
--color-teal-6
medium
--color-teal-7
strong tint
--color-teal-8
strong
--color-teal-9
solid
--color-teal-10
hover solid
--color-teal-11
info text
--color-teal-12
deep text
Raw OKLCH AI ramp
Saturated AI identity colors. AI semantics use ai-1 as readable text, with translucent ai-1 fills and borders for surfaces.
--color-ai-1
ai text
--color-ai-2
violet
--color-ai-3
purple
--color-ai-4
magenta
--color-ai-5
hot pink
--color-ai-6
rose
--color-ai-7
coral
--color-ai-8
glow
Solid color comparison
Every chromatic family at its solid step (9), placed flush so the set can be judged together.
Alpha ramp
Adaptive overlay tokens for borders, interaction states, and scrims. Dark alpha is previewed on white; light alpha is previewed on dark.
alpha-dark-2
2% dark overlay
alpha-dark-4
4% dark overlay
alpha-dark-6
6% dark overlay
alpha-dark-8
8% dark overlay
alpha-dark-12
12% dark overlay
alpha-dark-16
16% dark overlay
alpha-light-4
4% light overlay
alpha-light-8
8% light overlay
alpha-light-12
12% light overlay
alpha-light-16
16% light overlay
Product semantic tokens
| background | ||
| bg-bg-canvas | Lowest app background | |
| bg-bg-primary | Primary white surface | |
| bg-bg-subtle | Almost-white subtle background surface | |
| bg-bg-secondary | Grouped secondary surface | |
| bg-bg-tertiary | Recessed or inset surface | |
| bg-bg-elevated | Floating surface | |
| text | ||
| text-text-primary | Default readable text | |
| text-text-secondary | Supporting body text | |
| text-text-tertiary | Metadata and helper text | |
| text-text-disabled | Disabled or unavailable text | |
| text-text-inverse | Text on dark or brand fills | |
| icon | ||
| text-icon-primary | Primary icons | |
| text-icon-secondary | Secondary icons | |
| text-icon-tertiary | Subtle icons | |
| text-icon-disabled | Disabled icons | |
| text-icon-inverse | Icons on dark or brand fills | |
| border and state | ||
| border-border-primary | Default hairline edge | |
| border-border-secondary | Stronger dividers and inputs | |
| border-border-tertiary | Highest contrast border | |
| bg-state-hover | Hover state fill | |
| bg-state-pressed | Pressed state fill | |
| bg-state-selected | Selected state fill | |
| ring-state-focus | Keyboard focus ring | |
| bg-overlay-scrim | Modal and overlay scrim | |
| accent | ||
| accent-primary | Tenant brand action color | |
| accent-primary-hover | Primary action hover | |
| accent-primary-active | Primary action pressed | |
| accent-primary-foreground | Text on primary actions | |
| action-secondary | Secondary action fill | |
| action-secondary-hover | Secondary action hover | |
| action-secondary-active | Secondary action pressed | |
| action-secondary-foreground | Text on secondary actions | |
| action-destructive | Destructive action fill | |
| action-destructive-hover | Destructive action hover | |
| action-destructive-active | Destructive action pressed | |
| action-destructive-foreground | Text on destructive actions | |
| status | ||
| bg-status-success-bg | Success background | |
| text-status-success-text | Success text | |
| border-status-success-border | Success border | |
| bg-status-success-solid | Success solid | |
| text-status-success-solid-foreground | Success solid foreground | |
| bg-status-warning-bg | Warning background | |
| text-status-warning-text | Warning text | |
| border-status-warning-border | Warning border | |
| bg-status-error-bg | Error background | |
| text-status-error-text | Error text | |
| border-status-error-border | Error border | |
| bg-status-info-bg | Info background | |
| text-status-info-text | Info text | |
| border-status-info-border | Info border | |
| bg-status-remediation-bg | Remediation background | |
| text-status-remediation-text | Remediation text | |
| border-status-remediation-border | Remediation border | |
| bg-status-ai-bg | AI background | |
| text-status-ai-text | AI text | |
| border-status-ai-border | AI border | |
Rules
Use semantic roles
Product UI should use bg-bg-*, text-text-*, text-icon-*, border-border-*, state, accent, and status tokens.
Avoid raw grays
The neutral ramp exists as a foundation. Components should not reach for raw gray steps unless documenting the system.
Status is fixed
Success, warning, error, info, and AI colors stay independent from tenant brand colors so meaning remains stable.
Surfaces
How background tokens stack to build layered layouts.
Surface stack
Surfaces are the background tokens arranged by depth. The warm canvas sits lowest as the app shell; white primary surfaces hold content; subtle, secondary, and tertiary surfaces create gentle hierarchy inside them; and elevated floats above for popovers and menus.
Roles
| bg-bg-canvas | Lowest app background — the dashboard shell. | |
| bg-bg-primary | Primary white surface for cards, panels, and content. | |
| bg-bg-subtle | Almost-white subtle background inside white surfaces. | |
| bg-bg-secondary | Grouped secondary surface for related blocks. | |
| bg-bg-tertiary | Recessed or inset surface such as wells. | |
| bg-bg-elevated | Floating UI: popovers, dropdowns, dialogs, sheets. |
Rules
Stack by depth
Use canvas for the shell, primary for content, and subtle/secondary/tertiary only when nested hierarchy is needed.
Elevated for floating
Reach for bg-bg-elevated on floating UI even when it matches primary in the light theme — the role may diverge in other themes.
Pair with elevation
Floating surfaces combine with the shadow scale (shadow-out-*) to read as lifted above the page.
Typography
Font families, named size tokens, weights, and composite title utilities.
Families
Inter Variable
Primary UI and display
var(--font-sans)
Geist Mono
Code, token names, keyboard hints
var(--font-mono)
Named Size Tokens
text-micro
11px · lh 1.35
0.6875rem
Micro labels
text-mini
12px · lh 1.35
0.75rem
Small metadata
text-small
14px · lh 1.4
0.875rem
Controls and labels
text-regular
16px · lh 1.45
1rem
Body default
text-large
18px · lh 1.4
1.125rem
Large body
text-title3
20px · lh 1.3
1.25rem
Section title
text-title2
24px · lh 1.25
1.5rem
Page title
text-title1
36px · lh 1.1
2.25rem
Hero title
Weight Tokens
light
300
normal
450
medium
500
semibold
600
bold
700
Composite Utilities
title-display · 20px / 500
Build training that scales
title-display-bold · 24px / 700
Manager dashboard
Title + Subtitle Pairings
Common label/metadata combinations. Title uses text-text-primary; subtitles step down in size and color for hierarchy.
Assign trainees
Choose who receives this module
16px / 14px · secondary
Manager dashboard
Updated 2 hours ago
14px / 13px · secondary
Forklift safety basics
6 screens · Draft
14px / 12px · tertiary
Completion rate
Last 30 days
14px / 11px · tertiary
Certificate issued
Sent to 12 trainees
13px / 13px · tertiary
Alex Brinza
Operations lead
13px / 12px · tertiary
Paragraphs
Body copy options for descriptions and helper text. Sorted largest to smallest; use text-text-secondary for readable body and text-text-tertiary for supporting detail.
16px · lh 1.45 · secondary · Regular body
About this training module
Assign this module to a trainee to begin tracking completion and check-ins. Managers can review progress, send reminders, and issue certificates once every screen is finished.
14px · lh 1.4 · secondary · Compact body
How completion tracking works
Assign this module to a trainee to begin tracking completion and check-ins. Managers can review progress, send reminders, and issue certificates once every screen is finished.
13px · lh 1.35 · tertiary · Helper text
When reminders are sent
Assign this module to a trainee to begin tracking completion and check-ins. Managers can review progress, send reminders, and issue certificates once every screen is finished.
12px · lh 1.35 · tertiary · Fine print
Certificate and completion policy
Assign this module to a trainee to begin tracking completion and check-ins. Managers can review progress, send reminders, and issue certificates once every screen is finished.
Rules
Atomic first
Compose typography from one family, one size token, and one weight token. Reach for title-display utilities only for product headings.
Body default
Body text uses text-regular with normal weight 450 and the app-wide letter spacing from globals.css.
Docs chrome
The documentation frame still uses only 14px, 13px, and 11px. Larger type appears here only as typography samples.
Radius
Corner scale for controls, cards, and large containers.
sm
4px
md
6px
control
10px
xl
12px
full
9999px
Use by role
Compact controls use radius-control, small inner affordances use sm/md, card-like containers use lg/xl, and pills/tabs/buttons use full.
Icons
Iconography used across the design system. Icons inherit currentColor and size from the component that owns them.
Rules
Color follows text
Use currentColor for strokes and fills. Component variants own the foreground token, so icons inherit status, action, and glass colors automatically.
Size follows component
Do not hardcode icon dimensions in call sites. Buttons, badges, tabs, and toolbar controls set icon sizes through their component styles.
Stroke style
System icons use a 1.5px rounded stroke. Custom SVGs should match that rhythm unless their source shape requires dots or filled details.
Status and badges
Lucide icons used inside Badge variants. Render at currentColor and inherit the badge foreground token.
Check
currentColor
Circle
currentColor
CircleAlert
currentColor
CircleCheck
currentColor
CircleDashed
currentColor
Clock
currentColor
FileCheck2
currentColor
FileX2
currentColor
Hourglass
currentColor
Info
currentColor
RefreshCcw
currentColor
Timer
currentColor
Actions and navigation
General action icons used by buttons, component cards, tabs, and navigation affordances.
ArrowUpRight
currentColor
LayoutGrid
currentColor
Layers
currentColor
MoreHorizontal
currentColor
Plus
currentColor
RectangleVertical
currentColor
Settings
currentColor
Product and custom
Local SVG components for branded or non-Lucide shapes. These must also use currentColor.
StackPerspectiveIcon
currentColor
ToolbarTrashIcon
currentColor
ToolbarLayersIcon
currentColor
ToolbarCheckIcon
currentColor
ToolbarPlusIcon
currentColor
Elevation
Shadow families for lift, panels, and modal-level surfaces.
Base — soft shadow, no ring
bas-sm
Subtle lift
bas-md
Card elevation
bas-lg
Raised panel
bas-dif
Diffuse float
bas-scr
Modal / scrim
Outlined — shadow + 1px hairline ring
out-sm
Outlined subtle
out-md
Outlined card
out-lg
Raised panel
out-dif
Outlined float
out-scr
Outlined modal
Motion
Timing and easing guidance for purposeful interface movement.
Principle
Use motion only when it clarifies a change, never for decoration. Most interactions should feel instant: a duration of 0ms is often the snappiest and best choice, and the call is context-dependent.
Easing
When motion genuinely helps, use cubic-bezier(0.175, 0.885, 0.32, 1.1) for short, physical movement.
150ms
Use for small state changes, such as pressed, selected, expanded, or inline feedback.
200ms
Use for popovers, tooltips, and lightweight reveal interactions.
300ms
Use for overlays and modal-level surfaces when the spatial change needs to be understood.
Reduced motion
Honor prefers-reduced-motion by dropping nonessential motion.
Avoid long, looping, or attention-grabbing animation.
Token Usage
How to choose the right foundation token family in product code.
Surface
bg-bg-primary, bg-bg-subtle, bg-bg-secondary, bg-bg-tertiary
Text
text-text-primary, text-text-secondary, text-text-tertiary
Icon
text-icon-primary, text-icon-secondary, text-icon-tertiary
Border
border-border-primary, ring-border-primary
State
hover:bg-state-hover, active:bg-state-pressed
Status
bg-status-success-bg, text-status-error-text
Avatar
User identity with fallbacks and grouping.
Badge
Compact status and metadata labels.
Demo badges
| Badge | Color | Tokens |
|---|---|---|
| Completed | Green | bg-status-success-bgtext-status-success-texttype: text-small / normal |
| Completed solid | Green | bg-status-success-solidtext-status-success-solid-foregroundtype: text-small / normal |
| Pass | Green | bg-status-success-bgtext-status-success-texttype: text-small / normal |
| Past due | Yellow | bg-status-warning-bgtext-status-warning-texttype: text-small / normal |
| Missed | Yellow | bg-status-warning-bgtext-status-warning-texttype: text-small / normal |
| Fail | Red | bg-status-error-bgtext-status-error-texttype: text-small / normal |
| In remediation | Orange | bg-status-remediation-bgtext-status-remediation-texttype: text-small / normal |
| Upcoming | Gray | bg-bg-secondarytext-text-secondarytype: text-small / normal |
| Not started | Gray | bg-bg-secondarytext-text-secondarytype: text-small / normal |
| In progress | AI | bg-status-ai-bgtext-status-ai-texttype: text-small / normal |
| Ready for review | Brand | bg-brand-bgtext-brand-texttype: text-small / normal |
Collection Card
A board / collection tile: a fanned stack of cover images over a title and count. Hover to open the stack — back covers fan out and the front cover lifts.
Ghost
Filled (gray surface)
Small
Row · framed covers
Row · subtle surface
Gooey Loader
An indeterminate loader of two circles rotating horizontally around a shared axis. The circle turning to the front swells as it eclipses the other; an SVG metaball filter melts them where they cross. Color follows currentColor.
Default
Small
AI thinking
Success
Thinking → done
Card
Elevated white surface for grouped content.
Checkbox
Binary selection with an associated label.
Divider
Hairline separator between content groups.
Label
Field caption tied to an input control.
Progress
Linear completion indicator.
Select
Single-choice menu from a list of options.
Tabs
Switch between related panels of content.
Text labels
Icon only
Canvas view switcher
Text Field
Single-line text input with states.
Toggle
Two-state button for inline options.
Tooltip
Contextual hint shown on hover or focus.
Glass Surface
A reusable glass material primitive backed by CSS tokens and the glass-surface utility. Use it for controls, overlays and toolbars that float above busy content.
Glass Surface
Token-backed material using --glass-surface-* and the shared glass-surface utility.
Glass Surface
Same material on a light canvas — useful for toolbars and controls that float above white panels.
Glass Popover
A rich, hover-triggered popover — a tooltip with a body. Defaults to a light translucent surface, with an optional shared glass-surface material for darker overlay moments.



