# How Hallmark's Token System Works with OKLCH Color Spaces

> Discover how Hallmark's token system uses OKLCH color spaces to enable instant theme switching across 24 palettes by updating a single attribute.

- Repository: [Hassan El Mghari/hallmark](https://github.com/Nutlope/hallmark)
- Tags: deep-dive
- Published: 2026-08-06

---

**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](https://github.com/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`](https://github.com/Nutlope/hallmark/blob/main/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:

```css
[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`](https://github.com/Nutlope/hallmark/blob/main/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`](https://github.com/Nutlope/hallmark/blob/main/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`](https://github.com/Nutlope/hallmark/blob/main/site/js/main.js) (lines 546–548), the `setTheme()` function updates the `<html>` element:

```javascript
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`](https://github.com/Nutlope/hallmark/blob/main/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`](https://github.com/Nutlope/hallmark/blob/main/tokens.css) before they can be referenced, preserving architectural integrity.

## Using Tokens in Components

Component styles reference tokens abstractly, remaining theme-agnostic:

```css
.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`](https://github.com/Nutlope/hallmark/blob/main/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`](https://github.com/Nutlope/hallmark/blob/main/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`](https://github.com/Nutlope/hallmark/blob/main/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`](https://github.com/Nutlope/hallmark/blob/main/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`](https://github.com/Nutlope/hallmark/blob/main/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`](https://github.com/Nutlope/hallmark/blob/main/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.