Skip to main content
The Stride Design System uses a three-tier token architecture: Foundation Tokens (base values), Core Brand Tokens (brand-specific colors), and Semantic Tokens (purpose-driven mappings).

Token Architecture

Foundation Tokens (--spacing-lg, --radius-md)

Core Brand Tokens (--brand-primary-500, --brand-neutral-900)

Semantic Tokens (--text-primary, --interactive-primary)

    Components
This cascade allows brands to override values at any level while maintaining consistency.

Foundation Tokens

Brand-agnostic foundation values defined in styles.css.

Spacing

Base spacing scale (can be scaled by brands using --spacing-scale):
:root {
  --spacing-0: 0;
  --spacing-xs: 0.25rem;   /* 4px */
  --spacing-sm: 0.5rem;    /* 8px */
  --spacing-md: 0.75rem;   /* 12px */
  --spacing-lg: 1rem;      /* 16px */
  --spacing-xl: 1.5rem;    /* 24px */
  --spacing-2xl: 2rem;     /* 32px */
  --spacing-3xl: 3rem;     /* 48px */
  --spacing-4xl: 4rem;     /* 64px */
  --spacing-5xl: 6rem;     /* 96px */
}
Example - Forest Brand with Scaled Spacing:
.brand-forest {
  --spacing-scale: 1.2;
  --spacing-lg: calc(1rem * 1.2);    /* 1.2rem = 19.2px */
  --spacing-xl: calc(1.5rem * 1.2);  /* 1.8rem = 28.8px */
}

Border Radius

:root {
  --radius-none: 0;
  --radius-xs: 0.125rem;   /* 2px */
  --radius-sm: 0.25rem;    /* 4px */
  --radius-md: 0.375rem;   /* 6px */
  --radius-lg: 0.5rem;     /* 8px */
  --radius-xl: 0.75rem;    /* 12px */
  --radius-2xl: 1rem;      /* 16px */
  --radius-3xl: 1.5rem;    /* 24px */
  --radius-full: 9999px;   /* Fully rounded */
}

Typography

:root {
  /* Font sizes */
  --font-size-xs: 0.75rem;    /* 12px */
  --font-size-sm: 0.875rem;   /* 14px */
  --font-size-md: 1rem;       /* 16px */
  --font-size-lg: 1.125rem;   /* 18px */
  --font-size-xl: 1.25rem;    /* 20px */
  --font-size-2xl: 1.5rem;    /* 24px */
  --font-size-3xl: 1.875rem;  /* 30px */
  --font-size-4xl: 2.25rem;   /* 36px */
  --font-size-5xl: 3rem;      /* 48px */

  /* Font weights */
  --font-weight-light: 300;
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
}

Shadows

:root {
  --shadow-none: none;
  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
  --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
  --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
  --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
  --shadow-skeuomorphic: 0 0 0 1px rgba(10, 13, 18, 0.18) inset, 
                         0 -2px 0 0 rgba(10, 13, 18, 0.05) inset, 
                         0 1px 2px 0 rgba(10, 13, 18, 0.05);
}

Transitions

:root {
  --transition-fast: 150ms ease-in-out;
  --transition-normal: 200ms ease-in-out;
  --transition-slow: 300ms ease-in-out;
}

Component Tokens

:root {
  /* Buttons */
  --button-height-sm: 2rem;      /* 32px */
  --button-height-md: 2.5rem;    /* 40px */
  --button-height-lg: 3rem;      /* 48px */
  --button-padding-sm: 0 0.75rem;
  --button-padding-md: 0 1rem;
  --button-padding-lg: 0 1.5rem;
  --radius-button: var(--radius-full); /* Brand override */

  /* Inputs */
  --input-height-sm: 2.25rem;    /* 36px */
  --input-height-md: 2.75rem;    /* 44px */
  --input-height-lg: 3.25rem;    /* 52px */
  --input-padding: 0 0.75rem;
  --input-border-width: 1px;

  /* Cards */
  --card-padding-sm: 1rem;
  --card-padding-md: 1.5rem;
  --card-padding-lg: 2rem;
  --card-radius: var(--radius-3xl);
  --card-border-width: 1px;

  /* Focus ring */
  --focus-ring-width: 2px;
  --focus-ring-offset: 1px;
  --focus-ring-color: var(--border-focus);
}

Core Brand Tokens

Brand-specific color palettes defined per brand in brands.css.

Primary Colors

11-shade palette for brand colors:
.brand-stride {
  --brand-primary-50: #f0f9ff;   /* Lightest */
  --brand-primary-100: #e0f2fe;
  --brand-primary-200: #bae6fd;
  --brand-primary-300: #7dd3fc;
  --brand-primary-400: #38bdf8;
  --brand-primary-500: #0ea5e9;  /* Main brand color */
  --brand-primary-600: #0284c7;  /* Default interactive color */
  --brand-primary-700: #0369a1;
  --brand-primary-800: #075985;
  --brand-primary-900: #0c4a6e;
  --brand-primary-950: #082f49;  /* Darkest */
}
Usage:
  • 50-200: Light backgrounds, subtle highlights
  • 300-400: Hover states, borders
  • 500: Main brand color, logos
  • 600-700: Interactive elements, buttons
  • 800-950: Dark mode, text on light backgrounds

Neutral Colors

12-shade grayscale palette:
.brand-stride {
  --brand-neutral-0: #ffffff;    /* Pure white */
  --brand-neutral-50: #f8fafc;
  --brand-neutral-100: #f1f5f9;
  --brand-neutral-200: #e2e8f0;  /* Borders */
  --brand-neutral-300: #cbd5e1;
  --brand-neutral-400: #94a3b8;
  --brand-neutral-500: #64748b;  /* Mid-gray */
  --brand-neutral-600: #475569;
  --brand-neutral-700: #334155;
  --brand-neutral-800: #1e293b;
  --brand-neutral-900: #0f172a;  /* Text color */
  --brand-neutral-950: #020617;  /* Near black */
}
Brand Variations:
/* Coral: Warm-tinted neutrals */
.brand-coral {
  --brand-neutral-100: #fdf4f0;  /* Warm tint */
  --brand-neutral-500: #d4957c;  /* Warm mid-gray */
}

/* Acme: Cool blue-tinted neutrals */
.brand-acme {
  --brand-neutral-100: #f1f5f9;  /* Cool tint */
  --brand-neutral-500: #64748b;  /* Cool mid-gray */
}

Status Colors

5-shade palettes for success, warning, and danger:
.brand-stride {
  /* Success (green) */
  --brand-success-50: #f0fdf4;
  --brand-success-100: #dcfce7;
  --brand-success-500: #22c55e;
  --brand-success-600: #16a34a;
  --brand-success-700: #15803d;

  /* Warning (amber) */
  --brand-warning-50: #fffbeb;
  --brand-warning-100: #fef3c7;
  --brand-warning-500: #f59e0b;
  --brand-warning-600: #d97706;
  --brand-warning-700: #b45309;

  /* Danger (red) */
  --brand-danger-50: #fef2f2;
  --brand-danger-100: #fee2e2;
  --brand-danger-500: #ef4444;
  --brand-danger-600: #dc2626;
  --brand-danger-700: #b91c1c;
}

Typography Tokens

Brand-specific font stacks:
/* Stride */
.brand-stride {
  --font-family-primary: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-family-secondary: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* Coral */
.brand-coral {
  --font-family-primary: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-family-secondary: 'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* Acme (with monospace) */
.brand-acme {
  --font-family-primary: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-family-secondary: 'JetBrains Mono', 'Fira Code', 'Courier New', monospace;
}

Semantic Tokens

Purpose-driven tokens that map to core tokens.

Text Tokens (8)

.brand-stride {
  --text-primary: var(--brand-neutral-900);     /* Main text */
  --text-secondary: var(--brand-neutral-600);   /* Secondary text */
  --text-tertiary: var(--brand-neutral-500);    /* Tertiary text */
  --text-inverse: var(--brand-neutral-0);       /* Text on dark bg */
  --text-disabled: var(--brand-neutral-400);    /* Disabled text */
  --text-link: var(--brand-primary-600);        /* Links */
  --text-link-hover: var(--brand-primary-700);  /* Link hover */
  --text-brand: var(--brand-primary-500);       /* Brand-colored text */
}
Usage:
<p style={{ color: 'var(--text-primary)' }}>Main text</p>
<a style={{ color: 'var(--text-link)' }}>Link</a>
<span style={{ color: 'var(--text-disabled)' }}>Disabled</span>

Background Tokens (7)

.brand-stride {
  --bg-primary: var(--brand-neutral-0);       /* Page background */
  --bg-secondary: var(--brand-neutral-50);    /* Cards, panels */
  --bg-tertiary: var(--brand-neutral-100);    /* Nested sections */
  --bg-inverse: var(--brand-neutral-900);     /* Dark sections */
  --bg-disabled: var(--brand-neutral-100);    /* Disabled bg */
  --bg-overlay: rgba(0, 0, 0, 0.6);           /* Modal overlay */
  --bg-brand: var(--brand-primary-500);       /* Brand bg */
}

Interactive Tokens (8)

For buttons, links, and interactive elements:
.brand-stride {
  /* Primary buttons */
  --interactive-primary: var(--brand-primary-600);
  --interactive-primary-hover: var(--brand-primary-700);
  --interactive-primary-active: var(--brand-primary-800);
  --interactive-primary-disabled: var(--brand-neutral-200);
  --interactive-primary-text: var(--brand-neutral-0);

  /* Secondary buttons */
  --interactive-secondary: var(--brand-neutral-100);
  --interactive-secondary-hover: var(--brand-neutral-200);
  --interactive-secondary-active: var(--brand-neutral-300);
  --interactive-secondary-disabled: var(--brand-neutral-100);

  /* Ghost buttons */
  --interactive-ghost: transparent;
  --interactive-ghost-hover: var(--brand-neutral-100);
  --interactive-ghost-active: var(--brand-neutral-200);
  --interactive-ghost-disabled: transparent;
}

Border Tokens (6)

.brand-stride {
  --border-primary: var(--brand-neutral-200);     /* Default borders */
  --border-secondary: var(--brand-neutral-300);   /* Stronger borders */
  --border-strong: var(--brand-neutral-400);      /* Emphasis */
  --border-inverse: var(--brand-neutral-700);     /* On dark bg */
  --border-focus: var(--brand-primary-500);       /* Focus rings */
  --border-brand: var(--brand-primary-500);       /* Brand borders */
}

Status Tokens (9)

For alerts, badges, notifications:
.brand-stride {
  /* Success */
  --status-success: var(--brand-success-500);         /* Icon/accent */
  --status-success-hover: var(--brand-success-600);   /* Hover */
  --status-success-bg: var(--brand-success-50);       /* Background */
  --status-success-text: var(--brand-success-700);    /* Text */

  /* Warning */
  --status-warning: var(--brand-warning-500);
  --status-warning-hover: var(--brand-warning-600);
  --status-warning-bg: var(--brand-warning-50);
  --status-warning-text: var(--brand-warning-700);

  /* Danger */
  --status-danger: var(--brand-danger-500);
  --status-danger-hover: var(--brand-danger-600);
  --status-danger-bg: var(--brand-danger-50);
  --status-danger-text: var(--brand-danger-700);
}
Usage:
<div style={{ 
  backgroundColor: 'var(--status-success-bg)',
  color: 'var(--status-success-text)'
}}>
  Success message
</div>

Surface Tokens (4)

For elevated surfaces:
.brand-stride {
  --surface-card: var(--brand-neutral-0);
  --surface-modal: var(--brand-neutral-0);
  --surface-popover: var(--brand-neutral-0);
  --surface-tooltip: var(--brand-neutral-900);
}

Dark Mode Tokens

All brands support automatic dark mode token remapping:
.brand-stride.dark {
  /* Inverted text */
  --text-primary: var(--brand-neutral-50);      /* Was 900 */
  --text-secondary: var(--brand-neutral-300);   /* Was 600 */
  --text-inverse: var(--brand-neutral-900);     /* Was 0 */

  /* Inverted backgrounds */
  --bg-primary: var(--brand-neutral-900);       /* Was 0 */
  --bg-secondary: var(--brand-neutral-800);     /* Was 50 */
  --bg-inverse: var(--brand-neutral-50);        /* Was 900 */

  /* Adjusted borders */
  --border-primary: var(--brand-neutral-700);   /* Was 200 */
  --border-secondary: var(--brand-neutral-600); /* Was 300 */

  /* Interactive adjustments */
  --interactive-secondary: var(--brand-neutral-800);
  --interactive-ghost-hover: var(--brand-neutral-800);
}

Component-Specific Overrides

Some brands override component-specific tokens:

Coral: No Button Radius

.brand-coral {
  --radius-button: 0; /* Sharp corners */
}

Forest: Moderate Radius

.brand-forest {
  --card-radius: var(--radius-md);    /* Instead of 3xl */
  --radius-button: var(--radius-sm);  /* Instead of full */
}

Acme: Tech Aesthetic

.brand-acme {
  --radius-button: var(--radius-lg);  /* Rounded buttons */
  --card-radius: var(--radius-xl);    /* Slightly more rounded */
}

Using Tokens in Code

CSS

.my-component {
  background-color: var(--bg-secondary);
  color: var(--text-primary);
  border: 1px solid var(--border-primary);
  border-radius: var(--radius-lg);
  padding: var(--spacing-lg);
  font-family: var(--font-family-primary);
  transition: var(--transition-normal);
}

.my-component:hover {
  background-color: var(--interactive-secondary-hover);
}

Tailwind CSS

Tokens are mapped to Tailwind utilities:
<div className="bg-[--bg-secondary] text-[--text-primary] border-[--border-primary]">
  Styled with Tailwind
</div>

Inline Styles

<div style={{
  backgroundColor: 'var(--bg-secondary)',
  color: 'var(--text-primary)',
  borderRadius: 'var(--radius-lg)',
}}>
  Inline styles
</div>

JavaScript

const primaryColor = getComputedStyle(document.documentElement)
  .getPropertyValue('--brand-primary-500');

console.log(primaryColor); // '#0ea5e9'

Token Naming Convention

Tokens follow a consistent naming pattern:
--{category}-{property}-{variant}
Examples:
  • --brand-primary-500 (category: brand, property: primary, variant: 500)
  • --text-link-hover (category: text, property: link, variant: hover)
  • --interactive-primary-disabled (category: interactive, property: primary, variant: disabled)

Complete Token Reference

Foundation Tokens (32)

  • Spacing: 10 tokens
  • Radius: 9 tokens
  • Typography: 13 tokens (sizes + weights)

Core Brand Tokens (per brand)

  • Primary colors: 11 tokens
  • Neutral colors: 12 tokens
  • Success colors: 5 tokens
  • Warning colors: 5 tokens
  • Danger colors: 5 tokens
  • Typography: 2 tokens
  • Total: 40 core tokens per brand

Semantic Tokens (per brand)

  • Text: 8 tokens
  • Background: 7 tokens
  • Interactive: 12 tokens
  • Border: 6 tokens
  • Status: 9 tokens
  • Surface: 4 tokens
  • Total: 46 semantic tokens per brand

Component Tokens (13)

  • Button: 7 tokens
  • Input: 3 tokens
  • Card: 3 tokens
Grand Total: ~131 tokens per brand

Next Steps

Build docs developers (and LLMs) love