# Turn Website Color Roles Into Reusable Design Tokens

[Open the live Fudge conversation](https://design.withfudge.com/share/turn-website-color-roles-into-reusable-design-tokens)

Last updated: 2026-08-25

Turn website colors into reusable design tokens by first identifying each color's job, then grouping related shades into named roles instead of saving isolated hex values. A practical token set should explain where a color belongs, how strong it is, and which accessible alternatives to use when the same role appears on different surfaces.

## Start with roles, not hex codes

Begin with a role map for the interface:

- `color.text.primary` for the main reading color
- `color.text.muted` for supporting copy and metadata
- `color.surface.canvas` for the page background
- `color.surface.raised` for cards, panels, and inputs
- `color.border.subtle` for low-emphasis separators
- `color.action.primary` for the main button or link
- `color.action.primary-hover` for interaction feedback
- `color.state.success`, `warning`, and `danger` for status messages

This prevents a common mistake: naming tokens after their current appearance, such as `green-700`, when the real requirement is usually `button-primary` or `success-text`. A named role can stay stable even when the visual palette changes.

Open the examples below and compare the first screen before borrowing a pattern. The captured Pangram example is associated with a muted green direction, while the color list includes dark greens, medium greens, gray-green neutrals, and a lighter green-gray. Treat those colors as observations to classify, not as a finished token system.

## Captured pages

[![Pangram AI Detector](https://pin.fontofweb.com/9687?format=jpg)](https://design.withfudge.com/share/pin-9687)

[Pangram AI Detector](https://design.withfudge.com/share/pin-9687)

## Colors

- `#496c10`
- `#15502e`
- `#14532d`
- `#233f2a`
- `#254f1a`
- `#1e6f30`
- `#295631`
- `#556659`
- `#4a5a4a`
- `#2c7a4a`
- `#2a966f`
- `#799c92`

## Build a small token ladder

For each important role, create a limited ladder rather than assigning every observed shade a separate name. A useful structure is:

```css
:root {
  --color-brand-700: #15502e;
  --color-brand-600: #1e6f30;
  --color-brand-500: #2c7a4a;
  --color-brand-300: #2a966f;
  --color-brand-100: #799c92;

  --color-text-primary: /* verify against the page surface */;
  --color-text-muted: /* verify at the smallest text size */;
  --color-surface-canvas: /* inspect the page background */;
  --color-border-subtle: /* inspect repeated separators */;

  --color-action-primary: var(--color-brand-700);
  --color-action-primary-hover: var(--color-brand-600);
}
```

The exact assignments above are a starting illustration based on the supplied observed palette, not a claim about an official internal system. Check every proposed assignment against the actual component and background where it appears. If several dark greens serve the same purpose, keep the strongest candidate and document the others as alternatives or context-specific tones.

## Check usage before exporting

A color's frequency does not prove its role. A common dark shade may be body text, navigation, or a large illustration. A rare bright shade may be the only meaningful action color. Review colors alongside page structure and component usage, then test:

1. Does text remain readable on its surface?
2. Does the action color stand apart from surrounding content?
3. Does hover or focus feedback remain visible without relying on color alone?
4. Do success and danger states remain distinguishable for people with color-vision differences?
5. Can the role work in both light and dark surfaces, or does it need a paired token?

Keep semantic tokens separate from raw palette tokens. For example, `--color-brand-700` is a palette value, while `--color-action-primary` is a decision about use. That separation makes later redesigns safer.

## Make the token file usable

For a handoff, include the token name, value, intended use, contrast notes, and replacement guidance. A compact JSON shape works well:

```json
{
  "color.action.primary": {
    "value": "{color.brand.700}",
    "use": "Primary buttons and key actions",
    "hover": "{color.brand.600}",
    "onColor": "#ffffff",
    "check": "Verify contrast on every button surface"
  }
}
```

Do not confuse an extracted palette with ownership of an official design system. The observed colors can help you recreate a direction, but your team still needs to confirm naming, contrast, states, themes, and component rules before adopting the tokens across a product.

## Use this in your AI agent

> Inspect the saved website reference, group its observed colors into semantic roles, separate raw palette tokens from component tokens, flag uncertain assignments, check text and action contrast, and return a compact CSS and JSON token draft with usage notes. Do not treat frequency alone as proof of a role.

[Install Fudge for your AI agent](/mcp) to reuse this prompt while comparing saved website references.

---

Choose roles by combining three signals: where the color appears, what it does in the interface, and whether it remains readable in that context. Start with the largest repeated jobs: page background, main text, supporting text, borders, primary action, secondary action, and status states.

Use the darkest repeated neutral or tinted shade for primary text only if it works on the main surface. Use a lighter gray-green for muted text only after checking that small text remains readable. A medium or saturated color is a stronger candidate for actions when it appears on buttons, links, active controls, or selected states. Do not assign a color to a state role just because it looks green, amber, or red. Confirm that the surrounding message or icon also communicates the state.

Keep near-duplicates out of the first token pass. Pick one value for each role, record the alternatives, and test them in real components. If two shades have different jobs, name the jobs directly, such as `action-primary` and `surface-accent`, rather than inventing arbitrary numeric labels. Then add hover, pressed, focus, and disabled variants only where the interface demonstrates a meaningful change.

---

Use this five-step workflow:

1. **Create a raw palette.** Store each observed hex value with its source reference and a short note. Keep this layer unchanged so you can trace later decisions.
2. **Assign semantic roles.** Map only the colors you can explain: text, surfaces, borders, actions, links, and states. Mark uncertain mappings instead of hiding them.
3. **Add component aliases.** Point button, input, card, badge, and navigation tokens to semantic roles. This avoids repeating hex values throughout component styles.
4. **Test combinations.** Check normal and large text, icons, borders, buttons, focus indicators, hover states, and disabled states on every relevant surface. Recheck any role that changes in dark mode.
5. **Export with notes.** Deliver CSS variables or JSON alongside a short table that explains each token, its intended use, its contrast result, and its fallback.

Before merging, ask a designer or engineer to review names and confirm that the tokens describe decisions rather than temporary screenshots. A token file is ready when another person can use it without reopening the reference to guess what each value means.

## Related questions

- [Turn a Website Gradient Palette Into Reusable Design Tokens](/share/turn-website-gradient-palette-into-reusable-design-tokens)
- [How to analyze accessible CTA colors on a live website](/share/analyze-accessible-cta-colors-on-a-live-website)
- [Turn Text and Background Contrast Into Reusable Design Tokens](/share/turn-text-and-background-contrast-into-reusable-design-tokens)
- [Analyze a Dark Mode Color Palette on a Live Website](/share/analyze-dark-mode-color-palette-on-a-live-website)
