/* ══════════════════════════════════════════════════════════════════════════
   theme.css — the light/dark palette layer.

   Loaded FIRST, before base.css, so base.css (and every page stylesheet) can
   consume these tokens and still override any structural rule it wants.

   ── How the two themes are expressed ─────────────────────────────────────
   The dark UI was written against a small set of literal colors that appear
   over and over: the near-black backgrounds, the three brand blues, the
   ink/white overlays and the four status hues. Rather than duplicate every
   rule per theme, each of those literals became a **channel token** — the
   bare `R,G,B` triplet — and the ~1200 `rgba(96,165,250,.12)`-style literals
   scattered across the stylesheets became `rgba(var(--accent-rgb),.12)`.
   Flipping the theme therefore only has to redefine ~20 triplets here; every
   alpha, every gradient stop and every shadow follows automatically and keeps
   its original layering intent.

   Two of those channels flip *meaning* rather than value, which is what makes
   a single set of rules read correctly in both themes:

     --hi-rgb     "brighter than the surface" — white on dark, near-black on
                  light. A `rgba(var(--hi-rgb),.06)` card tint stays a subtle
                  lift in both; a `rgba(var(--hi-rgb),.6)` text color stays
                  readable in both.
     --on-accent  the text color that sits ON a filled brand surface. Dark
                  theme paints light-blue buttons and writes near-black on
                  them; light theme paints deep-blue buttons and writes white.

   ── Do not ────────────────────────────────────────────────────────────────
   * Don't add new literal colors to page CSS — use the tokens, or add a
     channel here. A literal is invisible in one of the two themes and there
     is no build step that would catch it.
   * `widget.css` and `admin.css` are deliberately NOT part of this system.
     The widget renders on customer sites and takes its palette from the
     agent's own appearance config; the admin console is a separate operator
     app served by a separate process that never loads this file.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Tell the browser this is a dark UI so native controls (dropdown lists,
     scrollbars, date pickers) render dark instead of OS-default white. */
  color-scheme: dark;

  /* ── Surfaces ── */
  --bg: #08080e;
  --bg-alt: #0c0c16;
  --bg-deep: #06060c;
  --bg-rgb: 8, 8, 14;          /* page/backdrop channel */
  --card-rgb: 18, 20, 32;      /* raised panel channel (menus, cards, sheets) */

  --surface: rgba(96, 165, 250, .05);
  --surface-hover: rgba(96, 165, 250, .10);
  --glass: rgba(96, 165, 250, .06);
  --glass-border: rgba(96, 165, 250, .12);
  --sidebar-bg: rgba(8, 8, 14, .95);
  --sidebar-border: rgba(96, 165, 250, .08);

  /* ── Type ── */
  --text: #c8d8f0;
  --text-bright: #cfe4ff;
  --text-muted: rgba(200, 216, 240, .4);
  --heading: #e8f0ff;
  --ink-rgb: 200, 216, 240;    /* body-text channel */
  --hi-rgb: 255, 255, 255;     /* "brighter than the surface" — see header */

  /* ── Brand ── */
  --accent: #60a5fa;
  --accent2: #93c5fd;
  --accent3: #3b82f6;
  --accent-rgb: 96, 165, 250;
  --accent2-rgb: 147, 197, 253;
  --accent3-rgb: 59, 130, 246;
  /* Text/iconography painted on top of a filled brand surface. */
  --on-accent: #061021;

  /* The specular top stop of a filled brand button's radial. It must stay
     LIGHTER than --accent in both themes — it is a highlight on the button,
     not a text colour — so it walks down the blue scale in light mode rather
     than inverting the way the ink tokens do. */
  --accent-hi: #cfe4ff;
  --gradient-1: linear-gradient(135deg, #60a5fa, #93c5fd);
  --gradient-2: linear-gradient(135deg, #3b82f6, #60a5fa);
  --gradient-text: linear-gradient(135deg, #60a5fa, #93c5fd, #3b82f6);
  --glow: rgba(96, 165, 250, .2);
  --glow2: rgba(147, 197, 253, .12);
  --glow-text: 0 0 40px rgba(96, 165, 250, .25);

  /* ── Status ── */
  --success: #6ee7b7;
  --success-strong: #34d399;
  --warning: #fde68a;
  --warning-strong: #fbbf24;
  --warning-deep: #f59e0b;
  --warning-bright: #fcd34d;
  --danger: #fca5a5;
  --danger-strong: #f87171;
  --danger-deep: #ef4444;
  --violet: #a78bfa;
  --violet-soft: #c4b3f5;
  --indigo: #7c8cf8;
  --sky: #7dd3fc;
  --orange: #fb923c;
  --success-rgb: 110, 231, 183;
  --success-surface-rgb: 6, 78, 59;
  --success2-rgb: 52, 211, 153;
  --warning-rgb: 251, 191, 36;
  --warning2-rgb: 253, 230, 138;
  --warning3-rgb: 245, 158, 11;
  --danger-rgb: 239, 68, 68;
  --danger2-rgb: 252, 165, 165;
  --danger3-rgb: 248, 113, 113;
  --violet-rgb: 167, 139, 250;
  --orange-rgb: 251, 146, 60;
  --teal-rgb: 45, 212, 191;
  --indigo-rgb: 99, 102, 241;
  --sky-rgb: 56, 189, 248;

  /* ── Depth ── */
  --shadow-rgb: 0, 0, 0;
  --shadow-panel: 0 8px 32px rgba(0, 0, 0, .35);
  --scrim: rgba(6, 6, 12, .62);
  /* A recessed field or code block INSIDE a card — distinct from --scrim,
     which covers the whole viewport behind a modal. Dark theme sinks it with
     black, light theme with a trace of ink; both read as "set into the card"
     at the same strength. */
  --well: rgba(0, 0, 0, .32);
  /* The chip on a toggle switch. It must read against its own TRACK in both
     states, so it follows neither the ink tokens (which invert) nor the
     surface tokens (which would match the off-state track). */
  --knob: #c8d8f0;

  /* Tint tokens — formalize the hand-picked rgba() alpha variants of the
     brand colors that were scattered across landing.css/auth.css/etc. */
  --accent-tint-08: rgba(96, 165, 250, .08);
  --accent-tint-12: rgba(96, 165, 250, .12);
  --accent-tint-30: rgba(96, 165, 250, .3);
  --success-tint: rgba(110, 231, 183, .1);
  --warning-tint: rgba(253, 230, 138, .1);
  --danger-tint: rgba(252, 165, 165, .1);

  /* Spacing / radius / motion scale — shared rhythm so pages stop hand-picking
     one-off values. See foundations.css for the components built on top. */
  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
  --space-5: 20px; --space-6: 24px; --space-7: 32px; --space-8: 48px;
  --radius-sm: 8px; --radius-md: 10px; --radius-lg: 14px; --radius-xl: 20px; --radius-pill: 999px;
  --ease-standard: cubic-bezier(.4, 0, .2, 1);
  --dur-fast: .18s; --dur-base: .22s; --dur-slow: .25s;

  /* How long a theme flip takes. Read by theme.js for the view-transition
     path and used by the property-transition fallback below. */
  --theme-swap-dur: .85s;
}

/* ══════════════════════════════════════════════════════════════════════════
   LIGHT
   Same geometry, different palette — no rule here may change a size, a
   position or a radius. Only color.

   The blues walk *down* the scale rather than up: dark theme brightens for
   emphasis (#60a5fa -> #93c5fd), light theme deepens (#2563eb -> #1d4ed8).
   That keeps `--accent2` meaning "more prominent than --accent" in both, so
   every hover rule written for dark still reads correctly here.
   ══════════════════════════════════════════════════════════════════════════ */
:root[data-theme="light"] {
  color-scheme: light;

  --bg: #f4f7fc;
  --bg-alt: #ffffff;
  --bg-deep: #eef2f9;
  --bg-rgb: 255, 255, 255;
  --card-rgb: 255, 255, 255;

  --surface: rgba(37, 99, 235, .045);
  --surface-hover: rgba(37, 99, 235, .09);
  --glass: rgba(37, 99, 235, .045);
  --glass-border: rgba(37, 99, 235, .16);
  --sidebar-bg: rgba(255, 255, 255, .92);
  --sidebar-border: rgba(37, 99, 235, .12);

  --text: #1f2b45;
  --text-bright: #16243d;
  --text-muted: rgba(31, 43, 69, .58);
  --heading: #0d1729;
  --ink-rgb: 31, 43, 69;
  /* Flips to "darker than the surface" — see the note in the header. */
  --hi-rgb: 13, 23, 41;

  --accent: #2563eb;
  --accent2: #1d4ed8;
  --accent3: #1e40af;
  --accent-rgb: 37, 99, 235;
  --accent2-rgb: 29, 78, 216;
  --accent3-rgb: 30, 64, 175;
  --on-accent: #ffffff;

  --accent-hi: #7fa9f7;
  --gradient-1: linear-gradient(135deg, #2563eb, #4f7ef4);
  --gradient-2: linear-gradient(135deg, #1d4ed8, #3b82f6);
  --gradient-text: linear-gradient(135deg, #1d4ed8, #2563eb, #3b82f6);
  --glow: rgba(37, 99, 235, .18);
  --glow2: rgba(59, 130, 246, .12);
  --glow-text: 0 0 40px rgba(37, 99, 235, .14);

  --success: #047857;
  --success-strong: #059669;
  --warning: #a16207;
  --warning-strong: #b45309;
  --warning-deep: #c2410c;
  --warning-bright: #a16207;
  --danger: #dc2626;
  --danger-strong: #dc2626;
  --danger-deep: #b91c1c;
  --violet: #6d28d9;
  --violet-soft: #6d28d9;
  --indigo: #4f46e5;
  --sky: #0369a1;
  --orange: #c2410c;
  --success-rgb: 4, 120, 87;
  /* Filled success surface (the "everything's resolved" banner) — the dark
     theme paints emerald-900 behind light text, the light theme emerald-100
     behind dark text, so the same alpha reads as the same lift in both. */
  --success-surface-rgb: 209, 250, 229;
  --success2-rgb: 5, 150, 105;
  --warning-rgb: 180, 83, 9;
  --warning2-rgb: 161, 98, 7;
  --warning3-rgb: 194, 65, 12;
  --danger-rgb: 220, 38, 38;
  --danger2-rgb: 220, 38, 38;
  --danger3-rgb: 185, 28, 28;
  --violet-rgb: 109, 40, 217;
  --orange-rgb: 194, 65, 12;
  --teal-rgb: 13, 148, 136;
  --indigo-rgb: 79, 70, 229;
  --sky-rgb: 3, 105, 161;

  /* Slate rather than pure black: at the large blurs this codebase uses, a
     black shadow on a white card reads as dirt, a slate one reads as depth. */
  --shadow-rgb: 100, 116, 139;
  --shadow-panel: 0 8px 32px rgba(100, 116, 139, .18);
  --scrim: rgba(15, 23, 42, .38);
  --well: rgba(15, 23, 42, .05);
  --knob: #ffffff;

  --accent-tint-08: rgba(37, 99, 235, .07);
  --accent-tint-12: rgba(37, 99, 235, .12);
  --accent-tint-30: rgba(37, 99, 235, .3);
  --success-tint: rgba(4, 120, 87, .1);
  --warning-tint: rgba(180, 83, 9, .1);
  --danger-tint: rgba(220, 38, 38, .1);
}

/* ══════════════════════════════════════════════════════════════════════════
   The flip animation.

   Preferred path is a full-page View Transition crossfade (theme.js), which
   is the only technique that also morphs the things a property transition
   cannot touch: gradients, backdrop-filtered glass, mask images, SVG fills
   and the <canvas> constellation on the home page.

   `.lx-theme-anim` below is the fallback for engines without
   startViewTransition. It is applied for exactly one swap and then removed —
   leaving a global `transition: *` on the document would make every hover
   state on the site sluggish.
   ══════════════════════════════════════════════════════════════════════════ */
html.lx-theme-anim,
html.lx-theme-anim *,
html.lx-theme-anim *::before,
html.lx-theme-anim *::after {
  transition:
    background-color var(--theme-swap-dur) var(--ease-standard),
    border-color var(--theme-swap-dur) var(--ease-standard),
    color var(--theme-swap-dur) var(--ease-standard),
    fill var(--theme-swap-dur) var(--ease-standard),
    stroke var(--theme-swap-dur) var(--ease-standard),
    box-shadow var(--theme-swap-dur) var(--ease-standard),
    outline-color var(--theme-swap-dur) var(--ease-standard) !important;
  transition-delay: 0s !important;
}

/* The crossfade itself. Named `theme-swap` so it can be distinguished from
   the router's navigation transitions, which use the stock root animation
   at their own (much shorter) duration. */
html.lx-theme-vt::view-transition-old(root),
html.lx-theme-vt::view-transition-new(root) {
  animation-duration: var(--theme-swap-dur);
  animation-timing-function: var(--ease-standard);
  /* Both layers hold their own opacity ramp; mixing them normally is what
     produces a true dissolve rather than a flash of the page beneath. */
  mix-blend-mode: normal;
}
html.lx-theme-vt::view-transition-old(root) {
  animation-name: lxThemeFadeOut;
}
html.lx-theme-vt::view-transition-new(root) {
  animation-name: lxThemeFadeIn;
}
@keyframes lxThemeFadeOut { from { opacity: 1 } to { opacity: 0 } }
@keyframes lxThemeFadeIn { from { opacity: 0 } to { opacity: 1 } }

/* Somebody who asked the OS for less motion gets the new palette instantly
   rather than a slower, gentler version of the same big crossfade. */
@media (prefers-reduced-motion: reduce) {
  :root { --theme-swap-dur: .01s; }
  html.lx-theme-anim,
  html.lx-theme-anim *,
  html.lx-theme-anim *::before,
  html.lx-theme-anim *::after { transition: none !important; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Theme switcher — shared by the marketing header (`.th-nav`) and the
   dashboard account menu, so the two can never drift apart. Placement is the
   caller's job; everything below is self-contained.
   ══════════════════════════════════════════════════════════════════════════ */
.lx-theme { position: relative; flex-shrink: 0; }

.lx-theme-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border-radius: var(--radius-sm);
  border: 1px solid var(--glass-border);
  background: var(--glass);
  color: var(--text);
  cursor: pointer;
  transition: background var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.lx-theme-trigger:hover {
  background: var(--surface-hover);
  border-color: var(--accent);
  color: var(--accent);
}
.lx-theme-trigger.is-active {
  border-color: var(--accent);
  color: var(--accent);
}

/* The two glyphs are stacked and cross-rotated so the button itself animates
   on the flip instead of hard-cutting between icons. */
.lx-theme-trigger .lx-theme-ic {
  position: relative;
  width: 17px;
  height: 17px;
}
.lx-theme-trigger .lx-theme-ic svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transition: opacity .45s var(--ease-standard), transform .45s var(--ease-standard);
}
.lx-theme-trigger .lx-theme-sun { opacity: 0; transform: rotate(-90deg) scale(.5); }
.lx-theme-trigger .lx-theme-moon { opacity: 1; transform: rotate(0) scale(1); }
:root[data-theme="light"] .lx-theme-trigger .lx-theme-sun { opacity: 1; transform: rotate(0) scale(1); }
:root[data-theme="light"] .lx-theme-trigger .lx-theme-moon { opacity: 0; transform: rotate(90deg) scale(.5); }

.lx-theme-menu {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  min-width: 168px;
  padding: 6px;
  border-radius: var(--radius-md);
  border: 1px solid var(--glass-border);
  background: rgba(var(--card-rgb), .97);
  backdrop-filter: blur(24px);
  box-shadow: 0 18px 44px rgba(var(--shadow-rgb), .45);
  z-index: 300;
  animation: lxThemePop .16s var(--ease-standard);
  transform-origin: top right;
}
.lx-theme-menu[hidden] { display: none; }
/* Anchored under a left-aligned trigger (the account menu's header row keeps
   the popover inside the card rather than off its right edge). */
.lx-theme-menu.is-left { right: auto; left: 0; transform-origin: top left; }

@keyframes lxThemePop {
  from { opacity: 0; transform: translateY(-6px) scale(.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.lx-theme-opt {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font-family: 'Inter', sans-serif;
  font-size: 13px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-standard),
              color var(--dur-fast) var(--ease-standard);
}
.lx-theme-opt svg { width: 15px; height: 15px; flex-shrink: 0; color: var(--text-muted); }
.lx-theme-opt:hover { background: var(--surface-hover); color: var(--heading); }
.lx-theme-opt:hover svg { color: var(--accent); }
.lx-theme-opt[aria-checked="true"] { color: var(--accent); font-weight: 600; }
.lx-theme-opt[aria-checked="true"] svg { color: var(--accent); }
.lx-theme-opt .lx-theme-tick {
  margin-left: auto;
  width: 14px;
  height: 14px;
  opacity: 0;
  color: var(--accent);
}
.lx-theme-opt[aria-checked="true"] .lx-theme-tick { opacity: 1; }

/* Qunivex wordmark: the shipped PNG is white-on-transparent, so it goes flat
   against the light theme's pale surfaces. A soft dark shadow keeps it the
   same asset while giving it enough contrast to read. */
:root[data-theme="light"] .app-logo,
:root[data-theme="light"] .th-nav-logo,
:root[data-theme="light"] .th-footer-logo,
:root[data-theme="light"] .auth-logo-img,
:root[data-theme="light"] .nav-logo,
:root[data-theme="light"] .footer-logo-img {
  filter: drop-shadow(0 1px 2px rgba(15, 23, 42, .18))
          drop-shadow(0 0 1px rgba(15, 23, 42, .25));
}
