/* ═══════════════════════════════════════════════════════════════════════════
   theme-linear.css — the EdiX web theme. ONE copy.

   WHY THIS FILE EXISTS
   This palette used to live in four places — home.css, admin.css, docs.css and
   neo.css — each carrying a "LINEAR TOKENS v1 — keep values in sync" comment.
   They had already drifted (--cyber-text-dim was #7d7d86 in two and #a6a6ae in
   the other two). This is that block, deduplicated.

   WHY IT ISN'T IN cyber.css
   cyber.css is @import-ed by every OBS overlay, and overlays/theme.css documents
   its :root as byte-equal to the `cyber` overlay preset. Editing cyber.css would
   repaint live browser sources mid-stream. This file is linked ONLY by web pages,
   so overlays are unaffected by construction — never add it to public/overlays/.

   HOW IT WORKS
   It overrides the --cyber-* namespace that cyber.css defines, so every existing
   var() downstream resolves to Linear values with no per-component edits. Load it
   directly AFTER cyber.css and BEFORE the page's own stylesheet.

   ACCENT: #31cee6 — "EdiX brand cyan" (src/overlayTheme.js:33). ~10.7:1 on #050506.
   Text ON solid cyan must use --lin-accent-ink; white fails at 1.9:1.
   ═══════════════════════════════════════════════════════════════════════════ */
:root {
  /* ── surfaces ── */
  --cyber-bg: #050506;
  --lin-deep: #020203;
  --cyber-card: rgba(255,255,255,.04);
  --lin-card-hover: rgba(255,255,255,.065);
  --cyber-input: rgba(255,255,255,.04);
  --cyber-surface: #0e0e11;          /* opaque — <option>, dropdowns */
  --cyber-surface-2: #131317;
  --cyber-muted: rgba(255,255,255,.03);
  --cyber-border: rgba(255,255,255,.08);
  --lin-border-strong: rgba(255,255,255,.14);
  --cyber-line: rgba(255,255,255,.06);

  /* ── ink ── */
  --cyber-fg: #f7f8f8;
  --cyber-text: #f7f8f8;
  --cyber-muted-fg: #9b9ba3;         /* ~7.2:1 on #050506 */
  --cyber-text-dim: #9b9ba3;         /* was split #7d7d86 / #a6a6ae across the four
                                        copies; unified UP so real text clears 7:1 */
  --cyber-dim: #7d7d86;              /* ~4.9:1 — floor, decorative/disabled only */

  /* ── accent: cyan family ── */
  --cyber-accent: #31cee6;
  --cyber-accent-hover: #5cdaef;
  --lin-accent-ink: #06272e;         /* text ON solid cyan — never white */
  --cyber-accent-dim: rgba(49,206,230,.10);
  --cyber-accent-soft: rgba(49,206,230,.16);
  --cyber-accent-line: rgba(49,206,230,.30);
  --cyber-accent-glow: rgba(49,206,230,.35);
  --cyber-accent-2: #67e8f9;         /* light cyan (old magenta slot) */
  --cyber-accent-3: #7ab5f5;         /* steel blue (old cyan slot) */
  --cyber-accent2-dim:  rgba(103,232,249,.12);
  --cyber-accent2-line: rgba(103,232,249,.45);
  --cyber-accent3-dim:  rgba(122,181,245,.10);
  --cyber-accent3-line: rgba(122,181,245,.45);
  --cyber-ring: #31cee6;

  /* ── status: stays distinct from the accent so success/warn keep their meaning ── */
  --cyber-ok: #45e0b0;
  --cyber-ok-dim:  rgba(69,224,176,.12);
  --cyber-ok-line: rgba(69,224,176,.45);
  --cyber-warn: #f5c26b;
  --cyber-warn-dim:  rgba(245,194,107,.12);
  --cyber-warn-line: rgba(245,194,107,.45);
  --cyber-danger: #f58c81;
  --cyber-danger-dim:  rgba(245,140,129,.12);
  --cyber-danger-line: rgba(245,140,129,.45);
  --cyber-grad-danger: linear-gradient(90deg, #f58c81, #f5c26b);

  /* ── depth: hairline ring + diffuse shadow + top-light, never a single shadow ──
     Also re-homes the --neon* names, which cyber.css bakes as literal green. */
  --lin-shadow-sm: 0 0 0 1px rgba(255,255,255,.06), 0 4px 12px rgba(0,0,0,.40);
  --lin-shadow:    0 0 0 1px rgba(255,255,255,.07), 0 8px 28px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.06);
  --lin-shadow-lg: 0 0 0 1px rgba(255,255,255,.08), 0 16px 48px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.07);
  --lin-glow-accent: 0 0 0 1px var(--cyber-accent-line), 0 8px 32px rgba(49,206,230,.18);
  --neon-sm: var(--lin-shadow-sm);
  --neon: var(--lin-glow-accent);
  --neon-lg: var(--lin-shadow-lg);
  --neon-magenta: var(--lin-shadow-sm);
  --neon-cyan: var(--lin-shadow-sm);

  /* ── motion: one easing, three tiers ──
     Sized to absorb the durations already in the codebase rather than to look tidy:
       .12 / .15 / .16  →  tier 1     (~114 rules, the bulk)
       .18 / .2         →  tier 2
       .24 / .26 / .28  →  tier 3
     No .15s token even though .15s was the single most-used value: .15s and .16s are
     10ms apart — one frame at 120Hz — so a token for each would encode an accident.

     These names are also declared at :root in cyber.css. Every site page loads this
     file after it, so these win everywhere on the web; cyber.css's values survive only
     in the OBS overlays, which never load this file. That is why cyber.css is never
     edited — see the header. */
  --lin-dur-1: .14s;   /* micro:    ink, icon, border on small controls */
  --lin-dur-2: .2s;    /* default:  buttons, cards, chips, nav links */
  --lin-dur-3: .28s;   /* surfaces: panels, drawers, dock, modal */
  --lin-ease: cubic-bezier(.16, 1, .3, 1);

  --cyber-ease: var(--lin-ease);
  --cyber-dur: var(--lin-dur-3);
  --cyber-dur-fast: var(--lin-dur-1);
  --lin-dur-quick: var(--lin-dur-2);   /* kept: existing consumers */

  /* ── shape ── */
  --cyber-radius: 10px;
  --cyber-radius-sm: 8px;
  --cyber-radius-xs: 6px;
  --lin-radius-lg: 16px;

  /* ── focus: one ring for the whole site ──
     SOLID --cyber-ring, not the translucent --cyber-accent-line this used to use.
     rgba(49,206,230,.30) composites to 1.93:1 against the page background, under the 3:1
     WCAG 2.2 SC 1.4.11 wants for a focus indicator; the solid colour gives 10.2:1.
     Zero blur radius on purpose — a diffuse glow reads as decoration, not as focus. */
  --lin-focus-ring: 0 0 0 1px var(--cyber-bg), 0 0 0 3px var(--cyber-ring);

  /* ── type ── */
  --font-head: 'Plus Jakarta Sans', 'Heebo', sans-serif;
  --font-body: 'DM Sans', 'Heebo', sans-serif;
  --lin-grad-type: linear-gradient(180deg, #fff 0%, rgba(255,255,255,.68) 100%);
}

/* ── Ambient canvas ───────────────────────────────────────────────────────────
   The layered-light background: a noise film over three static radial light pools.
   This was ALSO copy-pasted four times (home, admin, docs, neo) with slightly different
   opacities; this is the shared copy, so every page gets it, not just the four.

   Deliberately STATIC — no filter:blur, no keyframes. The soft edges come from the gradient
   falloff instead, so a phone GPU pays nothing to composite it and there is nothing for
   reduced-motion to switch off. `background-attachment: fixed` keeps the pools anchored to
   the viewport while the page scrolls, which is what sells the depth. */
body {
  background-color: var(--cyber-bg);
  background-image:
    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.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.028'/%3E%3C/svg%3E"),
    radial-gradient(55% 40% at 78% -8%,  rgba(49,206,230,.10), transparent 65%),
    radial-gradient(45% 38% at -12% 42%, rgba(74,124,230,.06), transparent 60%),
    radial-gradient(52% 42% at 55% 112%, rgba(49,206,230,.04), transparent 60%);
  background-attachment: fixed, fixed, fixed, fixed;
  -webkit-font-smoothing: antialiased;
}

/* ── Focus ────────────────────────────────────────────────────────────────────
   One ring for the whole site. :focus-visible only, so a mouse click never paints a ring
   but keyboard and screen-reader navigation always does. Uses box-shadow rather than
   outline so it follows border-radius on rounded controls.

   Two selectors, not one. The non-form half stays in :where() (specificity 0) so pages can
   still style their own links and buttons freely. The form-control half is a REAL selector:
   at specificity 0 every `input:focus` rule in the codebase outranked it, so on text fields
   this ring was unreachable and the per-file glow was all there was. That is the actual bug
   behind "remove the glow from text fields" — the glow was standing in for a ring that
   could never paint.

   NOTE for anyone tempted to also repoint --neon-sm (see the alias above): don't. It has
   ~20 non-input consumers — cards, badges, buttons, @keyframes docHit — where its hairline
   ring is correct. The input rules were edited individually instead. */
:where(a, button, summary, [tabindex]):focus-visible {
  outline: none;
  box-shadow: var(--lin-focus-ring);
  border-radius: var(--cyber-radius-sm);
}
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: none;
  box-shadow: var(--lin-focus-ring);
  border-color: var(--cyber-accent);
}


/* ── Reduced motion ───────────────────────────────────────────────────────────
   Two switches, both previously unimplemented:
     • the OS-level media query had no global fallback, so every new component had
       to opt in by hand and most never did;
     • body.a11y-reduce-motion is set by shared/protect.js:54 and had ZERO rules
       anywhere in the repo — the accessibility panel's toggle did nothing at all.
   Animation is cut rather than merely shortened; `.01ms` keeps animationend
   handlers firing so JS that waits on them doesn't hang. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
body.a11y-reduce-motion *,
body.a11y-reduce-motion *::before,
body.a11y-reduce-motion *::after {
  animation-duration: .01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: .01ms !important;
  scroll-behavior: auto !important;
}

/* ═══ Component recipes ═══════════════════════════════════════════════════════
   These override the .cyber-* primitives from cyber.css, which are the shared
   vocabulary across auth, legal, download, brief and the marketing pages. They live
   here (not in cyber.css) for the same reason the tokens do: cyber.css ships to the
   OBS overlays. None of these classes are used by an overlay, but keeping the split
   clean means nobody has to check.

   The Linear treatment: rounded instead of chamfered, hairline borders, layered
   shadows, and small precise motion (2px lifts, expo-out). ══════════════════════ */

/* ── Buttons ─────────────────────────────────────────────────────────────────── */
.cyber-btn {
  font-family: var(--font-body);
  font-size: 14px; font-weight: 600;
  letter-spacing: 0; text-transform: none;      /* the uppercase+wide-tracking look is cyberpunk, not Linear */
  padding: 10px 18px; min-height: 40px;
  border-width: 1px;
  border-radius: var(--cyber-radius-sm);
  clip-path: none;                              /* drop the chamfer */
  transition: background var(--lin-dur-quick) var(--cyber-ease),
              border-color var(--lin-dur-quick) var(--cyber-ease),
              box-shadow var(--lin-dur-quick) var(--cyber-ease),
              transform var(--lin-dur-quick) var(--cyber-ease);
}
.cyber-btn:hover  { box-shadow: var(--lin-glow-accent); transform: translateY(-1px); }
.cyber-btn:active { transform: translateY(0); }

/* Solid CTA: ink on cyan — white text on this accent is 1.9:1 and unreadable. */
.cyber-btn--cta {
  background: var(--cyber-accent);
  color: var(--lin-accent-ink);
  border-color: transparent;
  box-shadow: 0 0 0 1px var(--cyber-accent-line), 0 4px 14px rgba(49,206,230,.24),
              inset 0 1px 0 rgba(255,255,255,.22);
}
.cyber-btn--cta:hover { background: var(--cyber-accent-hover); color: var(--lin-accent-ink); }

.cyber-btn--secondary {
  background: var(--cyber-card); color: var(--cyber-fg);
  border-color: var(--cyber-border);
}
.cyber-btn--secondary:hover {
  background: var(--lin-card-hover); color: var(--cyber-fg);
  border-color: var(--lin-border-strong); box-shadow: var(--lin-shadow-sm);
}
.cyber-btn--ghost { color: var(--cyber-fg); }
.cyber-btn--ghost:hover { background: var(--cyber-accent-dim); color: var(--cyber-accent); box-shadow: none; }

/* ── Inputs ──────────────────────────────────────────────────────────────────── */
.cyber-input {
  font-family: var(--font-body); color: var(--cyber-fg);
  border-radius: var(--cyber-radius-sm);
  clip-path: none;
  padding-inline-start: 14px;    /* the chamfer needed 30px of inset; rounded doesn't */
  transition: border-color var(--lin-dur-quick) var(--cyber-ease),
              box-shadow var(--lin-dur-quick) var(--cyber-ease);
}
/* Border only — the ring comes from the shared :focus-visible rule above. The
   --lin-glow-accent that used to be here is a 32px cyan bloom: the blue glow. */
.cyber-input:focus { border-color: var(--cyber-accent); }
/* The decorative prompt glyph belonged to the terminal look. */
.cyber-field::before { display: none; }

/* ── Effects the Linear look drops ────────────────────────────────────────────
   .cyber-glitch paints a chromatic-aberration text shadow — deliberately preserved by
   cyber.css even under reduced motion, because it was the brand signature. It isn't any
   more: the Linear system calls for precise type, not artefacts. The class stays in the
   markup (29 pages use it) and simply renders as clean text. */
.cyber-glitch { text-shadow: none !important; }
.cyber-glitch::before, .cyber-glitch::after { display: none !important; }

/* ── Cards ───────────────────────────────────────────────────────────────────── */
.cyber-chamfer, .cyber-chamfer-sm { clip-path: none; border-radius: var(--lin-radius-lg); }

/* ── Beta chip ────────────────────────────────────────────────────────────────
   One rule for what used to be three near-identical copies (.ax-beta in app-nav.css,
   .brand-beta in dashboard.css, .nav-beta in home.css). */
.ax-beta, .brand-beta, .nav-beta {
  display: inline-flex; align-items: center;
  font-family: var(--font-body); font-size: .58rem; font-weight: 800;
  letter-spacing: .1em; text-transform: uppercase;
  padding: 2px 6px; border-radius: var(--cyber-radius-xs);
  color: var(--cyber-accent);
  background: var(--cyber-accent-dim);
  border: 1px solid var(--cyber-accent-line);
}
