Design reference

The chat widget, in five layouts.

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.

  1. 01 Bubble
  2. 02 Compact
  3. 03 Bar
  4. 04 Inline
  5. 05 Sidebar
  6. 06 Token layer
variant="bubble"

Bubble live

Every marketing page

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.

TokenResolves to
--lc-primaryvar(--lead-auth-primary)
--lc-primary-fgvar(--lead-auth-primary-foreground)
--lc-surfacevar(--lead-auth-surface)
--lc-surface-softvar(--lead-auth-field-surface)
--lc-fgvar(--lead-auth-foreground)
--lc-mutedvar(--lead-auth-muted)
--lc-bordervar(--lead-auth-border)
--lc-shadow0 18px 50px -12px var(--lead-auth-shadow)
--lc-accentvar(--lead-brand-primary)

Spacing — exact scale matches

These four land exactly on the vendored --space-* scale, so they reference it.

TokenResolves to
--lc-gapvar(--space-2) · 8px
--lc-gap-lgvar(--space-3) · 12px
--lc-pad-panelvar(--space-4) · 16px
--lc-pad-inlinevar(--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.

TokenResolves to
--lc-font-titlevar(--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.

TokenResolves to
--lc-radius-bubble14px
--lc-radius-control12px
--lc-radius-tail4px
--lc-pad-msg9px 13px
--lc-font-msg0.9rem