Colors and the CSS cascade
Six color keys, and the four layers your styles land in.
The six keys
Section titled “The six keys”colors is required and takes exactly six keys, no more and no fewer:
{ "colors": { "accent-primary": { "light": "#4E7D4A", "dark": "#7FAE79" }, "background": { "light": "#FBFAF7", "dark": "#14130F" }, "border": { "light": "#E4E0D8", "dark": "#2E2C26" }, "sidebar-background": { "light": "#F6F4EE", "dark": "#1C1B17" }, "header-background": { "light": "#FFFFFF", "dark": "#0B0A08" }, "card-background": { "light": "#FFFFFF", "dark": "#1C1B17" } }}Every key needs both light and dark. Six-digit hex only — three-digit shorthand and
eight-digit alpha forms are rejected rather than silently losing their alpha channel.
Six keys is deliberately few. They seed a much larger derived palette rather than being the palette themselves.
The four-layer cascade
Section titled “The four-layer cascade”Reed assembles one stylesheet from four layers, concatenated in a fixed order so later layers win:
L0 — component token contract
Declares every custom property the shared components read, for every template. Lowest precedence, and it exists so components never resolve a property to nothing on a template that did not declare it.
L1 — template baseline
The chosen template’s own stylesheet.
mintre-declares the L0 properties in its own baseline and therefore wins over them.L2 — generated design tokens
The variables derived from your
colors,typographyand explicitly-setlayoutvalues.L3 — customCss
The contents of your
customCssfiles, indocs.jsonarray order. Highest precedence.
Each layer is emitted with a marker comment — /* reed:L0 … */ through
/* reed:L3 … */ — so you can read the built stylesheet and see exactly which layer a
declaration came from. When an override does not take effect, that comment tells you
whether you are fighting L1 or L2.
Overriding
Section titled “Overriding”Your colors reach L2, above both the contract and the template baseline. customCss
reaches L3, above everything. Reed emits around 185 --reed-* custom properties plus the
underlying --sl-* variables, so overriding a token is usually better than overriding a
selector: tokens are the supported surface, selectors are an implementation detail that
can move.