Skip to content

Chapter 03

Colour

Every colour has one job, and the job is the rule. There is no palette to pick from. Written from 01_BRAND-LAYER/colour.md v3.1.1 and two-grounds.md v3. Sixty two measured rules hold in 05_TOOLS/measure-palette.mjs.

Two grounds, and there is no dark mode

Paper is the sheet the work is read on. The flood is the same ink at full coverage: a place on the page where the ink has covered everything, and the one place the chrome mark is at home. Which one a block sits on follows from what the block does, never from a preference and never from a theme.

A theme is a preference the reader sets. A ground is a decision the document makes. A headline set in paper on the flood is an object; the same headline on paper is a heading in a report. Offering both would mean neither is designed. There is exactly one dark ground token and exactly one reading ground token, and no house stylesheet contains a colour scheme query or a theme attribute.

The flood is counted. The paper is not. At most two flood entries per surface, at most one in an audit, and the audit's one closes the document.

ground.paper --u-color-ground-paper #F5F4F1 The reading ground of every surface. Ink measures 16.50 to 1 on it. It may not carry a tint.
ground.paper-raised --u-color-ground-paper-raised #EBE9E4 The one step. Table zebra, quote figure, notice, hover. Never the ground of a section, never stacked on itself.
ground.trough --u-color-ground-trough #E2E0DD The bar track, full width, so the remainder reads as remainder. It may not carry a label: the faint ink measures 4.16 to 1 there, under the floor.
ground.flood --u-color-ground-flood #191512 The only dark. The same six digits as the ink. A full bleed block, never a theme, never alternating section by section, never sharing an edge with a signal.

Three light values read as three, 3.82 and 3.12 lightness steps apart. A fourth would need a job no surface has. Every light ground sits under a chroma of 10, because pastel grounds are coach code.

One pigment, and the ink ramp on each ground

The flood, the primary ink and the action are the same value. Paper, the inverse ink, the action ink and two of the signal inks are the same value. One near black, one near white.

On paper

ink.primary --u-color-ink-primary #191512 Headings, figures, body, flush blocks, the action. 16.50 to 1 on paper, floor 12. Never screened to a grey.
ink.secondary --u-color-ink-secondary #4E4B45 Secondary prose and captions with content weight. The cool secondary. 7.90 to 1. Never a headline, never a label.
ink.secondary-warm --u-color-ink-secondary-warm #595248 The warm secondary, for a document where the cool one reads clinical against the warm paper. 7.01 to 1. Chosen once per document, never mixed with the cool one.
ink.faint --u-color-ink-faint #6C6962 Labels, footnotes, source lines. 4.98 to 1. Never body, never under 12px, never on the trough, never on the heat band.

On the flood

ink.inverse --u-color-ink-inverse #F5F4F1 Every headline and body line on a flood. Paper itself. 16.50 to 1.
ink.inverse-secondary --u-color-ink-inverse-secondary #A3A19E The second voice in a flood colophon. 7.04 to 1.
ink.inverse-faint --u-color-ink-inverse-faint #898683 Labels on the flood. 5.01 to 1.

The lines

rule.paper --u-color-rule-paper #D9D6CF Every hairline on the light grounds. One weight, 1px. No gridlines, no radius, no shadows.
rule.flood --u-color-rule-flood #322F2C Every hairline on the flood, including a frame there.
rule.axis --u-color-rule-axis #7C7976 Chart baseline, reference line, ticks, and any hairline inside a zebra band or a bar track. Under the marks, never over.

Three signals, three named jobs

A signal is a field: a full bleed band or a bounded field carrying display type in the signal's own ink. It is never type, never a control, never a border, never a chart colour, never a grade. Each field carries its own ink token, because the primary ink on vermilion measures 2.85 to 1 and is a defect. The four are named on the swatches below; heat's is a near black of its own and is not a value anyone would guess. And before you look for one: there is no warning colour, no error colour, no success colour. A surface that has to say something went wrong says so in words. The reason is under no status token exists.

signal.primary, vermilion --u-color-signal-primary #B7260E ink on the field, signal.primary-ink --u-color-signal-primary-ink #F5F4F1 The default and only signal a surface shows unless it needs two. The one band under the hero block, the offer slide, the painted print edge. Recognition lives here.
signal.secondary, blue --u-color-signal-secondary #1743B8 ink on the field, signal.secondary-ink --u-color-signal-secondary-ink #F5F4F1 Data colour on a brand surface. Link colour on paper, the one place a signal is allowed to be type. The second field when the primary is already on the page.
signal.tertiary, acid --u-color-signal-tertiary #D8FF3E ink on the field, signal.tertiary-ink --u-color-signal-tertiary-ink #191512 The highlight field behind one quoted client line, once per document. Paper with a hue in it, 1.68 lightness from paper. Never a band, never a section ground, never beside a finding.
signal.heat --u-color-signal-heat #FF6A13 ink on the field, signal.heat-ink --u-color-signal-heat-ink #1C0B00 Not a fourth signal. One job: the audit band, the conversion module with its label, statement, handle input and action. Nowhere else, ever.

The budget, as numbers

  • Signal fields per viewport: 1. A viewport shows vermilion or heat and never both. Three signals on one viewport: never.
  • A field's height: 25 percent of the viewport or less. The audit band is a module, not a field, and carries its own cap of 50 percent, measured at 1280 by 900 and 390 by 844.
  • Acid per document: 1 or fewer.
  • A signal adjacent to a flood: zero. The two measure 2.85 to 1 against each other and the seam reads as a fault.
  • A signal carrying a mark: zero. Recognition lives on the field, not on the mark.
  • A signal as type, control, rule, border, chart palette or grade: zero. The one exception is blue as link text on paper.
  • Signals on the audit surface: zero. In the audit build the tokens do not exist, which is stronger than a rule telling people not to.

The three signals sit at least 60 degrees apart in hue, so signals that can share a surface are told apart by hue alone and never by weight. Heat and vermilion sit 10.9 degrees apart and are deliberately not hue gated, because the layout rule already keeps them out of the same viewport.

The action is the ink

One per viewport. An ink block, squared, uppercase label in paper, a two pixel border, inverting instantly when the pointer enters it. There is no chromatic action and no chrome action anywhere in the system. A vermilion button fails two rules at once.

See how a surface is built

On the heat band the action is this same ink block, which measures 6.33 to 1 against the field. The inversion is instant because both motion tokens are zero.

Chrome is an ingredient, never a surface

The ramp was measured, not chosen: read off the wordmark itself over 780,205 opaque pixels. A chrome fill with ink text on it was ruled a catastrophe on 2026-08-22, and the two tokens that made it possible were deleted.

chrome.100 --u-color-chrome-100 #F7F5F2 The high stop of the frame's ramp.
chrome.300 --u-color-chrome-300 #BEBDBB The upper mid stop.
chrome.500 --u-color-chrome-500 #8B8A88 The mark's own mean, and the one colour a single colour reproduction of the mark uses. 3.14 to 1 on paper, 5.26 to 1 on a printed flood.
chrome.700 --u-color-chrome-700 #574F48 The lower mid stop and the ramp's highest chroma, which is still under 6, so chrome has no hue.
chrome.900 --u-color-chrome-900 #262523 The deep stop. 13.92 to 1 on paper.

Chrome appears in exactly three places

  1. The mark. Light version at home on the flood, on paper only with air. Dark version for small sizes and inline use on paper. See Marks.
  2. The three explainer objects, the gear, the engine and the anvil, as cutouts lying on the paper against the type. See Imagery.
  3. The one pixel hairline frame, a ten stop gradient at 96 degrees applied as a border image on a transparent border. Paper only; on the flood a frame takes the flood's own hairline. This page head is framed with it.

Never a fill, a band, a slab, a button, a background, or a letterform other than the logo. In print, chrome is nothing, and the substitution is the mark's own mean.

The person pair, audit only

Two values that code which of two people a figure belongs to, and nothing else. Light grounds only, because on the flood they fall under the accessibility floor.

person.a --u-color-person-a #26627F One of two people in an audit figure. Equal weight and equal lightness to its pair by measurement, separated by hue alone.
person.b --u-color-person-b #8A5216 The other person. 179.3 degrees away in hue, 1.37 lightness apart, and still separated under the worst colour vision deficiency case.

Rows carrying the pair sort alphabetically, so no call site can order them by value. A brand surface has no person colour: it codes its data in blue.

Colour never grades a person

This is the rule the whole palette is arranged around, and it is the reason there is nothing to argue about.

What may sit on what

The quick answer to the question a builder actually has. Every ratio below is measured, and the floor beside it is the gate that fails first if a value moves.

Permitted pairs and their measured contrast
Ground What may sit on it Measured What may not
Paper Primary ink, either secondary, faint ink, the blue link, the dark mark, an explainer object, the chrome frame, a signal field, the ink action 16.50, 7.90, 7.01, 4.98 A tint of paper, a fourth light ground, the light mark outside a hero header
Paper raised Primary ink, either secondary, faint ink, the blue link. As an element ground only 14.96, 7.16, 6.35, 4.51 A section, itself stacked, a mark
Trough A bar, the axis line. Nothing else 13.77 for ink Words. The faint ink measures 4.16 there, under the floor
Flood Inverse ink, inverse secondary, inverse faint, the flood hairline, the light mark at 240px or wider, the inverted action 16.50, 7.04, 5.01 A signal field or a shared edge with one, a chart, a table, the person pair, the chrome frame, a second chrome object
Vermilion Its own ink, at display sizes only 5.79 A mark, a control, primary ink, an image, an adjacent flood
Blue Its own ink as a field. As type it is the link on paper 7.54 field, 7.54 as a link Being the first field on a surface, or swapped in for vermilion page by page
Acid Primary ink, behind one quoted client line 15.81 A band, a section ground, type, a position beside a finding
Heat Heat ink for the label, statement and input text; the primary ink block as the action and the input hairline 6.67 and 6.33 Paper type at 2.61, faint ink at 1.91, any line that is not the audit band's

The gate

Run node 05_TOOLS/measure-palette.mjs from 01_IDENTITY/. Exit 0 means all 62 rules hold. Exit 1 prints the broken rule with a detail line. The colour maths lives once, in that script, and nowhere else.

Print

Paper is the stock reference. Ink is one pigment and the flood is that pigment at full coverage. The identity is print native by construction, which is what won it the direction.

Vermilion is a flat spot colour in its one job: the painted edge of a print object, the offer slide, the one band. Every adjacency rule holds on stock. Chrome is nothing in print, and the substitution is the mark's own mean at 3.14 to 1 on paper and 5.26 to 1 on a printed flood. A printed page passes when a viewer who saw the system once can still name the brand from a monochrome sheet with the wordmark covered.

Open: no spot ink reference is recorded for vermilion, and heat has no print job stated, because the audit band is a web module with an input and a printed sheet has no input.

Chapter 03 of the Unforged brand book. Written from 01_IDENTITY/01_BRAND-LAYER/colour.md v3.1.1 and two-grounds.md v3. Every chip above is painted from its token; the hex beside it is the same value printed as documentation.