Resolved: light

Typography

The Save the Dogs type system — Mulish for body / UI, Fraunces for display — built entirely on --text-*, --lh-* and --tracking-* tokens. Flip the theme in the top bar; the type is theme-aware via the semantic color tokens.

Type system

Two faces, one token-driven scale. Body and UI copy is set in Mulish (--font-sans); display headlines opt in to Fraunces with the font-display utility. Sizes, line-heights and tracking are all CSS variables so the scale stays consistent across the app and re-skins cleanly.

The quick brown fox jumps over the lazy dog

Default face. Inherited from <body>; no class needed. Used for paragraphs, labels, controls and data.

font face — Mulish (body / UI · --font-sans)

The quick brown fox jumps over the lazy dog

Opt in with className="font-display" (or the font-display util). Reserve for hero / section headlines, not running text.

font face — Fraunces (display · .font-display)
--font-sans
Mulish, Inter, system-ui — the body/UI face, set on <body> and inherited everywhere.
--font-display
Fraunces (serif). Opt in via .font-display / font-display; falls back to Georgia.
--font-mono
Geist Mono — used here for token names and code via the font-mono utility.
text color
Primary = text-[var(--color-text)]; secondary = text-muted; tertiary = text-faint. Never rely on size alone for hierarchy.

Type scale

Every --text-* step, largest to smallest, with its token, rem/px size and intended role. Heading tiers are shown in the Fraunces display face (as the app uses them); body tiers in Mulish. Each sample is captioned with its token.

Save the Dogs
--text-display-2xl3.5rem · 56px · font-displayHero / marketing display — the largest face. Pair with font-display.
Save the Dogs
--text-display-xl2.75rem · 44px · font-displaySecondary hero / large display headline.
Save the Dogs
--text-h12rem · 32px · font-displayPage title (PageHeader sets this in font-display).
Save the Dogs
--text-h21.5rem · 24px · font-displaySection heading (DsSection title is font-display at this size).
Save the Dogs
--text-h31.25rem · 20pxSub-section / card group heading.
Save the Dogs
--text-h41.0625rem · 17pxCard title / dense heading (same size as body-lg).
Save the Dogs
--text-body-lg1.0625rem · 17pxLead paragraph / emphasized body copy.
Save the Dogs
--text-body0.875rem · 14pxDefault body text — inherited from <body>.
Save the Dogs
--text-small0.8125rem · 13pxSecondary / supporting copy, captions, metadata.
Eyebrow label
--text-eyebrow0.6875rem · 11pxEyebrow / overline label — uppercase + tracked out.

Display vs body face

The same heading rendered in both faces at the same size, so you can see why Fraunces is the display choice and Mulish the body choice. Headlines use font-display; everything below h3 stays in Mulish.

Fraunces display

Mulish body

font-display vs Mulish @ --text-h1

Fraunces display

Mulish body

font-display vs Mulish @ --text-h2

Fraunces display

Mulish body

font-display vs Mulish @ --text-h3

Fraunces display

Mulish body

font-display vs Mulish @ --text-body-lg

Line-height

The --lh-* tokens. Tight leading on display/headings keeps multi-line headlines compact; the looser --lh-body is the readable default for paragraphs (and the value set on <body>).

The quick brown fox jumps over the lazy dog. Save the Dogs is dark by default; every color resolves from a CSS variable, so the same type ramp re-skins across the light and dark themes with no per-component edits.

--lh-body = 1.5 · pairs with body / body-lg / small

The quick brown fox jumps over the lazy dog. Save the Dogs is dark by default; every color resolves from a CSS variable, so the same type ramp re-skins across the light and dark themes with no per-component edits.

--lh-h1 = 1.15 · pairs with display-2xl, display-xl, h1

The quick brown fox jumps over the lazy dog. Save the Dogs is dark by default; every color resolves from a CSS variable, so the same type ramp re-skins across the light and dark themes with no per-component edits.

--lh-h2 = 1.25 · pairs with h2

The quick brown fox jumps over the lazy dog. Save the Dogs is dark by default; every color resolves from a CSS variable, so the same type ramp re-skins across the light and dark themes with no per-component edits.

--lh-h3 = 1.3 · pairs with h3

The quick brown fox jumps over the lazy dog. Save the Dogs is dark by default; every color resolves from a CSS variable, so the same type ramp re-skins across the light and dark themes with no per-component edits.

--lh-h4 = 1.35 · pairs with h4
--lh-body
1.5 — body / body-lg / small.
--lh-h1
1.15 — display-2xl, display-xl, h1.
--lh-h2
1.25 — h2.
--lh-h3
1.3 — h3.
--lh-h4
1.35 — h4.

Letter-spacing (tracking)

The --tracking-* tokens. Negative values optically tighten large display text; the positive eyebrow value tracks small uppercase labels OUT for legibility. Each line below is the same string at one tracking value.

Save the Dogs design system

--tracking-tight = -0.025em

Save the Dogs design system

--tracking-display = -0.02em

Save the Dogs design system

--tracking-h = -0.012em

Track small uppercase labels out

--tracking-eyebrow = 0.08em
--tracking-tight
-0.025em — Tightest — large display / numerals.
--tracking-display
-0.02em — Display faces (display-2xl, display-xl).
--tracking-h
-0.012em — Headings (h1–h4) — subtle optical tighten.
--tracking-eyebrow
0.08em — Eyebrows / uppercase labels — track OUT.

Eyebrow & uppercase

The eyebrow pattern: --text-eyebrow size, --tracking-eyebrow spacing, uppercase, set in a faint/muted tone above a heading. Used as overlines on section cards and table headers.

Foundations

Typography

eyebrow → heading (overline pattern)
NameRoleStatus
RosaLeadActive
MarcusVolunteerPending
table-header style (th uppercase, tracked, faint)
--text-eyebrow
0.6875rem / 11px — the eyebrow font-size.
--tracking-eyebrow
0.08em — tracks the uppercase label out so it reads as a label, not shouting.
uppercase + faint
Pair uppercase with text-faint/text-muted weight 600 — the global `th` style applies exactly this.

Tabular numerals

Opt into fixed-width figures with the tabular-nums utility so columns of numbers (metrics, tables, money) align vertically. Compare the proportional default against tabular — the digits line up on the right.

1,118.40
97,001.11
342.07
default (proportional figures)
1,118.40
97,001.11
342.07
tabular-nums (aligned figures)
tabular-nums
Utility class setting font-variant-numeric: tabular-nums. Apply to any container of figures that must align.
When to use
Stat blocks, data tables, currency, counters, anything where digits stack in a column.