Typography
Summary
Soma uses the system font stack (zero network weight, native rendering on every platform) with a monospace stack for code, logs and diffs. Type is styled at the element level: headings, paragraphs, lists, quotes and code need no classes inside content areas.
Type scale
| Token | Size | Used for |
|---|---|---|
--soma-font-size-display | 30px | Stat-tile values, the shell page title (.soma-page-title) |
--soma-font-size-xxl | 24px | h1 |
--soma-font-size-xl | 20px | h2, the navbar brand, dialog titles |
--soma-font-size-lg | 16px | h3, widget/drawer/toolbar titles |
--soma-font-size-md | 14px | Body, controls, menus (the base size) |
--soma-font-size-sm | 13px | Dense UI: table cells, sidebar, <small> |
--soma-font-size-xs | 12px | Micro-text: timestamps, hints, badges, h5/h6 labels |
Density modes never change the scale (only vertical padding), so compact screens stay as readable as comfortable ones.
Examples
Small print
<small> renders at the sm size (13px) in the
muted colour; badges, timestamps and other micro-text use xs
(12px). Two colour tiers matter here:
--soma-color-text-muted for informational
micro-text (timestamps and gutters, which must stay readable), and
--soma-color-text-subtle for decorative text only.
The axe sweep enforces this split.
Vertical rhythm
Spacing flows downward only: block elements push
away from whatever precedes them with a top margin, and nothing
carries a bottom margin. That makes spacing predictable (the gap
above an element depends only on that element, never on what came
before), and containers never end with stray trailing space,
because every :first-child block sits flush
(margin-top: 0).
- Flowing blocks (
p,ul,ol,dl,blockquote,pre,table.soma-table,.soma-tabs,.soma-widget,.soma-list-group) getmargin: var(--soma-space-3) 0 0(12px above, nothing below). - Headings push down harder, scaled to their level:
h1/h2get--soma-space-6(32px) above,h3gets--soma-space-5(24px),h4–h6get--soma-space-4(16px). - Directly stacked headings (
h1 + h2,h2 + h3, …) tighten to--soma-space-2(8px), so a title and its subtitle read as one unit.
If you add your own block components to content areas, follow the
same contract: top margin from a --soma-space-*
token, no bottom margin, flush when first.
Changing the font
The whole library reads its faces from two tokens, so swapping
the font is a two-line override after soma.css, no
rebuild needed:
:root {
--soma-font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
--soma-font-family-mono: 'JetBrains Mono', ui-monospace, monospace; /* optional */
}
Keep the system faces in the fallback chain, and remember the trade you're making: a webfont costs network weight and a flash of fallback text that the default system stack avoids. Sizes are unaffected; the scale tokens are separate.
HTML
<h1>Page title</h1>
<p>Body text with a <a href="…">link</a> and <code>code</code>.</p>
<blockquote><p>Quote</p><cite>Source</cite></blockquote>
<pre><code>block code</code></pre>
No classes needed: the element styles live in
_typography.scss. The mono stack is exposed as
--soma-font-family-mono for custom components
(the log viewer and diff consume it).