Tokens

Tokens are your design contract: define values once, generate consistent utilities everywhere.

Token layers

Keep tokens in layers so changes stay controlled: primitives for raw values, semantics for roles, and utilities generated from those values.

{
  "colours": {
    "brand": "#DB2777",
    "neutral": "#57534E"
  },
  "semanticColours": {
    "surface": "#12100E",
    "text": "#F8F5F0",
    "text-muted": "#A8A29E"
  },
  "spacing": {
    "scale": {
      "2": "0.5rem",
      "4": "1rem",
      "6": "1.5rem"
    }
  }
}

Primitive

Raw values

Values like #DB2777 or 0.75rem. Keep names neutral and stable.

Semantic

Role values

Names like surface, text-muted, focus-ring map meaning to primitives.

Utility output

Generated classes

Classes are generated from config and manifest, not hand-written per page.

Token change workflow

  1. Update config tokens in one place.
  2. Run emily-css build to regenerate CSS and metadata.
  3. Review utilities and variant support in docs.
  4. Run doctor to catch unknown or stale class usage.
npx emily-css build
npx emily-css doctor
npm run dev

Naming guidance

  • Prefer intent names like surface or danger over project-specific names.
  • Avoid one-off page variables when a token can express the same decision globally.
  • Keep token names short and predictable to reduce class churn.

Next step

Read Colours to set robust ramps and semantic roles from your token base.