Typeface
Pho speaks in three voices: PolySans— the primary sans for body at 400 and UI/headings/hero slogans at 550 (withss02 via font-display) —Azeret Mono for code and small labels, and Instrument Serif as the editorial accent, most often italic. PolySans and Azeret Mono ship as variable files, though the system exposes only three weight stops; Instrument Serif ships as regular and italic at 400. All three are served from the shared asset CDN (assets.photon.codes).
Weights
The weight set is closed: three stops, nothing else generates a utility. Light (300) is for display and marketing lines only. Regular (400) is body copy. Medium (550) is the single emphatic stop — UI controls, headings, and hero slogans — unifying the former Medium (500) and Semibold (600). There is no font-semibold; use font-medium.
Casing rule: all-caps small text is banned — no uppercase eyebrows, section labels, subtitles, or descriptions (no uppercase +tracking-* label treatment). Hierarchy comes from size, weight, and the two-ink text ramp, never from capitalization. Sentence case for labels and descriptions; Title Case only for headings that name things.
Display & marketing lines
Body copy
UI, headings, hero slogans
Type scale
The scale is closed — Tailwind defaults like text-2xl are removed, and only these steps generate utilities: five body sizes and seven display sizes.
60px / 1.05 · -0.04em
48px / 1.05 · -0.02em
40px / 1.1 · -0.02em
32px / 1.2 · -0.02em
24px / 1.3 · -0.02em
20px / 1.3 · -0.02em
18px / 1.3 · -0.02em
20px / 30px
18px / 28px
16px / 24px
14px / 20px
13px / 18px
Azeret Mono
const photon = connect({ channel: "imessage" });
await photon.send({ to: "+1 555 0142", body: "0123456789" });Instrument Serif
An editorial accent, spoken in italics.
Character set
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789
& @ # % * ( ) { } [ ] / \ — – · • ! ? : ; “ ” ‘ ’ → ←