# Customer UI theming
You can customize the appearance of self-service pages to match your brand identity using CSS custom properties (variables). These cascade from brand tokens to Bootstrap components.
# Picking a branding system
In the customer-service admin you pick one of five branding systems:
- Neutral, Modern, Classic — three curated presets. Each ships with its own typography, shadow/border language and page treatment. You can optionally set a primary color and the preset tints CTAs, links, focus rings and accents with it. Pick one of these if you want a finished look out of the box.
- Simple — a small form where you pick primary color, page background, corner style and font type. Good if the presets are close but not quite right.
- Advanced — paste raw CSS variable declarations directly. Everything below on this page applies to the advanced system. Use this when you need full control.
The three presets render on top of the same CSS variable system described here. You can read the presets' own values under preset personality variables below if you want to emulate one in advanced mode.
# Quick start
Here's a complete starter theme. Paste only the variable declarations — not
the :root { ... } wrapper — into the Advanced theme variables field. Iteras
adds the :root wrapper itself when the page renders. Once pasted, swap the three
primary-color values for your brand color; the rest are sensible defaults.
/* Paste the lines below (not the :root wrapper) into the Advanced field. */
:root {
/* Your brand color. Swap these three values to match. Focus rings and
other tinted accents read from the RGB value automatically. */
--iteras-primary-color: #0891b2;
--iteras-primary-color-rgb: 8, 145, 178;
--iteras-primary-hover-color: #0e7490;
/* Page chrome. #fafafa is a quiet light gray that works anywhere. */
--iteras-page-background: #fafafa;
/* Body and heading fonts. Load via @import or <link> if needed. */
--iteras-font-family: 'Figtree', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--iteras-font-family-heading: var(--iteras-font-family);
/* Corner feel. Try 0 for sharp, 6px for modest (shown), 16px for soft. */
--iteras-border-radius: 6px;
--iteras-border-radius-sm: 4px;
--iteras-border-radius-lg: 10px;
--iteras-border-radius-pill: 9999px;
}
Everything else — buttons, cards, forms, links, semantic colors — inherits defaults from the base stylesheet and doesn't need to be set. Scroll down for the full reference if you want to fine-tune further.
# Variable reference
Full list of CSS variables, grouped by what they affect. The Quick Start above already covers the core brand variables — everything below is for when you want to go further.
# Core brand variables
The Quick Start block sets all of these. Defaults shown match the Neutral preset. The primary color trio has no fallback in advanced mode, so it must be set; everything else works off a Bootstrap default if left unset but will look generic.
| Variable | Default | Description |
|---|---|---|
--iteras-primary-color |
#1f2937 |
Main brand color for buttons, links, and accents |
--iteras-primary-color-rgb |
31, 41, 55 |
RGB values for use with rgba() opacity effects |
--iteras-primary-hover-color |
#0f172a |
Primary color hover/active state |
--iteras-page-background |
#fafafa |
Page background color |
--iteras-font-family |
'Figtree', sans-serif |
Body text font stack |
--iteras-font-family-heading |
var(--iteras-font-family) |
Heading font stack |
--iteras-border-radius |
6px |
Default border radius for components |
--iteras-border-radius-sm |
4px |
Small border radius |
--iteras-border-radius-lg |
10px |
Large border radius |
--iteras-border-radius-pill |
6px |
Pill-shaped border radius |
--iteras-icon-background |
rgba(var(--iteras-primary-color-rgb), 0.10) |
Icon container background (typically 10% of primary) |
# Text colors
Control the color of body text and secondary text. The defaults work well for most brands:
| Variable | Default | Description |
|---|---|---|
--iteras-body-color |
#212529 |
Body text color |
--iteras-secondary-color |
#6c757d |
Muted/secondary text color |
# Neutral palette
These neutral colors are used for backgrounds, borders, and UI chrome. Override them if you need a warmer or cooler gray palette:
| Variable | Default | Description |
|---|---|---|
--iteras-color-white |
#ffffff |
White color |
--iteras-color-dark |
#171717 |
Near-black color for text and dark elements |
--iteras-color-light |
#e9ecef |
Light gray for backgrounds |
--iteras-color-light-hover |
#d3d6d9 |
Light gray hover state |
--iteras-color-light-active |
#c4c8cc |
Light gray active state |
--iteras-border-color |
#ced4da |
Default border color for inputs and components |
# Link variables
Links inherit from your primary color by default. You can override these if you want links to look different from buttons:
| Variable | Default | Description |
|---|---|---|
--iteras-link-color |
var(--iteras-primary-color) |
Link text color |
--iteras-link-hover-color |
var(--iteras-primary-hover-color) |
Link hover color |
--iteras-link-decoration |
none |
Link underline (none or underline) |
--iteras-link-underline-thickness |
1px |
Thickness of underline when --iteras-link-decoration is underline |
--iteras-link-underline-offset |
.12em |
Distance between the text baseline and the underline |
# Typography rhythm
Fine-tune heading weight and spacing without restating the font stacks. Use these if your font family works best at a non-default weight or if you want tighter/looser headings:
| Variable | Default | Description |
|---|---|---|
--iteras-heading-font-weight |
500 |
Weight applied to all headings (h1–h6) |
--iteras-heading-letter-spacing |
normal |
Letter-spacing on headings. Geometric fonts often look better at -0.02em |
--iteras-heading-line-height |
1.2 |
Line-height on headings |
--iteras-display-font-family |
var(--iteras-font-family-heading) |
Optional separate font stack for hero-style numbers and masthead-weight h1s |
--iteras-display-font-weight |
var(--iteras-heading-font-weight) |
Weight for the display font |
--iteras-heading-rule-display |
none |
Set to block to draw a thin rule below h1 (masthead look) |
--iteras-heading-rule-color |
rgba(0, 0, 0, 0.2) |
Color of the masthead rule when enabled |
# Page background layer
An optional decorative background image drawn on top of the page background color:
| Variable | Default | Description |
|---|---|---|
--iteras-page-background-image |
none |
Any valid background-image value. Applied with background-attachment: fixed,
so gradients or SVGs stay put while the user scrolls. Typical use: a radial-gradient mesh tinted
with rgba(var(--iteras-primary-color-rgb), 0.12). |
# Form input variables
Fine-tune the appearance of form inputs and labels:
| Variable | Default | Description |
|---|---|---|
--iteras-input-height |
38px |
Default input height |
--iteras-input-border-color |
#ced4da |
Input border color |
--iteras-input-background |
#ffffff |
Input background color |
--iteras-input-focus-border-color |
var(--iteras-primary-color) |
Input border color when focused |
--iteras-label-color |
var(--iteras-body-color) |
Form label color |
--iteras-label-font-weight |
500 |
Form label font weight |
--iteras-label-text-transform |
none |
Use uppercase for editorial eyebrow-style labels |
--iteras-label-letter-spacing |
0 |
Useful with text-transform: uppercase — try 0.1em |
# Button variables
Primary buttons use your primary color automatically. These variables control secondary buttons:
| Variable | Default | Description |
|---|---|---|
--iteras-button-secondary-bg |
var(--iteras-color-light) |
Secondary button background |
--iteras-button-secondary-color |
#171717 |
Secondary button text color |
--iteras-button-secondary-border |
#ced4da |
Secondary button border color |
--iteras-button-font-weight |
600 |
Weight for all button types |
--iteras-button-padding-x |
1rem |
Horizontal padding on default-size buttons. Increase for roomier CTAs |
--iteras-button-padding-y |
0.375rem |
Vertical padding on default-size buttons |
# Card variables
Cards are the main content containers. You can customize their background, borders, and headers:
| Variable | Default | Description |
|---|---|---|
--iteras-card-background |
#ffffff |
Card background color |
--iteras-card-border-color |
rgba(0, 0, 0, 0.18) |
Card border color |
--iteras-card-header-background |
#000000 |
Dark card header background |
--iteras-card-image-background |
#eeeeee |
Placeholder background for card images |
--iteras-section-border |
none |
Section divider border |
--iteras-card-padding |
1rem |
Padding inside .card-body, .card-header, .card-footer. The three
presets use 1.25rem–1.75rem. |
--iteras-shadow-card |
none |
Drop-shadow applied to cards. Useful value for colored shadows:
0 1px 2px rgba(0,0,0,.04), 0 8px 24px -8px rgba(var(--iteras-primary-color-rgb), .14) |
--iteras-shadow-card-hover |
none |
Drop-shadow on card hover. Falls back to --iteras-shadow-card if not set. |
# Semantic colors (shared)
These colors are the same across all brands to keep the user experience consistent. They are WCAG AA compliant (4.5:1 contrast ratio) for use on tinted alert backgrounds. Don't change these unless you have a good reason:
| Variable | Default | Purpose |
|---|---|---|
--iteras-success-color |
#0d7a3e |
Success states |
--iteras-warning-color |
#a16207 |
Warning states |
--iteras-danger-color |
#c41e1e |
Error/danger states |
--iteras-info-color |
#1766a5 |
Info states |
# Multi-brand support
If you have multiple brands (e.g., a media company with multiple publications), you can scope variables to CSS classes:
/* Brand A */
.brand-a {
--iteras-primary-color: #059669;
--iteras-primary-color-rgb: 5, 150, 105;
--iteras-icon-background: rgba(5, 150, 105, 0.1);
}
/* Brand B */
.brand-b {
--iteras-primary-color: #7c3aed;
--iteras-primary-color-rgb: 124, 58, 237;
--iteras-icon-background: rgba(124, 58, 237, 0.1);
}
Apply the brand class to the body element:
<body class="selfservice brand-a">
<!-- Content inherits brand-a colors -->
</body>
# Theme examples
Here are three complete themes showing different design directions. Copy one as a starting point and adjust the colors to match your brand:
# Sharp corners, warm palette
:root {
--iteras-primary-color: #e07020;
--iteras-primary-color-rgb: 224, 112, 32;
--iteras-primary-hover-color: #c2610d;
--iteras-page-background: #fef3e2;
--iteras-font-family: 'Inter', sans-serif;
--iteras-font-family-heading: 'Sora', sans-serif;
--iteras-border-radius: 0;
--iteras-border-radius-sm: 0;
--iteras-border-radius-lg: 0;
--iteras-border-radius-pill: 0;
--iteras-icon-background: rgba(224, 112, 32, 0.1);
}
# Rounded corners, cool palette
:root {
--iteras-primary-color: #7c3aed;
--iteras-primary-color-rgb: 124, 58, 237;
--iteras-primary-hover-color: #6d28d9;
--iteras-page-background: #f5f3ff;
--iteras-font-family: 'Inter', sans-serif;
--iteras-font-family-heading: 'Inter Tight', sans-serif;
--iteras-border-radius: 12px;
--iteras-border-radius-sm: 12px;
--iteras-border-radius-lg: 16px;
--iteras-border-radius-pill: 999px;
--iteras-icon-background: rgba(124, 58, 237, 0.1);
}
# Soft gradient atmosphere with colored shadows
Uses the page background layer and card-shadow tokens for a contemporary SaaS feel:
:root {
--iteras-primary-color: #0d9488;
--iteras-primary-color-rgb: 13, 148, 136;
--iteras-primary-hover-color: #0f766e;
--iteras-page-background: #fbfbfd;
--iteras-page-background-image:
radial-gradient(1200px 600px at 85% -10%,
rgba(var(--iteras-primary-color-rgb), 0.12) 0%,
rgba(var(--iteras-primary-color-rgb), 0) 60%);
--iteras-font-family: 'General Sans', sans-serif;
--iteras-font-family-heading: 'Geist', 'General Sans', sans-serif;
--iteras-heading-letter-spacing: -0.02em;
--iteras-heading-line-height: 1.1;
--iteras-border-radius: 16px;
--iteras-border-radius-sm: 10px;
--iteras-border-radius-lg: 20px;
--iteras-border-radius-pill: 999px;
--iteras-shadow-card:
0 1px 2px rgba(0, 0, 0, 0.04),
0 8px 24px -8px rgba(var(--iteras-primary-color-rgb), 0.14);
--iteras-shadow-card-hover:
0 1px 2px rgba(0, 0, 0, 0.04),
0 16px 40px -12px rgba(var(--iteras-primary-color-rgb), 0.22);
--iteras-button-padding-x: 1.5rem;
--iteras-card-padding: 1.75rem;
--iteras-icon-background: rgba(var(--iteras-primary-color-rgb), 0.12);
}
# Preset personality variables
This is what each of the three presets sets, if you want to emulate or extend one in the advanced system. Only the distinctive tokens are listed; each preset also sets the usual primary color, radii and icon background.
| Neutral | Modern | Classic | |
|---|---|---|---|
| Body font | Figtree | General Sans | Inter Tight |
| Heading font | Figtree | Geist | Fraunces (serif) |
--iteras-border-radius |
6px | 16px + pill buttons | 2px |
--iteras-heading-font-weight |
600 | 600 | 500 |
--iteras-heading-letter-spacing |
-0.005em |
-0.02em |
-0.005em |
--iteras-shadow-card |
none (hairline border) | colored, tinted with primary | none (top rule in primary) |
--iteras-page-background-image |
none | radial-gradient mesh tinted with primary | none |
--iteras-label-text-transform |
none | none | uppercase (small-caps eyebrows) |
--iteras-heading-rule-display |
none | none | block (masthead rule under h1) |
| Page background | #fafafa |
#fbfbfd |
#f7f3ec (warm cream) |
# Common questions
# Why do I need both the hex color and the RGB values?
The hex color (--iteras-primary-color) is used directly for solid colors. The RGB values
(--iteras-primary-color-rgb) are needed when we need to apply opacity, like for hover
states or the icon background. CSS can't extract RGB values from a hex color, so you need to provide both.
# What if my brand uses multiple primary colors?
Pick one as your main primary color for buttons and interactive elements. You can use the other colors for accents by defining additional custom variables in your CSS.
# How do I load custom fonts?
Load your fonts using @font-face rules or a Google Fonts link in your CSS, then reference
them in the font family variables. Make sure the fonts are loaded before the page renders to avoid
flash of unstyled text.
← Paywall