/* ==========================================================================
   Lake Mead Admin — Animated appearance toggles
   --------------------------------------------------------------------------
   Ported from an earlier portfolio project's toggle page. Three hand-drawn SVG icons for
   the Auto / Day / Night switcher, each with three distinct motion states:

     hover      a quick physical reaction, independent of the theme change
     activate   a one-shot pulse fired on click (.is-activating)
     ambient    a slow loop that only the active choice keeps running

   The icons are inline SVG using currentColor, so they inherit the switcher's
   color and need no separate day/night artwork.
   ========================================================================== */

.theme-icon {
  width: 17px;
  height: 17px;
  display: block;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --- Day: solid core, stroked rays ---------------------------------------- */
.icon-day .sun-core { fill: currentColor; stroke: none; }
.icon-day .sun-rays { transform-origin: 12px 12px; }

/* The active sun breathes and turns slowly. */
.theme-choice[aria-pressed="true"] .icon-day .sun-rays {
  animation: sun-spin 18s linear infinite;
}
.theme-choice[aria-pressed="true"] .icon-day .sun-core {
  animation: sun-pulse 3.2s ease-in-out infinite;
}
/* Hover splays the rays outward a touch. */
.theme-choice:hover .icon-day .sun-rays { transform: scale(1.14); }
.icon-day .sun-rays { transition: transform var(--t-base) var(--ease); }

@keyframes sun-spin  { to { transform: rotate(360deg); } }
@keyframes sun-pulse { 0%,100% { opacity: 1; } 50% { opacity: .72; } }

/* --- Night: crescent plus three stars ------------------------------------- */
.icon-night .moon-body { fill: currentColor; stroke: none; }
.icon-night .star { fill: currentColor; stroke: none; opacity: .35; }

/* Each star twinkles on its own offset so they never blink in unison. */
.theme-choice[aria-pressed="true"] .icon-night .star-1 { animation: twinkle 2.4s ease-in-out infinite; }
.theme-choice[aria-pressed="true"] .icon-night .star-2 { animation: twinkle 2.4s ease-in-out .8s infinite; }
.theme-choice[aria-pressed="true"] .icon-night .star-3 { animation: twinkle 2.4s ease-in-out 1.6s infinite; }
.theme-choice:hover .icon-night .star { opacity: .9; }
.icon-night .star { transition: opacity var(--t-base) var(--ease); }

@keyframes twinkle { 0%,100% { opacity: .25; } 50% { opacity: 1; } }

/* --- Auto: split disc with an orbiting dot -------------------------------- */
.icon-auto .auto-half-sun  { fill: none; stroke: currentColor; }
.icon-auto .auto-half-moon { fill: currentColor; stroke: none; }
.icon-auto .auto-orbit     { transform-origin: 12px 12px; }

.theme-choice[aria-pressed="true"] .icon-auto .auto-orbit {
  animation: orbit 6s linear infinite;
}
.theme-choice:hover .icon-auto .auto-orbit { transform: rotate(28deg); }
.icon-auto .auto-orbit { transition: transform var(--t-base) var(--ease); }

@keyframes orbit { to { transform: rotate(360deg); } }

/* --- Activation pulse -----------------------------------------------------
   Added on click and removed on animationend, so it can fire repeatedly. */
.theme-choice.is-activating .theme-icon { animation: choice-pop .42s var(--ease); }
@keyframes choice-pop {
  0%   { transform: scale(1); }
  38%  { transform: scale(1.34); }
  100% { transform: scale(1); }
}

/* A ring that expands out of the pressed control. */
.theme-choice.is-activating::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 2px solid var(--aqua);
  animation: choice-ring .52s var(--ease) forwards;
  pointer-events: none;
}
@keyframes choice-ring {
  from { opacity: .85; transform: scale(1); }
  to   { opacity: 0;   transform: scale(1.85); }
}

/* ==========================================================================
   TOGGLE REFERENCE PAGE
   ========================================================================== */

/* A large version of the switcher for the demo page. */
.toggle-demo {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  flex-wrap: wrap;
}
.theme-switcher--lg { padding: var(--sp-2); gap: var(--sp-2); }
.theme-switcher--lg .theme-choice {
  width: auto;
  height: 46px;
  padding: 0 var(--sp-4);
  gap: var(--sp-2);
  display: inline-flex;
  align-items: center;
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
}
.theme-switcher--lg .theme-icon { width: 20px; height: 20px; }

/* The live state readout under a demo. */
.toggle-status {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--muted);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius-xs);
  background: var(--surface-alt);
  border: 1px solid var(--line-soft);
}

/* --- Robot toggle (San Pedro's Human/Cyber control) -----------------------
   A rounded head whose eyes and antenna react to hover and to state. */
.robot-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  background: var(--surface);
  cursor: pointer;
  transition: border-color var(--t-base) var(--ease), background var(--t-base) var(--ease);
}
.robot-toggle:hover { border-color: var(--aqua); background: var(--aqua-soft); }

.robot-head {
  width: 26px; height: 26px;
  flex: 0 0 26px;
  position: relative;
  border-radius: 8px;
  border: 2px solid currentColor;
  color: var(--ink-soft);
  transition: color var(--t-base) var(--ease), transform var(--t-base) var(--ease);
}
.robot-toggle:hover .robot-head { transform: translateY(-2px) rotate(-6deg); }

/* Antenna. */
.robot-head::before {
  content: "";
  position: absolute;
  top: -7px; left: 50%;
  width: 2px; height: 5px;
  margin-left: -1px;
  background: currentColor;
}
/* The pair of eyes, drawn as one element with a box-shadow twin. */
.robot-eyes {
  position: absolute;
  top: 8px; left: 6px;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 8px 0 0 currentColor;
}
.robot-toggle[aria-pressed="true"] .robot-head { color: var(--aqua-deep); }
.robot-toggle[aria-pressed="true"] .robot-eyes { animation: robot-blink 4s steps(1) infinite; }
@keyframes robot-blink {
  0%, 92%, 100% { opacity: 1; }
  94%, 98%      { opacity: .15; }
}
.robot-label { font-size: var(--fs-sm); font-weight: var(--fw-bold); }

/* --- Brand switcher (Magnolia365's data-brand pattern) -------------------- */
.brand-swatch-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.brand-swatch {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-card);
  border: 1.5px solid var(--line);
  background: var(--surface);
  cursor: pointer;
  transition: border-color var(--t-base) var(--ease), transform var(--t-base) var(--ease);
}
.brand-swatch:hover { transform: translateY(-2px); }
.brand-swatch.is-active { border-color: var(--aqua); }
.brand-swatch__chip {
  width: 28px; height: 28px;
  border-radius: 8px;
  flex: 0 0 28px;
  background: var(--chip, var(--aqua));
}
.brand-swatch__name { font-size: var(--fs-sm); font-weight: var(--fw-bold); }
.brand-swatch__hex { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--muted); }

@media (prefers-reduced-motion: reduce) {
  /* The ::after ring must be listed too — it carries the 0.52s activation
     pulse, and without it reduced-motion users still got the full ring. */
  .theme-icon, .theme-icon *, .robot-head, .robot-eyes,
  .theme-choice.is-activating::after { animation: none !important; }
}

/* ==========================================================================
   SVG ANIMATION — SEARCH TOOLBAR
   The gallery passed 380 designs, at which point scrolling stopped being a
   way to find anything. Lives here rather than in toggle-ideas.css because
   that file is written whole by gen-toggles.py.

   The group chips inside .tg-search__groups are built by svg-search.js from
   the headings in the spliced card region, so this file never names a group.
   ========================================================================== */
.tg-search {
  position: sticky;
  /* Clears whatever sticky chrome is above it — the topbar's height while the
     navbar is sticky, zero when it is static or hidden. The shadow below only
     appears once the toolbar has actually parked (svg-search.js sets
     .is-stuck). */
  top: var(--sticky-top);
  z-index: 20;
  padding: var(--sp-4) 0 var(--sp-3);
  background: var(--paper);
  transition: box-shadow var(--t-base) var(--ease);
}
.tg-search.is-stuck {
  box-shadow: 0 12px 16px -14px rgba(0, 0, 0, .45);
}
.tg-search__row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}
.tg-search__box { flex: 1 1 260px; max-width: 340px; }
/* Pushes the reset button to the far edge and keeps the count beside it. */
.tg-search__count { margin: 0 0 0 auto; white-space: nowrap; }

/* A group with every card filtered out hides its heading too, so the results
   never show an empty section header. */
.tg-group.is-empty,
.tg-grid.is-empty { display: none; }

.tg.is-hidden { display: none; }

/* Match highlight inside the design name. Uses the on-tint token rather than
   the raw hue: the accent on its own soft tint reads at under 2:1. */
.tg__name mark {
  padding: 0 1px;
  border-radius: var(--radius-xs);
  background: var(--sun-soft);
  color: var(--sun-ink);
  font-weight: var(--fw-heavy);
}

.tg-search__empty {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-6);
  border: 1px dashed var(--line);
  border-radius: var(--radius-card);
  color: var(--muted);
  font-size: var(--fs-sm);
}
.tg-search__empty i { font-size: var(--fs-lg); }

@media (max-width: 640px) {
  .tg-search { position: static; }
  .tg-search__box { max-width: none; }
  .tg-search__count { margin-left: 0; }
}

/* --- Liquid glass: the scene ----------------------------------------------
   An ocean for the glass to refract. Glass with nothing behind it is just a
   grey rectangle; the whole effect is what the lens does to what is UNDER it,
   so the backdrop is part of the component, not decoration around it. Two
   caustic layers drift on their own clocks so the water never repeats.
   The mode attribute is written by the demo switcher and drives the palette
   here — never the app's own theme. */
.lg-scene {
  --lg-deep:  #0b3a5a;
  --lg-mid:   #1c7fa8;
  --lg-light: #7fd6e6;
  --lg-foam:  #e6fbff;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: 220px;
  border-radius: var(--radius-card);
  background:
    radial-gradient(120% 80% at 20% 110%, color-mix(in srgb, var(--lg-light) 70%, transparent) 0%, transparent 55%),
    radial-gradient(90% 70% at 85% 0%,   color-mix(in srgb, var(--lg-foam) 60%, transparent) 0%, transparent 50%),
    linear-gradient(160deg, var(--lg-mid), var(--lg-deep));
  display: grid;
  place-items: center;
  padding: var(--sp-6);
}
.lg-scene[data-mode="night"] { --lg-deep: #03101c; --lg-mid: #0b3550; --lg-light: #2a7ea6; --lg-foam: #9fd0e6; }
.lg-scene[data-mode="auto"]  { --lg-deep: #1f2a5c; --lg-mid: #c4587a; --lg-light: #f2b27a; --lg-foam: #ffe6c4; }
.lg-scene::before,
.lg-scene::after {
  content: "";
  position: absolute;
  inset: -20%;
  z-index: -1;
  background-image:
    radial-gradient(circle at 30% 40%, color-mix(in srgb, var(--lg-foam) 55%, transparent) 0 2px, transparent 18px),
    radial-gradient(circle at 70% 65%, color-mix(in srgb, var(--lg-foam) 45%, transparent) 0 3px, transparent 26px);
  background-size: 140px 120px, 210px 170px;
  opacity: .55;
  animation: lg-caustic 14s linear infinite;
}
.lg-scene::after { background-size: 180px 150px, 260px 220px; opacity: .35; animation-duration: 23s; animation-direction: reverse; }
@keyframes lg-caustic {
  from { transform: translate(0, 0) rotate(0deg); }
  to   { transform: translate(-60px, 40px) rotate(2deg); }
}

/* --- Liquid glass: the lens -----------------------------------------------
   Refraction comes from an SVG displacement map applied THROUGH backdrop-filter,
   so it bends whatever is behind the glass rather than the glass itself. Only
   Chromium honours url() in backdrop-filter today, so the plain frosted version
   is declared first and the lens second: a browser that rejects the second
   keeps the first, and nobody sees a hole. The filter element lives inline on
   the page — a stylesheet cannot carry SVG. */
.lg-glass {
  position: relative;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--lg-foam, #fff) 18%, transparent);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 70%, transparent),
    inset 0 -1px 0 color-mix(in srgb, #000 18%, transparent),
    0 10px 30px color-mix(in srgb, #000 22%, transparent);
  backdrop-filter: blur(10px) saturate(1.5);
  -webkit-backdrop-filter: blur(10px) saturate(1.5);
}
.lg-glass { backdrop-filter: url(#lg-lens) blur(2px) saturate(1.5); }
/* The specular highlight: a soft bright edge that sells "curved surface". */
.lg-glass::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(115deg,
    color-mix(in srgb, #fff 55%, transparent) 0%,
    transparent 38%,
    transparent 62%,
    color-mix(in srgb, #fff 22%, transparent) 100%);
  mix-blend-mode: screen;
  opacity: .8;
}

/* --- Liquid glass: the switcher -------------------------------------------
   Three radios in a fieldset and one glass thumb. The thumb has no JS: the
   fieldset's :has() reads which radio is checked and translates the thumb to
   that third. Radios, not buttons, because a "pick one of three" is exactly what
   a radio group already is — arrow keys, roving focus and the announced state
   all arrive for free. */
.lg-switch {
  --lg-n: 3;
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--lg-n), 64px);
  height: 56px;
  margin: 0;
  padding: 6px;
  border: 0;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--lg-foam) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #fff 30%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.lg-switch__opt {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  color: color-mix(in srgb, var(--lg-foam) 85%, #000);
  font-size: 20px;
  cursor: pointer;
  transition: color var(--t-base) var(--ease), transform var(--t-base) var(--ease);
}
.lg-switch__opt input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.lg-switch__opt:hover { transform: translateY(-1px); }
.lg-switch__opt:has(input:checked) { color: #0b1e2b; }
.lg-switch__opt:has(input:focus-visible) { outline: 2px solid #fff; outline-offset: -6px; border-radius: var(--radius-pill); }
.lg-switch__thumb {
  position: absolute;
  top: 6px; left: 6px;
  width: calc((100% - 12px) / var(--lg-n));
  height: calc(100% - 12px);
  border-radius: var(--radius-pill);
  transition: translate .42s cubic-bezier(.34, 1.4, .64, 1);
}
.lg-switch:has(input[value="night"]:checked) .lg-switch__thumb { translate: 100% 0; }
.lg-switch:has(input[value="auto"]:checked)  .lg-switch__thumb { translate: 200% 0; }

@media (prefers-reduced-motion: reduce) {
  .lg-scene::before, .lg-scene::after { animation: none; }
  .lg-switch__thumb { transition: none; }
  .lg-switch__opt:hover { transform: none; }
}
