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 fromgen-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).