fix(ui): use runtime :root color vars in shimmer gradient - #434
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes the chat Shimmer text gradient by replacing references to Tailwind v4 @theme inline variables (--color-*, not available as runtime custom properties) with coss-ui’s runtime :root/.dark CSS variables (--background, --muted-foreground), ensuring the background-image computes correctly in both themes.
Changes:
- Update
Shimmer’sbackgroundImageto usevar(--background)andvar(--muted-foreground)so the gradient no longer resolves tononeat computed-value time. - Add an inline comment documenting why
--color-*variables are not safe to use at runtime.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
ℹ️ The fix is correct and I verified the premise independently. One comment-accuracy nit inline, plus a stacking question below.
Reviewed changes — the single commit 8f7e4fb0, one file.
- Shimmer gradient reads the
:rootvars —packages/presentation/ui/src/chat/shimmer.tsxswapsvar(--color-background)/var(--color-muted-foreground)forvar(--background)/var(--muted-foreground)in the inlinestyle.backgroundImage, and adds a one-line trap comment.
I confirmed the premise rather than taking it on faith, by compiling Tailwind 4.3.3 through its compile() API against a minimal repro of coss-ui's @theme inline block. The A/B was decisive: with no candidates the alias is not emitted; with a bg-muted utility candidate it is still not emitted (the value is inlined); only an arbitrary-value candidate like [background:var(--color-muted)] forces it into :root. A var(--color-*) written inside a JS inline style string is never a scanned candidate, so nothing forced --color-background to be emitted — the declaration was invalid at computed-value time and background-image fell back to none.
Worth recording that the blast radius was larger than "rendered with no colors": because the component itself sets bg-clip-text text-transparent, a background-image of none leaves nothing to clip, so every in-progress label was fully invisible — tool.tsx:85, reasoning.tsx:92, activity-run.tsx:131,138, compaction-marker.tsx:42, terminal.tsx:46 all sit behind an isStreaming ? <Shimmer>x</Shimmer> : x ternary, so the text vanished while running and popped in on completion. Only the reduceMotion early-return branch was spared.
I also reproduced the sweep: var(--color- has no remaining non-vendor hits. The packages/vendor/coss-ui hits are correctly out of scope — --color-white / --color-zinc-* come from Tailwind's non-inline default @theme and are emitted normally, and skeleton.tsx:14's arbitrary value does force emission.
ℹ️ A standalone user-visible fix is gated behind an unmerged branch
The base is ruocheng/code-525, not master, and master still carries the broken string. Every streaming label in chat is invisible until this lands, so stacking it behind an unrelated agent-adapter branch delays a fix that has no dependency on that work.
Technical details
# Shimmer fix is stacked behind `ruocheng/code-525`
## Affected sites
- PR base ref — `ruocheng/code-525` (`a730f54f`), whose recent commits are opencode/MCP
agent-adapter work unrelated to the shimmer gradient.
- `packages/presentation/ui/src/chat/shimmer.tsx` on `origin/master` — still has
`var(--color-background)` / `var(--color-muted-foreground)`.
## Required outcome
- A conscious decision about whether this one-line fix should reach `master` on its own
schedule rather than inheriting the parent branch's merge timeline.
## Open questions for the human
- Does this change actually depend on anything in `ruocheng/code-525`? If not, retargeting
the base to `master` makes it mergeable immediately.
- If the stack is intentional (e.g. CODE-575 is scoped as a follow-up to CODE-525), no
action needed — this is purely a sequencing observation.Claude Opus | 𝕏
lucas77778
left a comment
There was a problem hiding this comment.
No blocking findings. Independently verified the Tailwind 4.3.3 behavior: @theme inline utilities inline var(--background) / var(--muted-foreground) and do not emit the corresponding --color-* runtime declarations for this JS inline-style usage. Also confirmed coss-ui defines both replacement variables in :root and .dark, and both renderer entries import the shared stylesheet.
Checked the complete one-commit diff, all Shimmer call sites, reduced-motion behavior, applicable repository/frontend guidance, and current CI results. git diff --check is clean and all required GitHub checks are green. The non-master base affects sequencing only; it does not introduce a correctness dependency in this change.
8f7e4fb to
612f5c6
Compare
There was a problem hiding this comment.
✅ No new issues found. The one finding from the previous review is fixed, and the gradient line itself is unchanged from the version I already verified.
Reviewed changes — the delta from 8f7e4fb0 to 612f5c66: a rebase onto a newer ruocheng/code-525 plus a reword of the trap comment. The backgroundImage string is byte-identical to the previously reviewed version.
- Trap comment now states the real invariant —
packages/presentation/ui/src/chat/shimmer.tsx:30-31replaces "--color-*are @theme-inline-only (no runtime custom properties)" with wording scoped to coss-ui's semantic@theme inlinealiases, naming the actual rule: Tailwind never scans a JS style string, so nothing forces those aliases onto:root. That distinguishes "not emitted here" from "never exists", which is what the old wording got wrong for Tailwind's non-inline default palette and for@theme inlinealiases referenced by a scanned candidate.
One note on reading this delta, since it will matter again if the branch is rebased: git diff-tree 8f7e4fb0 612f5c66 returns roughly ten files (codex MCP slug extraction, opencode config-read catch, command-echo gating, tool-search headers). All of it is ruocheng/code-525 drift absorbed by the rebase, not work authored on this branch — the merge-base diff is still the single shimmer.tsx file, and that is what I reviewed.
The sequencing observation from the previous review stands unchanged and needs no action here: the base is still ruocheng/code-525 and master still carries the broken string, so every in-progress chat label stays invisible until the parent branch merges. Whether that is worth retargeting is the author's call, not a defect in this diff.
Claude Opus | 𝕏
|
On sequencing: keeping the stack — the branch was cut on top of code-525's tree and the stack merges bottom-up, so this lands with its parents rather than retargeting master. |
612f5c6 to
bc57dbe
Compare
bc57dbe to
3ed2768
Compare

Summary
The chat
Shimmergradient referencedvar(--color-background)/var(--color-muted-foreground)— Tailwind v4@theme inlinenames that never exist as runtime custom properties, so the wholebackground-imagewas invalid at computed-value time and the shimmer silently rendered with no colors in both themes. Switch to the:root/.darkvars coss-ui actually defines (--background,--muted-foreground), matching the existingcolor-mix(in oklab, var(--foreground) …)pattern inpackages/presentation/ui/src/styles.css.Swept
packages/presentation/ui,packages/client/workbench, and both app renderers for othervar(--color-*)usages — this was the only one.Closes CODE-575
Verification
dev:mockwebview, on a liveShimmer("Running a command" during the showcase's streaming playback): computedbackground-imageresolves to a white sweep over a muted-gray fill in light, and a near-black sweep over a lighter muted fill with thedarkclass toggled. Before the fix the computed value wasnone.pnpm format:check,pnpm lint,pnpm typecheckclean;vitest run2722 passed. The singlegit-mutations.test.tsfailure is the signing-machine environment (productiongit commitpath hits headless gpg pinentry) — the file passes 5/5 withGIT_CONFIG_GLOBAL=/dev/null.Checklist
pnpm check:ciandpnpm testboth pass (pluscargo fmt/clippy/testfor Rust changes)WIRE_PROTOCOL_VERSIONis bumped