@cf/ui

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 body in styles/globals.css, falling back to the system UI stack.
  • Italic: em switches to Rodney at weight 400, and a em to Rodney Medium italic. Italic is a different typeface rather than a slanted KAG.
  • Mono: JetBrains Mono through next/font, then the self-hosted geist-mono, then monospace.

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-rodney or any other family utility inside a component; only font-mono in Kbd is allowed.

    no-font-family-in-components

  • must

    Keep text fields at text-base below md and drop to md:text-sm only 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 with font-medium; avoid arbitrary sizes except where a component documents why.

    use-the-size-scale

  • should

    If you use KAG, list kag-fallback before kag in the font stack so its broken glyphs are replaced.

    fallback-before-brand-face