All docs
3 min read

Themes

Every hosted form ships with a small theme — a JSON blob of design tokens that we render as CSS variables on the public page. You don't write CSS to make a form look on-brand. You set tokens.

If you do want to write CSS, there's an escape hatch at the bottom.

Tokens

Open the Theme tab in the builder inspector (or click the canvas background). The tokens that matter:

Token What it controls
brand_color Primary color — buttons, focus rings, accents.
text_color Body text on the form.
background_color Page background behind the form card.
card_color The form card itself.
radius Border radius applied to inputs, buttons, the card. 0, 4, 8, 12, 16 (px).
font Font family. We bundle Inter, JetBrains Mono, and a system stack.
font_size Base font size — small (14), normal (16), large (18).
spacing Field spacing — compact, normal, roomy.

Tokens are stored as plain JSON on the form:

{
  "brand_color": "#0EA5E9",
  "text_color": "#0F172A",
  "background_color": "#F8FAFC",
  "card_color": "#FFFFFF",
  "radius": 12,
  "font": "inter",
  "font_size": "normal",
  "spacing": "normal"
}

Light and dark mode

Each token has a light and a dark value. The public page picks based on the visitor's system preference. To preview, click the sun/moon toggle in the canvas header.

If you only want one mode (e.g. always-light branded forms), set both light and dark to the same value — the auto-switching just becomes a no-op.

Brand color

Pick one. The brand color flows through to:

  • Submit button background.
  • Focus rings on inputs.
  • Step indicator dots in multi-step forms.
  • The default from-color of any badges or accents.

We auto-pick a contrasting text color (black or white) so a dark brand color still gets a readable button.

Templates

Built-in templates (Contact, Newsletter, etc.) ship with their own theme. Picking one hydrates both fields and tokens. You can edit either independently afterwards. See Templates →.

Custom CSS escape hatch

For Pro+ plans there's a Custom CSS field under Theme → Advanced. Whatever you put there is appended to the public page's stylesheet, scoped to the form root.

.fs-form {
  font-feature-settings: "ss01", "cv11";
}

.fs-form button[type="submit"] {
  background: linear-gradient(135deg, #6366f1, #ec4899);
}

A few rules:

  • Keep selectors scoped to .fs-form (we do prefix them, but writing them already-scoped is clearer).
  • No @import — bundle your fonts via font-family or use the font token.
  • We sanitize aggressively. behavior:, expression(), javascript: are stripped. If something doesn't render, check the page source.

What this isn't

  • Not a full theme editor — there's no per-field styling.
  • Not a CSS-in-JS layer — tokens are just CSS variables.
  • Not a CDN-hosted asset — every page renders your tokens inline, no separate fetch.

If you need pixel-level control, use legacy mode — write your own HTML, point its action at the endpoint URL, and style it however you want.

What's next