openpencil/apps/web
Fini 0bbdb0bf35 fix(ai): button contrast resolves \$color refs via built-in semantic palette
Codex flagged the previous fix (1c08ac3f, "skip on unresolved ref")
as too conservative: a sub-agent's button with `\$color-accent` bg
and a text child WITHOUT a fill ended up with no fill at all when
doc.variables hadn't been seeded yet — text falls back to black,
which is invisible on a dark accent button.

Better fix: extend `resolveColorMaybeRef` with a step-2 fallback
into the built-in semantic palette (`getSemanticPaletteHex`). Every
core token (`color-accent`, `color-bg`, `color-text-primary`, etc.)
has a known hex for both `Light` and `Dark` modes, so the cascade
now is:
  1. Doc-seeded variables (user's palette).
  2. Built-in semantic palette for the requested mode.
  3. Original ref string (unresolvable) — caller bails.

In the food-app + GPT-5.5 path, step 1 already worked because
`seedDocVariablesFromStyleGuide` runs before the sub-agents.
The fallback is for paths that bypass seeding (test fixtures,
external MCP callers, mid-flight states), not the common case.

Skip-on-NaN behavior stays — it now only triggers for genuinely
unknown tokens (`\$color-foobar` or similar), where any guess is
worse than leaving the model's existing fill alone.

Tests:
- New: `\$color-accent` ref resolves to #2563EB via semantic palette
  even with no doc.variables, contrast pass picks white fg correctly
  for the unfilled text child.
- New: `\$color-mystery-token` (not in palette) — step-2 misses,
  contrast pass skips, existing text fill survives.
- Replaces the prior "skips on unresolved" test which over-asserted
  the conservative path.
2026-05-05 12:22:49 +08:00
..
public V0.5.0 (#67) 2026-03-22 09:44:04 +08:00
server fix(ai): image-search retries with 2-keyword query when 3-keyword returns 0 2026-05-05 12:22:44 +08:00
src fix(ai): button contrast resolves \$color refs via built-in semantic palette 2026-05-05 12:22:49 +08:00
CLAUDE.md V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
components.json V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
dev.ts V0.7.2-bugfix (#109) 2026-04-14 21:42:56 +08:00
package.json fix(ai): proxy dispatcher uses ESM import, actually installs in dev path 2026-05-05 12:22:40 +08:00
tsconfig.json V0.7.2-bugfix (#109) 2026-04-14 21:42:56 +08:00
vite.config.ts Merge origin/v0.8.0 into feat/rust-ification 2026-05-03 21:00:00 +08:00