figma guide

Figma Color System: Semantic Tokens, Palettes, and Modes That Do Not Break

Build a Figma color system with base palettes, semantic tokens, light/dark modes, and contrast checks—so components stay themeable and handoff stays consistent.

Published
Updated
May 29, 2026
Read time
5 min
Level
Intermediate

Quick answer

A Figma color system has two layers: primitive palettes (brand blues, neutrals, status reds) and semantic tokens (surface/default, text/primary, border/subtle) that components actually use. Create primitives as color variables, alias semantics to primitives, then add modes (Light, Dark, High contrast) on the semantic collection—not on every button layer. Components bind to semantic tokens only; marketing one-offs are the rare exception. Validate contrast before publish, and pair this guide with variables & modes, dark mode workflow, and accessibility plugins. Start from the Figma guides hub if you are new to libraries.

Who this is for

  • Design system owners defining the first shared color collection.
  • Product designers tired of #F5F5F5 forks on every card.
  • Teams preparing Dev Mode handoff where CSS must map cleanly to token names (Dev Mode checklist).

Primitives vs semantic tokens

LayerExamplesWho uses it
Primitiveblue/500, gray/100, red/600System designers only
Semanticsurface/raised, text/secondary, border/focusAll product components
Component-specific (avoid)button-primary-bgOnly when truly unique

Verdict: if a product designer picks blue/500 for a card background, you will not ship dark mode without pain. They should pick surface/raised.


Build the primitive palette

Step 1: Choose scales

Most systems need:

  • Brand — 5–9 steps (50–900 naming or 100–900)
  • Neutral — 8–12 steps for surfaces and borders
  • Status — success, warning, error, info (4–5 steps each, or single + background pair)

Step 2: Create color variables

  1. Open your library file (file organization guide).
  2. Local variables panel → create collection primitive.
  3. Add variables color/blue/500, color/gray/100, etc.
  4. Paste hex from brand guidelines; document source of truth on the cover page.

Step 3: Sanity-check ramps

CheckWhy
Neighboring steps are visually distinctPrevents hover states that look identical
Text gray on white passes contrastAvoids retrofitting semantics later
Status colors work on both white and tinted surfacesError text on error background is a common fail

Use accessibility plugins on text/primary against surface/default early—not after 200 screens.


Semantic tokens and aliasing

Naming pattern

Use category / role / emphasis:

  • color/surface/default
  • color/surface/raised
  • color/text/primary
  • color/text/disabled
  • color/border/subtle
  • color/border/focus
  • color/icon/secondary

Alias primitives

In the semantic collection, set each variable to alias a primitive (e.g. surface/defaultgray/50 in Light mode). When brand blue shifts, you update one primitive, not forty screens.

Comparison: color styles vs variables (2026)

ApproachBest forLimitation
Variables + modesTheming, Dev Mode token namesLearning curve for aliases
Legacy color stylesOlder filesWeak mode story; migrate when touching file
Local fillsExploratory sketchDo not ship

Deep dive on modes: variables & modes designer-first.


Light, dark, and brand modes

  1. Keep primitives mode-free or duplicate only when brand truly differs per theme.
  2. Add modes on the semantic collection: Light, Dark (optional High contrast).
  3. For each semantic token, set mode values (dark surface/default aliases a deep neutral, not #000 on every layer).

Preview tricks: file mode switcher, prototype flows, and side-by-side frames—see dark mode design in Figma. Do not paint dark UI by manually inverting fills on instances.


Apply tokens to components

ElementBind to
Card backgroundcolor/surface/raised
Primary button fillcolor/action/primary or color/brand/default
Button labelcolor/text/on-primary
Input bordercolor/border/default
Focus ringcolor/border/focus

Publish components from the library; product files swap instances, never copy hex from the primitive panel.

Forms and states: error borders should use color/border/error, not ad hoc red—align with designing forms in Figma.


Color in Dev Mode and code handoff

Engineers need stable token names, not “Rectangle Fill #1A1A1A”.

  • Bind all production fills to semantic variables.
  • Document mode default on the cover (“App ships Dark; marketing ships Light”).
  • When tokens sync to code, align names with repo (surface.defaultcolor/surface/default).

For Git/token pipelines, see best dev handoff plugins and design system plugins.


Migration: from hex chaos to tokens

PhaseAction
1Freeze new screens without semantics
2Map top 20 fills to semantic tokens
3Update library components first
4Run swap on product files section by section
5Delete unused color styles after QA

Imported Sketch/Illustrator files often carry raw fills—clean with Illustrator import guide before tokenizing.


Common mistakes

MistakeSymptomFix
Semantic names that are hex (blue-500 on buttons)Dark mode breaksRename to role-based tokens
Too many primitivesDesigners grep 400 swatchesCap ramps; use aliases
Modes on primitives onlyComponents still hard-codedModes on semantics
Status color as text on same hue backgroundFails WCAGPair foreground/background tokens
Detached instances after rebrandRandom old bluesRe-link library + publish

FAQ

How many semantic tokens for v1?

20–35 semantics usually cover SaaS UI (surfaces, text, borders, actions, status). Add more when a second product line needs distinct action tokens—not before.

Should icons use text tokens?

Often yescolor/icon/secondary aliased separately so icon-only buttons can diverge from paragraph text without new primitives.

How does this relate to typography color?

Keep text color in semantic tokens; keep font metrics in text styles (typography guide). Avoid encoding color inside text style names unless your system spec requires it.

What about print or CMYK?

Screen tokens differ from print inks—use print checklist for bleed/PDF workflows; do not assume hex variables export to CMYK correctly.


Bottom line

Primitives hold brand; semantics hold meaning; modes hold theme. Components consume semantics only, contrast is checked on real pairs, and Dev Mode shows names engineers can ship. Next steps: dark mode tokens, Dev Mode handoff checklist, and the tutorials hub.

Share on X

§ Keep reading

Related guides.