Elegant, modern typography sets the foundation for professional interfaces.
Elegant, modern typography sets the foundation for professional interfaces.
1. Zen (https://hanzo.ai/font) - USE FOR ALL UI TEXT
Hanzo's own family, drawn for interfaces. It ships in @hanzo/font, so a project carries it rather than fetching it.
Characteristics:
Use Zen for:
font-family: 'Zen', -apple-system, BlinkMacSystemFont, sans-serif;
2. Zen Mono (https://hanzo.ai/font) - USE FOR ALL CODE/TECHNICAL
Purpose-built for developers.
Characteristics:
Use Zen Mono for:
font-family: 'Zen Mono', 'Fira Code', Consolas, monospace;
font-size: 14px; /* minimum */
font-variant-ligatures: common-ligatures; /* enable ligatures */
If Zen or Zen Mono are unavailable:
Sans-serif alternatives:
Monospace alternatives:
System font fallback:
/* If custom fonts fail to load */
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif
Use optimal loading to prevent FOIT (Flash of Invisible Text):
One import declares both faces, already set to font-display: swap:
import '@hanzo/font/css';
It expands to this, which is what to write by hand if you are self-hosting the files rather than taking the package:
@font-face {
font-family: 'Zen';
src: url('/fonts/zen-sans/Zen-Variable.woff2') format('woff2');
font-display: swap; /* Show fallback immediately, swap when loaded */
font-weight: 100 900; /* Variable font weight range */
}
@font-face {
font-family: 'Zen Mono';
src: url('/fonts/zen-mono/ZenMono-Variable.woff2') format('woff2');
font-display: swap;
font-weight: 100 900;
}
Use a modular scale for consistent hierarchy.
Common scales:
Example: 1.25 scale (recommended):
:root {
--font-size-xs: 0.64rem; /* 10.24px */
--font-size-sm: 0.8rem; /* 12.8px */
--font-size-base: 1rem; /* 16px */
--font-size-lg: 1.25rem; /* 20px */
--font-size-xl: 1.563rem; /* 25px */
--font-size-2xl: 1.953rem; /* 31.25px */
--font-size-3xl: 2.441rem; /* 39px */
--font-size-4xl: 3.052rem; /* 48.8px */
}
Usage:
body {
font-size: var(--font-size-base);
line-height: 1.6;
}
h1 { font-size: var(--font-size-4xl); }
h2 { font-size: var(--font-size-3xl); }
h3 { font-size: var(--font-size-2xl); }
h4 { font-size: var(--font-size-xl); }
small { font-size: var(--font-size-sm); }
Body text: 1.5-1.6 for readability Headings: 1.1-1.3 for impact Code: 1.5-1.6 for clarity
body {
line-height: 1.6;
}
h1, h2, h3, h4, h5, h6 {
line-height: 1.2;
}
code, pre {
line-height: 1.6;
}
Zen supports variable weights (100-900):
Zen Mono:
/* Semantic weight variables */
:root {
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
}
Minimum sizes:
Contrast requirements:
/* CSS Variables */
:root {
/* Font families */
--font-sans: 'Zen', -apple-system, BlinkMacSystemFont, sans-serif;
--font-mono: 'Zen Mono', 'Fira Code', Consolas, monospace;
/* Font sizes (1.25 scale) */
--font-size-xs: 0.64rem;
--font-size-sm: 0.8rem;
--font-size-base: 1rem;
--font-size-lg: 1.25rem;
--font-size-xl: 1.563rem;
--font-size-2xl: 1.953rem;
--font-size-3xl: 2.441rem;
--font-size-4xl: 3.052rem;
/* Font weights */
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
}
/* Base styles */
body {
font-family: var(--font-sans);
font-size: var(--font-size-base);
line-height: 1.6;
font-weight: var(--font-weight-normal);
}
/* Code elements */
code, pre, kbd, samp {
font-family: var(--font-mono);
font-size: 14px; /* minimum readable size */
line-height: 1.6;
font-variant-ligatures: common-ligatures;
}
/* Headings */
h1 {
font-size: var(--font-size-4xl);
font-weight: var(--font-weight-bold);
line-height: 1.2;
}
h2 {
font-size: var(--font-size-3xl);
font-weight: var(--font-weight-semibold);
line-height: 1.2;
}
h3 {
font-size: var(--font-size-2xl);
font-weight: var(--font-weight-semibold);
line-height: 1.3;
}
Zen and ZenMono arrive already built — subsetting, display: swap and the fallback metrics are baked in, so there is nothing to call and nothing to pass.
// app/layout.tsx or _app.tsx
import { Zen, ZenMono } from '@hanzo/font';
export default function RootLayout({ children }) {
return (
<html className={`${Zen.variable} ${ZenMono.variable}`}>
<body>{children}</body>
</html>
);
}
They publish --font-zen-sans and --font-zen-mono.
| Element | Font | Size | Weight | |---------|------|------|--------| | Body text | Zen | 16px (1rem) | 400 | | UI labels | Zen | 14-16px | 500 | | Headings | Zen | Scale-based | 600-700 | | Buttons | Zen | 14-16px | 500-600 | | Code blocks | Zen Mono | 14px min | 400 | | Terminal | Zen Mono | 14px | 400 | | Small text | Zen | 14px min | 400 |