How Hallmark Detects the Genre for a Design Brief: Signal-Based Matching Explained
Hallmark detects design brief genre through a deterministic signal-matching system that scans for cue words and falls back to a default editorial style when no signals are found.
Determining a page's genre — the high-level visual-style family that guides theme, layout, and component choices — is the first step in Hallmark's Design flow. The detection happens before any theme rotation or component selection, ensuring the entire pipeline is correctly scoped. This article breaks down the exact mechanism used in Nutlope/hallmark.
Signal-Based Detection: The Four Keyword Groups
Hallmark scans the design brief for cue words that map to one of four supported genres: editorial, atmospheric, modern-minimal, or playful. The detection follows a strict priority order with a silent default fallback.
According to the source code in skills/hallmark/SKILL.md (lines 230-236), the keyword matching works as follows:
Atmospheric Genre Signals
If the brief contains any atmospheric cues, Hallmark selects atmospheric:
- Common triggers: "AI tool", "generative", "music", "video", "voice", "late-night", "dark mode", "atmospheric"
These signals typically indicate immersive, mood-driven experiences.
Modern-Minimal Genre Signals
If atmospheric cues are absent but modern-minimal cues appear, Hallmark selects modern-minimal:
- Common triggers: "SaaS", "enterprise", "API", "platform", "developer tool", "infra", "B2B", "dev experience"
This genre suits technical, business-focused products.
Playful Genre Signals
If neither of the above match but playful cues are present, Hallmark selects playful:
- Common triggers: "fun", "consumer", "casual", "friendly", "onboarding", "family", "community"
This targets approachable, consumer-oriented experiences.
The Silent Default: Editorial
When no signals fire, Hallmark falls back to editorial — the baseline genre with no explicit markers required.
Conflict Resolution for Overlapping Signals
When more than one non-default signal fires — a rare edge case — Hallmark does not guess. Instead, it presents a clarification question:
"This brief fits both modern-minimal and atmospheric — which feels closer?"
This explicit user choice prevents misclassification and ensures the pipeline receives a single, authoritative genre.
Eager Loading of Genre Descriptors
Once a genre is determined, Hallmark immediately loads the corresponding descriptor file from references/genres/<genre>.md. This eager loading pattern scopes all downstream operations:
- Theme rotation rules
- Slop-test overrides
- Navigation and footer routing
The rest of the pipeline cannot proceed without this genre context locked in place.
Code Implementation
The detection logic can be implemented as straightforward regex matching with priority evaluation:
// Mirrors Hallmark's genre-detection logic
function detectGenre(brief) {
const atmospheric = /\b(ai tool|generative|music|video|voice|late[- ]night|dark mode|atmospheric)\b/i;
const modernMinimal = /\b(saas|enterprise|api|platform|developer tool|infra|b2b|dev experience)\b/i;
const playful = /\b(fun|consumer|casual|friendly|onboarding|family|community)\b/i;
const hasAtmos = atmospheric.test(brief);
const hasModern = modernMinimal.test(brief);
const hasPlayful = playful.test(brief);
const matches = [hasAtmos, hasModern, hasPlayful].filter(Boolean).length;
if (matches > 1) {
// Real implementation triggers a clarification question here
return 'conflict';
}
if (hasAtmos) return 'atmospheric';
if (hasModern) return 'modern-minimal';
if (hasPlayful) return 'playful';
return 'editorial'; // silent default
}
After detection, the genre file loads dynamically:
const genre = detectGenre(userBrief);
import(`./references/genres/${genre}.md`).then(module => {
applyGenreRules(module);
});
The front-end demo in site/js/main.js also maintains a theme-to-genre map for UI feedback, demonstrating the same eager loading pattern in a client-side context.
Key Files and Their Roles
| File | Purpose |
|---|---|
skills/hallmark/SKILL.md |
Official genre-signal table and conflict-resolution wording (lines 230-236) |
references/genres/editorial.md |
Default genre when no signals match |
references/genres/atmospheric.md |
Atmospheric genre layout and theme rules |
references/genres/modern-minimal.md |
Modern-minimal genre specifications |
references/genres/playful.md |
Playful genre descriptor |
site/js/main.js |
UI-side genre mapping and display logic |
Summary
- Signal-based detection scans for three keyword groups in priority order: atmospheric, modern-minimal, playful
- Silent default to editorial when no signals fire
- Conflict resolution asks users to clarify when multiple genres match
- Eager loading of
references/genres/<genre>.mdscopes the entire subsequent pipeline - All logic is defined in
SKILL.mdand executed before any theme or component selection
Frequently Asked Questions
What happens if my brief matches multiple genre keywords?
Hallmark detects the overlap and presents a clarification question asking you to choose between the matched genres. This prevents automatic misclassification.
Where are the genre rules actually stored?
Each genre has a dedicated Markdown file in references/genres/: editorial.md, atmospheric.md, modern-minimal.md, and playful.md. These files contain layout rules, theme clusters, and slop-test overrides.
Can I force a specific genre regardless of the brief content?
The source documentation does not indicate manual genre override. The system is designed to infer from brief signals or user clarification when conflicts occur.
Is genre detection performed on every generation request?
Yes. Genre detection runs at the start of every Design flow, ensuring the correct visual-style family guides all subsequent decisions.
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 →