fix(explorer): give the landing orb a light-mode render - #1231
Open
max-digi wants to merge 2 commits into
Open
Conversation
The landing orb only ever had one asset: near-white flat line work sized for the dark page. On a white background it washed out to almost nothing. Adds a second render of the same artwork carrying its own shading, framed identically to the dark one (both 1312x570, the orb at 1312 wide cropped to its top 570 rows) so switching theme swaps the shading without moving the arch. Verified the two agree to half a pixel on every edge of the visible window. The artwork is painted as a background rather than an <img> so only the asset for the active theme is fetched, and so the swap happens before first paint -- theme is a `data-theme` attribute set by an inline boot script, while React theme state resolves after hydration, which would flash the dark render at light-mode visitors. Held to 42% opacity in light mode, where the strands otherwise compete with the footer links they pass behind. Rendered at 4x and downsampled, because the strands are sub-pixel hairlines at 656px and rasterising straight to target size breaks them into dotted lines. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bundle Size Report
Chunk changes (>1KB)
Compared against main branch (baseline from 4/27/2026, 4:02:54 PM) |
Drops the band from 242px to 194px. The band is anchored to the viewport bottom and the artwork to the band's top, so a shorter band both sits the orb lower and clips more of it: 194 of 285 CSS px now show (68%) instead of 242 (85%) -- 20% less of the artwork. Applies to both themes; the height is on the shared container. Verified the artwork box is identical across themes (62,506 656x285) and that the two renders agree to half a pixel on every edge of the newly visible window, so switching theme moves nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bundle Size Report
Chunk changes (>1KB)
Compared against main branch (baseline from 4/27/2026, 4:02:54 PM) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The landing orb had only one asset —
landing-circles.png, near-white flat line work sized for the dark page. It was used in both themes, so on a white background it washed out to almost nothing.Change
landing-circles-light.png, a second render of the same artwork carrying its own shading.Sphere.Artworkpaints the orb as a background instead of an<img>, andstyles.cssselects the asset offhtml[data-theme="light"].opacity: 0.42, where the strands otherwise compete with the footer links they pass behind.242pxto194px, showing 68% of the artwork instead of 85%.Dark mode keeps the same asset at full strength; only its position changes, along with light's.
Why a background and not an
<img>Only the asset for the active theme gets fetched (verified: one 200, no request for the other), and the swap lands before first paint. Theme is a
data-themeattribute set by an inline boot script, while React theme state resolves after hydration — a React-drivensrcwould flash the dark render at light-mode visitors.Framing — nothing jumps when switching theme
Both assets are 1312×570: the orb rendered 1312px wide, cropped to its top 570 rows. The band is anchored to the viewport bottom and the artwork to the band's top, so the
194pxheight both lowers the orb and clips more of it — 194 of 285 CSS px visible, i.e. asset rows 0..388.Measured live in both themes at the same viewport:
62,506 656×28562,506 656×2850,506 780×1940,506 780×194background-size/position100%/0% 0%100%/0% 0%The only properties differing between themes are
background-imageandopacity. Within the visible window the two renders' ink bounding boxes agree to 0.5 CSS px on every edge, the arch's top edge differs by a mean of 0.010 CSS px across 1208 columns (max 1 px), and mask IoU is 0.952.Note: the light render's strands continue to row 569 where the dark one stops at 482 — both well below the clip line at 388, so hidden. If
h-[194px]ever grows past ~241px, the two will stop revealing the same amount of orb.Anti-aliasing
The strands are sub-pixel hairlines at 656 CSS px, so rasterising straight to target size broke them into dotted lines. Rendered at 4× and downsampled with Lanczos over premultiplied alpha. Grain (mean |Laplacian| in strand bodies) measured on the rendered page:
Screenshots
before-light.pngherelower-light.pnghereVerification
pnpm checkinapps/explorer— biome, tsgo, 110 env testspnpm exec vitest run— 112 testspnpm lint:tempo— exit 0NODE_ENV=production pnpm build— clean, both assets present indist/client🤖 Generated with Claude Code