Styling tokens
On this page
Styling tokens are CSS custom properties named --andor-*. Every AndOr
widget reads them, so you can restyle all widgets with one global token,
or one widget with a per-widget token.
There are two layers, chained by var() fallback:
- Global tokens change every widget at once. Example:
--andor-color-accent. - Per-widget tokens change one widget. Example:
--andor-badge-background.
A merchant who never opens a setting gets the shipped look.
Where to put your CSS
All of these work equally well:
- The theme’s own stylesheet. On Dawn, that is
assets/base.css. On Horizon, useassets/base.cssor a snippet you render inlayout/theme.liquid. - Theme settings, Custom CSS, in the theme editor.
- The Custom CSS box in the AndOr app embed. It is printed after the
token block, so a
:rootrule there wins without specificity games.
<style>
:root { /* tokens */ }
</style>
<style>
/* the Custom CSS field, verbatim */
</style>Global tokens
The app embed prints these into :root. With the embed off they are
absent, and the fallbacks in the stylesheet give the same look.
| Token | As emitted | Set from |
|---|---|---|
--andor-sale-color |
#c0392b |
embed setting “Sale price color” |
--andor-original-color |
#6d7175 |
embed setting “Original price color” |
--andor-font-family |
inherit |
not settable, override in CSS |
--andor-color-text |
inherit |
not settable, override in CSS |
--andor-color-accent |
var(--andor-sale-color, #c0392b) |
follows the sale color |
--andor-color-on-accent |
#ffffff |
not settable, override in CSS |
--andor-color-muted |
var(--andor-original-color, #6d7175) |
follows the original color |
--andor-color-border |
rgba(0, 0, 0, 0.08) |
not settable, set in CSS |
--andor-radius |
4px |
embed setting “Corner radius”, range 0-24 |
--andor-space |
0.4em |
not settable, override in CSS |
--andor-sale-colorfollows the app brand color while the embed’s Sale price color stays at its default. For example, a brand color of#0b6b4fwith the sale color untouched gives--andor-sale-color: #0b6b4f. Not every widget uses the brand color. See Brand color.--andor-sale-colorand--andor-original-colorare the older pair. The newer names default through them, so an existing override keeps working.- When Show reward icons on goal bars is off, the embed also prints
--andor-goal-icons: none.
Opt-in tokens
The embed does not print these. Set them in CSS, or pick a style preset. Unset, nothing changes.
| Token | Read by | Unset falls back to |
|---|---|---|
--andor-color-success |
goal fill once won | the goal accent |
--andor-color-background |
goal, claim, cards | transparent |
--andor-color-background-soft |
tiers current row | rgba(0,0,0,.04) |
Skeleton tokens
Widgets printed by JavaScript show a quiet shimmer while they wait. It
stands still under prefers-reduced-motion: reduce.
| Property | Default | Controls |
|---|---|---|
--andor-skeleton-color |
border, 8% ink | the fill |
--andor-skeleton-highlight |
transparent |
the moving band |
--andor-skeleton-duration |
1.6s |
one pass of the band |
--andor-skeleton-radius |
radius, 4px |
corners, unframed parts |
:root {
--andor-skeleton-color: rgba(var(--color-foreground), 0.06);
--andor-skeleton-highlight: rgba(var(--color-foreground), 0.02);
}Goal bar icon position
--andor-goal-icon-spot is read by a script when the bar is first
printed. The value label puts each step’s icon beside its label. Any
other value, or none, keeps the icon inside the step’s circle.
:root {
--andor-goal-icon-spot: label;
}Per-widget tokens
Per-widget tokens are named --andor-<widget>-<property>. Each one
falls back to a global token where one exists, then to a literal:
background: var(
--andor-badge-background,
var(--andor-color-accent, #c0392b)
);Some examples:
| Token | Falls back to | Literal | Widget |
|---|---|---|---|
--andor-price-gap |
--andor-space |
0.4em |
price |
--andor-badge-background |
--andor-color-accent |
#c0392b |
badge |
--andor-badge-color |
--andor-color-on-accent |
#ffffff |
badge |
--andor-badge-radius |
0.25em |
badge | |
--andor-badge-font-size |
0.85em |
badge | |
--andor-countdown-color |
--andor-color-accent |
#c0392b |
countdown |
--andor-offers-accent |
--andor-color-accent |
#c0392b |
offers |
--andor-price-space-block-start |
0 |
price | |
--andor-price-space-block-end |
0 |
price |
Every widget’s full list is on its styling page. For example, see Goal bar styling and Savings badge styling.
Note
--andor-badge-radiusdoes not follow--andor-radius. The badge keeps its own0.25emdefault.
Which value wins
Highest to lowest:
- An inline
styleon the widget’s host. The badge’s background and text, the countdown’s text and the offers accent are always inline. The accent of the volume tiers, goal bar, offer picker and claim rows is inline only when the merchant changed it from#c0392b. - A block-scoped rule,
[data-andor-widget-id="<block id>"], printed by the block when a setting differs from its default. - A per-widget token set anywhere in your CSS.
- A global token set anywhere in your CSS.
- The literal fallback in the AndOr stylesheet.
Levels 2 and 3 have the same specificity. The block’s rule wins because it comes later in the page. Raise your selector’s specificity to beat it.
Two consequences:
- A stylesheet rule on
--andor-badge-backgrounddoes not beat the inline color, even when the merchant never touched it. Override the property itself (andor-badge { background: … }) or use!important. - An inline custom property can also be beaten from a child element, where your value wins by inheritance:
andor-goal .andor-goal__bar {
--andor-goal-accent: #0b6b4f;
}Examples
Retune the brand once, at :root. Blocks still on their default colors
follow it. Inline colors still win, as shown in
Which value wins:
:root {
--andor-color-accent: #0b6b4f;
--andor-color-on-accent: #ffffff;
--andor-color-muted: #5c6670;
--andor-color-border: rgba(11, 107, 79, 0.18);
--andor-radius: 999px;
--andor-space: 0.5em;
}Then change one widget only:
:root {
/* Pill badge, larger, in the brand's secondary color. */
--andor-badge-background: #f4f1ea;
--andor-badge-color: #1c1b19;
--andor-badge-radius: 999px;
--andor-badge-padding: 0.25em 0.75em;
--andor-badge-font-size: 0.9em;
}
/* Every widget has space-block-start and -end tokens. */
:root {
--andor-price-space-block-start: 0.5rem;
--andor-price-space-block-end: 0.75rem;
}
.andor-offers__item {
padding-block: 0.6em;
}Keep in mind
- Contrast is yours to check. Target at least 4.5:1 for normal text.
The shipped default is
#ffffffon#c0392b. - Never force a hidden widget back on. Hidden widgets carry both
hiddenand an inlinedisplay: none. A rule likeandor-badge { display: block }would bring back an expired sale. - Do not restyle
.andor-vh. It is the visually hidden text for screen readers.
See it in action