One ChatWidget part (src/components/ChatWidget.astro), in five spots picked to suit what else is on the page. Each frame draws the real part in preview mode — not a
mockup — so this page can't drift from what ships.
The real component, in preview mode. Every frame renders the actual ChatWidget with preview set. No shared id, no live hooks, no screen-reader roles. So five of them can sit on one page without clashing.
Where it ships live.Bubble is the only variant currently wired into BaseLayout and is what folks see today. The other four are written up and ready to switch on.
One token layer, five layouts. Variants re-declare a handful of --lc-* settings rather than copied rules. See the table under each frame.
The default, and the only one wired into the site right now. A small button pinned bottom right with its label showing. It opens a panel above itself. This is the baseline every other variant overrides.
— baseline —
variant="bubble"
Lead Caravan
We typically reply in a few minutes.
👋 Hi there! Ask us anything about Lead Caravan and we'll get right back to you.
How fast can you get us booked leads?
Most campaigns are live within 48 hours.
variant="compact"
Compact
Pages with a competing primary CTA
Drops the "Chat with us" label so the launcher reduces to a circular icon. Use where a sticky buy/book button already owns the bottom-right corner and the pill would read as a second primary action.
--lc-pad-launcher
--lc-panel-w
--lc-panel-h
variant="compact"
Lead Caravan
We typically reply in a few minutes.
👋 Hi there! Ask us anything about Lead Caravan and we'll get right back to you.
How fast can you get us booked leads?
Most campaigns are live within 48 hours.
variant="bar"
Bar
Mobile-first and long-form pages
A full-width strip along the bottom edge, with square corners so it reads as part of the page rather than a floating box. The panel rises flush from the bar.
--lc-radius-launcher
--lc-panel-w
right/bottom/left
variant="bar"
Lead Caravan
We typically reply in a few minutes.
👋 Hi there! Ask us anything about Lead Caravan and we'll get right back to you.
How fast can you get us booked leads?
Most campaigns are live within 48 hours.
variant="inline"
Inline
Contact and help pages
Not pinned at all. It sits in the page like any other block — no floating position, no shadow, no rise-in animation on the panel. The launcher still opens and closes it; nothing here forces it open. For a page where chat is a section, not an interruption layered over it.
--lc-panel-w
--lc-panel-h
position: static
variant="inline"
Lead Caravan
We typically reply in a few minutes.
👋 Hi there! Ask us anything about Lead Caravan and we'll get right back to you.
How fast can you get us booked leads?
Most campaigns are live within 48 hours.
variant="sidebar"
Sidebar
Documentation and dashboards
A tall bar stuck to the right edge with square outer corners, so it reads as a second column that stays put. For long reading surfaces where chat should stay open alongside the content.
--lc-radius
--lc-panel-w
--lc-panel-h
top/right/bottom
variant="sidebar"
Lead Caravan
We typically reply in a few minutes.
👋 Hi there! Ask us anything about Lead Caravan and we'll get right back to you.
How fast can you get us booked leads?
Most campaigns are live within 48 hours.
The token layer
Every value the widget paints flows through an --lc-* custom property
declared on .lc-chat. Each shape changes only a few of these instead of copying whole rules. That is why five shapes cost so little.
Colour
Mapped onto the site's auth palette — already fully tokenized. Every colour value resolves through a --lead-auth-* or --lead-brand-* token; the hex/rgba values alongside them in the component are fallbacks for that token, not overrides.
Token
Resolves to
--lc-primary
var(--lead-auth-primary)
--lc-primary-fg
var(--lead-auth-primary-foreground)
--lc-surface
var(--lead-auth-surface)
--lc-surface-soft
var(--lead-auth-field-surface)
--lc-fg
var(--lead-auth-foreground)
--lc-muted
var(--lead-auth-muted)
--lc-border
var(--lead-auth-border)
--lc-shadow
0 18px 50px -12px var(--lead-auth-shadow)
--lc-accent
var(--lead-brand-primary)
Spacing — exact scale matches
These four land exactly on the vendored --space-* scale, so they reference it.
Token
Resolves to
--lc-gap
var(--space-2) · 8px
--lc-gap-lg
var(--space-3) · 12px
--lc-pad-panel
var(--space-4) · 16px
--lc-pad-inline
var(--space-3) · 12px
Type — exact scale match
The one type size that lands on the vendored scale; every other font size in the widget is off-scale, kept literal the same way the radii are below.
Token
Resolves to
--lc-font-title
var(--typography-font-size-base) · 1rem
Off-scale — kept literal on purpose
The site ships only --corner-radius-md 6px / -lg 8px / -pill. This widget's bubbles are 14px and its controls 12px, with no scale step in between. Snapping them to the nearest token would visibly change a widget that is live in production, so the token carries the literal instead. Named, overridable, and honest about the gap.