All pages

Foundations

Typography

Type follows the reader's writing system, not just their locale. The root element carries a data-writing-system attribute — latin or cjk — and the font stacks and metrics answer to it. The root font size stays 16px at every breakpoint, so legacy rem values map one to one.

Families

Three families, spent as font-sans, font-serif and font-mono. Latin leads the sans stack because the unprefixed route is the global site: Geist Sans (self-hosted through next/font), then Inter, then the CJK families. Serif is not hypothetical — the clock-collage list style sets its heading in font-serif.

Curate everything you love — 收集你所热爱的一切

Curate everything you love — 收集你所热爱的一切

Curate everything you love

--font-sans:  Geist Sans, Inter, PingFang SC, …
--font-serif: Georgia, Cambria, … Songti SC, SimSun, …
--font-mono:  SFMono-Regular, Menlo, Monaco, …

The fallback order

The CJK families sit ahead of ui-sans-serif and -apple-system, and that order is load-bearing. Per-character fallback only continues while a font has no glyph — and the system keywords always produce one, because a missing character resolves through LastResort, whose glyph is the ▯ box. On any engine whose system font lacks hanzi, a stack that leads with the system keywords stops the cascade with tofu and every CJK family after them is unreachable. Naming the CJK families first costs Latin text nothing: fallback is per character.

The same rule generalises: sans-serif is terminal — a generic family matches everything — so new families go before it, never after.

Writing systems

The locale layout stamps data-writing-system on <html>, so future Latin-script locales inherit the Latin treatment without language-specific selectors. Content keeps a language of its own: a Chinese list read by an English reader is the ordinary case, which is why the CJK families stay in the Latin stack for per-character fallback.

Writing systemTreatment
latinGeist Sans with a tuned rhythm: semibold rides at weight 560, a tighter line-height ladder (text-base 1.5 down to text-4xl 1.1), body letter-spacing −0.006em, and kerning, optical sizing and contextual ligatures switched on. Code runs reset their tracking to 0.
cjkThe legacy PingFang-first stack and Tailwind's stock type metrics, unchanged. Hiragino Sans earns its odd place in the stack: the iOS Simulator ships no Simplified Chinese font, and Hiragino covers the shared kanji there; on a real device PingFang is ahead of it and always present.

Scale

Tailwind's stock type scale, spent as utilities. What Curation adds is the Latin line-height ladder above and the discipline that sizes are stated in rem — the root never changes, so a text-[0.94rem] ported from legacy renders at exactly the legacy size.

Taste, kept deliberately

Taste, kept deliberately

Taste, kept deliberately

Taste, kept deliberately

Taste, kept deliberately

Taste, kept deliberately