# Hallmark Catalog Themes vs Custom Themes: Understanding the Two Styling Approaches

> Explore Hallmark's catalog themes versus custom themes. Discover rapid repeatable designs with 20 catalog themes or unique aesthetics with custom palettes and layouts. Choose the best styling for your project.

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

---

**Hallmark provides two styling pathways—20 fixed catalog themes for rapid, repeatable designs, and a custom theme route for bespoke palettes and layouts when briefs demand unique aesthetics.**

This guide examines the technical differences between Hallmark's catalog themes and its custom theme route, as implemented in Nutlope/hallmark's styling engine. You'll learn how each approach is selected, where their definitions live in the codebase, and when to use one versus the other.

## How Hallmark Selects Between Catalog and Custom Themes

The Hallmark system automatically routes briefs to either pathway based on signal detection rules defined in [`skills/hallmark/SKILL.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md).

### Default Path: Catalog Rotation

Most briefs follow the **catalog rotation rule** without any user intervention. The system:

1. Maintains a history of previously used themes
2. Ensures consecutive runs differ on at least one of three diversification axes: **paper-band**, **display-style**, and **accent-hue**
3. Injects the theme via a `data-theme` attribute on the `<body>` element

This rotation happens silently. The user never sees "catalog" mentioned—it's simply how Hallmark operates by default.

### Custom Path: Signal-Triggered Fork

The custom theme route activates only when the brief contains specific signals, as documented in [`skills/hallmark/references/custom-theme.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/custom-theme.md):

- Three or more vibe attributes in the aesthetic description
- An explicit "custom" or "make it unique" request
- A structural vision that no catalog macrostructure covers
- A brand color that has no corresponding catalog palette

When signals are detected, Hallmark presents a brief confirmation dialog before proceeding.

## Source and Storage: Where Theme Definitions Live

### Catalog Themes: Persistent Files

Each catalog theme exists as a permanent file in the repository:

| Component | Location | Purpose |
|-----------|----------|---------|
| Theme definition | `skills/hallmark/references/themes/<theme>.md` | Human-readable spec for themes like *hum*, *specimen*, *carnival*, *lumen* |
| CSS tokens | [`site/css/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css) | OKLCH values scoped under `[data-theme="…"]` selectors |

The 20 catalog themes are closed sets. You cannot tweak *hum* to have a slightly redder accent—you must select a different catalog entry that matches your desired combination.

### Custom Themes: Generated Per-Brief

Custom themes are ephemeral by design. Their definition lives only in:

- The generated page's CSS comment stamp
- The build log for diversification tracking

No file is added to `references/themes/`. The palette is computed on-the-fly using OKLCH color space, paired with freely available fonts, and written directly to `:root`.

## Scope of Variation: Fixed vs. Tunable

### Catalog Theme Constraints

Every catalog theme binds you to a specific combination of three axes. From [`skills/hallmark/references/themes/hum.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/themes/hum.md), example:

- **Paper-band**: Warm cream
- **Display-style**: Rounded, friendly sans-serif
- **Accent-hue**: Muted coral

These are immutable. If your brief calls for warm cream with a sharp geometric display and coral accents, you must find a catalog entry matching that exact triplet—or abandon the catalog.

### Custom Theme Flexibility

The custom route offers two depths, per [`custom-theme.md`](https://github.com/Nutlope/hallmark/blob/main/custom-theme.md):

**Tuned custom**
- Bespoke OKLCH palette
- Free-font pairing
- Respects all Hallmark slop-test gates

**Bespoke depth**
- Fully custom macrostructure designed from first principles
- No dependency on catalog layout patterns

Both depths allow per-brief tuning of hue, chroma, lightness, and typography without swapping entire theme packages.

## Recording and Persistence

### Catalog Theme Stamps

Pages using catalog themes carry a simple stamp:

```html
<body data-theme="hum">
  ...
</body>

```

The `theme: hum` value is recorded for rotation checks. Future runs compare against this to enforce diversification.

### Custom Theme Stamps

Custom themes use an expanded stamp format:

```css
/* Hallmark · macrostructure: Catalogue · theme: custom (vibe: "soft moss, warm terracotta")
   paper: oklch(95% 0.07 85)
   accent: oklch(70% 0.13 45)
   display-font: "Plus Jakarta Sans"
   body-font: "IBM Plex Serif"
*/

```

Diversification reads the axis values directly from this comment rather than looking up a name in [`tokens.css`](https://github.com/Nutlope/hallmark/blob/main/tokens.css).

## Working Examples in Practice

### Example 1: Implicit Catalog Usage

```html
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="/css/tokens.css">
</head>
<body data-theme="carnival">
  <main>
    <h1>Festival Announcement</h1>
  </main>
</body>
</html>

```

The `carnival` theme loads from [`site/css/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css) under the `[data-theme="carnival"]` selector. No custom CSS variables are defined in `:root`.

### Example 2: Explicit Custom Declaration

```css
:root {
  --paper: oklch(96% 0.02 100);
  --ink: oklch(25% 0.05 260);
  --accent: oklch(65% 0.15 25);
  --font-display: "Space Grotesk", sans-serif;
  --font-body: "Source Serif 4", serif;
}

/* Stamp records: theme: custom (vibe: "editorial warmth") */

```

No `data-theme` attribute appears on `<body>`. Hallmark gate tests verify this palette against slop criteria before finalizing.

### Example 3: Signal Detection Logic

The fork logic in [`skills/hallmark/SKILL.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md) operates approximately as:

```javascript
function routeBrief(brief, history) {
  if (detectCustomSignal(brief)) {
    const confirmed = askUser(
      "This brief reads like a custom palette would fit better " +
      "than the catalog. Construct a custom OKLCH palette?"
    );
    return confirmed ? buildCustomTheme(brief) : rotateCatalog(history);
  }
  
  return rotateCatalog(history);
}

```

The `detectCustomSignal` function counts vibe attributes, checks for explicit markers, and evaluates structural fit against catalog macrostructures.

## Diversification Rules: Universal Application

Both pathways obey the same diversification constraint. Per [`custom-theme.md`](https://github.com/Nutlope/hallmark/blob/main/custom-theme.md):

> A custom‑run that follows a catalog‑run (or another custom‑run) must differ on at least one of the three axes.

The implementation compares the current brief's axis values—whether drawn from catalog lookup or custom generation—against the previous run's recorded values. This prevents visual repetition regardless of which theme route produced the prior page.

## Performance and Operational Characteristics

| Factor | Catalog Themes | Custom Themes |
|--------|---------------|---------------|
| Build time | Immediate (file read) | Moderate (palette computation + font selection) |
| Cacheability | High (static CSS) | Lower (per-brief generation) |
| Reproducibility | Exact (theme name) | Documented (stamp values) |
| User friction | None | Single confirmation dialog |

Catalog themes excel for rapid iteration and consistent brand-adjacent work. Custom themes serve exploratory aesthetics and brand-exact color requirements outside the catalog's curated range.

## Summary

- **20 catalog themes** provide fast, repeatable styling from closed, curated designs stored in `skills/hallmark/references/themes/` with CSS tokens in [`site/css/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css)
- **Custom theme route** generates unique OKLCH palettes and font pairings on-the-fly when briefs contain multi-attribute aesthetics or explicit custom signals
- **Selection is automatic**: catalog rotation runs silently by default; custom fork triggers only on detected signals with user confirmation
- **Diversification rules apply universally**: consecutive runs must differ on paper-band, display-style, or accent-hue regardless of theme source
- **Persistence differs**: catalog themes are named and reusable; custom themes exist only in page stamps and build logs

## Frequently Asked Questions

### Can I modify a catalog theme's colors directly?

No. Catalog themes are immutable—each represents a fixed combination of axes. If you need a specific hue variation, you must either find a catalog entry matching that combination or switch to the custom theme route, which computes bespoke palettes per [`custom-theme.md`](https://github.com/Nutlope/hallmark/blob/main/custom-theme.md).

### How does Hallmark prevent the same theme from appearing twice in a row?

The diversification rule, implemented in the SKILL flow, tracks the three axes (paper-band, display-style, accent-hue) from the previous run. The rotation logic selects themes—or generates custom palettes—that differ on at least one axis. This applies across both catalog and custom themes.

### What file should I edit to add a 21st catalog theme?

Hallmark's current architecture does not support extending the catalog. The 20 themes in `skills/hallmark/references/themes/` and their corresponding CSS in [`site/css/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css) form a closed set. For new aesthetics, use the custom theme route and document the result in your page stamp.

### Does the custom theme route always require user approval?

Yes, by design. When signal detection triggers the custom fork, Hallmark presents a confirmation dialog before proceeding. The default path remains catalog rotation, ensuring unassisted operation for standard briefs.