Marigold
v18.0.0-beta.4
Marigold
v18.0.0-beta.4
Component Principles
Accessibilityupdated
Token Overviewnew
Typographyalpha
Elevationupdated
Layoutsupdated
Responsive Designnew
Iconographynew
Form Fields
Spacingalpha
Foundations

Token Overview

The complete reference for the Marigold design token system

Design tokens are the bridge between design decisions and code. They capture color, spacing, elevation, and motion as named variables so that every component speaks the same visual language. Names describe purpose, not appearance, so a token stays correct even when its value changes.

How token names work

Tokens are used as Tailwind CSS utility classes. A class name has up to three parts:

border-destructive-accent
|       |          |
|       role       emphasis
property
  • Property: the Tailwind prefix that determines the CSS property: bg-, text-, border-, shadow-
  • Role: the semantic purpose: primary, disabled, surface, hover
  • Emphasis: an optional intensity modifier: -foreground, -accent, -surface

For example, border-destructive-accent breaks down into the property border-, the role destructive, and the emphasis -accent, giving you the vivid red border used on error messages.

Background and foreground pairing

Many tokens come in pairs: a background token and a -foreground token for text on that background. Always use the paired foreground when placing text on a colored background.

BackgroundForegroundExample
bg-primarytext-primary-foregroundButtons
bg-selected-boldtext-selected-bold-foregroundBinary controls (Checkbox, Switch)
bg-destructivetext-destructive-foregroundError badges, section messages
bg-destructive-boldtext-destructive-bold-foregroundDestructive button
bg-access-mastertext-access-master-foregroundMaster access rows
bg-access-admintext-access-admin-foregroundAdmin access rows

Tokens without a foreground pair:

  • muted: uses text-foreground (the tint is light enough for regular text)
  • hover: uses text-foreground
  • selected: no explicit text color set on selection
  • focus-highlight: no explicit text color set on focus
  • focus-highlight-bold: uses text-foreground (the stronger tint still meets contrast with regular text)
  • surface: uses text-foreground or text-secondary
  • soft: uses text-foreground (the near-white cap is light enough for regular text)
  • secondary, placeholder: these ARE text tokens, not backgrounds
  • disabled: primarily a text token. When a background is needed, pair with bg-disabled-surface (see Disabled for details)

These tokens do not need a dedicated foreground color because they already meet WCAG/APCA contrast requirements with text-foreground or their respective text tokens.

Do

Always use the paired -foreground token when placing text on a colored background: bg-primary + text-primary-foreground.

Don't

Don't use text-foreground on colored backgrounds. It may not have sufficient contrast.

foreground vs primary

foreground and primary share the same charcoal value but serve different roles. foreground is the default body text color. primary is the action/interaction color (buttons, selections). A theme could change primary to blue while foreground stays dark.

Tokens in context

This diagram shows how tokens map to a typical form card. The gray page background (bg-background) contrasts with the white card surface (bg-surface), creating natural visual hierarchy.

Annotated UI showing token usage on a form card

Color palette

The RUI theme is built on a warm neutral palette called charcoal, an oklch gray with a subtle warm hue (hue 54). The 11-step scale runs from near-white (50) to near-black (950). All semantic color tokens below reference values from this palette.

50
100
200
300
400
500
600
700
800
900
950

Contrast matrix

This matrix shows the contrast ratio between every pair of charcoal steps. Use it to verify that your text and background combinations meet accessibility requirements.

Bg \ Text50100200300400500600700800900950
50
AaLc 01.0:1
AaLc 01.1:1
AaLc 131.2:1
AaLc 241.5:1
AaLc 452.2:1
AaLc 643.5:1
AaLc 775.3:1
AaLc 898.1:1
AaLc 9912.2:1
AaLc 10616.6:1
AaLc 11018.9:1
100
AaLc 01.1:1
AaLc 01.0:1
AaLc 01.1:1
AaLc 201.4:1
AaLc 412.1:1
AaLc 603.3:1
AaLc 735.0:1
AaLc 857.7:1
AaLc 9511.5:1
AaLc 10215.6:1
AaLc 10517.8:1
200
AaLc 131.2:1
AaLc 01.1:1
AaLc 01.0:1
AaLc 121.2:1
AaLc 331.8:1
AaLc 512.9:1
AaLc 654.3:1
AaLc 766.7:1
AaLc 8610.0:1
AaLc 9313.7:1
AaLc 9715.6:1
300
AaLc 241.5:1
AaLc 201.4:1
AaLc 111.2:1
AaLc 01.0:1
AaLc 211.5:1
AaLc 402.4:1
AaLc 533.6:1
AaLc 655.5:1
AaLc 758.3:1
AaLc 8211.3:1
AaLc 8612.9:1
400
AaLc 452.2:1
AaLc 402.1:1
AaLc 321.8:1
AaLc 201.5:1
AaLc 01.0:1
AaLc 191.6:1
AaLc 332.4:1
AaLc 443.7:1
AaLc 545.5:1
AaLc 617.5:1
AaLc 658.5:1
500
AaLc 633.5:1
AaLc 593.3:1
AaLc 502.9:1
AaLc 392.4:1
AaLc 181.6:1
AaLc 01.0:1
AaLc 141.5:1
AaLc 262.3:1
AaLc 353.5:1
AaLc 434.7:1
AaLc 465.4:1
600
AaLc 765.3:1
AaLc 725.0:1
AaLc 644.3:1
AaLc 523.6:1
AaLc 312.4:1
AaLc 131.5:1
AaLc 01.0:1
AaLc 121.5:1
AaLc 222.3:1
AaLc 293.1:1
AaLc 333.6:1
700
AaLc 888.1:1
AaLc 847.7:1
AaLc 756.7:1
AaLc 645.5:1
AaLc 433.7:1
AaLc 242.3:1
AaLc 111.5:1
AaLc 01.0:1
AaLc 101.5:1
AaLc 182.0:1
AaLc 212.3:1
800
AaLc 9812.2:1
AaLc 9411.5:1
AaLc 8510.0:1
AaLc 748.3:1
AaLc 535.5:1
AaLc 343.5:1
AaLc 212.3:1
AaLc 01.5:1
AaLc 01.0:1
AaLc 01.4:1
AaLc 111.6:1
900
AaLc 10616.6:1
AaLc 10115.6:1
AaLc 9313.7:1
AaLc 8111.3:1
AaLc 607.5:1
AaLc 424.7:1
AaLc 283.1:1
AaLc 172.0:1
AaLc 01.4:1
AaLc 01.0:1
AaLc 01.1:1
950
AaLc 10918.9:1
AaLc 10517.8:1
AaLc 9615.6:1
AaLc 8512.9:1
AaLc 648.5:1
AaLc 465.4:1
AaLc 323.6:1
AaLc 202.3:1
AaLc 111.6:1
AaLc 01.1:1
AaLc 01.0:1
APCA: 75+ Body 60+ Sub 45+ Large Fail|WCAG: 7+ AAA 4.5+ AA 3+ Large Fail

Color tokens

Page background & text

The foundational layer: page background and text hierarchy.

TokenValueUse for
background
var(--color-background)
charcoal-100Page-level background (<body>), gray so white surfaces separate from it by fill
foreground
var(--color-foreground)
charcoal-900Primary body text
secondary
var(--color-secondary)
charcoal-600Help text, descriptions, input icons
secondary-bold
var(--color-secondary-bold)
charcoal-700Emphatic secondary text that must out-rank quiet captions without reaching full foreground — e.g. idle sidebar nav labels above group labels
placeholder
var(--color-placeholder)
charcoal-600Placeholder text in empty inputs
<body className="bg-background text-foreground">
  <p>Primary text</p>
  <p className="text-secondary">Secondary text</p>
</body>

No pairing needed

secondary, secondary-bold and placeholder are standalone text colors. They do not have a paired background token. secondary is the industry standard name for this role (Carbon, Material Design, Atlassian all use "secondary" for secondary text); secondary-bold follows the system's -bold emphasis modifier (cf. selected/selected-bold) for text that sits between secondary and foreground.

Primary

The primary token represents the strongest visual weight in the interface. It is reserved for elements that trigger an action: buttons, links styled as buttons, and similar call-to-action surfaces. Primary draws the eye and signals "this is the main thing you can do here."

TokenValueUse for
primary
var(--color-primary)
charcoal-900Button backgrounds, call-to-action elements
primary-foreground
var(--color-primary-foreground)
charcoal-50Text and icons on primary backgrounds
<div className="bg-primary text-primary-foreground">Save</div>

Do

Use bg-primary for action elements like buttons. Use bg-selected-bold for binary controls (Checkbox, Radio, Switch, ToggleButton).

Don't

Don't use bg-primary for selection states or large decorative backgrounds like cards or sections.

Surfaces

The page is gray (bg-background), component panels are lighter (bg-surface). This contrast creates natural visual hierarchy without relying solely on shadows and borders.

Raised surfaces (Card, Panel, Dialog, Menu) draw their rim with surface-border, a translucent decorative hairline applied through the ui-surface utility rather than a standalone border. Controls use the same mechanism with a denser edge, the control-border token covered under Control below. See Borders for the full set of edge tokens, and Elevation for how boundaries combine with the overlay shadow.

TokenValueUse for
surface
var(--color-surface)
whiteWhite component backgrounds (cards, panels, inputs, tables)
surface-border
var(--color-surface-border)
charcoal-950 / 13%Decorative rim of a raised surface (Card, Panel, Dialog, Menu), applied via ui-surface. Sits below the contrast threshold, so never for an edge that must be seen
<div className="ui-surface">Content on a white surface</div>

Muted

Some elements need a subtle visual distinction from the white surface they sit on without drawing too much attention. Readonly inputs, badges, and table headers all benefit from a light background tint that says "this content is secondary" without implying any interactive state.

TokenValueUse for
muted
var(--color-muted)
charcoal-50Subtle tint for readonly inputs, badges, secondary highlights
// Readonly input with muted background
<input className="bg-muted" readOnly />

// Badge with subtle background
<span className="bg-muted text-foreground">Draft</span>

Do

Use bg-muted for content that is visually secondary but still readable, like readonly inputs, badges, and table sub-headers.

Don't

Don't use bg-muted for disabled states. Disabled elements need bg-disabled-surface to clearly signal that interaction is blocked.

Control

Controls carry two neutral tokens. Most define their shape with a border, drawn with control-border through the ui-control utility. A few communicate their state through a filled background instead, and that resting fill is the control token.

control-border is the visible edge of a bordered control such as a text input or a select. It is the denser sibling of surface-border, kept above the contrast threshold so the boundary is always seen. The full set of edge tokens lives under Borders.

Some controls have no border to define them. The switch track is the clearest example. When OFF, the track needs to look like a solid, physical groove that the thumb can slide along. A white or transparent background would make it disappear into the surface, while selected or disabled-surface would send the wrong signal. control fills this gap with a medium-weight neutral background that reads as an interactive control in its resting state, and it pairs naturally with selected-bold for the ON state.

TokenValueUse for
control-border
var(--color-control-border)
charcoal-950 / 26%Visible boundary of a bordered control (inputs, selects), applied via ui-control. Denser than surface-border and above the contrast threshold, so the edge stays visible
control
var(--color-control)
charcoal-300Resting fill for controls that show their inactive state through a background instead of a border (e.g. switch track)
// Switch track: control when off, selected-bold when on
<div className="bg-control group-selected/switch:bg-selected-bold" />

Not a default for all controls

Most form controls sit on bg-surface (white) and define their shape with a border. That border is the ui-control ring for inputs and selects, or border-control-border for checkboxes and radios, and its color is the control-border token documented with the other edges under Borders. Only reach for bg-control when a control communicates its state through a filled background rather than a border, like switch tracks, slider tracks, and similar "trough" elements.

Do

Use bg-control for controls that communicate state through a filled background, like the switch track or slider track.

Don't

Don't use bg-control for bordered form controls like text inputs, selects, or textareas. Those should use bg-surface with the ui-control ring.

Soft

The secondary Button and the Menu trigger don't wear a boundary at all. They're raised caps: a convex fill gradient with the lift baked into the shading itself, no drop shadow attached. soft is the light, neutral cap. Its dark counterpart, ui-contrast, retints around primary and powers the primary Button and ActionBar instead.

TokenValueUse for
soft
var(--color-soft)
oklch(0.99 0.002 54)Resting fill for the soft cap (secondary Button, Menu trigger)
soft-hover
var(--color-soft-hover)
charcoal-100Fill on hover and expanded states
soft-edge
var(--color-soft-edge)
charcoal-200Base the soft cap ring derives from (the ring itself sits one step darker, computed at render time)
soft-edge-hover
var(--color-soft-edge-hover)
charcoal-300Edge base on hover and expanded states
// Secondary Button / Menu trigger: the soft cap
<button className="ui-soft">Save</button>

Selected

Selection tells users which item has already been chosen. Not every selection looks the same though. Binary controls like checkboxes and switches flip between on and off, so they use bg-selected-bold with text-selected-bold-foreground for a strong, inverted style that clearly communicates the on/off state. List-based components use the quieter bg-selected wash paired with the row's own indicator (the checkbox, radio, or check icon), which carries the selection boundary and its WCAG 1.4.11 contrast. The wash sits one step darker than the hover fill, so a committed row reads heavier than one the cursor merely floats over.

Known issue: secondary text on the selected wash

Because bg-selected is charcoal-300, secondary description text (text-secondary, charcoal-600) on a selected row lands at 3.6:1, below the 4.5:1 AA minimum. Selection is carried by the indicator, so the failure is limited to the description subtext. The fix is to render selected-row descriptions in text-foreground, or to move the fill onto an alpha ramp.

TokenValueUse for
selected
var(--color-selected)
charcoal-300Selection wash for list items (SelectList, ListBox, Sidebar), one step darker than hover, paired with the row indicator
selected-bold
var(--color-selected-bold)
charcoal-900Binary selection (Checkbox, Radio, Switch, ToggleButton)
selected-bold-foreground
var(--color-selected-bold-foreground)
charcoal-50Text and icons on selected-bold backgrounds

Binary controls (Checkbox, Radio, Switch, ToggleButton) use the strong/inverted pattern:

<div className="bg-selected-bold text-selected-bold-foreground" />

List selection (SelectList, ListBox) uses the quiet wash. The row's indicator is the ink:

<div className="selected:bg-selected" /> // + checkbox / radio / check indicator

Navigation (Sidebar) marks the current item with the wash and a stronger text color:

<a className="data-active:bg-selected data-active:text-foreground" />

Do

Use bg-selected for list-based selection (ListBox, Sidebar) and bg-selected-bold for binary controls (Checkbox, Switch, ToggleButton).

Don't

Don't use bg-selected for binary controls. A checkbox or switch should use the strong bg-selected-bold pattern to clearly communicate its on/off state.

Focus highlight

Focus highlight marks the item the user is currently navigating to via keyboard. Unlike selection, which shows a confirmed choice, focus indicates where the user's cursor is right now. Two intensities handle different contexts: a subtle tint for menu items and drop zones, and a bolder fill for inline segments like date fields where the focused part needs to stand out clearly.

TokenValueUse for
focus-highlight
var(--color-focus-highlight)
charcoal-100Subtle focus background for keyboard navigation (Menu, FileField)
focus-highlight-bold
var(--color-focus-highlight-bold)
charcoal-300Strong focus background for inline segments (DateField)
// Subtle focus: menu items, file drop zones
<div className="data-focused:bg-focus-highlight" />

// Bold focus: inline segments like date fields
<div className="data-focused:bg-focus-highlight-bold" />

Do

Use bg-focus-highlight for list-like navigation (Menu, FileField) and bg-focus-highlight-bold for inline segments (DateField) where the focused part needs stronger contrast.

Don't

Don't use bg-selected for focus states. Selection and focus are different concepts: selection is a confirmed choice, focus is where the keyboard cursor currently sits.

Hover

Hover feedback tells users that an element is interactive. Unlike disabled or selected states, hover is momentary and must feel lightweight. Two patterns handle different contexts depending on the surface the element sits on: a solid tint for elements on white surfaces, and a translucent overlay for elements that float over varying backgrounds.

TokenValueUse for
hover
var(--color-hover)
charcoal-200Hover background for menu items, list options, sidebar links

Why two hover patterns?

Elements on white surfaces (list items, table rows, menu items) need a solid background tint to stand out. But ghost buttons, tabs, and action bar buttons sit on varying backgrounds, so a solid color would clash. Instead they use a translucent overlay (bg-current/10) that adapts to any context. The two utilities ui-state-hover and ui-state-hover-ghost bundle the correct styles for each case.

// Solid hover: list items, table rows, menu items, sidebar links
<div className="hover:ui-state-hover" />

// Ghost hover: ghost buttons, tabs, action bar buttons
<div className="hover:ui-state-hover-ghost" />

The ui-state-hover utility applies bg-hover with text-foreground. The ui-state-hover-ghost utility applies bg-current/10, a 10% translucent overlay of the current text color.

Do

Use ui-state-hover for items on white surfaces like list items, table rows, and menu items.

Don't

Don't use ui-state-hover on ghost buttons or tabs. Use ui-state-hover-ghost instead so the hover adapts to any background.

Disabled

Disabled elements must look visually inactive so users don't try to interact with them. Not every disabled element needs the same treatment though. A disabled label or help text only needs dimmed text, while a disabled input or button also needs a gray background to signal that the entire control is inactive. Two tokens handle these cases.

TokenValueUse for
disabled
var(--color-disabled)
charcoal-400Disabled text color, works standalone on white backgrounds
disabled-surface
var(--color-disabled-surface)
charcoal-200Disabled background for full controls (paired with text-disabled)
disabled-border
var(--color-disabled-border)
charcoal-300Boundary of a disabled control: a soft, receding edge (applied via ui-state-disabled, so the border dims rather than disappears)

Most token pairs follow the pattern bg-X + text-X-foreground. Disabled is different because disabled is primarily a text color, not a background. Many disabled elements only need dimmed text on a white surface (labels, menu items, help text). Only full controls like inputs and buttons need a gray background on top of that. So disabled-surface is the optional background add-on, while disabled itself is the text color. The pair is bg-disabled-surface + text-disabled, reversed from the usual direction.

// Text-only disabled (labels, help text, menu items)
<span className="text-disabled cursor-not-allowed">Disabled label</span>

// Full disabled control (inputs, buttons)
<input className="bg-disabled-surface text-disabled cursor-not-allowed" />

The ui-state-disabled utility bundles background, text, and cursor into one class. Its edge is the disabled-border token, listed with the other boundaries under Borders.

Do

Use bg-disabled-surface with text-disabled for disabled controls like inputs and buttons.

Don't

Don't use bg-muted for disabled states. muted is for subtle content highlights (badges, readonly), not disabled controls.

Borders

Every boundary token in one place. Marigold draws element edges with five tokens, and each one answers a different question. There is the decorative rim of a surface, the visible edge of a control, that edge dimmed for a disabled control, the structural divider, and the focus ring. surface-border also appears in the Surfaces section, control-border in the Control section, and disabled-border in the Disabled section, and they are repeated here so the whole set is discoverable at a glance. See Form Fields for component-level guidelines and Elevation for the surface and control rule these tokens implement.

TokenValueUse for
surface-border
var(--color-surface-border)
charcoal-950 / 13%Decorative rim of a raised surface (Card, Panel, Dialog, Menu), applied via ui-surface. Translucent and below the contrast threshold, so never for an edge that must be seen
control-border
var(--color-control-border)
charcoal-950 / 26%The boundary of a control such as inputs, selects, and date fields (via ui-control), plus checkboxes and radios (directly). An affordance the user must see (WCAG 1.4.11)
disabled-border
var(--color-disabled-border)
charcoal-300The control edge dimmed for a disabled control, a soft receding boundary (applied via ui-state-disabled, so it dims rather than disappears)
border
var(--color-border)
oklch(0.9 0.004 54)Structural lines drawn on a known surface, such as dividers, table row and grid lines, section rules, and internal separators. Opaque so crossing strokes cannot stack
ring
var(--color-ring)
charcoal-600Focus ring outline color for keyboard navigation

Which border token to pick for the job

Each boundary answers a different question. surface-border is the decorative rim of a raised surface (Card, Panel, Dialog). It sits below the contrast threshold, so never use it where the edge has to be seen. control-border marks an element you operate. It is the same translucent charcoal stroke as surface-border at about twice the density, so it stays clearly visible and adapts to the ground beneath it. disabled-border is that control edge dimmed for an inactive control, receding rather than vanishing. border draws structural lines such as dividers, grid lines, and section rules. It is opaque on purpose, because separators are many strokes drawn by many cells and translucent strokes would render darker wherever they cross. ring is the focus outline, the perceivable affordance for keyboard users.

Status colors

Status colors communicate feedback to the user: errors, confirmations, warnings, and informational messages. Components like Badge, SectionMessage, and Toast use these tokens to convey meaning through color.

Every status follows the same bg-X / text-X-foreground pairing as other tokens. On top of that, an accent level adds a higher-intensity variant for borders and icons. Here is how the pattern looks using destructive as an example:

Token suffixRoleExample usage
destructiveSubtle background for containersbg-destructive on Badge, SectionMessage, Toast
-foregroundText on that backgroundtext-destructive-foreground
-accentVibrant, saturated variant for borders, iconsborder-destructive-accent for accent borders, icon colors in Toast/SectionMessage
-boldStrong fill background (destructive only)bg-destructive-bold for destructive button
-bold-foregroundText on a bold background (destructive only)text-destructive-bold-foreground on destructive button

Replace destructive with success, warning, or info for the other statuses. Most statuses only need the first three levels. The -bold / -bold-foreground pair exists only for destructive, where a solid red button needs a dedicated fill and contrast text.

// Subtle container: light background + dark text
<div className="bg-destructive text-destructive-foreground">Error</div>

// Accent border on a subtle container
<div className="bg-warning border-warning-accent text-warning-foreground" />

// Accent icon color
<svg className="text-destructive-accent" />

// Strong fill: bold background + bold-foreground text
<div className="bg-destructive-bold text-destructive-bold-foreground">
  Delete
</div>

Do

Use the status token (bg-destructive, bg-warning) for containers like badges and section messages. Reserve the accent variant for borders and icons.

Don't

Don't use the accent token as a container background (except for destructive buttons). The saturated color is too strong for large areas.

Destructive

TokenValueUse for
destructive
var(--color-destructive)
red-100Subtle error/destructive background
destructive-foreground
var(--color-destructive-foreground)
red-950Text on destructive background
destructive-accent
var(--color-destructive-accent)
red-600Accent borders, icons
destructive-bold
var(--color-destructive-bold)
red-600Destructive button fill
destructive-bold-foreground
var(--color-destructive-bold-foreground)
whiteText on destructive button

Success

TokenValueUse for
success
var(--color-success)
green-100Subtle success background
success-foreground
var(--color-success-foreground)
green-950Text on success background
success-accent
var(--color-success-accent)
green-600Success borders, icons

Warning

TokenValueUse for
warning
var(--color-warning)
yellow-100Subtle warning background
warning-foreground
var(--color-warning-foreground)
yellow-950Text on warning background
warning-accent
var(--color-warning-accent)
yellow-700Warning borders, icons

Info

TokenValueUse for
info
var(--color-info)
blue-100Subtle info background
info-foreground
var(--color-info-foreground)
blue-950Text on info background
info-accent
var(--color-info-accent)
blue-600Info borders, icons

Access control

Domain-specific tokens for Reservix access level indicators. Follows the same structure as status colors: a subtle background, a foreground for text, and an accent for borders and icons.

TokenValueUse for
access-master
var(--color-access-master)
orange-100Master-level access background
access-master-foreground
var(--color-access-master-foreground)
orange-800Text on master-level access background
access-master-accent
var(--color-access-master-accent)
orange-700Master-level borders, icons, standalone text
access-admin
var(--color-access-admin)
purple-100Admin-level access background
access-admin-foreground
var(--color-access-admin-foreground)
purple-900Text on admin-level access background
access-admin-accent
var(--color-access-admin-accent)
purple-800Admin-level borders, icons, standalone text

The master/admin variants of Badge, Link, and Menu.Item mark access-restricted content with an icon (lock = master, key = admin, derived from the lucide icons lock-keyhole and key) colored with the matching access foreground token. The icon is purely decorative; on links and menu items the access level is exposed to assistive technology through a visually hidden text label. See the Admin- and Mastermark pattern for when and how to apply the variants.

Links

Text links use a dedicated color token to distinguish them from regular body text.

TokenValueUse for
link
var(--color-link)
blue-600Clickable text links

Overlay

When a modal or tray opens, a backdrop covers the page to focus attention on the overlay content. The token includes opacity so every overlay dims the page consistently.

TokenValueUse for
overlay-backdrop
var(--color-overlay-backdrop)
charcoal-950 / 45%Semi-transparent backdrop behind modals and trays
<div className="bg-overlay-backdrop" />

Scrollbar

Custom scrollbar tokens keep scrollbars visually consistent with the rest of the UI. The thumb uses a subtle neutral color by default and darkens on hover for better visibility.

TokenValueUse for
scrollbar
var(--color-scrollbar)
charcoal-300Scrollbar thumb color
scrollbar-hover
var(--color-scrollbar-hover)
charcoal-950Scrollbar thumb on hover
scrollbar-track
var(--color-scrollbar-track)
transparentScrollbar track background

Elevation

A single shadow marks the one layer that floats above the page. Everything else in normal flow separates by fill and boundary instead: cards and panels by the gray page ground, buttons by a raised cap (ui-soft, ui-contrast), fields by a flat well (ui-control).

TokenUse forComponents
shadow-elevation-overlayFloating elementsDialog, Drawer, Menu, Popover, Toast, ActionBar

Shadows are generated using the Josh Comeau shadow palette technique with multiple layers for natural-looking depth.

See Elevation for visual examples and usage guidelines.

Spacing

Control heights

All interactive controls share a consistent height scale.

TokenValueUse for
h-control2.25rem (36px)Default height for buttons and inputs
h-control-small2rem (32px)Compact buttons and controls
h-control-large2.5rem (40px)Large buttons

Relational spacing

Semantic spacing tokens for gaps between elements. The scale increases with the visual distance between items: tightly coupled elements sit close together, independent sections get more breathing room.

TokenValueUse for
tight6pxClosely related items (icon + label)
related8pxItems in a group
regular24pxIndependent items
group48pxGroups of content
section96pxMajor page sections

For visual examples and detailed guidance on when to use each level, see Spacing.

Inset spacing

Padding tokens for inside elements, available in three aspect ratios:

  • Square: equal padding on all sides
  • Squish: more horizontal than vertical (buttons, action items)
  • Stretch: more vertical than horizontal (cards, stacked content)

Each comes in five sizes: tight, snug, regular, relaxed, loose. For the full list of values and visual examples, see Spacing.

Animation

Easing

Six easing curves in three families: ease-out-* (enter), ease-in-* (exit), ease-in-out-* (looping). Each family includes quad, cubic, quart, quint, expo, and circ variants.

Animations

TokenUse for
animate-fade-in / animate-fade-outModal overlay transitions
animate-fade-in-upContent reveal with upward slide and blur
animate-slide-in / animate-slide-outActionBar enter/exit
animate-slide-in-right / animate-slide-out-rightDrawer enter/exit
animate-slide-in-left / animate-slide-out-leftSidebar enter/exit
animate-slide-in-top/bottomDropdown/bottom sheet enter/exit
animate-rotate-spinnerLoading spinner rotation
animate-progress-cycleIndeterminate progress animation

Proposing changes

If you want to change existing tokens or add new ones, please write a Support Ticket in the DST project so the design system team can review and discuss your request.

Related

Spacing

Spacing scale and visual examples for gaps, padding, and margins.

Elevation

Shadow system and surface hierarchy for visual depth.
Last update: 4 days ago

Accessibility

A guide to accessibility best practices for making your product usable for all.

Typography

Where the heading and body scales live today, and where they're heading.

On this page

How token names workBackground and foreground pairingTokens in contextColor paletteContrast matrixColor tokensPage background & textPrimarySurfacesMutedControlSoftSelectedFocus highlightHoverDisabledBordersStatus colorsAccess controlLinksOverlayScrollbarElevationSpacingControl heightsRelational spacingInset spacingAnimationEasingAnimationsProposing changesRelated