Skip to main content
The widget renders as a glassmorphic bar with built-in light and dark themes. Customization is available at three levels: props for common options, CSS custom properties for theming, and CSS class overrides for full control.
These styling options apply to the pre-built widget rendered by the ThunderPhoneWidget React component and the ThunderPhone.mount() CDN method. If you need a completely custom UI, use the headless hook instead.

Themes

The theme prop controls the widget’s color scheme. It applies a tp--light or tp--dark class to the widget root:
Both themes use the glassmorphic bar design with backdrop blur and subtle transparency.

CSS Custom Properties

The widget exposes CSS custom properties (variables) that you can override to change colors without touching individual classes. They are defined by the theme class (.tp--light or .tp--dark) applied to the .tp-widget root:

Overriding Custom Properties

Set the accent color via the primaryColor prop:
--tp-accent is set as an inline style from the primaryColor prop, so stylesheet overrides of --tp-accent have no effect. Change the accent with the prop. Every other custom property can be overridden in CSS.
Override the other custom properties with CSS. Use a two-class selector (.tp-widget.tp--light / .tp-widget.tp--dark) so your rule outweighs the theme class that defines the defaults, regardless of stylesheet order:

CSS Classes

All widget classes are prefixed with tp- to avoid conflicts with your existing styles.

Examples

Custom Accent via Props

The simplest way to brand the widget:

Custom Colors via CSS

Override the custom properties for full color control. Remember that the accent comes from the primaryColor prop, not CSS:

Custom Size

Make the widget larger or smaller by adjusting the bar, button, and text dimensions:

Hide the Text Labels

All of the widget’s text lives in .tp-meta. Hide it entirely to keep just the waveform and buttons:
Or hide individual pieces:
The idle label lives in .tp-name/.tp-sub, not .tp-status — hiding .tp-status alone still shows the title when the widget is idle.

Theme-Specific Overrides

Target a specific theme with the theme class:

Scoping with className

When using the React component, pass a className prop to scope your overrides to a specific widget instance:
Then target that class in your CSS:
This lets you have multiple widget instances on the same page with different styles. Give each instance its own accent through its primaryColor prop (CSS cannot override --tp-accent — it is set inline).

Fully Custom UI

If CSS overrides are not enough, the headless hook gives you full control. You provide all the HTML and styling while useThunderPhone handles the voice session. The hook also provides audioLevelRef for building audio-reactive visualizations like waveforms.
The headless hook is the right choice when you need audio-reactive animations, custom layouts, or integration into an existing component library. CSS overrides and custom properties are better for quick theming adjustments.