# How to Configure Custom Themes with OKLCH Palettes in Hallmark

> Easily configure custom themes with OKLCH palettes in Hallmark. Generate a deterministic palette and font pairing by describing your brand's vibe. Learn how now.

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

---

**To configure a custom theme with OKLCH palettes in Hallmark, trigger the custom-theme protocol by requesting a bespoke design or providing an anchor colour, then describe your brand's vibe in 4-8 words to generate a deterministic palette and font pairing that writes inline CSS variables to your page's `:root`.**

Hallmark is a strict design system that enforces "slop-test" gates and chroma limits to prevent accidental visual noise. While the system ships with catalog themes stored in [`site/css/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css), it also exposes a **custom route** for generating one-off OKLCH colour palettes and free-font pairings tailored to specific brand briefs. This custom-theme protocol is implemented in [`skills/hallmark/references/custom-theme.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/custom-theme.md) and only activates when your brief signals a need for bespoke treatment.

## Triggering the Custom Theme Protocol

Hallmark detects the need for a custom theme through specific signals in your brief. The system switches from catalog rotation to custom generation when it encounters any of the following:

- An explicit request for a "custom" theme
- An anchor colour (hex, OKLCH, or named)
- A multi-attribute vibe description
- A brand-mood reference
- A structural vision requirement

When such a signal fires, Hallmark prompts for exactly one required input:

> *“Custom needs one input — describe the brand’s vibe in 4‑8 words. Optional: an anchor colour (hex/OKLCH/name).”*

If you provide an anchor colour, Hallmark converts it to OKLCH space and clamps the chroma to **0.12–0.20** according to the colour discipline defined in [`color.md`](https://github.com/Nutlope/hallmark/blob/main/color.md). If you omit the anchor, Hallmark derives the hue from your vibe keywords (warm tones map to **30–60°**, technical vibes to **220–250°**, etc.).

## The Three-Stage Custom Theme Pipeline

Once the custom route is engaged, Hallmark executes a deterministic three-stage pipeline documented in **Section B, C, and D** of [`custom-theme.md`](https://github.com/Nutlope/hallmark/blob/main/custom-theme.md).

### Stage 1: OKLCH Palette Construction (Section B)

The palette construction follows a strict ordinal process from **B.1 through B.7**, calculating each colour in OKLCH space:

**B.1 Anchor Accent** — Converts your supplied colour to OKLCH and constrains chroma between **0.12 and 0.20**. If no anchor is provided, Hallmark calculates the hue angle from your vibe description.

**B.2 Paper** — Determines lightness (**L**) based on the vibe's brightness:
- **95–98%** for light themes
- **12–18%** for dark themes

Hallmark then tints the paper toward the anchor hue with minimal chroma (**0.005–0.020**) to maintain warmth without saturation.

**B.3 Ink** — Sets ink lightness opposite to the paper value:
- **88–96%** when paper is dark
- **16–24%** when paper is light

The ink is tinted toward the anchor hue to ensure chromatic harmony.

**B.4–B.7 Supporting Colors and Verification** — Generates greys, focus states, and accent-ink colours. Hallmark enforces verification gates that reject pure `#000` or `#fff`, require minimum chroma of **0.005**, and limit the accent footprint to **≤5%** of the surface area.

### Stage 2: Font Pairing (Section C)

With the palette established, Hallmark selects **one display** and **one body** font from the seven tone-pairings catalogued in [`typography.md`](https://github.com/Nutlope/hallmark/blob/main/typography.md). Unlike catalog themes that restrict you to predefined pairs, the custom route allows **free mixing of tones** across the seven categories (Editorial, Technical, Vernacular, etc.).

The selection respects the font ban-list and follows the "free-baseline discipline," ensuring that body fonts maintain strict baseline alignment regardless of tone mixing (e.g., pairing an *Editorial* display with a *Technical* body).

### Stage 3: Axis Declaration and CSS Stamping (Sections D & E)

Hallmark records three diversification axes—the **paper band**, **display style**, and **accent-hue band**—to maintain rotation rules consistent with catalog themes. It then emits a CSS comment stamp prepended to your stylesheet containing:

- Macrostructure type
- Vibe description
- OKLCH values for paper and accent
- Font selections
- Axis classifications
- Version metadata

Simultaneously, Hallmark writes a JSON entry to [`.hallmark/log.json`](https://github.com/Nutlope/hallmark/blob/main/.hallmark/log.json) preserving the theme axes, vibe string, and brief context for future reference.

## Output Format and Persistence

Custom themes write their OKLCH values **inline to the page's `:root`** rather than to [`tokens.css`](https://github.com/Nutlope/hallmark/blob/main/tokens.css). This makes the theme a one-off that lives only for that specific page.

```css
:root {
  --paper: oklch(94% 0.020 65);
  --paper-2: oklch(91% 0.022 65);
  --ink: oklch(22% 0.014 60);
  --ink-2: oklch(40% 0.014 60);
  --rule: oklch(78% 0.018 65);
  --muted: oklch(54% 0.014 60);
  --accent: oklch(58% 0.16 35);
  --accent-ink: oklch(96% 0.014 65);
  --focus: oklch(56% 0.20 35);
}

```

The generated stamp appears as a comment block:

```css
/* Hallmark · macrostructure: Long Document · H5 hero knobs: salutation=time-stamp, body=2 paragraphs, signoff=initials
 * theme: custom · vibe: "archival warmth, hand-set, no varnish" · paper: oklch(94% 0.020 65) · accent: oklch(58% 0.16 35)
 * display: Frachues italic · body: Source Serif 4 · axes: light / italic-serif / chromatic-terracotta
 * studied: no · context: explicit · v0.8.0
 */

```

To make a custom theme reusable across multiple pages, you must manually copy these generated CSS variables into [`site/css/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css).

Hallmark persists metadata about the run to [`.hallmark/log.json`](https://github.com/Nutlope/hallmark/blob/main/.hallmark/log.json):

```json
{
  "date": "2026-05-01",
  "macrostructure": "Long Document",
  "theme": "custom",
  "theme_axes": "light / italic-serif / chromatic-terracotta",
  "vibe": "archival warmth, hand-set, no varnish",
  "enrichment": "none",
  "brief": "Coffeebox · subscription"
}

```

## Key Implementation Files

Understanding these source files is essential for advanced custom theme configuration:

- **[`skills/hallmark/references/custom-theme.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/custom-theme.md)** — Complete protocol for custom theme generation, including palette construction steps B.1–B.7, font pairing rules, and axis computation.
- **[`skills/hallmark/references/color.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/color.md)** — Defines OKLCH chroma caps, neutral-tinting algorithms, and APCA contrast thresholds used during palette verification.
- **[`skills/hallmark/references/typography.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/typography.md)** — Catalogs the seven tone-pairings, font ban-list, and baseline-discipline requirements.
- **[`skills/hallmark/SKILL.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md)** — Core rule-set governing Hallmark's design flow and diversification-rotation logic.
- **[`site/css/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css)** — Permanent storage for catalog themes; custom themes bypass this file initially.
- **[`.hallmark/log.json`](https://github.com/Nutlope/hallmark/blob/main/.hallmark/log.json)** — Persistent log recording custom theme axes, vibe strings, and generation metadata.

## Summary

- **Trigger custom mode** by requesting a bespoke theme, providing an anchor colour, or describing a specific brand mood in your brief.
- **Provide a 4-8 word vibe description** when prompted; optionally supply an anchor colour to seed the OKLCH hue.
- **Hallmark constructs the palette deterministically** through stages B.1–B.7, calculating paper, ink, and accent colours with strict chroma and lightness constraints.
- **Fonts mix freely** across the seven tone categories while respecting ban-lists and baseline discipline.
- **Output writes to `:root`** as inline CSS variables accompanied by a descriptive stamp and JSON log entry; copy to [`tokens.css`](https://github.com/Nutlope/hallmark/blob/main/tokens.css) to make the theme permanent.

## Frequently Asked Questions

### How do I convert an existing hex colour to Hallmark's OKLCH format?

Hallmark automatically converts any supplied hex colour to OKLCH during the **B.1 Anchor Accent** step. The system clamps the chroma value to **0.12–0.20** to maintain the design system's colour discipline. If you need to manually convert colours for debugging, reference the conversion logic in [`color.md`](https://github.com/Nutlope/hallmark/blob/main/color.md) which handles the perceptual uniformity calculations required for the palette generation pipeline.

### Can I reuse a custom theme across multiple pages?

Custom themes write inline to `:root` by default, making them page-specific. To reuse a custom theme, copy the generated CSS variables from the page's stylesheet into [`site/css/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css). This promotes the one-off theme to a catalog theme that Hallmark can rotate through like any other predefined option in the system.

### What happens if I provide a vibe that contradicts my anchor colour?

Hallmark prioritizes the anchor colour for the **hue** calculation but uses the vibe description to determine **lightness values** (paper brightness) and **temperature** adjustments. If you specify a "cold, clinical" vibe with a warm orange anchor, Hallmark will use the orange hue (35°) but set the paper lightness to a cooler, bright range (95–98%) and minimize chroma on neutrals to maintain the clinical feel while respecting your anchor constraint.

### Why does Hallmark limit chroma to 0.12–0.20 for accent colours?

These limits enforce the system's **slop-test gates** defined in [`color.md`](https://github.com/Nutlope/hallmark/blob/main/color.md), preventing oversaturated colours that violate perceptual uniformity or APCA contrast requirements. The **0.12** floor ensures enough chroma to distinguish the accent from neutrals, while the **0.20** ceiling prevents garish saturation that would break the restrained aesthetic. Focus colours may exceed this range briefly but must pass verification gates before final output.