View as markdown

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 propschromeless, compactControls, showMinimize, showClose
  3. Hooks — opt out of <AvatarWidget> entirely and build your own (covered in Hooks)
tsx
<AvatarWidget
  agentId="agt_abc123"
  branding={{
    logoUrl: "/your-logo.svg",
    productName: "Acme Assistant",
    primaryColor: "#0EA5E9",
    accentColor: "#06B6D4",
    backgroundColor: "#FFFFFF",
    textColor: "#0F172A",
  }}
/>
NameTypeDescription
logoUrlstringURL of your logo. Renders in the panel header alongside the agent name.
productNamestringBranded product name shown in the header. Default: agent name from dashboard.
primaryColorstringHex/rgb color used for primary CTAs and active states.
accentColorstringColor for highlights, active mic ring, transcript hover states.
backgroundColorstringPanel background. Defaults to white in light mode, near-black in dark mode.
textColorstringPrimary text color.

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

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
import { useRef } from "react";

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

  return (
    <div ref={cardRef} className="relative rounded-2xl overflow-hidden">
      {/* Your card content */}
      <AvatarWidget
        agentId="agt_abc123"
        floatingChromeContainer={cardRef.current}
      />
    </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
<AvatarWidget
  agentId="agt_abc123"
  position="custom"
  className="my-custom-widget-positioning"
  style={{
    position: "fixed",
    top: 80,
    right: 24,
    zIndex: 100,
  }}
/>

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
<AvatarWidget agentId="agt_abc123" zIndex={50} />

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. It's more work, but the upper bound is unlimited.