Skip to main content
OrchestKit v7.5.2 โ€” 89 skills, 31 agents, 99 hooks ยท Claude Code 2.1.74+
OrchestKit
Skills

Design System Tokens

Design token management with W3C Design Token Community Group specification, three-tier token hierarchy (global/alias/component), OKLCH color spaces, Style Dictionary transformation, and dark mode theming. Use when creating design token files, implementing theme systems, managing token versioning, or building design-to-code pipelines.

Reference medium

Primary Agent: frontend-ui-developer

Design System Tokens

Design token management following the W3C Design Token Community Group (DTCG) specification. Tokens provide a single source of truth for design decisions โ€” colors, spacing, typography, elevation โ€” shared between design tools (Figma, Penpot) and code (CSS, Tailwind, iOS, Android). Major adopters include Figma (Variables API), Google (Material Design 3), Microsoft (Fluent UI), and Shopify (Polaris).

Quick Reference

CategoryRule FileImpactWhen to Use
W3C Token Formattokens-w3c-format.mdCRITICALCreating or reading .tokens.json files
Contrast Enforcementtokens-contrast-enforcement.mdCRITICALValidating WCAG contrast at token definition time
Three-Tier Hierarchytokens-three-tier.mdHIGHOrganizing tokens into global/alias/component layers
OKLCH Color Spacetokens-oklch-color.mdHIGHDefining colors with perceptual uniformity
Spacing & Depthtokens-spacing-depth.mdHIGHDefining elevation shadows and spacing scales as tokens
Style Dictionarytokens-style-dictionary.mdHIGHTransforming tokens to CSS/Tailwind/iOS/Android
Theming & Dark Modetokens-theming-darkmode.mdHIGHImplementing theme switching and dark mode
Versioningtokens-versioning.mdHIGHEvolving tokens without breaking consumers

Total: 8 rules across 8 categories

Quick Start

W3C DTCG token format (.tokens.json):

{
  "color": {
    "primary": {
      "50": {
        "$type": "color",
        "$value": "oklch(0.97 0.01 250)",
        "$description": "Lightest primary shade"
      },
      "500": {
        "$type": "color",
        "$value": "oklch(0.55 0.18 250)",
        "$description": "Base primary"
      },
      "900": {
        "$type": "color",
        "$value": "oklch(0.25 0.10 250)",
        "$description": "Darkest primary shade"
      }
    }
  },
  "spacing": {
    "sm": {
      "$type": "dimension",
      "$value": "8px"
    },
    "md": {
      "$type": "dimension",
      "$value": "16px"
    },
    "lg": {
      "$type": "dimension",
      "$value": "24px"
    }
  }
}

Three-Tier Token Hierarchy

Tokens are organized in three layers โ€” each referencing the layer below:

TierPurposeExample
GlobalRaw valuescolor.blue.500 = oklch(0.55 0.18 250)
AliasSemantic meaningcolor.primary = \{color.blue.500\}
ComponentScoped usagebutton.bg = \{color.primary\}

This separation enables theme switching (swap alias mappings) without touching component tokens.

{
  "color": {
    "blue": {
      "500": { "$type": "color", "$value": "oklch(0.55 0.18 250)" }
    },
    "primary": { "$type": "color", "$value": "{color.blue.500}" },
    "action": {
      "default": { "$type": "color", "$value": "{color.primary}" }
    }
  }
}

OKLCH Color Space

OKLCH (Oklab Lightness, Chroma, Hue) provides perceptual uniformity โ€” equal numeric changes produce equal visual changes. This solves HSL's problems where hsl(60, 100%, 50%) (yellow) appears far brighter than hsl(240, 100%, 50%) (blue) at the same lightness.

/* OKLCH: L (0-1 lightness), C (0-0.4 chroma/saturation), H (0-360 hue) */
--color-primary: oklch(0.55 0.18 250);
--color-primary-hover: oklch(0.50 0.18 250);  /* Just reduce L for darker */

Key advantage: adjusting lightness channel alone creates accessible shade scales with consistent contrast ratios.

Detailed Rules

Each rule file contains incorrect/correct code pairs and implementation guidance.

Read("${CLAUDE_SKILL_DIR}/rules/tokens-w3c-format.md")

Read("${CLAUDE_SKILL_DIR}/rules/tokens-contrast-enforcement.md")

Read("${CLAUDE_SKILL_DIR}/rules/tokens-three-tier.md")

Read("${CLAUDE_SKILL_DIR}/rules/tokens-oklch-color.md")

Read("${CLAUDE_SKILL_DIR}/rules/tokens-spacing-depth.md")

Read("${CLAUDE_SKILL_DIR}/rules/tokens-style-dictionary.md")

Read("${CLAUDE_SKILL_DIR}/rules/tokens-theming-darkmode.md")

Read("${CLAUDE_SKILL_DIR}/rules/tokens-versioning.md")

Style Dictionary Integration

Style Dictionary transforms W3C tokens into platform-specific outputs (CSS custom properties, Tailwind theme, iOS Swift, Android XML). Configure a single config.json to generate all platform outputs from one token source.

See rules/tokens-style-dictionary.md for configuration patterns and custom transforms.

Dark Mode & Theming

Token-based theming maps alias tokens to different global values per theme. Dark mode is one theme โ€” you can support any number (high contrast, brand variants, seasonal).

:root {
  --color-surface: oklch(0.99 0.00 0);
  --color-on-surface: oklch(0.15 0.00 0);
}

[data-theme="dark"] {
  --color-surface: oklch(0.15 0.00 0);
  --color-on-surface: oklch(0.95 0.00 0);
}

See rules/tokens-theming-darkmode.md for full theme switching patterns.

Versioning & Migration

Tokens evolve. Use semantic versioning for your token packages, deprecation annotations in token files, and codemods for breaking changes.

{
  "color": {
    "brand": {
      "$type": "color",
      "$value": "oklch(0.55 0.18 250)",
      "$extensions": {
        "com.tokens.deprecated": {
          "since": "2.0.0",
          "replacement": "color.primary.500",
          "removal": "3.0.0"
        }
      }
    }
  }
}

See rules/tokens-versioning.md for migration strategies.

Key Decisions

DecisionRecommendation
Token formatW3C DTCG .tokens.json with $type/$value
Color spaceOKLCH for perceptual uniformity
HierarchyThree-tier: global, alias, component
Build toolStyle Dictionary 4.x with W3C parser
ThemingCSS custom properties with data-theme attribute
Token referencesUse \{path.to.token\} alias syntax

Anti-Patterns (FORBIDDEN)

  • Hardcoded values in components: Always reference tokens, never raw #hex or 16px
  • Flat token structure: Use three-tier hierarchy for theme-ability
  • HSL for shade scales: OKLCH produces perceptually uniform scales; HSL does not
  • Skipping $type: Every token must declare its type for tooling compatibility
  • Theme via class toggling raw values: Use semantic alias tokens that remap per theme
  • Unversioned token packages: Token changes break consumers; use semver

References

ResourceDescription
references/w3c-token-spec.mdW3C DTCG specification overview
references/style-dictionary-config.mdStyle Dictionary 4.x configuration guide
references/token-naming-conventions.mdNaming patterns and conventions

Agent Integration

The design-system-architect agent orchestrates token workflows end-to-end โ€” from Figma Variables extraction through Style Dictionary transformation to theme deployment. When working on token architecture decisions, the agent coordinates with frontend-ui-developer for component token consumption and accessibility skills for contrast validation.

  • ork:ui-components โ€” Component library patterns (shadcn/ui, Radix)
  • ork:accessibility โ€” WCAG compliance, contrast ratios
  • ork:responsive-patterns โ€” Responsive breakpoints, fluid typography
  • ork:figma-design-handoff โ€” Figma Variables to tokens pipeline

Rules (8)

Enforce contrast ratios at token definition time, not per component โ€” CRITICAL

Token-Level Contrast Enforcement

Validate contrast ratios when tokens are defined, not when components are reviewed. If --color-text-muted is 4.3:1 on its paired background, every component using it fails WCAG AA โ€” and no per-component audit will fix the root cause.

Incorrect:

{
  "color": {
    "text": {
      "muted": { "$type": "color", "$value": "oklch(0.60 0.00 0)" }
    }
  }
}
/* No declared background pairing, no contrast metadata โ€” silent failure */
--color-text-muted: oklch(0.60 0.00 0);

Correct โ€” W3C DTCG token with contrast metadata:

{
  "color": {
    "text": {
      "primary": {
        "$type": "color",
        "$value": "oklch(0.15 0.00 0)",
        "$description": "Primary body text",
        "$extensions": {
          "a11y": {
            "pairedBackground": "{color.bg.primary}",
            "contrastRatio": 12.6,
            "wcagLevel": "AAA"
          }
        }
      },
      "muted": {
        "$type": "color",
        "$value": "oklch(0.45 0.00 0)",
        "$description": "Secondary/muted text โ€” must still meet AA",
        "$extensions": {
          "a11y": {
            "pairedBackground": "{color.bg.primary}",
            "contrastRatio": 4.7,
            "wcagLevel": "AA"
          }
        }
      }
    }
  }
}

Correct โ€” Style Dictionary build-time contrast check:

// style-dictionary.config.js
StyleDictionary.registerAction({
  name: 'validate/contrast',
  do(dictionary) {
    dictionary.allTokens
      .filter(t => t.$extensions?.a11y?.contrastRatio !== undefined)
      .forEach(t => {
        const { contrastRatio, wcagLevel } = t.$extensions.a11y;
        const threshold = wcagLevel === 'AAA' ? 7 : 4.5;
        if (contrastRatio < threshold) {
          throw new Error(
            `Token ${t.name}: contrast ${contrastRatio} < ${threshold} (${wcagLevel})`
          );
        }
      });
  },
  undo() {}
});

Key rules:

Minimum ratios at token definition level:

  • --color-text-* against paired background: >= 4.5:1 (WCAG AA)
  • --color-text-muted / --color-text-subtle: >= 4.5:1 โ€” "muted" describes tone, not an a11y exemption
  • --color-border-* against adjacent background: >= 3:1 (WCAG 1.4.11 non-text contrast)
  • --color-icon-* conveying information: >= 3:1
  • --color-interactive-* (links, button labels): >= 4.5:1 against background; >= 3:1 against surrounding body text

Dark mode:

  • Recalculate every pair independently for dark theme tokens โ€” do not assume inversion produces valid contrast
  • Pure white (oklch(1.00 0 0)) on dark backgrounds often exceeds 15:1 and causes eye strain; target 9-12:1
  • Document the dark-mode pairing in $extensions.a11y just as you do for light mode

Process:

  • Every text-role token declares its intended background pair in $extensions.a11y.pairedBackground
  • Run style-dictionary build as a CI gate โ€” contrast failures block the build
  • Review the generated contrast table in pull requests alongside visual diffs

Reference: references/w3c-token-spec.md

Define colors in OKLCH for perceptual uniformity โ€” HIGH

OKLCH Color Space

Use OKLCH (Oklab Lightness, Chroma, Hue) for all color token definitions. OKLCH is perceptually uniform โ€” equal numeric changes in lightness produce equal visual changes, unlike HSL where yellow at 50% lightness appears far brighter than blue at 50%.

Incorrect:

{
  "color": {
    "primary": {
      "$type": "color",
      "100": { "$value": "#dbeafe" },
      "500": { "$value": "#3b82f6" },
      "900": { "$value": "#1e3a5f" }
    }
  }
}
/* HSL shade scale โ€” uneven perception */
--blue-100: hsl(214, 95%, 93%);
--blue-500: hsl(217, 91%, 60%);
--blue-900: hsl(224, 64%, 33%);

Correct:

{
  "color": {
    "primary": {
      "$type": "color",
      "50":  { "$value": "oklch(0.97 0.01 250)" },
      "100": { "$value": "oklch(0.93 0.04 250)" },
      "200": { "$value": "oklch(0.85 0.08 250)" },
      "300": { "$value": "oklch(0.75 0.12 250)" },
      "400": { "$value": "oklch(0.65 0.16 250)" },
      "500": { "$value": "oklch(0.55 0.18 250)" },
      "600": { "$value": "oklch(0.48 0.16 250)" },
      "700": { "$value": "oklch(0.40 0.14 250)" },
      "800": { "$value": "oklch(0.32 0.10 250)" },
      "900": { "$value": "oklch(0.25 0.08 250)" }
    }
  }
}

Key rules:

  • OKLCH format: oklch(L C H) โ€” L: 0-1 lightness, C: 0-0.4 chroma, H: 0-360 hue
  • Generate shade scales by varying L (lightness) while keeping H (hue) constant
  • Reduce C (chroma) slightly at extremes (very light/dark) to stay within sRGB gamut
  • For accessible contrast: ensure 4.5:1 ratio between text and background tokens (WCAG AA)
  • Light shades (50-200): L > 0.80; mid shades (300-500): L 0.45-0.75; dark shades (600-900): L < 0.50
  • Use CSS color-mix(in oklch, ...) for runtime blending if needed
  • All modern browsers support OKLCH natively (Chrome 111+, Safari 15.4+, Firefox 113+)

Reference: references/w3c-token-spec.md

Define elevation and spacing as explicit token scales โ€” HIGH

Spacing and Depth as Tokens

Every spacing value and shadow must come from a named token โ€” no magic numbers. Spacing tokens create visual rhythm through proximity grouping; elevation tokens communicate layer hierarchy through a consistent light-source model.

Incorrect:

.card { padding: 12px 20px; box-shadow: 0 3px 8px rgba(0,0,0,0.12); }
.modal { box-shadow: 0 12px 20px rgba(0,0,0,0.18); }
.dropdown { margin-top: 6px; }

Correct โ€” token definitions:

{
  "spacing": {
    "$type": "dimension",
    "xs":  { "$value": "4px" },
    "sm":  { "$value": "8px" },
    "md":  { "$value": "16px" },
    "lg":  { "$value": "24px" },
    "xl":  { "$value": "32px" },
    "2xl": { "$value": "48px" },
    "3xl": { "$value": "64px" }
  },
  "elevation": {
    "$type": "shadow",
    "0": { "$value": "none" },
    "1": { "$value": "0 1px 2px rgba(0,0,0,0.05)" },
    "2": { "$value": "0 4px 6px rgba(0,0,0,0.07), 0 2px 4px rgba(0,0,0,0.06)" },
    "3": { "$value": "0 10px 15px rgba(0,0,0,0.10), 0 4px 6px rgba(0,0,0,0.05)" },
    "4": { "$value": "0 20px 25px rgba(0,0,0,0.15), 0 8px 10px rgba(0,0,0,0.07)" }
  }
}

Correct โ€” CSS custom properties:

:root {
  --space-xs: 4px;   --space-sm: 8px;   --space-md: 16px;
  --space-lg: 24px;  --space-xl: 32px;  --space-2xl: 48px;

  --elevation-0: none;
  --elevation-1: 0 1px 2px rgba(0,0,0,0.05);
  --elevation-2: 0 4px 6px rgba(0,0,0,0.07), 0 2px 4px rgba(0,0,0,0.06);
  --elevation-3: 0 10px 15px rgba(0,0,0,0.10), 0 4px 6px rgba(0,0,0,0.05);
  --elevation-4: 0 20px 25px rgba(0,0,0,0.15), 0 8px 10px rgba(0,0,0,0.07);
}

/* Component tokens reference the scale */
.card    { padding: var(--space-md); box-shadow: var(--elevation-1); }
.popover { box-shadow: var(--elevation-2); }
.modal   { box-shadow: var(--elevation-3); }
.toast   { box-shadow: var(--elevation-4); }

Key rules:

Spacing:

  • Base unit is 4px; the scale is geometric: 4, 8, 16, 24, 32, 48, 64
  • Start with generous whitespace, then reduce โ€” under-spaced UIs feel cramped and hard to scan
  • Use proximity to signal grouping: related elements share a closer spacing step
  • Sibling flow spacing via * + * \{ margin-block-start: var(--space-md) \} (owl selector)

Elevation (5 levels, top-left light source):

  • Level 0 โ€” flat, inline: no shadow, use background color change to separate regions
  • Level 1 โ€” raised surfaces (cards, list items): single, subtle contact shadow
  • Level 2 โ€” overlays floating above content (dropdowns, popovers): contact + ambient shadows
  • Level 3 โ€” modal dialogs: pronounced contact shadow, heavier ambient shadow
  • Level 4 โ€” highest-priority floating elements (toasts, command palette): maximum shadow
  • Every shadow uses two parts: a tight dark contact shadow + a large soft ambient shadow

Flat depth (no shadows needed):

  • Layer backgrounds: white card on --color-bg-secondary reads as elevated without a shadow
  • Overlap elements deliberately to imply z-order
  • Accent borders (left or top, 2px, brand color) add depth cues without full borders

Reference: references/token-naming-conventions.md

Use Style Dictionary 4.x to transform W3C tokens โ€” HIGH

Style Dictionary Integration

Use Style Dictionary 4.x with the W3C DTCG parser to transform design tokens into platform-specific outputs. A single token source generates CSS custom properties, Tailwind theme config, iOS Swift constants, and Android XML resources.

Incorrect:

// Manually maintaining separate files per platform
// tokens.css
:root { --color-primary: #3b82f6; }

// tokens.swift
struct Colors { static let primary = UIColor(hex: "#3b82f6") }

// tokens.xml
<color name="colorPrimary">#3b82f6</color>

Correct:

// config.mjs โ€” Style Dictionary 4.x
import { register } from '@tokens-studio/sd-transforms';
import StyleDictionary from 'style-dictionary';

register(StyleDictionary);

const sd = new StyleDictionary({
  source: ['tokens/**/*.tokens.json'],
  parsers: ['tokens-studio'],
  platforms: {
    css: {
      transformGroup: 'tokens-studio',
      buildPath: 'build/css/',
      files: [{
        destination: 'variables.css',
        format: 'css/variables',
        options: { outputReferences: true }
      }]
    },
    tailwind: {
      transformGroup: 'tokens-studio',
      buildPath: 'build/',
      files: [{
        destination: 'tailwind-tokens.js',
        format: 'javascript/es6'
      }]
    }
  }
});

await sd.buildAllPlatforms();

Key rules:

  • Use Style Dictionary 4.x (ESM) โ€” v3 does not support W3C format natively
  • Enable outputReferences: true to preserve alias chains in CSS output
  • Use @tokens-studio/sd-transforms for Tokens Studio / Figma Variables compatibility
  • Run token builds in CI to catch reference errors before merge
  • Custom transforms go in config.mjs โ€” never patch generated output files
  • Separate source files by tier: tokens/global/, tokens/alias/, tokens/component/

Reference: references/style-dictionary-config.md

Implement theme switching via alias token remapping โ€” HIGH

Theming & Dark Mode

Implement themes by remapping alias tokens to different global values. Dark mode is one theme among many. Use data-theme attribute on the root element and prefers-color-scheme media query for system preference detection.

Incorrect:

/* Hardcoded dark overrides โ€” fragile, misses semantics */
.dark .card { background: #1f2937; color: #f9fafb; }
.dark .button { background: #60a5fa; }
.dark .sidebar { background: #111827; }
/* Hundreds of component-level overrides... */

Correct:

/* Light theme (default) โ€” alias tokens mapped to light globals */
:root {
  --color-surface: oklch(0.99 0.00 0);
  --color-surface-raised: oklch(1.00 0.00 0);
  --color-on-surface: oklch(0.15 0.00 0);
  --color-on-surface-muted: oklch(0.45 0.00 0);
  --color-action: oklch(0.55 0.18 250);
  --color-action-hover: oklch(0.48 0.18 250);
  --color-border: oklch(0.88 0.00 0);
}

/* Dark theme โ€” same aliases, different globals */
[data-theme="dark"] {
  --color-surface: oklch(0.15 0.00 0);
  --color-surface-raised: oklch(0.20 0.01 250);
  --color-on-surface: oklch(0.95 0.00 0);
  --color-on-surface-muted: oklch(0.65 0.00 0);
  --color-action: oklch(0.65 0.16 250);
  --color-action-hover: oklch(0.70 0.14 250);
  --color-border: oklch(0.30 0.00 0);
}

/* System preference fallback */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --color-surface: oklch(0.15 0.00 0);
    --color-on-surface: oklch(0.95 0.00 0);
    /* ... same as [data-theme="dark"] */
  }
}
// Theme toggle with system preference detection
function initTheme() {
  const stored = localStorage.getItem('theme');
  if (stored) {
    document.documentElement.setAttribute('data-theme', stored);
  }
  // If no stored preference, :root:not([data-theme]) lets CSS handle it
}

function setTheme(theme) {
  document.documentElement.setAttribute('data-theme', theme);
  localStorage.setItem('theme', theme);
}

Key rules:

  • Use data-theme attribute, not CSS classes, for theme selection
  • Use :root:not([data-theme]) with prefers-color-scheme for system preference when no explicit choice is set
  • Components reference only alias tokens (--color-surface) โ€” never raw values
  • Dark mode is not just "invert lightness" โ€” reduce chroma and adjust contrast for readability
  • In dark themes, raise surface lightness slightly for elevated elements (cards, modals)
  • Test all themes against WCAG AA contrast requirements (4.5:1 text, 3:1 UI elements)

Reference: references/w3c-token-spec.md

Organize tokens in global, alias, and component tiers โ€” HIGH

Three-Tier Token Hierarchy

Organize tokens into three layers: global (raw values), alias (semantic meaning), and component (scoped usage). Components reference aliases, aliases reference globals. This enables theme switching by remapping aliases without touching components.

Incorrect:

{
  "button": {
    "background": { "$type": "color", "$value": "#3b82f6" },
    "text": { "$type": "color", "$value": "#ffffff" },
    "border-radius": { "$type": "dimension", "$value": "8px" }
  },
  "card": {
    "background": { "$type": "color", "$value": "#ffffff" },
    "border": { "$type": "color", "$value": "#e5e7eb" }
  }
}

Correct:

{
  "global": {
    "color": {
      "blue": {
        "$type": "color",
        "500": { "$value": "oklch(0.55 0.18 250)" },
        "600": { "$value": "oklch(0.48 0.18 250)" }
      },
      "neutral": {
        "$type": "color",
        "0": { "$value": "oklch(1.00 0 0)" },
        "100": { "$value": "oklch(0.96 0.00 0)" },
        "800": { "$value": "oklch(0.27 0.00 0)" }
      }
    }
  },
  "alias": {
    "color": {
      "$type": "color",
      "action": { "$value": "{global.color.blue.500}" },
      "actionHover": { "$value": "{global.color.blue.600}" },
      "surface": { "$value": "{global.color.neutral.0}" },
      "onSurface": { "$value": "{global.color.neutral.800}" }
    }
  },
  "component": {
    "button": {
      "bg": { "$type": "color", "$value": "{alias.color.action}" },
      "bgHover": { "$type": "color", "$value": "{alias.color.actionHover}" },
      "text": { "$type": "color", "$value": "{global.color.neutral.0}" }
    }
  }
}

Key rules:

  • Global tokens are raw values โ€” colors, sizes, font stacks โ€” never used directly in components
  • Alias tokens add semantic meaning โ€” action, surface, onSurface, danger โ€” and reference globals
  • Component tokens scope usage โ€” button.bg, card.border โ€” and reference aliases
  • Theme switching remaps alias layer only; component tokens stay unchanged
  • Keep global palette complete (all shades); keep alias layer minimal (only used semantics)
  • A component token referencing a global directly is a code smell โ€” add an alias

Reference: references/token-naming-conventions.md

Version token packages with semver and deprecation annotations โ€” HIGH

Token Versioning & Migration

Version your token packages with semantic versioning. Use $extensions for deprecation metadata. Provide codemods or migration scripts for breaking changes.

Incorrect:

{
  "color": {
    "brand": { "$type": "color", "$value": "oklch(0.55 0.18 250)" }
  }
}
# Renaming "brand" to "primary" with no warning, no migration path
git commit -m "rename brand to primary"
# Every consumer breaks silently

Correct:

{
  "color": {
    "brand": {
      "$type": "color",
      "$value": "{color.primary.500}",
      "$extensions": {
        "com.tokens.deprecated": {
          "since": "2.0.0",
          "replacement": "color.primary.500",
          "removal": "3.0.0",
          "message": "Use color.primary.500 instead"
        }
      }
    },
    "primary": {
      "$type": "color",
      "500": { "$value": "oklch(0.55 0.18 250)" }
    }
  }
}
// codemod for consumers (jscodeshift or custom script)
const tokenMigrations = {
  '--color-brand': '--color-primary-500',
  'var(--color-brand)': 'var(--color-primary-500)',
};

function migrateCSS(source) {
  let result = source;
  for (const [old, replacement] of Object.entries(tokenMigrations)) {
    result = result.replaceAll(old, replacement);
  }
  return result;
}

Key rules:

  • PATCH (1.0.x): New tokens, updated $description, metadata changes
  • MINOR (1.x.0): New token groups, new aliases, deprecated tokens (still functional)
  • MAJOR (x.0.0): Removed tokens, renamed tokens, changed $value semantics
  • Always deprecate before removing โ€” minimum one minor version between deprecation and removal
  • Include replacement path in deprecation metadata so tooling can auto-migrate
  • Maintain a CHANGELOG.md for your token package with migration instructions
  • Run a CI check that flags usage of deprecated tokens in consuming repos
  • Publish tokens as an npm package (e.g., @myorg/design-tokens) for versioned consumption

Reference: references/token-naming-conventions.md

Use W3C DTCG token format with $type and $value โ€” CRITICAL

W3C DTCG Token Format

All design tokens must follow the W3C Design Token Community Group specification. Every token requires $type and $value properties. Group tokens hierarchically using nested objects.

Incorrect:

{
  "colors": {
    "primary": "#3b82f6",
    "secondary": "rgb(99, 102, 241)"
  },
  "spacing": {
    "small": 8,
    "medium": "16px"
  }
}

Correct:

{
  "color": {
    "$type": "color",
    "primary": {
      "$value": "oklch(0.55 0.18 250)",
      "$description": "Primary brand color"
    },
    "secondary": {
      "$value": "oklch(0.50 0.17 280)",
      "$description": "Secondary accent color"
    }
  },
  "spacing": {
    "$type": "dimension",
    "sm": {
      "$value": "8px",
      "$description": "Compact spacing"
    },
    "md": {
      "$value": "16px",
      "$description": "Default spacing"
    }
  }
}

Key rules:

  • Every token must have $value; $type can be set on the token or inherited from a parent group
  • Valid $type values: color, dimension, fontFamily, fontWeight, duration, cubicBezier, number, strokeStyle, border, transition, shadow, gradient, typography, fontStyle
  • Use $description for documentation; tooling can extract these for style guides
  • File extension should be .tokens.json for tooling auto-detection
  • Use $extensions for vendor-specific metadata (deprecation, figma-mapping, etc.)
  • Token names use camelCase; group names use camelCase
  • References use curly brace syntax: "\{color.primary\}" to alias another token

W3C token group inheritance:

{
  "spacing": {
    "$type": "dimension",
    "xs": { "$value": "4px" },
    "sm": { "$value": "8px" },
    "md": { "$value": "16px" },
    "lg": { "$value": "24px" },
    "xl": { "$value": "32px" }
  }
}

All children inherit $type: "dimension" from the parent group โ€” no need to repeat it.

Reference: W3C Design Tokens Specification


References (3)

Style Dictionary Config

Style Dictionary 4.x Configuration Guide

Overview

Style Dictionary is a build system for transforming design tokens into platform-specific outputs. Version 4.x introduces ESM configuration, the W3C DTCG parser, and improved reference resolution.

Basic Configuration

// config.mjs
import StyleDictionary from 'style-dictionary';

const sd = new StyleDictionary({
  source: ['tokens/**/*.tokens.json'],
  platforms: {
    css: {
      transformGroup: 'css',
      buildPath: 'build/css/',
      files: [{
        destination: 'variables.css',
        format: 'css/variables',
        options: { outputReferences: true }
      }]
    }
  }
});

await sd.buildAllPlatforms();

Multi-Platform Output

Add platform entries for each target. Supported transform groups: css, js, ios, android.

// Add to platforms object alongside css:
js:      { transformGroup: 'js',      buildPath: 'build/js/',      files: [{ destination: 'tokens.js', format: 'javascript/es6' }] },
ios:     { transformGroup: 'ios',     buildPath: 'build/ios/',     files: [{ destination: 'Colors.swift', format: 'ios-swift/class.swift', filter: { type: 'color' } }] },
android: { transformGroup: 'android', buildPath: 'build/android/', files: [{ destination: 'colors.xml', format: 'android/colors', filter: { type: 'color' } }] },

Tokens Studio Integration

When using Tokens Studio (Figma plugin), use @tokens-studio/sd-transforms:

import { register } from '@tokens-studio/sd-transforms';
import StyleDictionary from 'style-dictionary';

// Register Tokens Studio transforms and parsers
register(StyleDictionary);

const sd = new StyleDictionary({
  source: ['tokens/**/*.tokens.json'],
  parsers: ['tokens-studio'],
  platforms: {
    css: {
      transformGroup: 'tokens-studio',
      buildPath: 'build/css/',
      files: [{
        destination: 'variables.css',
        format: 'css/variables',
        options: { outputReferences: true }
      }]
    }
  }
});

Custom Transforms

StyleDictionary.registerTransform({
  name: 'oklch/css',
  type: 'value',
  filter: (token) => token.$type === 'color',
  transform: (token) => {
    // Custom color transformation logic
    return token.$value;
  }
});

Theming with Multiple Files

Generate separate CSS files per theme:

const themes = ['light', 'dark', 'high-contrast'];

for (const theme of themes) {
  const sd = new StyleDictionary({
    source: [
      'tokens/global/**/*.tokens.json',
      `tokens/alias/${theme}.tokens.json`,
      'tokens/component/**/*.tokens.json'
    ],
    platforms: {
      css: {
        transformGroup: 'css',
        buildPath: 'build/css/',
        files: [{
          destination: `${theme}.css`,
          format: 'css/variables',
          options: {
            outputReferences: true,
            selector: theme === 'light' ? ':root' : `[data-theme="${theme}"]`
          }
        }]
      }
    }
  });
  await sd.buildAllPlatforms();
}

Key Options

OptionDescription
outputReferences: truePreserve alias chains in output (var(--color-primary))
selectorCSS selector for the variables block (default: :root)
filterFilter tokens by type, path, or custom function
transformGroupPreset group of transforms (css, js, ios, android)

Token Naming Conventions

Token Naming Conventions

Overview

Consistent token naming is essential for discoverability, tooling compatibility, and team collaboration. This guide covers naming patterns aligned with the W3C DTCG specification and industry best practices.

Naming Structure

Tokens follow a hierarchical dot-notation path: category.concept.modifier.state

SegmentExamplesPurpose
Categorycolor, spacing, typographyWhat type of value
Conceptprimary, surface, bodySemantic meaning
Modifier500, lg, boldVariant within concept
Statehover, active, disabledInteractive state

Examples by Category

Colors

color.primary.500          โ†’ Base primary color
color.primary.500.hover    โ†’ Hovered state
color.surface.default      โ†’ Default background
color.on-surface.default   โ†’ Text on default background
color.border.default       โ†’ Default border color
color.danger.500           โ†’ Error/danger base

Spacing

spacing.xs     โ†’ 4px   (extra small)
spacing.sm     โ†’ 8px   (small)
spacing.md     โ†’ 16px  (medium / base)
spacing.lg     โ†’ 24px  (large)
spacing.xl     โ†’ 32px  (extra large)
spacing.2xl    โ†’ 48px  (2x extra large)

Typography

typography.heading.xl      โ†’ Page title
typography.heading.lg      โ†’ Section heading
typography.body.md         โ†’ Body text
typography.body.sm         โ†’ Small body text
typography.label.md        โ†’ Form labels
typography.code.md         โ†’ Code blocks

Component Tokens

button.bg.default          โ†’ Button background
button.bg.hover            โ†’ Button hover background
button.text.default        โ†’ Button text color
button.border.radius       โ†’ Button corner radius
input.bg.default           โ†’ Input background
input.border.default       โ†’ Input border
input.border.focus         โ†’ Input focus border
card.bg.default            โ†’ Card background
card.shadow.default        โ†’ Card shadow
card.border.radius         โ†’ Card corner radius

Naming Rules

  1. Use camelCase for multi-word segments: fontSize, lineHeight, borderRadius
  2. Use dot notation for hierarchy: color.primary.500, not color-primary-500
  3. Semantic over visual: color.danger not color.red; spacing.md not spacing.16
  4. Consistent state naming: default, hover, active, focus, disabled
  5. Consistent scale naming: Use t-shirt sizes (xs, sm, md, lg, xl) or numeric scales (100-900)
  6. No abbreviations except well-known ones: bg, sm, md, lg, xl, 2xl
  7. Prefix component tokens with component name: button.bg, card.shadow

CSS Custom Property Output

When tokens are transformed to CSS, dots become dashes:

color.primary.500  โ†’  --color-primary-500
spacing.md         โ†’  --spacing-md
button.bg.hover    โ†’  --button-bg-hover

Common Mistakes

MistakeWhy It's WrongBetter
blue-500Visual, not semanticprimary-500
small-paddingMixes concept and categoryspacing-sm
btnBgUnclear abbreviationbutton-bg-default
color1, color2Meaningless namesprimary, secondary
dark-backgroundTheme-specific namingsurface-default

Mapping Figma Variables

When exporting from Figma, map variable collections to token tiers:

Figma CollectionToken TierExample
PrimitivesGlobalcolor/blue/500
TokensAliascolor/action/default
ComponentsComponentbutton/bg/default

W3c Token Spec

W3C Design Token Community Group Specification

Overview

The W3C Design Token Community Group (DTCG) defines a standard file format for design tokens, enabling interoperability between design tools, development platforms, and token management systems. The specification is available at design-tokens.github.io/community-group/format/.

File Format

Token files use JSON with the .tokens.json extension. Each token is an object with $-prefixed properties:

PropertyRequiredDescription
$valueYesThe token's resolved value
$typeYes*Token type (can be inherited from parent group)
$descriptionNoHuman-readable description
$extensionsNoVendor-specific metadata

*$type is required but can be declared on a parent group and inherited by all children.

Token Types

The specification defines these token types:

Simple Types

  • color โ€” CSS color value (hex, rgb, oklch, etc.)
  • dimension โ€” Number with unit (16px, 1.5rem)
  • fontFamily โ€” Font name string or array
  • fontWeight โ€” Numeric weight (100-900) or keyword
  • duration โ€” Time value (200ms, 0.3s)
  • cubicBezier โ€” Bezier curve array [x1, y1, x2, y2]
  • number โ€” Unitless number

Composite Types

  • strokeStyle โ€” Border stroke definition
  • border โ€” Composed of color, width, style
  • transition โ€” Composed of duration, delay, timing function
  • shadow โ€” Composed of color, offset, blur, spread
  • gradient โ€” Array of color stops
  • typography โ€” Composed of font family, size, weight, line height, letter spacing

Token References (Aliases)

Tokens can reference other tokens using curly brace syntax:

{
  "color": {
    "blue": {
      "500": { "$type": "color", "$value": "oklch(0.55 0.18 250)" }
    },
    "primary": { "$type": "color", "$value": "{color.blue.500}" }
  }
}

References are resolved by the token processing tool (e.g., Style Dictionary). Circular references are invalid.

Group Inheritance

A $type set on a group applies to all descendant tokens that don't specify their own $type:

{
  "spacing": {
    "$type": "dimension",
    "sm": { "$value": "8px" },
    "md": { "$value": "16px" },
    "lg": { "$value": "24px" }
  }
}

Extensions

The $extensions property allows vendor-specific metadata:

{
  "color": {
    "primary": {
      "$type": "color",
      "$value": "oklch(0.55 0.18 250)",
      "$extensions": {
        "com.figma": { "variableId": "VariableID:123:456" },
        "com.tokens.deprecated": { "since": "2.0.0", "replacement": "color.brand.primary" }
      }
    }
  }
}

Adoption

Major platforms supporting or converging on the W3C format:

  • Figma โ€” Variables API exports W3C-compatible tokens
  • Tokens Studio โ€” Figma plugin with full W3C support
  • Style Dictionary 4.x โ€” Built-in W3C parser
  • Google Material Design 3 โ€” Aligned with DTCG concepts
  • Microsoft Fluent UI โ€” Token architecture follows DTCG principles
  • Shopify Polaris โ€” Uses token hierarchy patterns from DTCG
  • Salesforce Lightning โ€” Early DTCG contributor

File Organization

Recommended file structure for a token package:

tokens/
โ”œโ”€โ”€ global/
โ”‚   โ”œโ”€โ”€ color.tokens.json
โ”‚   โ”œโ”€โ”€ spacing.tokens.json
โ”‚   โ”œโ”€โ”€ typography.tokens.json
โ”‚   โ””โ”€โ”€ elevation.tokens.json
โ”œโ”€โ”€ alias/
โ”‚   โ”œโ”€โ”€ light.tokens.json
โ”‚   โ””โ”€โ”€ dark.tokens.json
โ”œโ”€โ”€ component/
โ”‚   โ”œโ”€โ”€ button.tokens.json
โ”‚   โ”œโ”€โ”€ card.tokens.json
โ”‚   โ””โ”€โ”€ input.tokens.json
โ””โ”€โ”€ $metadata.json
Edit on GitHub

Last updated on

On this page

Design System TokensQuick ReferenceQuick StartThree-Tier Token HierarchyOKLCH Color SpaceDetailed RulesStyle Dictionary IntegrationDark Mode & ThemingVersioning & MigrationKey DecisionsAnti-Patterns (FORBIDDEN)ReferencesAgent IntegrationRelated SkillsRules (8)Enforce contrast ratios at token definition time, not per component โ€” CRITICALToken-Level Contrast EnforcementDefine colors in OKLCH for perceptual uniformity โ€” HIGHOKLCH Color SpaceDefine elevation and spacing as explicit token scales โ€” HIGHSpacing and Depth as TokensUse Style Dictionary 4.x to transform W3C tokens โ€” HIGHStyle Dictionary IntegrationImplement theme switching via alias token remapping โ€” HIGHTheming & Dark ModeOrganize tokens in global, alias, and component tiers โ€” HIGHThree-Tier Token HierarchyVersion token packages with semver and deprecation annotations โ€” HIGHToken Versioning & MigrationUse W3C DTCG token format with $type and $value โ€” CRITICALW3C DTCG Token FormatReferences (3)Style Dictionary ConfigStyle Dictionary 4.x Configuration GuideOverviewBasic ConfigurationMulti-Platform OutputTokens Studio IntegrationCustom TransformsTheming with Multiple FilesKey OptionsToken Naming ConventionsToken Naming ConventionsOverviewNaming StructureExamples by CategoryColorsSpacingTypographyComponent TokensNaming RulesCSS Custom Property OutputCommon MistakesMapping Figma VariablesW3c Token SpecW3C Design Token Community Group SpecificationOverviewFile FormatToken TypesSimple TypesComposite TypesToken References (Aliases)Group InheritanceExtensionsAdoptionFile Organization