# When Does Hallmark Use a Custom Theme? Signal Detection & Activation Flow

> Discover when Hallmark uses a custom theme instead of its standard rotation. Learn about signal detection and activation flow in this technical breakdown.

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

---

**Hallmark switches from its 21-catalog-theme rotation to a custom theme only when the design brief contains specific signals that the catalog cannot satisfy.**

By default, Hallmark's design engine rotates silently through curated themes like *Specimen*, *Carnival*, and *Lumen*. The custom-theme branch is gated behind explicit user intent, not automatic inference. This article breaks down the five detection signals defined in [[`skills/hallmark/SKILL.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md)](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md) and the activation protocol in [[`custom-theme.md`](https://github.com/Nutlope/hallmark/blob/main/custom-theme.md)](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/custom-theme.md).

---

## The Five Custom-Theme Signals

Hallmark evaluates the brief against five signal types in Step 1 of its design flow. If **any** signal triggers, the system prompts a single confirmation question before proceeding.

| Signal | Trigger Pattern | Example Input |
|--------|---------------|-------------|
| 1. **Explicit ask** | Contains "custom", "custom theme", "tailored to our brand", "make it ours" | *"Give me a custom theme for this landing page"* |
| 2. **Named brand colour** | Hex code, OKLCH value, or named colour like "terracotta" | *"#E07A5F" or "terracotta highlights"* |
| 3. **Multi-attribute aesthetic** | 3+ vibe words no catalog theme matches | *"moss, lichen, soft pink, herbal"* |
| 4. **Brand-mood reference** | Colour swatch or mood board attachment | Uploaded palette image (colour-only) |
| 5. **Singular structural vision** | Explicit rejection of themed layouts | *"No theme", "fully bespoke", "art-direct it"* |

Signal detection is implemented as regex pattern matching against the normalized brief text. Here's the simplified logic extracted from [`SKILL.md`](https://github.com/Nutlope/hallmark/blob/main/SKILL.md):

```javascript
// SKILL.md – Step 1 signal detection (simplified)
function shouldUseCustomTheme(brief) {
  const signals = [
    /custom|tailored|make it ours|play around with the colors/i,
    /#([0-9a-f]{3,6})|oklch|(?:red|blue|green|terracotta)/i,
    /(moss|lichen|soft pink|herbal|neon|brutalist)/i, // three-plus vibe words
    /swatch|moodboard/i,
    /no theme|bespoke|art-direct/i,
  ];
  return signals.some(rx => rx.test(brief));
}

```

---

## Custom-Theme Depth Levels

Once activated, Hallmark applies one of two **custom-theme depths** based on which signal fired:

### Tuned Custom (Signals 1–4)

- **One-off OKLCH palette** derived from the brief's colour hints
- **Free-font pairing** selected from Hallmark's allowed typefaces
- **Preserves existing macrostructures** — the page layout skeleton remains catalog-standard

### Bespoke Custom (Signal 5 Only)

- **Full page redesign from first principles**
- Custom palette, typography, **and** composition
- Drops catalog macrostructure entirely
- Requires explicit "singular structural vision" signal

Both depths enforce Hallmark's universal **slop-test gates**, accessibility rules, and floor constraints (no pure `#fff` paper, banned fonts, guaranteed contrast ratios). The bespoke route simply removes the guardrails around layout diversification.

---

## Where Custom Themes Live in the Codebase

### Generation Location

Custom themes are generated inline within the page's `:root` selector. They never join the permanent catalog in [`site/css/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css).

```css
/* Hallmark · route: custom (tuned) · paper: oklch(96% 0.012 80) · accent: oklch(45% 0.18 210) · display: Inter · body: Atkinson Hyperlegible */
:root[data-theme="custom"] {
  /* Palette */
  --color-paper: oklch(96% 0.012 80);
  --color-accent: oklch(45% 0.18 210);
  --color-accent-ink: oklch(10% 0.02 210);

  /* Typography */
  --font-display: "Inter", sans-serif;
  --font-body: "Atkinson Hyperlegible", serif;

  /* Structural tokens */
  --radius-card: 12px;
  --space-section: 4rem;
}

```

### Stamp Comment Protocol

Every custom theme includes a **stamp comment** at the top of generated CSS. This enables future diversification logic and reproducibility:

```css
/* Hallmark · route: custom (bespoke) · structure: scroll-poem · idea: "interactive timeline" · paper: oklch(92% 0.010 30) · accent: oklch(50% 0.15 280) · display: "Bebas Neue" · body: "Inter" · axes: paper-band / display-style / accent-hue · gates: all-pass · studied: no */

```

### Diversification Logging

The custom run is recorded in [`/.hallmark/log.json`](https://github.com/Nutlope/hallmark/blob/main//.hallmark/log.json) with `"theme": "custom"`. This ensures future rotations avoid collision with the one-off design.

---

## Key Files for Custom-Theme Implementation

| File | Purpose |
|------|---------|
| [[`skills/hallmark/SKILL.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md)](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md) | Main design flow; defines signal detection and branch logic |
| [[`skills/hallmark/references/custom-theme.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/custom-theme.md)](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/custom-theme.md) | Full protocol: depth levels, confirmation flow, stamping format |
| [[`site/css/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css)](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css) | Catalog theme tokens; custom themes inject alongside |
| [[`site/examples/najm/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/examples/najm/tokens.css)](https://github.com/Nutlope/hallmark/blob/main/site/examples/najm/tokens.css) | Working example of a tuned custom theme |

---

## Summary

- **Hallmark uses a custom theme only on explicit signal detection**, not by default or automatic inference.
- Five signals trigger the custom branch: explicit ask, named colour, multi-attribute aesthetic, brand-mood reference, or singular structural vision.
- Two depths exist: **tuned custom** (palette + fonts, standard layout) and **bespoke custom** (full redesign, signal 5 only).
- Confirmation is required — the system asks once, then proceeds or falls back to catalog rotation.
- Custom themes generate inline CSS with machine-readable stamp comments and log to [`/.hallmark/log.json`](https://github.com/Nutlope/hallmark/blob/main//.hallmark/log.json).

---

## Frequently Asked Questions

### What happens if multiple signals appear in the same brief?

Hallmark treats signal detection as a binary OR operation — one match is sufficient. The system does not weight or rank signals; it simply confirms once with the user and proceeds to the appropriate depth level. Signal 5 alone unlocks bespoke depth.

### Can a custom theme become part of the permanent catalog?

No. According to [`custom-theme.md`](https://github.com/Nutlope/hallmark/blob/main/custom-theme.md) §B, custom themes are **ephemeral by design**. They inject into `:root[data-theme="custom"]` without modifying [`site/css/tokens.css`](https://github.com/Nutlope/hallmark/blob/main/site/css/tokens.css). The stamp comment and log entry exist purely for diversification tracking, not for catalog admission.

### How does Hallmark handle colour values in the brief?

The regex in Step 1 captures hex codes (`#E07A5F`), OKLCH strings (`oklch(45% 0.18 210)`), and common colour names. These are passed to the palette generator, which builds a harmonized OKLCH scale with automatic contrast-ink derivation for accessibility compliance.

### What's the difference between a mood board and a page screenshot?

Hallmark distinguishes colour-only references from layout references. A **mood board** or **swatch** (signal 4) triggers tuned custom depth for palette extraction. A **full page screenshot** is treated as structural inspiration, not a custom-theme signal — it routes through different analysis pathways.