# Theming

Three layers of visual customization, from "tweak the colors" to "build your own UI from scratch":

1. **`branding`** — quick palette + logo override
2. **Chrome props** — `chromeless`, `compactControls`, `showMinimize`, `showClose`
3. **Hooks** — opt out of `<AvatarWidget>` entirely and build your own (covered in [Hooks](/docs/develop/npm/react/hooks))

## `branding` — colors and logo

```tsx
<!-- omitted: AvatarWidget -->
```

<!-- omitted: ParamsTable -->

The dashboard also accepts brand colors per-agent. The `branding` prop overrides those; useful for white-label scenarios where one agent serves multiple resellers.

## Chrome controls — what to show, hide, or compact

**Default chrome:**

```tsx
<!-- omitted: AvatarWidget -->
```

Renders the full UI: header (logo + name + minimize/close), avatar, transcript, mic toolbar, text input.

**Hide minimize / close:**

```tsx
<!-- omitted: AvatarWidget -->
```

Use when the widget is the entire surface (e.g., a dedicated `/talk-to-our-agent` page). The visitor can't dismiss it — they're meant to be there.

**Compact controls:**

```tsx
<!-- omitted: AvatarWidget -->
```

Hides the top header and tucks secondary controls (camera, screen share, settings) behind an overflow `•••` menu. Best for dense pages where vertical real estate matters. Mic and text input remain always-visible.

**Chromeless:**

```tsx
<!-- omitted: AvatarWidget -->
```

Hides header AND toolbar entirely. Just the avatar + transcript. The close button stays so the visitor can dismiss. Pair with `controlledSession` if you want to drive everything (mic toggle, mute, etc.) from your own UI.

## Floating chrome anchoring — `floatingChromeContainer`

In widget mode, some UI elements (the side-tab, the bottom action bar) are portaled to `document.body` so they can escape any `overflow: hidden` ancestor. If you want them anchored to a specific container instead (so they move with that container, not the viewport), pass it explicitly:

```tsx title="card-anchored.tsx"
import { useRef } from "react";

function ProductCard() {
  const cardRef = useRef<HTMLDivElement>(null);

  return (
    <div ref={cardRef} className="relative rounded-2xl overflow-hidden">
      {/* Your card content */}
      <!-- omitted: AvatarWidget -->
    </div>
  );
}
```

This is how the live-layer landing page keeps the demo widget's chrome inside the demo card.

## Custom positioning

For full position control, use `position="custom"` and apply your own styles:

```tsx
<!-- omitted: AvatarWidget -->
```

## Z-index defaults

The widget defaults to `z-index: 2147483647` (max safe int) so it stacks above modals, toasts, and tooltips. Override with the `zIndex` prop:

```tsx
<!-- omitted: AvatarWidget -->
```

## Limits of `branding`

Three things are NOT brandable via the prop:

1. **The agent's avatar/idle loop** — set those at the dashboard or override per-instance with `avatarImageUrl` and `idleLoopUrl`.
2. **The transcript bubble shapes** — fixed by the design system.
3. **The mic-active animation** — uses `accentColor` but the shape is fixed.

For full visual control, build your own UI on top of [hooks](/docs/develop/npm/react/hooks). It's more work, but the upper bound is unlimited.

## Read next

- [Hooks](/docs/develop/npm/react/hooks) — bypass `<AvatarWidget>` and compose your own UI
- [`AvatarWidget` props](/docs/develop/npm/react/avatar-widget) — full reference
