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

# Advanced Styling

> CSS variables, launcher tokens, and responsive behavior for the Bonsai Concierge

<Callout color="#0A5B3B" icon="info">
  **Where styling lives.** The Concierge renders in a closed shadow DOM, so your page's CSS cannot reach inside it and its styles cannot leak out. Everything is customized through CSS custom properties, set two ways:

  1. **From the Bonsai dashboard** (preferred) — your brand colors are fetched per-tenant at load time and applied automatically.
  2. **Inline on the element** — set any variable in the tag's `style` attribute to override it for that embed.

  Because the shadow root is closed, an inline `style` on the tag is the only way page-side CSS can reach the component. A stylesheet rule like `bonsai-chat-bubble { --bonsai-agent-brand: red }` will **not** take effect.
</Callout>

## Setting variables

```html theme={null}
<bonsai-chat-bubble
  api-key="API-KEY"
  label="Ask us anything"
  style="
    --bonsai-agent-brand: #122940;
    --bonsai-agent-bubble-bg: #fed31d;
    --bonsai-agent-bubble-fg: #122940;
    --bonsai-agent-bubble-radius: 8px;
    --bonsai-agent-bubble-padding: 13px 16px;
    --bonsai-agent-bubble-font-size: 14px;
  "
></bonsai-chat-bubble>
```

Inline values are re-applied after the dashboard response arrives, so anything you pin here survives a later dashboard change.

## Color reference

| Variable                  | Default               | Purpose                                                                                |
| ------------------------- | --------------------- | -------------------------------------------------------------------------------------- |
| `--bonsai-agent-brand`    | `#0a5b3b`             | Brand color. Drives the accent, launcher, and header unless those are set individually |
| `--bonsai-agent-brand-fg` | `#ffffff`             | Text and icons drawn on top of the brand color                                         |
| `--bonsai-agent-accent`   | brand                 | Accent for interactive details                                                         |
| `--bonsai-agent-bg`       | `#ffffff`             | Panel background                                                                       |
| `--bonsai-agent-canvas`   | `#fafafa`             | Conversation area background                                                           |
| `--bonsai-agent-fg`       | `#303030`             | Primary text                                                                           |
| `--bonsai-agent-muted`    | `#9ca3af`             | Secondary text                                                                         |
| `--bonsai-agent-border`   | `#e5e7eb`             | Borders and dividers                                                                   |
| `--bonsai-agent-surface`  | `#f5f5f5`             | Raised surfaces                                                                        |
| `--bonsai-agent-hover-bg` | `rgba(0, 0, 0, 0.04)` | Hover background                                                                       |

### Header

| Variable                         | Default                        | Purpose                 |
| -------------------------------- | ------------------------------ | ----------------------- |
| `--bonsai-agent-header-bg`       | brand                          | Header background       |
| `--bonsai-agent-header-fg`       | brand foreground               | Header text and icons   |
| `--bonsai-agent-header-hover-bg` | `rgba(255, 255, 255, 0.14)`    | Header control hover    |
| `--bonsai-agent-header-close-bg` | `#ffffff`                      | Close button background |
| `--bonsai-agent-header-close-fg` | brand                          | Close button glyph      |
| `--bonsai-agent-title-font`      | inherits `--bonsai-agent-font` | Header title typeface   |

### Conversation

| Variable                       | Default         | Purpose                    |
| ------------------------------ | --------------- | -------------------------- |
| `--bonsai-agent-welcome-bg`    | surface         | Opening message background |
| `--bonsai-agent-welcome-fg`    | foreground      | Opening message text       |
| `--bonsai-agent-card-bg`       | surface         | Product card background    |
| `--bonsai-agent-card-fg`       | foreground      | Product card text          |
| `--bonsai-agent-input-bg`      | `#f5f5f5`       | Composer background        |
| `--bonsai-agent-input-fg`      | foreground      | Composer text              |
| `--bonsai-agent-suggestion-fg` | foreground      | Suggested question text    |
| `--bonsai-agent-chip-bg`       | card background | Suggestion chip background |
| `--bonsai-agent-chip-fg`       | accent          | Suggestion chip text       |
| `--bonsai-agent-chip-border`   | accent          | Suggestion chip border     |

### Panel and shape

| Variable                             | Default                           | Purpose                            |
| ------------------------------------ | --------------------------------- | ---------------------------------- |
| `--bonsai-agent-panel-width`         | `400px`                           | Panel width on desktop             |
| `--bonsai-agent-radius`              | `12px`                            | Corner radius throughout the panel |
| `--bonsai-agent-font`                | system UI stack                   | Typeface throughout                |
| `--bonsai-agent-shadow`              | `0 6px 24px rgba(0, 0, 0, 0.18)`  | Default shadow                     |
| `--bonsai-agent-panel-shadow`        | `-8px 0 32px rgba(0, 0, 0, 0.16)` | Panel shadow on desktop            |
| `--bonsai-agent-mobile-panel-shadow` | `0 -8px 32px rgba(0, 0, 0, 0.18)` | Panel shadow on phones             |

## Launcher reference

The launcher has its own token set, so you can restyle the button without touching the panel.

| Variable                                 | Default                                             | Purpose                                                     |
| ---------------------------------------- | --------------------------------------------------- | ----------------------------------------------------------- |
| `--bonsai-agent-bubble-bg`               | brand                                               | Launcher background                                         |
| `--bonsai-agent-bubble-fg`               | brand foreground                                    | Launcher text and icon                                      |
| `--bonsai-agent-bubble-font-size`        | `15px`                                              | Label size                                                  |
| `--bonsai-agent-bubble-font-weight`      | `600`                                               | Label weight                                                |
| `--bonsai-agent-bubble-padding`          | `14px 22px` pill, `14px 12px` tab                   | Inner spacing                                               |
| `--bonsai-agent-bubble-radius`           | `999px` pill, `10px` on the outer corners for a tab | Corner radius                                               |
| `--bonsai-agent-bubble-gap`              | `8px`                                               | Space between icon and label                                |
| `--bonsai-agent-bubble-icon-size`        | `24px`                                              | Icon size                                                   |
| `--bonsai-agent-bubble-icon-color`       | `currentColor`                                      | Icon color                                                  |
| `--bonsai-agent-bubble-icon-radius`      | inherits the launcher radius                        | Icon corner radius                                          |
| `--bonsai-agent-bubble-min-height`       | `44px`                                              | Minimum touch target height                                 |
| `--bonsai-agent-bubble-min-width`        | `44px`                                              | Minimum touch target width                                  |
| `--bonsai-agent-bubble-icon-button-size` | `56px`                                              | Size of the square button in icon-only mode                 |
| `--bonsai-agent-bubble-border`           | `none`                                              | Launcher border                                             |
| `--bonsai-agent-bubble-shadow`           | inherits `--bonsai-agent-shadow`                    | Launcher shadow                                             |
| `--bonsai-agent-bubble-focus-offset`     | `3px`                                               | Focus ring offset                                           |
| `--bonsai-agent-bubble-opposite-margin`  | `8px`                                               | Clearance kept from the opposite viewport edge              |
| `--bonsai-agent-bubble-bottom`           | `20px`                                              | Distance from the bottom. Also settable via `bubble-bottom` |
| `--bonsai-agent-bubble-right`            | `20px` pill, `0` tab                                | Distance from the right. Also settable via `bubble-right`   |
| `--bonsai-agent-bubble-left`             | `20px` pill, `0` tab                                | Distance from the left. Also settable via `bubble-left`     |
| `--bonsai-agent-bubble-top`              | `50%`                                               | Vertical position of a tab. Also settable via `bubble-top`  |

<Callout color="#0A5B3B" icon="info">
  **Minimum sizes are accessibility floors, not suggestions.** `--bonsai-agent-bubble-min-height` and `--bonsai-agent-bubble-min-width` default to 44px because that is the smallest reliably tappable target. A design that specifies a shorter button will render at 44px unless you lower these explicitly — and lowering them makes the launcher harder to hit on a phone.
</Callout>

## Responsive behavior

The launcher adapts to the viewport at two breakpoints. Both apply automatically — there is nothing to enable.

| Viewport           | Launcher                                                                                                         |
| ------------------ | ---------------------------------------------------------------------------------------------------------------- |
| 380px and narrower | Label is hidden, the icon is shown, and the button squares up to `--bonsai-agent-bubble-icon-button-size` (56px) |
| 381px to 767px     | Unchanged                                                                                                        |
| 768px to 1024px    | Label grows to 16px and the minimum height to 48px                                                               |
| 1025px and wider   | Unchanged                                                                                                        |

380px is the threshold so that an iPhone SE (375px wide) collapses while an iPhone 12 through 16 (390px) keeps its text label.

### Your pinned values always win

A tier only changes a value you have **not** pinned. Because inline styles beat the component's own rules, any variable you set on the tag survives every breakpoint.

This works per variable, not per install. If you pin the font size but not the minimum height, your font size holds everywhere and your minimum height still grows on tablets:

```html theme={null}
<!-- Label stays 14px at every width; the button still grows to 48px on tablet -->
<bonsai-chat-bubble
  api-key="API-KEY"
  style="--bonsai-agent-bubble-font-size: 14px;"
></bonsai-chat-bubble>

<!-- Pin both to opt out of the tablet tier entirely -->
<bonsai-chat-bubble
  api-key="API-KEY"
  style="
    --bonsai-agent-bubble-font-size: 14px;
    --bonsai-agent-bubble-min-height: 44px;
  "
></bonsai-chat-bubble>
```

The collapse at 380px is not a variable override — it changes which elements are visible — so it applies whatever you have pinned.

### The icon shown when the label collapses

At 380px and narrower the launcher shows its icon in place of the label, **including when `launcher-content="text"`**. Which icon that is depends on what you configured:

1. `launcher-icon-url`, if set
2. Otherwise the built-in glyph named by `launcher-icon` — `mark` (the Bonsai mark, the default), `sparkles`, or `chat`

<Callout color="#0A5B3B" icon="circle-alert">
  **Set `launcher-icon-url` if you do not want the Bonsai mark on your storefront.** With no `launcher-icon-url` and no `launcher-icon`, a text-only launcher collapses to our mark on small phones. `header-icon-url` is a separate attribute for the panel header and is **not** reused here — set `launcher-icon-url` explicitly even if it points at the same file.

  ```html theme={null}
  <bonsai-chat-bubble
    api-key="API-KEY"
    label="Ask us anything"
    launcher-icon-url="https://cdn.example.com/brand-mark.svg"
    header-icon-url="https://cdn.example.com/brand-mark.svg"
  ></bonsai-chat-bubble>
  ```
</Callout>

If `launcher-icon-url` points at an image that fails to load, the component falls back to the built-in glyph rather than rendering an empty button.

## Dark mode

Set `theme="dark"` to use the dark palette. It adjusts the background, foreground, muted, border, surface, input, card, and hover variables; brand and launcher colors are unchanged, since those are yours.

```html theme={null}
<bonsai-chat-bubble api-key="API-KEY" theme="dark"></bonsai-chat-bubble>
```

Any value other than `dark` resolves to the light palette. The component does not follow the operating system setting on its own — to do that, set the attribute from your own theme switcher.
