perf(frontend): stop theme switches from janking the whole page

Two inherited-custom-property transitions were forcing a full style
recalculation on every animation frame during a theme switch:

- html transitioned --color-ice/--page-accent-glow (inherits: true),
  both read by dozens of selectors site-wide (buttons, links, glows,
  color-mix() gradients) -- animating them recomputed style for every
  element that references them, across the whole page, not just the
  swatch that was clicked.
- .lv-gui (the ClickGui replica used in ThemeStrip, HudPlayground, the
  login backdrop and the theme editor panel) transitioned 21 inherited
  custom properties at once, including per-row/per-tab ones
  (--gui-row-*, --gui-tab-*, --gui-menu-*) -- with a long module list
  that's the same cost multiplied by every row/tab in the tree.

Both now snap instantly instead of transitioning; .lv-gui keeps a
300ms cross-fade but only on the ~8 properties that read as "the
theme" (window/header/stroke/text/accent/panel), not per-row state.

Claude-Session: https://claude.ai/code/session_01F1M1Jic1wTSn4igUENynmZ
This commit is contained in:
loki5512344 2026-09-30 10:37:40 +02:00
parent 756ebc6d86
commit ab86078ca3
Signed by: boba
GPG key ID: 253067914055423B
2 changed files with 17 additions and 6 deletions

View file

@ -38,11 +38,17 @@
color: var(--gui-text);
text-align: left;
user-select: none;
transition-property: --gui-window-from, --gui-window-to, --gui-stroke-from, --gui-stroke-to, --gui-text, --gui-text-muted,
--gui-accent, --gui-accent-soft, --gui-accent-glow, --gui-panel-tint, --gui-panel-stroke, --gui-split, --gui-row-hover,
--gui-row-glow, --gui-row-text, --gui-tab-left, --gui-tab-right, --gui-tab-active-left, --gui-tab-active-right,
--gui-menu-left, --gui-menu-right;
transition-duration: 400ms;
/* Only the big, always-visible surfaces cross-fade. The old list also animated
per-row/per-tab properties (--gui-row-*, --gui-tab-*, --gui-menu-*) -- since those are
`inherits: true` custom properties, transitioning them forces the browser to recompute
style for every module row/tab in the tree on every frame, not just once. With a long
module list that was the actual jank a theme switch caused; trimming the list to the
handful of properties that read as "the theme" (not each individual row) keeps the
visible cross-fade while cutting the recalculation cost roughly proportional to how many
properties/elements were removed from it. */
transition-property: --gui-window-from, --gui-window-to, --gui-stroke-from, --gui-stroke-to, --gui-text, --gui-accent,
--gui-panel-tint, --gui-panel-stroke;
transition-duration: 300ms;
transition-timing-function: ease;
}
.lv-gui button { font: inherit; color: inherit; cursor: pointer; }

View file

@ -47,7 +47,12 @@
/* 100vw full-bleed sections exceed the scrollbar-less client width by a few px;
clip on html too so the document can never pan horizontally. */
overflow-x: clip;
transition: --color-ice 400ms ease, --page-accent-glow 400ms ease;
/* No transition here on purpose: --color-ice/--page-accent-glow are `inherits: true`
custom properties read by dozens of selectors across the whole site (buttons, links,
glows, color-mix() gradients). Transitioning an inherited custom property at the root
forces the browser to recompute style for every element that references it, on every
frame, for the whole page -- that was the actual site-wide jank a theme switch caused.
The value still snaps instantly, which reads fine for a deliberate theme-swatch click. */
}
body {
@apply bg-abyss text-snow font-sans antialiased;