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
| Prop | Type | Default | Description |
|---|---|---|---|
--cairn-accent | color | #4f46e5 | Ring, progress, primary button. |
--cairn-accent-rgb | r g b | 79 70 229 | Same colour for alpha compositing. |
--cairn-accent-contrast | color | #ffffff | Text on the accent. |
--cairn-surface | color | #ffffff | Card background. |
--cairn-surface-border | color | — | Card and arrow border. |
--cairn-text | color | — | Title text. |
--cairn-text-muted | color | — | Body and secondary text. |
--cairn-scrim | color | — | The dimmed backdrop. |
--cairn-rail | color | — | Unfilled progress segments. |
--cairn-radius | length | 14px | Card corner radius. |
--cairn-shadow | shadow | — | Card elevation. |
--cairn-font | font | inherit | Inherits your app's typeface by default. |
--cairn-duration | time | 200ms | Motion duration. |
--cairn-ease | easing | — | Motion curve. |
--cairn-z | number | 2147483000 | Overlay stacking order. |
--cairn-launcher-inset | length | 24px | Distance 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}`,
}}
/>