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_pickerthe platform writes--font-{id}on:rootwith 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}-rgbasr, g, b. A section that readssection.settings.color_schemeand writesclass="color-{{ section.settings.color_scheme }}"gets its palette; the layout does the same on<body>. - Responsive overrides. Every setting marked
responsiveis 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'sunitwhen it ispx,%,rem,em,vw,vh,svh,ms,sordeg; a boolean is1or0; a string reaches the stylesheet only as a plain keyword (letters, digits,-,_,#,., at most 40 characters). The section's CSS readsvar(--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 (aftertheme.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.durationanddelayin milliseconds, 0–3,000 (defaults 600 and 0);children: truestaggers the element's children bystaggermilliseconds, 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.