/* ============================================================
   Theme toggle — coffee-cup icon + "spill" circular colour-invert.
   State machine and timings (2500/800/400ms, linear easing) from
   refer/system-merge.html's Spill component. NOT a port of its
   clone-based preview: that demo clones the *entire page* once at
   init and re-themes the clone, which is safe on a small static demo
   but would duplicate this page's dozen live, JS-driven mechanics
   (StackArc's orbit, the braided thread, the scatter grid) as inert,
   non-animating ghosts — collision-protocol.md's frozen-ghost bug.

   Owner correction Aug 2026, from a reference site: the circle should
   invert the REAL page's colours in place — text stays visible the
   whole time, it just flips from dark-on-light to light-on-dark as
   the boundary sweeps past — not cover everything with an opaque
   panel (the previous version of this file). The mechanism is
   `mix-blend-mode:difference`, the exact technique the header already
   uses to stay legible over anything beneath it. A flat `--w-00`
   (white) fill, differenced against this page's neutral black/white
   ramp, inverts correctly in *either* direction with one static
   colour: difference(white, near-white bg) ≈ near-black; difference
   (white, black bg) = white. No per-theme colour logic needed, no hex
   outside tokens.css, and — because difference is its own inverse —
   the header's own already-differenced text composes correctly
   underneath the spill with no double-inversion special-casing.
   The real theme flip (on click-commit) is still the actual
   `data-theme` swap on `<html>`, exact and instant; the blend-mode
   circle is only ever the animated preview around it. See EXCEPTIONS.md.
   ============================================================ */

.theme-btn{
  position:relative; width:34px; height:34px;
  display:flex; align-items:center; justify-content:center;
  background:none; border:0; color:inherit; cursor:pointer;
}
.theme-btn svg{ width:19px; height:19px; transform-origin:50% 80%; }
@keyframes cup-wobble{ 0%,100%{ transform:rotate(-7deg); } 50%{ transform:rotate(7deg); } }
.theme-btn:hover svg{ animation:cup-wobble .78s ease-in-out infinite; }

.spill{
  position:fixed; inset:0; z-index:var(--z-spill);
  pointer-events:none; visibility:hidden;
  background:var(--w-00); mix-blend-mode:difference;
  clip-path:circle(0px at 50% 0%);
}
.spill.is-active{ visibility:visible; }

@media (prefers-reduced-motion:reduce){
  .spill{ display:none; }
}
