Get started

Semantic color tokens explained

A semantic color token names a color by what it does, not what it looks like: --primary, --muted-foreground, --border. Define the roles once in light and dark, style against the names, and your whole UI themes coherently. This is the model behind shadcn/ui and Tailwind theming.

Updated August 3, 2026

Semantic vs raw color

A raw color token names the color itself: --blue-500, --gray-900. A semantic token names the job the color does: --primary, --background, --muted-foreground. Components can then ignore the brand's literal hues. A button styled with bg-primary text-primary-foreground works with sage green, hot pink, or a dark theme because the role stays fixed while its value changes.

This is the model shadcn/ui popularized and Tailwind's theming builds on. With semantic tokens, re-theming an app can be limited to one :root block. Hardcoded classes such as bg-gray-900 and text-white turn the same change into a codebase-wide search.

The foreground pairing rule

Most base roles come with a paired -foreground role for text or icons on that surface: --primary / --primary-foreground, --card / --card-foreground, --muted / --muted-foreground. Use --primary-foreground on --primary instead of hoping the default foreground has enough contrast. Each pair must still be checked in both modes.

The 28 roles a complete system needs

A minimal three-color palette leaves 25 decisions undefined: hover states, muted text, borders, focus rings, chart series, dark mode. A complete system names all of them. Identity Forge kits define these 28 roles, grouped by what they do, for light and dark:

  • Surfaces: background / foreground, card / card-foreground, popover / popover-foreground. The page, raised panels, and floating layers, each with its legible text color.
  • Brand & emphasis: primary / primary-foreground, secondary / secondary-foreground, accent / accent-foreground. The main action, the supporting one, and the highlight.
  • Quiet & neutral: muted / muted-foreground. Subdued backgrounds and secondary text.
  • State: destructive / destructive-foreground, success / success-foreground, warning / warning-foreground. Errors, confirmations, and cautions.
  • Form & focus: border, input, ring. Dividers and outlines, form field surfaces, and the focus indicator.
  • Data: chart-1, chart-2, chart-3, chart-4, chart-5. Five distinct, on-brand series colors so charts don't fall back to a generic default palette.

Why five chart colors matter

Data visualization is where under-specified systems break most visibly: a dashboard with three brand colors and a random rainbow for its bar chart. Defining chart-1…5 up front keeps graphs inside the same visual language as the rest of the app.

See the roles on a real kit

Below is the free ambient-sage kit rendered entirely from these tokens. The swatch row is --primary, --secondary, --accent, and the five chart roles; the button uses --primary with --primary-foreground; the surfaces use --background, --card, and --muted. Nothing here is a hardcoded color:

Ambient Sage

Live render

Rendered from the kit's actual tokens, fonts, and treatments

Ambient SageOverview
Search anything⌘K
AS

Analytics

Revenue overview

See revenue and retention trends alongside account health.

Jan 1 to Jan 30, 2026
Overview
Analytics
Reports
Notifications

Active users

15.1k

2,491 new

+5%

MRR

$49.1k

Net of churn

+3%

Retention

89%

28-day window

+2%

NPS

69

1,204 replies

+3

Revenue

Last 12 months

$49.1k +18.2%

12m30d7d
JanFebMarAprMayJunJulAugSepOctNovDec

Acquisition

Goal completion

On track
78%of goal
Organic48%
Direct31%
Referral21%

Recent transactions

Latest activity across your workspace

View all
CustomerStatusDateAmount
AR

Alex Rivera

Founder & CEO

Paid2 min ago$1,999.00
MO

Mira Okonkwo

Head of Product

Pending1 hour ago$39.00
JF

Jonas Feld

Design Lead

Processing3 hours ago$299.00

Typography

Plus Jakarta Sans

Color system

28 semantic roles, light + dark

Agent outputs

DESIGN.md, CSS, Tailwind, shadcn

Every color you see is a semantic token. Toggle a kit and each role takes a new value while the component code stays identical.

Get a full token set

You can define all 28 roles by hand, but it's tedious to keep light and dark balanced and accessible. Every Identity Forge kit ships them complete in both modes, exportable as CSS variables, Tailwind v3/v4 @theme, a shadcn registry item, or DTCG/W3C JSON. The quickest way to drop a complete set into a shadcn/ui project:

npx shadcn add https://identityforge.io/r/ambient-sage.json
Installs all 28 semantic roles (light + dark) into your theme

The tokens are also half of a DESIGN.md: the values the written brief references. Together they're what you give a coding agent so its UI stays coherent.

FAQ

What are semantic color tokens?

Color variables named by role rather than hue: --primary, --background, --muted-foreground instead of --blue-500. Components style against the role name, so changing themes or switching to dark mode never requires editing components.

How many color tokens does a design system need?

Identity Forge uses 28 semantic roles: surfaces with their foregrounds, brand and muted roles, state colors, form roles, and five chart colors. Every role has a light and dark value.

What is the -foreground convention?

Most base roles pair with a -foreground role for the text or icons placed on that surface: --primary with --primary-foreground. The pairing guarantees legible contrast in both light and dark without guesswork.

How do I export a full semantic token set?

Every Identity Forge kit exports its 28 roles (light + dark) as CSS variables, Tailwind v3/v4 @theme, a shadcn registry item, or DTCG/W3C JSON. For shadcn/ui, npx shadcn add https://identityforge.io/r/<slug>.json installs them directly.