Skip to content

Add viewer theme toggle + fix washed-out dark-mode comment highlights#4

Merged
AnnaXWang merged 1 commit into
mainfrom
hypeship/theme-toggle-dark-highlight
Jul 1, 2026
Merged

Add viewer theme toggle + fix washed-out dark-mode comment highlights#4
AnnaXWang merged 1 commit into
mainfrom
hypeship/theme-toggle-dark-highlight

Conversation

@AnnaXWang

@AnnaXWang AnnaXWang commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Makes comments render correctly across light and dark documents. Three fixes:

1. Light/dark/auto theme toggle (saved). The viewer chrome had no theme control — it was inferred from the document's background and never selectable (CommentsShell hardcoded mode = "auto"). Adds a ☀ / ☾ / ◐(auto) segmented control to the chrome bar, persisted per viewer in localStorage (global preference), driving the chrome palette via an effectiveTheme. Default stays auto, so light docs are byte-identical to before.

2. Dark-mode highlight legibility. The dark highlight was rgba(241,196,15,.16) — a 16% wash invisible on a dark page. Strengthened to a readable amber wash (.30–.54 by overlap depth) with a near-opaque warm underline, across depth levels, hover, and focus, tuned to keep the doc's light text legible.

3. Two rendering bugs found in review:

  • Highlight ↔ chrome coupling (also the root of the jh:setThemeMode re-post concern). The in-document highlight is painted on the document, so it must contrast with the document's background — not the chrome theme. An earlier iteration tied the highlight treatment to the toggle, so forcing light chrome on a dark doc flipped the highlight toward the light treatment and it stopped reading. Fixed by keying .jh-dark on the doc's sampled darkness only. This removes jh:setThemeMode entirely, so there's no re-post gap on a second jh:ready.
  • Block-boundary anchors rendered no highlight. An anchor whose first character starts a block (a heading, a paragraph) resolved its range to the block's leading edge, so wrapping pulled the whole <h3> into an inline <span> whose background never paints — the highlight silently vanished (in light mode too). locateStart biases a boundary start into the next text node, so we wrap the text, not the block.

Presentation-only: no API, DB, or anchoring-model changes. /d/:slug/raw stays byte-pristine (overlay only under ?overlay=1).

Verification

  • tsc --noEmit clean · vitest 108/108 · next build clean
  • Reproduced the reported doc in an overlay harness (real HTML + real anchor). Confirmed: darkness is detected, the heading highlight now paints a clear amber block (was invisible), and a mid-paragraph anchor still wraps correctly (no regression).
  • Rendered old-vs-new dark highlight CSS on a dark page; rendered the toggle in light + dark chrome.
  • Live click-through on the branch preview / after merge (toggle persistence, drawer on mobile).

Known limitation (not a bug)

The toggle themes the viewer chrome; it can't repaint the author's document, which renders as byte-pristine HTML in a sandboxed iframe. A doc authored with fixed dark colors stays dark; auto keeps the chrome matched to it. Forwarding the choice to adaptive (prefers-color-scheme) docs is possible as a follow-up.

🤖 Generated with Claude Code

Add a light/dark/auto control to the viewer chrome bar and persist the
choice per viewer in localStorage. A forced mode drives both the chrome
palette and the in-iframe highlight treatment via a new jh:setThemeMode
message to the overlay, so it also serves as a manual override when the
doc's darkness is mis-detected.

Strengthen the dark-mode comment highlight: the previous ~16% warm tint
was nearly invisible on a dark page. It's now a readable amber wash
(~.30-.54 by overlap depth) with a near-opaque warm underline across
depth levels, hover, and focus, tuned to keep the doc's light text legible.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
justhtml Ready Ready Preview, Comment Jul 1, 2026 6:25pm

@AnnaXWang AnnaXWang marked this pull request as ready for review July 1, 2026 18:41
@AnnaXWang AnnaXWang requested review from masnwilliams and rgarcia July 1, 2026 18:42

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 609727d. Configure here.

() => (mode === "auto" && theme && theme.isDark ? buildChromePalette(theme) : null),
[theme]
() => (effectiveTheme ? buildChromePalette(effectiveTheme) : null),
[effectiveTheme]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Theme mode not re-synced

Medium Severity

On a second jh:ready while overlayReady is already true, the shell re-posts anchors and reactions but never sends jh:setThemeMode. The new iframe overlay keeps forcedMode at auto, so saved light/dark highlight treatment can disagree with the chrome until the user toggles theme again.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 609727d. Configure here.

@rgarcia rgarcia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏

@AnnaXWang AnnaXWang merged commit 02fa850 into main Jul 1, 2026
5 checks passed
@AnnaXWang AnnaXWang deleted the hypeship/theme-toggle-dark-highlight branch July 1, 2026 22:45
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.

2 participants