feat: theme select with system option - #26
Merged
Merged
Conversation
Replace the light/dark toggle button with a select control offering system/light/dark, backed by a shared readStoredThemeChoice() helper and a one-time migration of the legacy "theme" localStorage key into "theme-choice". Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RS53kTLmTNo4QVtiVrNLyj
Owner
Author
🔍 Local review (cycle 1) — round 4a33bea6-b683-4ce9-8012-affd25e97575Reviewed locally (
Summary: No blocking issues found. 0 FIX, 1 SKIP (optional hardening, not a regression), 4 IRRELEVANT (out of this PR's diff scope or self-retracted by the reviewer). |
Owner
Author
📋 Review summary — all cycles
Totals: 0 FIX, 1 SKIP, 4 IRRELEVANT, 0 UNVERIFIED. No blocking issues found by either reviewer. |
axisrow
added a commit
that referenced
this pull request
Aug 13, 2026
Three follow-ups on the topbar icon work: - Mobile topbar broke onto two rows. .topbar-inner declared four columns while only three children are visible there, and .topbar-actions was left to auto-placement after .menu-toggle had already claimed column 4 — so the grid cursor had passed it and dropped the actions onto row 2. Pin brand/actions/burger to explicit row-1 columns over a 3-column track and right-align the actions. - Restore the original ◐ glyph the pre-select toggle used, replacing the three-SVG sun/moon/monitor set. - Translate the theme control back to English (Colour theme / System / Light / Dark); the page is lang="en" and everything else on it is English, but #26 introduced Russian strings here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0176vakGzooXWuenVBEeKosv
axisrow
added a commit
that referenced
this pull request
Aug 13, 2026
* fix: restore icon-style theme toggle and GitHub topbar buttons The theme select and GitHub link had regressed to wide text pills after the theme-select rework. Restore compact circular icon buttons for both: the theme select now shows a sun/moon/monitor icon matching the current mode (system/light/dark) with the native <select> as a transparent click target on top, and the GitHub link is now an icon button with an inline GitHub mark, matching the same icon-button style/size. Fixes #37 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0176vakGzooXWuenVBEeKosv * fix: repair mobile topbar row and restore the original theme glyph Three follow-ups on the topbar icon work: - Mobile topbar broke onto two rows. .topbar-inner declared four columns while only three children are visible there, and .topbar-actions was left to auto-placement after .menu-toggle had already claimed column 4 — so the grid cursor had passed it and dropped the actions onto row 2. Pin brand/actions/burger to explicit row-1 columns over a 3-column track and right-align the actions. - Restore the original ◐ glyph the pre-select toggle used, replacing the three-SVG sun/moon/monitor set. - Translate the theme control back to English (Colour theme / System / Light / Dark); the page is lang="en" and everything else on it is English, but #26 introduced Russian strings here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0176vakGzooXWuenVBEeKosv * style: let the effect canvases read through their copy panels The panels overlaying a live canvas (stars, projects, proof, contact) each painted a near-opaque plate -- 0.91 via .veil-panel, and 0.97 for proof -- so the field behind them was flattened into a flat rectangle. Add a --veil-canvas token at 0.8 and point those four panels at it, leaving --veil for .project-surface, which has no canvas behind it. 0.8 is the floor rather than a taste call: composited over a black canvas pixel (mandelbrot does reach 0,0,0) it holds the in-panel --ink-faint at 4.91:1 light / 5.74:1 dark, still clear of AA. At 0.72 that secondary copy drops to 3.96:1. Mobile is deliberately untouched: those panels sit directly over the canvas with no side-by-side layout, and the existing mobile rules already tune them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0176vakGzooXWuenVBEeKosv * style: fade veil panels toward their canvas, tune effect motion - Veil panels over a live canvas now use a directional gradient fade (matching .experience-field/.about-field) instead of a flat semi-transparent plate, so the effect visibly runs into the panel. - projects-field-copy fades from the opposite side since its canvas sits to the left. - Bump plasma motion speed, starfield particle count, and copper-bars alpha scale for more visible motion/contrast. - Bump styles.css/effect-skins.js cache-busting query strings. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0176vakGzooXWuenVBEeKosv * fix: restore theme option contrast and cap starfield particle budget - .theme-select inherits color: transparent into its <option> elements, making System/Light/Dark unreadable when the dropdown opens in browsers that render option text with the select's author color. Restore an explicit, opaque color/background on .theme-select option. - The starfield preview skin raised particleCount to 900/1200, ~10x the vendored preview.mobile/preview.desktop budget (90/120). densityMode stays "explicit" here, so densityMax never clamps the value -- the prior comment's clamp claim was incorrect. Cap the override at 180/240 (2x budget) and correct the comment. - Add regression tests for both: option-list contrast and a particle-count ceiling relative to the vendored preview budget. - Bump styles.css/effect-skins.js cache-busting query strings. Fixes review findings from cycle 1 (codex + claude /review). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0176vakGzooXWuenVBEeKosv --------- Co-authored-by: axisrow <axisrow@users.noreply.github.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
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.
Summary
<select>offering system / light / dark.theme-choicelocalStorage key, with a one-time migration of the legacythemekey.Details
index.html:<head>bootstrap script resolves the theme before paint (avoids FOUC), performs the legacy-key migration, and stashes the resolved choice ondocument.documentElement.dataset.themeChoiceformain.jsto reuse without re-touchinglocalStorage.main.js:readStoredThemeChoice()/resolveTheme()/applyTheme()are the single set of helpers used by both the select'schangehandler and theprefers-color-schememedia-query listener.styles.css: new.theme-select,.theme-select-label,.visually-hiddenrules; adjusted mobile topbar grid columns to fit the wider control.main.jsandstyles.cssper repo convention.Testing
npm test— all 28 tests pass.🤖 Generated with Claude Code