Repository navigation
fix(theme): keep all surfaces in sync when switching appearance - #3628
Conversation
Suppress CSS transitions for one frame while the theme class flips, so the nav (0.2s) and shiki code blocks (0.5s) no longer fade at their own pace while the rest of the page switches instantly. The nav transition itself is kept for the home-page scroll transparent/opaque effect, and now animates border-bottom-color instead of the layout-affecting border-bottom shorthand.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a2da6b91ca
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
This PR improves appearance switching in the default theme by ensuring all themed UI surfaces update simultaneously, eliminating mismatched fade transitions during a theme toggle (while keeping the scroll-driven nav fade behavior intact).
Changes:
- Temporarily suppresses CSS transitions for one animation frame during the theme class flip in the single theme-application entry point (
applyThemeToDOM). - Adjusts the nav transition to animate
border-bottom-color(instead of theborder-bottomshorthand) to avoid layout-affecting transition semantics.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/core/src/theme/logic/useThemeState.ts | Injects/removes a temporary global transition: none rule around the theme DOM update to synchronize surface switching. |
| packages/core/src/theme/components/Nav/index.scss | Updates nav transition to animate border-bottom-color instead of border-bottom. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Replace the injected <style> with a static base.css rule toggled via a root class, so the suppression works under strict CSP and also covers ::before/::after pseudo-elements - Apply the same CSP-safe pattern to removeClipViewTransition - Skip the suppression (and its forced style recalcs) when the DOM already matches the theme, e.g. on the post-hydration call - Add unit tests for applyThemeToDOM
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 532a5aae66
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Extract applyThemeToDOM into its own React-free module so the test needs no runtime mock or testing-only export - Move the scrollbar suppression next to the transition it cancels in scrollbar.scss, scoped to .rp-scrollbar instead of the universal bucket - Move the appearance view-transition rule into SwitchAppearance's global.scss where its sibling rules live - Fold the suppression toggle into a single guarded block and mark the forced style flush with void so it does not read as dead code
Summary
before:
before.mp4
after:
iShot_2026-08-26_12.43.16.mp4
When switching the theme, the nav faded its background over 0.2s (and shiki code blocks over 0.5s) while the rest of the page switched instantly, producing a visible mismatch. The nav transition was introduced in #3017 for the home-page scroll transparent/opaque effect, not for theme switching.
This PR suppresses CSS transitions for one frame while the theme class flips (in
applyThemeToDOM, the single entry point for all theme changes), so every themed surface switches in sync. The suppression is deliberately a temporary globaltransition: nonerather than a nav-specific override: it cannot be re-overridden by the nav's own transition rule, and it also covers any other component that declares a transition on themed properties, now or in the future. The scroll-driven nav fade on the home page is unaffected. The nav transition now also animatesborder-bottom-colorinstead of the layout-affectingborder-bottomshorthand.Related Issue
N/A
Screenshots
Uploading before/after comparison videos...
Checklist