# How Hallmark's Pre‑Flight Scan Detects Design Tokens, Fonts, and Frameworks

> Discover how Hallmark's pre-flight scan automatically detects design tokens, fonts, and frameworks by inspecting file trees for known patterns. Streamline your code generation.

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

---

**Hallmark’s pre‑flight scan uses a rule‑based JavaScript routine that inspects file trees for known patterns—including `:root` CSS variables, [`package.json`](https://github.com/Nutlope/hallmark/blob/main/package.json) dependencies, and specific config files—to automatically detect existing design systems and front‑end tooling before generating code.**

The Nutlope/hallmark repository implements an intelligent pre‑flight stage that runs at the start of every generation cycle. This scan prevents style collisions by discovering whether your project already uses design tokens, custom font variables, or frameworks like Tailwind CSS, ensuring subsequent output aligns with your existing architecture.

## What Happens During the Pre‑Flight Scan?

The scan is performed by a core JavaScript routine that walks the project directory and applies heuristics defined in [`skills/hallmark/SKILL.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md). It caches results to avoid redundant file system operations, emitting a one‑line note when reused: “Pre‑flight cached …”. Users can force a fresh scan using a “refresh pre‑flight” command.

When the scanner finds missing assets, Hallmark reports them in the pre‑flight outcome block and later generates the necessary scaffolding—such as a full token system, Tailwind `@theme` blocks, or motion‑library imports.

## Detecting Design Tokens in CSS and TypeScript

### Root Custom Properties and Token Files

Hallmark identifies design tokens by searching for CSS custom properties following the `--color-*` and `--font-*` naming conventions. According to [`skills/hallmark/references/contract.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/contract.md), the scanner looks for:

- A `:root` CSS block (or `[data-theme]` selector) containing variable definitions
- Dedicated token files named [`tokens.css`](https://github.com/Nutlope/hallmark/blob/main/tokens.css) or [`tokens.ts`](https://github.com/Nutlope/hallmark/blob/main/tokens.ts)
- The presence of a [`design.md`](https://github.com/Nutlope/hallmark/blob/main/design.md) file that lists token names

If none of these patterns match, the pre‑flight outcome reports “No design tokens” and Hallmark introduces a full token system in subsequent generation steps.

### The design.md Convention

Beyond code inspection, the scanner checks for a [`design.md`](https://github.com/Nutlope/hallmark/blob/main/design.md) file in the project root. This file serves as an explicit declaration of the design system, allowing Hallmark to parse token definitions without inferring them from stylesheets.

## Identifying Font References and Typography Tokens

### CSS Variable Patterns

Font detection relies on `font-family` declarations that reference CSS variables rather than raw strings. As specified in [`skills/hallmark/references/slop-test.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/slop-test.md), valid projects must use patterns like:

```css
font-family: var(--font-display);

```

The scanner flags any inline font definitions that do not map to a named token (e.g., `font-family: "Helvetica"`), which triggers “mid‑render token improvisation” to replace hardcoded values with variable references.

### Flagging Raw Font Strings

If the scan detects raw font strings without corresponding CSS variables, it marks these as violations. This enforcement ensures that every colour and every font in the generated artifact references a named token such as `var(--color-accent)` or `var(--font-body)`.

## Framework and Motion Library Discovery

### package.json Dependency Analysis

The scanner reads [`package.json`](https://github.com/Nutlope/hallmark/blob/main/package.json) to detect front‑end frameworks and animation libraries. It inspects both `dependencies` and `devDependencies` for packages including:

- **tailwindcss**
- **framer‑motion**
- **styled‑components**
- **gsap**
- **motion‑one**

When these entries exist, Hallmark adjusts its export format accordingly. For example, [`skills/hallmark/references/export-formats.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/export-formats.md) notes that “On Tailwind projects (detected at pre‑flight) …” the generator will output Tailwind‑specific syntax rather than raw CSS.

### Configuration File Signatures

Beyond [`package.json`](https://github.com/Nutlope/hallmark/blob/main/package.json), the scan checks for configuration files such as:

- [`tailwind.config.js`](https://github.com/Nutlope/hallmark/blob/main/tailwind.config.js) or [`tailwind.config.ts`](https://github.com/Nutlope/hallmark/blob/main/tailwind.config.ts)
- [`postcss.config.js`](https://github.com/Nutlope/hallmark/blob/main/postcss.config.js)

If no framework is detected, the pre‑flight outcome logs “vanilla HTML, no framework detected” and Hallmark may add Tailwind along with motion libraries as needed.

## Caching and Refresh Mechanics

The scan result is cached to improve performance. When the cache is utilized, Hallmark emits a concise notification indicating that the pre‑flight data is being reused. Developers can invalidate this cache and trigger a re‑scan to pick up recent changes to dependencies or design tokens.

## Implementation Example: Scan Logic

The following pseudo‑code illustrates how Hallmark’s scanner implements these detection rules:

```javascript
import { readFileSync, readdirSync } from 'fs';
import path from 'path';

function hasDesignTokens(root) {
  const cssFiles = readdirSync(root).filter(f => f.endsWith('.css'));
  for (const f of cssFiles) {
    const content = readFileSync(path.join(root, f), 'utf8');
    // Check for :root or [data-theme] blocks with font variables
    if (/:\s*root\s*\{[^}]*--font-/.test(content)) return true;
  }
  // Check for explicit design documentation
  return !!(readdirSync(root).includes('design.md'));
}

function detectsFramework(root) {
  const pkgPath = path.join(root, 'package.json');
  if (fs.existsSync(pkgPath)) {
    const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
    const deps = { ...pkg.dependencies, ...pkg.devDependencies };
    return Object.keys(deps).some(d => /tailwind|framer-motion|styled-components/.test(d));
  }
  // Fallback to config file detection
  return readdirSync(root).some(f => /tailwind\.config/.test(f));
}

// Example usage within Hallmark's pipeline
if (!hasDesignTokens(projectRoot)) {
  console.log('❌ No design tokens detected – Hallmark will introduce a full token system.');
}
if (!detectsFramework(projectRoot)) {
  console.log('❌ No framework detected – Hallmark will add Tailwind & motion libs as needed.');
}

```

## Summary

- **Rule‑based detection**: Hallmark’s pre‑flight scanner inspects [`package.json`](https://github.com/Nutlope/hallmark/blob/main/package.json), CSS files, and config files to identify existing design systems.
- **Token discovery**: Looks for `:root` custom properties (`--color-*`, `--font-*`), [`tokens.css`](https://github.com/Nutlope/hallmark/blob/main/tokens.css) files, and [`design.md`](https://github.com/Nutlope/hallmark/blob/main/design.md) documentation.
- **Font validation**: Enforces CSS variable references (e.g., `var(--font-display)`) and flags raw font strings.
- **Framework awareness**: Detects Tailwind, Framer Motion, and other libraries via dependencies and config files like [`tailwind.config.js`](https://github.com/Nutlope/hallmark/blob/main/tailwind.config.js).
- **Caching support**: Scan results are cached for performance, with options to refresh when project dependencies change.

## Frequently Asked Questions

### How does Hallmark know if my project uses design tokens?

Hallmark checks for CSS custom properties within `:root` or `[data-theme]` selectors, looks for dedicated [`tokens.css`](https://github.com/Nutlope/hallmark/blob/main/tokens.css) or [`tokens.ts`](https://github.com/Nutlope/hallmark/blob/main/tokens.ts) files, and verifies the existence of a [`design.md`](https://github.com/Nutlope/hallmark/blob/main/design.md) file. If none are found, it reports “No design tokens” in the pre‑flight block.

### What font patterns does the pre‑flight scan recognize?

The scanner expects fonts to reference CSS variables such as `var(--font-display)` rather than hardcoded strings like `"Helvetica"`. According to [`skills/hallmark/references/slop-test.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/slop-test.md), any inline font or color that does not use a token variable is flagged for correction.

### Can Hallmark detect specific UI frameworks automatically?

Yes. The scan parses [`package.json`](https://github.com/Nutlope/hallmark/blob/main/package.json) for dependencies like `tailwindcss`, `framer‑motion`, `styled‑components`, `gsap`, and `motion‑one`. It also looks for framework‑specific config files (e.g., `tailwind.config.*`). If detected, Hallmark tailors its output to match the framework’s conventions.

### What happens if the pre‑flight scan finds no frameworks or tokens?

If the scan detects “vanilla HTML, no framework detected” and no design tokens, Hallmark generates a complete baseline setup including a Tailwind configuration, motion library scaffolding, and a comprehensive token system defined in CSS custom properties.