dioxus-cli 0.7.9 requires a `dev` sub-table under [web.resource].
Added [web.resource.dev] with the same style/script arrays as the
production [web.resource] section.
The CSS transition on the body's background-color (0.3s ease) was
causing the browser's View Transitions to capture a stale snapshot
during the Dark -> Light change. Even though the .dark class was
removed synchronously and we tried to disable transitions via an
!important override class, the interaction between Tailwind classes
and the raw CSS transition on body still caused the root VT snapshot
to render as Dark when it should have been Light.
By removing the transition from body entirely (which is redundant
anyway since we're using View Transitions for theme changes), the
body jumps to its target color instantly, guaranteeing the NEW
snapshot accurately reflects the final Light theme, eliminating
the 'ghost circle' or 'circle outline' bug.
When turning Dark off (Dark -> Light transition), the NEW layer is Light.
Previously we tried shrinking the OLD layer (Dark) over it, but if the
root snapshot captured a transparent html, revealing the transparent layer
produced no visual change.
Now we:
1. Always keep the NEW layer on top (z-index: 2).
2. Always animate the NEW layer expanding from 0 to max radius.
3. Explicitly set background-color on html in input.css to ensure the
VT root snapshots are fully opaque, avoiding transparent captures that
make expansions invisible.
4. Add background: var(--color-paper-theme) directly to ::view-transition-new
just to be absolutely certain it's painted opaque.
Adopt a fully CSS-driven strategy for the theme transition:
- Use CSS variables (--tt-x, --tt-y, --tt-r) injected onto documentElement
- Define static @keyframes in style.css using these variables
- Key logic: the Dark layer is ALWAYS placed on top (z-index: 2).
- Light -> Dark: NEW layer is Dark, so NEW expands from circle(0) to cover OLD.
- Dark -> Light: OLD layer is Dark, so OLD shrinks to circle(0) to reveal NEW.
This completely eliminates reliance on Web Animations API (which had bugs
with clip-path when animation:none is set) and eliminates dynamic <style>
injection (which caused timing gaps and style residue).
The result is perfectly symmetrical and bug-free in both directions.
Chrome does not allow WAAPI clip-path animations on ::view-transition-new
when animation:none !important is set via CSS. This caused dark→light
transitions to have no visible animation.
Replace with opacity:1 !important to neutralize the UA fade-in/out
animations: the UA animations still 'run' but cannot change opacity
because !important author declarations override CSS animation values.
WAAPI clip-path is no longer blocked.
Gray expanding circle was caused by UA default animations (fade-in/out)
and mix-blend-mode: plus-lighter not being fully overridden by WAAPI
opacity animations alone.
Fix: use CSS with !important to hard-lock the VT pseudo-elements:
- animation: none !important — kills UA fade-in/out
- opacity: 1 !important — both layers stay fully opaque
- mix-blend-mode: normal !important — no color addition
WAAPI now only controls clip-path on ::view-transition-new(root),
which doesn't conflict with any CSS property (no CSS clip-path exists).
This cleanly separates concerns: CSS handles static properties,
WAAPI handles the dynamic circle expansion.