# Luuphub 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-brand-hover: #c02a23;
  --bc-brand-text: color-mix(in srgb, var(--bc-brand) 60%, var(--bc-fg));
  --bc-brand-control: color-mix(in srgb, var(--bc-brand) 92%, #0e1311);
  --bc-brand-control-hover: color-mix(in srgb, var(--bc-brand-hover) 80%, #0e1311);
  --bc-bg: #f7f9f8;
  --bc-fg: #0f1512;
}
```

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.

### Accessible text and controls

The optional `--bc-brand-text` role mixes the brand toward the current foreground
for small text. `--bc-brand-control` and `--bc-brand-control-hover` provide solid
primary-action treatments with readable text. Existing `--bc-brand`,
`--bc-brand-fg` and `--bc-brand-hover` overrides still control those actions.
Saved branding keeps its exact chosen action/foreground pairs. Direct CSS themes
can override the derived roles too. The same `--bc-success-text`,
`--bc-warning-text`, `--bc-danger-text` and `--bc-info-text` roles support small
status text on either theme. The contract version remains 1: these are additions.

## 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.
