# Colors

_Box Kite 2.2.6 · a markdown copy of https://www.box-kite.dev/colors/_

Every colour token in OKLCH — twenty-six families of eleven steps — and the one modifier a colour value takes.

## A colour is a variable

Every token is a CSS variable, written with its own value as the fallback, so it is declared nowhere: a `:root` insert after the page has painted would recalculate every element on it. Declare `--blue-500` yourself and it wins. That is what makes a colour cheap to repeat and possible to override — and why the values below are `oklch()` rather than hex: a perceptual space is what keeps a step even across the hues and a theme legible at every one of them.

**What a token compiles to**

```css
/* bgColor="blue-500" — lightness, chroma, hue */
.bgColor-blue-500 {
  background-color: var(--blue-500,oklch(62.3% .214 259.8));
}
```

## Twenty-six families, eleven steps

Five neutrals, four more that sit between them (`mauve`, `mist`, `olive`, `taupe`) and the seventeen hues. Hover a swatch for the value behind it.

### keywords

currentColor · transparent · green · red · blue · gray · black · white · vi

### slate

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### gray

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### zinc

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### neutral

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### stone

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### mauve

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### mist

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### olive

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### taupe

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### red

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### orange

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### amber

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### yellow

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### lime

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### green

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### emerald

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### teal

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### cyan

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### sky

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### blue

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### indigo

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### violet

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### purple

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### fuchsia

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### pink

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

### rose

50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950

## An opacity modifier

A slash and a number on any colour value — `bgColor="blue-500/40"` — is the token at 40% opacity. It works on every colour prop, and it nests wherever a colour does: inside a `hover`, a theme, a breakpoint, a `cq`.

**The same token, five opacities**

```jsx
<Flex gap={3}>
  <Box width={16} height={16} borderRadius={2} bgColor="violet-500/100" />
  <Box width={16} height={16} borderRadius={2} bgColor="violet-500/80" />
  <Box width={16} height={16} borderRadius={2} bgColor="violet-500/60" />
  <Box width={16} height={16} borderRadius={2} bgColor="violet-500/40" />
  <Box width={16} height={16} borderRadius={2} bgColor="violet-500/20" />
</Flex>
```

## The alpha lands on the colour, not on the element

`opacity` fades the whole element — its text, its border, its children. The modifier fades one declaration, because it compiles to a `color-mix()` against `transparent`: the token stays a `var()`, so a themed colour is still themed and every element asking for the same value still shares one class. The mix is done in `oklab` — mixing towards transparency in a polar space would drag the hue along with it.

**What the modifier compiles to**

```css
/* bgColor="blue-500/40" */
.bgColor-blue-500\/40 {
  background-color: color-mix(in oklab, var(--blue-500,oklch(62.3% .214 259.8)) 40%, transparent);
}
```

## Your own colours take it too

A variable declared through `Box.extend()` is a colour value on every one of those props, and the modifier applies to it unchanged — the mix reaches the variable, whatever it was declared as. A token the palette does not have (or a percentage outside 0–100) is not a colour: it produces no rule and no class name, the way every unmatched value does.

**A brand colour, and the modifier on it**

```jsx
// once, before the first render
Box.extend({ brand: 'oklch(62% 0.19 264)' });

<Box bgColor="brand" b={1} borderColor="brand/30">
  Brand, and its border at 30%
</Box>;
```

---

_Every page: https://www.box-kite.dev/llms.txt · every prop, measured: https://www.box-kite.dev/props.md_

