Product

Form theming

Restyle any form with custom CSS, the behaviour stays locked, only the skin changes.

Every form runner ships with our default behaviour: keyboard-first navigation, panel transitions, the floating glass nav. All of it is themable without touching the mechanics. Your CSS is confined to the form before it runs, so another agency can make it fully theirs without any rule escaping onto the rest of the page.

The styling hooks

The runner root carries data-questionnaire, the floating Back/Continue bar carries data-nav-pill. Write against those directly, no prefix needed:

[data-questionnaire] {
  --brand: #ff5533;
  --bg: #0f0f10;
  --ink: rgba(255, 255, 255, 0.92);
}

[data-nav-pill] {
  background: transparent;
  backdrop-filter: none;
  box-shadow: none;
  padding: 0;
}

Generic selectors need no prefix either. Every rule you write is scoped to the form before it is injected, so button or input only ever matches inside the runner, never the surrounding page or the site you embed it in. Naming your slug, [data-questionnaire="brand-intake"], still works and changes nothing; it is simply never required.

The same boundary is why html and body do nothing here. Style [data-questionnaire] instead, it already covers the full screen. And because the confinement uses the CSS @scope rule, a browser too old to support it drops your custom CSS entirely rather than letting it land in the wrong place.

Design tokens

The fastest way to re-skin is overriding the CSS variables, everything hangs off them:

--brandAccent color: check mark, focus states, highlights
--bgPage background of the runner
--inkPrimary text color
--mutedSecondary text (subtitles, helper lines)
--faintTertiary text (hints, keycaps, placeholders)
--surface / --surface-2Cards and fields base colors
--line / --line-2Hairline borders
--fieldInput backgrounds
--r-lg / --r-md / --r-smCorner radii
--ease-out / --ease-backThe motion curves every transition uses

Going further

Colors set in the builder (accent, background) are applied as inline variables; your CSS wins when it's more specific. For deeper changes you can target the runner's elements, headings, option rows, the progress bar. Class names are stable within a release but treat them as semi-private. Example, a dark serif look:

[data-questionnaire="brand-intake"] {
  --bg: #101012;
  --ink: #f4f4f0;
  --field: rgba(255,255,255,0.07);
  --line-2: rgba(255,255,255,0.14);
  font-family: "Editorial New", Georgia, serif;
}
[data-questionnaire="brand-intake"] h1 {
  font-weight: 400;
  letter-spacing: -0.01em;
}

The navigation pill

The Back/Continue bar floats as a translucent glass pill. It is the one inner part with its own hook, because the classes around it carry a build hash and would break on the next release. data-nav-pill is stable, and the buttons inside come along as descendants:

[data-nav-pill] {
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: none;
  padding: 0;
}

[data-nav-pill] button {
  border-radius: 8px;
}

What you can't break

Behaviour is locked: keyboard shortcuts, validation, tracking and drop-off analytics keep working whatever the skin. Reach is locked too, nothing outside the form can be styled from here. If a form ever looks broken, delete the custom CSS block and it snaps back to the SystemOS default.