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…t4Surfaces 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.
Type
Onest · 1 familyOne 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 · 64Tight inside a group, generous between groups. Areas are separated by space and fills, not borders.
Radius
5 · 7 · 9 · 12 · 16 · 22 · pillRadius grows with the size of the thing. Pills are only for small chips, never for every button.
Icons
24 grid · 1.75 stroke · currentColorOne drawn set, one stroke weight, coloured by the text around it. Icons sit beside a label unless the control has an accessible name.
Button
.btn · .btn.primary · .btn.lgOne primary per area. The label names the action ("Get code", not "Submit"). Secondary actions use the quiet fill.
<button class="btn primary">Get code</button> <button class="btn">Copy link</button>
Icon button
.icon-btnFor a single, well-known action. Always give it an aria-label that says what happens.
<button class="icon-btn" aria-label="Close"> <svg class="ic"><use href="#i-x"/></svg> </button>
Search input
.searchThe placeholder says what you can find, with the real count. The key hint shows the shortcut. Focus is a thin ring, not a glow.
<label class="search"> <svg class="ic"><use href="#i-search"/></svg> <input type="text" placeholder="Search 180 Google Fonts"> <kbd>/</kbd> </label>
Dropdown
.dd · role=listboxNever a native select. Arrow keys move, Enter picks, Escape closes and returns focus, clicking outside closes. Options that can't be chosen stay visible and say why.
- 400 Regular
- 700 BoldNot in font
- 800 Extra boldNot in font
<div class="dd">
<button class="dd-btn" aria-haspopup="listbox" aria-expanded="false">
<span class="dd-k">Weight</span><span>700</span>
</button>
<ul class="dd-pop" role="listbox" hidden>…</ul>
</div>Segmented control
.seg · role=radiogroupFor two to four views of the same thing. The selected segment is a step lighter, not a colour.
Chip
.chip · role=radioSmall filters. The only place a pill shape is used. Selected is inverted: light on dark.
Swatch
.sw · role=radioPicks a colour for the preview, not for the tool. Each swatch has a name for screen readers. The selected one gets a ring.
Tabs
.tabs · role=tablistSwitch between versions of the same content, like code for different stacks. Left and right arrows move between tabs.
Font slot
.slot · role=radioShows 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.
List option
.opt · role=optionEach 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.
Toast
.toast · aria-live=politeConfirms an action or explains a failure. Errors say what went wrong and what to do next, and stay on screen longer.
Code block
pre · .copyLabelled with where the code goes. Long lines wrap so nothing hides off to the side. Copy confirms in place.
:root {
--font-heading: "Fraunces", serif;
--font-body: "Inter", sans-serif;
}