Skip to content

Pin color-scheme on rich-part surface frames (fix white canvas in dark mode)#191

Merged
benvinegar merged 2 commits into
mainfrom
fix/rich-part-colorscheme
Jun 30, 2026
Merged

Pin color-scheme on rich-part surface frames (fix white canvas in dark mode)#191
benvinegar merged 2 commits into
mainfrom
fix/rich-part-colorscheme

Conversation

@benvinegar

Copy link
Copy Markdown
Member

Problem

A markdown (or code/diff/mermaid) surface renders as a near-blank white box with washed-out text on a dark board:

Take 3 — code review. posts a diff surface; pin comments to lines like a PR.

…rendered as faint light-gray text on solid white, inside an otherwise-dark card.

Root cause

Rich-part surfaces (renderSandboxedPart, renderMermaidPage) are sandboxed, opaque-origin iframes loaded by URL. Such a frame defaults to color-scheme: normal (i.e. light). Its body is background: transparent — the design intends the dark card to show through — but with a light color-scheme the UA paints the iframe canvas white, and the dark-mode text (--text: #e6edf3) washes out over it.

A comment in renderSandboxedPart explicitly omitted color-scheme, reasoning that forcing it "would paint an opaque UA canvas." That's backwards: omitting it is what leaves the canvas light/white; html surfaces (renderHtmlPage) already pin it via colorSchemeCss(mode) and render correctly.

Verified by reproduction (Playwright, real engine + cloud embed, dark mode): the markdown frame's computed values are all "dark + transparent," yet it visibly paints white — and adding colorSchemeCss(doc.mode) makes it render correctly and seamlessly against the card.

before after
white box, faint text transparent, readable on the dark card

Change

  • renderSandboxedPart and renderMermaidPage now emit colorSchemeCss(doc.mode) — the exact pin html surfaces already use — so the UA canvas tracks the resolved scheme (dark→dark, light→light). No mode → left to the OS, unchanged.
  • Corrected the misleading comment.
  • Updated the regression test: it previously asserted the buggy "rich frame must NOT force color-scheme"; it now asserts the pin (dark→:root{color-scheme:dark}, light→light, no-mode→unpinned).

Tests

npm test (400), npm run typecheck, npm run lint, npm run format:check all green.

🤖 Generated with Claude Code

benvinegar and others added 2 commits June 30, 2026 18:43
…n dark mode)

markdown/code/diff/mermaid surfaces render in sandboxed, opaque-origin
iframes. Those default to `color-scheme: normal` (light), so in dark mode
the UA painted a WHITE canvas behind the transparent body and the
dark-mode text (--text) washed out over it — a markdown caption looked
like a near-blank white box on a dark board.

renderSandboxedPart/renderMermaidPage now emit colorSchemeCss(mode), the
same pin html surfaces already use, so the frame's UA canvas tracks the
card in both schemes. A prior comment claimed omitting the property kept
the frame transparent; it doesn't — it just leaves the canvas light. That
note is corrected, and the regression test now asserts the pin (it
previously asserted the buggy "must NOT force color-scheme").

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…g the bug)

The e2e theme spec encoded the old buggy behavior — that a transparent
markdown frame keeps no forced color-scheme. With the canvas now pinned to
the resolved scheme, it must be `dark` in dark mode. Invert the assertion
and its comment to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@benvinegar benvinegar merged commit 46cf918 into main Jun 30, 2026
9 checks passed
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