zeekay b9b47efcda Arabic companions: Noto Kufi Arabic under Zen, Noto Sans Arabic beside it; 1.9.4
Zen draws no Arabic, so an Arabic page fell to whatever face the browser
picked. Two variable companions over Zen's own weight axis, cut to the
Arabic blocks, now ship in fonts/arabic. Each is declared under its own
family with an Arabic unicode-range, and the default under Zen and Zen
Mono too, so font-family: Zen sets Arabic and a page with no Arabic on it
requests nothing new.

They are not ours and keep their names, notices and vendor; identity.py
checks them for exactly that, from the table arabic.py builds them from,
pinned by commit and checksum. next.mjs refuses a default whose weight
range is not Zen's: faces composite only when their descriptors match,
and a companion that wins the weight match sends Latin to the system sans.
2026-10-22 19:22:13 -07:00
2026-08-24 17:55:31 -07:00
2026-08-22 21:00:00 -07:00
2026-08-22 21:00:00 -07:00

Zen

The word Zen set twice — in Zen at a thin display weight, and beside it in Zen Pixel's triangle cut — over the line "Sans · Mono · Pixel" and, in Zen Mono, "one variable file · 100–900 · font.hanzo.ai". The word Zen set twice — in Zen at a thin display weight, and beside it in Zen Pixel's triangle cut — over the line "Sans · Mono · Pixel" and, in Zen Mono, "one variable file · 100–900 · font.hanzo.ai".

Zen, Zen Mono & Zen Pixel

Zen is the Hanzo typeface. Sans is a geometric sans-serif in the Swiss line — one variable file across weight 100–900, drawn for headlines, wordmarks and text alike. Mono is its fixed-width companion, cut for code editors, terminals and diagrams. Pixel is a display family of five cuts — Square, Grid, Circle, Triangle, Line — one alphabet drawn five ways.

Installing

Fonts to install on a machine are in fonts/: otf/ and ttf/ for the static cuts, variable/ for the one-file version of each family, webfonts/ for .woff2. make build regenerates all of it from sources/.

For a web or app surface, take the package instead — it carries the faces, the stylesheet and the presets:

pnpm add @hanzo/font
import '@hanzo/font/css'          // the faces
import '@hanzo/font/presets.css'  // the presets

Then name the role rather than the face: var(--font-sans), var(--font-mono). Full instructions are in the package README, and font.hanzo.ai is the live specimen.

Building

CI builds the fonts on every push — look under Actions for the latest. To build on your own machine:

  • make build produces the font files.
  • make test runs Fontspector's quality checks.
  • make proof writes HTML proofs.

crates/zen is the type tooling behind the presets — it reads outlines, measures optical white between pairs, and fits one setting to a target shape. It compiles to a native binary and to wasm from the same source, which is what lets the specimen page run the fitter live.

License

This Font Software is licensed under the SIL Open Font License, Version 1.1, in LICENSE.txt, which ships beside the binaries. The license is also available with a FAQ at https://scripts.sil.org/OFL

Repository layout

Structured as Unified Font Repository v0.3, adjusted for the Google Fonts build workflow.

S
Description
Zen — the Hanzo, Lux and Zoo typeface. Sans, Mono and Pixel, plus the Rust tools that fit a wordmark to drawn artwork.
Readme
132 MiB
Languages
Rust 43.4%
JavaScript 37.5%
Python 15.2%
Makefile 3.7%
HTML 0.2%