Skip to main content

Font families

Three font families cover every typographic need — editorial headings, functional body text, and technical code.
RoleFont familyWeightsUsage
HeadingsNoto Serif400, 600, 700Page titles, section headers, display text, strain names
BodyNoto Sans300, 400, 500, 600, 700Paragraphs, labels, UI text, navigation
CodeJetBrains Mono400, 500, 700Code blocks, technical values, inline code
Fonts are self-hosted via Astro’s experimental fonts API — no Google Fonts CDN dependency. This improves privacy and performance by eliminating third-party network requests.

Type hierarchy

Each level in the hierarchy has a defined size, weight, letter spacing, and line height. These values create a consistent visual rhythm from hero text down to fine print.
LevelSizeWeightLetter spacingLine heightUsage
Display / Heroclamp(3rem, 2rem + 6vw, 5.5rem)800-0.04em1.0Homepage hero, major headings
H1clamp(2.25rem, 1.75rem + 3vw, 3.5rem)700-0.02em1.15Page titles
H21.375rem (22px)600-0.01em1.3Section headings
H31.1875rem (19px)600-0.01em1.3Subsection headings
Body0.9375rem (15px)400-0.01em1.55Paragraph text
Small0.8125rem (13px)400normal1.55Captions, labels
XS0.75rem (12px)4000.02em1.55Fine print, badges

Fluid type scale

Text scales smoothly between mobile and desktop using CSS clamp() — no breakpoint jumps. This ensures readability at every viewport width.
TokenMinPreferredMax
fluid-sm0.8125rem (13px)0.75rem + 0.3vw0.9375rem (15px)
fluid-base0.9375rem (15px)0.85rem + 0.4vw1.0625rem (17px)
fluid-lg1.0625rem (17px)0.95rem + 0.45vw1.1875rem (19px)
fluid-xl1.1875rem (19px)1.05rem + 0.6vw1.375rem (22px)
fluid-2xl1.375rem (22px)1.2rem + 0.9vw1.625rem (26px)
fluid-3xl1.625rem (26px)1.3rem + 1.2vw1.875rem (30px)
fluid-display-sm1.875rem (30px)1.5rem + 2vw2.5rem (40px)
fluid-display2.25rem (36px)1.75rem + 3vw3.5rem (56px)
fluid-display-lg2.5rem (40px)2rem + 4vw4.5rem (72px)
fluid-hero3rem (48px)2rem + 6vw5.5rem (88px)
The fluid scale uses a dramatic progression for display sizes. A heading that reads 36px on mobile expands to 56px on desktop without any media query intervention.

Letter spacing

Tighter tracking for large display text, wider tracking for small labels and all-caps elements. This follows the typographic principle that large text needs negative tracking while small text benefits from positive tracking.
TokenValueUsage
tighter-0.04emDisplay/hero text
tight-0.02emH1 headings
normal-0.01emBody text, H2, H3
wide0.02emSmall caps, labels, XS text
wider0.05emButtons, UI elements
widest0.1emDecorative all-caps

Line height

Line height values control vertical rhythm. Tighter values for headings keep multi-line titles compact. Looser values for body text improve long-form readability.
TokenValueUsage
none1Display text, single-line elements
tight1.15Headings
snug1.3Subheadings, cards
normal1.55Body text (default)
relaxed1.7Long-form content
loose1.85Wide-set text, accessibility

Pairing rules

The serif-sans pairing gives the brand its distinctive editorial authority — a knowledge platform that reads like a magazine, not a database. Follow these rules to maintain that identity:
  • Noto Serif for emotional, editorial content: headings, hero text, strain names, pull quotes
  • Noto Sans for functional, informational content: body text, UI elements, labels, navigation
  • Never mix serif and sans-serif within a single heading
  • JetBrains Mono exclusively for code and technical contexts (terpene percentages in code blocks, API responses, developer documentation)
  • Use weight contrast (bold heading + regular body) rather than size contrast alone to establish hierarchy

For developers

Source of truth: apps/website/src/config/design-system/typography.ts. CSS custom properties are prefixed with --ds-typography-*. Mobile typography is defined separately in apps/mobile/src/_config/design-system/typography.ts with platform-appropriate values for React Native.