Skip to content

Foundations

Typography

Four faces, split by surface rather than by taste. Weights 400 and 500 only. 500 is the heaviest thing in the system, and hierarchy comes from size, colour and small caps instead of from weight.

Source of truth: varick-site/app/globals.css · varick-charts chart-spec.md §2 · varick-docs SKILL.md

The four faces

Which face you use is decided by where the thing renders, not by how it should feel.

FaceSurfaceWeightsCSS variable
Season MixThe home page and /brand. Marketing site headlines, article titles.400 only--font-season
Helvetica NeueEverything. Web UI, every .docx and PDF the company issues, every chart.400, 500--font-sans
MenloThis site and engineering surfaces. Never inside a chart or a document.400--font-mono

Geist for the web and Helvetica Neue for documents is deliberate, not drift. Geist is licensed for the web and has the numerals we want; Helvetica Neue is what renders identically in Word, Google Docs and a PDF on a client machine. Do not unify them.

Web scale

Seven steps, rendered here at the size and tracking they ship at.

Display64px / 1.02 · 400 · -0.03em

Agents that finish the work

Section landing headline. Season Mix, scoped to the home page and /brand.

H148px / 1.06 · 400 · -0.025em

Agents that finish the work

Page title. Every page has exactly one.

H232px / 1.15 · 400 · -0.02em

Agents that finish the work

Section heading, set in navy so the navy-carries-hierarchy rule is visibly true.

H322px / 1.3 · 500 · -0.015em

Agents that finish the work

Subhead. 500 is the heaviest weight in the system.

Body16px / 1.6 · 400 · -0.01em

Agents that finish the work

Running prose. The default, and the only size prose is ever set at.

Small14px / 1.55 · 400 · -0.01em

Agents that finish the work

Table cells, captions, secondary copy. Replaces the old 11 to 13.5px cluster.

UI body13px / 1.4 · 400 · -0.01em

Agents that finish the work

Product UI: navigation items, table cells, menu items, breadcrumbs.

UI control12.5px / 1.4 · 400 or 500 · -0.01em

Agents that finish the work

Product UI: buttons, tabs, form fields, card titles, row titles. 500 for the control label, 400 for the value.

UI meta11.5px / 1.4 · 400 or 500 · 0

Agents that finish the work

Product UI: status pills, meta lines, hints, code chips. The smallest size that carries words.

Label11px / 1.4 · 400 · 0.04em

Operational detail

Uppercase. 11px is the legibility floor; do not go below it.

Document scale

docx sizes are half-points, so 21 is 10.5pt. These are the only seven sizes a Varick document uses.

TokenHalf-pointsPointsRoleColour
SZ_TITLE3417ptDocument titleNavy
SZ_H12814ptNumbered section headingNavy
SZ_H22412ptSubhead inside a sectionNavy
SZ_BODY2110.5ptBody copy and every table cellInk
SZ_META189ptMeta rows, footer, gantt labelsGrey
SZ_LABEL168ptSmall-caps kicker, column labelsGrey
SZ_NOTE157.5ptGrey qualifier, "illustrative only"Grey

Do not set sizes per block. Every block in the document system already carries its size. If a document runs long, cut copy.

Chart sizes

Small, and fixed. A chart that needs bigger type usually needs fewer series.

Card label
10px uppercase, 0.04em, 400
Card heading
14–22px, 500
Axis tick
12px, 400
Tooltip
12px
Standings name
14px, 500
Value
13px, 500, tabular-nums
Legend
12px, 400

The label look

Uppercase and tracked, in place of a monospace face. It appears on every surface and it is always the same three declarations.

Engagement at a glance

Order-to-cash diagnostic

font-size: 10px;
letter-spacing: 0.04em;
text-transform: uppercase;
font-weight: 400;
color: var(--muted-foreground);

This replaces the monospace uppercase labels used in earlier work. Do not reach for a mono face to get this look. Inside a chart or a document, mono is forbidden outright.

Rules

The forbidden list is short and it is absolute. Most of it exists because synthesised weights and italics look broken in a PDF.

Do

  • Weights 400 and 500. 500 is the heaviest weight in the system.
  • font-variant-numeric: tabular-nums on any column of figures.
  • Uppercase at 0.04em tracking for labels.
  • Body tracking -0.01em; headings -0.02em.
  • font-synthesis: none, so no browser fakes a weight the family does not have.

Don’t

  • Weight 600, 700, 800, 900 or the keyword bold.
  • Italic, and especially synthesised italic: set font-synthesis: none.
  • A monospace face inside a chart or a document.
  • A serif face inside a chart or a document.
  • Centred text. The whole system is left-aligned.

Set font-synthesis: none

Without it a browser will fake a bold or an italic that the family does not have, and the result is a smeared letterform that survives all the way into a client PDF. The chart spec sets it globally, and so should you.

Setup

What to paste into a new project.

Web (Next.js)

import { Geist, Geist_Mono } from 'next/font/google'

const geistSans = Geist({
  subsets: ['latin'],
  weight: ['400', '500'],
  variable: '--font-geist-sans',
})

const geistMono = Geist_Mono({
  subsets: ['latin'],
  weight: ['400', '500'],
  variable: '--font-geist-mono',
})

Anything that ends up as a PDF

* {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-synthesis: none;
}

Helvetica Neue is a system font on macOS and iOS. Elsewhere the stack falls back to Helvetica then Arial, and that is accepted. Do not substitute a different family to “fix” it.