/*  AXIS Design System – Tokens
 *  Colorway: AXIS Signal («Сигнал»), v0.9.0
 *  ---------------------------------------------------------------------------
 *  Three layers, in order. Never skip a layer downward.
 *
 *    1. PRIMITIVE  --axis-c-*     raw ramps. Theme-independent. Never used in a
 *                                 component – only semantic tokens may read them.
 *    2. SEMANTIC   --axis-*       roles ("surface", "danger"). Theme-dependent.
 *                                 This is what application CSS reads.
 *    3. COMPONENT  --axis-btn-*   per-component knobs, derived from semantic, so
 *                                 they track the theme with no dark-mode copy.
 *
 *  Light is the default; dark comes from the OS (prefers-color-scheme) or from
 *  data-theme="dark" on <html> – the explicit attribute wins over the OS.
 *
 *  The two themes are one character in two registers: light is a paper ledger
 *  (hairline structure, bare numerals, no glow), dark is a command center (the
 *  same structure over a deep canvas, and accents are allowed to glow). Both
 *  carry the same engineering-grid texture and the same telemetry details.
 *
 *  Rule: never a raw hex in a component. A component that needs a new value gets
 *  a new token, not a literal.
 * ------------------------------------------------------------------------- */

/* ═══════════════════════════════════════════════════════════════════════════
   LAYER 1 – PRIMITIVES
   Raw ramps. These do not change between themes; the semantic layer picks
   different steps per theme. Do not reference these from a component.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Signal – the brand hue. Deep marine blue, taken past the stock SaaS
        blue into the dark end, where it can carry text on white and still
        sit under white text. ─────────────────────────────────── */
  --axis-c-signal-50:  #e9f1fd;
  --axis-c-signal-100: #d2e5fc;
  --axis-c-signal-200: #a5c8f3;
  --axis-c-signal-300: #72a6e6;
  --axis-c-signal-400: #4280ca;
  --axis-c-signal-500: #05519c;   /* brand anchor (light): text on canvas AND the action fill */
  --axis-c-signal-600: #054688;
  --axis-c-signal-700: #043c74;
  --axis-c-signal-800: #043160;
  --axis-c-signal-900: #03274e;
  /* lifted steps for the dark theme */
  --axis-c-signal-250: #a9caf4;   /* hover of brand text on near-black */
  --axis-c-signal-280: #90b9ec;   /* brand anchor (dark): text, active nav, glow carrier */
  --axis-c-signal-350: #3293fe;   /* action fill (dark) – light fill, dark text on it */

  /* ── Flare – the guest accent. Marks what newly arrived and is not yet
        handled: the unread count, the "new" chip, one highlight in a chart.
        350 is the live flare and the loudest thing in the system; it is a
        dark-theme colour and a fill, never text on white (2.92 there). ── */
  --axis-c-flare-100: #f8ece7;
  --axis-c-flare-300: #f4ad90;   /* dark-theme accent text / dot */
  --axis-c-flare-350: #ff6700;   /* vivid signal flare: dark-theme accent, and fill under dark text */
  --axis-c-flare-400: #b0694a;   /* light-theme dot & mark – non-text use */
  --axis-c-flare-500: #8e4b2d;   /* accent text on soft, fill under white text */
  --axis-c-flare-700: #693721;
  --axis-c-flare-900: #472111;   /* dark-theme soft fill */

  /* ── Slate – the neutral ramp.
        Tinted toward the signal hue, never pure grey: the tint is most of the
        colorway's character. A stock grey ramp makes the signal read as an
        arbitrary accent on a template. ───────────────────────── */
  --axis-c-slate-0:   #ffffff;
  --axis-c-slate-25:  #f7f9fc;
  --axis-c-slate-50:  #f1f5fa;
  --axis-c-slate-100: #e6edf5;
  --axis-c-slate-150: #dee6f2;
  --axis-c-slate-200: #dce4f0;
  --axis-c-slate-300: #c1cfe1;
  --axis-c-slate-400: #9aafc8;
  --axis-c-slate-500: #6d85a2;
  /* Darkened from #55707d: muted text sits on the chip surface too, and that
     pair has to clear AA on its own (the v0.5.0 lesson, relearned by measure). */
  --axis-c-slate-550: #496485;
  --axis-c-slate-600: #435e7f;
  --axis-c-slate-700: #31455e;
  --axis-c-slate-800: #1b2d44;
  --axis-c-slate-900: #0d1c2d;
  --axis-c-slate-950: #0a131f;
  /* dark-theme surfaces */
  --axis-c-slate-d-canvas:  #0a131f;
  --axis-c-slate-d-surface: #101f31;
  --axis-c-slate-d-raised:  #182940;
  --axis-c-slate-d-chip:    #1d334d;
  --axis-c-slate-d-ink:     #e2edf9;
  --axis-c-slate-d-ink-2:   #bacee7;
  /* Secondary text in the dark theme: nearly neutral on purpose. The tint
     stays in the SURFACES; tinted secondary text at 11-12px reads as a link. */
  --axis-c-slate-d-muted:   #879fbd;

  /* ── Status hues ────────────────────────────────────────────
     Independent of the brand hue, so meaning never collides with identity.
     Soft fills are light enough that their own foreground clears AA – a status
     pill is text on the soft fill, so that pair is a real contrast pair. */
  --axis-c-green-100: #e9f5ed;
  --axis-c-green-500: #1a7a35;
  --axis-c-green-300: #54c97e;   /* dark theme */
  --axis-c-green-900: #12301d;
  --axis-c-amber-100: #f7f1da;
  --axis-c-amber-500: #7d6516;
  --axis-c-amber-300: #d3ab3f;   /* dark theme */
  --axis-c-amber-900: #302a10;
  --axis-c-red-100:   #fae9e6;
  --axis-c-red-500:   #bb3222;
  --axis-c-red-300:   #e57063;   /* dark theme */
  --axis-c-red-900:   #361a16;

  /* ── Data-visualisation series.
        A fixed, ordered categorical ramp. Charts must read these instead of
        re-deriving brand hexes per theme (which is how they drift). Ordered by
        first-use: series 1 is the brand, and later series stay distinguishable
        in both themes and under the common colour-vision deficiencies. ─────── */
  --axis-c-viz-1: #05519c;   /* signal   – the subject */
  --axis-c-viz-2: #0f7a68;   /* teal     */
  --axis-c-viz-3: #b3691a;   /* ochre    */
  --axis-c-viz-4: #7154c8;   /* violet   */
  --axis-c-viz-5: #a83a68;   /* mulberry */
  --axis-c-viz-6: #57771f;   /* olive    */
  --axis-c-viz-1-d: #90b9ec;
  --axis-c-viz-2-d: #45cbb4;
  --axis-c-viz-3-d: #e8a45f;
  --axis-c-viz-4-d: #a98ce0;
  --axis-c-viz-5-d: #d883a8;
  --axis-c-viz-6-d: #a3c56a;
}

/* ═══════════════════════════════════════════════════════════════════════════
   LAYER 2 – SEMANTIC (light – the paper ledger)
   Roles. This is the layer application CSS reads.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Brand ─────────────────────────────────────────────── */
  --axis-brand:           var(--axis-c-signal-500);
  --axis-brand-hover:     var(--axis-c-signal-600);
  --axis-brand-strong:    var(--axis-c-signal-700);
  --axis-brand-contrast:  var(--axis-c-slate-0);
  /* The ACTION FILL, split from --axis-brand on purpose. In the light ledger
     both are the same anchor. In the dark command center --axis-brand is the
     light text-on-canvas step, while the fill is the mid step carrying DARK
     text – a light key on a dark desk, the way instrument panels are lit. */
  --axis-brand-fill:          var(--axis-c-signal-500);
  --axis-brand-fill-hover:    var(--axis-c-signal-600);
  --axis-brand-fill-contrast: var(--axis-c-slate-0);
  --axis-brand-soft:      var(--axis-c-signal-50);    /* tinted background: active nav, selected row */
  --axis-brand-soft-hover:var(--axis-c-signal-100);
  --axis-brand-border:    var(--axis-c-signal-200);

  /* ── Accent (flare – a guest, see brand-guidelines §2) ──── */
  --axis-accent:          var(--axis-c-flare-400);  /* non-text: dots, marks, chart highlight */
  --axis-accent-fill:     var(--axis-c-flare-500);  /* text-bearing fill (badge) – passes AA with white */
  --axis-accent-strong:   var(--axis-c-flare-500);  /* accent text on a soft fill */
  --axis-accent-contrast: var(--axis-c-slate-0);
  --axis-accent-soft:     var(--axis-c-flare-100);

  /* ── Ink & surfaces ────────────────────────────────────── */
  --axis-ink:             var(--axis-c-slate-900);
  --axis-ink-2:           var(--axis-c-slate-700);
  --axis-muted:           var(--axis-c-slate-550);
  --axis-canvas:          var(--axis-c-slate-50);
  --axis-surface:         var(--axis-c-slate-0);
  --axis-surface-2:       var(--axis-c-slate-100);    /* rail, hover, zebra */
  --axis-surface-3:       var(--axis-c-slate-150);    /* pressed, nested panel */
  --axis-overlay:         var(--axis-c-slate-0);      /* popover / dropdown / menu */
  --axis-chip:            var(--axis-c-slate-150);
  --axis-line:            var(--axis-c-slate-200);
  --axis-line-strong:     var(--axis-c-slate-300);    /* table header rule, dialog divider */
  --axis-link:            var(--axis-c-signal-500);
  --axis-scrim:           rgba(16, 29, 36, .48);
  /* Tells the browser which way to paint the parts we cannot style: the
     <select> popup, scrollbars, date pickers, spinners, autofill. Without
     it a dark UI gets a white OS dropdown with a blue highlight. */
  color-scheme: light;
  /* Stays dark in BOTH themes: a toast and a tooltip are momentary overlays
     that must not blend into whichever surface they land on. */
  --axis-inverse-surface: var(--axis-c-slate-900);
  --axis-inverse-ink:     var(--axis-c-slate-0);
  --axis-danger-contrast: var(--axis-c-slate-0);
  --axis-inverse-ok:      var(--axis-c-green-300);

  /* ── Semantic status – colour, soft fill per state ──────── */
  --axis-ok:              var(--axis-c-green-500);
  --axis-ok-soft:         var(--axis-c-green-100);
  --axis-warn:            var(--axis-c-amber-500);
  --axis-warn-soft:       var(--axis-c-amber-100);
  --axis-danger:          var(--axis-c-red-500);
  --axis-danger-soft:     var(--axis-c-red-100);
  /* The live state ("в эфире") is the ok hue with a licence to breathe – the
     only motion loop in the system belongs to it. */
  --axis-live:            var(--axis-ok);

  /* ═══ Telemetry – the engineering-grid texture and the glow ═══
     The canvas carries a faint drafting grid with nodes at every fourth
     intersection. Light theme: printed on paper, no glow. Dark theme: the
     same plane as a lit board – accents may glow, nothing else does. */
  --axis-grid-line:   rgba(16, 29, 36, .045);
  --axis-grid-line-2: rgba(16, 29, 36, .03);
  --axis-grid-node:   rgba(16, 29, 36, .16);
  --axis-grid-step:   24px;
  --axis-grid-node-step: 96px;
  --axis-glow-brand:  none;
  --axis-glow-live:   none;
  /* Text selection is an interface surface too. */
  --axis-selection:   color-mix(in srgb, var(--axis-brand) 28%, transparent);

  /* ── Data-viz series (semantic aliases; charts read these) ─ */
  --axis-viz-1: var(--axis-c-viz-1);
  --axis-viz-2: var(--axis-c-viz-2);
  --axis-viz-3: var(--axis-c-viz-3);
  --axis-viz-4: var(--axis-c-viz-4);
  --axis-viz-5: var(--axis-c-viz-5);
  --axis-viz-6: var(--axis-c-viz-6);
  --axis-viz-grid: var(--axis-c-slate-200);
  --axis-viz-axis: var(--axis-c-slate-550);

  /* ── Chevron for <select> ──────────────────────────────────
     A data URI rather than a mask so it works without extra markup. Swapped per
     theme because a background-image cannot read currentColor. */
  --axis-chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%234d6672' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");

  /* Caret used as a MASK, so it follows currentColor. Distinct from
     --axis-chevron, which is a background-image and needs a baked colour. */
  --axis-caret-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");

  /* ── Focus ring ────────────────────────────────────────── */
  --axis-ring-width: 3px;
  --axis-ring: 0 0 0 var(--axis-ring-width) color-mix(in srgb, var(--axis-brand) 32%, transparent);
  --axis-ring-danger: 0 0 0 var(--axis-ring-width) color-mix(in srgb, var(--axis-danger) 32%, transparent);

  /* ═══ Typography ═══════════════════════════════════════════
     Two faces, two voices. IBM Plex Sans carries content; IBM Plex Mono is
     the telemetry voice – micro-labels, table headers, numerals, IDs,
     timestamps, the wordmark. Hierarchy inside each face comes from size and
     weight; the mono/sans switch itself is a semantic signal (data vs prose).
     Scale: 10, 11, 12, 13, 14, 16, 20, 24, 30 – integers only. */
  --axis-font-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --axis-font-mono: "IBM Plex Mono", "Consolas", "Menlo", monospace;

  --axis-text-3xs: 10px;  /* mono micro-label (uppercase, tracked) */
  --axis-text-2xs: 11px;  /* pill, dense caption */
  --axis-text-xs:  12px;  /* table cell, chip, control text */
  --axis-text-sm:  13px;  /* dense body, secondary prose */
  --axis-text-base:14px;  /* body, input value */
  --axis-text-md:  16px;  /* card title */
  --axis-text-lg:  20px;  /* section heading */
  --axis-text-xl:  24px;  /* page title */
  --axis-text-2xl: 30px;  /* stat value, display number */

  /* Line-height is per-role, not global. One global 1.55 leaked into buttons
     and table cells and made control heights unpredictable. */
  --axis-leading-none:  1;
  --axis-leading-tight: 1.2;    /* headings, display numbers */
  --axis-leading-snug:  1.35;   /* controls, table cells, dense UI */
  --axis-leading:       1.5;    /* prose body */

  /* Tracking is size-dependent. Negative tracking on 12px text hurts
     legibility, especially in Cyrillic; it belongs on large text only.
     The label track is wide on purpose: a mono micro-label reads as an
     engraved caption, not as a word. */
  --axis-tracking-tight: -0.02em;  /* ≥20px */
  --axis-tracking-snug:  -0.01em;  /* 16–19px */
  --axis-tracking:        0;       /* body */
  --axis-tracking-micro:  0.01em;  /* 11px sentence-case micro-label */
  --axis-tracking-wide:   0.04em;  /* uppercase sans, opt-in only */
  --axis-tracking-label:  0.12em;  /* uppercase mono telemetry labels */

  /* Plex ships 400/500/600 here; bolder steps alias to 600 rather than let
     the browser synthesise a faux bold. */
  --axis-w-regular:  400;
  --axis-w-medium:   500;
  --axis-w-semibold: 600;
  --axis-w-bold:     600;

  /* ═══ Spacing – 4px grid ═══════════════════════════════════
     Every value is a multiple of 4. Odd values (9px, 7px, 13px) are how a
     spacing system quietly dies. */
  --axis-space-0:   0;
  --axis-space-1:   4px;
  --axis-space-2:   8px;
  --axis-space-3:   12px;
  --axis-space-4:   16px;
  --axis-space-5:   20px;
  --axis-space-6:   24px;
  --axis-space-8:   32px;
  --axis-space-10:  40px;
  --axis-space-12:  48px;
  --axis-space-16:  64px;

  /* Rhythm tiers – the three legal gaps (brand-guidelines §4). Reach for these
     by name in layout; the numeric ramp above is for one-off insets. */
  --axis-gap-tight:   var(--axis-space-2);   /*  8 – inside a control */
  --axis-gap-group:   var(--axis-space-4);   /* 16 – form rows, card interior */
  --axis-gap-section: var(--axis-space-6);   /* 24 – between cards and sections */

  /* ═══ Density ══════════════════════════════════════════════
     Compact is the default: an operator scanning fifty rows needs the
     fiftieth on screen. The cozy and air tiers exist as a consumer-side
     switch (data-density on any container), not as a per-screen judgement
     call. Control heights do not change with density – only reading rows do. */
  --axis-density-row:   26px;  /* table row, list row */
  --axis-density-pad-y: var(--axis-space-1);
  --axis-density-pad-x: var(--axis-space-3);

  /* ═══ Control sizing ═══════════════════════════════════════
     Fixed heights, not min-height. min-height plus an inherited line-height
     made two buttons with identical classes render 32px and 33.4px. */
  --axis-control-sm: 28px;
  --axis-control:    36px;
  --axis-control-lg: 44px;
  --axis-control-pad-sm: var(--axis-space-2);
  --axis-control-pad:    var(--axis-space-3);
  --axis-control-pad-lg: var(--axis-space-4);

  /* ── Radius – the chamfer ─────────────────────────────────
     2px everywhere: square discipline with the digital point filed off.
     Dialogs get 4. Pills and avatars stay full capsules – that is their
     distinguishing mark, not decoration. Chat bubbles ride base + 2. */
  --axis-radius-xs:   2px;
  --axis-radius-sm:   2px;
  --axis-radius:      2px;
  --axis-radius-lg:   4px;
  --axis-radius-pill: 999px;

  /* ── Borders ──────────────────────────────────────────────── */
  --axis-border:        1px;
  --axis-border-strong: 2px;

  /* ── Icons ────────────────────────────────────────────────── */
  --axis-icon-xs:     14px;
  --axis-icon-sm:     16px;
  --axis-icon:        20px;
  --axis-icon-lg:     24px;
  --axis-icon-stroke: 2;

  /* ═══ Elevation ════════════════════════════════════════════
     The ledger is flat: a card lies in the plane of the page and is drawn by
     its hairline, full stop. Shadow means "floating above" and belongs only
     to surfaces that genuinely float – menu, dialog, toast, drawer. */
  --axis-shadow-none: none;
  --axis-shadow-sm:   0 1px 2px rgba(16, 29, 36, .06);
  --axis-shadow:      0 2px 4px rgba(16, 29, 36, .06), 0 1px 2px rgba(16, 29, 36, .04);
  --axis-shadow-md:   0 4px 12px -2px rgba(16, 29, 36, .10), 0 2px 4px -2px rgba(16, 29, 36, .06);
  --axis-shadow-lg:   0 12px 32px -8px rgba(16, 29, 36, .18), 0 4px 8px -4px rgba(16, 29, 36, .10);
  /* Deliberately no --axis-shadow-btn: buttons do not glow. */

  /* ── Z-index scale ────────────────────────────────────────── */
  --axis-z-base:    0;
  --axis-z-sticky:  10;
  --axis-z-dropdown:20;
  --axis-z-scrim:   40;
  --axis-z-dialog:  50;
  --axis-z-toast:   60;

  /* ── Motion ───────────────────────────────────────────────────
     Roles, not values: press, micro-reaction, state change, arriving layer.
     Exits run on --axis-dur-fast or faster: leaving is always quicker than
     arriving. Layout is moved by transform and opacity only; a state change
     moves colour and does not move layout. Nothing loops except the live dot,
     the skeleton and the ambient, and each loop takes --axis-ease-loop.
     The two toast values are read from JS: they are reading time, not motion,
     and prefers-reduced-motion does not shorten them. Everything else stops
     under prefers-reduced-motion. Which role takes which value, and what never
     moves at all: docs/ui-foundation.md §14. */
  --axis-ease:      cubic-bezier(.2, .7, .3, 1);
  --axis-ease-out:  cubic-bezier(0, 0, .2, 1);
  --axis-ease-loop: ease-in-out;
  --axis-dur-instant: 80ms;
  --axis-dur-fast:  120ms;
  --axis-dur:       200ms;
  --axis-dur-slow:  280ms;
  --axis-dur-stagger: 40ms;
  --axis-dur-loop:    2400ms;
  --axis-dur-ambient: 40s;
  --axis-dur-toast:      4s;
  --axis-dur-toast-undo: 8s;

  /* ── Layout ───────────────────────────────────────────────── */
  --axis-content-pad-x: var(--axis-space-8);
  --axis-content-pad-y: var(--axis-space-6);
  /* Height the topbar occupies. The bar is not pinned, but anchor scrolling
     still reserves this band so a jumped-to heading lands clear of it. */
  --axis-topbar-h: calc(var(--axis-content-pad-y) + var(--axis-control) + var(--axis-space-3));
  --axis-scroll-offset: calc(var(--axis-topbar-h) + var(--axis-space-3));
  --axis-rail-w:        224px;
  --axis-rail-w-narrow: 64px;
  /* The rail as a panel on a narrow screen. Wider than the docked rail: a panel
     that covers the screen carries the same words at touch size, and the canon
     forbids trading them for icons below 768 (docs/ux-foundation.md §4.6). */
  --axis-rail-w-mobile: 288px;
  /* The secondary rail is wider than the primary one: it lists the page's own
     data (conversation names, campaign names), which needs room to be read,
     where the primary rail lists seven fixed words. */
  --axis-subrail-w:     240px;
  /* Frame of a screen that has no navigation of its own - login, an adapter's
     settings page. Equal to the content of a screen WITH the rail at 1280:
     1280 - 224 rail - 2 x 32 padding. The frame stays wider than the measure
     because tables stand on it; the paragraph takes --axis-measure itself. */
  --axis-page-w:        992px;
  /* Prose max width. Measured on IBM Plex Sans at 14px over Cyrillic text:
     68ch ran to 82 characters on the longest line against a reading threshold
     of 75, 62ch keeps that line at 75 (docs/ui-foundation.md §5). */
  --axis-measure:       62ch;
}

/* ═══════════════════════════════════════════════════════════════════════════
   LAYER 3 – COMPONENT
   Derived from semantic, so they follow the theme with no dark-mode duplicate.
   Override one of these to reskin a single component without touching the rest.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Button */
  --axis-btn-h:            var(--axis-control);
  --axis-btn-pad-x:        var(--axis-space-4);
  --axis-btn-radius:       var(--axis-radius-sm);
  --axis-btn-font:         var(--axis-text-xs);
  --axis-btn-weight:       var(--axis-w-semibold);
  --axis-btn-bg:           var(--axis-brand-fill);
  --axis-btn-bg-hover:     var(--axis-brand-fill-hover);
  --axis-btn-bg-active:    var(--axis-brand-strong);
  --axis-btn-fg:           var(--axis-brand-fill-contrast);

  /* Input */
  --axis-input-h:          var(--axis-control);
  --axis-input-bg:         var(--axis-surface);
  --axis-input-border:     var(--axis-line-strong);
  --axis-input-radius:     var(--axis-radius-sm);

  /* Card */
  --axis-card-bg:          var(--axis-surface);
  --axis-card-border:      var(--axis-line);
  --axis-card-radius:      var(--axis-radius);
  --axis-card-pad:         var(--axis-space-4);
  --axis-card-shadow:      var(--axis-shadow-none);

  /* Rail / sidebar – the app-level navigation strip */
  --axis-rail-bg:          var(--axis-surface-2);
  --axis-rail-item-h:      var(--axis-control);
  --axis-rail-item-radius: var(--axis-radius-sm);

  /* Subrail – the in-page navigation strip beside the sidebar. Same surface,
     so the two read as one continuous band of navigation. */
  --axis-subrail-bg:       var(--axis-surface-2);

  /* Table */
  --axis-table-row-h:      var(--axis-density-row);
  --axis-table-pad-x:      var(--axis-density-pad-x);
  --axis-table-zebra:      transparent;
  --axis-table-hover:      var(--axis-surface-2);

  /* Dialog */
  --axis-dialog-w:         30rem;
  --axis-dialog-radius:    var(--axis-radius-lg);
  --axis-dialog-shadow:    var(--axis-shadow-lg);

  /* Instrument – the fused KPI block: cells divided by 1px machine seams */
  --axis-instrument-seam:  var(--axis-line);
  --axis-instrument-bg:    var(--axis-surface);

  /* Chat */
  --axis-bubble-radius:    var(--axis-radius-lg);   /* base + 2 */
  --axis-bubble-in-bg:     var(--axis-surface-2);
  --axis-bubble-out-bg:    color-mix(in srgb, var(--axis-brand) 10%, var(--axis-surface));
  --axis-bubble-out-border:color-mix(in srgb, var(--axis-brand) 28%, var(--axis-line));

  /* Command line */
  --axis-cmd-bg:           var(--axis-inverse-surface);
  --axis-cmd-ink:          var(--axis-inverse-ink);
  --axis-cmd-prompt:       var(--axis-brand);
}

/* ═══════════════════════════════════════════════════════════════════════════
   DARK THEME – the command center
   Only the semantic layer is restated. Primitives are shared; component tokens
   derive from semantic and therefore need no dark copy at all.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --axis-brand:           var(--axis-c-signal-280);
    --axis-brand-hover:     var(--axis-c-signal-250);
    --axis-brand-strong:    var(--axis-c-signal-350);
    --axis-brand-contrast:  var(--axis-c-slate-950);
    /* A light key on a dark desk: the fill is the mid step and carries DARK
       text. Instrument panels are lit, not painted. */
    --axis-brand-fill:          var(--axis-c-signal-350);
    --axis-brand-fill-hover:    var(--axis-c-signal-280);
    --axis-brand-fill-contrast: var(--axis-c-signal-900);
    --axis-brand-soft:      color-mix(in srgb, var(--axis-c-signal-280) 14%, transparent);
    --axis-brand-soft-hover:color-mix(in srgb, var(--axis-c-signal-280) 22%, transparent);
    --axis-brand-border:    color-mix(in srgb, var(--axis-c-signal-280) 34%, transparent);

    --axis-accent:          var(--axis-c-flare-350);
    --axis-accent-fill:     var(--axis-c-flare-350);
    --axis-accent-strong:   var(--axis-c-flare-350);
    --axis-accent-contrast: var(--axis-c-slate-950);
    --axis-accent-soft:     var(--axis-c-flare-900);

    --axis-ink:             var(--axis-c-slate-d-ink);
    --axis-ink-2:           var(--axis-c-slate-d-ink-2);
    --axis-muted:           var(--axis-c-slate-d-muted);
    --axis-canvas:          var(--axis-c-slate-d-canvas);
    --axis-surface:         var(--axis-c-slate-d-surface);
    --axis-surface-2:       var(--axis-c-slate-d-raised);
    --axis-surface-3:       var(--axis-c-slate-d-chip);
    --axis-overlay:         var(--axis-c-slate-d-raised);
    --axis-chip:            var(--axis-c-slate-d-chip);
    --axis-line:            rgba(255, 255, 255, .09);
    --axis-line-strong:     rgba(255, 255, 255, .18);
    --axis-link:            var(--axis-c-signal-280);
    --axis-scrim:           rgba(0, 0, 0, .60);
    color-scheme: dark;
    --axis-inverse-surface: var(--axis-c-slate-d-ink);
    --axis-inverse-ink:     var(--axis-c-slate-900);
    --axis-danger-contrast: var(--axis-c-slate-950);
    --axis-inverse-ok:      var(--axis-c-green-500);
    --axis-chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238ba1ac' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");

    --axis-ok:              var(--axis-c-green-300);
    --axis-ok-soft:         var(--axis-c-green-900);
    --axis-warn:            var(--axis-c-amber-300);
    --axis-warn-soft:       var(--axis-c-amber-900);
    --axis-danger:          var(--axis-c-red-300);
    --axis-danger-soft:     var(--axis-c-red-900);
    --axis-live:            var(--axis-ok);

    --axis-grid-line:   rgba(255, 255, 255, .05);
    --axis-grid-line-2: rgba(255, 255, 255, .035);
    --axis-grid-node:   rgba(255, 255, 255, .15);
    --axis-glow-brand:  0 0 14px rgba(108, 195, 230, .32);
    --axis-glow-live:   0 0 8px rgba(84, 201, 126, .60);
    --axis-selection:   color-mix(in srgb, var(--axis-c-signal-350) 40%, transparent);

    --axis-viz-1: var(--axis-c-viz-1-d);
    --axis-viz-2: var(--axis-c-viz-2-d);
    --axis-viz-3: var(--axis-c-viz-3-d);
    --axis-viz-4: var(--axis-c-viz-4-d);
    --axis-viz-5: var(--axis-c-viz-5-d);
    --axis-viz-6: var(--axis-c-viz-6-d);
    --axis-viz-grid: rgba(255, 255, 255, .10);
    --axis-viz-axis: var(--axis-c-slate-d-muted);

    --axis-shadow-sm: 0 1px 2px rgba(0, 0, 0, .40);
    --axis-shadow:    0 2px 4px rgba(0, 0, 0, .40), 0 1px 2px rgba(0, 0, 0, .30);
    --axis-shadow-md: 0 4px 12px -2px rgba(0, 0, 0, .55), 0 2px 4px -2px rgba(0, 0, 0, .40);
    --axis-shadow-lg: 0 12px 32px -8px rgba(0, 0, 0, .65), 0 4px 8px -4px rgba(0, 0, 0, .45);
  }
}

/* Explicit override – the in-app toggle stamps data-theme and beats the OS. */
:root[data-theme="dark"] {
  --axis-brand:           var(--axis-c-signal-280);
  --axis-brand-hover:     var(--axis-c-signal-250);
  --axis-brand-strong:    var(--axis-c-signal-350);
  --axis-brand-contrast:  var(--axis-c-slate-950);
  --axis-brand-fill:          var(--axis-c-signal-350);
  --axis-brand-fill-hover:    var(--axis-c-signal-280);
  --axis-brand-fill-contrast: var(--axis-c-signal-900);
  --axis-brand-soft:      color-mix(in srgb, var(--axis-c-signal-280) 14%, transparent);
  --axis-brand-soft-hover:color-mix(in srgb, var(--axis-c-signal-280) 22%, transparent);
  --axis-brand-border:    color-mix(in srgb, var(--axis-c-signal-280) 34%, transparent);

  --axis-accent:          var(--axis-c-flare-350);
  --axis-accent-fill:     var(--axis-c-flare-350);
  --axis-accent-strong:   var(--axis-c-flare-350);
  --axis-accent-contrast: var(--axis-c-slate-950);
  --axis-accent-soft:     var(--axis-c-flare-900);

  --axis-ink:             var(--axis-c-slate-d-ink);
  --axis-ink-2:           var(--axis-c-slate-d-ink-2);
  --axis-muted:           var(--axis-c-slate-d-muted);
  --axis-canvas:          var(--axis-c-slate-d-canvas);
  --axis-surface:         var(--axis-c-slate-d-surface);
  --axis-surface-2:       var(--axis-c-slate-d-raised);
  --axis-surface-3:       var(--axis-c-slate-d-chip);
  --axis-overlay:         var(--axis-c-slate-d-raised);
  --axis-chip:            var(--axis-c-slate-d-chip);
  --axis-line:            rgba(255, 255, 255, .09);
  --axis-line-strong:     rgba(255, 255, 255, .18);
  --axis-link:            var(--axis-c-signal-280);
  --axis-scrim:           rgba(0, 0, 0, .60);
  color-scheme: dark;
  --axis-inverse-surface: var(--axis-c-slate-d-ink);
  --axis-inverse-ink:     var(--axis-c-slate-900);
  --axis-danger-contrast: var(--axis-c-slate-950);
  --axis-inverse-ok:      var(--axis-c-green-500);
  --axis-chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238ba1ac' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");

  --axis-ok:              var(--axis-c-green-300);
  --axis-ok-soft:         var(--axis-c-green-900);
  --axis-warn:            var(--axis-c-amber-300);
  --axis-warn-soft:       var(--axis-c-amber-900);
  --axis-danger:          var(--axis-c-red-300);
  --axis-danger-soft:     var(--axis-c-red-900);
  --axis-live:            var(--axis-ok);

  --axis-grid-line:   rgba(255, 255, 255, .05);
  --axis-grid-line-2: rgba(255, 255, 255, .035);
  --axis-grid-node:   rgba(255, 255, 255, .15);
  --axis-glow-brand:  0 0 14px rgba(108, 195, 230, .32);
  --axis-glow-live:   0 0 8px rgba(84, 201, 126, .60);
  --axis-selection:   color-mix(in srgb, var(--axis-c-signal-350) 40%, transparent);

  --axis-viz-1: var(--axis-c-viz-1-d);
  --axis-viz-2: var(--axis-c-viz-2-d);
  --axis-viz-3: var(--axis-c-viz-3-d);
  --axis-viz-4: var(--axis-c-viz-4-d);
  --axis-viz-5: var(--axis-c-viz-5-d);
  --axis-viz-6: var(--axis-c-viz-6-d);
  --axis-viz-grid: rgba(255, 255, 255, .10);
  --axis-viz-axis: var(--axis-c-slate-d-muted);

  --axis-shadow-sm: 0 1px 2px rgba(0, 0, 0, .40);
  --axis-shadow:    0 2px 4px rgba(0, 0, 0, .40), 0 1px 2px rgba(0, 0, 0, .30);
  --axis-shadow-md: 0 4px 12px -2px rgba(0, 0, 0, .55), 0 2px 4px -2px rgba(0, 0, 0, .40);
  --axis-shadow-lg: 0 12px 32px -8px rgba(0, 0, 0, .65), 0 4px 8px -4px rgba(0, 0, 0, .45);
}

/* Explicit light – restates only what dark changed, so the toggle can return. */
:root[data-theme="light"] {
  --axis-brand:           var(--axis-c-signal-500);
  --axis-brand-hover:     var(--axis-c-signal-600);
  --axis-brand-strong:    var(--axis-c-signal-700);
  --axis-brand-contrast:  var(--axis-c-slate-0);
  --axis-brand-fill:          var(--axis-c-signal-500);
  --axis-brand-fill-hover:    var(--axis-c-signal-600);
  --axis-brand-fill-contrast: var(--axis-c-slate-0);
  --axis-brand-soft:      var(--axis-c-signal-50);
  --axis-brand-soft-hover:var(--axis-c-signal-100);
  --axis-brand-border:    var(--axis-c-signal-200);

  --axis-accent:          var(--axis-c-flare-400);
  --axis-accent-fill:     var(--axis-c-flare-500);
  --axis-accent-strong:   var(--axis-c-flare-500);
  --axis-accent-contrast: var(--axis-c-slate-0);
  --axis-accent-soft:     var(--axis-c-flare-100);

  --axis-ink:             var(--axis-c-slate-900);
  --axis-ink-2:           var(--axis-c-slate-700);
  --axis-muted:           var(--axis-c-slate-550);
  --axis-canvas:          var(--axis-c-slate-50);
  --axis-surface:         var(--axis-c-slate-0);
  --axis-surface-2:       var(--axis-c-slate-100);
  --axis-surface-3:       var(--axis-c-slate-150);
  --axis-overlay:         var(--axis-c-slate-0);
  --axis-chip:            var(--axis-c-slate-150);
  --axis-line:            var(--axis-c-slate-200);
  --axis-line-strong:     var(--axis-c-slate-300);
  --axis-link:            var(--axis-c-signal-500);
  --axis-scrim:           rgba(16, 29, 36, .48);
  color-scheme: light;
  --axis-inverse-surface: var(--axis-c-slate-900);
  --axis-inverse-ink:     var(--axis-c-slate-0);
  --axis-danger-contrast: var(--axis-c-slate-0);
  --axis-inverse-ok:      var(--axis-c-green-300);
  --axis-chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%234d6672' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");

  --axis-ok:              var(--axis-c-green-500);
  --axis-ok-soft:         var(--axis-c-green-100);
  --axis-warn:            var(--axis-c-amber-500);
  --axis-warn-soft:       var(--axis-c-amber-100);
  --axis-danger:          var(--axis-c-red-500);
  --axis-danger-soft:     var(--axis-c-red-100);
  --axis-live:            var(--axis-ok);

  --axis-grid-line:   rgba(16, 29, 36, .045);
  --axis-grid-line-2: rgba(16, 29, 36, .03);
  --axis-grid-node:   rgba(16, 29, 36, .16);
  --axis-glow-brand:  none;
  --axis-glow-live:   none;
  --axis-selection:   color-mix(in srgb, var(--axis-brand) 28%, transparent);

  --axis-viz-1: var(--axis-c-viz-1);
  --axis-viz-2: var(--axis-c-viz-2);
  --axis-viz-3: var(--axis-c-viz-3);
  --axis-viz-4: var(--axis-c-viz-4);
  --axis-viz-5: var(--axis-c-viz-5);
  --axis-viz-6: var(--axis-c-viz-6);
  --axis-viz-grid: var(--axis-c-slate-200);
  --axis-viz-axis: var(--axis-c-slate-550);

  --axis-shadow-sm: 0 1px 2px rgba(16, 29, 36, .06);
  --axis-shadow:    0 2px 4px rgba(16, 29, 36, .06), 0 1px 2px rgba(16, 29, 36, .04);
  --axis-shadow-md: 0 4px 12px -2px rgba(16, 29, 36, .10), 0 2px 4px -2px rgba(16, 29, 36, .06);
  --axis-shadow-lg: 0 12px 32px -8px rgba(16, 29, 36, .18), 0 4px 8px -4px rgba(16, 29, 36, .10);
}

/* ═══ Density switch ═════════════════════════════════════════
   Scoped, not global: any container may loosen its own reading rows.
   Compact (26px) is the default and needs no attribute. */
[data-density="cozy"] {
  --axis-density-row:   32px;
  --axis-density-pad-y: var(--axis-space-2);
}
[data-density="air"] {
  --axis-density-row:   40px;
  --axis-density-pad-y: var(--axis-space-3);
  --axis-density-pad-x: var(--axis-space-4);
}
