Branding
Branding
All Onelo hosted surfaces — Auth, Checkout card, Store, Customer portal, Feedback, Waitlist, and Roadmap — are styled from your Branding settings via CSS custom properties. This page covers both halves: the visual controls in the dashboard, and Custom CSS for anything they don't expose — injected into every surface automatically. No framework, no build step.
The visual controls
Open Dashboard → App → Branding. Along the top are tabs for each surface — Auth, Checkout card, Store, Customer portal, Feedback, Waitlist and Roadmap — with a live preview beside the controls. Switch the preview between Desktop and Mobile at any time.
Logo
| Control | Default | CSS variable | What it does |
|---|---|---|---|
| Logo | (none) | — | Upload your logo image. Used by every surface that shows one. |
| Logo frame | off | — | Draws a border/background ring around the logo. Off = clean transparent logo. |
| Logo frame fill | (empty) | --onelo-logo-bg | Fill colour of that ring. Empty = border only. Only used when Logo frame is on. |
| Logo frame thickness | 4px | --onelo-logo-frame-width | How thick the ring/padding around the logo is (1–16px). |
Below those, each surface gets its own show/hide and alignment — so you can centre the logo on the hosted Auth page but tuck it to the left in the compact checkout card, or hide it entirely on one surface without touching the others.
| Control | Default | CSS variable | What it does |
|---|---|---|---|
| Auth | shown · center | — | Hosted sign-in / sign-up page. |
| Checkout card | shown · left | — | The card sits in a compact header row, hence left by default. |
| Store | shown · left | — | Managed here, not in the Store panel — one source of truth. |
| Customer portal | shown · center | — | Subscription management page. |
| Feedback | shown · center | — | Hosted bug-report / feature-request form. |
| Waitlist | shown · center | — | Hosted waitlist form and its iframe embed. |
| Roadmap | shown · left | — | Public roadmap page. |
Colors
| Control | Default | CSS variable | What it does |
|---|---|---|---|
| Brand color | #f97316 | --onelo-brand | Price, highlights, and the default button background. |
| Page background | #111111 | --onelo-page-bg | The area behind the card on hosted pages. |
| Card background | #1a1a1a | --onelo-card-bg | The card / panel surface itself. |
| Text color | #ffffff | --onelo-text | Main text colour, inherited by inputs unless you override them. |
| Border color | #2a2a2a | --onelo-border | Default colour for card, input and button borders. |
Buttons
| Control | Default | CSS variable | What it does |
|---|---|---|---|
| Button background | (empty) | --onelo-button-bg | Leave empty to follow Brand color. |
| Button text | #ffffff | --onelo-button-text | Label colour. |
| Button border width | 0px | — | 0–4px. At 0 the border is removed entirely. |
| Button border color | (empty) | --onelo-button-border | Empty = Border color. The field only appears once width is above 0. |
| Button radius | 14px | --onelo-button-radius | 0–24px. Starts from Card radius, then overrides it. |
Inputs
| Control | Default | CSS variable | What it does |
|---|---|---|---|
| Input background | (empty) | --onelo-input-bg | Empty = an automatic subtle overlay that works on light and dark cards. |
| Input text | (empty) | --onelo-input-text | Empty = inherits Text color. |
| Input border color | (empty) | --onelo-input-border-color | Empty = Border color. Set it to make fields differ from the card frame. |
| Input border width | 1px | --onelo-field-border-width | 0–4px. |
| Field radius | 14px | --onelo-field-radius | 0–24px. Starts from Card radius, then overrides it. |
Card
| Control | Default | CSS variable | What it does |
|---|---|---|---|
| Show card border | on | — | Checkout card and Customer portal only. Waitlist and Store have their own toggles. |
| Card border width | 1px | --onelo-card-border-width | 0–4px. |
| Card radius | 14px | --onelo-radius | Rounds cards and panels. Button and Field radius start from this value. |
| Featured border width | 2px | --onelo-featured-border-width | Store only — the ring around a featured product (0–8px). |
| Featured border color | (empty) | --onelo-featured-border-color | Store only. Empty = Brand color. |
Typography
| Control | Default | CSS variable | What it does |
|---|---|---|---|
| Heading font | Inter | --onelo-heading-font | 15 web fonts, plus system-ui (uses the device font, loads nothing). |
| Heading size | 26px | --onelo-heading-size | 18 → 48px. |
| Body font | Inter | --onelo-body-font | Same list as headings — pick the same one for a quieter look. |
| Body size | 14px | --onelo-body-size | 12 → 18px. |
Shadow
Shadows are off by default. The master Shadow toggle turns the whole system on; from there each element carries its own geometry, which you set by dragging a light source around a 2D pad rather than typing offsets.
| Control | Default | CSS variable | What it does |
|---|---|---|---|
| Shadow | off | — | Master switch. Off = no shadow anywhere, whatever the per-element values say. |
| Shadow color | #000000 | --onelo-shadow-color | Shared by every element. |
| Card shadow | on · 0/12px · blur 48 · 15% | — | Per-element: enable, offset X/Y, blur, opacity. |
| Buttons shadow | on · 0/4px · blur 16 · 20% | — | Tighter and stronger than the card — buttons sit closer to the surface. |
| Inputs shadow | on · 0/2px · blur 8 · 10% | — | Subtlest of the three. |
Waitlist-only
| Control | Default | CSS variable | What it does |
|---|---|---|---|
| Card max width | 360px | --onelo-card-max-width | 240 → 600px. Widen it when your form collects more than an email. |
| Show card border | on | — | The Waitlist card has its own border toggle, separate from the Card one. |
Footer & Custom CSS
| Control | Default | CSS variable | What it does |
|---|---|---|---|
| Show "Powered by Onelo" | on | — | Turning it off requires a paid plan. On Free the footer always renders. |
| Custom CSS | (empty) | — | The Advanced field the rest of this page is about. Requires a paid plan — on Free it renders locked. |
Custom CSS — how it works
Onelo renders each surface on its own URL and sets a base set of --onelo-* CSS variables from your Branding settings. Your Custom CSS is appended on top.
Custom CSS is automatically scoped to the surface it runs on — every rule you write is prefixed with that surface's root so it can never leak into the Onelo dashboard or another surface. You can also scope a rule yourself to a single surface using its root ID (e.g. #onelo-auth).
:hover, :focus) don't show there — check them in the mobile preview or on the hosted URL.CSS Variables
Onelo sets these on each surface from your Branding settings. The canonical way to change color, font, and radius is the visual controls in Branding. In Custom CSS you can read these variables (e.g. box-shadow: var(--onelo-card-shadow)) and re-declare them scoped to a surface root for fine tuning. Some values (--onelo-button-bg, --onelo-input-bg) are pre-resolved on the root, so to change a concrete element reliably, override the property directly with !important (see Cookbook).
Colors
| Variable | Default | Description |
|---|---|---|
| --onelo-brand | #f97316 | Brand accent — price, highlights, default button background |
| --onelo-page-bg | #111111 | Page background, behind the card |
| --onelo-card-bg | #1a1a1a | Card / panel background |
| --onelo-text | #ffffff | Body text color |
| --onelo-border | #2a2a2a | Borders, inputs, dividers |
| --onelo-shadow-color | #000000 | Shared color for card / button / input shadows |
Buttons & inputs
| Variable | Default | Description |
|---|---|---|
| --onelo-button-bg | (brand) | Button background — falls back to --onelo-brand when unset |
| --onelo-button-text | #ffffff | Text color on buttons |
| --onelo-button-border | none | Button border — none unless a border width is set |
| --onelo-input-bg | rgba(255,255,255,0.06) | Input fill — auto subtle overlay when unset |
| --onelo-input-text | (inherits --onelo-text) | Input text color |
| --onelo-input-border-color | (inherits --onelo-border) | Input border — set “Input border color” in Branding to decouple inputs from the card frame |
Radius & borders
| Variable | Default | Description |
|---|---|---|
| --onelo-radius | 14px | Radius for cards / panels — when you haven’t set it explicitly it follows the larger of your button and field radius |
| --onelo-button-radius | 14px | Button corner radius (overrides master) |
| --onelo-field-radius | 14px | Input corner radius (overrides master) |
| --onelo-field-border-width | 1px | Input border width |
| --onelo-card-border-width | 1px | Card / panel border width |
--onelo-featured-border-width and --onelo-featured-border-color — set from the visual controls in Branding → Card.Typography
Font family and size are chosen from the Heading / Body pickers in Branding (16 built-in fonts). These variables carry the chosen values.
| Variable | Default | Description |
|---|---|---|
| --onelo-heading-font | Inter | Heading font family |
| --onelo-heading-size | 26px | Heading size |
| --onelo-body-font | Inter | Body font family |
| --onelo-body-size | 14px | Base body font size |
Shadows & logo
Shadows are off by default — enable them with the master Shadow toggle in Branding. The composite variables resolve to none while disabled.
| Variable | Default | Description |
|---|---|---|
| --onelo-card-shadow | (computed) | Card box-shadow — none unless shadows are enabled |
| --onelo-button-shadow | (computed) | Button box-shadow |
| --onelo-input-shadow | (computed) | Input box-shadow |
| --onelo-logo-bg | (unset) | Logo frame fill (when Logo frame is on) |
| --onelo-logo-frame-width | 4px | Logo frame thickness |
| --onelo-card-max-width | 360px | Waitlist card max width (Waitlist only) |
Selectors
These surfaces expose a root ID — scope a rule to one surface by prefixing it with the ID (e.g. #onelo-store .onelo-button).
| Selector | Surface | What it targets |
|---|---|---|
| #onelo-auth | Auth | Sign-in / sign-up form root |
| #onelo-store | Store | Pricing / products page root |
| #onelo-portal | Customer portal | Subscription / billing portal root |
| #onelo-waitlist | Waitlist | Waitlist widget root |
| #onelo-roadmap | Roadmap | Public roadmap root |
Element hooks you can target (with !important for concrete properties):
| Selector | Surface | What it targets |
|---|---|---|
| .checkout-card | Checkout card | The card container (the card has no #onelo-* root id — scope card-only rules to this) |
| .onelo-button | Auth / Store / Waitlist / Checkout card | CTA / submit / purchase buttons |
| .onelo-input | Auth / Waitlist / Checkout card | Text input fields — also bridged into the card’s Stripe fields (see “Checkout card & Stripe”) |
| [data-onelo-feedback-input] | Feedback | Feedback message / details inputs |
| [data-onelo-feedback-submit] | Feedback | Feedback submit button |
| [data-onelo-feedback-chip] | Feedback | Feedback type chips |
| .portal-btn | Customer portal | All portal buttons (base) |
| .portal-btn-primary / -secondary / -danger / -ghost | Customer portal | A specific portal button style |
| .portal-card / .portal-section | Customer portal | Portal cards & sections |
| [data-onelo-product-card] | Store | Each store product card |
| [data-onelo-card-divider] | Checkout card | The left/right column separator (set border-color to recolor it) |
#onelo-footer / [data-onelo-powered-by]) cannot be styled or hidden via Custom CSS — those rules are stripped. Hide it with the plan-gated toggle in Branding → Powered by Onelo instead.#onelo-store, the .checkout-card container, or an element hook).Per-surface & per-element targeting
Because every rule is auto-scoped to the surface it runs on, and each surface exposes a root ID plus element hooks, you can style one element type on one surface and nothing else — and give each surface its own independent settings. Combine a root ID with an element hook: #surface .element.
Shadow on Auth buttons only — inputs untouched
#onelo-auth .onelo-button {
box-shadow: 0 6px 24px rgba(255, 0, 255, 0.5) !important;
}Different settings per surface
Each #surface .element block is independent — style Auth and Portal buttons completely differently.
/* Auth buttons — magenta glow */
#onelo-auth .onelo-button {
box-shadow: 0 6px 24px rgba(255, 0, 255, 0.5) !important;
}
/* Portal primary button — different glow + sharper corners */
#onelo-portal .portal-btn-primary {
box-shadow: 0 2px 8px rgba(0, 255, 0, 0.4) !important;
border-radius: 4px !important;
}
/* Store CTA buttons — yet another look */
#onelo-store .onelo-button {
text-transform: uppercase !important;
letter-spacing: 0.06em !important;
}!important. Overriding a --onelo-* variable scoped to a root (e.g. #onelo-auth { --onelo-text: #eee }) does not need it..onelo-button) applies to that element on every surface that has it.Checkout card & Stripe
The checkout card is split in two. The left column (logo, product name, price) is rendered by Onelo and is fully stylable. The right column — every payment field (Email, Card number, Sort code…) and the payment-method tabs (Card / Bacs Direct Debit / …) — is rendered by Stripe inside an iframe. Custom CSS cannot reach inside it — a hard browser-security boundary.
How to style the Stripe fields & tabs anyway
Onelo bridges your input CSS into Stripe's appearance. A rule matching .onelo-input (or input / textarea) has its background, color, border, border-radius and box-shadow copied onto the Stripe fields and the unselected payment-method tabs. So this restyles them:
.onelo-input {
background: #11001a !important;
border: 2px solid #2a0040 !important;
color: #ffffff !important;
}The column divider line
The vertical line between the two columns is the left panel's border. Its color comes from Branding → Border color (applied inline). To recolor it from CSS, target the panel by its inline border — this works regardless of layout/build and leaves the lower divider untouched:
.checkout-card [data-onelo-card-divider] {
border-color: #00ff88 !important;
}[data-onelo-card-divider] is the supported hook for the card's separator lines — use it instead of matching inline styles, which breaks whenever the card's markup changes.Cookbook
Recolor buttons across surfaces
Buttons apply their background inline, so override the property with !important. A rule with no surface ID applies everywhere.
.onelo-button {
background: #7c3aed !important;
color: #ffffff !important;
}Different button per surface
Prefix with a root ID to scope to one surface.
#onelo-auth .onelo-button {
background: #6d28d9 !important;
}
#onelo-store .onelo-button {
background: linear-gradient(135deg, #7c3aed, #a855f7) !important;
box-shadow: 0 4px 20px rgba(124, 58, 237, 0.35) !important;
}Tune colors that read a variable live
Variables like --onelo-text and --onelo-border are read live, so re-declaring them scoped to a root works without !important.
#onelo-waitlist {
--onelo-text: #e8e8e8;
--onelo-border: rgba(14, 165, 233, 0.3);
}Button hover animation
#onelo-auth .onelo-button,
#onelo-waitlist .onelo-button {
transition: transform 0.15s ease, box-shadow 0.15s ease;
}
#onelo-auth .onelo-button:hover,
#onelo-waitlist .onelo-button:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(124, 58, 237, 0.45) !important;
}Light mode adaptation
Media queries are supported and scoped automatically.
@media (prefers-color-scheme: light) {
#onelo-auth,
#onelo-waitlist {
--onelo-border: rgba(0, 0, 0, 0.12);
--onelo-text: #111111;
}
}Mobile tweaks
@media (max-width: 400px) {
#onelo-store .onelo-button {
font-size: 13px;
padding: 10px;
}
}Fonts
Choose your heading and body fonts from the pickers in Branding → Typography — 15 web fonts are built in (Inter, Poppins, Plus Jakarta Sans, Figtree, Manrope, and more) and are loaded for you on every surface, plus system-ui, which uses the device's own font and loads nothing.
@import in Custom CSS — @import is stripped for security. Use the built-in font picker instead.What you cannot do with CSS
- ✕Hide or recolor the "Powered by Onelo" mark — Footer-targeted rules are stripped; hide it via the plan-gated Branding toggle
- ✕Load external fonts or stylesheets with @import — @import is removed during sanitization — use the built-in font picker
- ✕Change field order (e.g. name before email) — HTML structure is controlled by Onelo
- ✕Add custom fields to the Auth form — Use Waitlist for custom data collection
- ✕Change button labels ("Sign in", "Join Waitlist") — Text is managed by Onelo
- ✕Reach inside the Stripe iframe with CSS — Payment fields + method tabs are cross-origin — style them via the .onelo-input bridge instead (see “Checkout card & Stripe”)
Tips
- —Override variables, not concrete properties, where you can — variable overrides cascade naturally and never need !important.
- —Use !important only when overriding a concrete property (background, box-shadow, border) that a widget applies as an inline style — e.g. on .onelo-button.
- —Avoid structural selectors like > div > div — widget HTML may change between releases. Stick to .onelo-button, .onelo-input, the data-onelo-* hooks, or the root IDs.
- —The dashboard preview is a snapshot — :hover and :focus states are not visible there. Test them on the hosted URL.
- —All surfaces share one Custom CSS field — use the root IDs (#onelo-auth, #onelo-store…) to scope rules to specific surfaces.