Typography
Components inherit the page's typeface; the site sets KAG, Rodney and a mono stack itself.
The specimen below is set by this site, not by the components. On another site the same components would pick up that site's fonts.
Body is KAG at 300, and emphasis switches to Rodney, a different typeface rather than a slanted one.
font-mono: JetBrains Mono, then geist-mono
Ampersands & arrows → come from the Geist fallback
- text-base
- Inputs and menu items below md
- text-sm
- Buttons, labels, menu items from md
- font-medium
- Button and label weight
- text-xs
- Tooltips, message headers and footers
- 0.6875rem
- Kbd, the only mono component
Components don't own type
No component in @cf/ui sets a typeface. They set size (text-sm on buttons and labels, text-xs in tooltips), weight (font-medium) and leading, and inherit the family from the page. That's deliberate: the fonts I use are licensed and can't ship in a public registry, and a component that inherits looks right in someone else's product without edits.
The one family a component names is font-mono in Kbd, at text-[0.6875rem], because a keycap should look like a key.
What the site sets
For reference, and so the docs match what you see on connorforsyth.co:
- Body: Kyneton Art Grotesque ("KAG") at weight 300, set on
bodyinstyles/globals.css, falling back to the system UI stack. - Italic:
emswitches to Rodney at weight 400, anda emto Rodney Medium italic. Italic is a different typeface rather than a slanted KAG. - Mono: JetBrains Mono through
next/font, then the self-hostedgeist-mono, thenmonospace.
The KAG fallback
KAG's &, = and arrow glyphs don't render properly. styles/type.css declares a kag-fallback face that points at Geist with a unicode-range covering only those characters (U+0026, U+003D and the arrows U+2190, U+2192, U+2197, U+21B3), sized to 94% so they sit with KAG's metrics. Because it's first in the stack, the browser uses Geist for those code points and KAG for everything else. It's a patch, not a fix, and it only helps if the fallback is listed first.
Mobile
Inputs and textareas use text-base below md; dropdown items do the same with md:text-sm. The larger size is about zoom and legibility on touch, not a separate type scale.
Rules
The same rules ship in DESIGN.md and the MCP server, for the agents building with this.
- must
Do not add
font-kag,font-rodneyor any other family utility inside a component; onlyfont-monoinKbdis allowed.no-font-family-in-components
- must
Keep text fields at
text-basebelowmdand drop tomd:text-smonly at the breakpoint.iOS zooms into any field under 16px and doesn't zoom back out.
sixteen-pixel-inputs
- should
Size text with Tailwind's scale (
text-xs,text-sm,text-base) and weight withfont-medium; avoid arbitrary sizes except where a component documents why.use-the-size-scale
- should
If you use KAG, list
kag-fallbackbeforekagin the font stack so its broken glyphs are replaced.fallback-before-brand-face