0036 — Studio theme editor (rgba palette + full type-scoped theme controls)¶
Status: IN PROGRESS — from Matt's 2026-07-23 studio driving notes (0029 §9).
D1 + D2 resolved with Matt 2026-07-23: canonical form #RRGGBBAA, alpha
everywhere the renderer composites (gg's SetHexColor natively parses hex8; an
all-opaque palette renders identically). D3 resolved 2026-07-23: fonts are a
picker (datalist, free-text escape) over GET /fonts — the system DejaVu family
(bare names) + project fonts in assets/fonts/*.ttf|otf (project-relative
paths, which the renderer's resolveFont passes through verbatim — "brand fonts"
work today by dropping files there). Follow-up (Matt): a studio upload
manager to load fonts INTO the project (persisted with it), so brand fonts don't
require filesystem access. D4 (script-definition editability) still open.
Date: 2026-07-23
Relates: 0006 (avatar theme — the theme model this edits), 0034 (project settings —
the ThemesManager this replaces/extends), 0035 (config writes — themes persist via
Store.Apply), 0001 §6 (themes are config-driven).
1. Problem¶
The 0034 ThemesManager exposes only the palette, edited as HTML hex strings behind a
browser-default colour input — "an incomplete and confusing UI" (Matt). A theme is much
more than a palette (the blog's reel/blueprint: card.{font_bold,font_mono,mode,scrim,
style} · music.{gain,prompt} · palette · voice.{id,stability,similarity}), and the
editable surface should scope to what the theme's type actually uses.
2. Goals¶
- A proper colour picker — a real wheel/area picker (HSV area + hue slider), not the native swatch; palette entries displayed as named swatches.
- rgba, not hex — the palette gains an alpha channel. Intent (Matt, confirmed):
transparency is a designed axis, most immediately for scrims/overlays (e.g.
card.scrim.color+fromtoday approximates what an rgba scrim colour expresses directly). Storage moves from#RRGGBBto rgba-capable form. - Full theme controls, type-scoped — beyond palette: fonts (card.font_bold/mono),
style prompt (card.style), script definition (mode/scrim/accent conventions),
music (prompt · gain), voice (id · stability · similarity), each shown only for
the theme types that carry them (
reel= all;article/portrait= prompt+palette…).
3. Design sketch¶
- Colour model. Palette values accept
#RRGGBB(back-compat) and#RRGGBBAA/rgba(r,g,b,a). Canonical storage:#RRGGBBAA(compact, YAML-friendly, sorts stably); alphaFFmay serialise as#RRGGBBfor parity with existing themes. - Renderer impact.
internal/gen/reel(fogleman/gg + ffmpeg pipeline) must parse the extended form and honour alpha where compositing supports it (text fills, scrims, blocks). Parity guard: an all-opaque palette renders identically to today. - Editor layout. Per-theme accordion of sections (Palette · Fonts · Style prompt · Script · Music · Voice), each section present iff the type schema includes it. Raw-JSON "Advanced" per theme stays (0034 Q1) as the escape hatch.
- Persistence. Through the existing themes CRUD → project
Store.Apply(0035); targeted per-theme writes remain the deferred nicety.
4. Open questions (for review)¶
- D1:
#RRGGBBAAvsrgba()string as the canonical stored form? (Rec:#RRGGBBAA.) - D2: does alpha extend to every palette use (text/bg fills) or only compositing surfaces (scrim, overlay tints) in v1? (Rec: everywhere the renderer composites; the parity guard keeps opaque behaviour unchanged.)
- D3: font control = free-text font name, or a picker over fonts discovered in the assets/embedded set?
- D4: is "script definition" (mode/scrim conventions) editable v1 or read-only surfaced?
5. Non-goals¶
- New theme types; theme inheritance; per-card palette overrides (0038 territory).