How Hallmark Uses Catalog Themes for UI Design: A Complete Technical Breakdown
Hallmark powers its UI through a catalog of 20 pre-defined themes, each encoding a complete visual system via CSS custom properties that activate with a single data-theme attribute.
The Hallmark repository implements a theme-driven design engine that lets you swap entire visual languages—palette, typography, spacing, motion, and component defaults—without touching component code. This article explains how the catalog works, how themes are selected and rotated, and how they shape every layer of the UI.
Theme Definition and Structure
Hallmark's catalog lives in two locations: machine-readable CSS variables and human-readable design specifications.
CSS Custom Properties in tokens.css
All 20 themes are defined in site/css/tokens.css as [data-theme="…"] blocks. Each block declares the full set of CSS variables that downstream components consume:
[data-theme="hum"] {
/* Paper band */
--color-paper: #f7f3ef;
--color-paper-secondary: #efe9e2;
/* Accent hue */
--color-accent: #e85d4e;
--color-accent-secondary: #f4a261;
/* Display style */
--font-display: 'Plus Jakarta Sans', sans-serif;
--font-body: 'Plus Jakarta Sans', sans-serif;
/* Motion */
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
--dur-short: 150ms;
/* Component defaults */
--radius-pill: 9999px;
--radius-card: 24px;
}
The file encodes three diversification axes for every theme: paper band, display style, and accent hue. These axes drive the rotation logic that prevents visual repetition across builds.
Theme Documentation in Markdown
Individual theme specifications—design intent, reference palettes, motion rules, signature moves—are stored as Markdown files under skills/hallmark/references/themes/. The Hum theme (the only "playful" theme in the catalog) is documented in hum.md, covering typography (Plus Jakarta Sans for display), multi-accent section bands, and character moments that define its distinctive voice.
Theme Selection Workflow
When Hallmark runs a design build, it follows the Theme-diversification rule defined in skills/hallmark/SKILL.md:
- Default route — Select one of the 20 catalog themes.
- Rotation — Ensure successive builds differ on at least one of the three axes (paper, display, accent). The rotation is theme-route-blind, applying equally to catalog and custom runs.
- Signal-driven custom fork — Switch to a custom theme only if the brief signals a multi-attribute aesthetic or structural need, as described in
skills/hallmark/references/custom-theme.md. For ordinary briefs, the catalog operates silently without user intervention.
The selected theme's CSS variables are injected with a comment stamp:
/* Hallmark · macrostructure: marquee-hero · theme: hum */
This stamp allows Hallmark to read the previous run and enforce diversification on the next build.
How Themes Shape UI Components
Themes control five visual layers through CSS custom properties:
| Layer | Example Variables | Effect |
|---|---|---|
| Palette | --color-paper, --color-accent, --color-ink |
Background, foreground, interactive colors |
| Typography | --font-display, --font-body |
Typeface swaps (e.g., Hum uses Plus Jakarta Sans) |
| Component defaults | --radius-card, --shadow-elevated |
Shape and depth |
| Motion | --ease-out, --dur-short |
Animation curves and timing |
| Signature moves | Documented in theme MD | High-level interaction patterns (Hum's button system, multi-accent bands) |
Because components reference these variables directly—var(--color-accent), var(--font-display)—they remain theme-agnostic. No conditional logic, no theme-specific branches.
/* A button that works in any theme */
.btn {
background: var(--color-accent);
color: var(--color-ink);
border-radius: var(--radius-pill);
font-family: var(--font-display);
transition: transform var(--ease-out) var(--dur-short);
}
Runtime Theme Activation
Applying a catalog theme requires only a single HTML attribute:
<!doctype html>
<html data-theme="hum">
<head>
<link rel="stylesheet" href="site/css/tokens.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
</head>
<body>
<button class="btn btn--soft btn--pear">Get Started</button>
</body>
</html>
The browser matches [data-theme="hum"] in tokens.css, and all components inherit the correct visual language. Switching to data-theme="cobalt" requires zero code changes.
Theme-Aware Macrostructures
Each theme declares macrostructure affinities in its Markdown spec. Hum, for example, prefers Marquee Hero, Bento Grid, and Stat-Led layouts. When Hallmark selects a macrostructure from skills/hallmark/references/macrostructures.md, it cross-checks the active theme's affinity list. Mismatches fall back to neutral macrostructures, ensuring layout and visual language remain coherent.
Implementing Theme Rotation
The diversification rule prevents visual fatigue. Here's the selection pseudo-code that enforces it:
function pickTheme(previousTheme) {
const catalog = [
'specimen','midnight','brutal','garden','atelier','newsprint',
'terminal','manifesto','almanac','sport','studio','riso',
'bloom','coral','cobalt','aurora','editorial','carnival',
'lumen','hum'
];
const prevAxes = getAxes(previousTheme); // reads from tokens.css
const candidates = catalog.filter(t => {
const axes = getAxes(t);
return !(axes.paper === prevAxes.paper &&
axes.display === prevAxes.display &&
axes.accent === prevAxes.accent);
});
return candidates[Math.floor(Math.random() * candidates.length)];
}
The getAxes helper extracts paper, display, and accent values to guarantee at least one axis differs from the previous build.
Key Files in the Theme System
| File | Purpose |
|---|---|
site/css/tokens.css |
CSS custom properties for all 20 themes; the runtime theme engine |
skills/hallmark/references/themes/<theme>.md |
Design specs, signature moves, macrostructure affinities |
skills/hallmark/SKILL.md |
Theme-diversification rule, route logic, stamping format |
skills/hallmark/references/custom-theme.md |
Custom theme branch and fallback behavior |
skills/hallmark/references/macrostructures.md |
Layout index with theme affinity/rejection lists |
Summary
- Hallmark's catalog themes encode complete visual systems through CSS custom properties in
site/css/tokens.css. - Activation happens via
data-themeattribute—no JavaScript, no component changes. - Diversification is enforced across builds using three axes (paper, display, accent) recorded in theme stamps.
- Components stay theme-agnostic by referencing variables like
--color-accentand--font-display. - Macrostructure selection respects theme affinities to maintain visual coherence.
Frequently Asked Questions
How many themes are in Hallmark's catalog?
The catalog contains 20 pre-defined themes: specimen, midnight, brutal, garden, atelier, newsprint, terminal, manifesto, almanac, sport, studio, riso, bloom, coral, cobalt, aurora, editorial, carnival, lumen, and hum. Each lives in site/css/tokens.css with full CSS variable definitions.
Can I create a custom theme instead of using the catalog?
Yes, but only when the design brief signals a multi-attribute aesthetic or structural need. Hallmark defaults to catalog themes for ordinary briefs and switches to custom themes via the workflow described in skills/hallmark/references/custom-theme.md. The catalog is designed to be "silent" and sufficient for most use cases.
What happens if I use the same theme for multiple builds?
Hallmark's rotation rule prevents this. The system reads the previous build's theme stamp, extracts its three axes (paper, display, accent), and filters the catalog to exclude themes sharing all three. Only candidates that differ on at least one axis are eligible for selection.
Do components need to know which theme is active?
No. Components reference CSS custom properties (var(--color-accent), var(--radius-card)) without any theme-specific logic. This decouples implementation from styling—the same button component renders correctly for Hum's playful rounded style or Terminal's monospace aesthetic.
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 →