Skip to main content

Design Tokens

Design tokens define your ClearCMS site's visual language -- colors, fonts, spacing, radii, and shadows. They're stored as CSS custom properties (e.g. --theme-primary) and used by every section.

When building a custom frontend with Bridge Mode or the Headless API, fetch these tokens to stay in sync with the ClearCMS editor.

Try it — live token customizer

Change colors below and watch the section update in real time. One change propagates everywhere.

Primary
#2563eb
Secondary
#7c3aed
Text
#111827
Background
#ffffff
Alt Background
#f9fafb
Border
#e5e7eb

Ready to get started?

Join over 10,000 teams who use Acme to ship faster and collaborate better.

View generated CSS
:root {
  --theme-primary: #2563eb;
  --theme-secondary: #7c3aed;
  --theme-text: #111827;
  --theme-bg: #ffffff;
  --theme-bg-alt: #f9fafb;
  --theme-border: #e5e7eb;
}

Public endpoints

All public endpoints require no API key, support CORS, and are cached for 1 hour. They return published branding values only.

Get tokens as JSON

GET /api/v1/public/tokens.json

Returns tokens organized by category. Category keys have the --theme- prefix stripped. The raw object preserves full CSS variable names.

Response:

{
"colors": {
"primary": "#2563eb",
"primary-hover": "#1d4ed8",
"primary-light": "#dbeafe",
"secondary": "#7c3aed",
"secondary-hover": "#6d28d9",
"text": "#111827",
"text-muted": "#4b5563",
"text-on-primary": "#ffffff",
"bg": "#ffffff",
"bg-alt": "#f9fafb",
"bg-muted": "#f3f4f6",
"border": "#e5e7eb",
"border-strong": "#d1d5db"
},
"fonts": {
"font-sans": "Inter, sans-serif",
"font-heading": "Inter, sans-serif"
},
"spacing": {},
"radius": {},
"shadows": {},
"headings": {},
"layout": {},
"raw": {
"--theme-primary": "#2563eb",
"--theme-primary-hover": "#1d4ed8",
"--theme-text": "#111827",
"--theme-font-sans": "Inter, sans-serif"
}
}

The raw object contains every token with its full --theme-* name. Categorized objects use shortened keys (e.g. "primary" instead of "--theme-primary").

Empty categories return {}. Spacing, radius, shadows, and headings populate when you configure those values via branding or token overrides.

Get tokens as CSS

GET /api/v1/public/tokens.css

Returns all tokens as CSS custom properties:

Response:

html:root {
--theme-primary: #2563eb;
--theme-primary-hover: #1d4ed8;
--theme-primary-light: #dbeafe;
--theme-secondary: #7c3aed;
--theme-text: #111827;
--theme-text-muted: #4b5563;
--theme-bg: #ffffff;
--theme-bg-alt: #f9fafb;
--theme-border: #e5e7eb;
--theme-font-sans: Inter, sans-serif;
--theme-font-heading: Inter, sans-serif;
/* ... all active --theme-* variables */
}

Values are sanitized: url(), expression(), javascript:, @import, and injection attempts are stripped.

Get tokens as Tailwind config

GET /api/v1/public/tailwind.config.js

Returns a Tailwind CSS config module with tokens mapped to theme.extend keys (colors, fontFamily, borderRadius, boxShadow, spacing, fontSize, fontWeight, lineHeight, letterSpacing, maxWidth). Use as a Tailwind v3 preset or fetch at build time for v4.

Response (JavaScript module):

/**
* ClearCMS Tailwind Config — auto-generated from site branding tokens.
*
* Usage (Tailwind v3):
* const clearcms = require("./clearcms-tailwind.config");
* module.exports = { presets: [clearcms] };
*/
module.exports = {
theme: {
extend: {
colors: {
"primary": "#2563eb",
"primary-hover": "#1d4ed8",
"secondary": "#7c3aed",
"text": "#111827",
"bg": "#ffffff",
// ... all color tokens
},
fontFamily: {
"sans": ["Inter", "ui-sans-serif", "system-ui", "sans-serif"],
"heading": ["Inter", "ui-sans-serif", "system-ui", "sans-serif"],
},
// borderRadius, boxShadow, spacing, fontSize, etc.
},
},
};

This is the fastest way to keep a Tailwind-based frontend in sync with ClearCMS branding. Values reflect the merged cascade: defaults, then branding, then token overrides.


Using tokens in a custom frontend

Option 1: Load as CSS

Add the tokens stylesheet to your HTML head:

<link
rel="stylesheet"
href="https://your-site.clearcms.app/api/v1/public/tokens.css"
/>

Then use the variables in your CSS:

h1 {
color: var(--theme-primary);
font-family: var(--theme-font-heading);
}

.card {
border: 1px solid var(--theme-border);
background: var(--theme-bg-alt);
}

Option 2: Fetch as JSON

For build-time or JavaScript access:

const res = await fetch(
"https://your-site.clearcms.app/api/v1/public/tokens.json"
);
const tokens = await res.json();

// Categorized keys are stripped — use "primary", not "--theme-primary"
const primaryColor = tokens.colors["primary"];
const fontFamily = tokens.fonts["font-sans"];

// Or use the raw object for full CSS variable names
const rawPrimary = tokens.raw["--theme-primary"];

Option 3: Use with Tailwind CSS

Fetch the pre-built Tailwind config from the public endpoint:

// 1. Fetch at build time (e.g. in a script or CI step)
// curl https://your-site.clearcms.app/api/v1/public/tailwind.config.js -o clearcms-tailwind.config.js

// 2. Use as a preset in tailwind.config.js
const clearcms = require("./clearcms-tailwind.config");
module.exports = { presets: [clearcms] };

Or map CSS variables manually if you load the tokens CSS file alongside Tailwind:

// tailwind.config.js
export default {
theme: {
extend: {
colors: {
primary: "var(--theme-primary)",
"primary-hover": "var(--theme-primary-hover)",
secondary: "var(--theme-secondary)",
},
fontFamily: {
sans: "var(--theme-font-sans)",
heading: "var(--theme-font-heading)",
},
},
},
};

Either approach lets you use Tailwind classes like text-primary and bg-secondary.


Token cascade

Tokens resolve in this order (later values win):

  1. Package defaults -- built-in fallbacks for colors, text, and backgrounds
  2. Branding -- derived from your site's branding settings (colors and fonts in the editor)
  3. Token overrides -- manual values set in Settings > Design > Tokens

Setting a primary brand color auto-generates --theme-primary-hover (10% darker) and --theme-primary-light (90% lighter).

Manual overrides always win. If you override --theme-primary in token settings, changing the branding primary color has no effect until you remove the override.


Typography scale

Set --theme-type-scale to a ratio (1--2) and ClearCMS generates text sizes from --theme-text-xs through --theme-text-6xl, plus heading sizes --theme-h1-size through --theme-h6-size.

Example: --theme-type-scale: 1.25 ("Major Third") with a 16px base produces:

TokenSize
--theme-text-xs0.64rem
--theme-text-sm0.80rem
--theme-text-base1rem
--theme-text-lg1.25rem
--theme-text-xl1.5625rem
--theme-text-2xl1.9531rem
--theme-text-3xl2.4414rem
--theme-text-4xl3.0518rem
--theme-text-5xl3.8147rem
--theme-text-6xl4.7684rem

Heading tokens map automatically: --theme-h1-size = --theme-text-6xl, --theme-h2-size = --theme-text-5xl, down to --theme-h6-size = --theme-text-xl.

Set via the token management API:

PATCH /api/v1/settings/tokens

{
"tokens": {
"--theme-type-scale": "1.25"
}
}

Common ratios: 1.125 (Major Second), 1.2 (Minor Third), 1.25 (Major Third), 1.333 (Perfect Fourth), 1.5 (Perfect Fifth). Generated sizes are clamped between 12px and 72px.

--theme-type-scale is not emitted as a CSS variable -- it's consumed during generation and replaced by individual size tokens.


Default tokens

Built-in defaults before branding or overrides:

TokenDefaultPurpose
--theme-primary#2563ebPrimary brand color
--theme-primary-hover#1d4ed8Primary hover state
--theme-primary-light#dbeafeLight primary (backgrounds, badges)
--theme-secondary#7c3aedSecondary accent color
--theme-secondary-hover#6d28d9Secondary hover state
--theme-text#111827Main body text
--theme-text-muted#4b5563Subdued text (captions, help text)
--theme-text-on-primary#ffffffText on primary-colored backgrounds
--theme-bg#ffffffPage background
--theme-bg-alt#f9fafbAlternate background (alternating sections)
--theme-bg-muted#f3f4f6Muted background (cards, inputs)
--theme-border#e5e7ebStandard border color
--theme-border-strong#d1d5dbEmphasized border color

Additional tokens (spacing, radius, shadows, headings, layout) have no defaults -- they populate when configured through branding or token overrides.


Branding-to-token mapping

Colors and fonts set in the branding editor map to tokens:

Branding fieldToken(s) generated
Primary color--theme-primary, --theme-primary-hover, --theme-primary-light
Secondary color--theme-secondary, --theme-secondary-hover
Accent colorMaps to --theme-secondary if no secondary is set
Background--theme-bg
Surface--theme-bg-alt, --theme-bg-muted
Dark--theme-bg-dark
Text color--theme-text
Muted text--theme-text-muted
Border color--theme-border
Header background--theme-header-bg
Footer background--theme-footer-bg
Heading font--theme-font-heading
Body font--theme-font-sans
H1–H6 styles--theme-h1-size, --theme-h1-weight, etc.

Token management (authenticated)

Require authentication with settings:modify permission.

Get current tokens

GET /api/v1/settings/tokens

Returns current token overrides and valid token names:

{
"tokens": {
"--theme-primary": "#ff0000"
},
"validTokens": ["--theme-primary", "--theme-secondary", "..."]
}

Update tokens (merge)

PATCH /api/v1/settings/tokens

Merges provided tokens with existing overrides:

{
"tokens": {
"--theme-primary": "#ff0000",
"--theme-bg": "#fafafa"
}
}

Replace all tokens

PUT /api/v1/settings/tokens

Replaces all token overrides entirely. Any tokens not included are removed.

Reset tokens

DELETE /api/v1/settings/tokens

Removes all manual overrides, reverting to branding and default values.


Simple vs Advanced mode

The branding editor has two modes controlling how many tokens you can set directly.

Simple mode

You set two values:

  • Primary color — your main brand color
  • Light/dark toggle — light background (#ffffff) or dark background (#111827)

ClearCMS derives everything else:

Derived tokenHow it's calculated
SecondaryPrimary hue shifted +30° (analogous color)
Primary hoverPrimary darkened by ~10%
Primary lightPrimary at ~90% lightness
Text colorDark text on light backgrounds, white text on dark backgrounds
Text-on-primaryWhite or dark text, whichever has better contrast against primary

All derived colors meet WCAG 2.1 contrast requirements (4.5:1 for normal text).

Advanced mode

Gives you individual control over every color:

FieldToken(s)
Primary--theme-primary, auto-generates hover and light variants
Secondary--theme-secondary, auto-generates hover variant
AccentMaps to secondary if no secondary is set
Background--theme-bg
Surface--theme-bg-alt, --theme-bg-muted
Dark--theme-bg-dark
Text--theme-text
Muted text--theme-text-muted
Border--theme-border
Header background--theme-header-bg
Footer background--theme-footer-bg

Even in Advanced mode, text-on-primary, text-on-secondary, and text-on-dark colors are auto-calculated for WCAG compliance.


Full token reference

Color tokens

TokenDefaultPurpose
--theme-primary#2563ebPrimary brand color
--theme-primary-hover#1d4ed8Primary hover state
--theme-primary-light#dbeafeLight primary (backgrounds, badges)
--theme-secondary#7c3aedSecondary accent color
--theme-secondary-hover#6d28d9Secondary hover state
--theme-text#111827Main body text
--theme-text-muted#4b5563Subdued text (captions, help text)
--theme-text-light#9ca3afDecorative text
--theme-text-on-primary#ffffffText on primary-colored backgrounds
--theme-text-on-secondary#ffffffText on secondary-colored backgrounds
--theme-text-on-dark#ffffffText on dark backgrounds
--theme-text-on-dark-mutedrgba(255,255,255,0.7)Secondary text on dark backgrounds
--theme-bg#ffffffPage background
--theme-bg-alt#f9fafbAlternate background (alternating sections)
--theme-bg-muted#f3f4f6Muted background (cards, inputs)
--theme-bg-dark#111827Dark sections and footers
--theme-border#e5e7ebStandard border color
--theme-border-strong#d1d5dbEmphasized border color
--theme-header-bg(inherits --theme-bg)Navbar/header background
--theme-footer-bg#1e293bFooter background
--theme-success#059669Success messages
--theme-warning#d97706Warning messages
--theme-error#dc2626Error messages
--theme-info#0284c7Informational messages

Typography tokens

TokenDefaultPurpose
--theme-font-sansSystem UI stackBody text font family
--theme-font-headingSystem UI stackHeading font family
--theme-font-monoCascadia Code, Fira CodeCode and monospace text
--theme-text-xs0.75remMinimum readable text
--theme-text-sm0.875remSmall text
--theme-text-base1remBody text baseline
--theme-text-lg1.125remLarge body text
--theme-text-xl6xl1.25rem3.75remHeading scale
--theme-h1-sizeh6-size3.75rem1.25remPer-heading size override
--theme-h1-weighth6-weight700600Per-heading weight
--theme-h1-line-heighth6-line-height1.11.4Per-heading line height

Spacing tokens

TokenDefaultPurpose
--theme-section-y4remVertical section padding
--theme-container-x1remHorizontal container padding
--theme-card-padding1.5remCard internal padding
--theme-card-gap1.5remGap between cards
--theme-button-y8pxButton vertical padding
--theme-button-x16pxButton horizontal padding
--theme-input-y8pxInput vertical padding
--theme-input-x12pxInput horizontal padding
--theme-gap16pxGeneral content gap
--theme-padding24pxGeneral content padding

Spacing presets (set in branding):

PresetSection YGapPadding
Compact40px12px16px
Normal (default)64px16px24px
Spacious96px24px32px

Border radius tokens

TokenDefaultPurpose
--theme-radius8pxGlobal radius
--theme-button-radius6pxButton corners
--theme-card-radius8pxCard corners
--theme-input-radius6pxInput corners
--theme-badge-radius9999pxBadge/pill corners

Radius presets: Sharp (2px), Rounded (8px, default), Pill (9999px), or a custom value.

Shadow tokens

TokenDefaultPurpose
--theme-shadow-sm0 1px 2px rgba(0,0,0,0.05)Subtle depth
--theme-shadow-md0 4px 6px rgba(0,0,0,0.1)Standard shadow
--theme-shadow-lg0 10px 15px rgba(0,0,0,0.1)Prominent depth
--theme-card-shadow(mirrors shadow-md)Card shadows
--theme-button-shadow(mirrors shadow-sm)Button shadows
note

The shadow-sm, shadow-md, and shadow-lg tokens are CSS defaults defined in the stylesheet. They cannot be overridden via the token management API. Only card-shadow and button-shadow are configurable through token overrides.

Layout tokens

TokenDefaultPurpose
--theme-container-max1280pxMax site content width
--theme-content-max65chOptimal prose reading width

Available token categories

CategoryKey patternExample tokens
Colorsprimary*, secondary*, text*, bg*, border*, success, warning, error, info--theme-primary, --theme-bg-alt, --theme-border-strong
Fontsfont-*--theme-font-sans, --theme-font-heading, --theme-font-mono
Spacingsection-*, container-*, button-*, input-*, card-*--theme-section-y, --theme-card-padding
RadiusContains radius--theme-radius, --theme-card-radius
ShadowsContains shadow--theme-card-shadow, --theme-button-shadow
Headingsh1-* through h6-*--theme-h1-size, --theme-h2-weight, --theme-h3-line-height
Layoutcontent-*, hero-*, image-*--theme-content-max, --theme-hero-image-max

Only --theme--prefixed tokens are accepted. The system validates against ~90 known token names. Invalid names are silently stripped.

Was this page helpful?