---
title: Colors and the CSS cascade
description: Six color keys, and the four layers your styles land in.
---

## The six keys

`colors` is required and takes exactly six keys, no more and no fewer:

```json
{
  "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

Reed assembles one stylesheet from four layers, concatenated in a fixed order so later
layers win:

<Steps>
  <Step title="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.
  </Step>
  <Step title="L1 — template baseline">
    The chosen template's own stylesheet. `mint` re-declares the L0 properties in its own
    baseline and therefore wins over them.
  </Step>
  <Step title="L2 — generated design tokens">
    The variables derived from your `colors`, `typography` and explicitly-set `layout`
    values.
  </Step>
  <Step title="L3 — customCss">
    The contents of your `customCss` files, in `docs.json` array order. Highest
    precedence.
  </Step>
</Steps>

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

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.
