Heading

Names a page or a section in Archivo, expanded, at one of four sizes, so the reader can scan the argument by its headings alone.

Atom · stable · v1.0.0 · owner: Site system lead · contract 19 of 20 points (open: figma)

Do and don't

Do: A compact section title

Rendered by heading.ts

Open example: Heading · Do: A compact section title Use the full-page example to follow page links.

The heading keeps its section level while using the smaller existing type role.

Do: A section title

Rendered by heading.ts

Open example: Heading · Do: A section title Use the full-page example to follow page links.

A claim the reader can scan.

Do: A card title

Rendered by heading.ts

Open example: Heading · Do: A card title Use the full-page example to follow page links.

h3 keeps the outline right inside a section.

Don't: Capitals as a label

Rendered by heading.ts

Open example: Heading · Don't: Capitals as a label Use the full-page example to follow page links.

Capitals are banned and 'Overview' says nothing.

Don't: A display size on a section

Rendered by heading.ts

Open example: Heading · Don't: A display size on a section Use the full-page example to follow page links.

Display is for the h1 only; on a section it breaks words in a column.

Rules

RuleWhyCheck
Exactly one h1 per page.Screen-reader users jump to the h1 to learn what the page is about.Automated: scripts/site/system/compose.ts (outline check)
Heading levels never skip.A skipped level suggests missing content.Automated: scripts/site/system/compose.ts (outline check)
A heading never breaks inside a word or overflows its box.Broken words ('engagem/ent') look like a mistake and lose the word (owner, 26 Oct).Automated: tests/site/headings.spec.ts (every page, 1440 and 390)
Section headings use the h2 size, never display.Display at 96 px does not fit a half-page column without breaking words.Automated: tests/site/headings.spec.ts (h2 at most 56 px)

API

PropTypeRequiredDefaultWhat it does
level1 | 2 | 3YesThe outline level.
textstringYesThe heading text.
idstringNoThe anchor target and the section's accessible name.
sizedisplay | h2 | h3NoThe visual size when it differs from the level (the hero h1 is display).
htmlbooleanNofalseThe text already contains inline markup (Japanese <wbr>).
extraClassstringNoA class owned by the parent element.

Contract details

The full contract: identity, anatomy, variants, states, tokens, layout, motion, accessibility, content, tests

Identity

AspectValue
Idheading
LayerAtoms
Categorytypography
OwnerSite system lead
Statusstable
Version1.0.0
Sourceapps/showcase/site/system/atoms/heading.ts (private repository; the contract and the render function are this one module)
VersionDateChange
1.0.02026-10-26Four sizes (display, h2, h3, Japanese display); headings never break inside a word.

Use when

  • A page title (one h1) or a section title (h2). Why: Headings are how people and screen readers move through a page.
  • A card, tile or step title (h3). Why: A smaller heading keeps the outline correct inside a section.

Do not use when

  • To make text big for emphasis. Why: Size without structure breaks the outline screen readers navigate by.
  • Skipping a level (h2 to h4). Why: Skipped levels make people think a section is missing.

Anatomy

PartWhat it is
rooth1, h2 or h3 with the type role of its size.

Made of: tokens:type.

Used in: figure-frame, atomic-guide, contact-form, contents, faq-list, jobs-strip, library-grid, panel, showcase-frame, status-table, cta-section, flow-section, founder-section, hero, job-section, lead-section, page-head, problem-section, proof-section, related, roadmap-strip, roles-section, titled-section.

Variants

VariantWhenWhy
displayThe page's h1 only.One very large line sets the page's subject; more than one would compete.
h2Section titles, capped at 56 px.Large enough to carry a section, small enough that the longest word fits a column.
h3Cards, tiles and steps, 20 to 24 px.Three-column grids need titles that fit a third of the page without breaking words.

States

StateRendered or not applicable
defaultdefault
hoverNot applicable: A heading is not interactive, so it has no hover state.
focus-visibleNot applicable: Headings receive focus only from the skip link and in-page anchors, where the outline is suppressed (main:focus, h1:focus).
activeNot applicable: A heading cannot be pressed.
disabledNot applicable: A heading has nothing to disable.
loadingNot applicable: A heading is rendered at build time and is complete when the page loads.
emptyNot applicable: A heading is not rendered without content; the builder skips it.
errorNot applicable: A heading shows no data that can fail.
currentNot applicable: A heading has no current item.
visitedNot applicable: A heading is not a link.
expandedNot applicable: A heading does not open or close.

Tokens

PartToken
display.font--type-display
h2.font--type-h2 (30 to 56 px)
h3.font--type-h3 (20 to 24 px)
root.letter-spacing--ls-display / --ls-h2 / --ls-h3
ja.font--font-display-ja, letter-spacing 0, normal width
--heading-font-type-h1var(--type-h1)
--heading-letter-spacing-ls-h1var(--ls-h1)
--heading-font-type-h2var(--type-h2)
--heading-letter-spacing-ls-h2var(--ls-h2)
--heading-font-type-h3var(--type-h3)
--heading-letter-spacing-ls-h3var(--ls-h3)
--heading-font-weight-weight-heavyvar(--weight-heavy)
--heading-font-size-fs-h2var(--fs-h2)
--heading-font-size-fs-h3var(--fs-h3)

Layout

AspectValue
max22ch for h2 in prose; none for the display
breakpointsRequired review at 390, 768, 1024 and 1440 px; execution is not implied by this declaration; sizes are fluid between their minimum and maximum.
wrappingBalanced lines, no hyphens, no break inside a word (overflow-wrap normal); Japanese breaks between phrases with line-break strict.
textExpansionChecked at 390 and 1440 by tests/site/headings.spec.ts on every page; Japanese steps down to h3 under 360 px.

Spacing and rhythm

AspectValue
internalLine height 0.9 (display), 1 (h2), 1.2 (h3).
external--space-7 after an h2 in prose; more space above a heading than below.
rhythmOpens every section (D-SITE-005).

Motion

AspectValue
NoneHeading has no intrinsic animation. On generated Site pages, the document shell may apply the registered once-only claude-entrance profile to eligible below-fold section headings (20px, --dur-weave/--ease-enter with capped --stagger). Standalone Heading output remains static; content is never hidden, and reduced motion removes that transform through the shell's .motion-ok policy.

Runtime and reuse

  1. Render-only element; mount any registered child enhancements separately. Preserve required Site CSS, fonts, responsive and locale rules from nativeElement.

Accessibility passport

AspectValue
roleheading, with its level
nameIts text
keyboardNot interactive.
focusOnly via skip link or anchor.
screenReaderAnnounced with its level; one h1 per page.
contrastInk on cotton 15.9:1; cotton on every dye 7:1 or better; dark on saffron 9.1:1.
targetNot a target.

Content

SlotLengthVoice
textDisplay 6 words, h2 12 words, h3 8 wordsA claim or a plain name, sentence case, no full stop in Japanese card headings

Good: “The next level of your design system.” · “Every week, a design system drifts a little.”

Bad: “Introducing our innovative solution” · “OVERVIEW”

Japanese: Text comes from the page content; Japanese strings are reviewed per page (apps/showcase/site/loom/locales). Awaiting native review, as the banner on every Japanese page says.

Icons and illustrations

None: this element uses no icon or illustration of its own.

Decisions and exceptions

Usage

298 uses across the built pages (measured by npm run site:system).

Tests

AspectValue
unittests/unit/site-system.test.ts: renders every do and don't example through the registry and checks the classes it owns
visualNot yet: there are no screenshot baselines; the Library page is checked for sideways scroll at 1440 px by tests/site/system.spec.ts
a11ytests/site/system.spec.ts: axe (0 serious or critical) on the element's Library page in light and dark
parityscripts/site/system/check.ts: Library examples are rendered by the same render function the site imports

Figma

not-yet: The Loom Site Figma library is the last stage of the plan; this element is not mapped yet.

Open in Storybook

Start with a conversation about your system.

We read your system, show you what we found, and agree with your team what to fix first.