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; add sequenceOutline: true for 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:

  • palettelight and dark, each {accent, background, text} as #RRGGBB hex. 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.pairingserif (Literata prose, Atkinson UI — the default), sans (Atkinson everywhere), editorial (Literata everywhere). Fonts are self-hosted; there are no external font requests.
  • type.scalecompact, regular, or display (bigger headlines).
  • textureradius (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.