Skip to content

Tokens

CSS variables

Every token ships as a CSS custom property on :root. That is what makes the system usable from any framework, overridable at any scope, and themeable without a build step.

Why custom propertiesPermalink to this section

The alternative — compiling tokens into class names — loses the two properties that make this architecture work.

  • They cascade

    An override declared on a section applies to everything inside it. Re-theming a marketing page is a scoped CSS block, not a prop threaded through every component.

  • They resolve at runtime

    A theme switch is a change of one attribute on the root element. No rebuild, no double-shipping of stylesheets, no flash of the wrong theme.

  • They are framework-agnostic

    The same tokens drive the React components here, plain CSS, and anything else that can read a custom property.

Using themPermalink to this section

Three ways, depending on where you are writing.

component.tsx
// Preferred. The theme maps semantic tokens onto utilities,
// so most product code never writes var() at all.
<div className="bg-surface text-ink border border-line rounded-lg p-6">
  <h2 className="type-h3 text-ink">Deployment history</h2>
  <p className="type-body-sm text-ink-muted">Last 30 days.</p>
</div>

Tailwind theme mappingPermalink to this section

Semantic tokens are mapped into Tailwind's colour namespace with @theme inline, so the utility resolves the variable at the point of use rather than freezing its value at build time.

UtilityResolves toUse for
bg-canvasvar(--background)The page background
text-inkvar(--foreground)Primary text and headings
text-ink-mutedvar(--muted-foreground)Supporting copy
bg-surfacevar(--surface)Panels and inset regions
border-linevar(--border-default)Default borders
bg-brandvar(--brand-primary)Primary actions
rounded-lgvar(--radius-lg)Cards and dialogs
shadow-overlayvar(--shadow-overlay)Dialogs and the command menu
src/app/globals.css
@import "tailwindcss";
@theme inline {
  --color-canvas: var(--background);
  --color-ink: var(--foreground);
  --color-ink-muted: var(--muted-foreground);
  --color-surface: var(--surface);
  --color-line: var(--border-default);
  --color-brand: var(--brand-primary);
}

The full declaration blockPermalink to this section

Generated from the same typed data that powers the token explorer, so this listing cannot drift from the tokens themselves.

Primitive layerPermalink to this section

Raw values. Referenced by the semantic layer only.

generated from src/tokens — layer 1
--neutral-0: #ffffff;
--neutral-50: #fbfaf8;
--neutral-100: #f6f3ef;
--neutral-150: #efeae4;
--neutral-200: #e3dcd4;
--neutral-300: #ccc3b9;
--neutral-400: #999188;
--neutral-500: #6b655e;
--neutral-600: #514c46;
--neutral-700: #3a3632;
--neutral-800: #292624;
--neutral-850: #211f1d;
--neutral-900: #1a1919;
--neutral-950: #11100f;
--brand-50: #fff8f3;
--brand-100: #feeee2;
--brand-200: #fbd6be;
--brand-300: #f4ad7d;
--brand-400: #ee7c39;
--brand-500: #e96516;
--brand-600: #c94e0c;
--brand-700: #9f3b08;
--brand-800: #7d300b;
--brand-900: #61250d;
--brand-950: #351407;
--indigo-50: #f5f8fc;
--indigo-100: #e8eef7;
--indigo-400: #b2c7eb;
--indigo-500: #7f9fd3;
--indigo-600: #5c7fb9;
--indigo-700: #456395;
--indigo-950: #17233a;
--green-50: #eef6f2;
--green-100: #dcece5;
--green-400: #6fbfa1;
--green-600: #357a63;
--green-700: #2b6350;
--green-950: #10241d;
--amber-50: #fbf3ee;
--amber-100: #f5e5da;
--amber-400: #d9a07a;
--amber-600: #a15c38;
--amber-700: #85492b;
--amber-950: #2a1a11;
--red-50: #fbf0f0;
--red-100: #f5dede;
--red-300: #e7a3a3;
--red-400: #dd8080;
--red-600: #b34747;
--red-700: #973939;
--red-950: #2b1414;
--space-0: 0px;
--space-2: 2px;
--space-4: 4px;
--space-6: 6px;
--space-8: 8px;
--space-12: 12px;
--space-16: 16px;
--space-20: 20px;
--space-24: 24px;
--space-32: 32px;
--space-40: 40px;
--space-48: 48px;
--space-64: 64px;
--space-80: 80px;
--space-96: 96px;
--space-128: 128px;
--radius-sm: 6px;
--radius-md: 12px;
--radius-lg: 16px;
--radius-xl: 18px;
--radius-full: 999px;
--font-family-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;
--font-family-display: var(--font-family-sans);
--font-family-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
--font-weight-regular: 400;
--font-weight-medium: 450;
--font-weight-strong: 550;
--font-weight-bold: 600;
--tracking-tightest: -0.028em;
--tracking-tighter: -0.022em;
--tracking-tight: -0.018em;
--tracking-snug: -0.012em;
--tracking-normal: -0.006em;
--tracking-wide: 0.06em;
--duration-instant: 90ms;
--duration-fast: 150ms;
--duration-normal: 240ms;
--duration-slow: 360ms;
--duration-reveal: 520ms;
--ease-standard: cubic-bezier(0.22, 0, 0.12, 1);
--ease-enter: cubic-bezier(0.08, 0.72, 0.16, 1);
--ease-exit: cubic-bezier(0.3, 0, 0.8, 0.15);
--ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
--ease-spring: cubic-bezier(0.34, 1.3, 0.64, 1);

Semantic layerPermalink to this section

What product code and components should read.

generated from src/tokens — layer 2 · light
--foreground: var(--neutral-900);
--muted-foreground: var(--neutral-500);
--faint-foreground: var(--neutral-400);
--inverted-foreground: var(--neutral-0);
--background: var(--neutral-0);
--surface: var(--neutral-50);
--surface-hover: var(--neutral-100);
--surface-raised: var(--neutral-0);
--surface-sunken: var(--neutral-50);
--surface-inverted: var(--neutral-900);
--surface-inverted-hover: var(--neutral-800);
--overlay-background: rgb(23 23 23 / 0.32);
--border-subtle: var(--neutral-150);
--border-default: var(--neutral-200);
--border-strong: var(--neutral-300);
--border-focus: var(--brand-600);
--brand-primary: var(--brand-600);
--brand-primary-hover: var(--brand-700);
--brand-primary-soft: var(--brand-100);
--brand-primary-soft-hover: var(--brand-200);
--brand-primary-foreground: var(--neutral-0);
--brand-primary-on-soft: var(--brand-800);
--interactive-accent: var(--brand-700);
--interactive-accent-soft: var(--brand-50);
--brand-gradient: radial-gradient(42% 28% at 82% 0%, color-mix(in srgb, var(--brand-400) 20%, transparent) 0%, transparent 80%), linear-gradient(var(--neutral-0), var(--neutral-0));
--gradient-bulb: radial-gradient(38% 18% at 50% 0%, rgb(255 255 255 / 0.72) 0%, color-mix(in srgb, var(--brand-300) 12%, transparent) 30%, transparent 82%), linear-gradient(180deg, var(--neutral-50) 0%, var(--neutral-100) 100%);
--gradient-gobo: conic-gradient(from 92deg at 50% -18%, transparent 0deg, color-mix(in srgb, var(--brand-300) 7%, transparent) 16deg, transparent 34deg, transparent 142deg, color-mix(in srgb, var(--brand-500) 6%, transparent) 158deg, transparent 176deg), radial-gradient(36% 24% at 50% 0%, rgb(255 255 255 / 0.48) 0%, transparent 82%), linear-gradient(var(--neutral-50), var(--neutral-50));
--gradient-aurora: radial-gradient(34% 30% at 8% 8%, color-mix(in srgb, var(--brand-200) 14%, transparent) 0%, transparent 78%), radial-gradient(30% 26% at 92% 6%, color-mix(in srgb, var(--brand-400) 9%, transparent) 0%, transparent 80%), linear-gradient(142deg, var(--neutral-0) 0%, var(--neutral-100) 100%);
--gradient-horizon: radial-gradient(64% 12% at 50% 100%, color-mix(in srgb, var(--brand-400) 13%, transparent) 0%, transparent 82%), linear-gradient(180deg, var(--neutral-0) 0%, var(--neutral-100) 100%);
--gradient-mesh: radial-gradient(28% 24% at 6% 8%, color-mix(in srgb, var(--brand-200) 12%, transparent) 0%, transparent 80%), radial-gradient(26% 22% at 94% 14%, color-mix(in srgb, var(--brand-400) 8%, transparent) 0%, transparent 82%), radial-gradient(30% 18% at 56% 100%, color-mix(in srgb, var(--brand-100) 9%, transparent) 0%, transparent 84%), linear-gradient(var(--neutral-0), var(--neutral-0));
--gradient-prism: linear-gradient(116deg, transparent 38%, color-mix(in srgb, var(--brand-600) 10%, transparent) 46%, color-mix(in srgb, var(--brand-200) 16%, transparent) 50%, color-mix(in srgb, var(--brand-700) 9%, transparent) 54%, transparent 62%), linear-gradient(var(--neutral-50), var(--neutral-50));
--brand-gradient-foreground: var(--neutral-0);
--brand-gradient-muted-foreground: rgb(255 255 255 / 0.76);
--brand-gradient-surface: rgb(255 255 255 / 0.16);
--brand-gradient-border: rgb(255 255 255 / 0.22);
--success: var(--green-600);
--success-soft: var(--green-50);
--warning: var(--amber-600);
--warning-soft: var(--amber-50);
--danger: var(--red-600);
--danger-hover: var(--red-700);
--danger-soft: var(--red-50);
--danger-foreground: var(--neutral-0);
--code-keyword: var(--brand-600);
--code-string: var(--green-600);
--code-number: var(--amber-600);
--code-comment: var(--neutral-400);
--code-punctuation: var(--neutral-500);
--shadow-xs: 0 1px 2px rgb(80 45 24 / 0.04);
--shadow-sm: 0 2px 8px rgb(80 45 24 / 0.06);
--shadow-md: 0 12px 32px rgb(80 45 24 / 0.10), 0 2px 6px rgb(80 45 24 / 0.05);
--shadow-overlay: 0 24px 72px rgb(80 45 24 / 0.16), 0 4px 14px rgb(80 45 24 / 0.07);
--header-height: 76px;
--sidebar-width: 272px;
--toc-width: 224px;
--content-max: 1440px;

Component layerPermalink to this section

Per-component override points.

generated from src/tokens — layer 3 · light
--control-radius: var(--radius-md);
--control-pill-radius: var(--radius-full);
--control-item-radius: var(--radius-sm);
--control-height-sm: 36px;
--control-height-md: 44px;
--control-height-lg: 52px;
--control-font-size-sm: 13px;
--control-font-size-md: 14px;
--control-font-size-lg: 15px;
--control-icon-size-sm: 14px;
--control-icon-size-md: 16px;
--control-icon-size-lg: 18px;
--control-item-padding-x: 12px;
--control-item-padding-y: 10px;
--control-item-font-size: 14px;
--control-item-icon-size: 16px;
--checkbox-size-sm: 16px;
--checkbox-size-md: 18px;
--checkbox-icon-size-sm: 12px;
--checkbox-icon-size-md: 14px;
--radio-size-sm: 16px;
--radio-size-md: 18px;
--radio-indicator-size-sm: 6px;
--radio-indicator-size-md: 8px;
--switch-track-height-sm: 16px;
--switch-track-width-sm: 28px;
--switch-thumb-size-sm: 12px;
--switch-thumb-offset-sm: 12px;
--switch-track-height-md: 20px;
--switch-track-width-md: 36px;
--switch-thumb-size-md: 16px;
--switch-thumb-offset-md: 16px;
--button-radius: var(--control-radius);
--button-padding-x-sm: 16px;
--button-padding-x-md: 20px;
--button-padding-x-lg: 24px;
--button-primary-background: var(--brand-primary);
--button-primary-foreground: var(--brand-primary-foreground);
--button-primary-hover: var(--brand-primary-hover);
--button-secondary-background: var(--surface);
--button-secondary-foreground: var(--foreground);
--button-secondary-hover: var(--surface-hover);
--button-soft-background: var(--brand-primary-soft);
--button-soft-foreground: var(--brand-primary-on-soft);
--button-soft-hover: var(--brand-primary-soft-hover);
--button-outline-border: var(--border-default);
--button-outline-hover: var(--surface);
--button-ghost-hover: var(--surface-hover);
--button-destructive-background: var(--danger);
--button-destructive-foreground: var(--danger-foreground);
--button-destructive-hover: var(--danger-hover);
--button-depth-highlight: var(--surface-raised);
--button-depth-shade: var(--foreground);
--button-depth-rim: var(--border-strong);
--button-depth-accent: var(--interactive-accent);
--button-depth-spectrum-a: var(--success);
--button-depth-spectrum-b: var(--warning);
--button-depth-spectrum-c: var(--danger);
--button-depth-shadow-resting: var(--shadow-sm);
--button-depth-shadow-floating: var(--shadow-md);
--button-depth-duration: var(--duration-normal);
--button-depth-ambient-duration: 4800ms;
--button-depth-easing: var(--ease-standard);
--button-depth-glass-blur: var(--space-8);
--input-radius: var(--control-radius);
--textarea-radius: var(--radius-sm);
--input-padding-x-sm: 12px;
--input-padding-x-md: 16px;
--input-padding-x-lg: 20px;
--input-padding-y-multiline: 12px;
--input-padding-icon-sm: 32px;
--input-padding-icon-md: 36px;
--input-padding-icon-lg: 44px;
--input-background: var(--background);
--input-foreground: var(--foreground);
--input-border: var(--border-default);
--input-border-hover: var(--border-strong);
--input-border-focus: var(--border-focus);
--input-placeholder: var(--faint-foreground);
--input-soft-background: var(--brand-primary-soft);
--input-soft-foreground: var(--brand-primary-on-soft);
--input-soft-border: var(--brand-primary-soft-hover);
--input-soft-border-hover: var(--brand-primary);
--input-soft-border-focus: var(--border-focus);
--input-soft-placeholder: var(--muted-foreground);
--input-invalid-border: var(--danger);
--card-background: var(--surface-raised);
--card-border: var(--border-default);
--card-radius: var(--radius-lg);
--card-padding-sm: 16px;
--card-padding-md: 24px;
--card-padding-lg: 32px;
--dialog-background: var(--surface-raised);
--dialog-radius: var(--radius-lg);
--dialog-padding-sm: 20px;
--dialog-padding-md: 24px;
--dialog-width-sm: 384px;
--dialog-width-md: 512px;
--dialog-width-lg: 672px;
--dialog-overlay: var(--overlay-background);
--dialog-shadow: var(--shadow-overlay);
--popover-radius: var(--radius-lg);
--popover-padding: 4px;
--tooltip-radius: var(--radius-sm);
--tooltip-padding-x: 10px;
--tooltip-padding-y: 6px;
--tooltip-font-size: 12.5px;
--tooltip-line-height: 18px;
--tooltip-max-width: 256px;
--tooltip-background: var(--surface-inverted);
--tooltip-foreground: var(--inverted-foreground);
--popover-background: var(--surface-raised);
--popover-border: var(--border-default);
--popover-shadow: var(--shadow-md);
--popover-width: 320px;
--popover-content-padding: 16px;
--bento-gap: 16px;
--bento-radius: var(--radius-xl);
--bento-padding: 24px;
--bento-visual-radius: var(--radius-md);
--bento-background: var(--surface-raised);
--bento-border: var(--border-default);
--bento-elevated-border: rgb(0 0 0 / 0);
--bento-shadow: var(--shadow-sm);
--bento-shadow-hover: var(--shadow-md);
--bento-spotlight-background: var(--brand-gradient);
--bento-spotlight-foreground: var(--brand-gradient-foreground);
--bento-spotlight-muted-foreground: var(--brand-gradient-muted-foreground);
--bento-spotlight-surface: var(--brand-gradient-surface);
--bento-spotlight-border: var(--brand-gradient-border);
--cta-title-font-weight: 600;
--sidebar-item-active-background: var(--brand-primary-soft);
--sidebar-item-active-foreground: var(--brand-primary-on-soft);
--badge-radius: var(--radius-full);
--badge-height-sm: 20px;
--badge-height-md: 24px;
--badge-padding-x-sm: 8px;
--badge-padding-x-md: 10px;
--badge-font-size-sm: 11px;
--badge-font-size-md: 12px;
--badge-icon-size-sm: 12px;
--badge-icon-size-md: 14px;
--checkbox-radius: var(--radius-sm);
--avatar-radius: var(--radius-md);
--avatar-size-xs: 24px;
--avatar-size-sm: 32px;
--avatar-size-md: 40px;
--avatar-size-lg: 48px;
--avatar-size-xl: 64px;
--avatar-font-size-xs: 10px;
--avatar-font-size-sm: 12px;
--avatar-font-size-md: 13px;
--avatar-font-size-lg: 15px;
--avatar-font-size-xl: 19px;
--badge-neutral-background: var(--surface);
--badge-brand-background: var(--brand-primary-soft);
--badge-brand-foreground: var(--brand-primary-on-soft);
--toast-foreground: var(--foreground);
--toast-radius: var(--radius-lg);
--toast-shadow: var(--shadow-overlay);
--toast-success-background: var(--success-soft);
--toast-success-accent: var(--success);
--toast-warning-background: var(--warning-soft);
--toast-warning-accent: var(--warning);
--toast-danger-background: var(--danger-soft);
--toast-danger-accent: var(--danger);
--toast-info-background: var(--interactive-accent-soft);
--toast-info-accent: var(--interactive-accent);
--skeleton-background: var(--surface);
--skeleton-highlight: var(--surface-hover);
--skeleton-radius: var(--radius-sm);
--skeleton-duration: 1600ms;
--combobox-background: var(--surface-raised);
--combobox-border: var(--border-default);
--combobox-option-hover: var(--surface-hover);
--combobox-option-selected: var(--brand-primary-soft);
--combobox-option-selected-foreground: var(--brand-primary-on-soft);
--drawer-background: var(--surface-raised);
--drawer-overlay: var(--overlay-background);
--drawer-shadow: var(--shadow-overlay);
--drawer-radius: var(--radius-lg);
--drawer-width: 420px;
--drawer-height: 80vh;
--drawer-padding: 24px;
--pagination-active-background: var(--brand-primary);
--pagination-active-foreground: var(--brand-primary-foreground);
--tag-background: var(--surface);
--tag-selected-background: var(--brand-primary-soft);
--tag-selected-foreground: var(--brand-primary-on-soft);
--rating-active: var(--warning);
--rating-inactive: var(--border-strong);
--disclosure-background: var(--surface-raised);
--disclosure-border: var(--border-default);
--disclosure-radius: var(--radius-md);
--radio-background: var(--input-background);
--radio-border: var(--input-border);
--radio-border-hover: var(--input-border-hover);
--radio-checked: var(--brand-primary);
--progress-background: var(--surface);
--progress-indicator: var(--brand-primary);
--progress-height-sm: 6px;
--progress-height-md: 10px;
--progress-radius: var(--radius-full);
--spinner-track: var(--border-default);
--spinner-indicator: var(--brand-primary);
--spinner-size-sm: 16px;
--spinner-size-md: 24px;
--spinner-size-lg: 36px;
--table-background: var(--surface-raised);
--table-header-background: var(--surface);
--table-border: var(--border-default);
--table-row-border: var(--border-subtle);
--table-row-hover: var(--surface-hover);
--table-row-selected: var(--brand-primary-soft);
--table-cell-padding-x: 12px;
--table-cell-padding-y: 10px;
--toggle-background: var(--background);
--toggle-foreground: var(--muted-foreground);
--toggle-hover: var(--surface-hover);
--toggle-active-background: var(--brand-primary-soft);
--toggle-active-foreground: var(--brand-primary-on-soft);
--toggle-border: var(--border-default);
--separator-color: var(--border-subtle);
--separator-thickness: 1px;
--kbd-background: var(--surface);
--kbd-foreground: var(--muted-foreground);
--kbd-border: var(--border-default);
--kbd-radius: var(--control-item-radius);
--kbd-height: 20px;
--kbd-padding-x: 6px;
--kbd-font-size: 11px;

Scoped overridesPermalink to this section

Because custom properties cascade, an override applies to a subtree without any component knowing about it.

app/marketing/marketing.css
/* Everything inside .marketing-surface picks these up. */
.marketing-surface {
  --brand-primary: var(--brand-700);
  --card-radius: var(--radius-xl);
  --space-section: var(--space-96);
}

/* A single instance can be overridden inline, too — useful
   for one-off cases that do not deserve a class. */

Override the semantic layer, not the primitive

Reassigning --brand-600 in a scope changes what the primitive is, which will surprise anyone reading the ramp. Reassign --brand-primary instead — that is what the layer is for.