How Hallmark’s OKLCH Color System Works (and Why It Replaces Hex/HSL)
Hallmark defines every UI color with OKLCH values stored as CSS custom properties, enabling perceptually uniform themes with reliable contrast and runtime theme switching.
The Hallmark design system, developed in the Nutlope/hallmark repository, uses OKLCH as its sole color format. This modern color space powers a token-based architecture where themes like cobalt, hum, and lumen declare complete palettes through CSS custom properties. Unlike traditional hex or HSL values, OKLCH aligns with human vision, making contrast predictable and theme maintenance scalable.
What Is OKLCH and How Hallmark Implements It
OKLCH represents colors using three components: Lightness (L), Chroma (C), and Hue (H). In Hallmark, every color token is stored as an OKLCH value inside site/css/tokens.css, wrapped in theme-specific data attributes.
/* From site/css/tokens.css — Cobalt theme excerpt */
[data-theme="cobalt"] {
--color-paper: oklch(96% 0.018 80);
--color-ink: oklch(20% 0.012 250);
--color-accent: oklch(55% 0.14 255);
/* 20+ additional tokens per theme */
}
Components consume these tokens via var() references, never hard-coded values. This "Locked tokens" rule (documented in skills/hallmark/references/anti-patterns.md) forbids inline hex or HSL from appearing in generated markup.
Why OKLCH Is Preferred Over Hex and HSL
The Hallmark system explicitly rejects hex and HSL for five technical reasons grounded in perceptual color science.
Perceptual Uniformity Enables Reliable Contrast
OKLCH separates Lightness, Chroma, and Hue in a space matching human vision. Lightness values compare directly: oklch(60% ...) is visibly half as bright as oklch(90% ...). This linearity fails in HSL, where identical "Lightness" percentages produce vastly different perceived brightness across hues.
The skills/hallmark/references/color.md file documents how this property simplifies WCAG 2.1 contrast pre-checks using simple lightness deltas.
Predictable Lightness Prevents Unintentional Shifts
Adjusting Chroma or Hue in OKLCH does not accidental alter perceived brightness. In HSL, saturating a blue or manipulating yellow hue can darken or lighten the color unexpectedly.
Hallmark relies on this stability to guarantee that -color-paper remains a readable background across all theme variants, avoiding the "black-on-black" bugs caught by automated gates.
Consistent Hue Across Tints
The Hue (H) value stays constant for every shade of a color family. A brand accent at oklch(... 0.18 95) shares hue 95 with its lighter and darker variants, preserving recognizability.
This consistency enables Hallmark's strict "no pure #fff / #000" rule (see skills/hallmark/references/anti-patterns.md). Even "white" and "black" are slightly tinted OKLCH values, maintaining visual harmony.
Simple Math for Automated Contrast Checks
The slop-test OKLCH pre-check (documented in skills/hallmark/references/slop-test.md) uses lightness deltas as a fast accessibility filter:
// Pseudo-code from the slop-test implementation
function likelyFailsWCAG(color1, color2) {
const L1 = parseOKLCH(color1).lightness; // e.g., 0.96
const L2 = parseOKLCH(color2).lightness; // e.g., 0.20
return Math.abs(L1 - L2) < 0.50; // 76% difference = likely pass
}
Hex and HSL require full conversion to a perceptual space before such calculations work.
Future-Proof Token Architecture
Tokens declared once in site/css/tokens.css propagate everywhere through CSS variables. Adding a theme requires only a new [data-theme="..."] block with 20–30 OKLCH definitions:
/* Defining a custom OKLCH palette per skills/hallmark/references/custom-theme.md */
[data-theme="my-custom"] {
--color-paper: oklch(94% 0.005 60); /* warm off-white */
--color-ink: oklch(20% 0.012 250); /* deep blue-black */
--color-accent: oklch(68% 0.18 95); /* amber brand color */
}
Runtime theme switching requires zero JavaScript bundling changes:
<html data-theme="cobalt">…</html>
<script>
// Instant palette swap without page reload
document.documentElement.dataset.theme = 'hum';
</script>
How Hallmark Enforces OKLCH-Only Usage
The repository contains multiple enforcement mechanisms:
site/css/tokens.css— Source of truth for 20+ complete OKLCH themesskills/hallmark/references/anti-patterns.md— Explicit ban on inline hex/HSL valuesskills/hallmark/references/slop-test.md— Automated OKLCH contrast pre-checks in CIskills/hallmark/references/custom-theme.md— OKLCH palette generation workflow for new briefs
No component imports a raw color value. The token system guarantees that rotating themes, enforcing contrast, and preventing mid-render improvisations happen without manual updates to hundreds of hard-coded values.
OKLCH vs. Hex/HSL: Quick Comparison
| Dimension | Hex | HSL | OKLCH |
|---|---|---|---|
| Lightness perception | Non-linear, unpredictable | Angle-based, inconsistent | Perceptually uniform |
| Hue consistency across saturation | N/A | Shifts with lightness changes | Stable |
| Contrast calculation | Requires conversion | Requires conversion | Direct L delta |
| Human-readable adjustment | Impossible | Partial | Intuitive (L/C/H) |
| Theme maintainability | Fragmented | Fragmented | Centralized tokens |
Practical Implementation Example
/* Consumption: always via var(), never raw OKLCH */
.article-card {
background: var(--color-paper);
border: 1px solid var(--color-ink-weak);
color: var(--color-ink);
}
.article-card:hover {
background: var(--color-paper-hover); /* same hue, adjusted L */
}
// Runtime theme rotation
const themes = ['cobalt', 'hum', 'lumen', 'ink'];
let current = 0;
setInterval(() => {
current = (current + 1) % themes.length;
document.documentElement.dataset.theme = themes[current];
}, 5000);
Summary
- Hallmark defines all colors as OKLCH values in CSS custom properties within
site/css/tokens.css - Perceptual uniformity makes lightness directly comparable, enabling reliable contrast and automated accessibility checks
- Predictable lightness and stable hue prevent the unpredictable shifts common in hex and HSL
- The "Locked tokens" rule enforces OKLCH-only usage, banning inline hex/HSL from generated markup
- Runtime theme switching works through data attributes, with zero bundling changes required
Frequently Asked Questions
What makes OKLCH more accessible than HSL for web design?
OKLCH's Lightness (L) channel correlates directly with perceived brightness, unlike HSL's Lightness which varies dramatically across hues. This allows Hallmark's slop-test to pre-calculate contrast using simple subtraction (|L₁ - L₂|), catching WCAG failures before visual review. HSL requires expensive color space conversions to achieve the same accuracy.
Can I mix OKLCH with hex or HSL in a Hallmark project?
No. The skills/hallmark/references/anti-patterns.md documentation explicitly prohibits inline hex and HSL values. All colors must route through the token system in site/css/tokens.css. This ensures themes remain switchable and contrast checks remain valid across the entire UI.
How do I create a custom OKLCH theme for Hallmark?
Define a new [data-theme="..."] block in site/css/tokens.css with OKLCH values for the 20+ required tokens (--color-paper, --color-ink, --color-accent, etc.). The skills/hallmark/references/custom-theme.md file provides a generation workflow that preserves hue relationships and maintains the "no pure white/black" rule through careful L and C adjustments.
Does using OKLCH affect browser support or performance?
OKLCH is supported in all modern browsers. For Hallmark's token-driven architecture, the CSS custom property layer abstracts away any syntax concerns—components reference var(--color-paper), not raw OKLCH. The build process handles any necessary fallbacks, and runtime theme switching incurs no JavaScript performance penalty beyond a single attribute mutation.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →