Typography
Add these styles to your globals.css to apply the typographic scale to standard HTML elements. No component import required. Use native HTML tags directly.
Choosing fonts
Typography is often the first thing users perceive, before they read a word. A bad font breaks trust instantly. A good one disappears into the reading experience and lets the content do the work. Font choices affect readability, personality, and performance. DaFink UI doesn't bundle a font; we give you the scale and you supply the voice.
Font roles
Display
Hero headings and large feature text only, never body copy. Highly expressive at big sizes, unreadable small. If you use a display face, constrain it to h1 on marketing pages and nowhere else. The scale applies tracking-tight to headings, so pick a font that looks intentional at tight tracking, not squeezed.
Heading
Section titles, card headers, labels. Needs strong weight contrast from body so hierarchy is immediately clear. Sans-serifs with clear geometry work well; they read crisply at h2–h4 sizes and feel authoritative without shouting.
Body
The workhorse. Must be legible at 16–20px with good line spacing (~1.5). Neutral sans-serifs like Inter and Lato are standard because they never compete with the UI around them. Hard floor: 16px minimum. Below that, mobile browsers auto-zoom on focus and disorient users. Avoid condensed or display fonts at body size; they look striking in a specimen and exhausting in a product.
Monospace
Code blocks, terminal output, technical values. Always use monospace when showing code. The fixed-width columns signal “this is structured data” in a way no proportional font can replicate. IBM Plex Mono, JetBrains Mono, and Fira Code are top choices. Ligature support (→, =>, ≥) is useful but not worth sacrificing legibility.
Pairing rules
- •Two fonts maximum for most UIs (heading + body), three if you need a mono face for code. Beyond that you're just adding noise.
- •Contrast is the key rule. Heading and body need to feel different enough to create hierarchy and similar enough to feel unified. Avoid two fonts of the same style at the same weight.
- •The most reliable pairing: geometric or display heading + humanist sans-serif body. The geometry reads as structure; the humanism reads as warmth.
- •Variable fonts are worth it in 2026. One file covers every weight you need, no more loading separate 400/600/700 files. The performance win is real and the DX is better.
Performance
- •System font stacks load instantly: no network request, no layout shift. Use them when brand consistency isn't critical: internal tools, dashboards, admin UIs.
- •When loading custom fonts: subset to the character ranges you actually use, serve as WOFF2, and set
font-display: swapso text is visible immediately with a fallback while the custom font loads.
Line length
Keep body text at 50–75 characters per line. Around 66 is the sweet spot: enough to read in rhythm, short enough that the eye can find the next line without effort. Wider than that and reading flow breaks down; narrower and the constant line-breaking feels choppy. The max-w-2xl constraint on this page is intentional.
Recommended pairings
These combinations are tested against DaFink UI's token set across light and dark surfaces. Any of them drops in with no adjustments to the scale.
The neutral choice, works with every visual style. Inter's high x-height reads cleanly at 12px and looks authoritative at 48px. Available as a variable font via Fontsource. If you can't decide, start here.
npm install @fontsource-variable/inter @fontsource/jetbrains-monoRounder and friendlier than Inter without going cute. Works well for consumer-facing products. Variable weight axis from 200–800 in a single file.
npm install @fontsource-variable/plus-jakarta-sans @fontsource/jetbrains-monoDesigned together: display, body, and mono share optical metrics and feel like a single voice. Slightly more condensed than Inter; good for dense UIs.
npm install geistWiring it up
Import the font in your root layout, then set font-family on body in globals.css. The type scale inherits it automatically.
/* layout.tsx: import the font */
import '@fontsource-variable/inter';
import '@fontsource/jetbrains-mono';
/* globals.css: apply to body; the scale inherits it */
body {
font-family: 'Inter Variable', system-ui, sans-serif;
}
code, pre, kbd {
font-family: 'JetBrains Mono', ui-monospace, monospace;
}CSS snippet
@layer base {
h1 { @apply text-4xl font-bold tracking-tight text-text; }
h2 { @apply text-3xl font-semibold tracking-tight text-text; }
h3 { @apply text-2xl font-semibold tracking-tight text-text; }
h4 { @apply text-xl font-semibold text-text; }
p { @apply text-base text-text leading-7; }
blockquote { @apply border-l-2 border-surface-border pl-4 italic text-text-muted; }
code { @apply text-sm font-mono bg-surface-active px-1.5 py-0.5 rounded text-text; }
small { @apply text-xs text-text-muted; }
}Live preview
h1
The quick brown fox
h2
The quick brown fox
h3
The quick brown fox
h4
The quick brown fox
p (lead): text-xl text-text-muted leading-7
A lead paragraph introduces a section with slightly larger, muted text to ease the reader in before the main body.
p
Body text sits at the base size with a comfortable line-height. It is the default reading style for paragraphs and prose content across your UI.
blockquote
Good design is as little design as possible.
code
Inline code like const x = 42 appears inline within body text.
small
Caption or helper text rendered at the smallest size in the scale.