Every surface is a printed page.

assistant-ui is drawn as a printed document, not as an application skin. Four registers follow from that one sentence, and every component in the kit is what they produce.

01

Shape

Every shape question is answered by asking what the thing is. The page stays square, printed matter takes the smallest rounding, and only what you press reaches for the rest of the scale.

fig. 01 · the page itself
fig. 02 · matter printed on it
fig. 03 · an object you press or lift
--radius-page0
The page itself, and every full-bleed band on it: header, footer, section rules.
--radius-document6px
Anything printed on the page: a code sheet, a table, a figure plate, a specimen frame. Declared so a parent radius cannot leak in.
--radius-sm6px
Kbd, inline code, the smallest icon button.
--radius-control8px
Button, input, header CTA. Marketing calls to action are 8px rectangles, never pills.
--radius-surface10px
Menu, popover, tooltip.
--radius-xl12px
Dialog, toast, any floating card. Never square a surface that lifts: the shadow reads as a crescent at each corner.
--radius-thread16px
Composer and user bubble. Product vocabulary; it never appears on marketing chrome.
--radius-capsule9999px
Switch, avatar, status dot.
02

Ink

One knob sets the whole palette. --tint: 106 puts every neutral on a single low-chroma oklch hue, so the site reads as sand rather than gallery grayscale. Turn the knob and the mood of every page moves together.

--tint106
--background0.992 0.002
Paper. The dark ground is the same hue at 0.17.
--foreground0.145 0.006
Ink. Emphasis comes from weight and fill percentage of this one color, not from hue.
--muted0.97 0.004
The quiet fill under machine text and selected rows.
--border0.922 0.005
The hairline. One line weight for the whole site.
blue-500live
Blue means live: streaming, running, connected, or currently selected. One live accent per page, and if nothing is live the page has no blue.
--destructive0.577 0.245
A state, not an accent.
glint0.82 0.14 82
Specular light catching the printed mark. It carries no meaning and never becomes a second accent.

Chrome is ink; product data may be colored. A chart, a heat map, a trace waterfall, or a syntax theme keeps its own palette, because there the palette is the content.

03

Voice

One sans face for headings, prose, labels, and statistics. Mono is reserved for code, commands, and identifiers.

Display

Every state an assistant can be in.

Public Sans for h1, h2, h3, and the large figures a page is built around. Size and weight establish the hierarchy.

Sans

Reading text, set at a comfortable size and never shrunk to make density fit.

Public Sans, through --font-sans. Labels and captions use sentence case and normal letter spacing.

Mono

npx assistant-ui init

JetBrains Mono, ligatures off. What you type or install.

typeHero
The masthead statement, one per page at most.
typePage
The ordinary page title.
typeSection
A major section turn.
typeDeck
One short orientation passage.
typePackage
A package name set as a title, in mono.
04

Line

Ink is expensive, so a rule has to earn its place. Section boundaries are the only line kind a page owes; rows inside a section breathe on rhythm and a hover fill, not on dividers.

Streaming06
Reasoning06
Tools06
Approval06
Sources06
Attachments06
fig. 04 · a ledger of forty hairlines is a cage
Streaming06
Reasoning06
Tools06
Approval06
Sources06
Attachments06
fig. 05 · rhythm and a hover fill carry the same rows

A hairline never stacks with a ring and a shadow on the same edge, and rules never nest three levels deep. Shadows are zeroed globally; only a surface that floats may lift.

05

Motion

Motion explains a state change, preserves continuity, or confirms an action. It never gates reading, and every one of these is off under prefers-reduced-motion.

hero-word
A headline arrives word by word, the newest landing in blue and settling into ink.
hero-rise
Deck, actions, and metadata rise after the headline has landed.
hero-glint
A gold sweep crosses the printed mark, occasionally.
code-cascade
Code lines fade in in sequence when a snippet is swapped.
line-hot
The lines that changed between two snippets carry a blue gutter bar and settle once.
stage-progress
A hairline fills under the active label to show how long the current act has left.

What they produce