Skip to content

Themes

The thematic component of every artefact keryx generates — image-prompt styles, palette, music tone, voice — is config, not code. The Python reference scripts held these as constants (STYLES, PALETTE, the portrait prompt, the voice settings); keryx lifts them into a theme catalog in config so they can be added and edited without a rebuild, and so a second brand is just a new set of themes. Generators resolve a theme by keyword and never carry hardcoded thematic values (design spec §6).

Model

A theme is a self-contained aesthetic profile identified by a keyword and tagged with a type declaring the artefact it themes. Keywords are unique within a type, so editorial can name both an article theme and a reel theme; the command's type disambiguates.

Type Drives Fields
article cover art (keryx cover) palette, prompt (style prefix), aspect
reel the 9:16 reel (keryx reel build + voice + music) palette, card (mode, scrim, fonts, illustration style), music (prompt, gain), voice (id, stability, similarity)
portrait the avatar (keryx portrait) palette, prompt

Types are open-ended — a new generator adds a new type.

Config shape (nested by type → keyword):

themes:
  defaults:            # the keyword used when --theme is omitted, per type
    article: editorial
    reel: editorial
    portrait: default
  article:
    editorial: { palette: {...}, prompt: "Editorial conceptual illustration…", aspect: "16:9" }
  reel:
    editorial:
      palette: {...}
      card:  { mode: overlay, scrim: {from: 0.52, color: charcoal}, style: "…wordless…" }
      music: { prompt: "restrained editorial bed", gain: 0.16 }
      voice: { id: MhaH9hcD2Ulcr80j28Z1, stability: 0.6, similarity: 0.92 }
  portrait:
    default: { palette: {...}, prompt: "Stylised editorial avatar…" }

Resolution

Every generator takes --theme <keyword>. When omitted it falls back to themes.defaults.<type> for the command's type. Resolution is pure and unit-tested (no I/O), so timing/wrapping/theme logic stays deterministic (R-GLOBAL-10).

Seeding

keryx init seeds the catalog with the house set, at parity with the blog Python scripts:

  • article clay, editorial (default), blueprint — the three cover-style prompt prefixes from gen-cover.py.
  • reel editorial (default), clay, blueprint — mirroring the article flavours: they share the petrol-teal / amber / cream / charcoal palette and the voice clone (MhaH9hcD2Ulcr80j28Z1, stability 0.6 / similarity 0.92) but each has its own card treatment + illustration style.
  • portrait default — the risograph avatar prompt.

The seeded palette (from gen-reel.py):

Role Hex
teal #14534F
amber #E8923B
cream #F2EAD8
charcoal #282A2C

Managing themes

Use keryx theme to list, show, add (or clone with --from), edit (--set key=value), and remove themes. Edits persist through the GTB config layer and are picked up live via config hot-reload; secrets are never written to the theme config.

Parity note

The seeded values are intended to be identical to the Python scripts. The per-card reel illustration style strings and the clay/blueprint music prompts are derived from the cover styles / spec examples (the Python scripts did not yet generate per-card imagery); they are seeds to tune via keryx theme edit, not fixed constants. See PHASE-DECISIONS-LOG.md (Phase 1a).