Elevation — four surfaces
Color is never decoration — it is elevation or action, and nothing else. (It used to be a third thing, authorship; that is retired, and the last section on this page says what replaced it.) Depth is light, not lines.
The owner’s canvas
The canvas is a preference too. Pick any background — a light pick re-skins the light theme, a dark pick the dark — and the engine (@morna/tokens/surfaces) re-derives the whole ladder above from it, with the pick’s hue surviving into every rung. The contrast dial decides how far the rungs step from the canvas: 50 is the shipped look, 0 melts the cards into the room, 100 doubles the depth. Every rung is held to its ink floor, so no canvas ever ships that the words can’t stand on.
These write the real preferences — this documentation re-skins as you drag, and so does the product. Hairlines scale with the dial but never fully vanish: structure survives contrast 0.
Action — one accent
The accent is Morna ink by default — #111111 on light, #F2F2F2 on dark, black-on-white and white-on-black — and any color the owner picks after that: a swatch, the wheel, or a typed hex. The engine (@morna/tokens/accent) derives what ships: a light base held to 4.0:1 on white, a dark base held to 4.5:1 on the near-black canvas, and the ink that sits on the accent chosen by contrast rather than assumed to be white. No hue reaches the glass unreadable.
Four custom properties carry it, inlined on <html style> server-side: --accent-l, --accent-l-ink, --accent-d, --accent-d-ink. Consumers never read those directly — the token sheet routes them per theme into --sys-blue (the legacy variable name every consumer still reads) and --accent-ink, and washes and glows color-mix off the live value, so they follow a pick with no extra vars.
This is not a sandbox — the swatches above write the real preference. Pick one and this documentation, the product, and every derived wash re-derive together. The law survives the freedom: there is still exactly one accent per surface.
The semantic ramp
Four meanings, tuned per theme, and none of them competes with the accent. Semantics are moments, not moods — a row may flash them; a page never wears them.
| Token | Light | Dark |
|---|---|---|
--sem-success | #267747 | #63CF84 |
--sem-warning | #9B6200 | #F2B84B |
--sem-error | #C43D3D | #FF6B68 |
--sem-attention | #9B6200 | #F2B84B |
--sem-info | #111111 | #F2F2F2 |
Note --sem-info: it is the ink itself in both themes. Informational is not a hue in this system — it is simply the text.
Authorship — retired as a color
--prov-* token in tokens.css now resolves to one neutral gray — #757575 on light, #878787 on dark, glow transparent — and the enumerated [data-c="…"] switch was replaced by a single neutral block. What replaced it: the name, the role, the initial and the seat glyph, which were always required to stand beside the light and are now the whole carrier.The reason is stated in the token sheet itself: one signal accent for the system, and specialist identity kept neutral so a semantic color can never be misread as a specialist — an amber row means watch this, never Sofi.
One thing did survive: a grown seat — one this workspace added, that the base eight never heard of — still gets a generated, stable hue inline from seatVars(), because a seat with no token entry needs something of its own. The base eight never do. The full resolver lives under Components → Seats & provenance.