Skip to content

Theming

import { Aside } from ‘@astrojs/starlight/components’;

Built-in slot components (banner, modal, toast, etc.) use a theme system for colors, typography, shapes, and shadows. You can use the default theme, apply a built-in variant, or define your own.

TypeScript
interface RevTurbineTheme {
colors: RevTurbineThemeColors;
typography: RevTurbineThemeTypography;
shape: RevTurbineThemeShape;
shadows: RevTurbineThemeShadows;
}
TokenDefaultPurpose
primary#1e40afPrimary CTA buttons, links
primaryText#ffffffText on primary background
secondary#f3f4f6Secondary buttons, backgrounds
secondaryText#1f2937Text on secondary background
accent#7c3aedHighlight elements
accentText#ffffffText on accent background
background#ffffffPage background
surface#f8fafcCard/surface background
surfaceBorder#e2e8f0Card borders
text#111827Primary text
textSecondary#4b5563Secondary/description text
textMuted#6b7280Muted/hint text
overlayrgba(0,0,0,0.5)Modal backdrop
success#16a34aSuccess states
warning#f59e0bWarning states (quota 70–90%)
danger#dc2626Danger states (quota > 90%)
info#60a5faInformational states
track#e5e7ebMeter/progress track background
toastBackground#1f2937Toast notification background
toastText#ffffffToast notification text
TokenDefaultPurpose
fontFamilysystem-ui, -apple-system, sans-serifBody text
fontFamilyMonoui-monospace, SFMono-Regular, ...Code/CLI text
fontSize14pxBase font size
fontSizeSmall13pxSmall text
fontSizeHeader20pxSection headers
fontSizeLargeHeader28pxPage/modal titles
TokenDefaultPurpose
borderRadiusSmall6pxButtons, inputs
borderRadius8pxCards, panels
borderRadiusLarge12pxModals, large surfaces
TokenDefaultPurpose
medium0 10px 40px rgba(0,0,0,0.25)Toast, dropdown
large0 20px 60px rgba(0,0,0,0.3)Modal

Pass an optional branding value in your SDK options. This local React example changes a few tokens and lets the rest use defaults:

React
import { RevTurbineProvider } from '@revturbine/sdk';
import { useMemo, type ReactNode } from 'react';
import playbook from './revturbine.playbook.json';
const customTheme = {
colors: {
primary: '#6366f1', // Indigo
primaryText: '#ffffff',
accent: '#ec4899', // Pink
accentText: '#ffffff',
surface: '#fafafa',
surfaceBorder: '#e5e5e5',
text: '#171717',
textSecondary: '#525252',
// ... other tokens use defaults
},
typography: {
fontFamily: '"Inter", system-ui, sans-serif',
fontSizeHeader: '18px',
},
shape: {
borderRadius: '12px',
borderRadiusSmall: '8px',
},
shadows: {
large: '0 25px 50px rgba(0,0,0,0.15)',
},
};
export function App({ children }: { children: ReactNode }) {
const options = useMemo(() => ({
localRuntime: { playbook },
branding: { theme: customTheme },
}), []);
return (
<RevTurbineProvider options={options} colorScheme="system">
{children}
</RevTurbineProvider>
);
}

Partial themes are merged with defaults — you only need to specify the tokens you want to change.

Set the provider’s colorScheme prop to 'light', 'dark' or 'system' (the default). System follows the device’s preference. Pass your app’s current preference to that prop when the user changes it; placements repaint without reinitializing the SDK. Keep it outside options.

useRevTurbine().colorScheme reports the resolved 'light' or 'dark' value. The selected palette supplies the defaults; explicit branding tokens still override those defaults.

React
import { useRevTurbineTheme } from '@revturbine/sdk';
function ThemedBadge({ label }) {
const theme = useRevTurbineTheme();
return (
<span style={{
background: theme.colors.accent,
color: theme.colors.accentText,
borderRadius: theme.shape.borderRadiusSmall,
fontFamily: theme.typography.fontFamily,
fontSize: theme.typography.fontSizeSmall,
padding: '2px 8px',
}}>
{label}
</span>
);
}

Custom slot components receive the theme as a prop:

React
function MySlot({ content, theme }: PlacementSlotProps) {
return (
<div style={{
background: theme.colors.surface,
color: theme.colors.text,
borderRadius: theme.shape.borderRadius,
}}>
{content?.body}
</div>
);
}

The theme is resolved from multiple sources, in priority order:

  1. Explicit branding option — supplied by your app at initialization
  2. Branding API — supplied or fetched workspace branding
  3. Legacy config theme — accepted for older artifacts, deprecated for new integrations
  4. Defaults — the selected light or dark palette

The selected source’s partial theme merges over defaults. For local mode, pass branding explicitly or use defaults. A legacy config theme still resolves for older artifacts; new Playbooks do not need one.

An app-mounted RevTurbineThemeProvider above RevTurbineProvider owns the rendered theme and takes precedence over this automatic resolution. Development builds warn about that override. Use this wrapper when your app deliberately manages the rendered theme; otherwise let RevTurbineProvider resolve it.