Scale
Overview
The master numeric scale is the single ladder of numbers the whole system measures with. Spacing, corner radius, and sizing all draw from it — so every dimension in the system is a step on one shared ruler, never an arbitrary number.
It is built on a 4px base unit (--scale-1), expressed in rem (1rem = 16px). The step
number equals pixels ÷ 4 — so --scale-2 is 8px, --scale-4 is 16px, and so on.
Source of truth: tokens/primitives.css in the Monogem codebase.
Principles
- One scale feeds everything. Spacing, radius, and sizing reference these steps rather than inventing their own numbers. (Ties to Semantic over literal and Restraint.)
- A 4px rhythm. Every value is a multiple of 4px, so elements align to a shared grid without anyone thinking about it.
- Grow only on real need. Add a step when a repeated need appears — not preemptively.
Tokens
| Token | rem | px | Where you'd use it |
|---|---|---|---|
--scale-0 | 0 | 0 | No gap |
--scale-px | 0.0625 | 1 | Borders and dividers |
--scale-0-5 | 0.125 | 2 | Nudge an icon into alignment |
--scale-1 | 0.25 | 4 | Base unit — icon-to-label gap |
--scale-1-5 | 0.375 | 6 | Tag and badge padding |
--scale-2 | 0.5 | 8 | Small button padding |
--scale-3 | 0.75 | 12 | Input and button padding |
--scale-4 | 1 | 16 | Default gap between elements |
--scale-5 | 1.25 | 20 | Card and panel padding |
--scale-6 | 1.5 | 24 | Gap between form fields |
--scale-8 | 2 | 32 | Space between groups; small button height; small avatar size |
--scale-10 | 2.5 | 40 | Default button height; default avatar size |
--scale-12 | 3 | 48 | Large button height; large avatar size |
--scale-16 | 4 | 64 | Space between page sections |
--scale-20 | 5 | 80 | Gap between major sections |
--scale-24 | 6 | 96 | Page-level breathing room |
Rationale
Why 4px as the base? 4px is the finest step that still keeps a system tidy. It divides
evenly into the common 8px rhythm, gives enough granularity for small controls, and — critically
here — matches Tailwind's own spacing scale (Tailwind step n = n × 0.25rem). Aligning to
Tailwind means our tokens and Tailwind's utilities never disagree.
Why one scale for spacing, radius, and sizing? Because separate ad-hoc numbers are how systems drift. When a 14px gap and a 15px gap both exist, no one knows which is "right." A single ladder makes every dimension a deliberate, comparable choice, and keeps everything on the same rhythm.
Why skip some steps (no --scale-7, --scale-9…)? We keep the steps people actually reach
for and omit the ones that only invite bikeshedding. The numbering still maps to px÷4, so a
missing step is easy to add later without renumbering anything.
Why rem, not px? rem scales with the user's root font size, so the whole system
respects their zoom / accessibility settings. The px comments are just a reading aid.
Do / Don’t
Do
- Reach for a scale step for any gap, padding, margin, radius, or size.
- Reference the token (
var(--scale-4)), not the raw value. - Add a new step only when a real, repeated need shows up.
Don’t
- Hard-code one-off pixel values (
13px,17px) — pick the nearest step. - Use
--scale-pxfor spacing; it exists for hairline borders only. - Create a parallel scale for a single foundation — everything shares this one.