Skip to content

Foundations

Typography

Fonts, the text scale components use, and how to style headings and long-form content.

Components don't ship a font. They inherit font-family from your page and use Tailwind's text scale, so the type system is whatever your app sets on <body>.

Typography component

For headings, body text, lists, inline code and long-form content, use the Typography component. It renders plain elements with no "use client", so it works in server components.

Set a font

The examples, blocks and templates use Inter through next/font, exposed as Tailwind's --font-sans:

app/layout.tsxtsx
import { Inter } from "next/font/google";
import "./globals.css";

const inter = Inter({ subsets: ["latin"], variable: "--font-sans" });

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" className={inter.variable} suppressHydrationWarning>
      <body className="font-sans antialiased">{children}</body>
    </html>
  );
}
app/globals.csscss
@theme inline {
  --font-sans: var(--font-sans), ui-sans-serif, system-ui, sans-serif;
}

Any neutral sans works. Fonts with tabular figures (Inter, Geist, IBM Plex Sans) suit data-heavy screens: tables and stats in the library use tabular-nums.

The scale components use

WhereClassSize
Buttons, fields, menu items, table cells (md)text-sm14px
sm controls, badges, descriptions, field errorstext-xs12px
lg controlstext-base16px
Dialog titlestext-base font-semibold16px
Card titlestext-sm font-medium14px
Keyboard shortcuts, codefont-monoinherits

Body copy sits at 14px in dense product UI. For reading-heavy pages, set a larger base on the page container (text-base) and leave controls at their own sizes.

Hierarchy without extra sizes

Most screens need only three levels: a title, body text and muted secondary text.

tsx
<div className="grid gap-1">
  <h2 className="font-semibold text-lg tracking-tight">Billing</h2>
  <p className="text-muted-foreground text-sm">
    Manage your plan, payment method and invoices.
  </p>
</div>
  • Use text-muted-foreground for secondary text instead of a smaller size.
  • Use tracking-tight on headings 18px and larger.
  • Use text-balance on headings and text-pretty on paragraphs to avoid orphans.
  • Keep line length around 60–75 characters (max-w-prose) for long text.

Labels and descriptions

Form text comes from field.tsx, so all fields match:

PartStyle
Labeltext-sm font-medium, with a red * when the field is required
Descriptiontext-xs text-muted-foreground
FieldErrortext-xs text-destructive

Change those once in field.tsx to restyle every form.