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
| Element | Family | Size | Weight | Notes |
|---|---|---|---|---|
| Homepage nameplate | Signifier | 2.5rem | 400 | Not a link on the homepage |
| Interior nav name | Signifier | 1.1rem | 400 | Weight shifts to 500 on hover |
| Breadcrumb current | Signifier | 1.1rem | 400 | --text-2 color |
Headings
| Element | Family | Size | Weight | Notes |
|---|---|---|---|---|
| Article h1 | Signifier | 2rem | 400 | Letterpress text-shadow |
| Default h1 | Signifier | 1.5rem | 400 | Non-article pages |
| h2 | Signifier | 1.2rem | 400 | Letterpress text-shadow |
| h3 | Montreuil | 0.75rem | 600 | All-caps, 0.08em tracking. The typeface shift to sans creates hierarchy without needing a larger size |
Body and editorial
| Element | Family | Size | Weight | Notes |
|---|---|---|---|---|
| Body prose | Signifier | 1rem (15px base) | 400 | --text-2, line-height 1.6 |
| Lede paragraph | Signifier | 1.1rem | 400 | --text color, first paragraph of articles |
| Pull quote (centered) | Signifier | 1.25rem | 400 italic | Centered, no borders |
| Pull quote (light) | Signifier | 1.35rem | 340 italic | Hanging open-quote, letterpress shadow |
Meta and UI
| Element | Family | Size | Weight | Notes |
|---|---|---|---|---|
| Section label | Montreuil | 0.7rem | 600 | All-caps, 0.05em tracking |
| Post list date | Montreuil | 0.85rem | 400 | tabular-nums |
| Article meta | Montreuil | 0.85rem | 400 | tabular-nums, 0.02em tracking |
| Footer nav | Montreuil | 0.9rem | 400 | --text-2 |
| Footer colophon | Montreuil | 0.75rem | 400 | --text-3 |
| Figcaption | inherited | 0.85rem | 400 italic | --text-2 |
| Inline code | SF Mono | 0.85em | 400 | --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: prettyon prose containers for better line breakshanging-punctuation: first laston blockquotes;firston pull quotesfont-variant-numeric: tabular-numson all dates for aligned columnsstrongat weight 500, not 700. Signifier at 700 is too heavy for body text; 500 provides clear emphasis without disrupting reading rhythm.-webkit-font-smoothing: antialiasedglobally for consistent rendering
Font loading
Seven font files, all woff2:
| File | Family | Weight range |
|---|---|---|
signifier-vf-roman.woff2 | Signifier | 100-900 (variable) |
signifier-vf-italic.woff2 | Signifier | 100-900 (variable) |
Montreuil-Regular.woff2 | Montreuil | 400 |
Montreuil-Italic.woff2 | Montreuil | 400 italic |
Montreuil-Medium.woff2 | Montreuil | 500 |
Montreuil-Semibold.woff2 | Montreuil | 600 |
caveat-vf.woff2 | Caveat | 400-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-3exclusion: The tertiary text color fails AA intentionally and is restricted to decorative, non-informational elements.
Do’s and don’ts
| Do | Don’t |
|---|---|
| Use Signifier for anything the reader spends time with | Use Signifier for UI labels, nav, or meta |
| Use Montreuil for wayfinding, categories, dates | Use Montreuil for body paragraphs |
| Let weight, size, and family create hierarchy | Add background fills or borders to distinguish headings |
| Use weight 500 for strong emphasis | Use weight 700 with Signifier |
| Disable drop cap on mobile | Assume desktop typographic details work at small sizes |
Specimens
Two Voices
Type Scale
Weight Variation
Hover to feel the weight shift
Drop Cap
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.
Supporting Voices
const code = "monospace" SF Mono / 0.85rem / 400