Style the widget's chrome
read as.mdThe 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 names
Section titled “Class names”| 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. |
Custom properties
Section titled “Custom properties”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.radius — none 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. |
Example
Section titled “Example”/* 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;}Two rules
Section titled “Two rules”- 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.
- 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’sguuey-widget--openmodifier above is. Style the names above; the rest is ours to move.