/* ═════════════════════════════════════════════════════════════════════════
   The Ey3 — design tokens.

   Every colour, space, radius and duration in the interface resolves to a
   token defined here. Nothing downstream hard-codes a hex value, so the
   whole application can be re-themed from this one file and the palette
   cannot drift panel by panel — which is exactly how the Qt build ended up
   with slightly different greys in every dock.

   The palette is the existing Vlxs one, carried over unchanged: cyan
   #00f2fe on near-black, with amber/green/red reserved for state.
   ══════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Surfaces ────────────────────────────────────────────────────────
     Five depths, darkest at the back. Each step is a deliberate ~4% lift,
     which is enough to read as separation on an OLED panel without the
     "grey soup" that comes from too many near-identical greys.          */
  --sf-void:    #03060b;   /* behind everything; the globe's own backdrop */
  --sf-base:    #060d16;   /* app background                              */
  --sf-raised:  #0a1420;   /* rail, panel bodies                          */
  --sf-overlay: #0f1d2c;   /* cards, popovers, inputs                     */
  --sf-hover:   #16293c;   /* hover / active row                          */
  /* What covers the workbench while a modal is open. Not one of the five
     depths: it is the application dimmed, so it carries alpha and has to
     be defined per theme (dimming a light interface with near-black ink
     is a different colour from dimming a dark one).                      */
  --sf-scrim:   rgba(2, 6, 12, 0.78);

  /* ── Lines ─────────────────────────────────────────────────────────── */
  --ln-subtle:  #16293c;   /* separators inside a panel                   */
  --ln-default: #1e3a5f;   /* panel edges                                 */
  --ln-strong:  #2c5480;   /* focused input, active card                  */

  /* ── Text ───────────────────────────────────────────────────────────
     Four steps only. More than four and nobody can remember which is
     which, so they get used at random.                                  */
  --tx-primary:  #eaf8ff;
  --tx-secondary:#bfe6f5;
  --tx-muted:    #7f97b8;
  --tx-faint:    #4c6076;

  /* ── Accent ─────────────────────────────────────────────────────────
     One accent, three intensities. The mid tone is the brand cyan.      */
  --ac-bright: #7ff9ff;
  --ac:        #00f2fe;
  --ac-dim:    #4facfe;
  --ac-ghost:  rgba(0, 242, 254, 0.12);   /* fills, selected rows        */
  --ac-line:   rgba(0, 242, 254, 0.34);

  /* ── State ──────────────────────────────────────────────────────────
     Reserved strictly for meaning, never decoration. If a colour here
     appears, it is telling the operator something.                      */
  --st-ok:      #22e39a;
  --st-warn:    #ffb020;
  --st-danger:  #ff5f6d;
  --st-critical:#ff2d55;
  --st-info:    #7fd3ff;
  --st-ok-ghost:     rgba(34, 227, 154, 0.14);
  --st-warn-ghost:   rgba(255, 176, 32, 0.14);
  --st-danger-ghost: rgba(255, 95, 109, 0.14);

  /* ── Type ───────────────────────────────────────────────────────────
     Two families. The mono face carries anything an operator might read
     as data — coordinates, callsigns, timestamps — because aligned
     digits are legible at a glance and proportional ones are not.       */
  --ff-ui:   "Inter", "Segoe UI Variable", "Segoe UI", system-ui, sans-serif;
  --ff-mono: "JetBrains Mono", "Cascadia Code", "Consolas", ui-monospace, monospace;

  --fs-xs:  11px;   /* labels, chips            */
  --fs-sm:  12px;   /* dense table rows         */
  --fs-md:  13px;   /* default body             */
  --fs-lg:  15px;   /* panel titles             */
  --fs-xl:  19px;   /* view headers             */

  --lh-tight:  1.25;
  --lh-normal: 1.5;

  --fw-normal: 400;
  --fw-medium: 500;
  --fw-bold:   650;

  --ls-wide: 0.08em;   /* small-caps labels      */

  /* ── Space ──────────────────────────────────────────────────────────
     A 4 px scale. Every margin and padding is a multiple, which is what
     makes unrelated panels look like they belong to one application.    */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;

  /* ── Shape ──────────────────────────────────────────────────────────
     4 px on controls. The intelligence workbenches this interface is
     modelled on use one radius everywhere and it is what makes a dense
     screen read as one application rather than a pile of widgets; three
     different corner radii in one panel is the tell that it is not.     */
  --r-sm:  4px;
  --r-md:  4px;
  --r-lg:  8px;
  --r-pill: 999px;

  /* ── Elevation ──────────────────────────────────────────────────────
     On a dark interface a raised surface cannot be shown with a darker
     shadow alone — there is nothing darker left. The surface is lifted by
     a hairline of LIGHT around it plus the drop shadow, which is how the
     analytical workbenches this is modelled on do it, and why their cards
     read as raised while a plain dark border just reads as a box.

     The rings are inset so they do not enlarge the element, and the drop
     shadows stay cool-tinted rather than neutral black so they sit in the
     same colour world as the surfaces.                                  */
  --el-1: inset 0 0 0 1px rgba(255, 255, 255, 0.07),
          inset 0 0.5px 0 0 rgba(255, 255, 255, 0.06),
          0 1px 3px rgba(2, 6, 12, 0.55);
  --el-2: inset 0 0 0 1px rgba(255, 255, 255, 0.09),
          inset 0 0.5px 0 0 rgba(255, 255, 255, 0.08),
          0 4px 6px -4px rgba(2, 6, 12, 0.6),
          0 10px 24px -6px rgba(2, 6, 12, 0.55);
  --el-3: inset 0 0 0 1px rgba(255, 255, 255, 0.11),
          inset 0 0.5px 0 0 rgba(255, 255, 255, 0.1),
          0 20px 25px -5px rgba(2, 6, 12, 0.55),
          0 10px 30px -5px rgba(2, 6, 12, 0.5);
  --el-glow: 0 0 0 1px var(--ac-line), 0 0 18px rgba(0, 242, 254, 0.16);

  /* ── Motion ─────────────────────────────────────────────────────────
     100 ms on a control, and a curve that leaves fast and lands soft.
     That pairing is what the workbenches this is modelled on use, and it
     is the reason their interfaces feel immediate rather than animated:
     the movement is over before it can be watched, but the eye still gets
     told where the thing went.

     Only surfaces that ARRIVE (menus, popovers, toasts) get the bounce —
     a control that overshoots on every hover is a toy.                  */
  --mo-fast:  100ms;   /* hover, press, focus — anything under the cursor */
  --mo-base:  170ms;   /* a pane sliding, a row appearing                 */
  --mo-slow:  260ms;   /* a whole column opening                          */
  --mo-ease:  cubic-bezier(0.4, 1, 0.75, 0.9);
  --mo-bounce: cubic-bezier(0.54, 1.12, 0.38, 1.11);
  --mo-out:   cubic-bezier(0.16, 1, 0.3, 1);

  /* ── Layout ─────────────────────────────────────────────────────────
     The shell's fixed dimensions live here so panels never guess.       */
  --rail-w:      52px;
  --panel-w:     340px;
  --panel-w-lg:  460px;
  --ctl-h:       30px;   /* one control height, buttons and inputs alike */
  --ctl-h-sm:    24px;
  --statusbar-h: 26px;
  --panelhead-h: 40px;   /* the panel's own header row */
  --tabsbar-h:   30px;   /* the investigations row, above everything */
  --topbar-h:    40px;   /* matches it, so the two align */

  /* ── Layers ─────────────────────────────────────────────────────────
     A single ordered stack. Ad-hoc z-index values are how interfaces end
     up with dialogs behind overlays.                                    */
  --z-map:       0;
  --z-mapchrome: 10;
  --z-panel:     20;
  --z-rail:      30;
  --z-popover:   40;
  --z-modal:     50;
  --z-toast:     60;
}

/* Users who ask for reduced motion get none of it. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --mo-fast: 0ms;
    --mo-base: 0ms;
    --mo-slow: 0ms;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   THEMES

   A theme is a different set of values for the tokens above and nothing
   else. No component knows which theme is running, which is the whole
   reason the token layer exists — and why the scrollbars and the sliders
   follow a theme change without being told.

   Three things have to change together for a light theme, and missing any
   one of them is what makes a "light mode" look like a bug:

     THE SURFACES INVERT THEIR DIRECTION. On dark, a raised surface is
     LIGHTER than the one behind it. On light it is the other way round:
     white comes forward and grey recedes.

     ELEVATION CHANGES MECHANISM. The dark theme lifts a card with a
     hairline of light plus a shadow, because on a dark surface there is
     nothing darker left to cast. On a light surface that ring is invisible
     and an ordinary shadow does the work.

     THE ACCENT AND THE STATE COLOURS MOVE. #00f2fe on white is unreadable,
     and so are the greens and ambers that read perfectly on near-black.
     They darken rather than being reused.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Daylight: a clean, light workbench ────────────────────────────────── */
:root[data-theme="light"] {
  color-scheme: light;

  --sf-void:    #dfe5ec;   /* behind everything                           */
  --sf-base:    #f3f6f9;   /* app background                              */
  --sf-raised:  #ffffff;   /* rail, panel bodies                          */
  --sf-overlay: #ffffff;   /* cards, popovers, inputs                     */
  --sf-hover:   #eaf0f6;   /* hover / active row                          */
  --sf-sunken:  #eef2f6;   /* inputs, wells                               */
  /* A light interface is dimmed with grey, not with ink: near-black at
     this alpha turns the page into a photograph of itself. */
  --sf-scrim:   rgba(42, 56, 72, 0.55);

  --ln-subtle:  #e4e9f0;
  --ln-default: #ccd6e2;
  --ln-strong:  #93a9c0;

  --tx-primary:  #0d1b29;
  --tx-secondary:#2f4458;
  --tx-muted:    #5a7088;
  --tx-faint:    #8396aa;

  /* The brand cyan, taken down until it reads as ink rather than neon.
     --ac-bright is the STRONGEST here, not the lightest: on a light
     surface emphasis means darker. */
  --ac-bright: #055f6b;
  --ac:        #087f8f;
  --ac-dim:    #5aa7b4;
  --ac-ghost:  rgba(8, 127, 143, 0.10);
  --ac-line:   rgba(8, 127, 143, 0.32);

  --st-ok:      #0d7d53;
  --st-warn:    #9a5a00;
  --st-danger:  #c02432;
  --st-critical:#9c0f29;
  --st-info:    #1b6694;
  --st-ok-ghost:     rgba(13, 125, 83, 0.12);
  --st-warn-ghost:   rgba(154, 90, 0, 0.12);
  --st-danger-ghost: rgba(192, 36, 50, 0.12);

  /* No inset light ring: on white it cannot be seen. An ordinary shadow,
     tinted with the text colour so it stays in the same colour world. */
  --el-1: 0 0 0 1px rgba(13, 27, 41, 0.06),
          0 1px 2px rgba(13, 27, 41, 0.08);
  --el-2: 0 0 0 1px rgba(13, 27, 41, 0.07),
          0 2px 4px -2px rgba(13, 27, 41, 0.10),
          0 8px 16px -6px rgba(13, 27, 41, 0.12);
  --el-3: 0 0 0 1px rgba(13, 27, 41, 0.08),
          0 12px 20px -6px rgba(13, 27, 41, 0.14),
          0 6px 28px -8px rgba(13, 27, 41, 0.12);
  --el-glow: 0 0 0 1px var(--ac-line), 0 0 14px rgba(8, 127, 143, 0.18);
}

/* ── Operations: the dark workbench, named so it can be chosen ──────────
   The values are the ones in :root above; this block exists so "dark" is
   an explicit choice and not merely the absence of one. Anything that has
   to differ from the default goes here. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --sf-sunken: #080f19;
}

/* The default, when nobody has chosen: dark, as the application was drawn.
   Declared separately from [data-theme="dark"] so a missing attribute and
   an explicit dark are the same picture. */
:root:not([data-theme]) {
  color-scheme: dark;
  --sf-sunken: #080f19;
}
