Skip to content
Public beta preview — you're seeing the sneak peek

Style the widget's chrome

read as .md

The embed script renders three things into your page: the launcher bubble (or the ask bar, with layout: "bar"), the panel that holds the conversation, and the cold-open shell that shows while the conversation loads. Because they are your page’s DOM, your stylesheet reaches them — and the names below are a promise: they are pinned by a test, so a release cannot rename them under you.

The conversation itself renders inside a frame. Its look comes from the app’s chat theme, not from CSS on your page.

Class What it is
guuey-widget The root. Modifier classes: guuey-widget--open (panel open), guuey-widget--left (position: "left"), guuey-widget--bar (layout: "bar"), guuey-widget--expanded (the page asked for the full-height overlay), guuey-widget--hidden (guuey("hide")), guuey-widget--glass (the app’s chat theme states shape.glass — the panel and bar are translucent over your page, blurred behind).
guuey-widget-launcher The bubble. guuey-widget-launcher-label is the pill’s text (shape: "pill").
guuey-widget-panel The panel above the bubble or bar. guuey-widget-frame is the frame inside it.
guuey-widget-bar The ask bar (layout: "bar"): guuey-widget-bar-input and guuey-widget-bar-send.
guuey-widget-shell The cold-open shell shown over the panel until the conversation is ready.
guuey-widget-scrim The fullscreen frosted layer under the expanded panels (only under guuey-widget--expanded, desktop widths): the page shows through the gap between the two panels blurred and tinted, never crisp. It takes no click — Escape or a click on the gap dismisses the takeover.

The loader never writes colours inline. It sets these custom properties on the root and the injected stylesheet reads them — so a rule of yours wins. The two glass properties come from the resolved theme, so they are set from the first paint: frosted (0.82 / 14px) unless the app’s chat theme states its own shape.glass; a theme that states { "opacity": 1 } switches glass off — the guuey-widget--glass modifier comes off, both properties are cleared, and the panel paints opaque. The root also carries an inline color-scheme equal to the effective mode — it keeps the frame’s transparency honest across light and dark, and it is part of the paint, not the contract.

Property Paints
--guuey-widget-canvas The panel, shell and bar fill — the app theme’s canvas for the effective mode.
--guuey-widget-ink Text on that fill (the shell’s, the bar’s).
--guuey-widget-accent The launcher bubble’s fill — the color init option.
--guuey-widget-accent-ink The launcher icon and the pill label — the iconColor init option.
--guuey-widget-glass Under guuey-widget--glass: the panel’s and bar’s fill alpha, a number 0–1 (the theme’s shape.glass.opacity; 1 is opaque).
--guuey-widget-blur Under guuey-widget--glass: the backdrop blur behind the panel and bar, a length (the theme’s shape.glass.blur; 14px when unset).
--guuey-widget-shadow The panel’s and bar’s box-shadow — one value composed from the theme’s shape.shadow (colour at its intensity); frosted glass with a soft shadow is the default.
--guuey-widget-scrim-tint The expanded scrim’s colour — the theme’s scrim.tone (#fff / #000) when stated, else your page’s own ground (read from body), else the panel canvas.
--guuey-widget-scrim-opacity The scrim’s alpha, a number 0–1 (the theme’s scrim.opacity; 0.45 when unset). Where backdrop-filter is unsupported the tint alone frosts, at twice this alpha.
--guuey-widget-scrim-blur The blur of the page behind the scrim, a length (the theme’s scrim.blur; 14px when unset).
--guuey-widget-radius-scale A bare multiplier on the panel’s own radii (16px; the ask-bar panel’s 24px; the phone sheet’s top corners) from the theme’s shape.radiusnone 0, soft 1, round 1.5 — or, for an app with no theme, your page’s own card radius. The bubble and the ask-bar pill keep their shapes.
--guuey-widget-font The family of the cold-open shell, the ask bar and the pill label — the theme’s typography.fontFamily, else your page’s body family, else system-ui, sans-serif.
--guuey-widget-motion-duration The open/close fade length of the panel, the cold-open shell and the backdrop — the theme’s motion.duration.base (a CSS time), else 180ms. The loader keeps the panel mounted for the same time on close, so a longer fade is never cut.
--guuey-widget-motion-easing The easing of those fades — the theme’s motion.easing.standard, else ease-out. Under prefers-reduced-motion: reduce there is no transition at all, whatever these say.
/* Square corners on the bar, your brand on the bubble, your own fill everywhere */
.guuey-widget {
--guuey-widget-canvas: #fffdf7;
--guuey-widget-ink: #1a1a1a;
}
.guuey-widget-launcher {
--guuey-widget-accent: #0b5cff;
--guuey-widget-accent-ink: #fff;
}
.guuey-widget-bar {
border-radius: 8px;
box-shadow: none;
border: 2px solid #1a1a1a;
}
.guuey-widget-panel {
border-radius: 8px;
}
  1. Your CSS lives on your page. The widget never accepts a stylesheet or a CSS string — that would be a door into an origin that is not yours. Restyle the contract classes from your own stylesheet.
  2. Everything else may change. Badges, the backdrop, the shell’s inner rows and the panel’s own open/show state classes (guuey-widget-panel--open, guuey-widget-panel--show) are not in the contract — the root’s guuey-widget--open modifier above is. Style the names above; the rest is ours to move.