Theming
Import the default theme once:
import "@permito/react/styles.css";CSS variables
Section titled “CSS variables”The variables are defined with zero specificity on :root and inherited, so you can override them on :root, on any wrapper, or on .pmt-root:
:root { --pmt-accent: #0f766e; --pmt-accent-fg: #ffffff; --pmt-radius: 4px; --pmt-font: "Inter", system-ui, sans-serif;}| Variable | Purpose |
|---|---|
--pmt-bg, --pmt-fg, --pmt-muted |
Background, text, secondary text |
--pmt-accent, --pmt-accent-fg |
Buttons and switches |
--pmt-border, --pmt-surface |
Borders and nested surfaces |
--pmt-focus |
Focus ring |
--pmt-radius, --pmt-shadow, --pmt-font, --pmt-z, --pmt-max-width |
Shape, depth, typography, stacking, width |
Light and dark
Section titled “Light and dark”Dark mode follows prefers-color-scheme. To force a theme, either set data-pmt-theme="dark" (or "light") on <html> or any ancestor, or pass it to the provider:
<PermitoProvider config={config} theme={isDark ? "dark" : "light"}>Portals and scoped styles
Section titled “Portals and scoped styles”Banner, preference center and the preferences button render into document.body by default, so layouts with transform, filter or contain cannot clip them. Styles scoped to a wrapper (for example .tenant-a { --pmt-accent: … }) therefore do not reach them. Either:
- put the variables on
:rootor<html>, or - pass an element inside your wrapper as
portalContaineron the provider, or - render in place with
portal={false}on the component.
Keep “Accept all” and “Reject all” visually equal when you restyle them. Both use the class pmt-btn--choice.
Fully custom
Section titled “Fully custom”Every component accepts className and unstyled. For a completely own UI, use the hooks (useConsent) and render your own markup.