Consenti

Custom Themes & Dark Mode

Consenti's entire visual layer is built on CSS custom properties. You can match it to your brand by overriding a handful of variables in your stylesheet — no build step, no Shadow DOM to pierce, no specificity battles.

How theming works

The widget reads CSS custom properties from the :root scope at render time. Override any --consenti-* token in your own stylesheet and the widget picks it up automatically. You can also pass a core.theme object to ConsentiSetup to set tokens via JavaScript — useful when your brand colours come from an API or theme context.

Option A — CSS custom property override

This is the recommended approach for static brand customisation. No CSS import is required —ConsentiSetup injects its own default <style> tag at runtime. Add your overrides in your own stylesheet, loaded normally in your page.

styles/consent-theme.css
css
:root {
  /* Primary button and active states */
  --consenti-btn-primary-bg: #7c3aed;
  --consenti-btn-primary-text: #ffffff;

  /* Secondary button */
  --consenti-btn-secondary-bg: #f5f0ff;
  --consenti-btn-secondary-text: #7c3aed;

  /* Banner background */
  --consenti-primary-bg: #ffffff;
  --consenti-primary-text: #1a1a2e;

  /* Border radius — pill buttons */
  --consenti-btn-radius: 999px;
  --consenti-banner-radius: 12px;
  --consenti-modal-radius: 16px;

  /* Typography */
  --consenti-font-family: 'Inter', system-ui, sans-serif;
  --consenti-font-size-base: 14px;

  /* Toggle colours */
  --consenti-toggle-on: #7c3aed;
  --consenti-toggle-off: #d1d5db;
}

Option B — JS theme config

Pass a core.theme object to ConsentiSetup. The widget translates each field into the corresponding CSS custom property at initialisation.

typescript
new ConsentiSetup({
  compliance: { type: 'opt-in' },
  core: {
    theme: {
      primaryColor: '#7c3aed',       // maps to --consenti-btn-primary-bg
      primaryTextColor: '#ffffff',
      secondaryColor: '#f5f0ff',
      secondaryTextColor: '#7c3aed',
      borderRadius: '12px',
      buttonBorderRadius: '999px',   // pill buttons
      fontFamily: 'Inter, system-ui, sans-serif',
      fontSizeBase: '14px',
      bgColor: '#ffffff',
      textColor: '#1a1a2e',
    },
  },
})

Runtime theme swapping

Use widget.setTheme()to hot-swap tokens after the widget is initialised. This merges the new values into the current theme — you don't need to pass the full theme object.

typescript
const widget = new ConsentiSetup({ /* ... */ })

// Later — e.g. when a theme switcher is toggled
widget.setTheme({ primaryColor: '#e11d48' }) // swap accent colour only

Dark mode

Set darkMode: true in config, or let the widget follow the system preference:

typescript
// Follow system preference
new ConsentiSetup({
  compliance: { type: 'opt-in' },
  darkMode: window.matchMedia('(prefers-color-scheme: dark)').matches,
})

// Or toggle at runtime
widget.setDarkMode()        // toggle
widget.setDarkMode(true)    // force dark
widget.setDarkMode(false)   // force light
💡To keep dark mode in sync with a theme switcher in your own UI, listen to the toggle event and call widget.setDarkMode(isDark) whenever your theme changes.

Full CSS token reference

TokenDefaultWhat it controls
--consenti-primary-bg#ffffffBanner & modal background
--consenti-primary-text#1a1a1aMain text colour
--consenti-secondary-bg#f5f5f5Secondary surfaces
--consenti-secondary-text#555555Secondary text
--consenti-btn-primary-bg#1565c0Primary button background
--consenti-btn-primary-text#ffffffPrimary button text
--consenti-btn-secondary-bg#f5f5f5Secondary button background
--consenti-btn-secondary-text#1a3460Secondary button text
--consenti-btn-radius6pxButton border radius
--consenti-btn-padding0.5rem 1.25remButton padding
--consenti-banner-padding1.5remBanner inner padding
--consenti-banner-radius0Banner border radius
--consenti-banner-shadow0 -4px 24px rgba(0,0,0,.12)Banner box shadow
--consenti-modal-width560pxModal max width
--consenti-modal-radius12pxModal border radius
--consenti-modal-shadow0 8px 32px rgba(0,0,0,.24)Modal box shadow
--consenti-toggle-on#1565c0Toggle on-state colour
--consenti-toggle-off#cccToggle off-state colour
--consenti-font-familysystem-ui, sans-serifWidget font family
--consenti-font-size-base14pxBase font size

Frequently asked questions