# How Hallmark Ensures Design Consistency Across Different Genres

> Learn how Hallmark maintains design consistency across genres using a canonical genre identifier and a single markdown rule-set for typography, color, layout, motion, and voice.

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

---

**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`](https://github.com/Nutlope/hallmark/blob/main/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`](https://github.com/Nutlope/hallmark/blob/main/site/js/main.js):

```javascript
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:

```markdown

# 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`](https://github.com/Nutlope/hallmark/blob/main/site/js/main.js)) performs three operations:

```javascript
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:

1. **Theme selection** — User clicks a theme button, triggering `applyTheme(theme)`
2. **Genre resolution** — `applyTheme` calls `setPressed(theme)`, which looks up `THEME_GENRES[theme]`
3. **UI update** — The resolved genre is written to `themeGenreEl.textContent`
4. **Skill invocation** — The genre identifier is handed to the Hallmark LLM skill
5. **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:

```javascript
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.md`](https://github.com/Nutlope/hallmark/blob/main/modern-minimal.md) specification
- 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`](https://github.com/Nutlope/hallmark/blob/main/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`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/component-cookbook.md) | Component archetypes referenced by genre files |
| [`site/index.html`](https://github.com/Nutlope/hallmark/blob/main/site/index.html) | Loads [`main.js`](https://github.com/Nutlope/hallmark/blob/main/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`](https://github.com/Nutlope/hallmark/blob/main/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`](https://github.com/Nutlope/hallmark/blob/main/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.