Theming the widget

The widget renders inside a Shadow DOM and is neutral by default — restrained light neutrals, your page’s spacing rhythm, no imposed brand. You theme it with a small set of CSS custom properties prefixed --bw-*, set on the embed element. Custom properties inherit across the shadow boundary, so plain CSS on your page is the whole mechanism — no JavaScript theming API, no rebuild.

The contract

Every variable the widget reads, with its default:

[data-booking-widget] {
  /* surfaces */
  --bw-bg:       oklch(0.995 0.003 230);  /* widget background                  */
  --bw-surface:  oklch(0.99 0.003 230);   /* cards / inputs                     */
  --bw-soft:     oklch(0.97 0.004 230);   /* soft fills (info cards, rows)      */

  /* text */
  --bw-ink:      oklch(0.27 0.012 250);   /* primary text                       */
  --bw-muted:    oklch(0.53 0.012 250);   /* secondary text                     */
  --bw-line:     oklch(0.90 0.006 250);   /* borders / dividers                 */

  /* brand */
  --bw-brand:    var(--bw-ink);           /* CTA / accent — neutral until set   */
  --bw-brand-fg: oklch(0.99 0.005 250);   /* text on the brand color            */

  /* semantic (rarely overridden) */
  --bw-good:     oklch(0.51 0.12 150);    /* money-positive ("$0 fee", "paid")  */
  --bw-warn-bg:  oklch(0.96 0.035 75);
  --bw-warn-ink: oklch(0.47 0.10 60);
  --bw-danger:   oklch(0.55 0.18 27);

  /* shape & type */
  --bw-radius:   14px;
  --bw-font:     ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --bw-shadow:   0 1px 3px oklch(0.2 0.02 250 / 0.10);

  /* platform flourish — off by default */
  --bw-flash:    none;                    /* the platform's own theme sets this */

  /* color scheme */
  --bw-scheme:   light;                   /* light | dark | auto                */
}

Values are shown in oklch() but any CSS color works — hex, rgb(), whatever your design system already uses.

Match my brand — a worked example

Say your site is a deep harbor blue with Inter and squarer corners. One rule:

[data-booking-widget] {
  --bw-brand: #0b5c8a;       /* your accent — buttons, focus, selected states */
  --bw-brand-fg: #ffffff;    /* readable text on it                           */
  --bw-font: "Inter", system-ui, sans-serif;
  --bw-radius: 8px;
}

Setting --bw-brand is the single change that makes the widget feel native to your site; everything else has a sensible neutral default.

Dark host pages

Set --bw-scheme and the widget switches to its built-in dark palette:

[data-booking-widget] {
  --bw-scheme: dark;   /* or `auto` to follow the visitor's prefers-color-scheme */
}

The dark palette keeps the same neutral-guest posture (and the same AA contrast bars) as light. Any --bw-* value you set yourself still wins over the scheme’s defaults, so you can also hand-tune surfaces instead:

[data-booking-widget] {
  --bw-bg: #0f1722;          /* dark host page */
  --bw-surface: #16202e;
  --bw-soft: #1b2636;
  --bw-ink: #e8eef5;
  --bw-muted: #9fb0c2;
  --bw-line: #2a3646;
}

Rules the widget keeps for itself

  • Money green stays green. Positive financial state — the $0 booking fee line, “paid” badges — always renders in --bw-good, never your brand color, so the trust cues stay consistent for anglers across every charter site.
  • Warnings and errors keep their semantics. Override --bw-warn-* / --bw-danger only to adjust tone, not meaning.
  • The widget never imports fonts. --bw-font is a font-family stack; if you name a webfont, your page loads it (the widget inherits what’s there).
  • No layout variables. Width, spacing, and structure are fixed for reliability across hosts; the widget fills its container up to its max width.

Scoping

The selector is up to you — anything that matches the mount element works:

/* one widget */
#book-a-trip { --bw-brand: #0b5c8a; }

/* every widget on the site */
[data-booking-widget] { --bw-brand: #0b5c8a; }

Because custom properties inherit, you can also set them on body to theme all embeds at once — the widget’s internal styles are isolated by the shadow root, but the --bw-* variables pass through.