> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mzizi.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Design tokens

> The Seven African Minerals, the semantic colour layer, and how a value flows from N1 to every node above it.

N1 is the only node allowed to **define** a CSS value. Every other node reads values through
`var()`. That single rule is what makes the rest of the system portable: swapping the token
layer is one of the three declared fork seams, and it works because nothing above N1 has an
opinion about a hex code.

The live token set is published at `GET https://api.mzizi.dev/v1/brand`. Values below were
read from it on 29 September 2026 at brand version `4.0.31`.

```bash theme={null}
curl https://api.mzizi.dev/v1/brand
```

## The Seven African Minerals

<Warning>
  **Seven, not five.** A great deal of inherited documentation says "the Five African
  Minerals". Sodalite and copper were added, and the five-mineral phrasing was removed from
  the framework repository and guarded against there. If you find it in a client, a manifest
  or a page, it is out of date.
</Warning>

| Mineral | CSS variable | Light | Dark | Origin | Used for |
| - | - | - | - | - | - |
| Cobalt | `--color-cobalt` | `#0047AB` | `#00B0FF` | Katanga and the Zambian Copperbelt | Links, info, focus rings |
| Tanzanite | `--color-tanzanite` | `#4B0082` | `#B388FF` | Merelani Hills, Tanzania | Primary brand, creativity, social |
| Malachite | `--color-malachite` | `#004D40` | `#64FFDA` | The Congo copper belt | Success, positive actions |
| Gold | `--color-gold` | `#5D4037` | `#FFD740` | Ghana, South Africa, Mali | Achievements, rewards, highlights |
| Terracotta | `--color-terracotta` | `#A0522D` | `#E1B07E` | — | Warm accent |
| Sodalite | `--color-sodalite` | `#283593` | `#3D5AFE` | — | Deep blue accent |
| Copper | `--color-copper` | `#BF5A36` | `#FF8A65` | — | The Bundu parent identity |

Each mineral also carries a container pair — a pale fill for light mode and a deep one for
dark — for hover states, selected rows and soft highlights.

<Note>
  **`--primary` is never cobalt.** Cobalt is the exceptional mineral, reserved for links,
  informational states and the focus ring, for every brand. Reaching for cobalt as a primary
  action colour is the most common token mistake in this system. Which colour `--primary` is
  depends on the brand; see [brand minerals](#brand-minerals).
</Note>

## Brand minerals

Each brand in the Bundu ecosystem has a brand mineral, listed in the `ecosystem` array of
`GET /v1/brand`. It sets that brand's `--primary`. Read on 30 September 2026:

| Brand | Brand mineral | Family |
| - | - | - |
| Mzizi | Hematite | Heritage |
| bundu | Copper | African Minerals |
| nyuchi | Gold | African Minerals |
| mukoko | Tanzanite | African Minerals |
| shamwari | Sodalite | African Minerals |
| events | Malachite | African Minerals |

The mukoko mini-apps and sister brands carry their own rows in the same array. `events` is
Mukoko Events: the row was `nhimbe` until the brand was retired on 4 October 2026, and canon
keeps `nhimbe` as a deprecated alias of it.

**Mzizi's brand mineral is hematite**, by the owner's decision of 30 September 2026. Hematite
is one of the seven heritage tones, not one of the Seven African Minerals: `--color-hematite`,
`#546E7A` in light mode and `#90A4AE` in dark, "foundation, endurance, the substrate".

The registry's default stylesheet, `mzizi-tokens-globals.css`
([`GET /v1/ui/mzizi-tokens-globals`](https://api.mzizi.dev/v1/ui/mzizi-tokens-globals)),
resolves `--primary` per brand. Set `data-brand` on `<html>` to choose one; with no
`data-brand`, the default is Mzizi, so `--primary` is `var(--heritage-hematite-aa)`. Until
30 September 2026 that default was gold. `--ring` stays cobalt for every brand.

```css theme={null}
[data-brand="mzizi"] {
  --primary: var(--heritage-hematite-aa);
  --ring: var(--mineral-cobalt-aa);
}

[data-brand="mukoko"] {
  --primary: var(--mineral-tanzanite-aa);
  --ring: var(--mineral-cobalt-aa);
}
```

The `-aa` variants are the accessible tier of each family. For hematite that is `#546E7A` in
light mode, which already clears the bar, and `#C9D2D7` in dark mode.

## Semantic colours

Components reference semantic names, never minerals directly. Fourteen are published; these
are the ones components reach for most. The `--primary` value here is the one `/v1/brand`
publishes, tanzanite; the stylesheet sets it per brand, as [brand minerals](#brand-minerals)
describes.

| Token | Light | Dark | Meaning |
| - | - | - | - |
| `--primary` | `#4B0082` | `#B388FF` | Primary brand action — tanzanite in `/v1/brand` |
| `--success` | `#004D40` | `#64FFDA` | Success, positive actions |
| `--warning` | `#7A5C00` | `#FFD866` | Caution |
| `--error` | `#B3261E` | `#F2B8B5` | Errors, destructive actions |
| `--info` | `#0047AB` | `#00B0FF` | Informational states — cobalt |
| `--neutral` | `#55514B` | `#A09C93` | Inactive status, secondary data series |
| `--syncing` | `#1C5962` | `#36ABBA` | In-progress sync, pending |
| `--offline` | `#674C32` | `#BA9570` | Offline, disconnected |
| `--border` | `#E7E5E0` | `#2A2927` | Cards, inputs, dividers — warm stone, not cool grey |
| `--ring` | `#0047AB` | `#00B0FF` | Focus ring — cobalt, 2px with 2px offset |

### The `--status-*` aliases

Five aliases exist over the semantic set, and a large share of the registry references them by
those names:

```css theme={null}
--status-success: var(--success);
--status-warning: var(--warning);
--status-error:   var(--destructive);
--status-info:    var(--info);
--status-neutral: var(--neutral);
```

They are **not a second palette** — they are a naming layer, declared in both the light and
dark blocks so a utility class generates for each.

<Warning>
  Earlier documentation listed eight semantic status *categories* — `--severity-*`,
  `--notification-*`, `--connection-*`, `--tier-*`, `--crypto-*`, `--moderation-*` and
  `--health-*` alongside `--status-*`. Only `--status-*` is defined in the published token
  layer. Connection and health states are covered by the semantic tokens above (`--syncing`,
  `--offline`, `--success`, `--warning`, `--error`) rather than by prefixed sets of their own.
</Warning>

## Backgrounds

Surfaces are a ladder, not a single background colour:

| Token | Light | Dark | Where |
| - | - | - | - |
| `base` | `#F3F3F1` | `#0E0D0C` | Page background |
| `container` | `#E5E4E1` | `#1E1D1A` | Neutral containers, grouped content |
| `muted` | `#FAF9F5` | `#050504` | Inset sections, metadata rows |
| `overlay` | `#E0DFDC` | `#23221F` | Overlays and dialogs |
| `raised` | `#D6D5D1` | `#2E2C29` | Menus and toasts above an overlay |
| `pitch` | `#FAFAFA` | `#050505` | Media wells, splash |
| `scrim` | `rgba(0,0,0,0.40)` | `rgba(0,0,0,0.60)` | Backdrop behind an overlay |

## Radii

Four numbers, and one identity rule.

| Token | Value |
| - | - |
| `sm` | 7px |
| `md` | 12px |
| `lg` / `base` | 14px |
| `xl` / `2xl` | 17px |
| `full` | 9999px |

**Buttons are always pill-shaped**, and so are inputs, avatars and badges. That is a brand
identity decision rather than a styling preference, and it is why those categories carry
`borderRadius: 9999` rather than a scale value.

## Spacing

The scale runs from a 2px hairline upward, with names rather than raw numbers:

| Token | Value | Usage |
| - | - | - |
| `xxs` | 2px | Hairline gaps — chip-in-chip, inline meta separators |
| `xs` | 4px | Tight gaps, icon padding |
| `xs-plus` | 6px | Icon-to-text offset |
| `sm` | 8px | Compact spacing, inline gaps |
| `sm-plus` | 10px | Dense tag padding |
| `md` | 12px | Compact component padding |
| `base` | 16px | Default component padding — cards, inputs |
| `base-plus` | 20px | Comfortable component padding |

## How a value reaches a component

```css theme={null}
/* N1 defines */
--color-malachite: #004D40;
--success: var(--color-malachite);
--status-success: var(--success);

/* N2 and above consume */
background-color: var(--status-success);
```

The chain is semantic token → mineral token → value, and it is one-directional. A component
that writes a hex code has broken the seam that lets an adopter fork the token layer and keep
everything else.

## Component specifications

Some tokens are component-shaped rather than colour-shaped, and they are published the same
way:

| Component | Default height | Small | Minimum touch target | Radius |
| - | - | - | - | - |
| Button | 56px | 48px | 48px | 9999 |
| Input | 56px | 48px | 48px | 9999 |
| Avatar | 40px | 32px | 48px | 9999 |
| Badge | 22px | — | — | 9999 |

The 48px floor is not negotiable; see [accessibility](/foundations/accessibility).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.