Typeset
Echo's type is a set of roles, not a font. A component asks for "the machine voice" or "the screen face", and the theme decides which typeface that is. Change the faces in one place and every component follows.
The four roles
| Role | Specimen | Use it for | Default stack |
|---|---|---|---|
--echo-font-machine | REC · 48 kHz · MONITOR | Instrument labels, caps, panel legends, captions. The library's voice. | ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif |
--echo-font-sans | Settings are saved on this device. | Body and UI prose. | ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif |
--echo-font-mono | 0O 1lI 5S — 12:04:59 | Code, data, and digits that have to be told apart at a glance. | ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace |
--echo-font-lcd | -12.4 dB | The screen face on LCD panels and readouts. Tabular by necessity. | ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace |
The specimens use this site's typefaces; the last column is what a fresh install uses. Those defaults are system fonts, so nothing needs loading until you choose your own.
Choosing your faces
Fonts are part of the seed, so they are set where the colours are:
const { css } = createEchoTheme({
accent: "#3D8EF0",
fontSans: "'Inter', system-ui, sans-serif",
fontMachine: "'Inter', system-ui, sans-serif",
fontMono: "'JetBrains Mono', ui-monospace, monospace",
});Loading the font files is up to you (next/font, a <link>, self-hosting). Keep a system fallback
at the end of every stack.
When to use which
- Machine for anything a device would print on its panel: button labels, section legends, units. Short, often uppercase, letter-spaced.
- Sans for sentences: descriptions, help text, messages.
- Mono for anything a person might compare character by character: code, IDs, timestamps, values in a table.
- LCD only inside a screen: readouts, the LcdChip, chart values. It is tabular, so numbers do not jump as they change.
One size is for one line only: display (the sans, bold and tight, at the scale's 3xl step, 40px) is
the one large line a screen carries, like a headline or an entry's index number. A screen has at most
one; every other heading is heading.
The scale
| Token | Size | Specimen |
|---|---|---|
--echo-text-3xs | 0.625rem | Signal meter |
--echo-text-2xs | 0.6875rem | Signal meter |
--echo-text-xs | 0.75rem | Signal meter |
--echo-text-sm | 0.8125rem | Signal meter |
--echo-text-md | 0.875rem | Signal meter |
--echo-text-lg | 1rem | Signal meter |
--echo-text-xl | 1.25rem | Signal meter |
--echo-text-2xl | 1.625rem | Signal meter |
--echo-text-3xl | 2.5rem | Signal meter |
Component CSS takes every font size from this scale. It is in rem, so it follows the reader's
browser text size.
Weights, line heights and letter-spacing have scales too:
| Scale | Token | Value |
|---|---|---|
| Weight | --echo-weight-regular | 400 |
| Weight | --echo-weight-semibold | 600 |
| Weight | --echo-weight-bold | 700 |
| Weight | --echo-weight-heavy | 800 |
| Line height | --echo-leading-none | 1 |
| Line height | --echo-leading-tight | 1.25 |
| Line height | --echo-leading-snug | 1.4 |
| Line height | --echo-leading-body | 1.55 |
| Letter-spacing | --echo-tracking-tighter | -0.02em |
| Letter-spacing | --echo-tracking-tight | -0.01em |
| Letter-spacing | --echo-tracking-normal | 0 |
| Letter-spacing | --echo-tracking-wide | 0.06em |
| Letter-spacing | --echo-tracking-wider | 0.12em |
| Letter-spacing | --echo-tracking-label | 0.2em |
| Letter-spacing | --echo-tracking-widest | 0.25em |
Text styles
A text style bundles a face, size, weight, line height and tracking under the job it does. Use one by name instead of picking five values:
| Style | Built from | Specimen |
|---|---|---|
--echo-type-machine-label | machine, 3xs, bold, leading tight, tracking label, uppercase | Output level |
--echo-type-body | sans, md, regular, leading body, tracking normal | The signal drops out when the cable is loose. |
--echo-type-body-sm | sans, sm, regular, leading body, tracking normal | Changes apply to every channel on this device. |
--echo-type-caption | sans, xs, regular, leading snug, tracking normal | Last synced 2 minutes ago |
--echo-type-heading | machine, lg, bold, leading tight, tracking tight | Delete this preset? |
--echo-type-readout | lcd, xl, regular, leading none, tracking normal | -12.4 dB |
--echo-type-display | sans, 3xl, bold, leading none, tracking tighter | 017 |
letter-spacing and text-transform aren't part of the CSS font shorthand, so each style comes
as three tokens:
.panel-label {
font: var(--echo-type-machine-label);
letter-spacing: var(--echo-type-machine-label-tracking);
text-transform: var(--echo-type-machine-label-case);
}The machine label is Echo's voice: small, uppercase and spaced out, like the legend printed on a panel. Keep it for labels of two or three words. A sentence in spaced capitals is hard to read.