Skip to content

AI Rules

The authoritative rules ship with @airframeui/core as @airframeui/core/rules (AIRFRAME_RULES.md). This page is the docs summary agents and humans should follow when generating markup.

Prefer these entry points over scraping the whole site:

After npm install @airframeui/core, load in-project resources:

// JSON (safe to import in Node / bundlers)
import catalog from '@airframeui/core/catalog'; // component metadata
import classes from '@airframeui/core/classes'; // class reference
import examples from '@airframeui/core/examples'; // code examples

// Markdown — resolve the package export and read as text (do not assume a JS default export)
// @airframeui/core/rules  → AIRFRAME_RULES.md
// @airframeui/core/ai     → AI_INTEGRATION.md
  • Semantic HTML first<button>, <a>, <label>, real headings
  • Token-first theming — prefer --af-color-* / other --af-* tokens; do not invent unknown token names
  • Readable DOM — avoid utility soup; prefer patterns + layout recipes
  • af- prefix — only use known Airframe classes (see @airframeui/core/classes)
  • Minimal classes — components include sensible defaults; don’t restate them
  • Modifiers — variants/state use af-is-* (e.g. af-btn af-is-primary, af-btn af-is-outline)
  • Responsive — breakpoint suffixes use @ in HTML: af-grid-2@md, af-stack@lg
  • Framework attrsclass in HTML/Vue/Angular/Astro; className in React

Runtime CSS variable overrides are the default. When mapping an existing design system into Airframe tokens:

  • Theme Studio — upload Tokens Studio / DTCG / CSS / Figma Variables and export theme.css
  • CLInpx af theme generate --from ./tokens.json -o theme.css (via @airframeui/build)
  • MCP@airframeui/mcp tools: generate_theme, map_tokens, lint_theme, validate_theme
  • Rules@airframeui/theme/rules and @airframeui/theme/mapping after npm install @airframeui/theme

See Theming and Build Tool.

Canonical patterns (aligned with AIRFRAME_RULES.md):

Cards already display: flex; flex-direction: column with a default gap (--af-space-4). Do not add redundant stack/gap.

<!-- ✅ Good: default card stacking -->
<div class="af-card">
  <h2 class="af-card__title">
    Title
  </h2>
  <div class="af-card__body">
    Content
  </div>
</div>
<!-- ❌ Avoid: redundant stack/gap on cards -->
<div class="af-card af-stack af-gap-md">
  <h2 class="af-card__title">
    Title
  </h2>
  <div class="af-card__body">
    Content
  </div>
</div>

af-grid-* includes grid display. Default gap is --af-space-3 (same as af-gap-md).

<!-- 2 equal columns -->
<div class="af-grid af-grid-2 af-gap-lg">
  <div>
    Item 1
  </div>
  <div>
    Item 2
  </div>
</div>
<!-- Responsive equal columns -->
<div class="af-grid af-grid-1 af-grid-2@md af-grid-3@lg af-gap-lg">
  <div>
    Item 1
  </div>
  <div>
    Item 2
  </div>
  <div>
    Item 3
  </div>
</div>
<div class="af-grid">
  <div class="af-col-span-8@lg">
    Main content
  </div>
  <div class="af-col-span-4@lg">
    Sidebar
  </div>
</div>

Note: af-grid:has(> [class*='af-col-span']) switches to 12 columns. Default gap is --af-space-3 (af-gap-md). Override with af-gap-sm / af-gap-lg when needed.

<div class="af-stack af-gap-lg">
  <header class="af-inline af-justify-between">
    <h1>
      Title
    </h1>
    <div class="af-inline af-gap-sm">
      <button type="button" class="af-btn">
        Action
      </button>
    </div>
  </header>
</div>
<!-- ✅ Good: semantic element, no class needed -->
<h1>
  Title
</h1>
<p>
  Body text
</p>
<!-- ✅ Good: visual override when semantics differ -->
<h2 class="af-text-h1">
  Visually H1, semantically H2
</h2>
<p class="af-text-caption">
  Caption
</p>
<!-- ❌ Avoid: redundant class on semantic element -->
<h1 class="af-text-h1">
  Title
</h1>