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>.md scopes the entire subsequent pipeline
  • All logic is defined in SKILL.md and 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →