Dark-mode the document background, not just the rail, update text fonts in dark mode#6
Dark-mode the document background, not just the rail, update text fonts in dark mode#6AnnaXWang wants to merge 4 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The light/dark toggle themed the bar and rail but left the author's document (rendered in the sandboxed iframe) untouched, so picking dark left the doc area light — visibly inconsistent. Forward the toggle mode into the iframe via a new jh:themeMode message. The overlay (the only code that can touch the opaque-origin document) forces the doc's color-scheme and, with !important, its background/text so an explicit pick wins over an authored background; "auto" removes the override and restores the doc exactly as authored. The overlay re-samples after applying, so the chrome palette and dark-highlight treatment follow the document through the existing jh:theme round-trip. Per-element authored colors still cascade (we can't invert an arbitrary design) and @media(prefers-color-scheme) can't be driven from script; both are inherent and documented at the injection site. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
a0fbf0c to
0207d85
Compare
The forced-dark override set body text to #c9d1d9 (a light gray); use #ffffff so default document text is white on the dark canvas. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Setting body color white didn't work: authored element rules (p,li
{color:#1a1a1a}, th{color:#444}) beat inheritance, so most text stayed
dark. But blanket-whitening every element breaks anything with its own
light background — code chips, pill badges, callout boxes would render
white-on-light.
Walk the DOM instead: recolor the text of every element sitting on the
page background, and skip any element with its own background (or a code
block) plus its subtree — generalizing "leave code alone" to badges and
boxes too. A first pass pins each such surface's authored text color
inline (so a whitened ancestor can't leak white into a code chip that
inherits its color). Links keep their accent.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The rail/comment-card colors are derived from the doc's sampled fg. On a light doc forced dark, that fg is the authored dark text lifted only to AA — a gray, so comment text read gray, not white. When the viewer forces a theme, report the forced fg/bg from the overlay's sample so the chrome palette matches the forced document (white comment text in dark), and set the DEFAULT_DARK fallback fg to white for the pre-sample moment. Auto mode still samples the doc so the chrome adapts to genuinely-dark docs. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
| var c = kids[i], tag = c.tagName; | ||
| if (tag === "SCRIPT" || tag === "STYLE") continue; | ||
| if (isSurface(c, tag)){ | ||
| if (!c.hasAttribute("data-jh-fg-pin")){ |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e728b12. Configure here.
| + "html.jh-force-dark .jh-doc-fg{color:#fff!important}" | ||
| + "html.jh-force-light{color-scheme:light}" | ||
| + "html.jh-force-light,html.jh-force-light body{background-color:#ffffff!important}" | ||
| + "html.jh-force-light .jh-doc-fg{color:#111!important}"; |
There was a problem hiding this comment.
Forced theme skips highlight text
Medium Severity
When the viewer forces dark or light, recoloring only applies via .jh-doc-fg, but whitenPage deliberately skips span[data-jh-seg] highlight wrappers. Those spans still match authored span (or similar) color rules, so anchored comment text can stay dark on the forced-dark canvas while underlines-only highlights remain.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit e728b12. Configure here.


Summary
The light/dark toggle themed the bar and rail but left the author's document (rendered in the sandboxed iframe) untouched, so picking dark left the doc area light — visibly inconsistent.
This forwards the toggle mode into the iframe via a new
jh:themeModemessage. The overlay (the only code that can touch the opaque-origin document) forces the document'scolor-scheme+ background:dark/lightforce the doc canvas + default text (!important, so an explicit pick wins over an authored background);autoremoves the override and restores the doc exactly as authored.jh:themeround-trip — bar, rail, doc, and highlights all end up consistent.Small, presentation-only change: +9 lines in the shell (one effect), +39 in the overlay (a
jh:themeModehandler that setscolor-schemeand an injected bg/fg style). No API/DB/anchoring changes.Inherent limits (documented at the injection site)
colordeclarations are left alone.@media (prefers-color-scheme)can't be driven from script, so a doc that themes itself only via that media query won't respond to the toggle.Verification
tscclean,vitest108/108,next buildclean.autorestores the authored look.Note: this PR was scoped down to just the dark-mode document change. The earlier single-scrollbar work (and its iframe-height-ratchet fix) is preserved on the
hypeship/unify-scroll-archivebranch, out of this PR.Note
Low Risk
Presentation-only iframe DOM/CSS changes with no API or persistence impact; edge cases around authored colors and media-query-only docs are documented and intentionally limited.
Overview
The light/dark/auto control used to recolor only the shell chrome, so dark could leave the authored document in the iframe looking light. The shell now sends
jh:themeModeto the sandbox overlay whenever the viewer’s theme preference changes.Inside the overlay, forced dark or light sets
color-scheme, injects page background styles, and walks the DOM to recolor body text on the main canvas while skipping code blocks, elements with their own backgrounds, links, and highlight segments. Auto tears down those overrides. After applying,sampleThemereports forced bg/fg so rail/cards stay aligned via the existingjh:themepath, and the shell’sDEFAULT_DARKfallback foreground is white instead of gray.Reviewed by Cursor Bugbot for commit e728b12. Bugbot is set up for automated code reviews on this repo. Configure here.