How to Use Semantic Color Tokens

How to Use Semantic Color Tokens. A real In review status header, paired with an editorial semantic-role mapping rather than inferred implementation token names.

Your brand uses green. The primary button is green, the success message is green, and the selected navigation item is green. Everything looks coordinated until the brand changes to purple. Should a successful upload turn purple too? What about the focus outline or the warning beside an expiring account?

Semantic color tokens make those decisions explicit. A primitive token names a color value, such as green-700. A semantic token names its job, such as action-primary-background or status-success-text. Components refer to the job so that a brand update can change the intended roles without accidentally changing every use of a similar shade.

Start with the mistake you want to prevent

Imagine a workspace with a “Create project” button, a “Saved” confirmation, an error message, and a selected sidebar link. The original designer chose the same dark green for the button, confirmation, and selected link. A developer reasonably stored that value once and reused it. Now a new brand direction requests a different primary color.

Changing the shared green variable updates all three elements. The implementation is consistent with the original code, but the decision is wrong: the confirmation was green because it communicates success, not because it represents the brand’s main action. That distinction existed in the designer’s head and never reached the reusable rules.

Before adding tokens, write down that distinction in plain language. “The main action follows the product brand. Success feedback keeps its status meaning. Selection needs a clear active state.” These statements are more valuable than starting with a naming convention, because they tell you which values may safely travel together.

How Atlassian makes the role visible in the interface

Atlassian’s color guidance maps a Jira board to tokens for selection, text and a brand button background. Its vocabulary distinguishes color roles from emphasis and interaction state. It also treats selection and keyboard focus separately: a selected element should retain its selected treatment when a focus indicator is added.

Atlassian published Jira board screenshot annotated with tokens for a selected navigation item, subtle text and a brand button background.

Notice why an annotated interface is more useful than a palette by itself. A swatch can tell you its value. The board shows which part of the experience should consume that value and why. You can inspect whether the label refers to text, a surface or an icon rather than infer the intended use from how saturated the color looks.

For a small system, borrow that habit before borrowing the entire naming inventory. Place the proposed token beside a real use, describe what would cause it to change, and show one use it should not control. “Brand action” and “successful operation” can start as the same green while remaining independent decisions. If your map cannot express that distinction, it is storing a palette rather than the interface’s semantics.

Make the dependency test concrete

A small alias map is enough to expose the mistake. In this illustrative mapping, success and the primary action begin with the same value but refer to separate roles:

:root {
  --palette-green-700: #236646;
  --palette-purple-700: #6439a8;
  --action-primary-bg: var(--palette-green-700);
  --action-primary-fg: #fff;
  --status-success-text: var(--palette-green-700);
}
[data-brand="purple"] {
  --action-primary-bg: var(--palette-purple-700);
}

Changing the brand attribute should alter consumers of --action-primary-bg. It should not alter a success label that consumes --status-success-text. If both change, inspect the actual component references before choosing a new shade. If neither changes, check for a hardcoded color or a more specific override. This is a dependency test; the illustrative values still need contrast checks in their real contexts.

Next, test the foreground with the background. An action surface and its label are a pair. Updating only the surface can make a previously readable label fail, especially when a lighter brand replaces a dark one. Document the paired role in the map so that changing one starts a review of the other instead of relying on the reviewer to remember it.

Check the migration in three passes:

  1. Keep the values unchanged. Introduce the aliases and compare the visual baseline. Unexpected differences suggest mapping errors.
  2. Change one role temporarily. Inspect all intended consumers, including elements that should stay unchanged.
  3. Restore the approved theme. Review hover, focus, disabled, and selected combinations. Record deliberate raw values separately from unfinished migration work.
A token name is a promise about change.

Two uses can share a value today and still need different roles. Combine them only when changing one should intentionally change the other.

Separate values, roles, and component decisions

A small system can begin with two layers. The value layer holds the actual colors. The role layer maps those values to interface purposes. A third, component-specific layer is useful when an individual component needs to evolve independently, but it is not mandatory for every small project.

For example, neutral-950 might hold your darkest neutral. Both text-primary and border-strong could initially point to it. They remain different roles because improving body-text readability should not necessarily darken every strong border. Identical values today do not prove that two decisions should share a name forever.

The opposite mistake is creating a unique token for every visible element. If all ordinary body paragraphs serve the same role, giving each paragraph its own text token adds maintenance without adding meaning. A useful question is: would we ever intentionally change one of these uses without changing the other? If the answer is yes, consider separate roles. If the answer is no, reuse the existing role.

Layer Example What it answers
Primitive green-700 Which value is available?
Semantic status-success-text What does this color do?
Component, when needed toast-success-icon Which part needs independent control?

Names should help someone choose correctly without opening every component. A developer looking for an input error border should not have to guess whether accent-strong, special-red, or brand-secondary means danger. Prefer an understandable role over a clever abbreviation, especially when the same context will be used by a coding agent.

The green-700 primitive maps separately to action-primary-background for Create Project and status-success-text for Changes saved.

Map semantic colors to interface roles

Start by inspecting a representative page in several states. A static screenshot of the default dashboard will not reveal disabled actions, validation feedback, keyboard focus, or a selected menu item. You need enough states to discover actual color jobs, not every theoretical state a large organization might someday support.

For the fictional workspace, the first map can cover page background, raised surface, primary text, secondary text, ordinary border, primary action, text on that action, selection, focus, success, warning, and error. Some roles need a foreground and a background pair. A pale success surface and its dark text are different values with a shared purpose.

The first review is a mapping exercise. Mark each visible color on the example page and ask what it communicates. If a pale green panel merely groups related controls, it belongs to a surface or grouping role. If it announces a successful operation, it belongs to feedback. Those uses may look similar, but their future changes should follow different rules.

Keep the written description beside the token name. “Primary action background: the most important available action in a section” is more useful than just “green.” Include a contrasting example if confusion is likely: the token does not mean “any element we want people to notice.” An important error message still needs the appropriate feedback treatment.

Work through a brand change before you commit

Here is a deliberately small example. The workspace begins with a green brand action and green success feedback. Later, the action color changes to a different brand hue. You want the button and selected navigation treatment to follow the new direction, while “Saved” keeps its recognizable success role.

First, identify the roles affected by the brand decision. The button background and its foreground text need review together. Selection may use a separate brand-derived surface or indicator. The logo is a brand asset, not an ordinary button token. Do not recolor it through a general interface rule without considering its own asset requirements.

Next, change the role mappings in a copy of the page. Do not search for every occurrence of the old hex value and replace it indiscriminately. A raw-value search is useful for finding candidates, but it cannot tell you whether a particular occurrence represents a link, a success state, or an illustration detail.

Finally, inspect all consumers of the changed roles. The primary action might appear on a white page, a pale panel, and inside a dialog. A new fill that looks strong in one context may disappear into another. The mapping change is complete only when its intended uses still communicate the right action and remain readable.

Interface element Intended behavior during the example brand change
Create project button Review the action background and foreground pair
Selected sidebar item Review the selection treatment independently
Saved confirmation Preserve the success role unless feedback is also being redesigned
Invalid email message Preserve the error role and its explanatory text
Logo artwork Follow the approved brand asset, not a generic interface substitution

Specify states without creating a color for everything

An action’s default appearance is only one part of its behavior. Hover, pressed, focused, selected, and disabled can express different things. A navigation item can remain selected while it also receives keyboard focus. A button can be focused without being pressed. Avoid collapsing all those conditions into a single “active” color.

Start with the information each state must communicate. Hover indicates a pointer relationship. Focus tells a keyboard user where interaction will happen. Selection identifies a persistent choice. The visual treatments may share ingredients, but they must remain distinguishable when states occur together. A border, underline, icon, or shape can carry part of the message.

For the example sidebar, you might use a subtle selection background plus a clear focus outline. The outline should not disappear just because the item is already selected. Review that combined state directly. Looking at isolated swatches cannot show whether the two treatments interfere in the actual component.

Disabled styling deserves equal care. A disabled action needs an explanation when the user cannot infer why it is unavailable. Turning a button grey does not communicate whether a required field is missing, a permission is absent, or an operation is already running. A token names a visual role; it cannot replace the interaction logic or the explanatory copy.

Keep component-specific exceptions visible. If a destructive confirmation needs a distinct button treatment, document its purpose rather than silently replacing the primary-action token inside one dialog. The exception may be legitimate. The problem begins when nobody can tell whether it is intentional or a one-off implementation shortcut.

Pair color with readable meaning

Color makes an interface easier to scan, but meaning must survive when the hue is difficult to distinguish. A red border alone leaves users to infer what went wrong. An error label and a useful correction message make the state understandable. Similarly, a success icon accompanied by “Changes saved” communicates more than a green dot without a label.

The W3C guidance on use of color explains the requirement not to rely on color alone to convey information or identify an action. Apply that principle to each role in context. For this workspace, status messages receive readable text, selected items retain a visible selection treatment, and links remain identifiable beyond a subtle hue difference.

Contrast is a separate check. A color can communicate the right meaning and still be too faint to read. Evaluate foreground and background pairs rather than assigning a blanket “accessible” label to a brand swatch. A dark foreground on a light success surface is a different combination from white text on a saturated success button.

For normal text, WCAG’s minimum contrast criterion generally calls for 4.5:1, with 3:1 for qualifying large text and defined exceptions. The W3C contrast explanation gives the scope and details. Measure the actual pair and rendered use; passing one pair does not certify a component, theme, or complete site.

The earlier example values make this tangible. Calculating relative luminance for green #236646 and purple #6439a8 gives contrast ratios of 6.86:1 and 7.80:1 against white. Against black, the same fills give 3.06:1 and 2.69:1. Both fills therefore support the white label at the normal-text threshold, while neither supports black at that threshold. The semantic name does not establish this result: the specific foreground and background values do. Keep the calculation attached to that pair so a future lighter brand color triggers a fresh check.

Calculated contrast for the example green and purple fills: white text gives 6.86:1 and 7.80:1; black text gives 3.06:1 and 2.69:1.

Do not fix every failure by making the whole interface darker. Inspect which role failed, on which surface, and in which state. Secondary text still has a reading job. An overly pale helper message is not improved by calling it “subtle.” Conversely, turning every separator into a heavy dark line can erase the hierarchy the system was supposed to create.

Review a dark theme as a new mapping

A dark theme is a useful stress test because it separates purpose from appearance. Primary text still needs to be primary text, but its value changes. A raised surface still needs to be distinguishable from the page. Success feedback still needs to be understandable even if its background and foreground values are different from the light theme.

Do not simply invert each primitive or reuse the light-theme values against a dark page. Revisit the relationships. A bright action that felt balanced on white can dominate a dark surface. A border that was gently visible on a pale panel can vanish. Images, logos, and charts may require decisions outside the semantic color map as well.

Use the same content in both theme previews. Otherwise, differences in density or imagery can distract from the color decisions. Include a form error, a success message, a selected navigation item, a focused control, and some secondary text. These states create a more useful comparison than a gallery of attractive default buttons.

The role names should remain stable across the comparison. If you find yourself renaming text-primary to white-text in the dark theme, you are putting a value back into a name that was meant to describe a job. Keep the meaning constant and change the mapping that serves it.

Matching light and dark project-settings forms retain Save Changes and Changes saved roles while using theme-specific foreground, surface and status colors.

Give a coding agent the map, not just the palette

When you ask an agent to refine a page, include the role decisions alongside the visual reference. A screenshot shows the present colors. It does not explain which ones should remain coupled during a brand change or which state combinations must continue to work. A short mapping table and a representative component make that intention much easier to inspect.

In supported OpenDesign HTML previews, you can review the rendered result, use available manual style-editing controls, and attach comments to the relevant area for the conversation. Use those capabilities to point out a concrete mismatch, such as a success notice using the primary-action treatment. The feedback should name the intended role as well as the visible location.

For example, ask the agent to update the primary-action mapping while preserving success and error roles, then show the affected button uses in their different states. If your existing project already has token conventions, provide those files or design context. Avoid asking for an entirely new naming system as part of a small color correction.

After a visual correction, inspect the component reference in the generated files. The button may look right while still consuming the success token; the next theme change would expose the same dependency error.

Migrate one representative component first

You can introduce semantic roles without replacing the entire site in one pass. Choose a component with several meaningful states, such as the project-creation form. List its current values, decide the role of each, and map those roles to the existing palette. Initially, the visible design can remain almost unchanged.

Then change one role mapping as a controlled test. If primary actions are supposed to change together, verify that the intended buttons do. If status messages are supposed to remain independent, verify that they do not move with the action color. The test is about the dependency, not whether the temporary test color would be a good final brand choice.

Keep a record of consumers that still use raw values. Some will be deliberate: an illustration, a partner logo, or a data visualization may not belong to the same interface role. Others are migration work. Label the distinction so that the next person does not mistake an incomplete conversion for an approved exception.

Once the representative component behaves correctly, expand to related components. Review the rendered page after each meaningful group rather than trusting a global replacement. Shared rules can affect contexts you did not have open. A small migration gives you a chance to find those contexts before the entire interface is harder to compare.

What a useful token review should leave behind

The final review should leave a map someone else can use: role names, their intended purposes, current values by supported theme, and a few representative components showing how they behave. Add notes where a role must be paired with another, such as text on an action background. Record meaningful exceptions without turning every pixel into a separate policy.

Ask a teammate to choose the token for a new success message and a new primary action using that map. If they choose correctly without guessing from the swatches, the system is doing useful work. If both choices still lead to “use the brand green,” clarify the role descriptions before adding more tokens.