Settings
Theme settings
config/settings_schema.json defines the theme-wide settings shown under Theme settings in the editor, in groups:
[
{
"name": "Colors",
"settings": [
{ "type": "color", "id": "color_primary", "label": "Primary", "default": "#0f172a", "info": "Buttons, links and highlights." },
{ "type": "color", "id": "color_accent", "label": "Secondary", "default": "#2563eb" }
]
}
]
Their values live in config/settings_data.json and are read as settings.<id> everywhere:
{ "current": { "color_primary": "#0f172a", "color_accent": "#2563eb" } }
current may instead name one of a set of presets ({ "current": "Bold", "presets": { "Bold": { … } } }).
Brand colours. When a theme is published, its colours are saved as the firm's brand colours:
color_primaryandcolor_accentsettings if the theme has them, otherwise the page colour scheme'sbuttonandaccentcolours (Counsel's convention: acolor_schemesetting with the idpage_color_scheme,scheme-1if there's none).
Section and block settings
The same setting types go in a section's or block's settings, and are read as section.settings.<id> or block.settings.<id>.
Platform settings: animations and motion
The platform adds animation settings to every theme, so firms can animate any theme's sections without the theme declaring anything. You don't add them to your schemas; the editor, validation and Liquid all see them as if you had.
On every section (at the end of its settings, under an Animation heading):
| Id | Type | Values |
|---|---|---|
animation |
select |
none (default), fade, fade-up, zoom-in, slide-start, slide-end |
animation_stagger |
checkbox |
false (default). When on, the section hands its effect to its blocks and items instead of animating itself. |
On every block: animation, with the same values.
In theme settings (a Motion group after your own groups):
| Id | Type | Values |
|---|---|---|
motion |
select |
off, subtle (default), expressive |
page_transitions |
checkbox |
true (default): cross-document view transitions between pages |
Read them like any other setting (section.settings.animation, block.settings.animation, settings.motion). You rarely need to, though: the platform puts the effect on the markup and plays it for you (see Motion and animations).
Opting out. Add "animations": false to a section's schema (it also covers that section's blocks) or to one block's schema, for things that shouldn't move: headers, footers, sticky bars. If your schema already defines a setting with the id animation (or your theme settings one with the id motion), the platform leaves that schema alone and your setting wins.
{
"name": "Header",
"animations": false,
"settings": [ … ]
}
Setting types
Every setting has a type, an id (lowercase letters, digits and _, unique within its schema), a label, and optionally default and info (help text, shown in a tooltip beside the label in the theme editor; under the switch for a checkbox).
| Type | Value in Liquid | Extra keys |
|---|---|---|
text |
string | |
textarea |
string (multi-line) | |
richtext |
HTML (sanitised): output it without escape |
|
inline_richtext |
HTML without paragraphs | |
url |
a link string (/contact, https://…, #faq, mailto:…, tel:…): the firm picks a site page, the practice areas (all, a practice group or an area), the blog (the blog, a category or an article), the client portal's sign-in or a custom link. A link to a draft or deleted page, to a practice group or area that isn't public, to an article that isn't live, to the blog on a plan without it, or to sign-in while the firm's portal is off gives a blank value, so add a fallback with default. The firm's pages are stored as site://page/{id}, practice groups as site://practice/{id}, areas as site://area/{id}, blog categories as site://blog/{id} and articles as site://article/{id}; a schema default can also name site://practice/all or site://blog/all; a schema default can name site://page/home, site://page/contact (the firm's contact page), site://auth/signin (site://auth/signup still works and also means sign in: there is no public sign-up) |
|
video_url |
a URL; video_embed_url turns YouTube and Vimeo links into a player URL |
|
image_picker |
an image URL (the firm uploads it in the editor) | |
color |
#rgb, #rrggbb or #rrggbbaa |
|
font_picker |
a font: use with font_face and font_family |
|
select, radio |
the chosen value | options: [{ "value", "label" }] |
checkbox |
true / false |
|
range |
a number | min, max, step, unit |
number |
a number | min, max |
link_list |
a linklist object (a menu), or nil when the firm picked none. default is a menu handle, e.g. main-menu or footer |
|
color_scheme_group |
a list of color scheme objects (theme settings only, once per theme) |
definition |
color_scheme |
the chosen color scheme object; prints as its id |
|
header |
(none): a heading in the editor | content |
paragraph |
(none): explanatory text in the editor | content |
Colour schemes
A colour scheme is a named set of colours (background, text, button…) that a section picks as a whole, so its text stays readable whatever its background. Define the colours every scheme has once, with a color_scheme_group in config/settings_schema.json:
{
"type": "color_scheme_group",
"id": "color_schemes",
"definition": [
{ "type": "color", "id": "background", "label": "Background", "default": "#ffffff" },
{ "type": "header", "content": "Text" },
{ "type": "color", "id": "text", "label": "Text", "default": "#0f172a" },
{ "type": "color", "id": "eyebrow", "label": "Eyebrow", "default": "#2563eb" }
]
}
The schemes themselves are values in config/settings_data.json, keyed scheme-<letters or digits>. Firms can edit, add (up to 12) and delete them in the editor:
"color_schemes": {
"scheme-1": { "settings": { "background": "#ffffff", "text": "#0f172a", "eyebrow": "#2563eb" } },
"scheme-2": { "settings": { "background": "#0f172a", "text": "#e2e8f0", "eyebrow": "#93c5fd" } }
}
Sections and blocks then pick one with a color_scheme setting, which the editor shows as swatches:
{ "type": "color_scheme", "id": "color_scheme", "label": "Color scheme", "default": "scheme-1" }
Print one CSS rule per scheme that re-declares your colour variables, and put the class on the section's element. Everything inside that reads the variables then follows the scheme:
{%- for scheme in settings.color_schemes %}
.color-{{ scheme.id }} {
--theme-canvas: {{ scheme.settings.background }};
--theme-ink: {{ scheme.settings.text }};
--theme-eyebrow: {{ scheme.settings.eyebrow }};
}
{%- endfor %}
<div class="color-{{ section.settings.color_scheme }}" style="background: var(--theme-canvas); color: var(--theme-ink)">…</div>
If a section's scheme has since been deleted, section.settings.color_scheme falls back to the setting's default, then to the first scheme. Colours a scheme leaves out take the definition's defaults.
Colours, fonts and spacing in CSS
Settings reach your stylesheet as CSS variables. The starter kit's snippets/css-variables.liquid prints them in the page <head>: the fonts, sizes and spacing on :root, and the colours once per colour scheme (the page's scheme on :root too). A shortened version:
<style>
:root {
--theme-font-heading: {{ settings.heading_font | font_family }};
--theme-radius: {{ settings.corner_radius }}px;
}
{%- for scheme in settings.color_schemes %}
{% if scheme.id == settings.page_color_scheme.id %}:root, {% endif %}.color-{{ scheme.id }} {
--theme-brand: {{ scheme.settings.button }};
--theme-brand-2-ink: {{ scheme.settings.accent | color_readable }};
}
{%- endfor %}
</style>
color_readable picks a dark or white text colour that reads well on the given colour. See Styling for how the stylesheet uses these variables.
Load the chosen fonts in your layout's <head>:
{{ settings.heading_font | font_face }}
{%- if settings.body_font.key != settings.heading_font.key %}{{ settings.body_font | font_face }}{% endif %}
font_picker offers a fixed set of fonts that the platform hosts. External font services can't be loaded (see JavaScript and security). To use another font, put its .woff2 files in assets/ and declare it with @font-face in your CSS.
Custom CSS
Counsel has a Custom CSS setting (custom_css) that the layout prints after the theme's stylesheet. Keep it in your theme if firms should be able to add their own CSS.
Still need help?
Send a request to the Mattersimple team and we'll reply by email.