Theme is not only light and dark; it includes contrast and density
Aliases: contrast theme · density theme · theme axes
What it is
A theme is a set of independently switchable axes, not two skins called “light” and “dark”. Light-dark flips the luminance direction of surfaces and type. Contrast changes the minimum difference between roles; high contrast pushes borders, focus rings, and type to a harder delta. Density changes spacing, type size, and control height; compact folds the same tree into shorter rows. Treating theme as a dark switch leaves high-contrast users trapped in a low-contrast dark, and leaves people who need more rows per screen with only “the spacious layout, dimmed”.
The three axes are orthogonal: light + high contrast + compact is legal, as is dark + standard contrast + comfortable. A boolean called dark does not cover that space.
Why it happens
Light-dark is a surface palette. Contrast is a constraint: the same semantic roles, on the high-contrast axis, must open to a distinguishable delta — sometimes by adding a border or thickness, not by darkening a colour a little. Density is a measuring stick: the same role’s padding goes from 16 to 8, row height from 48 to 32, and every wrapping and truncation threshold moves. Three decisions act on different quantities, so they fail differently — dark fails as a surface you cannot see; contrast fails as two roles read as one; density fails as cannot-hit, cannot-read, or too much on one screen.
Implementing “theme” as one dark switch crams the other two axes into the luminance table. High contrast becomes “a darker dark”; compact becomes “padding that happened to be smaller in dark”. Users cannot open the one axis they need; the system cannot validate that axis on its own. After the axes are folded, a theme feature appears to exist, and only luminance is a first-class citizen.
Where it stops holding
One-off marketing pages with no vision or motor demand and very little information may ship light-dark only, or a single set, without building three axes first. A contrast axis that only multiplies every colour by a coefficient, without checking role pairs, produces blow-out or mud — that is a filter, not a contrast theme. A density axis that only scales the whole viewport is forcing everyone through browser zoom, mixing targets that must not shrink with spacing that should. When the OS already offers contrast and type size, product axes should follow or yield, not sit beside a second set of fighting switches. A brand table is not a theme axis: brand is who is speaking; theme is reading and motor conditions for the same speaker.
Applying it
- Split theme into independent axes: light-dark, contrast (at least standard / high), density (at least comfortable / compact). Each axis has its own value table; combinations come from the product, not a pre-baked fourth skin called “dark compact”.
- A high-contrast table must raise borders, focus rings, and type-versus-surface delta, not only swap a background image. A compact table must change control height and spacing, then remeasure hit targets and truncation.
- Expose the three axes separately in settings; do not let one “dark mode” switch impersonate the whole theme.
- How to check: hold brand and flow fixed, switch only the contrast axis, and inspect a pair of roles that used to blend (secondary type vs surface, unselected border vs background). Switch only density, measure row height and rows per screen on the same table, and tap the edge-most icon — if it cannot be hit, density shrank the target too far. Then use the old “light-dark only” switch: if a high-contrast user still cannot read, the other two axes have not come out of luminance yet.
Related
- Same group: R1.15.1 Brands share structure and only retarget semantic values · R1.15.2 Validation cost grows as brands times states when brands are added · R1.15.4 A user-chosen theme must persist across sessions and take effect immediately
- Adjacent: R1.01 Named values · R1.09 Value layers and semantics
- Search terms:
theme axes beyond light-dark·contrast theme·density theme