How Hallmark's Token System Works with OKLCH Color Spaces

Hallmark stores every UI color as a design token—a CSS custom property expressed in the perceptually-uniform OKLCH color space—enabling instant theme switching across 24 palettes by updating a single data-theme attribute on the <html> element.

All colors in the Hallmark design system are defined as tokens rather than raw color values. This architecture, implemented in the Nutlope/hallmark repository, uses OKLCH exclusively to guarantee perceptual consistency and uniform lightness scaling across themes.

The Token Architecture in tokens.css

The central token file site/css/tokens.css establishes a single source of truth for all colors. Base tokens are declared under :root, then overridden for each theme using [data-theme="…"] selectors.

Consider the Cobalt theme definition:

[data-theme="cobalt"] {
  --color-paper:  oklch(98.5% 0.004 250);
  --color-accent: oklch(58%   0.20  256);
  --color-ink:    oklch(25%   0.02  250);
  --color-rule:   oklch(85%   0.01  250);
}

Every component consumes these tokens via var() references. No hex, rgb(), or hsl() values appear in component stylesheets—this is the locked token rule enforced by the system (see skills/hallmark/SKILL.md).

Why OKLCH Powers the Hallmark Token System

OKLCH separates color into three perceptually meaningful channels:

  • L (lightness) – Perceptually uniform from 0% to 100%
  • C (chroma) – Color intensity, independent of lightness
  • H (hue) – Angle on the color wheel

This separation lets Hallmark place each theme at a distinct coordinate in color space. Lightness scales uniformly—doubling the L value genuinely doubles perceived brightness. Hues remain consistent when chroma changes, avoiding the muddy shifts common in HSL.

The skills/hallmark/references/color.md file documents why OKLCH is the exclusive color model: its perceptual uniformity ensures accessible contrast ratios and predictable visual relationships across all 24 themes.

Theme Switching via Data Attributes

Theme activation happens through a single DOM operation. In site/js/main.js (lines 546–548), the setTheme() function updates the <html> element:

function setTheme(name) {
  document.documentElement.dataset.theme = name;   // e.g., "cobalt", "hum", "ember"
}

// Event listener example
document.querySelector('[data-theme-btn="cobalt"]')
        .addEventListener('click', () => setTheme('cobalt'));

When data-theme changes, CSS cascade re-evaluation instantly applies the new [data-theme="…"] ruleset. Every var(--color-*) reference across the UI resolves to new OKLCH values without touching component CSS.

Token Discipline and Validation

Hallmark enforces token-only usage through a slop-test that runs at build time. As documented in skills/hallmark/references/slop-test.md (section 48), any color value found outside the token block triggers an error.

This validation guarantees that developers cannot bypass the system. New colors must be added to tokens.css before they can be referenced, preserving architectural integrity.

Using Tokens in Components

Component styles reference tokens abstractly, remaining theme-agnostic:

.card {
  background: var(--color-paper);
  border: var(--rule-card) solid var(--color-rule);
  color: var(--color-ink);
}

.button-primary {
  background: var(--color-accent);
  color: var(--color-paper);
}

The component knows nothing about cobalt, ember, or any specific theme—only semantic roles like "paper" (background), "ink" (text), and "accent" (interactive emphasis).

Extending the Token System

Adding a new theme requires only appending a [data-theme] block with OKLCH values. Since the entire UI is token-driven, the new palette applies everywhere immediately.

Theme-specific documentation in skills/hallmark/references/themes/ (e.g., cobalt.md) provides design rationale and precise OKLCH coordinates for reference.

Summary

  • Single source of truth: All colors defined as --color-* tokens in site/css/tokens.css
  • OKLCH exclusively: Perceptually-uniform color space enables consistent lightness and hue relationships
  • Theme switching: JavaScript updates data-theme on <html>; CSS cascade handles the rest
  • Locked token rule: Slop-test validation prevents raw color values in component CSS
  • Instant extensibility: New themes added by defining new [data-theme] blocks

Frequently Asked Questions

What is OKLCH and why does Hallmark use it?

OKLCH is a perceptually-uniform color space that separates lightness (L), chroma (C), and hue (H). Hallmark uses it because unlike HSL, OKLCH guarantees that changing one channel doesn't unpredictably affect perceived brightness or color identity—critical for maintaining accessible contrast ratios across 24 distinct themes.

How does theme switching work without reloading the page?

The JavaScript in site/js/main.js sets document.documentElement.dataset.theme to a theme name like "cobalt" or "hum". This attribute selector matches pre-defined rules in tokens.css, causing the browser to re-evaluate all var(--color-*) references instantly. No component styles are modified; only CSS custom property values change.

What prevents developers from using hardcoded colors?

Hallmark runs a slop-test (documented in skills/hallmark/references/slop-test.md) that scans all CSS for color values outside the token definitions. Any hex, rgb(), hsl(), or oklch() found in component styles fails the build, enforcing that all colors must be defined as tokens first.

Can I add custom themes to Hallmark?

Yes. Create a new [data-theme="customname"] block in site/css/tokens.css with OKLCH values for the required --color-* tokens. Because components only reference tokens abstractly, your new theme applies everywhere immediately without modifying any component code.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →