Pinecall

Theming

Theme presets, CSS variables, and full customization of the orb and transcript UI.

Five built-in presets#

PresetOrbRingsPanelsBest for
"dark"Pearl whiteWarm redDark purple glassDark-themed sites (default)
"midnight"Deep sapphireIce blueNavy glassCorporate / professional
"aurora"Emerald / tealGreenForest darkNature / wellness brands
"sunset"Warm coralGolden amberWarm darkHospitality / warm brands
"light"Clean whiteSoft blueWhite glassLight-themed sites
<VoiceWidget preset="midnight" agent="mara" />
<VoiceWidget preset="aurora" agent="mara" />
<VoiceWidget preset="sunset" agent="mara" />
<VoiceWidget preset="light" agent="mara" />
<VoiceWidget preset="dark" agent="mara" />     // default

Access preset values programmatically:

import { PRESETS } from "@pinecall/voice-widget";
console.log(PRESETS.midnight); // full theme object

Custom themes via the theme prop#

Pass overrides — they merge on top of the chosen preset:

<VoiceWidget
  agent="mara"
  preset="midnight"
  theme={{
    orbFrom: "200, 150, 255",
    orbMid: "140, 80, 220",
    orbTo: "80, 30, 160",
    colorAccent: "124, 58, 237",
    ringColor: "216, 65, 44",
    panelBg: "rgba(16, 14, 20, .92)",
    bubbleUserColor: "#e0d4f7",
  }}
/>

All theme variables#

FieldCSS variableTypeDefault (dark)Controls
orbFrom--vw-orb-fromRGB triplet255, 255, 255Idle orb gradient center
orbMid--vw-orb-midRGB triplet240, 238, 231Idle orb gradient midtone
orbTo--vw-orb-toRGB triplet184, 181, 168Idle orb gradient edge
colorConnecting--vw-color-connectingRGB triplet245, 158, 11Connecting state orb
colorActive--vw-color-activeRGB triplet76, 175, 80Connected / listening orb
colorUserSpeaking--vw-color-user-speakingRGB triplet52, 211, 153User speaking orb
colorSpeaking--vw-color-speakingRGB triplet248, 113, 113Agent speaking orb
colorThinking--vw-color-thinkingRGB triplet139, 92, 246Thinking / processing orb
colorWarning--vw-color-warningRGB triplet255, 160, 0Idle warning blink
colorAccent--vw-color-accentRGB triplet124, 58, 237User bubble accent
ringColor--vw-ring-colorRGB triplet216, 65, 44Idle ring glow
panelBg--vw-panel-bgCSS colorrgba(16,14,20,.92)Transcript panel bg
panelBorder--vw-panel-borderCSS colorrgba(255,255,255,.08)Transcript panel border
bubbleBotBg--vw-bubble-bot-bgCSS colorrgba(18,16,22,.9)Bot bubble background
bubbleBotColor--vw-bubble-bot-colorCSS color#e8e4f0Bot bubble text
bubbleUserColor--vw-bubble-user-colorCSS color#e0d4f7User bubble text
labelBg--vw-label-bgCSS color#181818Label tooltip background
labelColor--vw-label-colorCSS color#fffLabel tooltip text

RGB triplet vs CSS color. Variables that need alpha variants are stored as "R, G, B" strings (the widget uses rgba(var(--vw-color-x), 0.3) etc.). Plain CSS color values are used for backgrounds and text where alpha is baked into the value.

CSS-only override (no JS)#

Skip the theme prop entirely — override the CSS variables directly:

.vw-wrap {
  --vw-orb-from: 200, 150, 255;
  --vw-ring-color: 100, 80, 200;
  --vw-panel-bg: rgba(20, 10, 40, .95);
}

This is handy when you want the theme to follow a parent context (e.g. dark/light mode toggle in your app's own CSS).

Orb visual states#

The orb gets a different look per phase:

StateVisualCSS classWhen
IdlePearl gradient, breathing rings(default)Not connected
ConnectingAmber pulse.connectingEstablishing WebRTC
ActiveSoft green glow.activeConnected, listening
User speakingEmerald glow.user-speakingUser is talking
Agent speakingRose pulse.speakingBot TTS playing
ThinkingViolet pulse.thinkingWaiting for LLM response
Idle warningOrange blink.idle-warningUser silent — call will timeout soon

The idle warning state is driven by the server's session.idle_warning event and clears when the user speaks or the call ends.

Building on top of presets#

Start from a preset and modify selectively:

import { PRESETS } from "@pinecall/voice-widget";
import type { VoiceWidgetTheme } from "@pinecall/voice-widget";

const brandTheme: Partial<VoiceWidgetTheme> = {
  ...PRESETS.midnight,
  colorAccent: "255, 87, 34",      // brand orange
  ringColor: "255, 87, 34",
  bubbleUserColor: "#ffccbc",
};

<VoiceWidget agent="mara" preset="midnight" theme={brandTheme} />;

What's next#