Typography
Every font is a self-hosted variable font from Fontsource. Nothing is requested from Google Fonts, so there is no third-party request and no cookie banner question.
| Family | Used by | Width axis |
|---|---|---|
| Archivo | Signal, Mono (display and body) | 62% to 125% |
| Instrument Sans | Cobalt (display and body), Forest (body) | 75% to 100% |
| Bricolage Grotesque | Forest (display) | 75% to 100% |
| JetBrains Mono | All presets (code, meta labels) | none |
Each preset sets three families as CSS variables, which Tailwind exposes as classes:
| Variable | Tailwind | Use |
|---|---|---|
--font-display |
font-display |
Headings and display type |
--font-body |
font-sans |
Body copy and UI |
--font-mono |
font-mono |
Meta labels, code, numbers |
Fonts a preset doesn’t use cost a few bytes of @font-face rules and are never downloaded.
Type classes
Section titled “Type classes”| Class | Style | Use |
|---|---|---|
.type-display |
Display font, 800 weight, uppercase, wide | Big numbers, labels in bento cells |
.type-heading |
Display font, 700 weight, slightly wide | Section headings |
.type-meta |
Mono, small, uppercase, muted | Eyebrow labels. At most one per three sections |
.prose-swift |
Long-form rhythm: headings, lists, quotes, code | Journal articles and legal pages |
Combine them with the type scale: <h2 class="type-heading text-3xl">.
The width axis
Section titled “The width axis”The theme’s signature is type that stretches. Archivo, Instrument Sans and Bricolage Grotesque all have a variable width axis, and the theme animates it:
- Links and titles with
.stretchwiden when their.stretch-hostparent is hovered or focused. - The footer wordmark opens from condensed to full width as it scrolls into view.
- The 404 number follows the cursor.
<a href="/work" class="stretch-host"> <span class="stretch">View work</span></a>The range comes from the preset: Archivo rests at 100% and opens to 125%; the narrower families rest condensed at 84% and open to 100%.
Fallback fonts and layout shift
Section titled “Fallback fonts and layout shift”While a web font loads, the browser shows a local font. If the two have different metrics, text jumps when the web font arrives, which Lighthouse counts as layout shift (CLS).
src/styles/fallbacks.css defines a fallback for every family: Arial (or Courier New for mono) resized with size-adjust and ascent and descent overrides so it takes up the same space. Display type gets its own wider fallback, because headings are set on the width axis and no local font can imitate that. This is what keeps mobile CLS under 0.05 on every page.
Add a font
Section titled “Add a font”-
Install it from Fontsource, preferably the variable version:
Terminal window npm install @fontsource-variable/inter -
Import it at the top of
src/styles/global.css. Usewdth.cssif the font has a width axis, otherwiseindex.css:src/styles/global.css @import '@fontsource-variable/inter/index.css'; -
Add a stack in
src/config/presets.tsand use it in a preset:src/config/presets.ts const inter ='"Inter Variable", "Inter Variable Fallback", ui-sans-serif, system-ui, sans-serif'; -
Optional, but it keeps CLS at zero: generate a fallback with Capsize and paste it into
fallbacks.css, named after your stack (Inter Variable Fallback).// npm install -D @capsizecss/core @capsizecss/metrics, then run with nodeimport { createFontStack } from '@capsizecss/core';import inter from '@capsizecss/metrics/inter';import arial from '@capsizecss/metrics/arial';console.log(createFontStack([inter, arial]).fontFaces);
If the new font has no width axis, the stretch effect simply does nothing. Set the preset’s stretch values all to '100%' to make that explicit.