/* Sun/moon theme toggle.
 *
 * The entire morph is driven by :root[data-theme] — no JS class toggling and no
 * re-render. That matters for two reasons:
 *   1. base.html's vanilla handler must never touch the button's children
 *      (assigning textContent would delete the SVG), so it only sets aria-label.
 *   2. The React ThemeToggle has no state of its own; it re-renders only when
 *      its whole tree does. CSS-driven animation is correct in both cases.
 *
 * Animation uses transform and opacity ONLY. The obvious way to write this is to
 * animate the SVG geometry properties (r, cx, cy) as CSS, but Firefox does not
 * support those as CSS properties, so the morph would silently not animate there.
 *
 * The shape is a disc, a ring of rays, and an offset "bite" circle inside a mask.
 * Dark: the bite sits over the disc, carving a crescent, rays retracted.
 * Light: the bite slides away, the disc shrinks, rays fan out.
 */

.theme-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  font: inherit;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.theme-toggle:hover { background: var(--surface-inset); color: var(--text); }

.theme-toggle svg {
  width: 18px;
  height: 18px;
  display: block;
  overflow: visible;
}

.theme-toggle .tt-disc {
  fill: currentColor;
  transform-origin: 12px 12px;
  transition: transform var(--dur-base) var(--ease-spring);
}

.theme-toggle .tt-bite {
  fill: #000;
  transform-origin: 12px 12px;
  transition: transform var(--dur-base) var(--ease-spring);
}

.theme-toggle .tt-rays {
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  transform-origin: 12px 12px;
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-slow) var(--ease-spring);
}

/* Dark: full-size disc, bite overlapping to cut a crescent, rays hidden. */
:root[data-theme="dark"] .theme-toggle .tt-disc { transform: scale(1); }
:root[data-theme="dark"] .theme-toggle .tt-bite { transform: translate(3px, -5px); }
:root[data-theme="dark"] .theme-toggle .tt-rays {
  opacity: 0;
  transform: rotate(-60deg) scale(0.4);
}

/* Light: smaller disc, bite pushed off-canvas, rays fanned out. */
:root[data-theme="light"] .theme-toggle .tt-disc { transform: scale(0.64); }
:root[data-theme="light"] .theme-toggle .tt-bite { transform: translate(16px, -14px); }
:root[data-theme="light"] .theme-toggle .tt-rays {
  opacity: 1;
  transform: rotate(0deg) scale(1);
}

/* ---- language toggle ---------------------------------------------------- */
.lang-toggle {
  min-width: 40px;
  gap: var(--space-1);
}
.lang-toggle .lang-label {
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  /* Snap between end states rather than animating. Both states are fully
     defined by data-theme above, so neither is left mid-morph. */
  .theme-toggle .tt-disc,
  .theme-toggle .tt-bite,
  .theme-toggle .tt-rays {
    transition: none !important;
  }
}
