# How Hallmark Enforces OKLCH Color Usage Over Hex and RGB: A Token-Based Design System

> Learn how Hallmark enforces OKLCH color usage with a five-layer system and token-based design. Discover how it rejects hex, RGB, and HSL for consistent color implementation.

- Repository: [Hassan El Mghari/hallmark](https://github.com/Nutlope/hallmark)
- Tags: how-to-guide
- Published: 2026-07-21

---

**Hallmark enforces OKLCH-only color usage through a rigorous five-layer system that mandates all colors exist as CSS custom properties in [`tokens.css`](https://github.com/Nutlope/hallmark/blob/main/tokens.css), references them exclusively via `var(--token-name)`, and rejects any inline hex, RGB, or HSL values through automated validation gates.**

The Nutlope/hallmark repository implements a strict OKLCH color discipline that eliminates hex and RGB literals from generated CSS. By combining centralized design token architecture with automated slop-tests, Hallmark ensures every color value adheres to perceptually uniform OKLCH standards while preventing mid-render improvisation.

## The Five-Layer Enforcement Architecture

Hallmark’s enforcement strategy operates through distinct architectural layers, each targeting a specific vector where non-OKLCH values might enter the system.

### 1. Design Token Definition in tokens.css

All color values originate in [`site/css/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css), where every theme declares its palette using OKLCH literals exclusively. The file header explicitly establishes this constraint:

> "Twenty-four themes. Each occupies a distinct point in **OKLCH** space."

Each theme defines colors as CSS custom properties using the `oklch()` functional notation:

```css
/* site/css/tokens.css */
:root {
  --color-paper: oklch(96% 0.01 250);
  --color-ink: oklch(18% 0.02 250);
  --color-accent: oklch(55% 0.12 120);
}

```

This centralization ensures that hex codes (`#ffffff`) and RGB values (`rgb(0,0,0)`) never enter the system at the source.

### 2. Canonical Rule Documentation

The design philosophy is codified in [`skills/hallmark/references/color.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/color.md), which documents the **OKLCH-only** mandate:

> "**OKLCH only.** Perceptually uniform; predictable lightness; consistent hue across tints. `hsl()` and `rgb()` lie about brightness."

This reference serves as the authoritative specification for why the system rejects HSL and RGB color spaces, citing their non-linear lightness curves and inconsistent perceptual brightness across hues.

### 3. Token-Locking and Anti-Patterns

Hallmark explicitly forbids inline color declarations through its anti-pattern documentation in [`skills/hallmark/references/anti-patterns.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/anti-patterns.md). The **token-locking** rule states:

> "Every colour and every font in the artifact must come through `var(--token-name)`. Inline OKLCH or one-off hex values mid-render are not allowed."

If a required color does not exist in the token block, developers must **add it to `:root` first** rather than inserting literal values into component CSS. This prevents "mid-render token improvisation," where developers might otherwise paste hex codes directly into style rules during development.

### 4. Automated Validation: Slop-Test Gate 48

During the build validation phase, Hallmark runs a series of slop-test gates. **Gate 48** specifically scans generated CSS and HTML for any color declaration that violates the token system:

- Literal hex values (`#...`)
- RGB/RGBA functions (`rgb(...)`, `rgba(...)`)
- HSL/HSLA functions (`hsl(...)`, `hsla(...)`)
- Inline OKLCH values not referenced via `var()`

If Gate 48 detects any non-token color values, the build fails and reports the offending line. This automated enforcement operates according to the validation rules documented in [`site/_tests/verbs/redesign/notes.md`](https://github.com/Nutlope/hallmark/blob/main/site/_tests/verbs/redesign/notes.md) and referenced in the anti-patterns guide:

> "Mid-render token improvisation – Inline OKLCH or one-off hex values are not allowed. The fix: lift the value into the token block as a new named variable, then reference it."

### 5. SKILL.md Specification

The central specification in [`skills/hallmark/SKILL.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md) reinforces token locking at the architectural level:

> "Locked tokens — no mid-render improvisation. ... Inline OKLCH or hex values are not allowed."

This specification mandates that once a theme is selected, **every** `color` and `font-family` declaration must reference a named token (`var(--color-accent)`). Any literal values trigger a gate failure, ensuring consistency across all generated artifacts.

## Practical Implementation Examples

### Correct: Token-First Workflow

Define the color in your theme's token file:

```css
/* site/css/tokens.css */
:root {
  --color-highlight: oklch(70% 0.15 45);
}

```

Reference the token in component styles:

```css
.card {
  background: var(--color-paper);
  color: var(--color-ink);
  border: 2px solid var(--color-accent);
}

.highlight {
  background: var(--color-highlight);
}

```

### Incorrect: Gate 48 Failure

The following patterns will cause the build to fail at Slop-test Gate 48:

```css
/* ❌ Rejected: Hex literal */
.card {
  background: #ffffff;
}

/* ❌ Rejected: RGB literal */
.text {
  color: rgb(0, 0, 0);
}

/* ❌ Rejected: Inline OKLCH without token */
.border {
  border-color: oklch(55% 0.1 200);
}

```

### Handling Missing Colors

When you need a new color that doesn't exist in the token block:

1. Add the OKLCH value to [`tokens.css`](https://github.com/Nutlope/hallmark/blob/main/tokens.css) first:

```css
:root {
  --color-success: oklch(65% 0.18 145);
}

```

2. Then reference the new token:

```css
.button-success {
  background: var(--color-success);
}

```

## Summary

Hallmark enforces OKLCH color usage through architectural constraints rather than optional conventions:

- **Centralized tokens**: All colors originate in [`site/css/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css) as OKLCH literals
- **Documentation mandates**: [`skills/hallmark/references/color.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/color.md) establishes the OKLCH-only rule
- **Anti-pattern prevention**: [`skills/hallmark/references/anti-patterns.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/anti-patterns.md) forbids mid-render improvisation
- **Automated gates**: Slop-test Gate 48 scans for hex, RGB, and HSL literals during validation
- **Specification lock**: [`skills/hallmark/SKILL.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md) requires all colors reference tokens via `var()`

This multi-layer approach ensures perceptually uniform color spaces throughout the design system while eliminating the brightness inconsistencies inherent to hex and RGB values.

## Frequently Asked Questions

### What happens if I accidentally use a hex code in Hallmark?

The build will fail at Slop-test Gate 48, which scans generated CSS for non-token color literals including hex codes, RGB values, and HSL functions. The validation system reports the specific line containing the violation, requiring you to move the color value into [`site/css/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css) as a named token before the build will pass.

### Why does Hallmark reject HSL in addition to hex and RGB?

According to [`skills/hallmark/references/color.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/color.md), HSL and RGB "lie about brightness" because they do not account for perceptual uniformity. OKLCH maintains consistent perceived lightness across different hues, while HSL lightness values produce visually uneven brightness when comparing colors like yellow and blue at the same lightness percentage.

### Can I use inline OKLCH values if I don't want to create a token?

No. Hallmark treats inline OKLCH values as a gate failure just like hex codes. The anti-pattern documentation in [`skills/hallmark/references/anti-patterns.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/anti-patterns.md) explicitly states that "inline OKLCH or one-off hex values are not allowed." Even if the color uses the OKLCH color space, it must be defined in [`tokens.css`](https://github.com/Nutlope/hallmark/blob/main/tokens.css) and referenced via `var(--token-name)`.

### How do I add a new color to a Hallmark theme?

First, define the color as an OKLCH value in [`site/css/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css) (or the specific theme's tokens file) within the `:root` block. Then reference that custom property using `var(--your-color-name)` in your component CSS. This workflow prevents mid-render improvisation and ensures all colors remain centralized and maintainable.