Amperlise LogoAmperlise
Available on Pro

Custom Themes

Restyle the public look of your feedback forms, assessments, and pages with plain CSS — your colors, your type, your motion, applied safely to exactly the content you choose.

Overview

A theme is a stylesheet that belongs to a workspace. Apply it to a feedback form, an assessment, or a page, and its public render takes on your styling — participants and visitors see your look instead of the default one.

Themes are created per workspace and applied per item: one theme can style any number of forms, assessments, and pages, and every item picks which theme (if any) it uses.

A Professional feature

Custom Themes are part of the Professional plan — listed as “Custom CSS themes” on the pricing page. Amperlise is launching soon; join the waitlist to try it early.

Getting started

Themes live under Tools → Themes in the workspace sidebar. Any workspace member can browse the list; creating and editing themes requires the Manage workspace permission. You can also generate a starting theme with AI — describe the look you're after and refine the result in the editor (each generation uses one AI generation from the monthly allowance).

The editor shows a live preview of your CSS and validates it as you type, so you get instant feedback — including per-line errors — before anything is saved.

To apply a theme: in the form or assessment builder open Settings → Theme and pick one. For pages, choose the theme in Page settings → Theme.

How theming works

You write ordinary CSS — no wrapper syntax, no special dialect. When a theme is saved, the stylesheet is automatically sanitized and scoped so it can only affect the rendered form, assessment, or page it is applied to. You never add any scoping yourself.

:root, html, and body selectors are re-anchored to the themed region, so :root { --primary: … } overrides the design tokens for just that render — the quickest way to recolor everything at once.

For dark mode, target .amp-dark (e.g. .amp-dark .amp-card { … }). If you write .dark on a root selector it is mapped to .amp-dark automatically.

:root {
  --primary: oklch(0.55 0.22 275);
}

.amp-dark .amp-card {
  border-color: oklch(0.45 0.05 275);
}

Styling hooks

Three kinds of hooks are stable API for theme authors: structural amp-* classes, data-slot attributes on UI primitives, and the design token CSS variables. Anything else — like utility class names you may spot in the markup — can change without notice.

Structural classes

SelectorDescription
.amp-rootRoot element of every themed render. .amp-form-root and .amp-assessment-root narrow to forms or assessments.
.amp-headerHeader region containing the title and description.
.amp-titleThe form, assessment, or page title.
.amp-descriptionThe description shown under the title.
.amp-progressProgress indicator in multi-step layouts.
.amp-cardThe main card surface content renders in.
.amp-questionA single question or input block. .amp-question--{type} narrows per type, e.g. .amp-question--rating or .amp-question--multiple-choice.
.amp-navNavigation row holding the previous, next, and submit buttons on forms and multi-step assessments. The one-by-one dock is not part of .amp-nav — style it via .amp-pager.
.amp-btn-prev / .amp-btn-next / .amp-btn-submitThe individual previous, next, and submit buttons inside .amp-nav. Safe to style as full-width action bars — these classes never apply inside the one-by-one dock.
.amp-pager / .amp-pipThe floating navigation dock in one-by-one assessments and its question number buttons; pips carry .amp-pip--current and .amp-pip--answered. The dock's own previous/next/submit buttons are .amp-pager-prev, .amp-pager-next and .amp-pager-submit — keep them compact (no width or height overrides).
.amp-question[data-amp-qnum]Every question exposes its 1-based, zero-padded number as a data-amp-qnum attribute — render it with content: attr(data-amp-qnum).
.amp-start-cardThe assessment intro card shown before starting.
.amp-checklist / .amp-checklist-itemThe start card's readiness checklist and its rows; a checked row also carries .amp-checklist-item--checked.
.amp-statThe start card's stat tiles (questions, points, time limit).
.amp-instructionsThe scrollable instructions panel on the start card's instructions step.
.amp-calloutStart-card notices — proctoring/SEB disclosures and the pre-start warning. Carries .amp-callout--info or .amp-callout--warning.
.amp-auth-cardParticipant identity cards.
.amp-timerThe assessment countdown timer.
.amp-successThe completion screen shown after submitting.

Component attributes

Every shadcn UI primitive in the render carries a data-slot attribute you can target directly — a stable alternative to guessing at class names. A few of the most useful:

SelectorDescription
[data-slot="button"]All buttons in the render.
[data-slot="input"]Text inputs.
[data-slot="label"]Field labels.
[data-slot="select-trigger"]The clickable part of a select dropdown.
[data-slot="card"]Card primitives.

Design token variables

Design tokens are global CSS variables you can override from a :root { … } block in your theme. Color tokens are OKLch values.

VariableDescription
--background / --foregroundBase background and text colors of the themed region.
--cardCard surface color.
--popoverPopover and dropdown surface color.
--primaryPrimary buttons and highlights.
--secondarySecondary surfaces and buttons.
--mutedMuted backgrounds and subdued text.
--accentHover and subtle highlight surfaces.
--border / --inputBorder colors for surfaces and inputs.
--ringFocus ring color.
--destructiveError and destructive-action color.
--radiusBase corner radius the whole render derives from.

Motion presets

Themes can replace the default question entrance animation with a spring-physics preset played by the app's own animation engine. You declare plain CSS variables on :root — the theme stays pure CSS, no scripting involved — and every question animates in with the chosen preset, staggered one after another.

Presets apply wherever questions enter the screen: the initial reveal on single-page assessments and forms, each step of a multi-step assessment, and every card in one-by-one mode. An unknown preset value is simply ignored and the default animation plays instead.

Presets

ValueDescription
fade-upA springy rise from below — the soft default choice.
scale-inPops in with a bouncy scale — punchy and energetic.
slideSweeps in from the side with a firm spring.
blur-inCondenses out of a soft blur — suits glassy, airy designs.
flipA 3D flip up from the surface, like a card being dealt.

Variables

VariableDescription
--amp-motionThe entrance preset. Required for any of this to kick in.
--amp-motion-durationOptional length of one entrance, e.g. 0.6s — clamped between 0.15s and 1.5s.
--amp-motion-staggerOptional delay between consecutive questions, e.g. 90ms — clamped between 0 and 300ms, default 70ms. Total delay is capped so long question lists never keep the tail hidden.
:root {
  --amp-motion: scale-in;
  --amp-motion-duration: 0.6s;
  --amp-motion-stagger: 90ms;
}

Accessibility & conflicts

Visitors with a reduced-motion preference automatically get the plain, non-animated render — no media query needed on your side. One caveat: the presets animate the question wrappers' transform, opacity, and filter, so avoid also animating those same properties on .amp-question with your own keyframes, or the two animations will fight.

Rules & limits

External resources are blocked

url() may only reference assets you've uploaded or data: URIs. External hosts and @import are rejected at save time.

Animation and font names need a prefix

@keyframes and @font-face names must start with theme- — for example @keyframes theme-fade. Unprefixed names are rejected.

Size limit

Stylesheets are capped at 100 KB.

The watermark stays

The “Powered by Amperlise” watermark can't be styled or hidden by a theme. Removing it is a separate feature — Remove branding.

Invalid CSS never ships

Invalid CSS is rejected with per-line errors in the editor. A theme is either fully valid or it isn't saved.

Examples

Three complete themes you can paste straight into the editor.

Brand colors & radius

Override design tokens on :root for light mode and .amp-dark for dark mode — the fastest way to make a render match your brand.

:root {
  --primary: oklch(0.5 0.2 300);
  --ring: oklch(0.5 0.2 300);
  --card: oklch(0.99 0.005 300);
  --radius: 1rem;
}

.amp-dark {
  --primary: oklch(0.78 0.16 300);
  --card: oklch(0.24 0.02 300);
  --border: oklch(0.35 0.03 300);
}

Neo-brutalist cards

Hard shadows, thick borders, and no blur — restyle the card, the title, and every button directly.

.amp-card {
  border: 3px solid oklch(0.2 0 0);
  border-radius: 0;
  box-shadow: 8px 8px 0 oklch(0.2 0 0);
}

.amp-title {
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: -0.02em;
}

[data-slot="button"] {
  border: 3px solid oklch(0.2 0 0);
  border-radius: 0;
  box-shadow: 4px 4px 0 oklch(0.2 0 0);
}

[data-slot="button"]:hover {
  translate: -2px -2px;
  box-shadow: 6px 6px 0 oklch(0.2 0 0);
}

Entrance animation & motion presets

A motion preset for the questions (see Motion presets above) combined with hand-rolled keyframes for the header — note the required theme- prefix on the keyframes name.

:root {
  /* Built-in spring entrance */
  --amp-motion: scale-in;
  --amp-motion-stagger: 90ms;
}

/* …or hand-rolled keyframes */
@keyframes theme-rise {
  from {
    opacity: 0;
    translate: 0 12px;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

.amp-header {
  animation: theme-rise 400ms ease-out both;
}

Sharing themes

Export any theme as a .json file from its row menu on the Themes page, and bring it into another workspace with the Import button.

Imported CSS is re-validated on import, so a theme file is held to exactly the same rules as CSS written in the editor.

Theme library

The theme library is a public gallery of ready-made themes curated by Amperlise. Browse it from the Browse library button on your workspace's Themes page — every theme has a live preview against a sample form, assessment, and page, plus its full CSS source.

Use in workspace copies a library theme into a workspace of your choice as a regular custom theme: you can apply it as-is or open it in the theme editor and make it your own. Copies are independent — later changes to the library theme never touch your workspace.

Library CSS passes through exactly the same validation as CSS you write yourself, and applying a copied theme still requires the Professional plan's Custom Themes feature.

Publishing your own themes

Submitting your workspace themes to the public library is coming soon — the option is already visible in the theme row menu, but disabled for now.

Troubleshooting

My selector doesn't do anything

Check the styling hooks reference above — only amp-* classes, data-slot attributes, and design token variables are stable API. Utility class names in the page markup aren't, and can change at any time.

My theme isn't showing on the public page

Custom Themes are a Professional feature. If the organization's plan is downgraded, public renders fall back to the default look — check the plan before debugging the CSS.

My animation was rejected

@keyframes names must start with theme- (e.g. theme-fade). Rename the keyframes and every animation reference to it.

My image was rejected

url() can only point to uploaded assets or data: URIs. Upload the image instead of linking to an external host.