# Theming contract

Luuphub brands the hosted portal and the embedded widget through **CSS
custom properties**. Following the Ybug/Koala pattern:

> **The CSS variables are the API. The internal class names are not.**

Theme through the documented `--bc-*` variables and you are never broken by an
internal markup refactor. This is contract **version 1** — the
version is bumped only on a breaking change (a variable removed, renamed, or given
a new meaning), and every saved branding records the version it was authored
against.

## The variables

Each color role maps 1:1 to one stable `--bc-*` variable:

| CSS variable | Role | What it paints |
| --- | --- | --- |
| `--bc-brand` | Brand | Primary action color — buttons, the launcher, active tabs. |
| `--bc-brand-fg` | Brand text | Text/icon color that sits on the brand color. |
| `--bc-brand-hover` | Brand (hover) | Hover/pressed state of the brand color. |
| `--bc-bg` | Background | Page/surface background. |
| `--bc-bg-elevated` | Elevated surface | Cards, panels, popovers raised above the background. |
| `--bc-fg` | Text | Primary body text. |
| `--bc-fg-muted` | Muted text | Secondary text, metadata, captions. |
| `--bc-border` | Border | Hairlines and dividers. |
| `--bc-accent` | Accent | Secondary attention color for highlights and badges. |
| `--bc-accent-fg` | Accent text | Text/icon color that sits on the accent color. |
| `--bc-ring` | Focus ring | Keyboard focus outline color. |

## Using them

Set the variables on a scope that contains the widget/portal (or `:root`):

```css
:root {
  --bc-brand: #e0342c;
  --bc-brand-fg: #ffffff;
  --bc-bg: #fbf7f2;
  --bc-fg: #201613;
}
```

Foreground/background roles come in **pairs** so contrast can be validated: the
branding editor runs a WCAG contrast check on each pair and warns before you save
a combination that fails legibility. Dark mode is auto-derived per pair, so you set
light values once.

## Stability guarantee

- The variable names above are frozen across non-breaking releases.
- Class names (`.bc-launcher`, panel markup) are **not** part of the contract and
  may change at any time.
- On a breaking change we bump the contract version and migrate saved themes.
