We Built a Type Lab to Pick One Font Pairing
Our site ran Inter for everything: headings, body, numbers, labels. It worked fine. It also looked like every other AI agency site built in the last two years. The commit comment we had to write for the type-lab page was "Baseline for comparison. Clean, but the default AI-SaaS stack." That was the problem statement.
The Type Lab
Before we committed to any new typeface, we built a temporary page at /type-lab. It was noindexed and meant to be deleted. Its only job was to render five font pairings side-by-side in actual components: a hero section with a headline, a body paragraph, and a card with a stat and label.
The five pairings we tested:
- 0. Inter + JetBrains Mono — what was live. The comparison baseline.
- A. Fraunces + Inter — warm, literary, editorial. The paid version of this would be Signifier + Söhne from Klim Type Foundry.
- B. Newsreader + Geist — sharp, contemporary, more tech-luxury.
- C. Fraunces + Space Grotesk — higher contrast, characterful.
- D. Instrument Serif + Instrument Sans — airy, refined, elegant.
Each panel in the lab showed the display font italic on the hero headline, the body font on descriptive copy, and the mono font on a small label. We also annotated each pairing with the premium foundry typeface it was approximating. The reasoning: if this pairing eventually feels limiting, what would we upgrade to?
What We Shipped
We picked Fraunces + Inter. The headline set in italic Fraunces reads like something that cost money. The Inter body underneath it is familiar enough that reading stays effortless. Together they hit a register between editorial and professional without sliding into "corporate blog."
The CSS rule is simple:
h1,
h2,
h3 {
font-family: var(--font-fraunces), Georgia, "Times New Roman", serif;
letter-spacing: -0.015em;
}
That's it. The entire heading stack gets serif by default. Any heading that needs to opt out uses Tailwind's font-sans utility, and the type system backs off.
The Constraint That Drove the Final Call
Fraunces is scoped to headings only by design. Stat figures stay Inter.
When we were testing pairings, we noticed that oldstyle numerals in a serif often look elegant in long-form editorial but awkward sitting next to a label in a card. "324 clients served" in Fraunces felt like a typographic choice that wanted to be noticed. "324 clients served" in Inter just says the number.
Stats are data. Headings are voice. We wanted those to behave differently, so we didn't apply the serif globally.
Why a Throwaway Page
The alternative was iterating on the live site or swapping CSS variables back and forth in dev. Both approaches make it hard to compare. When you change a global font and reload, your eye adapts. After two minutes in the new font you can't remember what the old one looked like.
The type-lab rendered all five pairings in a single scroll. You could read the hero of pairing A and immediately drop to the hero of pairing B with your eye still calibrated. That compression is the point. It took about an hour to build, and we deleted it the same day we picked Fraunces.
The next time we're evaluating a major visual direction change, we'll probably build another throwaway like this. A comparison page is cheaper than your own uncertainty.