/* weblj admin — dark control panel.
 *
 * The palette is lifted directly from weblj.si rather than invented: the page
 * background, the indigo→violet signature gradient and the white@8% hairlines
 * are the values the marketing site already ships, so the admin reads as the
 * same product. Everything else here exists to keep that palette legible at
 * dashboard density.
 *
 * The neutral ramp is semantic, not a lightness scale:
 *   n-50…n-200  fills that sit *above* the surface (hover, tracks, chips)
 *   n-300…n-400 mid greys that work as a fill and as text on a dark well
 *   n-500…n-700 text on dark wells
 *   n-800…n-900 wells that sit *below* the surface (code, toast, replay stage)
 * Components depend on that meaning, so keep the direction if you retune it.
 */
:root {
  color-scheme: dark;

  /* type */
  --font-display: 'Sora', system-ui, sans-serif;
  --font-body: 'Public Sans', system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;

  /* ---- neutral ramp (see note above) ----
     Chroma raised well above the old 0.03-0.04 (which read as neutral grey,
     i.e. "just black") so the whole ramp carries a visible indigo cast even
     at low lightness. */
  --n-50:  oklch(0.195 0.05 270);
  --n-100: oklch(0.25  0.05 270);
  --n-200: oklch(0.29  0.048 270);
  --n-300: oklch(0.42  0.042 268);
  --n-400: oklch(0.58  0.036 265);
  --n-500: oklch(0.66  0.036 262);
  --n-600: oklch(0.76  0.032 260);
  --n-700: oklch(0.865 0.024 258);
  --n-800: oklch(0.15  0.046 270);
  --n-900: oklch(0.12  0.042 270);

  /* ---- surfaces ---- */
  --bg: oklch(0.165 0.052 267);          /* weblj.si background, richened — see --bg-aura below */
  --surface: oklch(0.205 0.05 268);      /* cards, sidebar, topbar */
  --surface-2: oklch(0.245 0.048 271);   /* modals, anything above a card */
  --border: oklch(0.62 0.24 265 / 0.16); /* tinted with the brand hue instead of plain white */
  --border-strong: oklch(0.68 0.2 267 / 0.3);
  /* A fixed, low-opacity aurora behind everything — three soft radial blobs
     in the brand's two hues plus the "live" green, so the ground reads as
     dark indigo with light in it, not a flat black rectangle. Kept off the
     --bg color itself (used for background-image, layered under content),
     so text contrast is computed against the flat --bg beneath it. */
  --bg-aura:
    radial-gradient(1100px 780px at 8% -12%, oklch(0.6 0.24 265 / 0.24), transparent 60%),
    radial-gradient(950px 900px at 104% 8%, oklch(0.58 0.26 300 / 0.20), transparent 55%),
    radial-gradient(900px 700px at 32% 118%, oklch(0.78 0.16 158 / 0.09), transparent 60%);

  /* ---- text ---- */
  --text: oklch(0.98 0.01 250);
  --text-muted: oklch(0.745 0.028 260);
  --text-faint: oklch(0.615 0.026 262);

  /* ---- brand ---- */
  --primary: oklch(0.62 0.24 265);           /* weblj indigo — fills only */
  --primary-hover: oklch(0.67 0.23 265);
  --primary-text: oklch(0.78 0.14 268);      /* same hue, raised so it reads at body size */
  --primary-soft: oklch(0.62 0.24 265 / 0.16);
  --accent: oklch(0.58 0.26 300);            /* weblj violet — gradient partner only */
  --secondary: var(--accent);
  --secondary-soft: oklch(0.58 0.26 300 / 0.16);
  /* weblj.si's signature gradient, verbatim. Deliberately used in three places
     only: the brand mark, the active nav rail, and primary buttons. Never as a
     background wash. */
  --grad-brand: linear-gradient(135deg, oklch(0.62 0.24 265), oklch(0.58 0.26 300));
  /* Same hues, four hundredths darker. White on the brand gradient measures
     4.05:1 — fine for weblj.si's big hero CTA, short of WCAG AA for the 13px
     buttons in here. This clears 4.65:1 and is indistinguishable side by side. */
  --grad-action: linear-gradient(135deg, oklch(0.58 0.24 265), oklch(0.55 0.26 300));

  /* ---- semantic (lifted in L so they carry on a dark ground) ---- */
  --success: oklch(0.78 0.16 158);
  --success-soft: oklch(0.78 0.16 158 / 0.15);
  --warning: oklch(0.83 0.15 82);
  --warning-soft: oklch(0.83 0.15 82 / 0.15);
  --danger: oklch(0.71 0.19 22);
  --danger-soft: oklch(0.71 0.19 22 / 0.16);

  /* radius */
  --r-sm: 9px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-pill: 999px;

  /* Drop shadows read as mud on a dark ground; elevation is carried by surface
     lightness and a 1px top highlight instead. These remain so existing
     component rules keep a sane value. */
  --shadow-sm: 0 1px 2px oklch(0 0 0 / 0.3);
  --shadow-md: 0 12px 34px oklch(0 0 0 / 0.55);
  /* A lift shadow tinted with the brand hue rather than plain black — used on
     hover so the panel reads as "rising toward the light source", not just
     darker-shadow-therefore-elevated. */
  --shadow-lift: 0 14px 28px -12px oklch(0.62 0.24 265 / 0.38), 0 2px 8px oklch(0 0 0 / 0.35);
  --ring: 0 0 0 3px oklch(0.62 0.24 265 / 0.35);

  /* motion — one curve, three durations, used everywhere instead of ad-hoc
     "ease"/"linear" per rule. Overshoots slightly then settles, which is what
     makes hover states feel like they were tuned rather than left at the
     browser default. */
  --ease: cubic-bezier(0.16, 0.84, 0.28, 1);
  /* --ease overshoots and settles, which is right for a state change and wrong
     for a loop that has to arrive back where it started. Symmetric partner for
     the ambient loops (brand drift, live pulse, skeleton sweep, scroll cue). */
  --ease-loop: cubic-bezier(0.45, 0, 0.55, 1);
  --dur-fast: 0.15s;
  --dur: 0.22s;
  --dur-slow: 0.5s;
  --dur-ambient: 7s;

  /* The signature cut corner: every elevated panel loses one corner instead
     of rounding all four. It is the one shape move repeated everywhere on
     purpose, so panels read as cut from the same sheet rather than as generic
     rounded-rectangle-soup. Applied via clip-path, sized off --r-lg so it
     scales with the rest of the radius system. */
  --notch: 20px;

  /* Faint film-grain, tiled at 180px. Pure texture, no color — it keeps flat
     dark fills from looking like a solid color swatch. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.04 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");

  /* spacing */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;

  --sidebar-w: 252px;
  --topbar-h: 60px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    /* Without zeroing the delay, `animation-fill-mode: both` holds the element
       at its `from` keyframe — opacity 0 — for the whole delay and then pops.
       Killing duration alone made reduced motion *worse* than the animation
       it opts out of: the marketing hero staggers up to 0.4s of blank. */
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
}
