Skip to content

Typography

Two component families: headings (H1H6, each rendering its semantic HTML tag) and body text (<Text variant>). Use these instead of raw HTML + Tailwind classes — that’s what keeps the spec honest across surfaces.

import from "@na/ui/components/typography" ▶ Open in Storybook packages/ui/src/components/typography.tsx

When to use

  • Always. Any user-facing string that isn’t a button label, badge, or input value should be a <Text> or a heading.

Don’t use: <h2 className="text-lg">. That’s the smell — replace it with <H3>.

Headings

The H1H6 components are semantic — they render <h1> through <h6>. Pick by role on the page, not by the size you want.

H1 — page title (24px)

H2 — detail-page title (20px)

H3 — section heading (16px)

H4 — card title, form section (14px)

H5 — minor heading (12px)
H6 — minor heading (12px)
<H1>Page title (24px) — rare in admin</H1>
<H2>Detail page title (20px)</H2>
<H3>Section heading (16px) — most common</H3>
<H4>Card title (14px)</H4>
<H5>Minor heading (12px)</H5>
ComponentHTMLSizeUse
<H1><h1>24pxPage title (rare in admin)
<H2><h2>20pxDetail-page title
<H3><h3>16pxSection heading, page bar title
<H4><h4>14pxCard title, form-section title
<H5><h5>12pxMinor heading
<H6><h6>12pxMinor heading

Text variants

Body text has 4 tiers. Pick by role, not by aesthetic — the muted tier is for description-style copy, not “make it lighter for visual interest.”

Body — default 14px foreground.

Muted — descriptions, timestamps, metadata.

Label — non-form labels, table headers (12px medium).

Caption — small metadata, helper text (12px).

<Text variant="body">Body — default 14px foreground.</Text>
<Text variant="muted" as="p">Descriptions, timestamps, metadata.</Text>
<Text variant="label" as="p">Non-form labels, table headers.</Text>
<Text variant="caption" as="p">Small metadata, helper text.</Text>
VariantSizeWeightColorUse
body14px400foregroundDefault body text
muted14px400muted-foregroundDescriptions, timestamps
label12px500foregroundNon-form labels, table headers
caption12px400muted-foregroundSmall metadata, helper text

Polymorphic via as and asChild

<Text> defaults to <span>. Use as for a different tag, or asChild to project styles onto a child element (e.g., wrap an <a>).

A paragraph rendered with body styles.

A link rendered with muted styles
<Text as="p">A paragraph rendered with body styles.</Text>
<Text asChild variant="muted">
<a href="/path">A link rendered with muted styles</a>
</Text>

API

Heading components (H1H6)

Prop Type Default Description
asChild boolean false Project heading styles onto a child element via Radix Slot.
className string Forwarded.
...rest HTMLAttributes Native <h1>–<h6> attributes.

Text

Prop Type Default Description
variant "body" | "muted" | "label" | "caption" "body" Type tier — see table above.
as "span" | "p" | "div" "span" Underlying tag.
asChild boolean false Project Text styles onto a child element via Radix Slot.
className string Forwarded.

Design guidelines

✓ Do

  • Pick the heading by role on the page (H3 = section heading), not by the pixel size you want.
  • Use Text variant="muted" for any descriptive paragraph next to a heading.
  • Use Text asChild to wrap an <a> when the link should look like body text, not a button.

✗ Don't

  • Reach for <h2 className="text-lg">. The whole point of these primitives is to remove that decision from the call site.
  • Add custom font sizes via className. The system has 6 heading sizes + 2 body sizes; that is the contract.
  • Use the muted variant for visual variety. It only means "this is secondary content."

Accessibility

  • Heading hierarchy on a page: one H1 (or zero — many admin surfaces don’t have one), one H2 for the page topic, H3 for sections, H4 inside.
  • Don’t skip levels. Screen readers expose heading nesting.
  • Color contrast is enforced by the underlying tokens — both foreground and muted-foreground meet AA in light + dark.
  • Label — Form-field labels (different from Text variant="label").
  • Card — Includes CardTitle / CardDescription styled to match this scale.

▶ Open Typography stories in Storybook