Theming
Layouts, card facts, field groups, click-through, and page chrome.
The theme is a document too: per-route layouts and per-entity-type presentation. It never contains free-form markup — every key is a closed enum or a field/route reference, validated against your schema.
Layouts (per route)
cards, list, masonry, table, feed, compact, magazine. The same items render correctly in any of them; pick the one the content deserves — dense link rows (compact), an editorial front page (magazine), a photo wall (masonry), a data table (table, which folds grouped queries into one aligned table).
Per-entity-type keys
cardFields— up to four field slugs rendered as a facts line on cards ("$260 · Excellent"; "Sep 15, 09:00 · Aurora Hall"). The difference between a picture wall and a shop.fieldGroups— the facts panel as labeled sections (a spec sheet).heroImageField/cardImageField— which asset field leads.clickThrough: "external"— cards link straight out to the external URL (link-board behavior) instead of the entity page.pageChrome: "plain"— suppresses the type eyebrow and facts panel: the About-page anatomy.primaryRelationship— promotes one relationship group to the page's main content (a board page IS its pins).sequenceRoute— previous/next links following a list route's order; addsequenceOutline: truefor a persistent table-of-contents sidebar (the anatomy of the page you are reading).
Design tokens (design)
The site's whole look, from the same theme document:
palette—lightanddark, each{accent, background, text}as#RRGGBBhex. All six colors together, or none: there is no partial palette. Every minor tone (borders, muted ink, soft accent, the favicon dot) derives automatically. Contrast is validated as a blocker — text on background must reach WCAG AA 4.5:1 and accent 3:1, in both modes; the error tells you the computed ratio.type.pairing—serif(Literata prose, Atkinson UI — the default),sans(Atkinson everywhere),editorial(Literata everywhere). Fonts are self-hosted; there are no external font requests.type.scale—compact,regular, ordisplay(bigger headlines).texture—radius(sharp/soft/round),rules(hairline/strong/none— the weight of every hairline border),density(compact/regular/airy— the page's structural rhythm).
Some starting looks to copy into design and tweak (omit design entirely for the default, Oxblood Deep):
- Botanist —
{"palette": {"light": {"accent": "#0F5E4C", "background": "#F7F8F6", "text": "#17211E"}, "dark": {"accent": "#7FB4A2", "background": "#101418", "text": "#E8ECEF"}}} - Broadsheet —
{"palette": {"light": {"accent": "#1A3A6B", "background": "#FAF7F0", "text": "#191714"}, "dark": {"accent": "#9DB8E3", "background": "#14161B", "text": "#EAE7E0"}}, "type": {"pairing": "editorial", "scale": "display"}, "texture": {"rules": "strong"}} - Gallery —
{"palette": {"light": {"accent": "#B3352C", "background": "#FCFCFC", "text": "#1C1C1C"}, "dark": {"accent": "#E88C7D", "background": "#171717", "text": "#EDEDED"}}, "type": {"pairing": "sans"}, "texture": {"density": "airy", "radius": "sharp", "rules": "none"}}
Custom CSS (customCss)
When the tokens are not enough: a customCss string in the same document (up to 64 KB), layered after the platform stylesheet. The platform's CSS custom properties (--r-accent, --r-bg, --r-text, --r-font, --r-radius, and friends) are stable hooks. Aesthetics at this rung are yours; mechanical correctness is not negotiable either way — the data API, feeds, page structure, escaping, and the sub-footer survive any skin, and deleting customCss restores a working site by construction. Like every theme change, it is versioned and one undo from repair.