Typography

Typography is the primary interface of this site. Size, weight, family, and spacing create all hierarchy. Not color, not borders, not backgrounds. Two typefaces carry the entire system, each with a distinct voice and a clear boundary of use.

For the complete type scale with every CSS value, see the implementation spec.


Two voices

Signifier (the reading voice)

Signifier is a variable serif by Klim Type Foundry. Transitional in classification, warm enough for long-form reading, sharp enough for display sizes. Its variable axis (weight 100-900) allows subtle modulation without loading multiple files.

Signifier handles everything the reader spends time with: body prose, headings (h1, h2), pull quotes, blockquotes, drop caps, the nameplate, breadcrumb names. If text is meant to be read at length, it’s set in Signifier.

--font-serif: 'Signifier', Georgia, serif

Montreuil (the functional voice)

Montreuil is a humanist sans by 205TF. Its construction pairs naturally with Signifier without competing for attention. Loaded in three weights (400, 500, 600) plus italic.

Montreuil handles everything that orients the reader: navigation labels, section headings (h3), dates, captions, meta text, the footer, category pills. If text is functional rather than literary, it’s set in Montreuil.

--font-sans: 'Montreuil', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif

Supporting voices

Caveat (Google, variable handwritten) is the editorial voice. It appears only in “must read” marginalia annotations on link posts, where a handwritten note should feel personal and informal. Desktop only, at widths above 1080px.

SF Mono (system monospace) is the technical voice. Code blocks and inline code use the system monospace stack, avoiding an additional font download.

--font-mono: 'SF Mono', ui-monospace, monospace


Type scale

The scale is organized by context rather than abstract size names. Each entry has a specific typographic role that determines its family, weight, and size.

Nameplate and navigation

ElementFamilySizeWeightNotes
Homepage nameplateSignifier2.5rem400Not a link on the homepage
Interior nav nameSignifier1.1rem400Weight shifts to 500 on hover
Breadcrumb currentSignifier1.1rem400--text-2 color

Headings

ElementFamilySizeWeightNotes
Article h1Signifier2rem400Letterpress text-shadow
Default h1Signifier1.5rem400Non-article pages
h2Signifier1.2rem400Letterpress text-shadow
h3Montreuil0.75rem600All-caps, 0.08em tracking. The typeface shift to sans creates hierarchy without needing a larger size

Body and editorial

ElementFamilySizeWeightNotes
Body proseSignifier1rem (15px base)400--text-2, line-height 1.6
Lede paragraphSignifier1.1rem400--text color, first paragraph of articles
Pull quote (centered)Signifier1.25rem400 italicCentered, no borders
Pull quote (light)Signifier1.35rem340 italicHanging open-quote, letterpress shadow

Meta and UI

ElementFamilySizeWeightNotes
Section labelMontreuil0.7rem600All-caps, 0.05em tracking
Post list dateMontreuil0.85rem400tabular-nums
Article metaMontreuil0.85rem400tabular-nums, 0.02em tracking
Footer navMontreuil0.9rem400--text-2
Footer colophonMontreuil0.75rem400--text-3
Figcaptioninherited0.85rem400 italic--text-2
Inline codeSF Mono0.85em400--code-bg background

The full table with line-height, letter-spacing, and color for every element is in the implementation spec.

Typography is the primary interface.


Responsive behavior

The site uses fixed sizes with a single step-down at 600px. The base font size drops from 15px to 14px, and everything sized in rem scales proportionally.

Fluid type (clamp-based scaling) was considered and rejected. At the scale of a personal site with a single content column, it adds implementation complexity without meaningful benefit. One clean breakpoint does the job.

What changes at 600px

  • Base font size: 15px to 14px
  • Drop cap: disabled (resets to inherited size, no float)
  • Pull quotes: size and spacing reduce
  • Article h1: may reduce
  • Navigation: collapses to simplified layout
  • Section labels and pills: stack vertically where they were inline

What stays the same

  • Line-height ratios (1.6 for body, 1.2-1.3 for headings)
  • Font families and weight relationships
  • The two-voice system and all semantic roles
  • Letter-spacing values

Typographic details

Drop cap

The first letter of the first paragraph in article posts gets a drop cap: Signifier at 3.5rem, floated left, weight 450. It uses --text color, not accent. The drop cap is decorative (a book convention), not interactive.

A subtle letterpress text-shadow adds dimensionality in both modes. At 600px and below, the drop cap is fully disabled: no float, no size increase, no special treatment. Drop caps don’t work well on narrow screens where they consume too much horizontal space. See the specimen below for a live example.

Letterpress text-shadows

h1, h2, h3, and pull-quote-light elements use dual text-shadows that simulate type pressed into paper. Light mode creates a highlight-below, shadow-above effect. Dark mode reverses the relationship. The values are hand-tuned per mode, not computed. Every heading on this page carries the effect — look at the section titles above for the highlight below each letter and shadow above.

Variable weight hover

The nav name link and post list titles animate font-variation-settings from weight 400 to 500 on hover, using the signature easing curve (cubic-bezier(0.22, 1, 0.36, 1)). Pull-quote-light links animate from 300 to 350. The effect is subtle and intentional: text thickens slightly to indicate interactivity, without a color change. Hover over any navigation link on this page to feel it.

Text-level refinements

  • text-wrap: pretty on prose containers for better line breaks
  • hanging-punctuation: first last on blockquotes; first on pull quotes
  • font-variant-numeric: tabular-nums on all dates for aligned columns
  • strong at weight 500, not 700. Signifier at 700 is too heavy for body text; 500 provides clear emphasis without disrupting reading rhythm.
  • -webkit-font-smoothing: antialiased globally for consistent rendering

Font loading

Seven font files, all woff2:

FileFamilyWeight range
signifier-vf-roman.woff2Signifier100-900 (variable)
signifier-vf-italic.woff2Signifier100-900 (variable)
Montreuil-Regular.woff2Montreuil400
Montreuil-Italic.woff2Montreuil400 italic
Montreuil-Medium.woff2Montreuil500
Montreuil-Semibold.woff2Montreuil600
caveat-vf.woff2Caveat400-700 (variable)

All faces use font-display: swap. Text renders immediately in the fallback stack, then swaps once the webfont loads.

Two fonts are preloaded in the <head>: Signifier Roman (the body text) and Montreuil Regular (the primary UI weight). The remaining five load on demand. This keeps initial payload focused on the fonts the reader sees first.


Accessibility

  • Minimum body size: 14px (at the 600px breakpoint). Never smaller for readable text.
  • Line-height: 1.6 for body prose, 1.2-1.4 for headings and display text. No line-height below 1.2.
  • Contrast: All text/background pairings meet WCAG 2.1 AA for their intended use. See color foundations for the full audit.
  • --text-3 exclusion: The tertiary text color fails AA intentionally and is restricted to decorative, non-informational elements.

Do’s and don’ts

DoDon’t
Use Signifier for anything the reader spends time withUse Signifier for UI labels, nav, or meta
Use Montreuil for wayfinding, categories, datesUse Montreuil for body paragraphs
Let weight, size, and family create hierarchyAdd background fills or borders to distinguish headings
Use weight 500 for strong emphasisUse weight 700 with Signifier
Disable drop cap on mobileAssume desktop typographic details work at small sizes

Specimens

The reading voice Signifier by Klim Type Foundry
The functional voice Montreuil by 205TF
Alex Priest Signifier / 2.5rem / 400
Article Title Signifier / 2rem / 400
Section Heading Signifier / 1.2rem / 400
SUBSECTION Montreuil / 0.75rem / 600
Body prose in Signifier at the reading size, the voice you hear at length. Signifier / 1rem / 400
The opening paragraph, slightly lifted to signal the start of a piece. Signifier / 1.1rem / 400
SECTION LABEL Montreuil / 0.7rem / 600
February 27, 2026 Montreuil / 0.85rem / 400

Hover to feel the weight shift

There is a moment, near the beginning of any serious piece of writing, where the first letter earns a quiet emphasis. It does not shout. It simply arrives with the authority of something that has been considered, weighted just enough to hold the eye before the sentence carries you forward.

Must read — a handwritten note Caveat / 1rem / 600
const code = "monospace" SF Mono / 0.85rem / 400