Role for AI agents
Role: Designer
Make a theme that draws every page type from the structure and does not break on incomplete content. Shared rules are on the page Instructions for AI agents.
How a theme works, in plain words, is in the guide Theme and design.
In plain words
The designer makes the clothes of the site: the theme. It works only in the theme/ folder and never writes texts of pages there. A good theme looks right with a full page and with a half-empty one, because a missing block should simply not appear.
Example. The structure says pages of type «service» have the sections intro, prices and faq. The designer makes a template for «service», makes sure a table module draws prices and an accordion draws faq, and checks a service page without prices: the page still looks finished.
You need this page when you hand the design to an agent such as Claude Design or to a person. To see every block form the theme must draw, open the forms reference.
Input and output
Input: page types and their sections from the architect (or an existing theme.yaml), a mockup or a description of the look.
Output: the theme/ folder: theme.yaml, base.html, type templates, form modules, partials/, assets/, interface string files in i18n/ for every language.
1. Start from the starter theme
heron new writes a working theme: the types home, page, 404 and the modules breadcrumbs, cards, facts, faq, list, prose, steps. It builds from the first minute: change it step by step and build after each step.
2. theme.yaml
Sample: templates/theme.yaml; every key: the contract, theme.yaml.
types:
home: {uses: [intro, "why:list", "how:steps", "faq:faq"], jsonld: [WebSite]}
category: {uses: [intro]}
service: {uses: [intro, "includes:list", "how:steps", "faq:faq"], jsonld: [Service]}
article: {uses: [intro, "*"], jsonld: [Article]}
page: {uses: [intro, "*"]}
"404": {uses: [intro]}
links:
- {field: related, type: service, back: related_from}
images:
ratios: ["1:1", "16:9"]
uses: all sections of the type, optional ones included; after the colon, the expected form (forms table)."*"means any sections. Fromuses,heron pagewrites placeholders and the report names empty sections;jsonld: the structured data types for pages of this type;requires: paths insite.yamlthe theme cannot work without (E011if empty);links: link fields;backbuilds the reverse list.
3. Type templates
One template per type, templates/TYPE.html (otherwise E008):
{% extends "base.html" %}
{% block content %}
{{ mod.breadcrumbs() }}
{# the heading: page.h1 inside an h1 tag #}
{{ mod.list('includes') }}
{{ mod.steps('how') }}
{{ mod.faq('faq') }}
{% for p in page.related.get('related', []) %}
{# a link to p.url with the text p.h1 #}
{% endfor %}
{% endblock %}
mod.MODULE('ANCHOR')draws the section, or nothing if it is missing: no conditions needed around it;page_of('KEY')is a page by its key;data.FILEis reference data;site.*issite.yamlin the page's language;t.*are interface strings;- paths in
extends/include/importstart from the theme root:{% extends "templates/page.html" %}, not"page.html"; - your own macros are imported in every template: an import in
base.htmlis not visible to child templates.modneeds no import; - your own page fields:
page.meta.get('topic'), no declaration needed; do not list them infields(E023); site.*is already in the page's language in every block:site.contact.addresson a Russian page isaddress_ru, no need to pick the language by hand;- the full list of variables: build, §7; the page model: build, §6.
4. Modules
One module per form the theme draws: modules/NAME.html. Inside: section (the section with title, kind, lead, note, callout), items (the parsed data of the form), html (the ready content). What items holds for each form: the forms table (§4.4).
5. Images and assets
- only
picture(src, ratio, alt=…): sizes, WebP/AVIF, dimensions; building a picture tag by hand means losing the variants; - the ratios you use go into
images.ratios; - CSS, JS, fonts in
theme/assets/; favicon and.well-knownin the site'sstatic/.
6. Interface strings
Everything that belongs to the theme rather than the page ("Read more", "Questions and answers") goes into theme/i18n/en.yaml and the same file for other languages; in a template it is t.KEY. One file per site language; init writes a blank one. The keys on, off, yes, no go in quotes.
7. What a theme does not do
- it holds no content texts and no site details: texts live in sections, phone and address in
site.contact.*; - it does not load content with a script: text and numbers must be in the HTML;
- it does not show the build stamp in production:
{% if not env.is_prod %}{{ env.stamp }}{% endif %}; - it outputs counters only when
env.analyticsis set.
Checklist
- every type in the structure has an entry in
typesand a template - every form in
useshas a module - the build passes on the starter content and on the full content
- templates hold no texts or company details; interface strings go through
t - the report lists no missing
i18nstrings and no template errors - images go through
picture(); ratios are declared
Source
This page mirrors docs/agents/designer.md from the prod branch. The repository is updated first: designer.md on GitHub. The original is written in Russian.