Presets
Picklight (default), dark, or auto (follows the visitor’s prefers-color-scheme):
Theme tokens
Layer per-property overrides on top of a preset. The same keys work everywhere:CSS variables
The widget exposes a--ww-* namespace that pierces the Shadow DOM boundary, so the script embed can be themed from your page’s own CSS:
Assistant message bubble (opt-in)
Assistant replies render as plain text by default. Turn them into filled bubbles — styled byassistantBubbleColor / assistantBubbleTextColor, sharing the user bubble’s radius and padding — with assistantBubble:
Deep customization
Tokens cover colors, typography, and bubble shape. To restyle an element beyond what a token exposes, target it directly. React — passclassNames (available on ChatEmbed directly, or overrides.classNames on WaniwaniChat). Each string is merged onto that slot:
root, header, message, userBubble, assistantBubble, input.
Script embed — the widget renders in a Shadow DOM, so your page’s own selectors cannot reach inside. Inject a stylesheet with data-css and target the stable semantic classes:
.ww-message, .ww-message-user, .ww-message-assistant, .ww-bubble, .ww-header, .ww-input. These are guaranteed selectors — the internal ww:-prefixed utility classes are not.
What is not themeable
To set expectations for a full rebrand, these are intentionally fixed today:- Typographic scale beyond the base —
fontSize/lineHeightset the message base; per-heading sizes inside markdown and built-in label sizes/weights are not individually exposed. - Chrome corner radii —
messageBorderRadiusshapes message bubbles only; tool-call cards, the chain-of-thought accordion, menus, and welcome-screen buttons keep their fixed radii. - Floating launcher accent — the dock’s animated border-glow uses a fixed accent gradient.
- “Powered by” mark — the footer logo is not removable via theming.
ChatTheme and ChatClassNames.