--- name: remotion-svg-colors description: How FlatRender makes template colors user-editable and generates per-scene SVG so the studio can recolor a template and preview it in real time. Use when wiring a template's colors to the studio color picker, choosing which elements are recolorable, or generating an SVG color-preview for a scene. --- # SVG + color system (real-time recolor) Goal: a user opens a template, changes its colors, and sees the result update live. This works because every colorable element reads from a NAMED color, those names are stored as editable color elements in the DB, and a lightweight SVG representation lets the studio recolor without a full re-render. ## The color data model - **`content.shared_colors`** — project-wide colors (key = `element_key`, e.g. `accentColor`). Used by every scene. - **`content.scene_color_elements`** — per-scene colors (key = `element_key`, e.g. `frl_c1t1` for AE, or a Remotion prop name). - Studio copies these into `studio.saved_shared_colors` / `saved_scene_colors`; the render binder (`GetRenderBindings` in render-svc) returns them as `{element_key: hex}`. - For **Remotion**, those keys must equal the composition's `colorSchema` props: `accentColor`, `secondaryColor`, `backgroundColor`, `textColor` (from `src/lib/branding.ts`). The node-agent passes them as `--props`. - For **AE**, colours bind into the `frshare` comp's text layers (`bind.jsx`). **Rule:** design every template so EVERY colorable element's color comes from a named prop — never a hardcoded hex for anything the user should be able to change. Seed a `shared_colors` row per color prop (the seed script already does accent/secondary/background/text). ## The SVG color-preview (live recolor without re-rendering) A full Remotion/AE re-render is too slow for a color picker. So a scene is also represented as an **SVG** whose shapes' `fill`/`stroke` reference the SAME color keys. The studio swaps the SVG's colors instantly as the user drags the picker. - AE pipeline: `content.projects.shared_colors_svg` + the `template_svg_previews` table + per-scene snapshots. - For a Remotion template, generate an SVG snapshot of a representative frame where colorable regions are tagged with their key, e.g.: ```svg ... ``` The studio sets CSS variables (`--accentColor: #...`) or rewrites `fill` by `data-color-key` to recolor live; on export the real props go to the renderer. ## How to author a recolorable template 1. Use the 4 `colorSchema` props for all themeable color (add more named props only if a template genuinely needs them — and seed a matching `shared_colors` row for each). 2. Keep colorable regions as FLAT fills/strokes that map cleanly to one key (gradients = blend of two named props via `mixHex`, still derived from props). 3. Produce an SVG preview of the key frame with each region tagged `data-color-key` = the prop name, so the studio can map picker → region. 4. Verify: changing a prop changes exactly the intended regions and nothing hardcoded stays the wrong color. ## Generating the SVG - Simple/flat scenes: hand-author or script an SVG mirroring the composition's shapes, tagging fills with the color keys. - 3D / complex scenes: an SVG can't represent them faithfully — fall back to a rendered key-frame thumbnail per color theme, or a simplified 2D SVG stand-in for the picker (note this limitation to the user). - Store alongside the template (the AE path uses `shared_colors_svg` / `template_svg_previews`; mirror that for Remotion). ## Pitfalls - A hardcoded hex on a "should-be-editable" element = the picker silently does nothing there. Audit for stray hexes. - Key mismatch (SVG `data-color-key` ≠ schema prop ≠ seeded `element_key`) breaks the binding — keep ONE naming source of truth. - Contrast: when users can recolor text + background, enforce/encourage a min contrast or the text can vanish. Related: `../remotion-template-composition/SKILL.md`, `../remotion-design-styles/SKILL.md`.