pageweave/resources

Design Tokens & Systems

Build scalable token architectures — primitives, semantics, component mappings — that make design systems consistent and themeable.

· .md

Build scalable design token architectures that make design systems consistent, themeable, and maintainable across platforms.

The Three-Tier Architecture

Tier 1: Primitives

Raw, named values. No meaning attached — just the palette of available options.

:root {
  /* Color primitives */
  --blue-50: oklch(0.97 0.02 240);
  --blue-100: oklch(0.93 0.04 240);
  --blue-500: oklch(0.55 0.2 240);
  --blue-900: oklch(0.2 0.1 240);
  
  /* Spacing primitives */
  --space-0: 0rem;
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-4: 1rem;
  --space-8: 2rem;
  
  /* Type scale primitives */
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
  --text-2xl: 1.5rem;
}

Rules:

Tier 2: Semantics

Purpose-driven aliases that reference primitives. This is where meaning lives.

:root {
  /* Foreground hierarchy */
  --fg-primary: var(--gray-900);
  --fg-secondary: var(--gray-600);
  --fg-tertiary: var(--gray-400);
  --fg-muted: var(--gray-300);
  
  /* Background elevation */
  --bg-base: var(--gray-50);
  --bg-raised: var(--white);
  --bg-sunken: var(--gray-100);
  
  /* Border progression */
  --border-subtle: var(--gray-200);
  --border-default: var(--gray-300);
  --border-strong: var(--gray-400);
  
  /* Brand */
  --color-primary: var(--blue-500);
  --color-primary-hover: var(--blue-600);
  --color-primary-content: var(--white);
  
  /* Semantic feedback */
  --color-success: var(--green-500);
  --color-warning: var(--amber-500);
  --color-error: var(--red-500);
  --color-info: var(--blue-500);
}

Rules:

Tier 3: Component Mappings

Component-specific tokens that reference semantics.

:root {
  --btn-bg: var(--color-primary);
  --btn-fg: var(--color-primary-content);
  --btn-border: var(--color-primary);
  --btn-radius: var(--radius-md);
  --btn-padding-x: var(--space-4);
  --btn-padding-y: var(--space-2);
  
  --card-bg: var(--bg-raised);
  --card-border: var(--border-subtle);
  --card-radius: var(--radius-lg);
  --card-shadow: var(--shadow-sm);
}

Rules:

Dark Theme Strategy

Dark themes swap the semantic layer only:

[data-theme="dark"] {
  --fg-primary: var(--gray-100);
  --fg-secondary: var(--gray-400);
  --bg-base: var(--gray-900);
  --bg-raised: var(--gray-800);
  --border-subtle: var(--gray-700);
  --color-primary: var(--blue-400);
}

For PageWeave/daisyUI: use update_theme(website, config: { css }) with bare variables (no [data-theme] wrapper — PageWeave adds it). Dark themes MUST include color-scheme: dark;.

Token Naming Conventions

Pattern Example When
{category}-{level} fg-primary General hierarchy
{component}-{property} btn-bg Component-specific
{category}-{state} btn-bg-hover Interactive states
{size}-{scale} text-sm, space-4 Scales

Avoid: color1, blue-light-ish, spacing-medium. If you can't describe the token's purpose in one word, rename it.

Spacing System

Pick a base unit. Stick to multiples. Random values signal no system.

Base: 4px (0.25rem)
Scale: 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64
Rem:   0, 0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4, 6, 8, 12, 16

Use the scale for: padding, margin, gap, border-radius (separate scale), component sizing.

Typography Scale

Use a modular scale for type sizes:

Minor third (1.2): 0.694, 0.833, 1, 1.2, 1.44, 1.728, 2.074, 2.488rem
Major third (1.25): 0.64, 0.8, 1, 1.25, 1.563, 1.953, 2.441rem

Pair with line-height and letter-spacing:

Radius & Elevation Scales

Radius (separate from spacing — different rhythm):

--radius-none: 0
--radius-sm: 0.25rem (4px)
--radius-md: 0.5rem (8px)
--radius-lg: 0.75rem (12px)
--radius-xl: 1rem (16px)
--radius-full: 9999px

Elevation (choose ONE approach):

Don't mix approaches. Commit.

Verification

  1. Every *-content token passes 4.5:1 contrast against its parent.
  2. Switching themes changes ONLY the semantic layer — primitives stay.
  3. No raw hex/rgb values in component code — everything traces to a token.
  4. Spacing values all come from the scale — no magic numbers.
  5. Component tokens are the only thing a developer needs to theme a component.