Expand description
The invariant half of the make-family design system.
[makeover] resolves colour, which varies by theme. This crate carries
everything that does not: spacing, radius, border width and the type scale.
The split is the same one Balanced Breakfast’s theme contract has always
drawn — a theme overrides colour tokens only — moved out of two app
stylesheets so the three consumers stop maintaining three copies of it.
§Spacing is relational, not numeric
The Mac OS 8 Human Interface Guidelines specify white space by what two things are being separated, never by a size name, and define no base grid unit. A control and its satellite pop-up are set 4 pixels apart; peers stacked in a list get 6; a group box’s inner margin is 10; separated groups and rows of push buttons get 12.
That vocabulary is the primary interface here. Gap names the
relationship and the size follows from it, exactly as surface-raised
names an intent and the hex follows from it. The raw Step scale exists
underneath for distances a relationship does not describe, but reaching for
it is a smell worth a second look.
Naming the relationship is what makes the rule reviewable. Whether a gap should be 6px or 8px is unanswerable in isolation; whether two things are peers is not.
§Ratios, not pixel counts
This is the deliberate departure from the HIG, which is specified in hard
device pixels because in 1997 there was one pixel density and one text
size. Every Step here is a Ratio of a single base unit, so the
whole system scales from one knob: --geometry-base, 1rem by default.
At the default base the ratios land exactly on the HIG’s numbers — Snug
is three eighths of 16px, which is 6px — so nothing is lost in the
translation. What is gained is that the layout tracks the user’s text size
instead of fighting it, an accessibility setting becomes one value rather
than a sweep, and the scale means the same thing at any display density.
§Density presets
Naming relationships instead of sizes is what makes a density preset
possible at all. Density changes what each relationship resolves to
without touching a single call site, because no call site names a size.
The mobile and desktop builds of a Tauri app should differ mostly by which
preset they emit, not by a parallel set of hand-written mode-scoped rules.
The two presets are not one scaled copy of the other, and the asymmetry is
the point — it is also why a base scalar alone cannot express this. Touch
needs more room between things you tap, because a fingertip is coarser
than a pointer, and less room around the edges, because the screen is
small and outer margin is screen you do not get to use. So Peer and
Section open up under Density::Touch while Pane and Page tighten.
Bound never moves: it is the one relationship that says “these are one
object”, and separating them on touch would say the opposite.
§Surfaces, and why a TUI is not a third density
Surface is the third axis and the one that carries this to alloy_tui. A
terminal is not a density preset; it is a surface whose smallest
representable step is one cell rather than one pixel. Give
Ratio::quanta a quantum and it answers in whole units of it, so the
relational vocabulary crosses to a character grid with nothing added.
Quantising is not a terminal special case either — a display quantises to the pixel. It is only that rounding 6.0 to the nearest pixel is uninteresting, while rounding three eighths of a cell to the nearest cell decides the layout.
On Surface::terminal the pointer preset resolves to 0, 0, 1, 1, 2, 2
cells. Bound and Peer collapsing to nothing is correct rather than lossy:
in a grid that dense, both relationships are expressed by adjacency. A
coarse surface genuinely has fewer distinctions available, and the model
should say so instead of inventing a gap to keep six names distinct.
So the three axes are: Gap is what is being separated, Density is
who is operating it, Surface is what it is drawn on.
Structs§
- Ratio
- A fraction of the base unit.
- Surface
- What the layout is being drawn on: a base unit, and the smallest step the surface can actually represent.
Enums§
- Density
- Which input the layout is being sized for.
- Gap
- A named separation between two things.
- Step
- A raw step on the underlying scale.
Constants§
- BASE_
TOKEN - The CSS custom property every ratio scales from.
- DEFAULT_
BASE_ PX - The default base unit in CSS pixels, at a 16px root font size.
Functions§
- density_
css - The whole spacing layer with the canonical density selection, as CSS.
- gap_
css_ declarations - Emit the relational layer for one density as CSS declarations, no selector.
- gap_
css_ overrides - Emit a density preset as a scoped override block.
- geometry_
css_ vars - Emit the whole geometry layer as a
:root { … }block at one density. - scale_
css_ declarations - Emit the base unit and the raw scale as CSS declarations, no selector.