Foundations
Colour
Twenty two raw values and twenty one roles. A component never reads a value from the top half of this page: colour is the one thing a theme and a rebrand override, so it is read through a role or not at all. Geometry goes the other way and is read straight from the primitive, because it has nothing to override.
Primitive, the raw values
Fourteen of these are the product. Nine came off brand-plate-j.png, eight as pixels and one measured, and five are derived. The eight below the rule are the light end of the same ramp, added at step 3 of this stage, and they are the only values this stage introduced. Every one carries where it came from.
The warm neutral ramp, and it carries the whole console
Amber, the one saturated hue the console spends
Attribute A2 says saturation is scarce, and on this product that is a number rather than a stance: the accent does four jobs and no fifth, counted in the DOM on the finished screen rather than asserted. Latitude, the live state, where you are, and the row being decided with its primary action.
The failure hue and the severity ramp
The ramp descends in chroma and not in loudness. On a dark ground every value has to clear 4.5:1, which compresses the whole ramp into 4.6 to 6.5, so brightness cannot carry it. Warm to cool, and it never reaches green: a low severity case is not a resolved one, and green would say it was. Nothing in this product is green anywhere, including the six state chips, because they are positions and not outcomes.
The light end of the same ramp, and it is all this stage added
A role without a pair is not allowed and the ramp above has no light end, so eight values were derived by the method the product already used for --warm-850 and --warm-400: hold the plate's hue and saturation, move lightness until the threshold is met. Nothing here is sampled from anywhere new and nothing here is a second palette.
Semantic, the roles
Every role names the surface it paints, because the surface decides the threshold. One role may not paint two surfaces even when the purpose is one and the value is identical: a fill role dropped onto a small bold label passes as a surface and fails as text, and a table of text and background pairs cannot see it, because nobody declared it as text.
Both themes are shown at once, on purpose. Each card is split: the left half is the theme the product ships and the right half is its pair. Neither half follows the switcher in the panel, because the pairs were written as material at step 3 and a page that showed only the current one would hide half of what it documents.
Contrast, computed in this page
Not transcribed. Every figure below is measured when the page renders, by painting each role onto each ground and reading the result back, so a token that changes changes this table with it. Every role is tabulated, not only the ones somebody called textual, because that is exactly where a fill role painting a label would hide.
Thresholds: 4.5:1 for ink, dropping to 3:1 at 24px or at 19px bold. 3:1 for fill and line, WCAG 1.4.11, non-text contrast. Eight rows are exempt and each carries its reason in the verdict: a ground is not a boundary, a divider is not a control, and a decorative glyph is not text. The exemption is written rather than assumed, which is the only way the next reader can tell a decision from an oversight.
| Role | Paints | Measured against | Dark | Light | Floor | Verdict |
|---|
The two lines that are below a floor on purpose
--line-separator separates and never carries meaning, so it sits below every floor deliberately. It is the line between rows, and it lived in four files and in no variable at all until the stage 06 audit found it.
--line-edge draws panel edges at 2.997 in dark and 2.88 in light, and that is allowed for exactly what it does. WCAG 1.4.11 covers what identifies a control, not a divider. Anything that is the boundary of a control takes --line-control, which clears 3:1 from both directions. This was recorded at stage 06 as sitting at "exactly 3.00", which was a rounded number reported as a threshold met, and the recomputation corrected it.