Skip to content

feat: IR-level design tokens + overlay re-skin (Phase 2a+2b)#90

Merged
kiyeonjeon21 merged 3 commits into
mainfrom
feat/design-tokens-ir
Jun 22, 2026
Merged

feat: IR-level design tokens + overlay re-skin (Phase 2a+2b)#90
kiyeonjeon21 merged 3 commits into
mainfrom
feat/design-tokens-ir

Conversation

@kiyeonjeon21

Copy link
Copy Markdown
Owner

Phase 2 (slices 2a+2b) of the design layer. Makes the theme a first-class IR field the compiler resolves, so a scene can be re-skinned via an overlay that survives an AI regen. The CLI --theme flag + per-brand batch + the 3-brand demo are the next PR (2c).

2a — compile-time resolution (packages/core)

  • SceneIR.design?: DeepPartial<Theme> + a token("color.accent") DSL helper that returns the deferred string "$color.accent".
  • The compiler resolves $refs against ir.design (merged onto the house brand via Phase 1's theme()), in the initialValues + pushSegment hooks every prop value flows through. evaluate/interpolate are untouched — they only ever see resolved hex.
  • Scoped to color props (fill/stroke/shadowColor), so a text content: "$5M" is never mistaken for a token (the one real collision, handled).
  • Golden-safe: no design and no $refhasDesign false → resolution never runs → byte-identical IR. The 6 golden scenes use neither and are untouched.

2b — overlay re-skin + manifest (packages/core)

  • OverlayDoc.design (dotted path → value). composeScene validates each path against the brand shape, deep-sets ir.design, and reports applied/orphan. Recompiling re-skins every token() ref.
  • Regen-stable: the address is the token's NAME, not a position, so a design.color.accent edit re-applies to any regenerated base that keeps the token; an unknown token path orphans loudly (never throws).
  • sceneManifest surfaces the patchable design.* tokens.

Demo (no CLI change — frame/render already take --overlay)

examples/scenes/themed-card.ts colors everything via token(); examples/overlays/themed-card-reskin.json patches design.color.{accent,bg,surface}. reframe frame themed-card.ts --t 1 vs … --overlay …reskin.json visibly re-skins, and reframe verify-overlay reports 3 applied, 0 orphaned.

Verification

  • pnpm test438 pass (427 + 11 new design.test.ts); the 6 golden snapshots stay byte-identical; determinism.test.ts green.
  • pnpm typecheck + pnpm lint clean.
  • Demo: base vs re-skinned frames differ; verify-overlay 3/0/0.

Next (2c)

render/frame/player --theme brand.json; theme-aware batch (design.* rows) + the 3-brand-from-one-datafile demo; scene-background tokens; numeric/type/gradient-stop tokens; teach token() in the guide/SKILL/DESIGN.md.

🤖 Generated with Claude Code

kiyeonjeon21 and others added 3 commits June 22, 2026 22:39
Phase 2a. A `token("color.accent")` ref is the deferred string "$color.accent"
on a color prop; unlike Phase 1's `brand.color.accent` (baked at author time),
the compiler resolves it against the scene's new `SceneIR.design` field (merged
onto the house brand) so the scene can be re-skinned later. Scoped to color
props (fill/stroke/shadowColor), so a text `content: "$5M"` is never touched;
evaluate/interpolate are unchanged (they only see resolved hex). Golden-safe:
no design + no token ref → `hasDesign` false → no resolution → byte-identical IR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 2b. An overlay can patch `design.color.accent` and every node that
references that token re-skins on recompile. Addressed by token NAME (validated
against the brand shape), so the re-skin survives an AI regen of the base and an
unknown token path is reported as a loud orphan, never a crash. `sceneManifest`
now surfaces the patchable `design.*` tokens. Tests cover resolution, the
"$5M" content scoping, re-skin, orphan, regen-survival, and manifest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A card whose every color is a token() ref; themed-card-reskin.json patches
design.color.{accent,bg,surface} to re-skin it with no edit to the scene.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kiyeonjeon21 kiyeonjeon21 merged commit 0294fa8 into main Jun 22, 2026
2 checks passed
@kiyeonjeon21 kiyeonjeon21 deleted the feat/design-tokens-ir branch June 22, 2026 13:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant