/*
 * base.css  —  Torus CFCS Design System
 * Refined 2026-08-11 toward a modern, professional, Apple-clean dark UI:
 * one restrained accent, real neutrals, subtle depth. The old "cosmic"
 * decoration (glowing background, starfield, floating orbs, colored halos)
 * was removed at the token level so the calm cascades across the whole app.
 */

*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  /* Dark app → tell the browser to render native controls (select popups,
     scrollbars, date pickers, autofill) in DARK. This is what fixes the
     white-popup / invisible-option-text on native <select> menus app-wide;
     [data-theme="light"] flips it back to light below. */
  color-scheme: dark;
  /* ─── Ground ramp (neutral-dark, slight cool bias — not cosmic navy) ─── */
  --col-void:       #0a0b0d;     /* app ground — near-black, barely cool */
  --col-navy:       #101216;     /* raised surface */
  --col-indigo:     #16181d;     /* panel */
  --col-deep:       #1c1f25;     /* elevated panel */

  /* Glass surfaces */
  --glass-1:        rgba(255,255,255,0.04);
  --glass-2:        rgba(255,255,255,0.07);
  --glass-3:        rgba(255,255,255,0.10);
  --glass-4:        rgba(255,255,255,0.14);

  /* Glass borders */
  --glass-border:   rgba(255,255,255,0.09);
  --glass-border-2: rgba(255,255,255,0.15);
  --glass-border-3: rgba(255,255,255,0.22);

  /* ─── Accent Palette ─────────────────────────────────────────────────
     Refined: ONE restrained blue leads (--accent-cyan); the others are
     desaturated so they harmonize instead of competing, and the status
     hues (emerald/rose/amber) keep their meaning but read calmer. */
  --accent-cyan:    #4f9fda;       /* PRIMARY — professional blue */
  --accent-violet:  #7d87d6;       /* muted indigo (secondary) */
  --accent-teal:    #3cb5a6;       /* muted teal */
  --accent-emerald: #43bd88;       /* success */
  --accent-rose:    #e46c7d;       /* danger */
  --accent-amber:   #e0aa3a;       /* warning */
  --accent-purple:  #9186d6;       /* muted purple */

  /* Glow versions — heavily reduced. Colored halos read as decoration;
     depth now comes from real offset shadows + borders, not glows. */
  --glow-cyan:      rgba(79,159,218,0.12);
  --glow-violet:    rgba(125,135,214,0.10);
  --glow-teal:      rgba(60,181,166,0.10);
  --glow-rose:      rgba(228,108,125,0.12);
  --glow-purple:    rgba(145,134,214,0.10);
  --glow-emerald:   rgba(67,189,136,0.10);

  /* ─── Text ───────────────────────────── */
  --text-primary:   #ffffff;
  --text-secondary: rgba(255,255,255,0.90);
  --text-muted:     rgba(255,255,255,0.58);
  --text-dim:       rgba(255,255,255,0.30);

  /* ─── Structure ──────────────────────── */
  --nav-h:          86px;

  /* ─── Typography ─────────────────────── */
  --font-display:   'Space Grotesk', 'Inter', sans-serif;
  --font-body:      'Inter', sans-serif;

  /* ─── Radius ─────────────────────────── */
  --r-xs:  4px;
  --r-sm:  8px;
  --r-md:  10px;
  --r-lg:  14px;    /* calmed 18→14 — pro card radius (craft floor 12–16px) */
  --r-xl:  18px;    /* calmed 24→18 */
  --r-2xl: 24px;    /* calmed 32→24 */

  /* ─── Motion ─────────────────────────── */
  --ease-out:   cubic-bezier(0.16, 1, 0.3, 1);
  /* Was a bouncy overshoot spring (…1.56…) — replaced 2026-08-11 with a smooth
     exponential ease-out. Real objects decelerate; they don't boing. The token
     name is kept for compatibility across existing var(--ease-spring) uses. */
  --ease-spring:cubic-bezier(0.22, 1, 0.36, 1);
  --ease-smooth:cubic-bezier(0.4, 0, 0.2, 1);
  --t-fast:  0.15s;
  --t-base:  0.25s;
  --t-slow:  0.45s;
  --t-xslow: 0.7s;
}

html, body {
  height: 100%;
  background: var(--col-void);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* ─── Ground ────────────────────────────────────────────────────────────
   Clean, near-solid dark ground with a single, barely-there top sheen for
   depth — no cosmic glows, no starfield, no animation. (Was: 3 colored
   radial glows + a 4-stop linear gradient, plus a 10-point starfield.) */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -3;
  background:
    radial-gradient(140% 90% at 50% -20%, rgba(255,255,255,0.028) 0%, transparent 55%),
    var(--col-void);
}

/* Starfield removed — kept inert so nothing that references body::after breaks. */
body::after { content: none; }

/* ─── Scrollbar ──────────────────────────── */
::-webkit-scrollbar            { width: 4px; height: 4px; }
::-webkit-scrollbar-track      { background: transparent; }
::-webkit-scrollbar-thumb      { background: rgba(255,255,255,0.12); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover{ background: rgba(56,189,248,0.4); }

/* ─── Glassmorphism Mixin Class ──────────── */
.glass {
  background: var(--glass-2);
  backdrop-filter: blur(16px) saturate(1.05);
  -webkit-backdrop-filter: blur(16px) saturate(1.05);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-lg);
}

.glass-sm {
  background: var(--glass-1);
  backdrop-filter: blur(12px) saturate(1.05);
  -webkit-backdrop-filter: blur(12px) saturate(1.05);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-md);
}

/* ─── Utility ────────────────────────────── */
.hidden { display: none !important; }

.section-label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--text-muted);
  text-transform: uppercase;
  margin-bottom: 16px;
}

/* ─── Floating Orbs — REMOVED 2026-08-11 ────────────────────────────────
   The four drifting blurred orbs were decorative "cosmic" ambiance and the
   dominant source of dashboard jank (each animated 540–640px blur forced
   every overlapping backdrop-filter panel to re-blur every frame). Hidden
   outright: cleaner look AND a large scroll/idle-frame performance win.
   The .orb-1..4 rules below are now inert. */
.orb, .orb-1, .orb-2, .orb-3, .orb-4 { display: none !important; }

.orb {
  position: fixed;
  border-radius: 50%;
  filter: blur(16px);
  pointer-events: none;
  z-index: -1;
}

.orb-1 {
  width: 540px; height: 540px;
  background: radial-gradient(circle, rgba(56,189,248,0.13) 0%, transparent 70%);
  top: -120px; left: -160px;
  animation: orb-drift-1 20s ease-in-out infinite alternate;
}

.orb-2 {
  width: 640px; height: 640px;
  background: radial-gradient(circle, rgba(167,139,250,0.11) 0%, transparent 70%);
  bottom: -160px; right: -110px;
  animation: orb-drift-2 26s ease-in-out infinite alternate;
}

.orb-3 {
  width: 380px; height: 380px;
  background: radial-gradient(circle, rgba(45,212,191,0.09) 0%, transparent 70%);
  top: 40%; left: 50%;
  transform: translate(-50%, -50%);
  animation: orb-drift-3 17s ease-in-out infinite alternate;
}

.orb-4 {
  width: 300px; height: 300px;
  background: radial-gradient(circle, rgba(251,113,133,0.07) 0%, transparent 70%);
  top: 20%; right: -80px;
  animation: orb-drift-4 14s ease-in-out infinite alternate;
}

/* Multi-waypoint drift — more organic than simple A→B.
   PERF: scale() was removed from these keyframes. The orbs sit behind ~200
   backdrop-filter glass panels; scaling a 540–640px blurred element every frame
   forced every overlapping glass surface to re-sample + re-blur its backdrop
   (the dominant cause of dashboard jank). translate() pans the orb without
   changing its rasterised size, so the look is virtually identical but the
   per-frame backdrop invalidation is far cheaper. opacity kept (compositor-cheap). */
@keyframes orb-drift-1 {
  0%   { transform: translate(0,    0); }
  30%  { transform: translate(55px, 75px); }
  65%  { transform: translate(85px, 25px); }
  100% { transform: translate(50px, 65px); }
}

@keyframes orb-drift-2 {
  0%   { transform: translate(0,     0); }
  35%  { transform: translate(-45px,-55px); }
  70%  { transform: translate(-75px,-20px); }
  100% { transform: translate(-55px,-70px); }
}

@keyframes orb-drift-3 {
  0%   { transform: translate(-50%,-50%); opacity: 0.55; }
  40%  { transform: translate(-52%,-47%); opacity: 0.85; }
  75%  { transform: translate(-47%,-54%); opacity: 0.70; }
  100% { transform: translate(-50%,-50%); opacity: 1.00; }
}

@keyframes orb-drift-4 {
  0%   { transform: translate(0,    0); opacity: 0.6; }
  45%  { transform: translate(-25px,55px); opacity: 0.9; }
  100% { transform: translate(-50px,20px); opacity: 0.7; }
}

/* ══════════════════════════════════════════
   LIGHT MODE — Tableau Liquid Glass Palette
══════════════════════════════════════════ */

[data-theme="light"] {
  color-scheme: light;   /* native controls render light in light mode */
  /* Base background colour (used by html,body rule) — clean cool-neutral */
  --col-void:       #eef0f4;
  /* Surface ramp — lightened so components that consume these tokens DIRECTLY
     (the post-login boot-loader splash gradient, native <select> option bg in
     dashboard.css, and misc panels) invert to light instead of staying dark-navy
     in light mode. Previously only --col-void was overridden, leaving these dark →
     dark-text-on-dark (near-invisible splash). Kept subtle + distinct so gradients
     still read. Verified: no component pairs these as a surface with hardcoded
     white text, so lightening them can't create white-on-light. */
  --col-navy:       #e7ecfb;
  --col-indigo:     #eef1fd;
  --col-deep:       #f4f6fe;

  /* Glass surfaces — frosted white */
  --glass-1:        rgba(255,255,255,0.52);
  --glass-2:        rgba(255,255,255,0.68);
  --glass-3:        rgba(255,255,255,0.80);
  --glass-4:        rgba(255,255,255,0.92);

  /* Glass borders — soft purple tint */
  --glass-border:   rgba(130,100,200,0.18);
  --glass-border-2: rgba(130,100,200,0.32);
  --glass-border-3: rgba(130,100,200,0.48);

  /* Accents — darkened for light-bg contrast.
     ⚑ EVERY VALUE HERE IS A MEASURED WCAG AA PASS AGAINST THE LIGHT SURFACE
       (#eef0f4), NOT A SHADE THAT LOOKS DARK ENOUGH. The previous set was picked
       by eye and five of the seven failed as body text: cyan 3.59:1, teal 3.28:1,
       emerald 3.30:1, rose 4.11:1, amber 2.79:1. A sweep of every tab at four
       viewports counted 173 contrast failures in light and ZERO in dark, and the
       same handful of ratios repeated across unrelated pages because they are
       these tokens, not page CSS. Dark mode was always fine — its accents sit at
       6.8-7.8:1 — so light was simply never held to the same bar CLAUDE.md sets
       for it ("light AND dark, both first-class").
       Ratios below are against --col-void's light value. Re-measure if you
       change the surface, and keep every one of them >= 4.5:1. */
  --accent-cyan:    #0369a1;       /* 5.20:1  was #0284c7 (3.59) */
  --accent-violet:  #4f46e5;       /* 5.51:1  unchanged — already passed */
  --accent-teal:    #0f766e;       /* 4.80:1  was #0d9488 (3.28) */
  --accent-emerald: #047857;       /* 4.80:1  was #059669 (3.30) */
  --accent-rose:    #be123c;       /* 5.51:1  was #e11d48 (4.11) */
  --accent-amber:   #92400e;       /* 6.21:1  was #d97706 (2.79) */
  --accent-purple:  #7c3aed;       /* 4.99:1  unchanged — already passed */

  /* Glows — kept in step with the accents above, same rgb, same 0.20 alpha.
     These are decorative halos, so contrast does not apply; they are updated
     only so a glow never disagrees with the colour it is supposed to be haloing. */
  --glow-cyan:      rgba(3,105,161,0.20);
  --glow-violet:    rgba(79,70,229,0.20);
  --glow-teal:      rgba(15,118,110,0.20);
  --glow-rose:      rgba(190,18,60,0.20);
  --glow-purple:    rgba(124,58,237,0.20);
  --glow-emerald:   rgba(4,120,87,0.20);

  /* Text — deep purple-navy.
     ⚑ THE ALPHA STEPS ARE THE CONTRAST LADDER. Light ink over a light surface
       loses contrast far faster than white ink over a dark one, so the dark
       theme's alphas (.90/.58/.30) cannot simply be reused here: at .50 muted
       measured 4.10:1 and at .28 dim measured 1.92:1 — dim was effectively
       unreadable while still carrying real words ("approved", "pending").
       Re-stepped so all four pass AA and the hierarchy still reads:
         primary 15.8:1  >  secondary 9.0:1  >  muted 6.4:1  >  dim 4.9:1
       4.5:1 is the floor for every one of them — dim included, because dim text
       in this app is informational, not decorative. */
  --text-primary:   #13103a;                 /* 15.83:1 */
  --text-secondary: rgba(19,16,58,0.80);     /*  9.02:1  was .74 */
  --text-muted:     rgba(19,16,58,0.70);     /*  6.41:1  was .50 (4.10) */
  --text-dim:       rgba(19,16,58,0.62);     /*  4.91:1  was .28 (1.92) */
}

/* Background: soft lavender gradient instead of cosmic dark */
/* Direct body override ensures the base colour changes even if ::before z-index is tricky */
html[data-theme="light"],
html[data-theme="light"] body {
  background: var(--col-void);
}

/* Clean light ground — single faint top sheen, no colored glows. */
html[data-theme="light"] body::before {
  background:
    radial-gradient(140% 90% at 50% -20%, rgba(255,255,255,0.6) 0%, transparent 55%),
    var(--col-void) !important;
}

/* Starfield + orbs already removed globally (base rules). */

/* Scrollbars */
html[data-theme="light"] ::-webkit-scrollbar-thumb       { background: rgba(130,100,200,0.22); }
html[data-theme="light"] ::-webkit-scrollbar-thumb:hover { background: rgba(2,132,199,0.45); }

/* ── Under-development placeholder (shared by all WIP tabs) ─── */
.wip-wrap {
  position: relative;
  min-height: calc(100vh - var(--nav-h));
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
  overflow: hidden;
}

.wip-bg-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: clamp(72px, 16vw, 190px);
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: 0.1em;
  color: rgba(56,189,248,0.04);
  pointer-events: none;
  user-select: none;
  white-space: nowrap;
}

html[data-theme="light"] .wip-bg-text {
  color: rgba(56,189,248,0.08);
}

.wip-card {
  position: relative;
  z-index: 1;
  background: var(--glass-2);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-lg);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  padding: 56px 72px;
  text-align: center;
  max-width: 500px;
  width: 100%;
  box-shadow: 0 32px 80px rgba(0,0,0,0.35);
}

html[data-theme="light"] .wip-card {
  background: rgba(255,255,255,0.55);
  border-color: rgba(100,120,200,0.18);
  box-shadow: 0 24px 64px rgba(80,90,160,0.14);
}

.wip-icon-ring {
  width: 72px;
  height: 72px;
  margin: 0 auto 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  /* color overridden per-tab */
}

.wip-eyebrow {
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--text-muted);
  text-transform: uppercase;
  margin-bottom: 10px;
}

.wip-title {
  font-family: var(--font-display);
  font-size: 38px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--text-primary);
  text-transform: uppercase;
  margin-bottom: 22px;
  line-height: 1;
}

.wip-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border-radius: 100px;
  padding: 6px 18px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-bottom: 26px;
  /* color overridden per-tab */
}

.wip-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
  animation: wip-pulse 2s ease-in-out infinite;
}

@keyframes wip-pulse {
  0%, 100% { opacity: 1;   transform: scale(1);   }
  50%       { opacity: 0.3; transform: scale(0.75); }
}

.wip-body {
  font-size: 13px;
  line-height: 1.75;
  letter-spacing: 0.025em;
  color: var(--text-muted);
}
