Typography

Three font families and 19 composite text style classes. Each class encodes font, size, weight, line-height, and tracking as a single token — apply one class per element rather than composing utilities.

Setup

Wire it up

Three pieces, all in plain CSS. Load IBM Plex Sans, IBM Plex Mono, and Space Grotesk via Google Fonts (or your framework's font helper) and expose them as the CSS variables --font-ibm-plex-sans, --font-ibm-plex-mono, and --font-space-grotesk on the document root. The @theme block aliases them; the composite classes consume them.

CSS·1. Alias fonts in @theme src/app/globals.css
@theme {
  /* Font families exposed to Tailwind utilities (font-sans, font-mono,
     font-heading) and consumable as var(--font-sans) etc. The CSS variables
     they reference (--font-ibm-plex-sans, --font-ibm-plex-mono,
     --font-space-grotesk) must be set on the document root by whatever loads
     the fonts in your app. */
  --font-sans:    var(--font-ibm-plex-sans),    system-ui, sans-serif;
  --font-heading: var(--font-space-grotesk),    system-ui, sans-serif;
  --font-mono:    var(--font-ibm-plex-mono),    ui-monospace, monospace;
}
CSS·2. Define composite classes src/app/globals.css
/* Composite text classes — each encodes font, size, weight,
   line-height, and tracking as a single token. Apply ONE class per
   text element — don't compose with text-[14px] font-medium. */

/* Headings — Sans */
.heading-30 { font-family: var(--font-sans); font-size: 30px; font-weight: 500; line-height: 40px; letter-spacing: 0; }
.heading-24 { font-family: var(--font-sans); font-size: 24px; font-weight: 500; line-height: 32px; letter-spacing: 0; }
.heading-20 { font-family: var(--font-sans); font-size: 20px; font-weight: 500; line-height: 24px; letter-spacing: 0; }

/* Headings — Grotesk */
.heading-30-grotesk { font-family: var(--font-heading); font-size: 30px; font-weight: 500; line-height: 40px; letter-spacing: -0.02em; }
.heading-24-grotesk { font-family: var(--font-heading); font-size: 24px; font-weight: 500; line-height: 32px; letter-spacing: -0.02em; }
.heading-20-grotesk { font-family: var(--font-heading); font-size: 20px; font-weight: 500; line-height: 24px; letter-spacing: -0.01em; }

/* Copy — Sans */
.copy-16        { font-family: var(--font-sans); font-size: 16px; font-weight: 400; line-height: 20px; letter-spacing: 0; }
.copy-16-medium { font-family: var(--font-sans); font-size: 16px; font-weight: 500; line-height: 20px; letter-spacing: 0; }
.copy-14        { font-family: var(--font-sans); font-size: 14px; font-weight: 400; line-height: 18px; letter-spacing: 0; }
.copy-14-medium { font-family: var(--font-sans); font-size: 14px; font-weight: 500; line-height: 18px; letter-spacing: 0; }
.copy-12        { font-family: var(--font-sans); font-size: 12px; font-weight: 400; line-height: 16px; letter-spacing: 0; }
.copy-12-medium { font-family: var(--font-sans); font-size: 12px; font-weight: 500; line-height: 16px; letter-spacing: 0; }
.copy-10        { font-family: var(--font-sans); font-size: 10px; font-weight: 500; line-height: 13px; letter-spacing: 0; }

/* Copy — Mono */
.copy-14-mono          { font-family: var(--font-mono); font-size: 14px; font-weight: 500; line-height: 18px; letter-spacing: 0; }
.copy-12-mono          { font-family: var(--font-mono); font-size: 12px; font-weight: 500; line-height: 16px; letter-spacing: 0; }
.copy-12-mono-semibold { font-family: var(--font-mono); font-size: 12px; font-weight: 600; line-height: 16px; letter-spacing: 0; }
.copy-10-mono          { font-family: var(--font-mono); font-size: 10px; font-weight: 500; line-height: 13px; letter-spacing: 0; text-transform: uppercase; }

/* Buttons */
.button-14 { font-family: var(--font-sans); font-size: 14px; font-weight: 500; line-height: 20px; letter-spacing: 0; }
.button-12 { font-family: var(--font-sans); font-size: 12px; font-weight: 500; line-height: 16px; letter-spacing: 0; }
TSX·3. Use in templates
// Treat composite classes like a token — one className per text element.
// Don't compose with text-[14px] font-medium etc.

<h1 className="heading-30">Page title</h1>
<h2 className="heading-24">Section header</h2>
<p className="copy-14 text-content-secondary">Body copy.</p>
<code className="copy-12-mono">inline-code</code>
<button className="button-14">Save</button>
info

These are CSS classes defined in globals.css, not Tailwind utilities. Use them as className="copy-14", not as text-[14px] font-normal.

Families

Font families

IBM Plex Sans for product UI, Space Grotesk for expressive headings, IBM Plex Mono for code and data.

Space Grotesk

--font-heading
.font-heading

Ag

Aa

Medium

500

Aa

Bold

700

IBM Plex Sans

--font-sans
.font-sans

Ag

Aa

Regular

400

Aa

Medium

500

IBM Plex Mono

--font-mono
.font-mono

Ag

Aa

Medium

500

Aa

Semibold

600

Sans

Headings — Sans

IBM Plex Sans headings for product UI.

Sample

Class

Font

Weight

Size / Lead

Usage

Heading 30

Sans

Medium / 500

30 / 40

Page titles

Heading 24

Sans

Medium / 500

24 / 32

Section headers

Heading 20

Sans

Medium / 500

20 / 24

Subsection headers

Grotesk

Headings — Grotesk

Space Grotesk headings for expressive and marketing contexts.

Sample

Class

Font

Weight

Size / Lead

Usage

Heading 30 Grotesk

Grotesk

Medium / 500

30 / 40

Marketing titles

Heading 24 Grotesk

Grotesk

Medium / 500

24 / 32

Marketing sections

Heading 20 Grotesk

Grotesk

Medium / 500

20 / 24

Marketing subsections

Body

Copy

Body, captions, labels, and inline code.

Sample

Class

Font

Weight

Size / Lead

Usage

Copy 16

Sans

Regular / 400

16 / 20

Larger views

Copy 16 Medium

Sans

Medium / 500

16 / 20

Copy 14

Sans

Regular / 400

14 / 18

Most body text

Copy 14 Medium

Sans

Medium / 500

14 / 18

Copy 14 Mono

Mono

Medium / 500

14 / 18

Largest mono

Copy 12

Sans

Regular / 400

12 / 16

Tertiary text

Copy 12 Medium

Sans

Medium / 500

12 / 16

Copy 12 Mono

Mono

Medium / 500

12 / 16

Inline code

Copy 12 Mono Semibold

Mono

Semibold / 600

12 / 16

Copy 10

Sans

Medium / 500

10 / 13

Notes

Copy 10 Mono

Mono

Medium / 500

10 / 13

Eyebrows, labels

Buttons

Buttons

Reserved for button labels.

Sample

Class

Font

Weight

Size / Lead

Usage

Button 14

Sans

Medium / 500

14 / 20

Button 12

Sans

Medium / 500

12 / 16