Documentation Abizvo Sites themes Liquid, the theme check and the premium standard — written from the code that enforces them

Settings

ThemeSettingTypes is the one gate between what an editor, an AI patch or an imported template sends and what a site stores: a value is normalized there or refused there, at save and again at publish, and the renderer trusts nothing else. Nothing a setting holds is ever HTML.

Declaring a setting

{ "type": "range", "id": "min_height", "label": "Height", "info": "Of the viewport.", "min": 30, "max": 100, "step": 5, "unit": "svh", "default": 80, "responsive": true,
  "visible_if": { "setting": "layout", "equals": "overlay" }, "group": "Layout" }
Field Meaning
type one of the forty-four types below; anything else is an error
id letters, digits, hyphens and underscores, at most 64 characters; unique within its owner. Not size, first, last, keys, values or empty — Liquid answers those from the settings dictionary itself, so {{ settings.size }} is the number of settings, not yours (name a size scale)
label required — it is what the owner reads
info help text under the control
content for header and paragraph: the words shown
default must itself be a valid value of the type
placeholder, unit, group editor hints; group names the panel group (Content, Layout, Design, Animation)
options for select, radio, button_group: [{ "value", "label", "group" }], at least one, values distinct
min, max, step for number and range; a range needs min below max and a positive step giving at most 1,000 positions
responsive tablet and mobile may override the value; allowed only on number, range, select, radio, button_group, text_alignment, spacing, radius, checkbox, toggle
dynamic whether a dynamic source may stand in for the value; textual types allow it unless told false
definition, role for color_scheme_group only
visible_if { "setting": "<id>", "equals": <value> } shows the control only when another setting has that value

When nothing is stored, the default applies; with no default, a checkbox or toggle is false, a range is its min, a select/radio/button_group is its first option, a text_alignment is left, and everything else is nil.

The forty-four types

Type Stored value Validation In Liquid
text a string at most 1,000 characters; control characters and newlines removed string
textarea a string at most 10,000 characters; newlines kept string
inline_richtext rich-text markup at most 50,000 characters, newlines folded rendered HTML (spans only)
richtext rich-text markup at most 50,000 characters rendered HTML (paragraphs, headings, lists, quotes, links)
date yyyy-MM-dd a real calendar date; "" clears string, for Liquid's date filter
number a number within min/max when set; a numeric string is accepted number
range a number within min–max, snapped to step number
checkbox, toggle true / false a boolean boolean
select, radio, button_group one option's value must be a listed option string
text_alignment left, center, right one of the three string
color #rrggbb (a 3-digit form is expanded; 8 digits allowed) or transparent hex or transparent, lowercased string
color_scheme a scheme handle must be a scheme the theme's group defines string — write it as color-{{ value }} on the element
color_scheme_group { "<handle>": { "name", "settings": { … } } } 1–24 schemes; each handle a valid id; each colour normalized against the group's definition; once per theme, in settings_schema.json a dictionary of schemes, each a dictionary of colours
color_background a gradient string linear-gradient(…) or radial-gradient(…) of 2–8 hex colours with optional stops, at most 400 characters; "" clears string
image_picker { "media": "<id>" } from the site's library, or { "asset": "images/x.webp" } from the theme, plus alt (≤300), decorative, focal: { x, y } (fractions 0–1) the id must be in this site's library; the asset must be a legal theme path { id, src, width, height, aspect_ratio, alt, decorative, focal_point } — a removed library picture renders as nil on the public page
video { "media": "<id>" } a video in the site's library { id, url }
video_url a YouTube or Vimeo address parsed to a provider and id; anything else refused { provider, id, embed_url, url }
url page:{id}, action:{target}, https://…, mailto:, tel:, /path or #anchor the link policy: no javascript:, data:, protocol-relative, whitespace or credentials the resolved address, or nil
page a page id of this site must be one of the site's pages a page object
gallery an id a GUID { id }
product the id of one of the business's products, or "" must be one of this organization's own products, shown on the website or not (another business's product is refused at save and at publish); the editor offers only the products marked Show on website the product as the products global shows it — nil once it is taken off the website or archived, so a block naming it shows nothing
product_list a list of ids of the business's products, or [] at most 50, each one of this organization's own products (the same once); another business's product is refused at save and at publish the products as the products global shows them, in the owner's order — one taken off the website drops out. A product named this way carries no product references of its own (its fields naming products, related, complementary), so a page can never loop
product_collection the id of one of the business's product collections, or "" must be one of this organization's own collections, published or not (another business's is refused at save and at publish); the editor offers every collection and marks the drafts the collection as the product_collections global shows it, with its products — nil while it is a draft or once it is deleted, so a section naming it shows nothing
album one of the business's album ids, or "" must be one of this organization's albums (Sites → Galleries); another business's id is refused at save and at publish the album as the albums global shows it, plus items (its photos and videos when the album is open and the page names it; never for an album with a guest code) and items_count — nil when the album has nothing published
team_member the id of one of the business's people, or "" must be one of this organization's own people (a person of another business is refused at save and at publish); the editor offers only the people switched on under HR → Employees → On the website the person as the Team app's team global shows them (name, title, bio, bio_text, initials, photo, order) — nil once they are no longer shown, so a block naming them shows nobody
business_event the id of one of the business's events, or "" must be one of this organization's own events, published or not (another business's event is refused at save and at publish); the editor offers the business's events from Operate → Events the event as the Events app's events global shows it — nil once it is over, unpublished or removed, so a block naming it shows nothing
collection a collection handle at most 120 characters the collection object
form contact, newsletter, lead, quote, booking one of the platform's forms string
business_form the id of one of the business's published forms (built on /app/forms) checked against the organization's live published forms at save and at publish; a draft, archived or another organization's form is refused string
signup_form the id of one of the business's email signup forms (built on Marketing → Forms) checked against the organization's live signup forms (switched on, not archived) at save and at publish; a switched-off, archived or another organization's form is refused string
link_list a menu's handle letters, digits, hyphens string — the handle of one of the site's menus (main, footer, or any menu the owner built under Website → Menus); read the menu as linklists[section.settings.menu]
icon an icon name one of the platform's icons string, for icon_tag
font_picker a font key one of the platform's font library (below) { key, family, stack, category }
spacing { top, right, bottom, left } each a number of pixels from −200 to 400 { top, right, bottom, left, css }
border { width, style, color } width 0–40; style none, solid, dashed, dotted, double; a colour { width, style, color, css }
radius a number 0–200 (or the declared min/max), whole number
shadow { x, y, blur, spread, opacity, color } x, y, spread −100–100; blur 0–200; opacity 0–100; a colour (default #000000) { css }
animation { entrance, trigger, easing, duration, delay, children, stagger } see below { entrance, trigger, duration, delay, attributes }
effect { effect, intensity } see below { name, intensity, attributes }
header, paragraph nothing content is required —

CSS custom properties

The platform writes several of a theme's values as custom properties, and one rule names them all: the setting id with _ written as -. A setting min_height is --min-height; a scheme colour button_text is --color-button-text. A theme reading the underscore form gets nothing.

  • Fonts. For every global font_picker the platform writes --font-{id} on :root with the family's stack: heading_font → --font-heading-font.
  • Colour schemes. For every scheme in the group the platform writes a class .color-{handle} carrying --color-{colour} for each colour and --color-{colour}-rgb as r, g, b. A section that reads section.settings.color_scheme and writes class="color-{{ section.settings.color_scheme }}" gets its palette; the layout does the same on <body>.
  • Responsive overrides. Every setting marked responsive is written as --{id} on the section's element (#ab-s-{sectionId}) or the block's ([data-ab-block="{id}"]) — the desktop value, then the tablet value under @media (max-width: 989px) and the mobile value under @media (max-width: 749px) where they differ. A number carries the setting's unit when it is px, %, rem, em, vw, vh, svh, ms, s or deg; a boolean is 1 or 0; a string reaches the stylesheet only as a plain keyword (letters, digits, -, _, #, ., at most 40 characters). The section's CSS reads var(--min-height) and never writes a media query of its own.
  • Everything else is the theme's to write in its layout's {% style %} block (after theme.css — see Liquid).

The platform also provides .ab-visually-hidden, .ab-hide-mobile (up to 749px), .ab-hide-tablet (750–989px) and .ab-hide-desktop (990px up). An owner can also hide any section or block on a device from the editor's Show on control; the platform writes it as data-ab-hide="mobile" (space-separated, from desktop, tablet, mobile) on the section wrapper and in a block's abizvo_attributes, and hides it at the same breakpoints — a theme needs nothing for it to work, as long as a block's markup prints {{ block.abizvo_attributes }}.

Colour schemes

One color_scheme_group per theme, in config/settings_schema.json:

{
  "type": "color_scheme_group", "id": "color_schemes", "label": "Colour schemes",
  "definition": [
    { "type": "color", "id": "background", "label": "Background", "default": "#ffffff" },
    { "type": "color", "id": "text", "label": "Text", "default": "#141414" },
    { "type": "color", "id": "accent", "label": "Accent", "default": "#2e5bff" },
    { "type": "color", "id": "button", "label": "Button", "default": "#141414" },
    { "type": "color", "id": "button_text", "label": "Button text", "default": "#ffffff" }
  ],
  "role": { "background": "background", "text": "text" }
}

definition is the colour settings every scheme carries; role says which is the ground and which the text, so the editor can draw a swatch and check contrast. The schemes themselves — scheme-1, scheme-2… with a name and their settings — live in settings_data.json and in each look of presets.json. A color_scheme setting on a section then picks one by handle. The header's scheme decides the page's theme-color meta tag.

Fonts

A font_picker stores one of these keys. Every family is served from the platform's own origin as one variable latin file per style (the site's page keeps font-src 'self'), preloaded upright, font-display: swap; all are SIL Open Font License families. A design's typeface that is not in this list has to be stood in for — Quire uses Fraunces for Instrument Serif.

Key Family Category
system-sans System sans-serif sans-serif
system-serif System serif serif
system-mono System monospace monospace
inter Inter sans-serif
dm-sans DM Sans sans-serif
manrope Manrope sans-serif
work-sans Work Sans sans-serif
jost Jost sans-serif
outfit Outfit sans-serif
space-grotesk Space Grotesk sans-serif
syne Syne display
playfair-display Playfair Display serif
cormorant-garamond Cormorant Garamond serif
eb-garamond EB Garamond serif
lora Lora serif
fraunces Fraunces serif
libre-baskerville Libre Baskerville serif

The animation type

An entrance the platform's motion runtime plays. The stored value is normalized to { entrance, trigger, easing, duration, delay, children, stagger }; a bare string is read as the entrance.

  • entrance: none, fade, fade-up, fade-down, fade-left, fade-right, slide-up, scale, zoom, reveal, mask-reveal, image-reveal, text-reveal, parallax, sticky-reveal.
  • trigger: enter (enters the screen, the default), load, scroll (tied to scrolling).
  • easing: smooth, gentle, snappy, linear, spring.
  • duration and delay in milliseconds, 0–3,000 (defaults 600 and 0); children: true staggers the element's children by stagger milliseconds, 0–1,000 (default 80).

The theme writes {{ section.settings.entrance | animation_attributes }} on the element. A global select of minimal, standard, expressive is the conventional way to expose a motion level in Theme settings.

The effect type

An interaction the owner picks and the platform's effects runtime plays; nobody but the platform writes the code. The value is { effect, intensity }; a bare string is read as the effect.

Key Label Group
none None —
tilt 3D tilt Hover
magnetic Magnetic Hover
spotlight Spotlight Hover
lift Lift Hover
zoom Image zoom Hover
scroll-zoom Zoom on scroll Scroll
counter Count up Scroll
sticky-stack Stacking cards Scroll
marquee Marquee Ambient
gradient Living gradient Ambient
split-words Word by word Text

Intensity is subtle (0.5), medium (1.0) or bold (1.6). The theme writes {{ section.settings.effect | effect_attributes }} — data-ab-fx and data-ab-fx-k, never an inline style, because an element may carry an entrance's style too and a browser silently drops the second style attribute. What each effect does is on Assets, motion and effects.

The date type

A calendar date as yyyy-MM-dd — what a browser's date input writes and what Liquid's date filter reads: {{ section.settings.starts | date: "%B %-d, %Y" }}. An empty string clears it; anything else is refused.