How Hallmark Ensures Design Consistency Across Different Genres
Hallmark ensures consistency across design genres by mapping every theme to a canonical genre identifier that references a single markdown rule-set specifying typography, color, layout, motion, and voice constraints.
The open-source Hallmark project isolates visual logic from theme selection through a three-layer architecture: a centralized theme-to-genre map, markdown genre specifications, and runtime wiring that enforces the correct rule-set for each page generation. This approach allows designers to introduce new themes without rebuilding the entire design system.
The Three Mechanisms Driving Genre Consistency
Hallmark maintains visual coherence through tightly-coupled components that separate what a genre looks like from which theme is currently active.
1. The Genre Map: THEME_GENRES in site/js/main.js
The genre map is a lookup table that assigns every available theme to one of four genre identifiers. This guarantees that themes sharing an identifier inherit identical constraints.
The map is defined at lines 97–123 of site/js/main.js:
const THEME_GENRES = {
// editorial – the canonical Hallmark voice
specimen: "editorial",
newsprint: "editorial",
atelier: "editorial",
// modern‑minimal – Stripe / Linear / ElevenLabs school
coral: "modern-minimal",
cobalt: "modern-minimal",
// atmospheric – Suno / Runway / dark‑AI‑tool school
bloom: "atmospheric",
midnight: "atmospheric",
// playful – a lighter, experimental voice
hum: "playful",
};
Each entry follows the pattern themeName: "genre-identifier". When a user selects a theme, the system resolves its genre in constant time.
2. Genre Reference Files: Canonical Markdown Specifications
Genre definitions live in skills/hallmark/references/genres/*.md. These files enumerate:
- Permitted typography families and weights
- Color palette constraints (primary, accent, surface)
- Layout grid specifications
- Motion easing and timing rules
- Voice and tone guidelines
- Validation gates ("slop tests") that must pass
The modern-minimal genre specification demonstrates this structure:
# Genre — modern‑minimal
## Themes that belong
`Coral` — warm‑grey paper, single warm coral accent, Geist throughout…
`Cobalt` — cool‑dev‑tool register, electric cobalt accent, Space Grotesk…
## Voice
- Display — Geist Sans 500–700, tight letter‑spacing.
- Layout — two‑column heroes, generous whitespace, subtle borders.
- Motion — minimal; reveals are off.
Because coral and cobalt both map to modern-minimal, any page built with either theme follows these identical constraints—even though their accent colors differ.
3. Runtime Wiring: setPressed Function
The runtime layer connects user interaction to genre enforcement. When a theme button is clicked, the setPressed function (lines 36–44 in site/js/main.js) performs three operations:
function setPressed(theme) {
const genre = THEME_GENRES[theme] || "editorial";
if (themeGenreEl) themeGenreEl.textContent = genre;
// genre is also passed to the Hallmark LLM skill
}
The function:
- Resolves the genre using
THEME_GENRES[theme]with a fallback to"editorial" - Updates the DOM to display the current genre
- Passes the identifier to the Hallmark skill, which loads the corresponding markdown specification
How the System Flows Together
The consistency mechanism operates as a five-step pipeline:
- Theme selection — User clicks a theme button, triggering
applyTheme(theme) - Genre resolution —
applyThemecallssetPressed(theme), which looks upTHEME_GENRES[theme] - UI update — The resolved genre is written to
themeGenreEl.textContent - Skill invocation — The genre identifier is handed to the Hallmark LLM skill
- Constraint loading — The skill reads the matching genre markdown file and applies its rule-set to code generation
This pipeline ensures that every page generated with themes mapping to the same genre shares underlying visual language, regardless of superficial variations like accent color or font weight.
Adding New Themes Without Breaking Consistency
The architecture supports theme expansion through a single-line change. To create a new theme that inherits existing genre constraints:
THEME_GENRES["new-theme"] = "modern-minimal";
No additional configuration is required. The new theme automatically:
- Displays as "modern-minimal" in the UI
- Loads the
modern-minimal.mdspecification - Enforces all typography, color, layout, motion, and voice constraints defined therein
This single source of truth per genre eliminates drift between themes and simplifies maintenance.
Key Files in the Consistency Architecture
| File | Responsibility |
|---|---|
site/js/main.js |
Contains THEME_GENRES map, applyTheme() and setPressed() functions, runtime genre enforcement |
skills/hallmark/references/genres/*.md |
Canonical markdown specifications for each genre's complete design system |
skills/hallmark/references/component-cookbook.md |
Component archetypes referenced by genre files |
site/index.html |
Loads main.js and displays the active genre label |
site/css/*.css |
Token-based styles scoped by data-theme attribute |
Summary
Hallmark ensures design consistency across genres through:
- A centralized genre map (
THEME_GENRES) that themes inherit from - Markdown specifications that serve as immutable rule-sets for typography, color, layout, motion, and voice
- Runtime wiring that resolves and enforces genres during page generation
- Single-source-of-truth architecture where adding themes requires only map entries, not new specifications
This separation of genre definition from theme selection allows unlimited theme variety while maintaining strict visual coherence within each genre boundary.
Frequently Asked Questions
What happens if a theme isn't found in THEME_GENRES?
The setPressed function provides a fallback: THEME_GENRES[theme] || "editorial". Any unrecognized theme defaults to the editorial genre, ensuring the system degrades gracefully to Hallmark's canonical voice rather than failing or producing unstructured output.
Can a single theme belong to multiple genres?
No. The THEME_GENRES structure uses unique keys, so each theme maps to exactly one genre identifier. This constraint prevents ambiguity in rule-set application and ensures predictable visual output. To combine genre characteristics, you must define a new genre specification that explicitly merges the desired properties.
How does the Hallmark skill use genre markdown files?
According to the comment above the THEME_GENRES definition in site/js/main.js, the skill "picks from" the genre's rule-set when generating code. The skill loads the markdown file matching the resolved genre identifier (e.g., modern-minimal.md), extracts constraints for typography families, color limits, layout grids, motion easing, and voice tone, then applies these as guardrails during LLM-driven page construction.
Where are genre definitions stored relative to the main application?
Genre markdown files live in skills/hallmark/references/genres/, separate from the frontend code in site/. This directory structure reflects Hallmark's skill-based architecture: the skills/ directory contains LLM-ready specifications, while site/ contains the user-facing theme selector and runtime logic that bridges user interaction to skill invocation.
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 →