Fontroom primitives

The tokens and components the clean tool is built from. Every value on this page is the one the app uses.

Colour

--bg --panel --s1…s3 --t1…t4

Surfaces step up in small, even amounts. Text uses four tiers. Colour only marks meaning: the selected state, the main action, success and error. Contrast is measured against the page background.

Slop: a three-stop purple to pink to cyan gradient used on text, buttons, borders and glows, so nothing is more important than anything else.
AI-Powered

Type

Onest · 1 family

One family, a clear scale and restrained weights. Tracking tightens as size grows and never goes past -0.035em. Monospace is only for code and keys.

Spacing

4 · 6 · 8 · 10 · 12 · 16 · 20 · 24 · 28 · 40 · 64

Tight inside a group, generous between groups. Areas are separated by space and fills, not borders.

Radius

5 · 7 · 9 · 12 · 16 · 22 · pill

Radius grows with the size of the thing. Pills are only for small chips, never for every button.

Slop: rounded-full on everything, including large buttons, inputs and cards.Get Started 🚀🔍 Search fonts with AI...

Icons

24 grid · 1.75 stroke · currentColor

One drawn set, one stroke weight, coloured by the text around it. Icons sit beside a label unless the control has an accessible name.

Slop: emoji standing in for icons, each with its own colour, style and size.🚀🤖🎯🔒💡

Button

.btn · .btn.primary · .btn.lg

One primary per area. The label names the action ("Get code", not "Submit"). Secondary actions use the quiet fill.

Primary
Hover
Focus
Loading
Secondary
Disabled
Large
<button class="btn primary">Get code</button>
<button class="btn">Copy link</button>
Slop: gradient pill, double glow, scales up on hover, emoji in the label.Export Code 🚀▶ Watch Demo

Icon button

.icon-btn

For a single, well-known action. Always give it an aria-label that says what happens.

Default
Hover
Focus
<button class="icon-btn" aria-label="Close">
  <svg class="ic"><use href="#i-x"/></svg>
</button>

Search input

.search

The placeholder says what you can find, with the real count. The key hint shows the shortcut. Focus is a thin ring, not a glow.

Default
Focus
<label class="search">
  <svg class="ic"><use href="#i-search"/></svg>
  <input type="text" placeholder="Search 180 Google Fonts">
  <kbd>/</kbd>
</label>
Slop: rounded-full, glowing border, "with AI" in the placeholder when no AI is involved.🔍 Search fonts with AI...

Segmented control

.seg · role=radiogroup

For two to four views of the same thing. The selected segment is a step lighter, not a colour.

Live, arrow keys switch
Slop: the selected segment is a glowing gradient pill.💻 Website📱 App

Chip

.chip · role=radio

Small filters. The only place a pill shape is used. Selected is inverted: light on dark.

Live
Slop: gradient fill, glow, and decorative badges that don't filter anything.AllSans serif⚡ Lightning Fast🤖 AI-Powered

Swatch

.sw · role=radio

Picks a colour for the preview, not for the tool. Each swatch has a name for screen readers. The selected one gets a ring.

Live

Tabs

.tabs · role=tablist

Switch between versions of the same content, like code for different stacks. Left and right arrows move between tabs.

Live

Font slot

.slot · role=radio

Shows which font each role uses, in that font. Its state is always written out: Editing, Previewing or Loading. The meta line gives facts, not praise.

Selected
HeadingsEditingFrauncesSerif · 9 weights
Previewing
HeadingsPreviewingPoppinsSans serif · 7 weights
Loading
Body textLoadingInterSans serif
Failed
Body textNope FontCould not load
Slop: glow ring, emoji in the label, and no clear state.
🎯 HeadingsFraunces

List option

.opt · role=option

Each font name is set in its own font. Hover or arrow key previews it, a click keeps it. The font in use is labelled, not just highlighted.

InterSans serif
RobotoSans serif
FrauncesIn use
Rows: default, active, in use

Toast

.toast · aria-live=polite

Confirms an action or explains a failure. Errors say what went wrong and what to do next, and stay on screen longer.

SuccessLink copied. It opens with this exact setup.
Error“Nope Font” isn't on Google Fonts. Check the spelling, then try again.
Slop: celebrates every action and never explains a failure.🎉 Link copied! Share the magic with your team ✨

Code block

pre · .copy

Labelled with where the code goes. Long lines wrap so nothing hides off to the side. Copy confirms in place.

In your CSS
:root {
  --font-heading: "Fraunces", serif;
  --font-body: "Inter", sans-serif;
}