How the Hallmark Theme Diversification Rule Ensures Consecutive Themes Differ on Axes
The Hallmark theme-diversification rule guarantees that no two consecutive builds reuse the exact same combination of paper-band, display-style, and accent-hue by rejecting candidates that match all three axes of the most recent entry in .hallmark/log.json.
The Nutlope/hallmark skill enforces the theme diversification rule every time it generates a page or component to keep consecutive outputs visually distinct. By tracking three independent design axes across builds, the system prevents repetitive styling while still allowing macrostructures and other visual elements to recur. This rule is formally specified in skills/hallmark/SKILL.md and operates against the persistent .hallmark/log.json file.
What Is the Theme Diversification Rule?
The theme diversification rule is a deterministic guard that runs before Hallmark finalizes a theme selection. It compares the candidate theme’s axis values against recent build history to ensure at least one attribute changes. If the candidate matches the previous entry on all three axes, the skill throws a diversification failure and selects a different theme.
The Three Diversification Axes
Every catalog theme and custom theme in Hallmark declares three independent attributes under an ## Axes (diversification) heading:
- paper-band — the background paper colour family, such as
cream,night, ordaylight. - display-style — the typographic treatment of headings, such as
classical-serif-lowercase,italic-serif, ormono-display. - accent-hue — the primary accent colour strategy, such as
single-hue,multi-hue, orduo-tone.
These axes are recorded in theme reference files like skills/hallmark/references/themes/hum.md and skills/hallmark/references/themes/carnival.md.
Where the Axes Are Defined
Catalog themes expose their axes directly in their reference markdown files. Custom themes declare them explicitly during generation so the rotation logic remains blind to whether a theme is built-in or user-created. This ensures the diversification rule applies uniformly across all theme types.
How the Rotation Check Works
Before committing to a candidate theme, Hallmark reads the last three to five entries from .hallmark/log.json as defined in skills/hallmark/SKILL.md § 2.5. It then compares the candidate’s axis tuple against the most recent log entry. If paper-band, display-style, and accent-hue all match, the candidate is rejected.
The logic is implemented roughly as follows:
// 1️⃣ Load the log (if it exists)
const logPath = '.hallmark/log.json';
let recent = [];
if (fs.existsSync(logPath)) {
const entries = JSON.parse(fs.readFileSync(logPath, 'utf8'));
recent = entries.slice(0, 5); // look at the last 3‑5 runs
}
// 2️⃣ Resolve candidate theme's axes
// (catalog themes read from site/css/tokens.css, custom themes specify them directly)
const candidate = {
theme: 'hum',
axes: { paperBand: 'cream', displayStyle: 'rounded‑sans', accentHue: 'multi' }
};
// 3️⃣ Compare with the most recent entry
const last = recent[0];
if (last && candidate.axes.paperBand === last.axes.paperBand &&
candidate.axes.displayStyle === last.axes.displayStyle &&
candidate.axes.accentHue === last.axes.accentHue) {
// ❌ All three axes match – reject this theme
throw new Error('Diversification failure: pick a theme that differs on at least one axis.');
}
// 4️⃣ If it passes, record the new entry
const newEntry = {
date: new Date().toISOString().split('T')[0],
macrostructure: chosenMacro,
theme: candidate.theme,
theme_axes: `${candidate.axes.paperBand} / ${candidate.axes.displayStyle} / ${candidate.axes.accentHue}`,
brief: briefOneLiner
};
fs.writeFileSync(logPath, JSON.stringify([newEntry, ...recent].slice(0, 20), null, 2));
Because the check only rejects when all three axes align, the rule allows two consecutive builds to share two attributes as long as at least one axis differs. This fine-grained control prevents "variety drift" without forcing total visual discontinuity.
Logging Prior Runs in .hallmark/log.json
The .hallmark/log.json file serves as the project-level memory for the skill. After each successful build, Hallmark appends a JSON entry containing the theme name, the three axis values, the chosen macrostructure, and a brief description. The file retains roughly the last 20 entries, giving the rotation check enough history to enforce variety.
A typical catalog build is logged like this:
{
"date": "2026-08-13",
"macrostructure": "long-document",
"theme": "hum",
"theme_axes": "cream / rounded‑sans / multi",
"brief": "Kids‑friendly habit tracker"
}
Custom themes follow the same shape but record explicitly provided axes:
{
"date": "2026-08-12",
"macrostructure": "gallery",
"theme": "custom",
"theme_axes": "day‑paper / mono‑display / duo‑tone",
"vibe": "playful tech startup",
"brief": "Landing page for a new SDK"
}
By persisting this data to disk, Hallmark maintains continuity across sessions and ensures the diversification rule is enforced even after the process restarts.
Special Cases and Inversions
The diversification rule has two important modifications depending on project context: full-app redesigns and custom themes.
App-Wide Redesigns with design.md
When a project contains a design.md file, Hallmark treats the work as a multi-page application redesign rather than a standalone page. In this mode, the rule is inverted: consecutive pages must share the same axes to preserve a coherent visual system. This behavior is documented in skills/hallmark/references/verbs/redesign.md § 2, where the skill rejects candidates that deviate from the established app-wide theme instead of ones that match it.
Custom Themes and the Same Rotation Logic
Custom-generated themes are not exempt from diversification. According to skills/hallmark/references/custom-theme.md § 4–5, custom themes declare their paper-band, display-style, and accent-hue values explicitly. The skill processes them through the same theme-route-blind rotation check, meaning a custom theme can still be rejected if its axes match the previous build. The log records the custom axes exactly like catalog entries.
Summary
- The theme diversification rule is specified in
skills/hallmark/SKILL.mdand prevents visual repetition across consecutive builds. - It operates on three axes: paper-band, display-style, and accent-hue.
- The skill reads the last 3–5 entries from
.hallmark/log.jsonand rejects any candidate whose axes exactly match the most recent entry. - Custom themes declare their own axes and are subject to the same rotation logic.
- In app-wide redesigns with a
design.mdfile, the rule inverts so consecutive pages share the same axes for consistency.
Frequently Asked Questions
What are the three diversification axes in Hallmark?
The three axes are paper-band (background colour family), display-style (heading typography), and accent-hue (primary colour strategy). Every theme declares these attributes under an ## Axes (diversification) heading in its reference file. The skill uses this tuple to decide whether a candidate theme is different enough from the previous build.
How does Hallmark prevent the same theme from appearing twice in a row?
Hallmark loads .hallmark/log.json and compares the candidate theme’s three axes against the most recent log entry. If all three axes match, the skill raises a diversification error and picks a different theme. This guarantees at least one axis differs between any two consecutive Hallmark outputs.
Where does Hallmark store the history of previously used themes?
The skill persists build history in .hallmark/log.json at the project root. Each entry records the theme name, macrostructure, the three axis values as a slash-delimited string, and a brief description of the build. This file allows the rotation check to enforce variety across multiple sessions.
Does the theme diversification rule apply to custom themes?
Yes. According to skills/hallmark/references/custom-theme.md, custom themes explicitly declare their three axes. The skill applies the same theme-route-blind rotation check to custom themes as it does to catalog themes, ensuring they are also compared against the log and rejected if they duplicate the most recent axes.
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 →