Typography
Headings and body share one typeface: Noto Sans. Code uses Noto Sans Mono — plus a tuned.prose layer for written content. Every specimen below renders with its real utility classes.
Part 1 · Design typography
Headings & body · font-sans
Noto Sans
One typeface for everything — headings (h1–h6), UI labels, body copy, and prose. Variable weight, 100–900.
AaBbCc 0123 — æ ß ç
Code · font-mono
Noto Sans Mono
Code, tokens, and literal specimens.
AaBbCc 0123 — æ ß ç
Type scale
Hero
Post titles (PostLayout h1)
Zmoki Astro Starter
text-4xl font-semibold tracking-tight xl:text-6xl
Lede
Post descriptions (PostLayout)
Ideas, art, and research, kept in the open.
text-2xl xl:text-3xl
Section heading
Landing sections & author bio (h2)
What you get
text-3xl font-semibold md:text-4xl
Card title
PostCard (h2)
An example post
text-2xl font-semibold leading-normal xl:text-3xl
Body
Global body (BaseLayout)
The base reading size — Noto Sans, set clean.
text-lg leading-normal tracking-tight xl:text-xl
Small labels
Eyebrow
Landing section eyebrows
What you get
text-sm font-semibold uppercase tracking-wide
Date / meta
Dates (PostCard, PostLayout)
20 Jun 2026
text-sm
Previous / Next
Post navigation (PostLayout)
Previous
text-sm font-medium
Button text
Code block Copy button
Copy
text-xs font-medium
Tracking
tracking-tightDefault — headings, body, nav & footer labels
Global body, nav, footer
tracking-wideUppercase eyebrows
Landing section eyebrows
Leading
leading-normalDefault — body copy, headings and multi-line titles
Global body (BaseLayout), PostCard, prev/next titles
leading-tightShort copy beside a form
Brevo form intro
Part 2 · Prose typography
.prose configuration
MDX content renders inside prose prose-xl (stepping up toxl:prose-2xl). Overrides live intailwind.config.mjs via typography().
- --tw-prose-headings→ zmoki-stone-900
- --tw-prose-body→ zmoki-stone-700
- --tw-prose-bold→ zmoki-stone-900
- prose-headings:font-semibold→ heading weight (PostLayout)
In-prose links
Link treatment is driven by data attributes added by the rehypeExternalLinks plugin. Each renders with its real token.
a
zmoki-indigo-600 · underline offset-2
[data-external]
zmoki-indigo-600 · underline offset-2
[data-resource]
zmoki-indigo-600 · underline offset-2
[data-anchor]
zmoki-indigo-600 · underline offset-2
Live specimen
The shape of a sentence
Prose body and headings are both set in Noto Sans at prose-xl, with ink-colored bold. This is a base internal link, anexternal link, aresource link, and ananchor link.
Lists
- Unordered items use the prose default marker.
- Inline
codepicks up the mono face.
- Ordered items count up.
- Then carry on.
A blockquote sets quoted material apart with a left rule and italic body.
Definition list
- Design token
- A named value (like a color) defined once and reused everywhere.
- Definition list
- A term paired with its description, like this one.
Table
Write a pipe table with a : Caption line under it. Every table sits in a scroll box, so on a phone a wide one scrolls instead of widening the page.
| Metric | Measures | Good | Needs improvement | Poor |
|---|---|---|---|---|
| LCP | Loading | ≤ 2.5 s | ≤ 4 s | > 4 s |
| INP | Responsiveness | ≤ 200 ms | ≤ 500 ms | > 500 ms |
| CLS | Visual stability | ≤ 0.1 | ≤ 0.25 | > 0.25 |
Code block
Fenced blocks are highlighted with Shiki (catppuccin-mocha) and get a copy button at build time. Hand-written here, they fall back to prose code styling:
const garden = ["posts", "resources", "now"];
garden.forEach((bed) => tend(bed));