# Semantic Color Roles in Diagram Design’s Token System

> Discover semantic color roles like paper ink muted accent link and soft in Diagram Design. Ensure consistent theming accessibility and abstract visual properties across skins.

- Repository: [Cathryn Lavery/diagram-design](https://github.com/cathrynlavery/diagram-design)
- Tags: deep-dive
- Published: 2026-08-22

---

**Diagram Design uses six semantic color roles—`paper`, `ink`, `muted`, `accent`, `link`, and `soft`—to abstract visual properties from concrete hex values, ensuring consistent theming across light and dark skins while enforcing accessibility constraints.**

The cathrynlavery/diagram-design repository implements a constraint-based design system where **semantic color roles** replace arbitrary color values. These roles encode meaning rather than appearance, allowing diagrams to adapt to different themes while maintaining visual hierarchy and accessibility standards. The system is documented primarily in [`references/style-guide.md`](https://github.com/cathrynlavery/diagram-design/blob/main/references/style-guide.md) and enforced throughout the diagram generation pipeline.

## Core Semantic Color Roles

The token system defines a minimal, opinionated palette where each role corresponds to a specific visual function. According to [`references/style-guide.md`](https://github.com/cathrynlavery/diagram-design/blob/main/references/style-guide.md), the core roles are:

- **`paper`** — The base canvas background color used for pages, cards, and panels.
- **`ink`** — Primary text and line strokes; the default readable color for labels and edges.
- **`muted`** — Secondary text, subtle lines, and non-focus elements that require reduced emphasis.
- **`accent`** — The singular highlight color reserved for focal elements; limited to one per diagram by design constraints.
- **`link`** — Interactive elements and hyperlink text, distinct from standard ink to indicate clickability.
- **`soft`** — Optional low-contrast fills for decorative background washes that must remain legible in grayscale.

### Optional Extended Roles

Some skin implementations include additional roles for specific states:

- **`dim`** — Used for disabled or de-emphasized UI controls, typically a desaturated variant of `muted`.

## How Semantic Roles Enforce Design Constraints

The Diagram Design system uses semantic coloring to enforce editorial consistency. **Focal elements**—the single editorial focal node, step, or series in any diagram—automatically receive the `accent` role regardless of any explicit color property.

Custom color overrides are permitted only for non-focal elements and must still map to semantic roles rather than arbitrary hex values. This ensures that even "custom" colors respect the skin’s accessibility constraints and theme variables.

## Implementing Semantic Tokens in Diagram Definitions

Diagram definitions reference semantic roles through a JSON-like schema. The actual color values are supplied by the active skin file at render time.

```json
{
  "tokens": {
    "paper": "paper",
    "ink": "ink",
    "muted": "muted",
    "accent": "accent",
    "link": "link"
  },
  "nodes": [
    {
      "id": "api",
      "label": "API",
      "role": "ink"
    },
    {
      "id": "db",
      "label": "Database",
      "role": "muted",
      "color": "#5a7d9a"
    },
    {
      "id": "frontend",
      "label": "Frontend",
      "focal": true,
      "role": "accent"
    }
  ],
  "edges": [
    { "from": "frontend", "to": "api", "style": "link" },
    { "from": "api", "to": "db", "style": "muted" }
  ]
}

```

In this example, the `frontend` node uses `accent` because it is marked as focal, while the `db` node demonstrates how custom colors are specified as hex values that map to the semantic "concern" role without breaking the token system.

## Rendering and Skin Substitution

When generating HTML or SVG output, the renderer substitutes semantic tokens with concrete CSS variables defined in the active skin.

```html
<style>
  :root {
    --paper: #fefefe;
    --ink: #212121;
    --muted: #666666;
    --accent: #eb6c36;
    --link: #0066cc;
  }
</style>

<rect fill="var(--paper)" />
<text fill="var(--ink)">API</text>
<text fill="var(--muted)">Database</text>
<rect fill="var(--accent)">Frontend</rect>
<a href="#" style="color:var(--link)">Link</a>

```

This substitution layer allows the same diagram definition to render correctly in both light and dark modes by swapping the skin file without modifying the diagram structure.

## Source Files and Token Architecture

The semantic color system is distributed across several key files in the repository:

- **[`references/style-guide.md`](https://github.com/cathrynlavery/diagram-design/blob/main/references/style-guide.md)** — Defines the semantic token mapping and maps roles to concrete colors for both light and dark skins.
- **[`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md)** — Explains how the token system drives diagram generation and validates custom overrides against semantic roles.
- **Type-specific references** (e.g., [`references/type-process.md`](https://github.com/cathrynlavery/diagram-design/blob/main/references/type-process.md), [`references/type-sankey.md`](https://github.com/cathrynlavery/diagram-design/blob/main/references/type-sankey.md)) — Demonstrate concrete applications of roles, such as when `accent` is applied to focal steps or how `muted` colors non-focal ribbons.
- **Validation scripts** (e.g., [`verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-semantic-motion.py)) — Enforce constraints such as the single-accent-element rule and validate that all color references resolve to defined semantic roles.

## Summary

- **Six core roles** (`paper`, `ink`, `muted`, `accent`, `link`, `soft`) abstract color from meaning in the Diagram Design system.
- **Focal elements** automatically receive the `accent` role, ensuring a single visual hierarchy per diagram.
- **Skin files** in [`references/style-guide.md`](https://github.com/cathrynlavery/diagram-design/blob/main/references/style-guide.md) map semantic roles to concrete hex values, enabling theme switching without diagram edits.
- **Custom colors** are permitted only for non-focal elements and must still map to semantic concerns rather than arbitrary hues.
- **Rendering pipelines** substitute tokens with CSS variables at build time, supporting both light and dark modes.

## Frequently Asked Questions

### What is the difference between accent and custom colors?

The `accent` role is reserved exclusively for the focal element of a diagram—the single node or step that represents the editorial emphasis. Custom colors, specified as hex values on non-focal elements, map to semantic "concern" roles but do not override the `accent` designation. According to the source code, any explicit color on a focal element is ignored in favor of the `accent` token.

### How do I override colors for specific diagram elements?

Override colors by specifying a hex value in the `color` property of non-focal nodes or edges. These values are treated as semantic concerns rather than literal colors, meaning they must still conform to the contrast ratios defined in [`references/style-guide.md`](https://github.com/cathrynlavery/diagram-design/blob/main/references/style-guide.md). Focal elements cannot be overridden; they always render with the `accent` role.

### Where are the actual hex values for semantic roles defined?

Concrete color values are defined in [`references/style-guide.md`](https://github.com/cathrynlavery/diagram-design/blob/main/references/style-guide.md), which serves as the skin file for the Diagram Design system. This file maps each semantic role (e.g., `paper`, `ink`) to specific hex codes for both light and dark themes. The renderer substitutes these values during the build process.

### Can I add new semantic roles to the system?

The core semantic roles are fixed to maintain consistency across the diagram ecosystem. While you can define additional custom colors using hex values for specific concerns, introducing new semantic roles (such as a second accent color) would violate the design constraints enforced by validation scripts like [`verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-semantic-motion.py).