# Your brand, no build step.

> Brand ApiGlow with your own daisyUI theme and no build step: a config entry or a plain CSS block, with theme generator output pasted verbatim.
>
> Source: https://apiglow.dev/docs/theming/index.md


A daisyUI 5 theme is a block of CSS custom properties scoped to a `data-theme` selector, which is why ApiGlow can accept yours at runtime. There are two channels, and both take the output of the [daisyUI theme generator](https://daisyui.com/theme-generator/) as-is.

The [builder](/docs/builder/) authors one for you: pick a base, set your color, and it writes the entry below — with a live preview of the console and a contrast audit of every text-on-surface pair.

## Channel 1: the config

Declare the theme in `theme.custom`. The app generates and injects its CSS at boot.

```json
{
  "theme": {
    "default": "acme",
    "available": ["acme", "light", "dark"],
    "custom": [
      {
        "name": "acme",
        "extends": "dark",
        "tokens": {
          "--color-primary": "#6d28d9",
          "--color-primary-content": "#f5f3ff",
          "--radius-box": "0.5rem"
        }
      }
    ]
  }
}
```

- `name` — required, matching `[a-z][a-z0-9-]*`. Naming it after a built-in theme such as `light` or `dark` restyles that theme in place. This is the shortest path to "keep light and dark, brand the primary".
- `extends` — optional, any **built-in** daisyUI theme to inherit from. The common case is "dark, but in our colors": a handful of tokens. Without it, unset tokens fall back to the build's default theme, so declare the full set — the generator emits every token anyway. Extending another custom theme is not supported.
- `colorScheme` — optional, `"light"` or `"dark"`. It drives browser-provided UI such as scrollbars and form controls, and is inherited from `extends` when absent.
- `tokens` — daisyUI 5 theme variables under their verbatim names: the twenty `--color-*`, the radii and sizes, `--border`, `--depth`, `--noise`. Generator output therefore pastes straight in.

List the theme in `theme.available` as well, or it is injected but not selectable.

## Channel 2: your own CSS

A plain block in the host page's stylesheet, plus the name in `theme.available`. No other config.

```css
[data-theme="acme"] {
  color-scheme: dark;
  --color-primary: #6d28d9;
  --color-primary-content: #f5f3ff;
  /* …the rest of the daisyUI theme variables… */
}
```

Undefined tokens fall back to the default theme's values. To restyle a built-in theme name in place, prefer the config channel: it mirrors daisyUI's own selectors, so it keeps working regardless of how daisyUI layers its styles.

## Validation is lenient

Nothing about a theme is allowed to break the page:

- An unknown token or an invalid value is skipped, with a console warning.
- A custom name missing from `available` is flagged as a likely config mistake, but still injected.
- A duplicate name warns, and the first declaration is kept.

## In multi-spec

`theme.custom` is root-only, since themes are injected once at boot. A `specs[]` entry can still override `theme.default` and `theme.available`: a spec narrows what is selectable, it never defines a theme. Details in the [multi-spec guide](/docs/multi-spec/).

The rest of the branding story — product name, logo, and the About dialog that always stays — is on the [portal pillar](/features/portal/).

