Skip to content
HyperDesign System

Typography

One family, Geist, in sans and mono. Each text-* size carries its own line-height and tracking, and the heading sizes carry the heading weight, so one class sets a whole role.

Usage

Pair font-heading with a size from text-xl up for headings. Copy takes a size and nothing else; labels add a weight.

// Headings: font-heading marks the role; text-<size> carries size,// line-height, tracking and the heading weight together.<h1 className="font-heading text-3xl md:text-4xl">Agents</h1><h2 className="font-heading text-2xl">Recent runs</h2> // Copy: size only. Weight stays at 400 unless the text names a control.<p className="text-base text-muted-foreground">Ask about a run or a file.</p><p className="text-md text-foreground-low">Updated 2 hours ago</p> // Labels and data<span className="text-sm font-medium">Share profile</span><span className="text-label-12-caps text-foreground-low">Suggested</span><code className="text-label-14-mono">npm run dev</code>

Families

Loaded once by next/font on <html>; the stacks fall back to the system UI face.

Font families
ExampleTokenUsage
Geist SansProse, headings, labels, controls, tables and figures. The default on <html>.Geist · next/font
Geist HeadingMarks a heading in markup. An alias of the sans today: the one line to point at a display face.var(--font-sans)
Geist MonoCode, commands, paths, raw tokens, timestamps and short identifiers. Never as a technical costume.Geist Mono · next/font

Weights

Four weights and nothing else. Hover and selected states never change weight.

Font weights
ExampleClass nameUsage
Regular 400Copy, labels that describe, table cells.--font-weight-normal · 400
Medium 500Buttons, chips, tabs, labels that name a thing, strong inside a label.--font-weight-medium · 500
Strong 550Strong inside running copy, a half step above the text around it.--font-weight-strong · 550
Semibold 600Every heading role. Small headings at body size set it by hand.--font-weight-semibold · 600
Heading weightThe knob the heading sizes read (text-xl and up, text-display, heading classes, prose headings).var(--font-weight-semibold)

Headings

Semibold, tightening as they grow: −0.02em at 20px, −0.06em from 40px.

Heading styles
ExampleClass nameUsage
Heading 48The one page-defining statement. Fluid from 40 to 48px with the viewport.40→48 / 1.15 · −0.06em · 600
Heading 48Display statement at a fixed size: marketing heroes, empty-state headlines.48/56 · −0.06em · 600
Heading 40The page title from md up.40/48 · −0.06em · 600
Heading 32Page title on narrow screens, tile names.32/40 · −0.04em · 600
Heading 24Major section turns, dialog titles. The h2 on these docs pages.24/32 · −0.04em · 600
Heading 20Nested structure, subsection headings, answer h2.20/26 · −0.02em · 600
Heading 18Row and card titles.18/28 · −0.02em · 600
Heading 16A heading that sits at body size. No token of its own; tracking stays at 0.16/24 · 0 · 600
Heading 14Group headings in dense UI: settings sections, panel titles.14/20 · 0 · 600

Copy

Regular weight, zero tracking. Hierarchy in copy comes from size and the text tier, not weight.

Copy styles
ExampleClass nameUsage
Copy 18, a short orientation passage.Lede: one passage under a page title. The lead on these docs pages from md.18/28 · 0 · 400
Copy 16, the body of an answer.Body, the composer, suggested questions, chat messages.16/24 · 0 · 400
Copy 14, dense UI and table cells.Secondary copy in panels, table cells, settings descriptions.14/20 · 0 · 400
Updated 2 hours ago · 3 collaboratorsMetadata and captions, usually on the third text tier.13/18 · 0 · 400
By continuing you agree to the Terms.Footers, disclaimers, keycaps. The smallest size the app sets.12/16 · 0 · 400
Copy with strong emphasis.Strong inside copy. 550, not 600, so emphasis never reads as a heading.inherits size · 550

Labels

Short text that names or measures something: controls, group labels, identifiers, figures.

Label styles
ExampleClass nameUsage
Share profileButton, chip and tab labels; a label that names a thing.14/20 · 0 · 500
Behavior designSmall control labels and a card's sentence-case label.12/16 · 0 · 500
Suggested questionsUppercase label over a group of cards, table headers. Tracking travels with the caps.12/16 · +0.06em · 500
npm run brand:check-contrastAn identifier, command or token set in mono. Tabular figures, slashed zero.14/20 · mono · 400
v2.4.0 · 1,234.56 msFigures and provenance only: a measured number, a version, a citation.12/16 · mono · 400

Best practices

Hierarchy

  • One text-heading-display or text-4xl per page; step down one size per level.
  • Separate levels with size and the text tier (foreground, muted-foreground, foreground-low) before weight.
  • Hold copy to a 65ch measure; balance headings with text-balance and wrap copy with text-pretty.

Mono and figures

  • Mono is for code, commands, tokens and measured figures. A label that names a thing stays in the sans.
  • Numbers that change in place (counters, timers, prices) use a mono label class or tabular-nums so nothing shifts.
  • Never invent a weight: anything outside the four above fails npm run brand:lint-tokens.