Body lead — a stand-out paragraph that introduces a section.
Body regular — standard reading text used for most paragraphs across the design system.
Body support — a quieter variant for secondary information.
Body caption — small text for figure captions and annotations.
Special
Overline (uppercase)
Mono — for inline code and snippets.
Adjacent-selector HTML defaults (inside <main>)
H1 in main → heading-title
P.lead in main → body-lead. Use this for the first paragraph after a heading when you want a softer intro.
P in main → body-regular. The default reading style for prose.
H2 in main → heading-section
Continuing body copy after the H2. And a small element rendered as caption.
H3 in main → heading-subsection
More body copy.
H4 in main → heading-group
The smallest heading in the in-document hierarchy.
/*
* Typography — foundation
*
* Adjacent-selector defaults per ADR-0009. The role utility classes
* (.font-display-hero, .font-heading-title, etc.) are generated
* automatically by @malevich/core's emit pipeline from semantic font
* tokens — this component only adds the HTML element defaults that
* map standard tags inside <main>/<article> to sensible roles.
*
* Defaults:
* main h1, article h1 → heading-title
* main h2, article h2 → heading-section
* main h3, article h3 → heading-subsection
* main h4, article h4 → heading-group
* main p, article p → body-regular
* main p.lead → body-lead
* main small,
* main figcaption → caption
*
* To override (e.g. landing-page H1 should be display-hero), apply
* the role utility class explicitly:
*
* <h1 class="font-display-hero">A semantic design system.</h1>
*/
@layer malevich.components {
main h1,
article h1 {
font-family: var(--font-heading-title-family);
font-size: var(--font-heading-title-size);
font-weight: var(--font-heading-title-weight);
line-height: var(--font-heading-title-line-height);
letter-spacing: var(--font-heading-title-letter-spacing);
}
main h2,
article h2 {
font-family: var(--font-heading-section-family);
font-size: var(--font-heading-section-size);
font-weight: var(--font-heading-section-weight);
line-height: var(--font-heading-section-line-height);
letter-spacing: var(--font-heading-section-letter-spacing);
}
main h3,
article h3 {
font-family: var(--font-heading-subsection-family);
font-size: var(--font-heading-subsection-size);
font-weight: var(--font-heading-subsection-weight);
line-height: var(--font-heading-subsection-line-height);
letter-spacing: var(--font-heading-subsection-letter-spacing);
}
main h4,
article h4 {
font-family: var(--font-heading-group-family);
font-size: var(--font-heading-group-size);
font-weight: var(--font-heading-group-weight);
line-height: var(--font-heading-group-line-height);
letter-spacing: var(--font-heading-group-letter-spacing);
}
main p,
article p {
font-family: var(--font-body-regular-family);
font-size: var(--font-body-regular-size);
font-weight: var(--font-body-regular-weight);
line-height: var(--font-body-regular-line-height);
letter-spacing: var(--font-body-regular-letter-spacing);
}
main p.lead,
article p.lead {
font-family: var(--font-body-lead-family);
font-size: var(--font-body-lead-size);
font-weight: var(--font-body-lead-weight);
line-height: var(--font-body-lead-line-height);
letter-spacing: var(--font-body-lead-letter-spacing);
}
main small,
article small,
main figcaption,
article figcaption {
font-family: var(--font-caption-family);
font-size: var(--font-caption-size);
font-weight: var(--font-caption-weight);
line-height: var(--font-caption-line-height);
letter-spacing: var(--font-caption-letter-spacing);
}
}
This component is pure CSS — no JavaScript required.
# Typography — AGENTS.md
> Auto-generated from `typography.docs.md` + the modifier applicability matrix.
> Edit those source files; this file regenerates on build.
## Identity
- **Component:** `typography`
- **Layer:** foundations
- **Status:** stable
- **Last updated:** 2026-05-19
## Summary
(no summary)
## Modifier applicability
Per ADR-0007. Modifiers attach via `data-{category}="value"` attributes.
| Category | Accepts |
|---|---|
| `background` | — |
| `surface` | — |
| `effect` | — |
| `shader` | — |
| `rhythm` | any value |
| `motion` | any value |
| `behavior` | — |
## Anatomy
```html
<!-- Default in-document typography (no classes needed) -->
<main>
<h1>Page title</h1>
<p class="lead">A lead paragraph stands out.</p>
<p>Standard body copy.</p>
<h2>Section heading</h2>
<p>More body copy. <small>A footnote.</small></p>
</main>
<!-- Override default to display-hero for landings -->
<main>
<h1 class="font-display-hero">A semantic design system.</h1>
<p class="font-body-lead">For humans and AI agents.</p>
</main>
<!-- Overline above a title -->
<div>
<span class="font-overline">v1.0 launch</span>
<h1 class="font-display-statement">Bigger ideas.</h1>
</div>
```
## Tokens consumed
All `font-{role}-*` semantic tokens. See ADR-0009 for the full role
inventory.
## Accessibility contract
- Default tag mappings preserve document outline. `<h1>` is still
`<h1>` semantically — the class affects only visual rendering.
- For pages where `<h1>` should be display-hero, apply the class
explicitly; don't reach for a smaller `<h1>` just to "make it look
big". Semantics first.
- Overline class adds `text-transform: uppercase`; consider whether
the visible text reads naturally in upper case or if it should be
Capitalized in source and uppercased only visually.
## Guidance
### Do
- Let `<main>` / `<article>` apply the defaults; only add `.font-*`
classes when the role needs to differ.
- Mark "lead" paragraphs with `class="lead"` for body-lead rendering.
### Don't
- Don't apply typography classes to `<h1>` just to change its size.
If the visual role is "display-hero", the semantic intent is also
display-hero — use the class. If the visual role is "heading-title",
no class needed.
- Don't combine multiple `.font-*` classes on one element — they
override each other unpredictably.