Theming

Tokens, light and dark, launcher placement.

The one-line version

Point the accent at your brand colour. Everything else follows.

globals.css
:root {
  --cairn-accent: #f75c03;
  --cairn-accent-rgb: 247 92 3;   /* same colour, space-separated, for alpha */
}

Every token

PropTypeDefaultDescription
--cairn-accentcolor#4f46e5Ring, progress, primary button.
--cairn-accent-rgbr g b79 70 229Same colour for alpha compositing.
--cairn-accent-contrastcolor#ffffffText on the accent.
--cairn-surfacecolor#ffffffCard background.
--cairn-surface-bordercolorCard and arrow border.
--cairn-textcolorTitle text.
--cairn-text-mutedcolorBody and secondary text.
--cairn-scrimcolorThe dimmed backdrop.
--cairn-railcolorUnfilled progress segments.
--cairn-radiuslength14pxCard corner radius.
--cairn-shadowshadowCard elevation.
--cairn-fontfontinheritInherits your app's typeface by default.
--cairn-durationtime200msMotion duration.
--cairn-easeeasingMotion curve.
--cairn-znumber2147483000Overlay stacking order.
--cairn-launcher-insetlength24pxDistance from the viewport edge.

Light and dark

Both are defined out of the box. prefers-color-scheme is the default signal, and data-cairn-theme lets your own toggle win in both directions.

<html data-cairn-theme="dark">   <!-- force dark -->
<html data-cairn-theme="light">  <!-- force light -->
<html>                           <!-- follow the OS -->

Launcher placement

The bottom-right corner is contested — support chat widgets live there. Seven placements, plus a custom icon.

<TourLauncher flowId="upgrade" position="bottom-left" />
<TourLauncher flowId="upgrade" position="inline" icon={<MyIcon />} />

bottom-right (default), bottom-left, bottom-center, top-right, top-left, top-center, inline. Raise --cairn-launcher-inset to clear a chat bubble.

Button labels

<CairnOverlay
  labels={{
    next: "Continue",
    back: "Back",
    skip: "Not now",
    done: "Finish",
    counter: (current, total) => `${current} / ${total}`,
  }}
/>