@charset "UTF-8";
/* ═══════════════════════════════════════════════════════════════════════
   aimy-ds.css — AiMY Design System, product-consumable layer
   ───────────────────────────────────────────────────────────────────────
   EXTRACTED, NOT AUTHORED. Do not edit this file to change a component —
   edit the design system and re-extract, or the product forks the system.

       node assets/ds-extract.js

   Source   design-system/index.html <style> block, commit 6817122
   Kept     tokens · light-theme overrides · base · every component section,
            including the .ds-prefixed components (.ds-tabs, .ds-switch,
            .ds-choice, .ds-range, .ds-progress, .ds-field, .ds-textarea,
            .ds-kbd, .ds-divider), the AiMY Canvas, the Doctrine Primitives
            and the Knowledge v2 Primitives, plus the reduced-motion block.
            NAVIGATION DEMOS is kept: despite the banner it holds .avatar,
            .user-pill, .tab, .tabs-strip and .nav-item.
   Dropped  documentation-site chrome only — the page's topbar, shell,
            sidebar, main, section furniture, its swatch/copy UI, #ds-toast,
            and the quick-find modal.
   Lifted   .ds-theme-toggle out of the dropped TOPBAR section: it is
            product chrome and every AiMY surface carries it.
   Pruned   light-theme overrides for dropped chrome. Their base rules are
            gone, so they can never match; css-audit.js cannot see them
            because it checks the other direction.

   The drop list is by banner section, never by ".ds-" prefix: nine real
   components carry that prefix and a prefix strip deletes them.
   ═══════════════════════════════════════════════════════════════════════ */
    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

    /* ═══════════════════════════════════════════════
       DESIGN TOKENS — single source of truth
       All surfaces import these exact values
    ═══════════════════════════════════════════════ */
    :root {
      /* ── AI Brand Gradient ── */
      --ai: linear-gradient(104deg, #0066ff 0%, #61adf1 47%, #45d3e6 100%);

      /* ── Dark Scale (navy-tinted) ── */
      --d950: #080b10;
      --d900: #0d1117;
      --d850: #141b24;
      --d800: #1c2630;
      --d750: #233040;
      --d700: #2e3d50;
      --d600: #4a5b6e;
      --d500: #637280;
      --d400: #8b9aaa;
      --d300: #b0bcca;
      --d200: #c8d2dc;
      --d100: #d8e0e8;
      --d50:  #eef2f6;

      /* ── Brand / Primary ── */
      --brand:        #3369ff;
      --brand-dim:    rgba(51,105,255,0.15);
      --brand-glow:   rgba(51,105,255,0.25);

      /* ── Product Accent (secondary — each Aimy product may re-theme this) ── */
      --accent:     #8b4ff4;
      --accent-rgb: 139,79,244;
      --accent-dim: rgba(139,79,244,0.15);
      --accent-glow:rgba(139,79,244,0.25);

      /* ── Secondary Accents ── */
      /* Cyan is the canonical name in the design system; --teal is kept as
         an alias because this library and the product both still ask for it
         by that name, and an alias costs nothing where a rename costs a
         sweep. Aliasing rather than duplicating also means the light theme
         re-points one token and the other two follow. */
      --cyan:        #45d3e6;
      --cyan-rgb:    69,211,230;
      --cyan-bg:     rgba(69,211,230,0.12);
      --cyan-border: rgba(69,211,230,0.30);
      --teal:        var(--cyan);
      --teal-dim:    var(--cyan-bg);
      --purple: #8b4ff4;

      /* ══ SEMANTIC STATUS — THE HUE CARRIES THE VERDICT ════════════
         This file spent a long time arguing the opposite: that four hues at
         full strength were four alarms, and that a quiet family of six would
         let a screen of labels read as one voice. That argument is correct
         about a screen where everything is tagged. It is the wrong argument
         for a screen where a tag is rare — and here it is rare: seven tones
         across the whole product, most of them neutral.

         At that density the failure inverts. A muted green and a muted clay
         at one chroma are two flavours of the same beige, and the reader has
         to READ the pill to learn the verdict, which is the one job the pill
         exists to save them. The design system settled it for the ecosystem:
         status is full saturation, used directly, so the verdict lands
         before the word does.

         Four hues, each with an -rgb companion for tinting, a -bg ground, a
         -border line in the same hue, and a -glow where a halo needs one.
         Always tint through the companion — rgba(var(--ok-rgb),.1) — never
         the literal, or the tint stays pinned to the dark value when the
         theme flips. */
      --ok:          #4ed6a1;
      --ok-rgb:      78,214,161;
      --ok-bg:       rgba(78,214,161,0.12);
      --ok-border:   rgba(78,214,161,0.30);
      --ok-glow:     rgba(78,214,161,0.20);
      --warn:        #f7c95c;
      --warn-rgb:    247,201,92;
      --warn-bg:     rgba(247,201,92,0.13);
      --warn-border: rgba(247,201,92,0.32);
      --err:         #ff7282;
      --err-rgb:     255,114,130;
      --err-bg:      rgba(255,114,130,0.12);
      --err-border:  rgba(255,114,130,0.30);
      --err-glow:    rgba(255,114,130,0.20);
      /* ══ AND ONE THAT IS NOT A LABEL ════════════════════════
         --err-strong stops something already IN FLIGHT — hanging up on a
         call mid-progress is the case it exists for. Never a badge ground,
         never a border, never status text. Where a red says what something
         IS, that is --err. Now that --err is itself a full red the gap
         between the two is deliberately small: what separates them is what
         the colour is DOING, not how loud it is. */
      --err-strong:  #ff5268;
      /* Provenance rather than verdict — informational, and the readable
         member of the AI ramp. Never on the same object as a verdict, so
         the two cannot collide. */
      --info:        #7ea7ff;
      --info-rgb:    126,167,255;
      --info-bg:     rgba(126,167,255,0.12);
      --info-border: rgba(126,167,255,0.28);
      /* Ink on a SOLID status fill. It inverts with the theme because a
         solid chip is bright in dark and deep in light. --heat-ink is the
         separate one for heat-scale cells, which are saturated tints in
         BOTH themes and want near-black in both — --text-on-status is wrong
         there and would go white on a light heat cell. */
      --text-on-status: #0d1117;
      --heat-ink:       #0d1117;
      /* The readable members of the AI ramp. --ai above is the gradient and
         it is decoration; these two carry text. */
      --ai-ink:      #61adf1;
      --ai-ink-soft: #a8ccff;
      --ai-rgb:      0,102,255;
      /* The label renderings of the two identity hues. They used to be
         separately desaturated values so they could join the quiet family;
         with the family gone they are the hues themselves, kept as tokens so
         the call sites do not have to change. */
      /* --teal-label can be the hue itself; --accent-label cannot. #8b4ff4
         on a 15% tint of itself over the card is 3.23:1, which is a purple
         nobody can read at 12px. This is the same hue carried up to where
         it holds a word: 5.11:1 on the card, 5.60 on the rail, which sits
         with --err at 5.55 and --info at 5.94 rather than above them. The
         accent names a KIND of thing, so it should not outrank a verdict. */
      --accent-label: #ab7ffb;
      --teal-label:   var(--cyan);

      /* ── Surface Tokens ── */
      --body-bg:          #0f1215;
      --card-bg:          #141b24;
      --card-bg-raised:   #1c2630;
      --card-border:      rgba(255,255,255,0.07);
      --card-border-hover:rgba(255,255,255,0.14);
      --card-border-focus:rgba(51,105,255,0.4);
      --panel-bg:         rgba(13,17,22,0.95);

      /* ── Overlay / Glass ── */
      --glass-bg:     rgba(20,27,36,0.85);
      --glass-border: rgba(255,255,255,0.08);

      /* ── Theme-aware helpers (overridden in light) ── */
      --ai-text: #61adf1;                  /* AI-blue text — darkened in light */
      --text-strong: #ffffff;              /* strongest text / gradient text stop */
      --hairline:    rgba(255,255,255,0.07);/* subtle dividers on raised surfaces */
      --code-bg:     #0b0f14;              /* code block bg — stays dark in both themes */

      /* ── Gradients ── */
      --grad-avatar: linear-gradient(135deg,#7c3aed,#3369ff);
      --grad-ellipse-1: radial-gradient(ellipse at 30% 50%, rgba(0,102,255,0.18) 0%, rgba(97,173,241,0.1) 28%, transparent 60%);
      --grad-ellipse-2: radial-gradient(ellipse at 75% 70%, rgba(69,211,230,0.1) 0%, rgba(139,79,244,0.07) 38%, transparent 60%);

      /* ── Layout ── */
      --topbar-height: 60px;
      --sidebar-width: 240px;

      /* ── Border Radius ── */
      --r-xs:  4px;
      --r-sm:  6px;
      --r-md:  8px;
      --r-lg:  10px;
      --r-xl:  12px;
      --r-2xl: 16px;
      --r-pill:9999px;

      /* ── Spacing (4px base) ── */
      --sp-1:  4px;
      --sp-2:  8px;
      --sp-3:  12px;
      --sp-4:  16px;
      --sp-5:  20px;
      --sp-6:  24px;
      --sp-8:  32px;
      --sp-10: 40px;
      --sp-12: 48px;
      --sp-15: 60px;

      /* ── Typography ── */
      /* ══ ONE FACE, EVERYWHERE ══════════════════════════
         Poppins sets every word in this product, body and titles alike. That
         is a decision rather than a default, so both tokens name it and there
         is no pairing left — nothing remains for a second face to do.

         ── What this costs, so nobody has to rediscover it ──

         Poppins has no tabular figures. Every `font-variant-numeric:
         tabular-nums` declaration in this build is therefore inert, and each
         count, duration and money column sets on proportional digits: a
         figure changes width when its value changes. Measured against
         controls that DO support the feature, so this is the font and not
         the test — digit-width spread at 100px, tabular-nums requested:

           Poppins   63.00     Urbanist  66.11     DM Sans  74.41   (inert)
           Figtree    0.00     Inter      0.00     Jakarta   0.00   (works)

         Figtree held this slot for exactly one commit and set those figures
         correctly. It was replaced deliberately. If aligned figures are ever
         wanted back without giving up this face, the cheap fix is a third
         token for numerals only, applied to elements that are PURELY a
         number and never to a sentence with one in it — a stray digit from
         another face inside running text shows. */
      --font-sans:    "Poppins", system-ui, sans-serif;   /* body AND titles */
      --font-display: "Poppins", system-ui, sans-serif;   /* the same face; the
                                    token stays so its callers keep working */
      --font-mono:    "JetBrains Mono", monospace;

      /* Font style */
      --fst-normal: normal;
      --fst-italic: italic;


      /* Font sizes — 12-step scale */
      /* ══ THREE SIZES, AND EACH ONE NAMES WHAT IT IS FOR ═══════════════
         12 — MINIMAL COMPONENTS. Tags, status labels, work states, and the
              metadata that sits beside something else: a timestamp, a
              count, a unit, an attribution. Things you recognise rather
              than read. At 14 a tag stops behaving like a mark and starts
              competing with the name next to it.
         14 — THE SMALLEST SENTENCE. A supporting line, help text, a dense
              cell. Anything with a verb in it starts here.
         16 — THE WORKING MINIMUM. Body, row text, card text, anything
              primary. Most of the product lives here.

         Nothing is smaller than 12, and 12 is never a paragraph. */
      --fs-2xs:  12px;   /* minimal components — a mark, not a sentence */
      --fs-xs:   14px;   /* the smallest sentence */
      --fs-sm:   16px;
      --fs-base: 16px;   /* body */
      --fs-md:   16px;
      --fs-lg:   18px;
      --fs-xl:   20px;
      --fs-2xl:  24px;
      --fs-3xl:  30px;
      --fs-4xl:  38px;
      --fs-5xl:  46px;

      /* ══ THE INK BAND — THREE VALUES, AND THEY ARE CLOSE TOGETHER ══════
         Muted text tested badly: readers skipped it, which means the ramp
         was not creating hierarchy, it was creating text nobody read. So
         the band that may carry type is narrow and every value in it is
         legible on its own.

         Only these carry type. --d300 and below are for rules, dots,
         dividers and disabled states — they are NON-TEXT, and the one
         exception is a placeholder, which has to read as an absence. */
      --ink-primary:     var(--d50);    /* anything you read */
      --ink-secondary:   var(--d100);   /* the supporting line under it */
      --ink-muted:       var(--d200);   /* the floor for type. Slightly quiet, still read */
      --ink-placeholder: var(--d400);   /* the ONE exception — must not read as a value */
      --ink-rule:        var(--d600);   /* NON-TEXT. Hairlines and dots. Never type. */

      /* Font weights */
      /* ══ THE LADDER, RE-CUT FOR POPPINS ═══════════════════
         These numbers moved because the face changed. The ROLES did not:
         --fw-bold still means "the emphatic one", it is just that in
         Poppins the emphatic one is 600.

         Poppins lays down more ink than Urbanist at every weight, and the
         gap widens as it gets heavier. Measured in canvas as alpha per px
         of line length — typographic colour, which is what the eye reads:

                      Urbanist   Poppins same number   drift
           regular      10.06        11.64             +15.7%
           medium       11.65        14.12             +21.2%
           semibold     13.74        16.60             +20.8%
           bold         15.44        19.34             +25.3%
           extrabold    16.83        21.37             +27.0%

         Every rank landed a fifth to a quarter heavier than the value the
         surface was calibrated against, and 47% of the runs on the desk
         sit at bold or above — so the page shouted. Poppins covers in
         300-700 the colour range Urbanist covered in 400-800, so the whole
         ladder drops one step and lands back on the intended colour:

                      target     now      drift
           regular     10.06     9.26     -8.0%   (300)
           medium      11.65    11.64     -0.1%   (400)
           semibold    13.74    14.12     +2.8%   (500)
           bold        15.44    16.60     +7.5%   (600)
           extrabold   16.83    19.34    +14.9%   (700)

         --fw-regular is 300 and deliberately unused: the type floor is 400
         or heavier below 18px, and every site that named it sits at 16px
         or under, so all twelve were moved to --fw-medium, which still
         holds 400. It is here for display sizes, where 300 is legal. */
      --fw-light:     200;
      --fw-regular:   300;
      --fw-medium:    400;
      --fw-semibold:  500;
      --fw-bold:      600;
      --fw-extrabold: 700;

      /* Line heights */
      --lh-none:    1;
      --lh-tight:   1.2;
      --lh-snug:    1.4;
      --lh-base:    1.55;
      --lh-relaxed: 1.75;

      /* Letter spacing */
      --ls-tighter: -0.03em;
      --ls-tight:   -0.02em;
      --ls-normal:  0;
      --ls-wide:    0.04em;
      --ls-wider:   0.08em;

      /* ── Motion ── */
      /* Press-release is the one interaction where 150ms reads as lag: the
         finger is up before the surface finishes answering. Without a step
         below --t-fast, every product invents its own value and they differ. */
      --t-press: 90ms;
      --t-fast: 150ms;
      --t-base: 200ms;
      --t-slow: 300ms;
      --ease-out:    cubic-bezier(0.22,1,0.36,1);
      --ease-spring: cubic-bezier(0.34,1.56,0.64,1);

      /* ── Shadow / Elevation ── */
      --shadow-sm: 0 1px 3px rgba(0,0,0,0.3);
      --shadow-md: 0 4px 16px rgba(0,0,0,0.35);
      --shadow-lg: 0 8px 32px rgba(0,0,0,0.4);
      --shadow-xl: 0 16px 48px rgba(0,0,0,0.5);
    }


    /* ═══════════════════════════════════════════════
       LIGHT THEME — token overrides only
       Same brand/semantic hues; neutral ramp inverted,
       surfaces/shadows re-tuned for a light background.
    ═══════════════════════════════════════════════ */
    :root[data-theme="light"] {
      /* Neutral ramp inverted: --d50 = strongest text, --d950 = lightest surface */
      --d950: #f7fafc;
      --d900: #eef2f6;
      --d850: #e4eaf0;
      --d800: #d8e0e8;
      --d750: #c8d2dc;
      --d700: #b0bcca;
      --d600: #6e7d8d;  /* muted labels/separators — #8b9aaa fails 3:1 on white */
      --d500: #637280;
      --d400: #566472;
      --d300: #3a4653;
      --d200: #2a3540;
      --d100: #1c2630;
      --d50:  #10151b;

      /* Brand tint slightly denser for contrast on white */
      --brand-dim:  rgba(51,105,255,0.12);
      --brand-glow: rgba(51,105,255,0.20);
      /* The accent itself has to darken on white. #8b4ff4 is 4.2:1 there,
         which fails the 12px label that wears it via --accent-label; the
         deeper purple clears with room and carries nav active, chip
         selection and the caret with it. */
      --accent:     #6725cc;
      --accent-rgb: 103,37,204;
      --accent-dim: rgba(103,37,204,0.10);
      --accent-glow:rgba(103,37,204,0.18);
      /* On white the accent is already deep enough to carry the label, so
         this one goes back to being the hue itself. */
      --accent-label: var(--accent);
      /* --cyan is very light in dark mode; on white it has to become a deep
         teal before it can carry text. --teal and --teal-dim alias --cyan,
         so re-pointing this one token moves all three. */
      --cyan:        #0d8f95;
      --cyan-rgb:    13,143,149;
      --cyan-bg:     rgba(13,143,149,0.14);
      --cyan-border: rgba(13,143,149,0.32);

      /* Semantic hues RE-DERIVED, not darkened by a step. The dark hues sit
         at 1.6–2.6:1 on white and cannot carry text at all, so each was
         re-picked against a contrast target and then re-checked inside a
         nested tint — a tag on a tinted card composites onto a darker ground
         than the card alone. Grounds and borders drop roughly a fifth of
         their alpha, because dark-on-light reads heavier than the reverse. */
      /* ══ THE BOLD FAMILY, BACK ═══════════════════════════
         These are the hues light carried until 8 Sep, restored on request.
         The set they replace was re-derived against a contrast target and
         came out a stop deeper and a lot quieter — a bottle green, a brown
         where amber had been. Correct by the numbers, and it took the
         colour out of the one theme that had room for it.

         THE TINT IS LIGHTER THAN THE INK, and that is deliberate rather than
         sloppy: `--ok-bg` is a lighter green than `--ok`, which is how the
         old family worked — the ground stays a wash while the word on it
         stays legible. `--ok-rgb` is the INK, since what reads it is a tint
         computed at some other alpha and it should track the word.

         WHAT THIS COSTS, measured on the card and on the body rather than
         asserted — the first draft of this comment guessed and got two of
         the three wrong:

             --ok    #0e9257   3.99 : 1 on white,  3.68 on the body
             --warn  #b26205   4.52 : 1            4.18
             --err   #d92d20   4.83 : 1            4.46
             --info  #067dc2   4.45 : 1            4.11
             --cyan  #0d8f95   3.90 : 1            3.61

         So the family clears the 3:1 a border, a dot, an icon or a tag's
         edge answers to, everywhere, and NONE of them clears the 4.5:1 that
         body copy needs on the body ground. That is the trade, and it is on
         the record so nobody re-derives it by accident: these are grounds
         and marks, not sentences. Where a sentence needs the hue, the ink is
         `--ok-text` / `--warn-text` / `--err-text`, which light gives its
         own deep values precisely so this set can stay bold. */
      --ok:          #0e9257;
      --ok-rgb:      14,146,87;
      --ok-bg:       rgba(23,178,106,0.14);
      --ok-border:   rgba(14,146,87,0.30);
      --ok-glow:     rgba(14,146,87,0.18);
      --warn:        #b26205;
      --warn-rgb:    178,98,5;
      --warn-bg:     rgba(247,144,9,0.14);
      --warn-border: rgba(178,98,5,0.30);
      --err:         #d92d20;
      --err-rgb:     217,45,32;
      --err-bg:      rgba(240,68,56,0.14);
      --err-border:  rgba(217,45,32,0.30);
      --err-glow:    rgba(217,45,32,0.18);
      /* Still a step deeper than `--err`: it stops something in flight. */
      --err-strong:  #b42318;
      --info:        #067dc2;
      --info-rgb:    6,125,194;
      --info-bg:     rgba(14,165,233,0.14);
      --info-border: rgba(6,125,194,0.30);
      /* A solid chip is deep on white, so its ink flips to white. A heat
         cell is a saturated tint in both themes and keeps its near-black. */
      --text-on-status: #ffffff;
      --heat-ink:       #0f172a;
      /* The gradient's mid blue is 2.4:1 on white and cannot carry text, so
         the gradient darkens for background-clip:text and the inks with it. */
      --ai:          linear-gradient(104deg, #0047c7 0%, #1f6fc4 47%, #0a7a8c 100%);
      --ai-rgb:      0,82,212;
      --ai-ink:      #0a57ac;
      --ai-ink-soft: #37618f;

      /* Surfaces */
      --body-bg:          #f4f6f9;
      --card-bg:          #ffffff;
      --card-bg-raised:   #f7f9fc;
      --card-border:      rgba(16,24,40,0.10);
      --card-border-hover:rgba(16,24,40,0.18);
      --card-border-focus:rgba(51,105,255,0.4);
      --panel-bg:         rgba(255,255,255,0.96);

      /* Glass */
      --glass-bg:     rgba(255,255,255,0.85);
      --glass-border: rgba(16,24,40,0.10);

      /* Theme-aware helpers */
      --ai-text: #1f5fd0;
      --text-strong: #10151b;
      --hairline:    rgba(16,24,40,0.09);
      /* --code-bg stays dark — code blocks keep their dark syntax theme */

      /* Softer, cooler shadows for light UI */
      --shadow-sm: 0 1px 3px rgba(16,24,40,0.08);
      --shadow-md: 0 4px 16px rgba(16,24,40,0.10);
      --shadow-lg: 0 8px 32px rgba(16,24,40,0.12);
      --shadow-xl: 0 16px 48px rgba(16,24,40,0.16);
    }

    /* ── Light-mode chrome overrides (topbar / sidebar / scrollbars use
       hard-coded dark surfaces; re-skin them for light) ── */
    :root[data-theme="light"] .ds-topbar {
      background: rgba(255,255,255,0.82);
      border-bottom-color: var(--card-border);
    }
    :root[data-theme="light"] .ds-sidebar {
      background: rgba(248,250,252,0.82);
      border-right-color: var(--card-border);
    }
    :root[data-theme="light"] .ds-theme-toggle { background: var(--card-bg); }
    :root[data-theme="light"] ::-webkit-scrollbar-thumb { background: rgba(16,24,40,0.18); }
    :root[data-theme="light"] ::-webkit-scrollbar-thumb:hover { background: rgba(16,24,40,0.30); }

    /* ── Light-mode contrast fixes: components that use white "wash" fills
       or pale text tuned for dark backgrounds. White fills flip to a dark
       overlay; pale text flips to the darker end of its hue. ── */
    /* Inputs & selects (older .input) */
    :root[data-theme="light"] .input { background: rgba(16,24,40,0.03); border-color: rgba(16,24,40,0.14); }
    :root[data-theme="light"] .input:hover { border-color: rgba(16,24,40,0.24); }
    :root[data-theme="light"] .input:focus { background: rgba(51,105,255,0.05); border-color: var(--brand); }
    /* Ghost & utility buttons */
    :root[data-theme="light"] .btn-ghost { background: rgba(16,24,40,0.05); border-color: rgba(16,24,40,0.12); }
    :root[data-theme="light"] .btn-ghost:hover,
    :root[data-theme="light"] .btn-ghost.is-hover { background: rgba(16,24,40,0.09); border-color: rgba(16,24,40,0.18); }
    :root[data-theme="light"] .copy-btn,
    :root[data-theme="light"] .copy-btn:hover { background: rgba(16,24,40,0.06); border-color: transparent; color: var(--d200); }
    /* Tags used to be flattened to this same grey pill on white, because the
       old family only darkened two of its hues and the rest could not carry
       text here. All four re-derive against white now, so every tone resolves
       through its own tokens and the flattening rule is gone.

       The neutral tone is the one that still needs an entry: its ground and
       its edge are a WHITE wash, and a white wash on a white card is nothing
       at all. It flips to a navy wash at the same two weights — navy rather
       than black, because a neutral black wash reads grey and dirty. */
    :root[data-theme="light"] .tag-neutral {
      background: rgba(15,23,42,0.038); border-color: rgba(15,23,42,0.105);
    }
    /* Chips & filters */
    :root[data-theme="light"] .chip.default { background: rgba(16,24,40,0.04); border-color: rgba(16,24,40,0.12); color: var(--ink-muted); }
    :root[data-theme="light"] .chip.default:hover { background: rgba(16,24,40,0.07); color: var(--d100); }
    :root[data-theme="light"] .chip.brand { color: #1f5fd0; }
    /* Active filter strip */
    :root[data-theme="light"] .afs { background: rgba(51,105,255,0.07); border-color: rgba(51,105,255,0.22); }
    :root[data-theme="light"] .afs-label { color: #2158e0; border-right-color: rgba(16,24,40,0.12); }
    :root[data-theme="light"] .afs-chip { background: rgba(51,105,255,0.10); border-color: rgba(51,105,255,0.28); color: #1b4fbf; }
    :root[data-theme="light"] .afs-chip strong { color: #143a94; }
    :root[data-theme="light"] .afs-chip .x { color: rgba(27,79,191,0.8); }
    :root[data-theme="light"] .afs-clear { color: var(--ink-muted); }
    :root[data-theme="light"] .afs-clear:hover { color: var(--d100); }
    /* Callouts — pale text → darker semantic hue */
    /* Semantic text on pale tints — mid-tone hues fail contrast on white,
       so tags / badges / chips use the darker shade of each hue in light mode. */
    /* The tag needs no entry here any more. Every semantic hue and every
       -bg / -border companion is re-derived against white in the light block
       above, so .tag-ok and .tag-err resolve correctly on their own; the
       literals that used to sit here were a patch for a palette that
       darkened only two of its four hues. .signal-badge and .chip do not
       render in this product, so their light inks are left as found. */
    :root[data-theme="light"] .signal-badge.ok,
    :root[data-theme="light"] .chip.ok   { color: #3f6b52; }
    :root[data-theme="light"] .signal-badge.err,
    :root[data-theme="light"] .chip.err   { color: #903b37; }
    /* The other four resolve through tokens that already darken on white,
       so they need no entry — these two are the light-mode inks the poles
       use, which are literals for the same reason. */
    :root[data-theme="light"] .chip.warn  { color: var(--ink-muted); }
    /* .tag-accent came off this: a tag is a label and the accent is not a
       verdict. The chip is a control holding a state, and keeps it. */
    :root[data-theme="light"] .chip.active { color: var(--accent-label); }
    /* Faint labels & stat deltas */
    :root[data-theme="light"] .stat-delta.up   { color: var(--ok); }
    :root[data-theme="light"] .stat-delta.down { color: var(--err); }
    /* Tab / table white-wash hovers */
    :root[data-theme="light"] .tab:hover { background: rgba(16,24,40,0.05); color: var(--d100); }

    /* ── AiMY Canvas — follows the theme. In light mode the chat bar, filter
       tray, and overlay become light surfaces; text tokens already flip. ── */
    /* ══ OFF-WHITE, NOT WHITE ═════════════════════════════
       Pure white is the brightest thing the light theme can produce, and the
       composer was wearing it on every surface — over a page at #f4f6f9 and
       over a canvas that is pale glass. It read as a slab punched out of both
       rather than as a control resting on them.

       #fafcfe is the value that works in both places, and finding it took
       measuring rather than taste. Translucency does nothing here: 72% white
       over near-white glass composites back to near-white. Going properly
       below the page — #f1f5fa, which looks right on the canvas — puts the
       bar DARKER than the body it floats over, so it sinks instead of rising.
       This sits above #f4f6f9 and below #ffffff, which is the only band where
       a raised control can be both. */
    :root[data-theme="light"] .aimy-float-bar,
    :root[data-theme="light"] .overlay-input-bar {
      background: #fafcfe;
      border-color: rgba(16,24,40,0.14);
      box-shadow: 0 8px 32px rgba(16,24,40,0.14), 0 0 0 1px rgba(16,24,40,0.03);
    }
    :root[data-theme="light"] .filter-tray-inner {
      background: rgba(255,255,255,0.94);
      border-color: rgba(16,24,40,0.12);
      box-shadow: 0 4px 20px rgba(16,24,40,0.16);
    }
    :root[data-theme="light"] .filter-tray-label { border-right-color: rgba(16,24,40,0.12); }
    :root[data-theme="light"] .filter-chip {
      background: rgba(16,24,40,0.05);
      border-color: rgba(16,24,40,0.12);
    }
    /* ══ LIGHT GLASS BRIGHTENS; IT DOES NOT DIM ═════════════════
       The base rule's `brightness(0.85)` is what gives the dark canvas its
       depth: the page behind sinks a stop and the panel floats. Light
       inherited it unchanged, and there the same filter is a grey cast — the
       backdrop goes muddy while a 60% veil sits on top of it, so the surface
       reads as frosted plastic rather than as glass. Nothing was wrong with
       the blur; the two adjustments either side of it pointed the wrong way
       for the theme.

       So light brightens instead, and the veil comes down to let the page
       through, which is the whole of what makes it read as glass. */
    :root[data-theme="light"] .aimy-overlay {
      background: rgba(255,255,255,0.45);
      backdrop-filter: blur(28px) saturate(1.5) brightness(1.06);
      -webkit-backdrop-filter: blur(28px) saturate(1.5) brightness(1.06);
    }
    :root[data-theme="light"] .overlay-close,
    :root[data-theme="light"] .overlay-badge { background: rgba(16,24,40,0.05); border-color: rgba(16,24,40,0.12); }
    :root[data-theme="light"] .overlay-close:hover { background: rgba(16,24,40,0.1); border-color: rgba(16,24,40,0.2); }
    /* ══ A SUGGESTION IS AN OFFER, NOT A CARD ═══════════════════
       Solid white, which on a dark canvas is the obvious read and on a light
       one turns every chip into an opaque tile sitting ON the surface. They
       are the lightest thing the page offers — four questions you may or may
       not want — and they were the most solid object on it.

       60% and a blur, so the ground they float on comes through them: the
       gate's bloom under one, the canvas glass under another. The border does
       the containing now, which is what a border is for. */
    :root[data-theme="light"] .overlay-sugg-chip {
      background: rgba(255,255,255,0.60);
      border-color: rgba(16,24,40,0.14);
      backdrop-filter: blur(8px);
      -webkit-backdrop-filter: blur(8px);
    }
    /* A message is not a raised control, so it does not need to sit above the
       ground the way the bar does — it can go properly below white and settle
       into the canvas instead of floating on it. The reader's own bubble is
       the accent and stays the loud one, which is right: one of the two is a
       thing you said. */
    :root[data-theme="light"] .chat-msg.aimy .msg-bubble { background: #edf2f8; border-color: rgba(16,24,40,0.10); }
    :root[data-theme="light"] .aimy-badge { color: #1f5fd0; border-color: rgba(0,102,255,0.3); }
    /* Logo tiles — the dark navy/purple surfaces sit too close to the logo's own
       blues in light mode; flip them to bright lavender so the mark reads clearly */
    :root[data-theme="light"] .aimy-float-icon,
    :root[data-theme="light"] .msg-avatar.aimy-av,
    :root[data-theme="light"] .aimy-av-tile {
      background: linear-gradient(135deg, #f2ecff, #e6efff);
      border-color: rgba(110,70,220,0.28);
    }
    :root[data-theme="light"] .aimy-float-icon { box-shadow: 0 0 12px rgba(110,70,220,0.15); }
    :root[data-theme="light"] .aimy-float-demo-shell { background: transparent; }
    /* Skeleton shimmer — white vanishes on light cards, so use a dark shimmer */
    :root[data-theme="light"] .skeleton {
      background: linear-gradient(90deg, rgba(16,24,40,0.06) 25%, rgba(16,24,40,0.13) 50%, rgba(16,24,40,0.06) 75%);
      background-size: 800px 100%;
    }
    /* AiMY toast is a light card in light mode — fix its white hairlines/shadow */
    :root[data-theme="light"] .aimy-toast { border-color: var(--card-border); box-shadow: var(--shadow-lg); }
    :root[data-theme="light"] .aimy-toast-divider { background: var(--hairline); }


    /* ═══════════════════════════════════════════════
       BASE
    ═══════════════════════════════════════════════ */
    html { scroll-behavior: smooth; }

    body {
      font-family: var(--font-sans);
      background: var(--body-bg);
      color: var(--d50);
      display: flex;
      flex-direction: column;
      min-height: 100vh;
    }

    /* Form-control reset.
       Components that omit a background, border, font or colour inherit
       whatever the UA supplies the moment they are used on the element they
       should be used on. `.tab` declares no background and no font-family, so
       on a <button> — the correct element for an interactive tab — buttonface
       showed through and the label rendered in Arial. `.link` kept the UA's
       2px outset border on three edges. Both were specimen'd only on <div>/<a>.

       At element specificity (0,0,1) every component class still wins; the
       only rule this changes is the one that was relying on a UA default it
       never asked for. */
    button, [type="button"], [type="submit"], [type="reset"] {
      background: none;
      border: 0;
      padding: 0;
      font: inherit;
      color: inherit;
      -webkit-appearance: none;
      appearance: none;
    }

    *:focus { outline: none; }
    button:focus-visible,
    a:focus-visible,
    [role="button"]:focus-visible,
    input:focus-visible,
    select:focus-visible {
      outline: 2px solid var(--brand);
      outline-offset: 2px;
      border-radius: var(--r-md);
    }

    ::-webkit-scrollbar { width: 5px; height: 5px; }
    ::-webkit-scrollbar-track { background: transparent; }
    ::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 3px; }
    ::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.14); }


    /* ═══════════════════════════════════════════════
       TAGS / BADGES
    ═══════════════════════════════════════════════ */
    /* ══ THE TAG READS THE TOKENS IT WAS GIVEN ════════════════════════
       Two literals, and both of them are the value a product overrides.
       `--fs-2xs` is 10px here and 11 in Sales, which raised it and wrote
       down why — eleven is the floor at which a capital is still a shape
       rather than a texture. `--ls-wide` is 0.04em here and 0.06 there,
       under a comment that says in as many words that four per cent is
       "uppercase with the fix left out": capitals need five to twelve.

       This component asked for neither. It hardcoded both, so the one
       element in the system whose whole job is small tracked capitals was
       the one element the small-tracked-capitals correction never reached.
       Sales has been rendering its own captions at 11/0.06 and its tags at
       10/0.04 side by side ever since.

       The line box is pinned for the same reason `.s-meta-st` pins its
       own: without it the pill's height is whatever line-height it happens
       to inherit, so the same tag is 21px in one place and 22 in another. */
    .tag {
      display: inline-flex; align-items: center; gap: 4px;
      /* ══ A WORD, NOT A SHOUT ══════════════════════════════════════
         Full capitals were doing two jobs and only one of them was real.
         The real one is "this is a label, not prose" — and the ground, the
         size and the weight already say that. The other was volume, and a
         label has no business being the loudest thing on a card.
         Capitals also cost legibility at 12px: every word becomes the same
         rectangle and the reader has to spell it. A capital on the first
         letter is enough. The tracking goes with the case — it was a
         correction FOR capitals, and on sentence case it is just gaps. */
      font-size: var(--fs-2xs); font-weight: 700; padding: 2px 8px;
      border-radius: var(--r-pill);
      line-height: 16px;
      vertical-align: middle; white-space: nowrap;
    }
    /* ══ THE TAG CARRIES ITS HUE ══════════════════════════════
       An earlier pass gave every tone one grey ground and no border, on the
       argument that eight tinted pills were eight coloured objects and none
       of them could recede. That holds where everything is tagged. This
       product tags rarely, and at that density a recessive pill is simply a
       pill you have to read.

       So the tag takes its tint as a ground, the full hue on the word, and a
       border in the same hue. The border had been argued away on the grounds
       that a hairline edge is this build's signature for something you can
       press — but that signature is a NEUTRAL hairline. An edge in a
       saturated hue at a third alpha is not mistakable for a ghost button,
       and it is what holds the pill's shape where a 12%-alpha ground on its
       own dissolves into the card behind it.

       Case and size are unchanged: a tag is still a name in sentence case at
       --fs-2xs, not a shout in capitals. What changed here is colour. */
    .tag-neutral {
      background: rgba(255,255,255,0.05); color: var(--ink-muted);
      border: 1px solid rgba(255,255,255,0.11);
    }
    .tag-ok     { background: var(--ok-bg);      color: var(--ok);           border: 1px solid var(--ok-border); }
    .tag-warn   { background: var(--warn-bg);    color: var(--warn);         border: 1px solid var(--warn-border); }
    .tag-err    { background: var(--err-bg);     color: var(--err);          border: 1px solid var(--err-border); }
    .tag-info   { background: var(--info-bg);    color: var(--info);         border: 1px solid var(--info-border); }
    /* Provenance: this came from AiMY. Cyan is the AI identity hue, so the
       provenance tag and the AI surface are the same colour. */
    .tag-teal,
    .tag-ai     { background: var(--cyan-bg);    color: var(--cyan);         border: 1px solid var(--cyan-border); }
    /* .tag-qa is the design system's name for this same object. */
    .tag-accent,
    .tag-qa     { background: var(--accent-dim); color: var(--accent-label); border: 1px solid rgba(var(--accent-rgb),0.22); }

    /* ══ SOLID — FOR A STATE, NOT A NAME ═══════════════════════
       The hue fills and the word inverts to --text-on-status. Reserved for
       short, high-priority states; the tinted tag stays the default for
       status and metadata, and a screen carrying two solid pills has one of
       them too many. */
    .tag-solid            { border-color: transparent; color: var(--text-on-status); }
    .tag-solid.tag-ok     { background: var(--ok); }
    .tag-solid.tag-warn   { background: var(--warn); }
    .tag-solid.tag-err    { background: var(--err); }
    .tag-solid.tag-info   { background: var(--info); }
    .tag-solid.tag-teal,
    .tag-solid.tag-ai     { background: var(--cyan); }

    /* ── Signal / Live Badge ── */
    .signal-badge {
      display: inline-flex; align-items: center; gap: 5px;
      font-size: var(--fs-2xs); font-weight: 700; padding: 3px 9px;
      border-radius: var(--r-pill);
    }
    .signal-badge.err { background: var(--err-bg); color: var(--err); border: 1px solid color-mix(in srgb, var(--err) 22%, transparent); }
    .signal-badge.ok  { background: var(--ok-bg);  color: var(--ok);  border: 1px solid color-mix(in srgb, var(--ok) 22%, transparent); }
    .signal-dot {
      width: 5px; height: 5px; border-radius: 50%; background: currentColor;
      animation: blink 1.2s ease-in-out infinite;
    }
    @keyframes blink { 0%,100%{opacity:1} 50%{opacity:0.2} }
    @keyframes spin  { to { transform: rotate(360deg); } }


    /* ═══════════════════════════════════════════════
       CHIPS & FILTERS
    ═══════════════════════════════════════════════ */
    .chip {
      display: inline-flex; align-items: center; gap: 5px;
      padding: 5px 14px; border-radius: var(--r-pill);
      font-size: 14px; font-weight: 600; cursor: pointer;
      transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast);
      white-space: nowrap;
      border: 1px solid transparent;
    }
    .chip.default {
      background: rgba(255,255,255,0.04);
      border-color: rgba(255,255,255,0.08);
      color: rgba(255,255,255,0.5);
    }
    .chip.default:hover {
      background: rgba(255,255,255,0.07);
      color: var(--d200);
    }
    .chip.active {
      background: var(--accent-dim);
      border-color: rgba(var(--accent-rgb),0.3);
      color: var(--accent);
    }
    .chip.brand {
      background: var(--brand-dim);
      border-color: rgba(51,105,255,0.3);
      color: #7badff;
    }
    .chip.ok    { background: var(--ok-bg);   border-color: color-mix(in srgb, var(--ok) 25%, transparent); color: var(--ok); }
    .chip.warn  { background: var(--warn-bg);  border-color: color-mix(in srgb, var(--warn) 25%, transparent);  color: var(--warn); }
    .chip.err   { background: var(--err-bg);   border-color: color-mix(in srgb, var(--err) 25%, transparent);  color: var(--err); }
    .chip-dismiss {
      font-size: 14px; line-height: 1; opacity: 0.5;
      cursor: pointer; margin-left: 2px;
    }
    .chip-dismiss:hover { opacity: 1; }

    /* Active Filter Strip */
    .afs {
      display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
      padding: 6px 12px; border-radius: var(--r-lg);
      background: rgba(51,105,255,0.05);
      border: 1px solid rgba(51,105,255,0.12);
      backdrop-filter: blur(12px);
    }
    .afs-label {
      font-size: 14px; font-weight: 700; color: rgba(99,169,255,0.45);
      letter-spacing: 0.08em; text-transform: uppercase;
      padding-right: 8px; border-right: 1px solid rgba(255,255,255,0.07);
      white-space: nowrap;
    }
    .afs-chip {
      display: inline-flex; align-items: center; gap: 4px;
      background: rgba(99,169,255,0.08); border: 1px solid rgba(99,169,255,0.18);
      border-radius: var(--r-pill); padding: 3px 9px;
      font-size: 14px; font-weight: 600; color: rgba(197,220,255,0.85);
    }
    .afs-chip strong { color: #a8ccff; }
    .afs-chip .x { color: rgba(168,204,255,0.35); cursor: pointer; margin-left: 2px; }
    .afs-clear {
      margin-left: auto; font-size: 14px; font-weight: 600;
      color: rgba(255,255,255,0.2); cursor: pointer;
    }
    .afs-clear:hover { color: rgba(255,255,255,0.5); }


    /* ═══════════════════════════════════════════════
       BUTTONS
    ═══════════════════════════════════════════════ */
    .btn {
      display: inline-flex; align-items: center; gap: 7px;
      font-family: var(--font-sans); font-size: 16px; font-weight: 700;
      /* Explicit, so height is a property of the button rather than of
         whatever container it lands in. Without it .btn-sm measured 29px
         inside a table row and 25px elsewhere — the same class, two heights.
         Values chosen to reproduce exactly what this page rendered before,
         measured: 32 / 24 / 37 including padding and border. */
      line-height: 14px;
      padding: 8px 16px; border-radius: var(--r-md);
      border: 1px solid transparent; cursor: pointer;
      transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast),
                  transform var(--t-fast), filter var(--t-fast);
      white-space: nowrap;
      text-decoration: none;
    }
    .btn svg { width: 14px; height: 14px; flex-shrink: 0; }

    .btn-brand  { background: var(--brand); color: #fff; border-color: var(--brand); }
    .btn-brand:hover  { background: #4d7fff; border-color: #4d7fff; }

    .btn-ghost  { background: rgba(255,255,255,0.05); color: var(--ink-muted); border-color: rgba(255,255,255,0.1); }
    .btn-ghost:hover  { background: rgba(255,255,255,0.09); color: var(--d50); border-color: rgba(255,255,255,0.16); }

    .btn-err    { background: var(--err-bg);  color: var(--err);  border-color: color-mix(in srgb, var(--err) 25%, transparent); }
    .btn-err:hover    { background: color-mix(in srgb, var(--err) 20%, transparent); }

    .btn-warn   { background: var(--warn-bg); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 25%, transparent); }
    .btn-warn:hover   { background: color-mix(in srgb, var(--warn) 20%, transparent); }

    .btn-ok     { background: var(--ok-bg);   color: var(--ok);   border-color: color-mix(in srgb, var(--ok) 25%, transparent); }
    .btn-ok:hover     { background: color-mix(in srgb, var(--ok) 22%, transparent); }

    .btn-accent     { background: var(--accent-dim); color: var(--accent); border-color: rgba(var(--accent-rgb),0.28); }
    .btn-accent:hover     { background: rgba(var(--accent-rgb),0.22); }

    .btn-sm { font-size: 14px; line-height: 12px; padding: 5px 11px; }
    .btn-lg { font-size: 14px; line-height: 15px; padding: 10px 20px; }
    .btn-icon { padding: 8px; }
    .btn:disabled { opacity: 0.38; cursor: not-allowed; }

    /* Press feedback. The library shipped :hover everywhere and :active almost
       nowhere — .btn.is-active is a static documentation helper, not the real
       pseudo-state — so each consuming product added its own. One speed, one
       displacement, defined once. Transform only, so nothing reflows. */
    .btn:active:not(:disabled),
    .entry-action:active,
    .filter-chip:active,
    .seg-btn:active,
    .nav-item:active,
    .tab:active {
      transform: translateY(1px);
      transition-duration: var(--t-press);
    }


    /* ═══════════════════════════════════════════════
       CARDS
    ═══════════════════════════════════════════════ */

    /* ── Base Card ── */
    .card {
      background: var(--card-bg); border: 1px solid var(--card-border);
      border-radius: var(--r-2xl);
      transition: border-color var(--t-base), transform var(--t-base), box-shadow var(--t-base);
    }
    .card:hover {
      border-color: var(--card-border-hover);
      transform: translateY(-1px);
      box-shadow: var(--shadow-md);
    }

    /* ── Briefing Card (bcard) ── */
    /* §1.2.1: the component said radius 16 / padding 14; the #bcard-extended
       specimen said radius 14 / padding 16 inline. The two were transposed,
       and the specimen is what everyone has actually looked at. Settled as
       radius 16 (the component's, via --r-2xl) and padding 16 (the
       specimen's, which reads better at briefing-grid card widths). */
    .bcard {
      background: var(--card-bg); border-radius: var(--r-2xl);
      border: 1px solid var(--card-border); padding: 16px;
      transition: border-color var(--t-base), transform var(--t-base), box-shadow var(--t-base);
    }
    .bcard:hover { border-color: var(--card-border-hover); transform: translateY(-1px); box-shadow: var(--shadow-md); }
    .bcard.p1 { border-color: color-mix(in srgb, var(--err) 20%, transparent); }
    .bcard.p2 { border-color: color-mix(in srgb, var(--warn) 20%, transparent); }
    .bcard.p3 { border-color: color-mix(in srgb, var(--ok) 16%, transparent); }
    .bcard.tier-primary { box-shadow: 0 0 0 1px rgba(var(--accent-rgb),0.3), var(--shadow-md); }

    .bcard-meta { display: flex; align-items: center; gap: 8px; margin-bottom: 9px; }
    .bcard-type { font-size: 14px; font-weight: 700; color: var(--ink-muted); letter-spacing: 0.05em; text-transform: uppercase; flex: 1; }
    .bcard-title { font-size: 16px; font-weight: 600; color: var(--d50); line-height: 1.45; margin-bottom: 10px; }
    .bcard-evidence { display: flex; gap: 5px; flex-wrap: wrap; }
    .evidence-pill {
      display: inline-flex; align-items: center; gap: 4px;
      background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08);
      border-radius: var(--r-pill); padding: 3px 8px;
      font-size: 14px; color: var(--ink-muted); font-weight: 500;
    }
    .evidence-pill .val { font-weight: 700; color: #fff; }

    /* ── Documented aliases (§1.2) ──────────────────────────────────────
       The #bcard-extended anatomy table and its copy-paste sample name these
       classes; the stylesheet implemented the same zones under different
       names. A developer copying the documented sample got an unstyled card
       and no error — the worst failure mode available, because it looks like
       their markup is wrong.

       Rather than rewrite the docs and break anyone already following them,
       the documented names are now real. Both spellings resolve to the same
       component; the .bcard-* names remain canonical. */
    .bcard-conclusion { font-size: 16px; font-weight: 600; color: var(--d50); line-height: 1.45; margin: 0 0 10px; }
    .evidence-row     { display: flex; gap: 5px; flex-wrap: wrap; }
    .type-label       { font-size: 14px; font-weight: 700; color: var(--ink-muted); letter-spacing: 0.05em; text-transform: uppercase; flex: 1; }
    .severity-dot     { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: var(--d500); }
    .severity-dot.p1  { background: var(--err); }
    .severity-dot.p2  { background: var(--warn); }
    .severity-dot.p3  { background: var(--ok); }
    .priority-badge {
      margin-left: auto; flex-shrink: 0;
      font-size: 14px; font-weight: 700; letter-spacing: 0.03em;
      padding: 2px 7px; border-radius: var(--r-pill);
      background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); color: var(--ink-muted);
    }
    .priority-badge.p1 { background: var(--err-bg);  border-color: color-mix(in srgb, var(--err) 25%, transparent); color: var(--err); }
    .priority-badge.p2 { background: var(--warn-bg); border-color: color-mix(in srgb, var(--warn) 25%, transparent); color: var(--warn); }
    .priority-badge.p3 { background: var(--ok-bg);   border-color: color-mix(in srgb, var(--ok) 25%, transparent); color: var(--ok); }
    /* Pass-through: .bcard already carries the padding, so a .bcard-body
       wrapper must not add a second inset. Documented as a zone, not a box. */
    .bcard-body   { display: block; }
    .bcard-action { display: flex; flex-direction: column; gap: 16px; align-items: center; justify-content: space-between; }
    .delta-up   { font-size: 14px; font-weight: 600; color: var(--ok); }
    .delta-down { font-size: 14px; font-weight: 600; color: var(--err); }

    /* ── Narrative Card ── */
    .narrative-card {
      background: var(--card-bg); border-radius: var(--r-2xl);
      border: 1px solid var(--card-border); padding: 20px 24px;
    }
    .narrative-meta {
      display: flex; align-items: center; gap: 8px; margin-bottom: 10px;
    }
    .narrative-body {
      font-size: 14px; font-weight: 500; color: var(--d50); line-height: 1.6;
    }

    /* ── Finding Item ── */
    .finding {
      display: flex; gap: 10px; align-items: flex-start;
      padding: 10px 12px; border-radius: var(--r-md);
      /* border-left: 2px solid transparent; */
      transition: background var(--t-fast);
    }
    .finding:hover { background: rgba(255,255,255,0.02); }
    .finding.f-err  { border-left-color: var(--err);  background: color-mix(in srgb,var(--err)  4%,var(--card-bg)); }
    .finding.f-warn { border-left-color: var(--warn); background: color-mix(in srgb,var(--warn) 4%,var(--card-bg)); }
    .finding.f-ok   { border-left-color: var(--ok);   background: color-mix(in srgb,var(--ok)   3%,var(--card-bg)); }
    .finding-icon {
      width: 20px; height: 20px; border-radius: var(--r-xs);
      display: flex; align-items: center; justify-content: center;
      flex-shrink: 0; font-size: 14px; font-weight: 700;
    }
    .finding-icon.f-err  { background: var(--err-bg);  color: var(--err); }
    .finding-icon.f-warn { background: var(--warn-bg); color: var(--warn); }
    .finding-icon.f-ok   { background: var(--ok-bg);   color: var(--ok); }
    .finding-title { font-size: 14px; font-weight: 700; color: var(--d50); margin-bottom: 2px; }
    .finding-sub   { font-size: 14px; color: var(--ink-muted); line-height: 1.4; }

    /* ── Surface Card (overview grid) ── */
    .surface-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 28px; }
    .surface-card {
      background: var(--card-bg); border: 1px solid var(--card-border);
      border-radius: var(--r-xl); padding: 18px 20px;
      transition: border-color var(--t-base), transform var(--t-base);
    }
    .surface-card:hover { border-color: var(--card-border-hover); transform: translateY(-1px); }
    .surface-icon {
      width: 34px; height: 34px; border-radius: var(--r-lg);
      display: flex; align-items: center; justify-content: center;
      margin-bottom: 10px; font-size: 16px;
    }
    .surface-name { font-size: 14px; font-weight: 700; color: var(--d50); margin-bottom: 3px; }
    .surface-type { font-size: 14px; font-weight: 700; color: var(--ink-muted); letter-spacing: 0.06em; text-transform: uppercase; margin-bottom: 7px; }
    .surface-desc { font-size: 14px; color: var(--ink-muted); line-height: 1.55; }


    /* ═══════════════════════════════════════════════
       FORM INPUTS
    ═══════════════════════════════════════════════ */
    .field { display: flex; flex-direction: column; gap: 5px; }
    .field-label {
      font-size: 14px; font-weight: 700; color: var(--ink-muted);
      letter-spacing: 0.02em;
    }
    .field-hint { font-size: 14px; color: var(--ink-muted); }
    .field-error { font-size: 14px; color: var(--err); }

    .input {
      background: rgba(255,255,255,0.04);
      border: 1px solid rgba(255,255,255,0.1);
      border-radius: var(--r-md);
      padding: 8px 12px;
      font-family: var(--font-sans); font-size: 14px;
      color: var(--d50); outline: none;
      transition: border-color var(--t-fast), background var(--t-fast);
      width: 100%;
    }
    .input::placeholder { color: var(--ink-muted); }
    .input:hover  { border-color: rgba(255,255,255,0.16); }
    .input:focus  { border-color: var(--brand); background: rgba(51,105,255,0.05); }
    .input.error  { border-color: var(--err); }
    .input.success{ border-color: var(--ok); }
    .input:disabled { opacity: 0.38; cursor: not-allowed; }

    .input-wrap {
      position: relative; display: flex; align-items: center;
    }
    .input-wrap .input { padding-left: 36px; }
    .input-wrap .input-icon {
      position: absolute; left: 11px;
      color: var(--ink-muted); pointer-events: none;
      display: flex; align-items: center;
    }
    .input-wrap .input-icon svg { width: 14px; height: 14px; }
    .input-wrap .input-suffix {
      position: absolute; right: 11px;
      font-size: 14px; color: var(--ink-muted); pointer-events: none;
    }

    textarea.input { resize: vertical; min-height: 80px; line-height: 1.6; }

    select.input {
      appearance: none; -webkit-appearance: none;
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238b9aaa' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
      background-repeat: no-repeat; background-position: right 12px center;
      padding-right: 36px; cursor: pointer;
    }

    /* ── Search Input ── */
    .search-input {
      display: flex; align-items: center; gap: 8px;
      background: rgba(255,255,255,0.04);
      border: 1px solid rgba(255,255,255,0.09);
      border-radius: var(--r-pill); padding: 6px 14px;
      transition: border-color var(--t-fast), background var(--t-fast);
    }
    .search-input:focus-within {
      border-color: rgba(255,255,255,0.18);
      background: rgba(255,255,255,0.06);
    }
    .search-input input {
      background: none; border: none; outline: none;
      font-family: var(--font-sans); font-size: 16px;
      color: var(--d50); flex: 1; min-width: 0;
    }
    .search-input input::placeholder { color: var(--ink-muted); }
    .search-input svg { width: 13px; height: 13px; color: var(--ink-muted); flex-shrink: 0; }

    /* ── Toggle Switch ── */
    .toggle-wrap { display: flex; align-items: center; gap: 10px; }
    .toggle {
      position: relative; width: 36px; height: 20px;
      flex-shrink: 0; cursor: pointer;
    }
    .toggle input { opacity: 0; width: 0; height: 0; position: absolute; }
    .toggle-track {
      position: absolute; inset: 0;
      background: rgba(255,255,255,0.12);
      border-radius: var(--r-pill);
      transition: background var(--t-fast);
    }
    .toggle input:checked ~ .toggle-track { background: var(--brand); }
    .toggle-thumb {
      position: absolute; top: 3px; left: 3px;
      width: 14px; height: 14px; border-radius: 50%;
      background: #fff;
      transition: transform var(--t-fast);
      box-shadow: 0 1px 3px rgba(0,0,0,0.4);
    }
    .toggle input:checked ~ .toggle-thumb { transform: translateX(16px); }
    .toggle-label { font-size: 16px; font-weight: 600; color: var(--ink-muted); }

    /* ── Checkbox ── */
    .checkbox-wrap { display: flex; align-items: center; gap: 8px; cursor: pointer; }
    .checkbox {
      width: 16px; height: 16px; border-radius: var(--r-xs);
      border: 1.5px solid rgba(255,255,255,0.2);
      background: transparent; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      transition: background-color var(--t-fast), border-color var(--t-fast);
    }
    .checkbox.checked {
      background: var(--brand); border-color: var(--brand);
    }
    .checkbox.checked::after {
      content: "✓"; font-size: 14px; color: #fff; font-weight: 700;
    }
    .checkbox-label { font-size: 16px; font-weight: 600; color: var(--ink-muted); }

    /* ── Radio ── */
    .radio-wrap { display: flex; align-items: center; gap: 8px; cursor: pointer; }
    .radio {
      width: 16px; height: 16px; border-radius: 50%;
      border: 1.5px solid rgba(255,255,255,0.2);
      background: transparent; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      transition: border-color var(--t-fast);
    }
    .radio.checked {
      border-color: var(--brand);
    }
    .radio.checked::after {
      content: ""; width: 7px; height: 7px;
      border-radius: 50%; background: var(--brand);
    }
    .radio-label { font-size: 16px; font-weight: 600; color: var(--ink-muted); }

    /* ── Masked / API Key Input ── */
    .masked-input-wrap {
      display: flex; align-items: center; gap: 8px;
    }
    .masked-input-wrap .input { font-family: var(--font-mono); letter-spacing: 0.08em; }
    .masked-input-wrap .btn-icon { flex-shrink: 0; }


    /* ═══════════════════════════════════════════════
       PROGRESS BARS
    ═══════════════════════════════════════════════ */
    .progress-bar-wrap { display: flex; flex-direction: column; gap: 4px; }
    .progress-bar-header {
      display: flex; justify-content: space-between; align-items: center;
    }
    .progress-bar-label { font-size: 14px; font-weight: 700; color: var(--ink-muted); }
    .progress-bar-value { font-size: 14px; font-weight: 700; color: var(--d50); }
    .progress-bar-track {
      height: 6px; background: rgba(255,255,255,0.07);
      border-radius: var(--r-pill); overflow: hidden;
    }
    /* scaleX, not width — a width transition relayouts on every frame.
       Set the level with `transform: scaleX(0–1)`, not `style="width:%"`. */
    .progress-bar-fill {
      height: 100%; width: 100%; border-radius: var(--r-pill);
      transform-origin: left center;
      transform: scaleX(var(--fill, 1));
      transition: transform var(--t-slow) var(--ease-out);
    }
    .progress-bar-fill.ok   { background: var(--ok); }
    .progress-bar-fill.warn { background: var(--warn); }
    .progress-bar-fill.err  { background: var(--err); }
    .progress-bar-fill.brand{ background: var(--brand); }
    .progress-bar-fill.ai   {
      background: linear-gradient(90deg, #0066ff, #45d3e6);
    }

    /* thick variant for KPI category breakdown */
    .progress-bar-track.thick { height: 10px; border-radius: var(--r-sm); }


    /* ═══════════════════════════════════════════════
       SCORE RING (SVG circular progress)
    ═══════════════════════════════════════════════ */
    .score-ring-wrap {
      display: flex; flex-direction: column; align-items: center; gap: 8px;
    }
    .score-ring { position: relative; display: inline-flex; }
    .score-ring svg { transform: rotate(-90deg); }
    .score-ring-track { fill: none; stroke: rgba(255,255,255,0.07); }
    /* stroke-dashoffset is the only way to draw an SVG arc, but the
       300ms ceiling still applies — 800ms read as sluggish. */
    .score-ring-fill  { fill: none; stroke-linecap: round;
      transition: stroke-dashoffset var(--t-slow) var(--ease-out);
    }
    .score-ring-fill.ok   { stroke: var(--ok); }
    .score-ring-fill.warn { stroke: var(--warn); }
    .score-ring-fill.err  { stroke: var(--err); }
    .score-ring-fill.brand{ stroke: var(--brand); }
    .score-ring-center {
      position: absolute; inset: 0;
      display: flex; flex-direction: column;
      align-items: center; justify-content: center;
    }
    .score-ring-number {
      font-size: 22px; font-weight: 800;
      letter-spacing: -0.03em; line-height: 1;
    }
    .score-ring-label {
      font-size: 14px; font-weight: 700; color: var(--ink-muted);
      letter-spacing: 0.05em; text-transform: uppercase; margin-top: 2px;
    }
    .score-ring-wrap .score-ring-title {
      font-size: 14px; font-weight: 700; color: var(--ink-muted); text-align: center;
    }


    /* ═══════════════════════════════════════════════
       OVERLAYS — Modal & Tooltip
    ═══════════════════════════════════════════════ */
    .modal-backdrop {
      position: fixed; inset: 0; z-index: 500;
      background: rgba(0,0,0,0.65); backdrop-filter: blur(6px);
      display: flex; align-items: center; justify-content: center;
    }
    .modal {
      background: var(--card-bg); border: 1px solid rgba(255,255,255,0.1);
      border-radius: var(--r-2xl); padding: 28px 32px;
      max-width: 520px; width: 100%;
      box-shadow: var(--shadow-xl);
      position: relative;
    }
    .modal-header {
      display: flex; align-items: flex-start; justify-content: space-between;
      gap: 16px; margin-bottom: 16px;
    }
    .modal-title { font-size: 16px; font-weight: 800; color: var(--d50); letter-spacing: -0.01em; }
    .modal-close {
      width: 28px; height: 28px; border-radius: var(--r-sm);
      background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.08);
      color: var(--ink-muted); cursor: pointer; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center; font-size: 14px;
      transition: background-color var(--t-fast), color var(--t-fast);
    }
    .modal-close:hover { background: rgba(255,255,255,0.1); color: var(--d50); }
    .modal-body { font-size: 14px; color: var(--ink-muted); line-height: 1.6; margin-bottom: 20px; }
    .modal-footer { display: flex; gap: 8px; justify-content: flex-end; }

    /* Tooltip */
    .tooltip-wrap { position: relative; display: inline-flex; }
    .tooltip {
      position: absolute; bottom: calc(100% + 8px); left: 50%;
      transform: translateX(-50%);
      background: var(--d800); border: 1px solid rgba(255,255,255,0.1);
      border-radius: var(--r-md); padding: 5px 10px;
      font-size: 14px; font-weight: 600; color: var(--d100);
      white-space: nowrap; pointer-events: none;
      box-shadow: var(--shadow-md);
      opacity: 0; transition: opacity var(--t-fast);
      z-index: 100;
    }
    .tooltip::after {
      content: ""; position: absolute; top: 100%; left: 50%;
      transform: translateX(-50%);
      border: 5px solid transparent;
      border-top-color: var(--d800);
    }
    .tooltip-wrap:hover .tooltip { opacity: 1; }


    /* ═══════════════════════════════════════════════
       SKELETON LOADER
    ═══════════════════════════════════════════════ */
    @keyframes shimmer {
      0%   { background-position: -400px 0; }
      100% { background-position:  400px 0; }
    }
    .skeleton {
      border-radius: var(--r-md);
      background: linear-gradient(90deg,
        rgba(255,255,255,0.04) 25%,
        rgba(255,255,255,0.09) 50%,
        rgba(255,255,255,0.04) 75%
      );
      background-size: 800px 100%;
      animation: shimmer 1.4s ease-in-out infinite;
    }
    .skeleton-text  { height: 12px; border-radius: var(--r-xs); }
    .skeleton-title { height: 20px; border-radius: var(--r-sm); }
    .skeleton-block { border-radius: var(--r-xl); }


    /* ═══════════════════════════════════════════════
       EMPTY STATE
    ═══════════════════════════════════════════════ */
    .empty-state {
      display: flex; flex-direction: column; align-items: center;
      justify-content: center; text-align: center;
      padding: 48px 32px;
      background: var(--card-bg); border: 1px dashed rgba(255,255,255,0.08);
      border-radius: var(--r-2xl);
    }
    .empty-state-icon {
      width: 48px; height: 48px; border-radius: var(--r-xl);
      background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08);
      display: flex; align-items: center; justify-content: center;
      font-size: 20px; margin-bottom: 16px;
    }
    .empty-state-title {
      font-size: 14px; font-weight: 700; color: var(--d50);
      margin-bottom: 6px; letter-spacing: -0.01em;
    }
    .empty-state-desc {
      font-size: 14px; color: var(--ink-muted); line-height: 1.6;
      max-width: 320px; margin-bottom: 20px;
    }


    /* ═══════════════════════════════════════════════
       NAVIGATION DEMOS
    ═══════════════════════════════════════════════ */
    .nav-item {
      display: flex; align-items: center; gap: 11px;
      padding: 10px 14px; border-radius: var(--r-md);
      font-size: 13px; font-weight: 600; color: var(--d400);
      cursor: pointer; border: 1px solid transparent;
      transition: background-color var(--t-base), border-color var(--t-base), color var(--t-base);
      max-width: 220px;
      text-decoration: none;
    }
    .nav-item svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; flex-shrink: 0; }
    .nav-item:hover { background: rgba(255,255,255,0.04); color: var(--d200); }
    .nav-item.active {
      background: var(--accent-dim); color: var(--accent);
      border-color: rgba(var(--accent-rgb),0.28);
    }
    .nav-item .nav-count {
      margin-left: auto; font-size: 10px; font-weight: 700;
      background: rgba(255,255,255,0.07); color: var(--d400);
      border-radius: var(--r-pill); padding: 1px 7px;
    }
    .nav-item.active .nav-count {
      background: rgba(var(--accent-rgb),0.15); color: var(--accent);
    }

    /* Product tab strip */
    .tabs-strip {
      display: inline-flex; align-items: center;
      border: 0.75px solid rgba(91,103,113,0.6); border-radius: var(--r-pill);
      padding: 3px; gap: 2px;
    }
    .tab {
      display: inline-flex; align-items: center; gap: 5px;
      padding: 5px 16px; border-radius: var(--r-pill);
      font-size: 16px; font-weight: 600; color: var(--ink-muted);
      cursor: pointer; border: 1px solid transparent;
      transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast);
    }
    .tab:hover { background: rgba(255,255,255,0.05); color: var(--d200); }
    .tab.active { color: var(--accent); }

    /* User pill / avatar */
    .avatar {
      border-radius: 50%; background: var(--grad-avatar);
      color: #fff; display: flex; align-items: center; justify-content: center;
      font-weight: 700; flex-shrink: 0;
    }
    .avatar-sm  { width: 24px; height: 24px; font-size: 14px; }
    .avatar-md  { width: 32px; height: 32px; font-size: 14px; }
    .avatar-lg  { width: 44px; height: 44px; font-size: 14px; }

    .user-pill {
      display: inline-flex; align-items: center; gap: 8px;
      padding: 4px 12px 4px 4px; border-radius: var(--r-pill);
      background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08);
      transition: border-color var(--t-fast);
    }
    .user-pill:hover { border-color: rgba(255,255,255,0.14); }
    .user-pill-name { font-size: 16px; font-weight: 700; color: var(--d50); }
    .user-pill-role { font-size: 14px; color: var(--ink-muted); }


    /* ═══════════════════════════════════════════════
       AIMY FLOAT INPUT BAR
    ═══════════════════════════════════════════════ */
    .aimy-float-demo-shell {
      position: relative; height: 100px;
      background: var(--d900); border-radius: var(--r-xl);
      overflow: hidden;
    }
    /* z-index: the float bar and the canvas overlay are designed to overlap,
       and only one order is ever correct — the canvas covers the bar. Both
       previously shipped at 10, which left paint order decided by DOM order:
       a coincidence that holds until someone reorders the markup or raises
       one of them. 200 / 500 are the values the reference implementation
       arrived at, with room between for product chrome. */
    .aimy-float-wrap {
      position: absolute;
      bottom: 14px; left: 20px; right: 20px; z-index: 200;
      display: flex; justify-content: center;
      pointer-events: none;
    }
    .aimy-float-bar {
      pointer-events: all;
      width: 100%; max-width: 760px;
      background: #1e2428;
      border: 1px solid rgba(255,255,255,0.09);
      border-radius: 40px;
      box-shadow:
        0 8px 32px rgba(0,0,0,0.55),
        0 0 0 1px rgba(0,0,0,0.3),
        inset 0 1px 0 rgba(255,255,255,0.05);
      display: flex; align-items: center; gap: 10px;
      padding: 8px;
      transition: border-color var(--t-base), box-shadow var(--t-base);
    }
    .aimy-float-bar:focus-within {
      border-color: rgba(var(--accent-rgb),0.55);
      box-shadow:
        0 12px 40px rgba(0,0,0,0.6),
        0 0 0 3px rgba(var(--accent-rgb),0.18),
        0 0 24px rgba(var(--accent-rgb),0.12),
        inset 0 1px 0 rgba(255,255,255,0.07);
      outline: none;
    }
    .aimy-float-bar.hidden { opacity: 0; pointer-events: none; transform: translateY(8px); }

    .aimy-float-icon {
      width: 36px; height: 36px; border-radius: 50%; position: relative;
      background: linear-gradient(135deg, #3d1f6b 0%, #1a3a6e 50%, #163b5e 100%);
      border: 1px solid rgba(139,79,244,0.3);
      display: flex; align-items: center; justify-content: center; flex-shrink: 0;
      box-shadow: 0 0 12px rgba(100,60,200,0.25);
    }
    .aimy-float-icon svg { width: 18px; height: 20px; }

    /* Unread alert badge on the icon */
    .float-badge {
      position: absolute; top: -3px; right: -3px;
      min-width: 16px; height: 16px; border-radius: var(--r-pill);
      /* NOT --err, which is a label hue: this is the one mark whose whole
         job is "now". --err is a full red again, but a label hue is still
         the wrong token here and still cannot carry white — #fff on #ff7282
         is 2.5:1. --err-strong is the deeper red this badge has to have. */
      background: var(--err-strong); border: 1.5px solid var(--body-bg);
      font-size: 9px; font-weight: 800; color: #fff;
      display: flex; align-items: center; justify-content: center;
      padding: 0 3px; letter-spacing: 0.02em;
    }

    .aimy-float-input {
      flex: 1; background: none; border: none; outline: none !important;
      font-family: var(--font-sans); font-size: 13.5px; font-weight: 500;
      color: var(--d50); caret-color: var(--accent);
      line-height: 1.4; padding: 0 4px;
    }
    .aimy-float-input::placeholder { color: var(--d500); font-weight: 400; }

    .aimy-float-hint {
      font-size: 11px; font-weight: 500; color: var(--d500);
      letter-spacing: 0.01em; white-space: nowrap; flex-shrink: 0;
      padding-right: 6px; pointer-events: none;
    }

    .aimy-float-send {
      width: 36px; height: 36px; border-radius: 50%;
      background: var(--accent); border: none; cursor: pointer;
      display: flex; align-items: center; justify-content: center; flex-shrink: 0;
      transition: transform var(--t-fast), box-shadow var(--t-fast);
      box-shadow: 0 2px 10px rgba(var(--accent-rgb),0.4);
    }
    .aimy-float-send:hover {
      box-shadow: 0 4px 18px rgba(var(--accent-rgb),0.55);
      transform: translateY(-1px);
    }
    .aimy-float-send:active { transform: scale(0.97); }
    .aimy-float-send svg { width: 14px; height: 14px; stroke: #fff; }

    /* Thinking state */
    .aimy-float-send.thinking {
      background: rgba(var(--accent-rgb),0.25);
      cursor: default; box-shadow: none; transform: none;
    }
    .aimy-float-send.thinking .send-icon { display: none; }
    .think-spinner {
      display: none; width: 14px; height: 14px;
      border: 2px solid rgba(var(--accent-rgb),0.3);
      border-top-color: var(--accent); border-radius: 50%;
      animation: spin 0.7s linear infinite;
    }
    .aimy-float-send.thinking .think-spinner { display: block; }


    /* ═══════════════════════════════════════════════
       FILTER TRAY (appears above float bar on focus)
    ═══════════════════════════════════════════════ */
    .filter-tray {
      position: absolute; bottom: 70px; left: 0; right: 0;
      display: flex; justify-content: center;
      pointer-events: none;
      opacity: 0; transform: translateY(6px);
      transition: opacity var(--t-base), transform var(--t-base);
    }
    .filter-tray.visible { opacity: 1; transform: translateY(0); pointer-events: all; }
    .filter-tray-inner {
      display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
      padding: 7px 12px; border-radius: var(--r-pill);
      background: rgba(20,27,36,0.9); backdrop-filter: blur(12px);
      border: 1px solid rgba(255,255,255,0.08);
      box-shadow: 0 4px 20px rgba(0,0,0,0.4);
    }
    .filter-tray-label {
      font-size: 14px; font-weight: 700; color: var(--ink-muted);
      letter-spacing: 0.07em; text-transform: uppercase;
      padding-right: 8px; border-right: 1px solid rgba(255,255,255,0.07);
      white-space: nowrap;
    }
    .filter-chip {
      display: inline-flex; align-items: center;
      padding: 4px 12px; border-radius: var(--r-pill);
      font-family: var(--font-sans); font-size: 14px; font-weight: 600;
      color: var(--ink-muted); cursor: pointer;
      background: rgba(255,255,255,0.05);
      border: 1px solid rgba(255,255,255,0.1);
      transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast);
    }
    .filter-chip:hover {
      background: rgba(var(--accent-rgb),0.12);
      border-color: rgba(var(--accent-rgb),0.3);
      color: var(--accent);
    }
    .filter-chip.active {
      background: var(--accent-dim);
      border-color: rgba(var(--accent-rgb),0.35);
      color: var(--accent);
    }


    /* ═══════════════════════════════════════════════
       AIMY CANVAS OVERLAY
    ═══════════════════════════════════════════════ */
    .aimy-overlay-demo {
      position: relative; height: 480px; border-radius: var(--r-xl); overflow: hidden;
      background: var(--d900);
    }
    .aimy-overlay {
      position: absolute; inset: 0; z-index: 500;   /* above .aimy-float-wrap (200) */
      backdrop-filter: blur(28px) saturate(1.4) brightness(0.85);
      -webkit-backdrop-filter: blur(28px) saturate(1.4) brightness(0.85);
      background: rgba(20,27,34,0.30);
      display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
      padding: 0 0 28px;
      opacity: 0; pointer-events: none;
      transition: opacity 280ms cubic-bezier(0.22,1,0.36,1);
    }
    .aimy-overlay.open { opacity: 1; pointer-events: all; }

    .overlay-close {
      position: absolute; top: 20px; right: 20px;
      width: 36px; height: 36px; border-radius: 10px;
      background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.1);
      cursor: pointer; display: flex; align-items: center; justify-content: center;
      color: var(--d300);
      transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
    }
    .overlay-close:hover { background: rgba(255,255,255,0.1); border-color: rgba(255,255,255,0.18); color: var(--d50); }
    .overlay-close svg { width: 16px; height: 16px; stroke: currentColor; stroke-width: 2; }

    .overlay-badge {
      position: absolute; top: 24px; left: 50%; transform: translateX(-50%);
      display: flex; align-items: center; gap: 6px;
      font-size: 11px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
      color: var(--d400); padding: 5px 14px;
      background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08);
      border-radius: var(--r-pill); white-space: nowrap;
    }

    .overlay-thread {
      width: 100%; max-width: 720px;
      flex: 1; overflow-y: auto; padding: 80px 24px 16px;
      display: flex; flex-direction: column; gap: 16px;
    }

    /* Suggested prompt chips */
    .overlay-suggestions {
      display: flex; flex-wrap: wrap; gap: 7px;
      justify-content: center; padding: 40px 0 20px;
    }
    .overlay-sugg-chip {
      font-family: var(--font-sans); font-size: 12px; font-weight: 600;
      padding: 7px 16px; border-radius: var(--r-pill);
      background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1);
      color: var(--d300); cursor: pointer;
      transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast);
    }
    .overlay-sugg-chip:hover {
      background: rgba(var(--accent-rgb),0.1);
      border-color: rgba(var(--accent-rgb),0.25);
      color: var(--accent);
    }

    /* Chat messages */
    .chat-msg {
      display: flex; gap: 10px; align-items: flex-start; max-width: 640px;
    }
    .chat-msg.user { flex-direction: row-reverse; margin-left: auto; }
    .msg-avatar {
      width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
      background: var(--grad-avatar);
      display: flex; align-items: center; justify-content: center;
      font-size: 14px; font-weight: 700; color: #fff;
    }
    .msg-avatar.aimy-av {
      background: linear-gradient(135deg, #3d1f6b, #1a3a6e);
      border: 1px solid rgba(139,79,244,0.3);
    }
    /* Generic AiMY logo tile — same dark surface, for ad-hoc avatar boxes */
    .aimy-av-tile {
      background: linear-gradient(135deg, #3d1f6b, #1a3a6e);
      border: 1px solid rgba(139,79,244,0.3);
    }
    .msg-bubble {
      padding: 10px 14px; border-radius: var(--r-xl);
      font-size: 14px; font-weight: 500; line-height: 1.55;
    }
    .chat-msg.aimy .msg-bubble {
      background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.07);
      color: var(--d50); border-radius: 4px 16px 16px 16px;
    }
    .chat-msg.user .msg-bubble {
      background: var(--accent-dim); border: 1px solid rgba(var(--accent-rgb),0.2);
      color: var(--d100); border-radius: 16px 4px 16px 16px;
    }

    /* Overlay input bar */
    .overlay-input-wrap {
      width: 100%; max-width: 720px; padding: 0 12px;
    }
    .overlay-input-bar {
      display: flex; align-items: center; gap: 10px;
      background: #1e2428; border: 1px solid rgba(255,255,255,0.1);
      border-radius: 40px; padding: 8px;
      transition: border-color var(--t-base), box-shadow var(--t-base);
    }
    .overlay-input-bar:focus-within {
      border-color: rgba(var(--accent-rgb),0.45);
      box-shadow: 0 0 0 3px rgba(var(--accent-rgb),0.12);
    }
    .overlay-input {
      flex: 1; background: none; border: none; outline: none;
      resize: none; overflow: hidden;
      font-family: var(--font-sans); font-size: 13.5px; font-weight: 500;
      color: var(--d50); caret-color: var(--accent);
      line-height: 1.5; padding: 0 4px; max-height: 120px;
    }
    .overlay-input::placeholder { color: var(--d500); font-weight: 400; }
    .overlay-send {
      width: 36px; height: 36px; border-radius: 50%;
      background: var(--accent); border: none; cursor: pointer;
      display: flex; align-items: center; justify-content: center; flex-shrink: 0;
      transition: transform var(--t-fast), box-shadow var(--t-fast);
      box-shadow: 0 2px 10px rgba(var(--accent-rgb),0.4);
    }
    .overlay-send:hover { transform: translateY(-1px); box-shadow: 0 4px 18px rgba(var(--accent-rgb),0.55); }
    .overlay-send svg { width: 14px; height: 14px; stroke: #fff; }


    /* ═══════════════════════════════════════════════
       PORTED WHOLE FROM KNOWLEDGE'S DESIGN SYSTEM

       Not rebuilt. Knowledge's copy of this file already carries the beam and
       the stop square, and its own comment says they ride `.aimy-float-bar` —
       this bar, by name — because the two products share one composer in
       three shells. What was missing here was the block itself: this file is
       an older cut of the same stylesheet.

       Taken byte for byte and dropped at the same seam it sits at there, so
       the two files stay a clean diff of each other. Everything below to the
       badge block is theirs, including the reasoning.
    ═══════════════════════════════════════════════ */
    /* ═══════════════════════════════════════════════
       THE BEAM — the composer while AiMY is answering

       A glow that rides the border of the bar for as long as an answer is being
       produced. It is the same fact the thinking mark carries inside the thread,
       put where the eye already is: you asked from the bar, so the bar is what
       should tell you the question was taken.

       It rides both composers the product has — .overlay-input-bar on the gate
       and in the canvas, .aimy-float-bar on the workbench — because they are
       one control in three shells, and an answer is being produced for
       whichever of them is on screen.

       ══ THE COLOUR DOES NOT MOVE. THE WINDOW ONTO IT DOES. ════════════════
       This is the whole mechanism, and it is worth stating plainly because
       every obvious reading of "a beam going round a border" is a different
       thing that looks wrong.

       Seven coloured blobs are pinned to fixed points ON the perimeter — some
       pushed just past it, which is why several sit at -6% or 100% — in the
       order of --ai. They never move. Over them sits a CONIC GRADIENT USED AS A
       MASK, a soft wedge of opacity with transparency either side of it, and
       what animates is the single angle that conic is drawn from.

       So the wedge sweeps the border and reveals whatever colour is pinned
       under it at that moment. The light appears to travel and to change colour
       as it travels, while nothing coloured has moved at all — and because the
       colours are fixed to the shape, the bar's own corners and ends are lit by
       the blobs nearest them rather than by whatever a travelling lamp happened
       to be carrying when it got there.

       A slow HUE SHIFT runs underneath, ±30° over 18 seconds, so the palette
       drifts on a period long enough that you never see it turn.

       ══ THE WEDGE IS WIDER THAN THE REFERENCE'S, AND HAS TO BE ════════════
       A cone measures ANGLE, and angle maps onto a perimeter evenly only on a
       shape near square. The reference is a 348×122 card — about 3:1, where the
       mismatch does not show. This bar is 720×54, about 14:1, and there the two
       long edges are 45% of the distance but 48% of the turn while each end is
       5.4% of the distance in 2.4% of the turn. The light therefore crosses the
       two ends around 2.2× quicker than it crosses the edges, and a narrow wedge
       turns that into a visible flick twice a lap.

       Widening the wedge is what absorbs it: the stroke's runs 42%→90% of the
       turn rather than 54%→78%, and the bloom's plateau is 3% of the turn rather
       than 0.5% — at any speed, half a percent of a turn is a hard line rather
       than a light. Both peaks come DOWN as they widen, 0.75 to 0.62 and 0.85 to
       0.70, because a wedge twice as wide lays down twice as much light for the
       same stop values.

       4.2 SECONDS A LAP, against the reference's 1.96. The reference sweeps a
       card you look at; this sweeps the control you are waiting at, and it has
       to still be doing it in thirty seconds' time without having become the
       thing in the room.

       THREE LAYERS, in the order they stack:
         · ::before  the inner glow — the blobs at low alpha, held to the outer
                     band of the bar by two linear masks, so it hugs the edge
                     rather than filling the middle
         · ::after   the stroke — a white wedge over the same blobs, cut to the
                     border itself by border-box-minus-content-box
         · > i       the bloom — the wedge again, blurred, which is what makes
                     the leading edge read as light rather than as paint

       The opacities — 0.42, 0.26, 0.24 — are what keep it quiet enough to be
       caught out of the corner of the eye rather than looked at.

       THE BAR TAKES A STACKING CONTEXT AND THE BEAM SITS AT -1. A negative
       child paints ABOVE the background of the element that forms the context
       and BELOW everything in flow inside it — which is exactly the one slot
       this needs, and it takes no rule on the children to get there. The
       alternative was lifting the icon, the input and the send button onto
       z-index and trusting the next child added to the bar to join them.
    ═══════════════════════════════════════════════ */
    @property --beam-angle { syntax: "<angle>"; inherits: true; initial-value: 0deg; }

    .overlay-input-bar,
    .aimy-float-bar { position: relative; isolation: isolate; }

    /* inset -1px, not 0: an absolutely positioned child is laid out against the
       PADDING box, which is inside the bar's 1px border — so at inset 0 the
       stroke would light the pixel next to the border rather than the border
       itself, and its 40px radius would sit a pixel proud of the bar's. At -1px
       the beam's box is the border box exactly and the two curves agree.

       The fade belongs on the wrapper rather than on each layer: one transition
       takes all three in and out together, and the spin only ever runs while
       there is an answer to run it for. */
    .beam {
      position: absolute; inset: -1px;
      border-radius: inherit;
      overflow: hidden;
      pointer-events: none;
      z-index: -1;
      opacity: 0;
      transition: opacity 420ms var(--ease-out);
    }
    .is-generating > .beam { opacity: 1; animation: beam-spin 4.2s linear infinite; }

    /* The seven blobs, pinned. Shared by all three layers through a custom
       property so the stroke, the glow and the bloom can never disagree about
       where the colour is — which they would, the first time one of them was
       retuned on its own. */
    .beam {
      --beam-blobs:
        radial-gradient(ellipse 130px 30px at  16%  -8%, rgb(139, 79,244), transparent),
        radial-gradient(ellipse 104px 26px at  41%  -5%, rgb( 51,105,255), transparent),
        radial-gradient(ellipse  84px 26px at  87%  -4%, rgb(106, 91,245), transparent),
        radial-gradient(ellipse  30px 42px at   1%  60%, rgb( 97,173,241), transparent),
        radial-gradient(ellipse  28px 40px at 100%  32%, rgb( 76,203,224), transparent),
        radial-gradient(ellipse 168px 28px at  68% 104%, rgb(  0,102,255), transparent),
        radial-gradient(ellipse  96px 24px at  31% 104%, rgb( 69,211,230), transparent);
    }

    .beam::before,
    .beam::after,
    .beam > i {
      content: ""; position: absolute; inset: 0;
      border-radius: inherit;
      pointer-events: none;
    }

    /* The inner glow. Held to the outer band by the two linear masks — 14px top
       and bottom, 28px left and right — which is what keeps the colour on the
       edge of a 54px bar instead of behind the placeholder. */
    .beam::before {
      background: var(--beam-blobs);
      box-shadow: inset 0 0 9px 1px rgba(255,255,255,0.22);
      opacity: 0.42;
      -webkit-mask-image:
        conic-gradient(from var(--beam-angle),
          transparent 0%, transparent 30%,
          rgba(255,255,255,0.1) 36%, rgba(255,255,255,0.35) 44%,
          #fff 52%, #fff 80%,
          rgba(255,255,255,0.35) 86%, rgba(255,255,255,0.1) 92%,
          transparent 95%, transparent 100%),
        linear-gradient(#fff, transparent 14px, transparent calc(100% - 14px), #fff),
        linear-gradient(to right, #fff, transparent 28px, transparent calc(100% - 28px), #fff);
      -webkit-mask-composite: source-in, source-over;
      mask-image:
        conic-gradient(from var(--beam-angle),
          transparent 0%, transparent 30%,
          rgba(255,255,255,0.1) 36%, rgba(255,255,255,0.35) 44%,
          #fff 52%, #fff 80%,
          rgba(255,255,255,0.35) 86%, rgba(255,255,255,0.1) 92%,
          transparent 95%, transparent 100%),
        linear-gradient(#fff, transparent 14px, transparent calc(100% - 14px), #fff),
        linear-gradient(to right, #fff, transparent 28px, transparent calc(100% - 28px), #fff);
      mask-composite: intersect, add;
      z-index: 1;
    }

    /* The stroke. A white wedge laid over the same blobs and cut to the border
       alone: border box, minus content box, is the one pixel between them. */
    .beam::after {
      padding: 1px;
      background:
        conic-gradient(from var(--beam-angle),
          transparent 0%, transparent 42%,
          rgba(255,255,255,0.06) 48%,
          rgba(255,255,255,0.20) 54%,
          rgba(255,255,255,0.42) 60%,
          rgba(255,255,255,0.62) 66%,
          rgba(255,255,255,0.42) 72%,
          rgba(255,255,255,0.20) 78%,
          rgba(255,255,255,0.06) 84%,
          transparent 90%, transparent 100%),
        var(--beam-blobs);
      opacity: 0.26;
      -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
      -webkit-mask-composite: xor;
      mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
      mask-composite: exclude;
      z-index: 2;
    }

    /* The bloom. The wedge again, tighter and blurred — this is the layer that
       makes the leading edge read as light rather than as a painted arc. */
    .beam > i {
      padding: 1px;
      background: conic-gradient(from var(--beam-angle),
        transparent 0%, transparent 50%,
        rgba(255,255,255,0.03) 56%,
        rgba(255,255,255,0.10) 61%,
        rgba(255,255,255,0.24) 65%,
        rgba(255,255,255,0.46) 68%,
        rgba(255,255,255,0.70) 71%,
        rgba(255,255,255,0.70) 74%,
        rgba(255,255,255,0.46) 77%,
        rgba(255,255,255,0.24) 80%,
        rgba(255,255,255,0.10) 84%,
        rgba(255,255,255,0.03) 88%,
        transparent 94%);
      opacity: 0.24;
      filter: blur(8px) brightness(1.3) saturate(1.2);
      -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
      -webkit-mask-composite: xor;
      mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
      mask-composite: exclude;
      z-index: 3;
    }

    /* The palette drifts underneath the sweep, on a period long enough that you
       never catch it turning. brightness and saturate are carried in the same
       declaration because a filter is one value — split across two rules, the
       second would simply replace the first. */
    .is-generating > .beam::before,
    .is-generating > .beam::after { animation: beam-hue 18s ease-in-out infinite; }

    /* Light theme, and it is not a tint of the dark one. On black the beam ADDS
       and any colour at all reads; on white it can only darken, so the same
       values disappeared into the page — measured, not guessed: at the dark
       theme's alphas the sweep was invisible against the gate's own pale
       lavender ground. The colours go to saturated mid-tones rather than the
       light tints that look right in a swatch and vanish on a white surface,
       and every layer roughly doubles in strength. */
    :root[data-theme="light"] .beam {
      --beam-blobs:
        radial-gradient(ellipse 130px 30px at  16%  -8%, rgb(109, 40,217), transparent),
        radial-gradient(ellipse 104px 26px at  41%  -5%, rgb( 29, 78,216), transparent),
        radial-gradient(ellipse  84px 26px at  87%  -4%, rgb( 76, 50,224), transparent),
        radial-gradient(ellipse  30px 42px at   1%  60%, rgb( 14,116,180), transparent),
        radial-gradient(ellipse  28px 40px at 100%  32%, rgb( 13,148,160), transparent),
        radial-gradient(ellipse 168px 28px at  68% 104%, rgb(  0, 88,200), transparent),
        radial-gradient(ellipse  96px 24px at  31% 104%, rgb( 16,168,170), transparent);
    }
    :root[data-theme="light"] .beam::before {
      opacity: 0.8;
      box-shadow: inset 0 0 9px 1px rgba(16,24,40,0.10);
    }
    :root[data-theme="light"] .beam::after { opacity: 0.7; }
    :root[data-theme="light"] .beam > i   { opacity: 0.4; }

    @keyframes beam-spin {
      to { --beam-angle: 360deg; }
    }
    @keyframes beam-hue {
      0%, 100% { filter: hue-rotate(-30deg) brightness(1.3) saturate(1.2); }
      50%      { filter: hue-rotate( 30deg) brightness(1.3) saturate(1.2); }
    }

    /* ── The send button becomes the stop button ──
       The same control, because there is only ever one thing to do with the
       composer while an answer is coming and it is not sending another. The
       square is drawn HERE rather than added as a second icon to the four send
       buttons across the two shells: nothing in the markup has to know about
       the state, so no shell can ship the beam without the way out of it. */
    .is-generating .overlay-send,
    .is-generating .aimy-float-send {
      background: rgba(var(--accent-rgb),0.22);
      box-shadow: none;
      transform: none;
    }
    .is-generating .overlay-send:hover,
    .is-generating .aimy-float-send:hover {
      background: rgba(var(--accent-rgb),0.34);
      box-shadow: none;
      transform: none;
    }
    .is-generating .overlay-send > svg,
    .is-generating .aimy-float-send > .send-icon { display: none; }
    .is-generating .overlay-send::after,
    .is-generating .aimy-float-send::after {
      content: "";
      width: 9px; height: 9px;
      border-radius: 2px;
      background: var(--d50);
    }
    :root[data-theme="light"] .is-generating .overlay-send::after,
    :root[data-theme="light"] .is-generating .aimy-float-send::after { background: var(--d900); }

    /* ── A turn that was called off ──
       Under whatever had already been said, never instead of it. */
    .msg-stopped {
      display: flex; align-items: center; gap: 6px;
      margin-top: 8px;
      font-size: 14px; font-weight: 600;
      color: var(--ink-muted);
    }
    .msg-stopped svg { width: 12px; height: 12px; flex-shrink: 0; opacity: 0.8; }

    /* ═══════════════════════════════════════════════
       AIMY BADGE (logo badge on float icon)
    ═══════════════════════════════════════════════ */
    .aimy-badge {
      display: inline-flex; align-items: center; gap: 5px;
      font-size: 14px; font-weight: 700; letter-spacing: 0.06em;
      text-transform: uppercase; padding: 3px 9px; border-radius: var(--r-pill);
      background: linear-gradient(104deg, rgba(0,102,255,0.15), rgba(69,211,230,0.12));
      border: 1px solid rgba(97,173,241,0.25); color: #61adf1;
    }
    .aimy-badge svg { width: 11px; height: 11px; }


    /* ═══════════════════════════════════════════════
       AIMY TOAST (action confirmation toast)
    ═══════════════════════════════════════════════ */
    /* This block previously implemented an older toast — bottom-right, green
       success chip, column layout, horizontal divider, --ok fill over 4s —
       while the anatomy table below and the published system both described a
       bottom-CENTRE, AiMY-branded one. A product reading the docs and a
       product using the CSS got different components. The table is what is
       published, so the table wins; every value here is quoted from it. */
    .aimy-toast {
      position: fixed; bottom: 90px; left: 50%; z-index: 9999;
      min-width: 280px; max-width: 360px;
      background: var(--card-bg-raised); border: 1px solid rgba(255,255,255,0.1);
      border-radius: var(--r-xl); padding: 12px 16px;
      box-shadow: 0 8px 32px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.04);
      display: flex; flex-direction: row; align-items: center; gap: 12px;
      overflow: hidden;
      opacity: 0; visibility: hidden;
      transform: translateX(-50%) translateY(20px) scale(0.97);
      pointer-events: none;
      transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out);
    }
    /* visibility, not opacity alone — an opacity-0 toast still takes clicks. */
    .aimy-toast.visible {
      opacity: 1; visibility: visible; pointer-events: auto;
      transform: translateX(-50%) translateY(0) scale(1);
    }

    .aimy-toast-icon {
      width: 30px; height: 30px; border-radius: 9px; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      background: rgba(var(--accent-rgb),0.1);
      border: 1px solid rgba(var(--accent-rgb),0.2);
    }
    /* The AiMY mark, not a checkmark: the toast confirms that AiMY acted, and
       it is used for reversible writes as often as for successes. */
    .aimy-toast-icon svg { width: 13px; height: 15px; stroke: none; }

    .aimy-toast-body { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; flex: 1; }
    .aimy-toast-title { font-size: 16px; font-weight: 700; color: var(--d50); letter-spacing: -0.005em; }
    .aimy-toast-sub { font-size: 14px; color: var(--ink-muted); line-height: 1.5; }

    /* Vertical rule separating the message from the undo, not a horizontal
       one splitting the card in half. */
    .aimy-toast-divider { width: 1px; height: 28px; flex-shrink: 0; background: rgba(255,255,255,0.06); }

    .aimy-toast-undo {
      display: inline-flex; align-items: center; gap: 5px;
      font-size: 14px; font-weight: 700; color: var(--ai-text);
      cursor: pointer; background: none; border: none; padding: 0;
      font-family: var(--font-sans);
      transition: color var(--t-fast);
    }
    .aimy-toast-undo:hover { color: var(--d50); }

    .aimy-toast-progress {
      position: absolute; bottom: 0; left: 0; right: 0;
      height: 2.5px; overflow: hidden;
    }
    .aimy-toast-progress-fill {
      height: 100%; width: 100%;
      background: var(--ai);
      transform-origin: left center;
      animation: toastProgress 5s linear forwards;
    }
    /* scaleX, not width — width animation forces layout on every frame */
    @keyframes toastProgress {
      from { transform: scaleX(1); }
      to   { transform: scaleX(0); }
    }


    /* ═══════════════════════════════════════════════
       GENERAL COMPONENTS — added for the Aimy ecosystem
       All theme-aware via tokens. Work in light & dark.
    ═══════════════════════════════════════════════ */

    /* ── Segmented control ── */
    .seg { display: inline-flex; background: var(--card-bg-raised); border: 1px solid var(--card-border);
      border-radius: var(--r-md); padding: 3px; gap: 2px; }
    .seg-btn { appearance: none; border: none; background: transparent; cursor: pointer;
      font-family: var(--font-sans); font-size: 16px; font-weight: 600; color: var(--ink-muted);
      padding: 5px 14px; border-radius: var(--r-sm); transition: background var(--t-fast), color var(--t-fast); }
    .seg-btn:hover { color: var(--d100); }
    .seg-btn.active { background: var(--accent-dim); color: var(--accent); }

    /* ── Toggle switch ── */
    .ds-switch { position: relative; display: inline-flex; align-items: center; gap: 10px; cursor: pointer;
      font-size: 14px; font-weight: 600; color: var(--d200); user-select: none; }
    .ds-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
    .ds-switch .track { width: 40px; height: 22px; border-radius: var(--r-pill);
      background: var(--card-bg-raised); border: 1px solid var(--card-border);
      transition: background var(--t-base), border-color var(--t-base); flex-shrink: 0; }
    /* translateX, not left — `left` relayouts; transform composites. */
    .ds-switch .thumb { position: absolute; top: 50%; left: 3px;
      transform: translateY(-50%) translateX(0);
      width: 16px; height: 16px; border-radius: 50%; background: var(--d400);
      transition: transform var(--t-base) var(--ease-spring), background-color var(--t-base); }
    .ds-switch input:checked + .track { background: var(--accent); border-color: transparent; }
    .ds-switch input:checked + .track .thumb { transform: translateY(-50%) translateX(18px); background: #fff; }
    .ds-switch input:focus-visible + .track { box-shadow: 0 0 0 3px var(--accent-glow); }

    /* ── Checkbox & radio ── */
    .ds-choice { display: inline-flex; align-items: center; gap: 9px; cursor: pointer;
      font-size: 14px; font-weight: 500; color: var(--d200); user-select: none; }
    .ds-choice input { appearance: none; margin: 0; width: 18px; height: 18px; flex-shrink: 0;
      background: var(--card-bg-raised); border: 1.5px solid var(--card-border-hover);
      transition: background var(--t-fast), border-color var(--t-fast); cursor: pointer; position: relative; }
    .ds-choice input[type="checkbox"] { border-radius: var(--r-xs); }
    .ds-choice input[type="radio"] { border-radius: 50%; }
    .ds-choice input:hover { border-color: var(--accent); }
    .ds-choice input:checked { background: var(--accent); border-color: var(--accent); }
    .ds-choice input[type="checkbox"]:checked::after { content: ""; position: absolute; left: 5px; top: 1.5px;
      width: 5px; height: 9px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
    .ds-choice input[type="radio"]:checked::after { content: ""; position: absolute; inset: 4px;
      border-radius: 50%; background: #fff; }
    .ds-choice input:focus-visible { box-shadow: 0 0 0 3px var(--accent-glow); }

    /* ── Range slider ── */
    .ds-range { appearance: none; width: 220px; height: 6px; border-radius: var(--r-pill);
      background: var(--card-bg-raised); border: 1px solid var(--card-border); outline: none; cursor: pointer; }
    .ds-range::-webkit-slider-thumb { appearance: none; width: 18px; height: 18px; border-radius: 50%;
      background: var(--accent); border: 2px solid var(--card-bg); box-shadow: var(--shadow-sm);
      transition: transform var(--t-fast); }
    .ds-range::-webkit-slider-thumb:hover { transform: scale(1.12); }
    .ds-range::-moz-range-thumb { width: 18px; height: 18px; border-radius: 50%; background: var(--accent);
      border: 2px solid var(--card-bg); }

    /* ── Progress & meter ── */
    .ds-progress { height: 8px; border-radius: var(--r-pill); background: var(--card-bg-raised);
      border: 1px solid var(--card-border); overflow: hidden; }
    .ds-progress-fill { height: 100%; border-radius: var(--r-pill); background: var(--ai); }
    .ds-progress-fill.ok  { background: var(--ok); }
    .ds-progress-fill.warn{ background: var(--warn); }
    .ds-progress-fill.err { background: var(--err); }

    /* ── Accordion (native <details>) ── */
    .acc { border: 1px solid var(--card-border); border-radius: var(--r-lg); overflow: hidden;
      background: var(--card-bg); max-width: 520px; }
    .acc-item { border-bottom: 1px solid var(--hairline); }
    .acc-item:last-child { border-bottom: none; }
    .acc-head { list-style: none; cursor: pointer; padding: 14px 16px; display: flex; align-items: center;
      justify-content: space-between; font-size: 14px; font-weight: 700; color: var(--d100);
      transition: background var(--t-fast); }
    .acc-head::-webkit-details-marker { display: none; }
    .acc-head:hover { background: var(--card-bg-raised); }
    .acc-head .chev { transition: transform var(--t-base) var(--ease-out); color: var(--ink-muted); flex-shrink: 0; }
    .acc-item[open] .acc-head .chev { transform: rotate(90deg); }
    .acc-body { padding: 0 16px 15px; font-size: 14px; line-height: 1.6; color: var(--ink-muted); }

    /* ── Breadcrumbs ── */
    .crumbs { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 600; flex-wrap: wrap; }
    .crumbs a { color: var(--ink-muted); text-decoration: none; transition: color var(--t-fast); }
    .crumbs a:hover { color: var(--accent); }
    .crumb-sep { color: var(--ink-muted); }
    .crumbs .current { color: var(--d100); }

    /* ── Pagination ── */
    .pager { display: inline-flex; align-items: center; gap: 4px; }
    .pager-btn { min-width: 32px; height: 32px; padding: 0 8px; display: inline-flex; align-items: center;
      justify-content: center; border-radius: var(--r-sm); border: 1px solid var(--card-border);
      background: var(--card-bg); color: var(--ink-muted); font-family: var(--font-sans); font-size: 14px;
      font-weight: 600; cursor: pointer; transition: border-color var(--t-fast), color var(--t-fast), background var(--t-fast); }
    .pager-btn:hover:not(:disabled) { border-color: var(--card-border-hover); color: var(--d50); }
    .pager-btn.active { background: var(--accent-dim); border-color: transparent; color: var(--accent); }
    .pager-btn:disabled { opacity: 0.4; cursor: not-allowed; }
    .pager-gap { color: var(--ink-muted); padding: 0 2px; }

    /* ── Banners / alerts ── */
    .banner { display: flex; align-items: flex-start; gap: 11px; padding: 12px 14px; border-radius: var(--r-lg);
      border: 1px solid; font-size: 14px; line-height: 1.5; }
    .banner-ico { flex-shrink: 0; margin-top: 1px; }
    .banner-body { color: var(--d200); }
    .banner-body strong { color: var(--d50); }
    .banner.info { background: var(--info-bg); border-color: color-mix(in srgb, var(--info) 28%, transparent); }
    .banner.info .banner-ico { color: var(--info); }
    .banner.ok   { background: var(--ok-bg);   border-color: var(--ok-glow); }
    .banner.ok   .banner-ico { color: var(--ok); }
    .banner.warn { background: var(--warn-bg); border-color: color-mix(in srgb, var(--warn) 30%, transparent); }
    .banner.warn .banner-ico { color: var(--warn); }
    .banner.err  { background: var(--err-bg);  border-color: var(--err-glow); }
    .banner.err  .banner-ico { color: var(--err); }

    /* ── Data table ── */
    .dtable-wrap { border: 1px solid var(--card-border); border-radius: var(--r-lg); overflow: hidden; }
    table.dtable { width: 100%; border-collapse: collapse; font-size: 14px; }
    table.dtable thead th { text-align: left; padding: 10px 14px; background: var(--card-bg-raised);
      color: var(--ink-muted); font-weight: 700; font-size: 14px; text-transform: uppercase; letter-spacing: 0.04em;
      border-bottom: 1px solid var(--card-border); }
    table.dtable tbody td { padding: 11px 14px; color: var(--d200); border-bottom: 1px solid var(--hairline); }
    table.dtable tbody tr:last-child td { border-bottom: none; }
    table.dtable tbody tr { transition: background var(--t-fast); }
    table.dtable tbody tr:hover { background: var(--card-bg-raised); }

    /* ── Drawer / side sheet ── */
    .drawer-stage { position: relative; height: 260px; border-radius: var(--r-lg); overflow: hidden;
      border: 1px solid var(--card-border); background: var(--card-bg-raised); }
    .drawer-scrim { position: absolute; inset: 0; background: rgba(0,0,0,0.45); opacity: 0; pointer-events: none;
      transition: opacity var(--t-base); }
    .drawer-panel { position: absolute; top: 0; right: 0; bottom: 0; width: 280px; max-width: 80%;
      background: var(--card-bg); border-left: 1px solid var(--card-border); box-shadow: var(--shadow-lg);
      transform: translateX(100%); transition: transform var(--t-slow) var(--ease-out);
      display: flex; flex-direction: column; padding: 18px; }
    .drawer-stage.open .drawer-scrim { opacity: 1; pointer-events: auto; }
    .drawer-stage.open .drawer-panel { transform: translateX(0); }
    .drawer-title { font-size: 14px; font-weight: 700; color: var(--d50); margin-bottom: 6px; }

    /* ── Popover ── */
    .pop { position: relative; display: inline-block; }
    .pop-bubble { position: absolute; bottom: calc(100% + 10px); left: 50%; transform: translateX(-50%) scale(0.96);
      width: 240px; background: var(--panel-bg); backdrop-filter: blur(12px);
      border: 1px solid var(--glass-border); border-radius: var(--r-lg); box-shadow: var(--shadow-lg);
      padding: 14px; opacity: 0; pointer-events: none; transition: opacity var(--t-fast), transform var(--t-fast);
      z-index: 20; }
    .pop-bubble::after { content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
      border: 6px solid transparent; border-top-color: var(--panel-bg); }
    .pop.open .pop-bubble { opacity: 1; pointer-events: auto; transform: translateX(-50%) scale(1); }
    .pop-title { font-size: 14px; font-weight: 700; color: var(--d50); margin-bottom: 4px; }
    .pop-text { font-size: 16px; line-height: 1.55; color: var(--ink-muted); }

    /* ── Inline notification ── */
    .inline-note { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: var(--r-md);
      background: var(--card-bg-raised); border: 1px solid var(--card-border); font-size: 14px; color: var(--d200); }
    .inline-note .dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; background: var(--accent); }
    .inline-note.ok .dot { background: var(--ok); }
    .inline-note.warn .dot { background: var(--warn); }
    .inline-note .close { margin-left: auto; color: var(--ink-muted); cursor: pointer; background: none; border: none;
      font-size: 16px; line-height: 1; padding: 0 2px; }
    .inline-note .close:hover { color: var(--d100); }

    /* ── Search field ── */
    .search-field { display: flex; align-items: center; gap: 9px; padding: 9px 14px; max-width: 340px;
      background: var(--card-bg-raised); border: 1px solid var(--card-border); border-radius: var(--r-pill);
      transition: border-color var(--t-fast), box-shadow var(--t-fast); }
    .search-field:focus-within { border-color: var(--card-border-focus); box-shadow: 0 0 0 3px var(--brand-glow); }
    .search-field svg { color: var(--ink-muted); flex-shrink: 0; }
    .search-field input { flex: 1; background: none; border: none; outline: none; color: var(--d50);
      font-family: var(--font-sans); font-size: 14px; }
    .search-field input::placeholder { color: var(--ink-muted); }

    /* ── Textarea ── */
    .ds-textarea { width: 100%; max-width: 420px; min-height: 96px; resize: vertical; padding: 11px 13px;
      background: var(--card-bg-raised); border: 1px solid var(--card-border); border-radius: var(--r-md);
      color: var(--d50); font-family: var(--font-sans); font-size: 14px; line-height: 1.55;
      transition: border-color var(--t-fast), box-shadow var(--t-fast); }
    .ds-textarea:focus { outline: none; border-color: var(--card-border-focus); box-shadow: 0 0 0 3px var(--brand-glow); }
    .ds-textarea::placeholder { color: var(--ink-muted); }

    /* ── Number stepper ── */
    .stepper { display: inline-flex; align-items: center; border: 1px solid var(--card-border);
      border-radius: var(--r-md); overflow: hidden; background: var(--card-bg-raised); }
    .stepper button { width: 34px; height: 34px; border: none; background: transparent; color: var(--d200);
      font-size: 18px; cursor: pointer; transition: background var(--t-fast), color var(--t-fast); }
    .stepper button:hover { background: var(--card-bg); color: var(--accent); }
    .stepper input { width: 48px; height: 34px; text-align: center; border: none; background: transparent;
      color: var(--d50); font-family: var(--font-sans); font-size: 14px; font-weight: 600; outline: none;
      border-left: 1px solid var(--hairline); border-right: 1px solid var(--hairline); }
    .stepper input::-webkit-outer-spin-button, .stepper input::-webkit-inner-spin-button { appearance: none; margin: 0; }

    /* ── File upload ── */
    .uploader { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
      max-width: 420px; padding: 28px; text-align: center; cursor: pointer;
      background: var(--card-bg-raised); border: 1.5px dashed var(--card-border-hover); border-radius: var(--r-lg);
      transition: border-color var(--t-fast), background var(--t-fast); }
    .uploader:hover { border-color: var(--accent); background: var(--accent-dim); }
    .uploader svg { color: var(--ink-muted); }
    .uploader .up-title { font-size: 14px; font-weight: 700; color: var(--d100); }
    .uploader .up-sub { font-size: 14px; color: var(--ink-muted); }


    /* ═══════════════════════════════════════════════
       GENERAL COMPONENTS — batch 2 (enterprise gaps)
    ═══════════════════════════════════════════════ */

    /* ── Content tabs (underline) ── */
    .ds-tabs { border-bottom: 1px solid var(--card-border); display: flex; gap: 4px; }
    .ds-tab { appearance: none; background: none; border: none; cursor: pointer; position: relative;
      font-family: var(--font-sans); font-size: 14px; font-weight: 600; color: var(--ink-muted);
      padding: 10px 14px; transition: color var(--t-fast); }
    .ds-tab::after { content: ""; position: absolute; left: 10px; right: 10px; bottom: -1px; height: 2px;
      border-radius: 2px; background: var(--accent); transform: scaleX(0); transition: transform var(--t-base) var(--ease-out); }
    .ds-tab:hover { color: var(--d100); }
    .ds-tab.active { color: var(--accent); }
    .ds-tab.active::after { transform: scaleX(1); }
    .ds-tab .tab-count { margin-left: 6px; font-size: 14px; font-weight: 700; padding: 1px 6px;
      border-radius: var(--r-pill); background: var(--card-bg-raised); color: var(--ink-muted); }
    .ds-tabpanel { padding: 16px 2px; font-size: 14px; color: var(--ink-muted); line-height: 1.6; }

    /* ── Button group + icon button ── */
    .btn-group { display: inline-flex; }
    .btn-group .btn { border-radius: 0; margin-left: -1px; }
    .btn-group .btn:first-child { border-radius: var(--r-md) 0 0 var(--r-md); margin-left: 0; }
    .btn-group .btn:last-child { border-radius: 0 var(--r-md) var(--r-md) 0; }
    .icon-btn { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px;
      border-radius: var(--r-md); background: var(--card-bg-raised); border: 1px solid var(--card-border);
      color: var(--ink-muted); cursor: pointer; transition: border-color var(--t-fast), color var(--t-fast), background var(--t-fast); }
    .icon-btn:hover { border-color: var(--card-border-hover); color: var(--accent); }

    /* ── Menu (dropdown action menu) ── */
    .menu-anchor { position: relative; display: inline-block; }
    .menu { position: absolute; top: calc(100% + 6px); left: 0; min-width: 200px; z-index: 25;
      background: var(--panel-bg); backdrop-filter: blur(12px); border: 1px solid var(--glass-border);
      border-radius: var(--r-lg); box-shadow: var(--shadow-lg); padding: 6px;
      opacity: 0; transform: translateY(-4px); pointer-events: none;
      transition: opacity var(--t-fast), transform var(--t-fast); }
    .menu-anchor.open .menu { opacity: 1; transform: translateY(0); pointer-events: auto; }
    .menu-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: var(--r-sm);
      font-size: 14px; color: var(--d200); cursor: pointer; transition: background var(--t-fast), color var(--t-fast); }
    .menu-item:hover { background: var(--card-bg-raised); color: var(--d50); }
    .menu-item svg { color: var(--ink-muted); flex-shrink: 0; }
    .menu-item.danger { color: var(--err); }
    .menu-item.danger:hover { background: var(--err-bg); }
    .menu-sep { height: 1px; background: var(--hairline); margin: 5px 0; }
    .menu-label { font-size: 14px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
      color: var(--ink-muted); padding: 6px 10px 3px; }

    /* ── Steps / wizard ── */
    .steps { display: flex; align-items: flex-start; gap: 0; }
    .step { display: flex; flex-direction: column; align-items: center; flex: 1; position: relative; text-align: center; }
    .step:not(:last-child)::after { content: ""; position: absolute; top: 14px; left: 50%; width: 100%; height: 2px;
      background: var(--card-border); z-index: 0; }
    .step.done:not(:last-child)::after { background: var(--accent); }
    .step-dot { width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
      font-size: 16px; font-weight: 700; z-index: 1; position: relative;
      background: var(--card-bg-raised); border: 1.5px solid var(--card-border); color: var(--ink-muted); }
    .step.done .step-dot { background: var(--accent); border-color: transparent; color: #fff; }
    .step.active .step-dot { border-color: var(--accent); color: var(--accent); box-shadow: 0 0 0 4px var(--accent-glow); }
    .step-label { margin-top: 8px; font-size: 14px; font-weight: 600; color: var(--ink-muted); }
    .step.active .step-label, .step.done .step-label { color: var(--d100); }

    /* ── Divider ── */
    .ds-divider { height: 1px; background: var(--card-border); border: none; margin: 4px 0; }
    .ds-divider.labeled { display: flex; align-items: center; gap: 12px; background: none; height: auto; }
    .ds-divider.labeled::before, .ds-divider.labeled::after { content: ""; flex: 1; height: 1px; background: var(--card-border); }
    .ds-divider .divider-text { font-size: 14px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-muted); }

    /* ── Stat card ── */
    .stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 14px; }
    .stat-card { padding: 16px; border-radius: var(--r-lg); background: var(--card-bg-raised);
      border: 1px solid var(--card-border); }
    .stat-label { font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-muted); }
    .stat-value { font-size: 28px; font-weight: 800; letter-spacing: -0.02em; color: var(--d50); margin: 6px 0 4px; }
    .stat-delta { font-size: 16px; font-weight: 700; display: inline-flex; align-items: center; gap: 3px; }
    .stat-delta.up { color: var(--ok); }
    .stat-delta.down { color: var(--err); }

    /* ── List group ── */
    .list-group { border: 1px solid var(--card-border); border-radius: var(--r-lg); overflow: hidden; max-width: 480px; }
    .list-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-bottom: 1px solid var(--hairline);
      transition: background var(--t-fast); }
    .list-row:last-child { border-bottom: none; }
    .list-row:hover { background: var(--card-bg-raised); }
    .list-ico { width: 34px; height: 34px; border-radius: var(--r-md); flex-shrink: 0; display: flex; align-items: center;
      justify-content: center; background: var(--accent-dim); color: var(--accent); }
    .list-main { flex: 1; min-width: 0; }
    .list-title { font-size: 14px; font-weight: 600; color: var(--d100); }
    .list-sub { font-size: 14px; color: var(--ink-muted); margin-top: 1px; }
    .list-meta { font-size: 14px; color: var(--ink-muted); flex-shrink: 0; }

    /* ── Description list (key/value) ── */
    .desc-list { display: grid; grid-template-columns: minmax(120px, max-content) 1fr; gap: 0; max-width: 480px;
      border: 1px solid var(--card-border); border-radius: var(--r-lg); overflow: hidden; }
    .desc-list dt { padding: 11px 14px; font-size: 16px; font-weight: 600; color: var(--ink-muted);
      background: var(--card-bg-raised); border-bottom: 1px solid var(--hairline); }
    .desc-list dd { padding: 11px 14px; font-size: 14px; color: var(--d100); border-bottom: 1px solid var(--hairline); margin: 0; }
    .desc-list dt:last-of-type, .desc-list dd:last-of-type { border-bottom: none; }

    /* ── Timeline ── */
    .timeline { position: relative; padding-left: 26px; max-width: 480px; }
    .timeline::before { content: ""; position: absolute; left: 7px; top: 4px; bottom: 4px; width: 2px; background: var(--card-border); }
    .tl-item { position: relative; padding-bottom: 20px; }
    .tl-item:last-child { padding-bottom: 0; }
    .tl-dot { position: absolute; left: -26px; top: 2px; width: 16px; height: 16px; border-radius: 50%;
      background: var(--card-bg); border: 2px solid var(--accent); }
    .tl-dot.ok { border-color: var(--ok); } .tl-dot.warn { border-color: var(--warn); } .tl-dot.err { border-color: var(--err); }
    .tl-title { font-size: 14px; font-weight: 600; color: var(--d100); }
    .tl-time { font-size: 14px; color: var(--ink-muted); margin-top: 1px; }
    .tl-body { font-size: 16px; color: var(--ink-muted); margin-top: 4px; line-height: 1.55; }

    /* ── Avatar group ── */
    .avatar-group { display: inline-flex; }
    .avatar-group .av { width: 32px; height: 32px; border-radius: 50%; border: 2px solid var(--card-bg);
      margin-left: -10px; display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 700;
      color: #fff; background: var(--grad-avatar); }
    .avatar-group .av:first-child { margin-left: 0; }
    .avatar-group .av.more { background: var(--card-bg-raised); color: var(--ink-muted); }

    /* ── Rating ── */
    .rating { display: inline-flex; gap: 3px; }
    .rating .star { color: var(--card-border-hover); }
    .rating .star.on { color: var(--warn); }

    /* ── Status dot + count badge ── */
    .status-pill { display: inline-flex; align-items: center; gap: 7px; font-size: 16px; font-weight: 600; color: var(--d200); }
    .status-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; position: relative; }
    .status-dot.online { background: var(--ok); }
    .status-dot.busy { background: var(--err); }
    .status-dot.away { background: var(--warn); }
    .status-dot.offline { background: var(--d500); }
    .status-dot.pulse::after { content: ""; position: absolute; inset: -3px; border-radius: 50%;
      border: 2px solid currentColor; opacity: 0.5; animation: statusPulse 1.6s ease-out infinite; }
    .status-dot.online.pulse::after { border-color: var(--ok); }
    @keyframes statusPulse { 0% { transform: scale(0.8); opacity: 0.6; } 100% { transform: scale(1.8); opacity: 0; } }
    .badge-anchor { position: relative; display: inline-flex; }
    .count-badge { position: absolute; top: -5px; right: -6px; min-width: 17px; height: 17px; padding: 0 5px;
      border-radius: var(--r-pill); background: var(--err); color: #fff; font-size: 14px; font-weight: 700;
      display: flex; align-items: center; justify-content: center; border: 2px solid var(--body-bg); }

    /* ── Keyboard keys ── */
    .ds-kbd { display: inline-flex; align-items: center; gap: 4px; }
    .ds-kbd kbd { font-family: var(--font-mono); font-size: 14px; color: var(--d200);
      background: var(--card-bg-raised); border: 1px solid var(--card-border); border-bottom-width: 2px;
      border-radius: var(--r-sm); padding: 2px 7px; min-width: 20px; text-align: center; }

    /* ── Confirmation popconfirm (reuses .pop) ── */
    .pop-actions { display: flex; gap: 6px; margin-top: 12px; justify-content: flex-end; }

    /* ── Form field + validation states ── */
    .ds-field { max-width: 380px; }
    .ds-field .field-label { display: block; font-size: 16px; font-weight: 600; color: var(--d200); margin-bottom: 6px; }
    .ds-field .field-label .req { color: var(--err); margin-left: 2px; }
    .field-input { width: 100%; padding: 10px 12px; background: var(--card-bg-raised);
      border: 1px solid var(--card-border); border-radius: var(--r-md); color: var(--d50);
      font-family: var(--font-sans); font-size: 14px; transition: border-color var(--t-fast), box-shadow var(--t-fast); }
    .field-input::placeholder { color: var(--ink-muted); }
    .field-input:focus { outline: none; border-color: var(--card-border-focus); box-shadow: 0 0 0 3px var(--brand-glow); }
    .ds-field.is-error .field-input { border-color: var(--err); }
    .ds-field.is-error .field-input:focus { box-shadow: 0 0 0 3px var(--err-glow); }
    .ds-field.is-success .field-input { border-color: var(--ok); }
    .ds-field .field-help { font-size: 14px; color: var(--ink-muted); margin-top: 6px; }
    .ds-field.is-error .field-help { color: var(--err); }
    .ds-field.is-success .field-help { color: var(--ok); }

    /* ── Dropdown (v2-dropdown) — the system's only select control ──
       Custom listbox. Styles lifted from the original specimen so the
       visual is unchanged; behaviour and states are now real.        */
    .v2-dropdown { position: relative; display: inline-flex; flex-direction: column; }
    .v2-dropdown.roster-dd { display: flex; width: 100%; }
    .v2-dropdown.roster-dd .v2-dropdown-btn { width: 100%; justify-content: space-between; }
    .v2-dropdown.roster-dd .v2-dropdown-panel { min-width: 100%; }

    .v2-dropdown-btn {
      display: flex; align-items: center; gap: 5px;
      background: rgba(255,255,255,0.04);
      border: 1px solid rgba(255,255,255,0.09);
      border-radius: var(--r-sm); padding: 4px 8px 4px 10px;
      font-family: var(--font-sans); font-size: 14px; font-weight: 600;
      color: var(--d200); cursor: pointer; white-space: nowrap;
      transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast);
    }
    .v2-dropdown-btn:hover { background: rgba(255,255,255,0.07); border-color: rgba(255,255,255,0.16); }
    .v2-dropdown-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
    .v2-dropdown-btn svg { width: 10px; height: 10px; color: var(--ink-muted); flex-shrink: 0;
      transition: transform var(--t-fast); }
    .v2-dropdown-btn.open,
    .v2-dropdown-btn[aria-expanded="true"] {
      background: rgba(51,105,255,0.08); border-color: rgba(99,169,255,0.28); color: var(--ai-text);
    }
    .v2-dropdown-btn.open svg,
    .v2-dropdown-btn[aria-expanded="true"] svg { transform: rotate(180deg); color: currentColor; }
    /* non-default value selected */
    .v2-dropdown-btn.active-filter {
      background: rgba(51,105,255,0.10); border-color: rgba(99,169,255,0.32); color: var(--ai-text);
    }
    .v2-dropdown-btn:disabled { opacity: 0.38; cursor: not-allowed; }
    .v2-dropdown.is-error .v2-dropdown-btn { border-color: var(--err); }
    .dd-label-text { max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .v2-dropdown.roster-dd .dd-label-text { max-width: none; }

    .v2-dropdown-panel {
      display: none;
      position: absolute; top: calc(100% + 4px); left: 0; min-width: 160px;
      background: var(--d800); border: 1px solid rgba(255,255,255,0.10);
      border-radius: var(--r-lg); padding: 4px; z-index: 200;
      box-shadow: 0 8px 32px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.06);
      max-height: 260px; overflow-y: auto;
    }
    .v2-dropdown-panel.open { display: block; }
    .v2-dropdown-panel:focus { outline: none; }

    .v2-dropdown-option {
      display: flex; align-items: center; gap: 8px;
      padding: 6px 10px; border-radius: var(--r-sm);
      font-size: 14px; font-weight: 600; color: var(--d200);
      cursor: pointer; white-space: nowrap;
      transition: background-color var(--t-fast), color var(--t-fast);
    }
    /* 5px dot indicator — reserved on every row so selection doesn't shift text */
    .v2-dropdown-option::before {
      content: ""; width: 5px; height: 5px; border-radius: 50%;
      background: transparent; flex-shrink: 0;
    }
    .v2-dropdown-option:hover,
    .v2-dropdown-option.is-active { background: rgba(255,255,255,0.06); color: var(--d50); }
    .v2-dropdown-option.selected,
    .v2-dropdown-option[aria-selected="true"] {
      background: rgba(51,105,255,0.10); color: var(--ai-text);
    }
    .v2-dropdown-option.selected::before,
    .v2-dropdown-option[aria-selected="true"]::before { background: #61adf1; }

    /* Light mode — the panel's dark glass and white-wash hovers need flipping */
    :root[data-theme="light"] .v2-dropdown-btn { background: rgba(16,24,40,0.04); border-color: rgba(16,24,40,0.12); }
    :root[data-theme="light"] .v2-dropdown-btn:hover { background: rgba(16,24,40,0.08); border-color: rgba(16,24,40,0.20); }
    :root[data-theme="light"] .v2-dropdown-btn.open,
    :root[data-theme="light"] .v2-dropdown-btn[aria-expanded="true"],
    :root[data-theme="light"] .v2-dropdown-btn.active-filter { background: rgba(51,105,255,0.10); border-color: rgba(51,105,255,0.32); color: #1f5fd0; }
    :root[data-theme="light"] .v2-dropdown-panel { background: #ffffff; border-color: rgba(16,24,40,0.12);
      box-shadow: 0 8px 32px rgba(16,24,40,0.16); }
    :root[data-theme="light"] .v2-dropdown-option:hover,
    :root[data-theme="light"] .v2-dropdown-option.is-active { background: rgba(16,24,40,0.05); }
    :root[data-theme="light"] .v2-dropdown-option.selected,
    :root[data-theme="light"] .v2-dropdown-option[aria-selected="true"] { color: #1f5fd0; }
    :root[data-theme="light"] .v2-dropdown-option.selected::before,
    :root[data-theme="light"] .v2-dropdown-option[aria-selected="true"]::before { background: #1f5fd0; }

    /* ── Date picker (mini calendar) ── */
    .cal { width: 260px; background: var(--card-bg); border: 1px solid var(--card-border); border-radius: var(--r-lg);
      padding: 14px; box-shadow: var(--shadow-md); }
    .cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
    .cal-title { font-size: 14px; font-weight: 700; color: var(--d50); }
    .cal-nav { width: 26px; height: 26px; border-radius: var(--r-sm); border: 1px solid var(--card-border);
      background: var(--card-bg-raised); color: var(--ink-muted); cursor: pointer; display: flex; align-items: center; justify-content: center; }
    .cal-nav:hover { color: var(--accent); border-color: var(--card-border-hover); }
    .cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
    .cal-dow { font-size: 14px; font-weight: 700; color: var(--ink-muted); text-align: center; padding: 4px 0; }
    .cal-day { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; font-size: 16px;
      color: var(--d200); border-radius: var(--r-sm); cursor: pointer; transition: background var(--t-fast), color var(--t-fast); }
    .cal-day:hover { background: var(--card-bg-raised); }
    .cal-day.muted { color: var(--ink-muted); }
    .cal-day.today { border: 1px solid var(--card-border-hover); }
    .cal-day.selected { background: var(--accent); color: #fff; font-weight: 700; }

    /* ── Radio cards (selection cards) ── */
    .radio-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; max-width: 520px; }
    .radio-card { position: relative; padding: 14px; border-radius: var(--r-lg); cursor: pointer;
      background: var(--card-bg-raised); border: 1.5px solid var(--card-border);
      transition: border-color var(--t-fast), background var(--t-fast); }
    .radio-card input { position: absolute; opacity: 0; }
    .radio-card:hover { border-color: var(--card-border-hover); }
    .radio-card:has(input:checked) { border-color: var(--accent); background: var(--accent-dim); }
    .radio-card:has(input:focus-visible) { box-shadow: 0 0 0 3px var(--accent-glow); }
    .rc-title { font-size: 14px; font-weight: 700; color: var(--d50); }
    .rc-desc { font-size: 14px; color: var(--ink-muted); margin-top: 3px; line-height: 1.5; }


    /* ═══════════════════════════════════════════════
       GENERAL COMPONENTS — batch 3 (all token-based,
       theme-aware in light & dark by construction)
    ═══════════════════════════════════════════════ */

    /* ── Toolbar ── */
    .toolbar { display: inline-flex; align-items: center; gap: 4px; padding: 5px;
      background: var(--card-bg-raised); border: 1px solid var(--card-border); border-radius: var(--r-lg); }
    .toolbar-sep { width: 1px; height: 20px; background: var(--card-border); margin: 0 3px; }
    .toolbar .icon-btn { border: none; background: transparent; }
    .toolbar .icon-btn:hover { background: var(--card-bg); }
    .toolbar .icon-btn.active { background: var(--accent-dim); color: var(--accent); }

    /* ── Split button ── */
    .split-btn { display: inline-flex; }
    .split-btn .btn { border-radius: var(--r-md) 0 0 var(--r-md); }
    .split-btn .split-caret { display: inline-flex; align-items: center; justify-content: center;
      width: 30px; border-radius: 0 var(--r-md) var(--r-md) 0; cursor: pointer;
      background: var(--brand); color: #fff; border: 1px solid var(--brand);
      border-left: 1px solid rgba(255,255,255,0.25); transition: filter var(--t-fast); }
    .split-btn .split-caret:hover { filter: brightness(1.12); }

    /* ── Tree view (native <details>) ── */
    .tree { max-width: 340px; font-size: 14px; }
    .tree details { margin: 0; }
    .tree summary { list-style: none; display: flex; align-items: center; gap: 7px;
      padding: 6px 8px; border-radius: var(--r-sm); cursor: pointer; color: var(--d200);
      font-weight: 600; transition: background var(--t-fast); }
    .tree summary::-webkit-details-marker { display: none; }
    .tree summary:hover, .tree .tree-leaf:hover { background: var(--card-bg-raised); }
    .tree .tree-chev { transition: transform var(--t-base) var(--ease-out); color: var(--ink-muted); flex-shrink: 0; }
    .tree details[open] > summary .tree-chev { transform: rotate(90deg); }
    .tree .tree-children { padding-left: 22px; }
    .tree .tree-leaf { display: flex; align-items: center; gap: 7px; padding: 6px 8px;
      border-radius: var(--r-sm); color: var(--ink-muted); cursor: pointer; font-weight: 500; }
    .tree .tree-leaf.selected { background: var(--accent-dim); color: var(--accent); font-weight: 600; }
    .tree svg { flex-shrink: 0; }

    /* ── Command palette (static specimen) ── */
    .cmdk { max-width: 480px; border-radius: var(--r-2xl); overflow: hidden;
      background: var(--panel-bg); border: 1px solid var(--glass-border);
      box-shadow: var(--shadow-xl); backdrop-filter: blur(16px); }
    .cmdk-input-row { display: flex; align-items: center; gap: 10px; padding: 14px 16px;
      border-bottom: 1px solid var(--hairline); color: var(--ink-muted); }
    .cmdk-input-row input { flex: 1; background: none; border: none; outline: none;
      font-family: var(--font-sans); font-size: 14px; color: var(--d50); }
    .cmdk-input-row input::placeholder { color: var(--ink-muted); }
    .cmdk-group { font-size: 14px; font-weight: 700; text-transform: uppercase;
      letter-spacing: 0.08em; color: var(--ink-muted); padding: 10px 16px 4px; }
    .cmdk-item { display: flex; align-items: center; gap: 11px; padding: 9px 16px;
      font-size: 14px; color: var(--d200); cursor: pointer; }
    .cmdk-item svg { color: var(--ink-muted); flex-shrink: 0; }
    .cmdk-item .cmdk-kbd { margin-left: auto; }
    .cmdk-item.active { background: var(--accent-dim); color: var(--d50); }
    .cmdk-item.active svg { color: var(--accent); }
    .cmdk-foot { display: flex; gap: 14px; padding: 9px 16px; border-top: 1px solid var(--hairline);
      font-size: 14px; color: var(--ink-muted); }

    /* ── Settings row ── */
    .settings-list { max-width: 520px; border: 1px solid var(--card-border);
      border-radius: var(--r-lg); overflow: hidden; background: var(--card-bg); }
    .settings-row { display: flex; align-items: center; gap: 16px; padding: 14px 16px;
      border-bottom: 1px solid var(--hairline); }
    .settings-row:last-child { border-bottom: none; }
    .settings-row .sr-main { flex: 1; min-width: 0; }
    .settings-row .sr-title { font-size: 14px; font-weight: 600; color: var(--d100); }
    .settings-row .sr-desc { font-size: 14px; color: var(--ink-muted); margin-top: 2px; line-height: 1.5; }

    /* ── Links ── */
    .link { color: var(--brand); text-decoration: none; font-weight: 600; cursor: pointer;
      border-bottom: 1px solid transparent; transition: border-color var(--t-fast); }
    .link:hover { border-bottom-color: currentColor; }
    .link.inline { text-decoration: underline; text-underline-offset: 3px; border: none; }
    .link.muted { color: var(--ink-muted); }
    .link.muted:hover { color: var(--d200); }
    .link svg { vertical-align: -2px; margin-left: 3px; }

    /* ── Sparkline ── */
    .sparkline { display: inline-block; vertical-align: middle; }
    .sparkline polyline { fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
    .sparkline .spark-fill { opacity: 0.12; stroke: none; }

    /* ── Gauge (semi-circle) ── */
    .gauge-wrap { display: inline-flex; flex-direction: column; align-items: center; }
    .gauge-value { font-size: 22px; font-weight: 800; color: var(--d50); margin-top: -30px; }
    .gauge-label { font-size: 14px; font-weight: 700; text-transform: uppercase;
      letter-spacing: 0.06em; color: var(--ink-muted); margin-top: 2px; }

    /* ── Progress circle ── */
    .pcircle-wrap { display: inline-flex; align-items: center; gap: 10px; }
    .pcircle { transform: rotate(-90deg); }
    .pcircle .track { fill: none; stroke: var(--card-border); stroke-width: 4; }
    .pcircle .val { fill: none; stroke: var(--brand); stroke-width: 4; stroke-linecap: round; }
    .pcircle-label { font-size: 14px; font-weight: 600; color: var(--d200); }

    /* ── Notification item ── */
    .notif-list { max-width: 440px; border: 1px solid var(--card-border);
      border-radius: var(--r-lg); overflow: hidden; background: var(--card-bg); }
    .notif { display: flex; gap: 12px; padding: 13px 14px; border-bottom: 1px solid var(--hairline);
      transition: background var(--t-fast); cursor: pointer; position: relative; }
    .notif:last-child { border-bottom: none; }
    .notif:hover { background: var(--card-bg-raised); }
    .notif.unread { background: var(--brand-dim); }
    .notif.unread::before { content: ""; position: absolute; left: 5px; top: 50%;
      transform: translateY(-50%); width: 6px; height: 6px; border-radius: 50%; background: var(--brand); }
    .notif-ico { width: 32px; height: 32px; border-radius: var(--r-md); flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      background: var(--card-bg-raised); color: var(--ink-muted); border: 1px solid var(--card-border); }
    .notif-title { font-size: 14px; font-weight: 600; color: var(--d100); }
    .notif-body { font-size: 14px; color: var(--ink-muted); margin-top: 2px; line-height: 1.5; }
    .notif-time { font-size: 14px; color: var(--ink-muted); margin-left: auto; flex-shrink: 0; }

    /* ── Comment thread ── */
    .comment { display: flex; gap: 11px; }
    .comment .comment-body { flex: 1; min-width: 0; }
    .comment-head { display: flex; align-items: baseline; gap: 8px; }
    .comment-author { font-size: 14px; font-weight: 700; color: var(--d100); }
    .comment-time { font-size: 14px; color: var(--ink-muted); }
    .comment-text { font-size: 14px; color: var(--ink-muted); line-height: 1.6; margin-top: 3px; }
    .comment-actions { display: flex; gap: 12px; margin-top: 6px; }
    .comment-actions .link { font-size: 14px; }
    .comment-replies { margin-top: 12px; padding-left: 16px; border-left: 2px solid var(--card-border); }

    /* ── Profile card ── */
    .profile-card { width: 280px; padding: 18px; border-radius: var(--r-xl);
      background: var(--card-bg); border: 1px solid var(--card-border); box-shadow: var(--shadow-md); }
    .profile-head { display: flex; align-items: center; gap: 12px; }
    .profile-name { font-size: 14px; font-weight: 700; color: var(--d50); }
    .profile-role { font-size: 14px; color: var(--ink-muted); margin-top: 1px; }
    .profile-stats { display: flex; gap: 0; margin: 14px 0; border: 1px solid var(--hairline);
      border-radius: var(--r-md); overflow: hidden; }
    .profile-stat { flex: 1; text-align: center; padding: 8px 4px; background: var(--card-bg-raised); }
    .profile-stat + .profile-stat { border-left: 1px solid var(--hairline); }
    .profile-stat b { display: block; font-size: 14px; font-weight: 800; color: var(--d50); }
    .profile-stat span { font-size: 14px; font-weight: 600; text-transform: uppercase;
      letter-spacing: 0.05em; color: var(--ink-muted); }

    /* ── Coach mark ── */
    .coach-anchor { position: relative; display: inline-block; }
    .coach-dot { position: absolute; top: -5px; right: -5px; width: 12px; height: 12px;
      border-radius: 50%; background: var(--accent); }
    .coach-dot::after { content: ""; position: absolute; inset: -4px; border-radius: 50%;
      border: 2px solid var(--accent); opacity: 0.5; animation: statusPulse 1.6s ease-out infinite; }
    .coach-card { position: absolute; top: calc(100% + 12px); left: 0; width: 250px; z-index: 20;
      background: var(--card-bg); border: 1px solid var(--card-border-focus);
      border-radius: var(--r-lg); box-shadow: var(--shadow-lg); padding: 14px; }
    .coach-step { font-size: 14px; font-weight: 700; letter-spacing: 0.07em;
      text-transform: uppercase; color: var(--accent); }
    .coach-title { font-size: 14px; font-weight: 700; color: var(--d50); margin: 4px 0 3px; }
    .coach-text { font-size: 14px; color: var(--ink-muted); line-height: 1.55; }
    .coach-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 12px; }

    /* ── Loading overlay ── */
    .loading-stage { position: relative; border-radius: var(--r-lg); overflow: hidden;
      border: 1px solid var(--card-border); }
    .loading-overlay { position: absolute; inset: 0; display: flex; flex-direction: column;
      align-items: center; justify-content: center; gap: 10px;
      background: rgba(0,0,0,0.32); backdrop-filter: blur(2px); z-index: 5; }
    .loading-panel { display: flex; flex-direction: column; align-items: center; gap: 10px;
      background: var(--card-bg); border: 1px solid var(--card-border); border-radius: var(--r-lg);
      padding: 18px 26px; box-shadow: var(--shadow-lg); }
    .loading-spinner { width: 22px; height: 22px; border-radius: 50%;
      border: 2.5px solid var(--brand-dim); border-top-color: var(--brand);
      animation: spin 0.7s linear infinite; }
    .loading-text { font-size: 16px; font-weight: 600; color: var(--ink-muted); }

    /* ── Tag input ── */
    .tag-input { display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
      max-width: 420px; padding: 7px 9px; background: var(--card-bg-raised);
      border: 1px solid var(--card-border); border-radius: var(--r-md);
      transition: border-color var(--t-fast), box-shadow var(--t-fast); }
    .tag-input:focus-within { border-color: var(--card-border-focus); box-shadow: 0 0 0 3px var(--brand-glow); }
    .tag-token { display: inline-flex; align-items: center; gap: 5px; padding: 3px 6px 3px 9px;
      border-radius: var(--r-sm); font-size: 14px; font-weight: 600;
      background: var(--accent-dim); color: var(--accent); border: 1px solid rgba(var(--accent-rgb),0.25); }
    .tag-token button { background: none; border: none; color: inherit; cursor: pointer;
      font-size: 14px; line-height: 1; padding: 0 2px; opacity: 0.65; }
    .tag-token button:hover { opacity: 1; }
    .tag-input input { flex: 1; min-width: 80px; background: none; border: none; outline: none;
      font-family: var(--font-sans); font-size: 14px; color: var(--d50); padding: 3px; }
    .tag-input input::placeholder { color: var(--ink-muted); }

    /* ── Password input ── */
    .pw-wrap { position: relative; max-width: 300px; }
    .pw-wrap .field-input { padding-right: 40px; }
    .pw-eye { position: absolute; right: 6px; top: 5px; width: 28px; height: 28px;
      display: flex; align-items: center; justify-content: center; border-radius: var(--r-sm);
      background: none; border: none; color: var(--ink-muted); cursor: pointer; }
    .pw-eye:hover { color: var(--d200); background: var(--card-bg-raised); }
    .pw-meter { display: flex; gap: 4px; margin-top: 8px; }
    .pw-meter span { height: 4px; flex: 1; border-radius: var(--r-pill); background: var(--card-border); }
    .pw-meter span.on-weak { background: var(--err); }
    .pw-meter span.on-mid  { background: var(--warn); }
    .pw-meter span.on-good { background: var(--ok); }
    .pw-hint { font-size: 14px; color: var(--ink-muted); margin-top: 5px; }

    /* ── OTP input ── */
    .otp { display: flex; gap: 8px; }
    .otp input { width: 42px; height: 48px; text-align: center; font-family: var(--font-mono);
      font-size: 18px; font-weight: 600; color: var(--d50);
      background: var(--card-bg-raised); border: 1.5px solid var(--card-border);
      border-radius: var(--r-md); outline: none; caret-color: var(--brand);
      transition: border-color var(--t-fast), box-shadow var(--t-fast); }
    .otp input:focus, .otp input.is-focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-glow); }

    /* ── Time picker ── */
    .time-picker { position: relative; display: inline-block; }
    .time-panel { width: 130px; max-height: 178px; overflow: hidden; margin-top: 6px;
      background: var(--card-bg); border: 1px solid var(--card-border);
      border-radius: var(--r-lg); box-shadow: var(--shadow-md); padding: 4px; }
    .time-opt { padding: 7px 12px; border-radius: var(--r-sm); font-size: 14px;
      color: var(--d200); cursor: pointer; font-variant-numeric: tabular-nums; }
    .time-opt:hover { background: var(--card-bg-raised); }
    .time-opt.selected { background: var(--accent-dim); color: var(--accent); font-weight: 700; }

    /* ── Input group (addons) ── */
    .input-group { display: flex; max-width: 420px; }
    .input-group .ig-addon { display: flex; align-items: center; padding: 0 12px;
      font-size: 14px; font-weight: 500; color: var(--ink-muted);
      background: var(--card-bg-raised); border: 1px solid var(--card-border); white-space: nowrap; }
    .input-group .ig-addon:first-child { border-radius: var(--r-md) 0 0 var(--r-md); border-right: none; }
    .input-group .ig-addon:last-child { border-radius: 0 var(--r-md) var(--r-md) 0; border-left: none; }
    .input-group .field-input { border-radius: 0; flex: 1; }
    .input-group .field-input:first-child { border-radius: var(--r-md) 0 0 var(--r-md); }
    .input-group .field-input:last-child { border-radius: 0 var(--r-md) var(--r-md) 0; }

    /* ── Copy field ── */
    /* Part of .copy-field's anatomy, so it lives in the component layer.
       The explicit svg size is load-bearing: an SVG with a viewBox and no
       dimensions expands to fill its container. */
    .copy-btn {
      display: inline-flex; align-items: center; gap: 4px;
      font-family: var(--font-sans); font-size: 14px; font-weight: 700;
      padding: 4px 9px; border-radius: var(--r-sm);
      background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.1);
      color: var(--ink-muted); cursor: pointer;
      transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast);
      white-space: nowrap;
    }
    .copy-btn:hover { background: rgba(255,255,255,0.1); color: var(--d100); border-color: rgba(255,255,255,0.18); }
    .copy-btn.copied { background: var(--ok-bg); border-color: color-mix(in srgb, var(--ok) 30%, transparent); color: var(--ok); }
    .copy-btn svg { width: 11px; height: 11px; flex-shrink: 0; }

    .copy-field { display: flex; align-items: center; gap: 10px; max-width: 420px;
      padding: 9px 9px 9px 13px; background: var(--card-bg-raised);
      border: 1px solid var(--card-border); border-radius: var(--r-md); }
    .copy-field code { flex: 1; font-family: var(--font-mono); font-size: 16px;
      color: var(--d100); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; background: none; }

    /* ── Dual range (specimen) ── */
    .drange { position: relative; width: 260px; height: 18px; }
    .drange .dr-track { position: absolute; top: 7px; left: 0; right: 0; height: 5px;
      border-radius: var(--r-pill); background: var(--card-bg-raised); border: 1px solid var(--card-border); }
    .drange .dr-fill { position: absolute; top: 7px; height: 5px; border-radius: var(--r-pill); background: var(--accent); }
    .drange .dr-thumb { position: absolute; top: 0; width: 17px; height: 17px; border-radius: 50%;
      background: var(--accent); border: 2px solid var(--card-bg); box-shadow: var(--shadow-sm); cursor: grab; }
    .drange-vals { font-size: 14px; color: var(--ink-muted); margin-top: 8px; font-variant-numeric: tabular-nums; }

    /* ── Upload progress item ── */
    .upload-list { max-width: 440px; display: flex; flex-direction: column; gap: 8px; }
    .upload-item { display: flex; align-items: center; gap: 11px; padding: 10px 12px;
      background: var(--card-bg); border: 1px solid var(--card-border); border-radius: var(--r-lg); }
    .upload-item.error { border-color: color-mix(in srgb, var(--err) 35%, transparent); }
    .upload-ico { width: 32px; height: 32px; border-radius: var(--r-md); flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      background: var(--brand-dim); color: var(--brand); }
    .upload-main { flex: 1; min-width: 0; }
    .upload-name { font-size: 16px; font-weight: 600; color: var(--d100);
      overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .upload-meta { font-size: 14px; color: var(--ink-muted); margin-top: 2px; }
    .upload-item .ds-progress { height: 4px; margin-top: 6px; border: none; }
    .upload-state { flex-shrink: 0; font-size: 14px; font-weight: 700; }
    .upload-state.ok { color: var(--ok); }
    .upload-state.err { color: var(--err); }


    /* ═══════════════════════════════════════════════
       ERROR & SYSTEM STATES — batch 4
    ═══════════════════════════════════════════════ */

    /* Error variants for inputs that lacked one */
    .v2-dropdown.is-error .v2-dropdown-btn { border-color: var(--err); }
    .ds-textarea.is-error { border-color: var(--err); }
    .tag-input.is-error { border-color: var(--err); }
    .tag-input.is-error:focus-within { border-color: var(--err); box-shadow: 0 0 0 3px var(--err-glow); }
    .otp.is-error input { border-color: var(--err); color: var(--err); }

    /* Error state panel (failed fetch) */
    .error-state { display: flex; flex-direction: column; align-items: center; text-align: center;
      padding: 40px 32px; background: var(--card-bg); border: 1px dashed color-mix(in srgb, var(--err) 35%, transparent);
      border-radius: var(--r-2xl); }
    .error-state-icon { width: 44px; height: 44px; border-radius: var(--r-xl);
      background: var(--err-bg); color: var(--err);
      display: flex; align-items: center; justify-content: center; margin-bottom: 14px; }
    .error-state-title { font-size: 14px; font-weight: 700; color: var(--d50); margin-bottom: 5px; }
    .error-state-desc { font-size: 14px; color: var(--ink-muted); line-height: 1.6; max-width: 320px; margin-bottom: 18px; }

    /* Offline / degraded bar */
    .offline-bar { display: flex; align-items: center; justify-content: center; gap: 9px;
      padding: 8px 14px; background: var(--warn-bg); border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent);
      border-radius: var(--r-md); font-size: 16px; font-weight: 600; color: var(--warn); }

    /* Error page specimen (404 / 500) */
    .error-page { display: flex; flex-direction: column; align-items: center; justify-content: center;
      text-align: center; padding: 44px 24px; }
    .error-code { font-family: var(--font-display); font-size: 54px; font-weight: 800;
      letter-spacing: -0.03em; color: var(--ink-muted); line-height: 1; }
    .error-page-title { font-family: var(--font-display); font-size: 18px; font-weight: 700;
      color: var(--d50); margin: 10px 0 6px; }
    .error-page-desc { font-size: 14px; color: var(--ink-muted); max-width: 340px; line-height: 1.6; margin-bottom: 18px; }

    /* Form error summary */
    .form-summary { border: 1px solid color-mix(in srgb, var(--err) 35%, transparent); border-left: 3px solid var(--err);
      background: var(--err-bg); border-radius: var(--r-lg); padding: 13px 16px; max-width: 420px; }
    .form-summary-title { display: flex; align-items: center; gap: 8px;
      font-size: 14px; font-weight: 700; color: var(--err); }
    .form-summary ul { margin: 8px 0 0; padding-left: 18px; display: flex; flex-direction: column; gap: 4px; }
    .form-summary li { font-size: 16px; color: var(--d200); }
    .form-summary li a { color: var(--err); font-weight: 600; cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }


    /* ═══════════════════════════════════════════════
       AI COMPONENTS — batch 5 (AI-native patterns)
    ═══════════════════════════════════════════════ */
    @keyframes aiDot { 0%,100% { opacity: 0.25; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-2px); } }
    @keyframes wave  { 0%,100% { transform: scaleY(0.35); } 50% { transform: scaleY(1); } }

    /* ── Thinking indicator + streaming cursor ── */
    .ai-thinking { display: inline-flex; align-items: center; gap: 10px; padding: 9px 15px;
      border-radius: var(--r-pill); background: var(--card-bg-raised); border: 1px solid var(--card-border); }
    .ai-thinking .dots { display: inline-flex; gap: 4px; }
    .ai-thinking .dots span { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); animation: aiDot 1.2s ease-in-out infinite; }
    .ai-thinking .dots span:nth-child(2) { animation-delay: 0.15s; }
    .ai-thinking .dots span:nth-child(3) { animation-delay: 0.3s; }
    .ai-thinking-label { font-size: 16px; font-weight: 600; color: var(--ink-muted); }
    .stream-cursor { display: inline-block; width: 7px; height: 14px; background: var(--accent);
      border-radius: 1px; vertical-align: -2px; margin-left: 2px; animation: blink 1s steps(1) infinite; }

    /* ── Reasoning disclosure ── */
    .reasoning { max-width: 480px; border: 1px solid var(--card-border); border-radius: var(--r-lg);
      background: var(--card-bg-raised); overflow: hidden; }
    .reasoning summary { list-style: none; display: flex; align-items: center; gap: 8px;
      padding: 10px 13px; cursor: pointer; font-size: 16px; font-weight: 600; color: var(--ink-muted); }
    .reasoning summary::-webkit-details-marker { display: none; }
    .reasoning .chev { transition: transform var(--t-base) var(--ease-out); flex-shrink: 0; }
    .reasoning[open] summary .chev { transform: rotate(90deg); }
    .reasoning-body { padding: 2px 13px 12px 34px; font-size: 16px; color: var(--ink-muted); line-height: 1.65; }

    /* ── Response actions ── */
    .ai-actions { display: inline-flex; align-items: center; gap: 2px; padding: 3px;
      border-radius: var(--r-md); background: var(--card-bg-raised); border: 1px solid var(--card-border); }
    .ai-actions button { width: 26px; height: 26px; display: flex; align-items: center; justify-content: center;
      border: none; background: none; border-radius: var(--r-sm); color: var(--ink-muted); cursor: pointer;
      transition: background var(--t-fast), color var(--t-fast); }
    .ai-actions button:hover { background: var(--card-bg); color: var(--d100); }
    .ai-actions button.selected { color: var(--ok); }
    .ai-actions .sep { width: 1px; height: 16px; background: var(--card-border); margin: 0 2px; }

    /* ── Citations & sources ── */
    .cite { display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px;
      padding: 0 4px; border-radius: 5px; background: var(--brand-dim); color: var(--brand);
      font-size: 14px; font-weight: 700; vertical-align: 2px; margin: 0 2px; cursor: pointer;
      border: 1px solid rgba(51,105,255,0.25); }
    .source-list { display: flex; flex-direction: column; gap: 6px; margin-top: 12px; }
    .source-item { display: flex; align-items: center; gap: 9px; padding: 8px 11px;
      border-radius: var(--r-md); background: var(--card-bg-raised); border: 1px solid var(--card-border);
      font-size: 14px; font-weight: 600; color: var(--d200); cursor: pointer; }
    .source-item .cite { margin: 0; flex-shrink: 0; }
    .source-domain { color: var(--ink-muted); margin-left: auto; font-size: 14px; font-weight: 500; }

    /* ── Agent steps ── */
    .agent-steps { display: flex; flex-direction: column; }
    .agent-step { display: flex; gap: 11px; padding: 6px 0; align-items: flex-start; }
    .agent-step-ico { width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      background: var(--card-bg-raised); border: 1.5px solid var(--card-border); color: var(--ink-muted); }
    .agent-step.done .agent-step-ico { background: var(--ok-bg); border-color: transparent; color: var(--ok); }
    .agent-step.running .agent-step-ico { border-color: var(--accent); }
    .agent-step .mini-spin { width: 10px; height: 10px; border-radius: 50%;
      border: 1.5px solid var(--accent-dim); border-top-color: var(--accent); animation: spin 0.7s linear infinite; }
    .agent-step-label { font-size: 14px; font-weight: 600; color: var(--d200); line-height: 1.4; }
    .agent-step.pending .agent-step-label { color: var(--ink-muted); font-weight: 500; }
    .agent-step-meta { font-size: 14px; color: var(--ink-muted); margin-top: 1px; }

    /* ── AI suggestion review ── */
    .ai-suggestion { border: 1px solid rgba(var(--accent-rgb),0.3);
      border-radius: var(--r-lg); background: var(--accent-dim); overflow: hidden; }
    .ai-suggestion-head { display: flex; align-items: center; gap: 7px; padding: 9px 13px;
      font-size: 14px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--accent); }
    .ai-suggestion-body { background: var(--card-bg); margin: 0 8px; border-radius: var(--r-md);
      padding: 10px 12px; font-size: 14px; line-height: 1.7; color: var(--d200);
      border: 1px solid var(--card-border); }
    .ai-suggestion-body del { color: var(--err); background: var(--err-bg); text-decoration: line-through; border-radius: 3px; padding: 0 3px; }
    .ai-suggestion-body ins { color: var(--ok); background: var(--ok-bg); text-decoration: none; border-radius: 3px; padding: 0 3px; }
    .ai-suggestion-foot { display: flex; gap: 8px; padding: 10px 8px 8px; }

    /* ── Context chips (attached to prompt) ── */
    .ctx-chips { display: flex; gap: 6px; flex-wrap: wrap; }
    .ctx-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 7px 4px 5px;
      border-radius: var(--r-md); background: var(--card-bg-raised); border: 1px solid var(--card-border);
      font-size: 14px; font-weight: 600; color: var(--d200); }
    .ctx-chip .ctx-ico { width: 18px; height: 18px; border-radius: 5px; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center; background: var(--brand-dim); color: var(--brand); }
    .ctx-chip button { background: none; border: none; color: var(--ink-muted); cursor: pointer;
      font-size: 16px; line-height: 1; padding: 0 1px; }
    .ctx-chip button:hover { color: var(--d100); }

    /* ── Model / agent picker ── */
    .model-picker { display: inline-flex; align-items: center; gap: 9px; padding: 7px 12px;
      border-radius: var(--r-lg); background: var(--card-bg-raised); border: 1px solid var(--card-border);
      cursor: pointer; transition: border-color var(--t-fast); }
    .model-picker:hover { border-color: var(--card-border-hover); }
    .model-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--ai); flex-shrink: 0; }
    .model-name { font-size: 14px; font-weight: 700; color: var(--d100); }
    .model-tag { font-size: var(--fs-2xs); font-weight: 700;
      padding: 2px 7px; border-radius: var(--r-pill); background: var(--teal-dim); color: var(--teal); }

    /* ── Voice input ── */
    .voice-btn { width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--card-border);
      background: var(--card-bg-raised); color: var(--ink-muted); cursor: pointer;
      display: inline-flex; align-items: center; justify-content: center;
      transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast); }
    .voice-btn:hover { color: var(--accent); border-color: var(--card-border-hover); }
    .voice-btn.recording { background: var(--err-bg); border-color: color-mix(in srgb, var(--err) 40%, transparent); color: var(--err); }
    .voice-wave { display: inline-flex; gap: 2.5px; align-items: center; height: 18px; }
    .voice-wave span { width: 2.5px; height: 16px; border-radius: 2px; background: var(--err);
      animation: wave 1s ease-in-out infinite; transform-origin: center; }
    .voice-wave span:nth-child(2) { animation-delay: 0.12s; } .voice-wave span:nth-child(3) { animation-delay: 0.24s; }
    .voice-wave span:nth-child(4) { animation-delay: 0.36s; } .voice-wave span:nth-child(5) { animation-delay: 0.48s; }
    /* Poppins, like everything else on screen. It has no tabular figures,
       so a timer set in it changes width as it counts — measured at this
       size: "1:11" is 15.91px against 28.50px for "9:59", a 12.59px range,
       and "0:10" to "0:11" alone jumps 4.17px in a single tick. Monospace
       held a flat 29.83px for every string and that is precisely what is
       being given up here.

       So the BOX is pinned instead: min-width at the widest string plus a
       little, which stops the composer around it reflowing once a second.
       The digits still shift inside that box. That part is inherent to a
       proportional face and only per-digit spans, or a face with real
       tabular figures, would cure it. tabular-nums is declared anyway — it
       costs nothing and starts working the day the face ships the feature. */
    .voice-timer { font-family: var(--font-sans); font-size: 14px; color: var(--err);
      font-variant-numeric: tabular-nums; min-width: 2.25em; text-align: center; }

    /* ── Inline AI menu (text-selection toolbar) ── */
    .ai-menu { display: inline-flex; align-items: center; gap: 2px; padding: 3px;
      border-radius: var(--r-lg); background: var(--panel-bg); border: 1px solid var(--glass-border);
      box-shadow: var(--shadow-lg); backdrop-filter: blur(12px); }
    .ai-menu button { display: inline-flex; align-items: center; gap: 5px; padding: 5px 10px;
      border-radius: var(--r-sm); background: none; border: none; font-family: var(--font-sans);
      font-size: 14px; font-weight: 600; color: var(--d200); cursor: pointer;
      transition: background var(--t-fast), color var(--t-fast); }
    .ai-menu button:hover { background: var(--card-bg-raised); color: var(--d50); }
    .ai-menu .ai-menu-primary { color: var(--accent); }
    .ai-menu .sep { width: 1px; height: 16px; background: var(--hairline); margin: 0 2px; }

    /* ── Usage meter + disclaimer ── */
    .usage-pill { display: inline-flex; align-items: center; gap: 10px; padding: 6px 13px;
      border-radius: var(--r-pill); background: var(--card-bg-raised); border: 1px solid var(--card-border);
      font-size: 14px; font-weight: 600; color: var(--ink-muted); }
    .usage-pill .ds-progress { display: inline-block; width: 70px; height: 5px; border: none; }
    .ai-disclaimer { display: flex; align-items: center; justify-content: center; gap: 7px;
      font-size: 14px; color: var(--ink-muted); }


    /* ═══════════════════════════════════════════════
       AIMY DOCTRINE PRIMITIVES
       Components required by the Knowledge-to-Action
       Doctrine (§2.3 work state, §3 entry modes,
       §3.1 confirmation ladder, §4 continuity, §6.2).
       Semantic tokens only — light mode inherits.
    ═══════════════════════════════════════════════ */

    /* ── Work state (§2.3) — six values, required on every surfaced item ── */
    /* Nine px was below the smallest step in the scale, and the tracking was
       a literal of the value the token now carries. Same footing as the tag:
       the two small tracked-capital badges in this system were at nine and
       ten by accident rather than by decision. */
    .work-state {
      display: inline-flex; align-items: center; gap: 6px;
      font-size: var(--fs-2xs); font-weight: 700; padding: 3px 9px 3px 7px;
      border-radius: var(--r-pill);
      line-height: 16px;
      white-space: nowrap; vertical-align: middle;
      border: 1px solid transparent;
    }
    .work-state .ws-dot {
      width: 6px; height: 6px; border-radius: 50%;
      background: currentColor; flex-shrink: 0;
    }
    /* ══ SIX STATES, SIX HUES, ONE EACH ═══════════════════════════════
       These read as a sequence and they are not one: an item can be
       detected and never move, and `failed` can end it from anywhere. They
       are six different CLAIMS — AiMY noticed this · AiMY has an opinion
       about it · AiMY wrote it · it is your turn · it ran · it did not —
       and a claim is exactly what the family is for. This is the most
       important label in the system, on every surfaced item, so it gets the
       whole family rather than a share of it.

       The dot keeps its own job on top: hollow while AiMY is still working
       on the thing, filled once the thing is real. */
    /* detected — AiMY noticed it, nothing proposed yet */
    .ws-detected .ws-dot { background: none; box-shadow: inset 0 0 0 1.5px currentColor; }
    /* drafted — AiMY produced content, not yet queued */
    .ws-drafted .ws-dot { background: none; box-shadow: inset 0 0 0 1.5px currentColor; }
    .ws-detected    { color: var(--info);         background: color-mix(in srgb, var(--info) 15%, transparent); }
    .ws-recommended { color: var(--accent-label); background: color-mix(in srgb, var(--accent-label) 15%, transparent); }
    .ws-drafted     { color: var(--teal-label);   background: color-mix(in srgb, var(--teal-label) 15%, transparent); }
    /* staged — the ball is in the human's court, and that is the one that
       wants attention rather than the one that is finished */
    .ws-staged      { color: var(--warn);         background: color-mix(in srgb, var(--warn) 15%, transparent); }
    /* completed (display label may be "handled") */
    .ws-completed   { color: var(--ok);           background: color-mix(in srgb, var(--ok) 15%, transparent); }
    /* failed (display label may be "blocked") */
    .ws-failed      { color: var(--err);          background: color-mix(in srgb, var(--err) 15%, transparent); }

    /* Work-state pipeline — shows position in detected → … → completed */
    .ws-track { display: inline-flex; align-items: center; gap: 0; flex-wrap: wrap; }
    .ws-track .ws-step {
      display: inline-flex; align-items: center; gap: 5px;
      font-size: var(--fs-2xs); font-weight: 700; color: var(--ink-muted); padding: 4px 8px;
    }
    .ws-track .ws-step .ws-dot {
      width: 6px; height: 6px; border-radius: 50%; background: var(--d700);
    }
    .ws-track .ws-step.is-past { color: var(--ink-muted); }
    .ws-track .ws-step.is-past .ws-dot { background: var(--d500); }
    /* Where you are on the track is carried by ink and weight, not by a
       hue — the step behind it is already a step down in ink, so a third
       value at the top of the ramp separates them without spending one. */
    .ws-track .ws-step.is-current { color: var(--d50); }
    .ws-track .ws-step.is-current .ws-dot { background: var(--d100); }
    .ws-track .ws-sep { width: 14px; height: 1px; background: var(--hairline); flex-shrink: 0; }

    /* ── Confidence badge (§5.7, §6.2, Level 5) ── */
    .conf-badge {
      display: inline-flex; align-items: center; gap: 6px;
      font-size: var(--fs-2xs); font-weight: 700; padding: 3px 9px 3px 7px;
      border-radius: var(--r-pill); white-space: nowrap; vertical-align: middle;
      background: rgba(255,255,255,0.05); border: 1px solid var(--card-border);
      color: var(--ink-muted);
    }
    .conf-meter { display: inline-flex; align-items: flex-end; gap: 2px; height: 10px; flex-shrink: 0; }
    .conf-meter i { width: 3px; border-radius: 1px; background: var(--d700); display: block; }
    .conf-meter i:nth-child(1) { height: 4px; }
    .conf-meter i:nth-child(2) { height: 7px; }
    .conf-meter i:nth-child(3) { height: 10px; }
    .conf-high .conf-meter i { background: var(--ok); }
    .conf-high   { color: var(--ok);   border-color: color-mix(in srgb, var(--ok) 24%, transparent); background: var(--ok-bg); }
    .conf-medium .conf-meter i:nth-child(-n+2) { background: var(--warn); }
    .conf-medium { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 24%, transparent); background: var(--warn-bg); }
    .conf-low .conf-meter i:nth-child(1) { background: var(--err); }
    .conf-low    { color: var(--err);  border-color: color-mix(in srgb, var(--err) 24%, transparent); background: var(--err-bg); }
    .conf-badge .conf-val { font-family: var(--font-mono); font-size: 14px; opacity: 0.75; }

    /* ── Entry-mode affordances (§3) — the same click must not always
         produce the same behaviour, so it must not always look the same ── */
    .entry-action {
      display: inline-flex; align-items: center; gap: 7px;
      font-family: var(--font-sans); font-size: 16px; font-weight: 700;
      padding: 8px 14px; border-radius: var(--r-md); cursor: pointer;
      border: 1px solid transparent; white-space: nowrap;
      transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast);
    }
    .entry-action .em-ico { width: 14px; height: 14px; flex-shrink: 0; opacity: 0.9; }
    .entry-action:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
    /* direct — completes in place, offers undo. Solid, committal. */
    .em-direct    { background: var(--brand); color: #fff; border-color: var(--brand); }
    .em-direct:hover { background: #4d7fff; border-color: #4d7fff; }
    /* automatic investigation — canvas opens and starts reading immediately */
    .em-investigate { background: rgba(0,102,255,0.1); color: var(--ai-text); border-color: rgba(0,102,255,0.28); }
    .em-investigate:hover { background: rgba(0,102,255,0.18); }
    /* prepared prompt — canvas opens with a question staged, user sends */
    .em-prompt    { background: var(--accent-dim); color: var(--accent); border-color: rgba(var(--accent-rgb),0.28); }
    .em-prompt:hover { background: rgba(var(--accent-rgb),0.2); }
    /* reviewed action — proposes a change, never applies it */
    .em-review    { background: var(--warn-bg); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 30%, transparent); }
    .em-review:hover { background: color-mix(in srgb, var(--warn) 20%, transparent); }
    /* Design-time classification tag — for specs and review, not production UI */
    .entry-mode-tag {
      display: inline-flex; align-items: center; gap: 4px;
      font-size: var(--fs-2xs); font-weight: 700; color: var(--ink-muted);
      padding: 2px 7px; border-radius: var(--r-xs);
      background: rgba(255,255,255,0.04); border: 1px dashed var(--card-border);
    }

    /* ── Briefing card ack / dismiss row (§5.9) ── */
    .bcard-ack-row {
      display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
      padding-top: 12px; margin-top: 12px; border-top: 1px solid var(--hairline);
    }
    .bcard-ack-btn {
      display: inline-flex; align-items: center; gap: 5px;
      font-family: var(--font-sans); font-size: 14px; font-weight: 600;
      color: var(--ink-muted); background: none; border: 1px solid transparent;
      padding: 5px 9px; border-radius: var(--r-sm); cursor: pointer;
      transition: background-color var(--t-fast), color var(--t-fast), border-color var(--t-fast);
    }
    .bcard-ack-btn:hover { background: rgba(255,255,255,0.05); color: var(--d100); border-color: var(--card-border); }
    .bcard-ack-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
    .bcard-ack-btn.is-acked { color: var(--ok); background: var(--ok-bg); border-color: color-mix(in srgb, var(--ok) 24%, transparent); }
    .bcard-dismiss-picker {
      display: none; align-items: center; gap: 5px; margin-left: auto;
    }
    .bcard-dismiss-picker.open { display: inline-flex; }
    .bcard-dismiss-reason {
      font-size: 14px; font-weight: 600; color: var(--ink-muted);
      padding: 3px 8px; border-radius: var(--r-pill);
      background: rgba(255,255,255,0.04); border: 1px solid var(--card-border);
      cursor: pointer; font-family: var(--font-sans);
      transition: background-color var(--t-fast), color var(--t-fast);
    }
    .bcard-dismiss-reason:hover { background: rgba(255,255,255,0.09); color: var(--d100); }
    .bcard-dismiss-reason:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

    /* ── Memory panel (§4 continuity) — prior-thread cue ── */
    .memory-panel {
      max-width: 460px; border-radius: var(--r-lg);
      background: var(--card-bg-raised); border: 1px solid var(--card-border);
      overflow: hidden;
    }
    .mem-head {
      display: flex; align-items: center; gap: 7px;
      padding: 9px 13px; font-size: 14px; font-weight: 700;
      text-transform: uppercase; letter-spacing: 0.06em; color: var(--ai-text);
      border-bottom: 1px solid var(--hairline);
    }
    .mem-head .mem-age { margin-left: auto; color: var(--ink-muted); letter-spacing: 0.02em; text-transform: none; font-weight: 600; }
    .mem-thread { padding: 11px 13px; display: flex; flex-direction: column; gap: 7px; }
    .mem-line { display: flex; gap: 8px; font-size: 14px; line-height: 1.5; }
    .mem-who { flex-shrink: 0; font-weight: 700; color: var(--ink-muted); min-width: 34px; }
    .mem-what { color: var(--ink-muted); }
    .mem-foot { display: flex; gap: 8px; padding: 0 13px 12px; }

    /* ── Governance change request card (§3.1 called 3, §6.2) ── */
    .gov-cr-card {
      max-width: 520px; border-radius: var(--r-lg); overflow: hidden;
      background: var(--card-bg); border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent);
    }
    .gov-cr-head {
      display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
      padding: 10px 14px; background: var(--warn-bg);
      border-bottom: 1px solid color-mix(in srgb, var(--warn) 20%, transparent);
      font-size: 14px; font-weight: 700; text-transform: uppercase;
      letter-spacing: 0.06em; color: var(--warn);
    }
    .gov-cr-head .work-state { margin-left: auto; }
    .gov-cr-title { padding: 12px 14px 0; font-size: 14px; font-weight: 700; color: var(--d50); }
    .gov-cr-diff { display: flex; align-items: stretch; gap: 8px; padding: 10px 14px; }
    .gov-cr-current, .gov-cr-proposed {
      flex: 1; min-width: 0; padding: 9px 11px; border-radius: var(--r-md);
      border: 1px solid var(--card-border); background: var(--card-bg-raised);
    }
    .gov-cr-current  { border-color: color-mix(in srgb, var(--err) 24%, transparent); background: var(--err-bg); }
    .gov-cr-proposed { border-color: color-mix(in srgb, var(--ok) 24%, transparent); background: var(--ok-bg); }
    .gov-cr-label {
      display: block; font-size: 14px; font-weight: 700; letter-spacing: 0.08em;
      text-transform: uppercase; margin-bottom: 4px;
    }
    .gov-cr-current  .gov-cr-label { color: var(--err); }
    .gov-cr-proposed .gov-cr-label { color: var(--ok); }
    .gov-cr-val { font-size: 14px; font-weight: 600; color: var(--d100); line-height: 1.5; }
    .gov-cr-arrow { align-self: center; color: var(--ink-muted); flex-shrink: 0; }
    .gov-cr-rationale {
      padding: 0 14px 10px; font-size: 14px; line-height: 1.6; color: var(--ink-muted);
    }
    .gov-cr-rationale strong { color: var(--d100); font-weight: 700; }
    .gov-cr-blast {
      display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
      margin: 0 14px 12px; padding: 8px 11px; border-radius: var(--r-md);
      background: rgba(255,255,255,0.03); border: 1px solid var(--card-border);
      font-size: 14px; color: var(--ink-muted);
    }
    .gov-cr-blast .blast-val { font-weight: 700; color: var(--d100); }
    .gov-cr-actions {
      display: flex; align-items: center; gap: 8px;
      padding: 10px 14px; border-top: 1px solid var(--hairline);
      background: rgba(255,255,255,0.02);
    }
    /* Stands alone. Any surface that commits a governed write should be able
       to say the write is logged — a modal footer is where that most often
       needs saying. Scoped under .gov-cr-actions it received nothing outside
       that one parent: no display, no gap, no font-size, so the icon jammed
       against the text at inherited size and read as broken markup. */
    .gov-cr-audit-note {
      font-size: 14px; color: var(--ink-muted);
      display: inline-flex; align-items: center; gap: 5px;
    }
    /* Parent selector kept only for the positional override it actually owns. */
    .gov-cr-actions .gov-cr-audit-note { margin-left: auto; }

    /* ── Decision zone (§3 reviewed action) ── */
    .decision-zone {
      max-width: 520px; padding: 14px; border-radius: var(--r-lg);
      background: var(--card-bg-raised); border: 1px solid var(--card-border);
    }
    .dz-prompt { font-size: 14px; font-weight: 600; color: var(--d100); line-height: 1.55; margin-bottom: 4px; }
    .dz-consequence {
      display: flex; align-items: flex-start; gap: 7px;
      font-size: 14px; line-height: 1.55; color: var(--ink-muted); margin-bottom: 12px;
    }
    .dz-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
    .dz-actions .dz-spacer { margin-left: auto; }
    .dz-meta {
      display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
      margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--hairline);
      font-size: 14px; color: var(--ink-muted);
    }

    /* ── Audit trail (§6.2, Level 6) ── */
    .audit-trail { display: flex; flex-direction: column; max-width: 560px; }
    .audit-entry {
      display: grid; grid-template-columns: 20px 1fr auto; gap: 10px;
      align-items: start; padding: 10px 0;
      border-bottom: 1px solid var(--hairline);
    }
    .audit-entry:last-child { border-bottom: none; }
    .audit-ico {
      width: 20px; height: 20px; border-radius: 50%; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      background: rgba(255,255,255,0.05); color: var(--ink-muted);
    }
    .audit-entry.is-ok   .audit-ico { background: var(--ok-bg);   color: var(--ok); }
    .audit-entry.is-warn .audit-ico { background: var(--warn-bg); color: var(--warn); }
    .audit-entry.is-err  .audit-ico { background: var(--err-bg);  color: var(--err); }
    .audit-entry.is-ai   .audit-ico { background: rgba(0,102,255,0.12); color: var(--ai-text); }
    .audit-main { min-width: 0; }
    .audit-action { font-size: 16px; font-weight: 600; color: var(--d100); line-height: 1.45; }
    .audit-actor { font-size: 14px; color: var(--ink-muted); margin-top: 2px; }
    .audit-actor .audit-who { font-weight: 700; color: var(--ink-muted); }
    .audit-side { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex-shrink: 0; }
    .audit-time { font-family: var(--font-mono); font-size: 14px; color: var(--ink-muted); white-space: nowrap; }
    .audit-revert {
      font-family: var(--font-sans); font-size: 14px; font-weight: 700;
      color: var(--ai-text); background: none; border: none; cursor: pointer;
      padding: 2px 4px; border-radius: var(--r-xs);
      transition: color var(--t-fast);
    }
    .audit-revert:hover { color: var(--brand); }
    .audit-revert:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
    .audit-irreversible { font-size: 14px; font-weight: 600; color: var(--ink-muted); white-space: nowrap; }

    /* ── AI-unavailable state (§6.7, Level 7) ── */
    .ai-unavailable {
      max-width: 460px; padding: 22px 20px; border-radius: var(--r-lg);
      background: var(--card-bg); border: 1px dashed var(--card-border);
      text-align: center;
    }
    .ai-unavailable .aiu-mark {
      width: 44px; height: 44px; margin: 0 auto 12px; border-radius: 50%;
      display: flex; align-items: center; justify-content: center;
      background: rgba(255,255,255,0.04); border: 1px solid var(--card-border);
      color: var(--ink-muted);
    }
    .aiu-title { font-size: 14px; font-weight: 700; color: var(--d100); margin-bottom: 5px; }
    .aiu-body { font-size: 14px; line-height: 1.6; color: var(--ink-muted); margin-bottom: 14px; }
    .aiu-fallback {
      display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap;
    }
    .aiu-note {
      margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--hairline);
      font-size: 14px; color: var(--ink-muted);
    }
    .ai-unavailable.is-degraded { border-style: solid; border-color: color-mix(in srgb, var(--warn) 30%, transparent); }
    .ai-unavailable.is-degraded .aiu-mark { background: var(--warn-bg); border-color: color-mix(in srgb, var(--warn) 24%, transparent); color: var(--warn); }

    /* Light-mode: semantic hues darken one step on pale tints (matches .tag rules) */
    :root[data-theme="light"] .ws-completed,
    :root[data-theme="light"] .conf-high    { color: #3f6b52; }
    :root[data-theme="light"] .ws-completed { background: color-mix(in srgb, #3f6b52 11%, transparent); }
    :root[data-theme="light"] .conf-medium,
    :root[data-theme="light"] .em-review,
    :root[data-theme="light"] .gov-cr-head  { color: var(--warn); }
    :root[data-theme="light"] .ws-failed,
    :root[data-theme="light"] .conf-low     { color: #8a473f; }
    :root[data-theme="light"] .ws-failed { background: color-mix(in srgb, #903b37 11%, transparent); }
    /* The four positions take the neutral pill on white too; only the two
       ends have an entry here, because only the two ends have a hue. */
    /* Every one of the six resolves through a token that already darkens on
       white, so the tint is the only thing this block still has to say. */
    :root[data-theme="light"] .ws-detected    { background: color-mix(in srgb, var(--info) 11%, transparent); }
    :root[data-theme="light"] .ws-recommended { background: color-mix(in srgb, var(--accent-label) 11%, transparent); }
    :root[data-theme="light"] .ws-drafted     { background: color-mix(in srgb, var(--teal-label) 11%, transparent); }
    :root[data-theme="light"] .ws-staged      { background: color-mix(in srgb, var(--warn) 11%, transparent); }
    :root[data-theme="light"] .em-investigate,
    :root[data-theme="light"] .em-investigate,
    :root[data-theme="light"] .mem-head,
    :root[data-theme="light"] .audit-entry.is-ai .audit-ico,
    :root[data-theme="light"] .audit-revert  { color: #1f5fd0; }
    :root[data-theme="light"] .gov-cr-current .gov-cr-label { color: var(--err); }
    :root[data-theme="light"] .gov-cr-proposed .gov-cr-label { color: var(--ok); }
    /* Neutral ghost fills — white-on-white vanishes in light mode.
       Scoped so the semantic variants below keep their own tint:
       .conf-badge and .audit-ico each have level/status modifiers that
       must out-specify this rule, not be flattened by it. */
    :root[data-theme="light"] .entry-mode-tag,
    :root[data-theme="light"] .bcard-dismiss-reason,
    :root[data-theme="light"] .gov-cr-blast,
    :root[data-theme="light"] .ai-unavailable .aiu-mark { background: rgba(16,24,40,0.04); }
    :root[data-theme="light"] .conf-badge:not(.conf-high):not(.conf-medium):not(.conf-low),
    :root[data-theme="light"] .audit-entry:not(.is-ok):not(.is-warn):not(.is-err):not(.is-ai) .audit-ico {
      background: rgba(16,24,40,0.04);
    }
    :root[data-theme="light"] .bcard-ack-btn:hover { background: rgba(16,24,40,0.05); }
    :root[data-theme="light"] .bcard-dismiss-reason:hover { background: rgba(16,24,40,0.08); }
    :root[data-theme="light"] .gov-cr-actions { background: rgba(16,24,40,0.02); }
    :root[data-theme="light"] .ws-track .ws-step .ws-dot { background: var(--d700); }


    /* ═══════════════════════════════════════════════
       TRUST STATE  (Knowledge v2 · D1)

       A SECOND, INDEPENDENT AXIS from work state.
       Work state = what AiMY has done with an item.
       Trust state = whether the content can be relied on.
       An object can be `drafted` and `expired` at once.

       Read differently on purpose: work state carries a
       DOT, trust state carries an ICON. When both sit in
       one meta row they must not look like two halves of
       the same field.

       PORTABLE BY CONSTRUCTION: semantic tokens only,
       never --accent. This renders inside other agents'
       surfaces which re-theme the accent, and an expired
       card must read as expired everywhere it is cited.
    ═══════════════════════════════════════════════ */
    .trust-state {
      display: inline-flex; align-items: center; gap: 5px;
      font-size: var(--fs-2xs); font-weight: 700; padding: 3px 9px 3px 7px;
      border-radius: var(--r-xs); white-space: nowrap; vertical-align: middle;
      border: 1px solid transparent;
    }
    .trust-state svg { width: 11px; height: 11px; flex-shrink: 0; }
    .ts-verified    { background: var(--ok-bg);   color: var(--ok);   border-color: color-mix(in srgb, var(--ok) 24%, transparent); }
    .ts-due         { background: var(--warn-bg); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 24%, transparent); }
    .ts-expired     { background: var(--err-bg);  color: var(--err);  border-color: color-mix(in srgb, var(--err) 32%, transparent); }
    .ts-unverified  { background: rgba(255,255,255,0.05); color: var(--ink-muted); border-color: var(--card-border); }
    .ts-superseded  { background: var(--info-bg); color: var(--info); border-color: color-mix(in srgb, var(--info) 24%, transparent); }

    /* Excluded from retrieval — the consequence must be visible on the badge
       itself, not only in a tooltip. Solid border + inset rule reads as "cut off". */
    .trust-state.is-excluded { border-style: solid; border-width: 1px; padding-right: 7px; }
    .trust-state.is-excluded::after {
      content: "NOT IN ANSWERS";
      font-size: 14px; letter-spacing: 0.06em; opacity: 0.75;
      padding-left: 6px; margin-left: 1px; border-left: 1px solid currentColor;
    }

    /* Object-level trust line — badge plus the dates that justify it */
    .trust-line { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 14px; color: var(--ink-muted); }
    .trust-line .trust-meta { display: inline-flex; align-items: center; gap: 5px; }
    .trust-line .trust-meta strong { color: var(--ink-muted); font-weight: 700; }

    /* ── Answer trust disclosure (§7.4) ──
       Every generated answer states the trust condition of its grounding.
       The exclusion case is the one that must never be silent: without it a
       governance gap is indistinguishable from a gap in the corpus. */
    .trust-disclosure {
      display: flex; flex-direction: column; gap: 7px;
      padding: 10px 12px; border-radius: var(--r-md);
      background: rgba(255,255,255,0.03); border: 1px solid var(--card-border);
      font-size: 14px; line-height: 1.55; color: var(--ink-muted);
    }
    .trust-disclosure.has-exclusion { background: var(--warn-bg); border-color: color-mix(in srgb, var(--warn) 28%, transparent); }
    .td-row { display: flex; align-items: flex-start; gap: 8px; }
    .td-row svg { width: 12px; height: 12px; flex-shrink: 0; margin-top: 2px; }
    .td-row.is-ok   { color: var(--ok); }
    .td-row.is-warn { color: var(--warn); }
    .td-row.is-err  { color: var(--err); }
    .td-row .td-text { color: var(--ink-muted); }
    .td-row.is-warn .td-text, .td-row.is-err .td-text { color: var(--d200); }
    .td-row .td-text strong { color: var(--d50); font-weight: 700; }
    .td-action {
      align-self: flex-start; margin-top: 1px;
      font-family: var(--font-sans); font-size: 14px; font-weight: 700;
      color: var(--ai-text); background: none; border: none; cursor: pointer;
      padding: 2px 0; border-bottom: 1px solid transparent;
      transition: border-color var(--t-fast), color var(--t-fast);
    }
    .td-action:hover { border-bottom-color: currentColor; }
    .td-action:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }


    /* ═══════════════════════════════════════════════
       CITATION PREVIEW & PER-CITATION FEEDBACK
       (Knowledge v2 · D2)

       The intermediate verification called. Rungs 1 (inline
       marker) and 4 (full source) already existed; this is
       the one that carries most verification traffic.

       Focus-driven, not hover-only — a preview reachable
       only by mouse is not a verification affordance.
    ═══════════════════════════════════════════════ */
    .cite-wrap { position: relative; display: inline-block; }
    .cite-wrap > .cite { cursor: pointer; }
    .cite-wrap > .cite:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

    .cite-preview {
      position: absolute; bottom: calc(100% + 8px); left: 50%;
      transform: translateX(-50%) translateY(3px);
      width: 320px; max-width: 84vw; z-index: 300;
      background: var(--panel-bg); border: 1px solid var(--glass-border);
      border-radius: var(--r-lg); box-shadow: var(--shadow-xl);
      backdrop-filter: blur(12px);
      padding: 11px 12px; text-align: left;
      opacity: 0; visibility: hidden; pointer-events: none;
      transition: opacity var(--t-fast), transform var(--t-fast), visibility var(--t-fast);
    }
    .cite-wrap:hover > .cite-preview,
    .cite-wrap:focus-within > .cite-preview,
    .cite-preview.is-open {
      opacity: 1; visibility: visible; pointer-events: auto;
      transform: translateX(-50%) translateY(0);
    }
    .cp-head { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-bottom: 7px; }
    .cp-title { font-size: 14px; font-weight: 700; color: var(--d50); line-height: 1.4;
      overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 175px; }
    .cp-head .trust-state { margin-left: auto; }
    /* The cited passage, shown in context — the surrounding text is dimmed
       so the quoted span is locatable at a glance. */
    .cp-passage {
      font-size: 14px; line-height: 1.65; color: var(--ink-muted);
      max-height: 96px; overflow: hidden; position: relative;
      padding-left: 9px; border-left: 2px solid var(--card-border);
    }
    .cp-passage mark {
      background: rgba(51,105,255,0.16); color: var(--d50);
      border-radius: 3px; padding: 0 2px; font-weight: 600;
    }
    .cp-foot { display: flex; align-items: center; gap: 6px; margin-top: 9px;
      padding-top: 8px; border-top: 1px solid var(--hairline); }
    .cp-src { font-size: 14px; color: var(--ink-muted); margin-right: auto;
      overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .cite-action {
      display: inline-flex; align-items: center; gap: 4px;
      font-family: var(--font-sans); font-size: 14px; font-weight: 700;
      padding: 4px 8px; border-radius: var(--r-sm); cursor: pointer;
      background: rgba(255,255,255,0.05); border: 1px solid var(--card-border);
      color: var(--ink-muted); white-space: nowrap;
      transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast);
    }
    .cite-action svg { width: 10px; height: 10px; flex-shrink: 0; }
    .cite-action:hover { background: rgba(255,255,255,0.09); color: var(--d50); }
    .cite-action:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
    /* Flagging one citation is the highest-signal, most-commonly-lost feedback */
    .cite-action.is-flag:hover { background: var(--err-bg); border-color: color-mix(in srgb, var(--err) 30%, transparent); color: var(--err); }
    .cite-action.is-flagged { background: var(--err-bg); border-color: color-mix(in srgb, var(--err) 30%, transparent); color: var(--err); }
    /* Citation whose source is excluded / flagged reads differently inline */
    .cite.is-flagged   { background: var(--warn-bg); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 35%, transparent); }
    .cite.is-excluded  { background: var(--err-bg);  color: var(--err);  border-color: color-mix(in srgb, var(--err) 35%, transparent); }


    /* ═══════════════════════════════════════════════
       SET-SCOPE OPERATIONS  (Knowledge v2 · D3)

       Batch work over a filtered collection. The scope
       statement is the component's reason for existing:
       "apply to selection" without saying what the
       selection IS makes blast radius invisible at the
       exact moment it matters.
    ═══════════════════════════════════════════════ */
    .set-scope-bar {
      display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
      padding: 10px 14px; border-radius: var(--r-lg);
      background: var(--card-bg-raised); border: 1px solid rgba(var(--accent-rgb),0.3);
      box-shadow: var(--shadow-md);
    }
    .ss-count {
      display: inline-flex; align-items: baseline; gap: 5px;
      font-size: 16px; font-weight: 700; color: var(--d50); flex-shrink: 0;
    }
    .ss-count .ss-num { font-size: 16px; letter-spacing: -0.02em; }
    /* The scope statement — never omit it */
    .ss-scope { font-size: 14px; color: var(--ink-muted); line-height: 1.5; min-width: 0; }
    .ss-scope strong { color: var(--d200); font-weight: 700; }
    .ss-actions { display: flex; align-items: center; gap: 7px; margin-left: auto; flex-wrap: wrap; }
    .ss-clear {
      font-family: var(--font-sans); font-size: 14px; font-weight: 600;
      color: var(--ink-muted); background: none; border: none; cursor: pointer; padding: 4px 6px;
      transition: color var(--t-fast);
    }
    .ss-clear:hover { color: var(--d100); }
    .ss-clear:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

    /* Effect preview — what the operation will actually do, before it runs */
    .ss-preview {
      margin-top: 10px; padding: 11px 13px; border-radius: var(--r-md);
      background: rgba(0,0,0,0.16); border: 1px solid var(--card-border);
    }
    :root[data-theme="light"] .ss-preview { background: rgba(16,24,40,0.03); }
    .ss-preview-head {
      font-size: 14px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
      color: var(--ink-muted); margin-bottom: 8px;
    }
    .ss-effect { display: flex; align-items: flex-start; gap: 8px; font-size: 14px;
      line-height: 1.55; color: var(--ink-muted); padding: 3px 0; }
    .ss-effect svg { width: 12px; height: 12px; flex-shrink: 0; margin-top: 2px; }
    .ss-effect strong { color: var(--d50); font-weight: 700; }
    .ss-effect.is-warn svg { color: var(--warn); }
    .ss-effect.is-ok svg   { color: var(--ok); }
    .ss-effect.is-skip { color: var(--ink-muted); }
    .ss-effect.is-skip svg { color: var(--ink-muted); }


    /* ═══════════════════════════════════════════════
       AGGREGATE BRIEFING CARD  (Knowledge v2 · D4)

       A briefing item whose subject is a CLUSTER, not a
       record. The standard bcard states one conclusion
       about one thing; this states a distribution across
       many, so the evidence row is replaced by a ranked
       contributor list.
    ═══════════════════════════════════════════════ */
    .bcard.is-aggregate .agg-list { display: flex; flex-direction: column; gap: 1px; margin-bottom: 12px; }
    .agg-row {
      display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 10px;
      padding: 6px 8px; border-radius: var(--r-sm); position: relative;
      font-size: 14px; color: var(--d200);
    }
    .agg-row:hover { background: rgba(255,255,255,0.04); }
    :root[data-theme="light"] .agg-row:hover { background: rgba(16,24,40,0.04); }
    .agg-label { position: relative; z-index: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .agg-val { position: relative; z-index: 1; font-size: 14px; font-weight: 700; color: var(--d50);
      font-variant-numeric: tabular-nums; }
    .agg-val .agg-unit { font-weight: 600; color: var(--ink-muted); margin-left: 3px; }
    /* Proportion bar sits behind the row — scaleX so it never animates width */
    .agg-bar {
      position: absolute; left: 0; top: 0; bottom: 0; border-radius: var(--r-sm);
      background: rgba(var(--accent-rgb),0.14); transform-origin: left center;
      transform: scaleX(var(--agg-share, 0)); width: 100%; z-index: 0;
    }
    .agg-more {
      font-size: 14px; font-weight: 600; color: var(--ink-muted);
      padding: 5px 8px 0;
    }
    /* Cluster totals strip */
    .agg-summary {
      display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
      padding: 8px 10px; margin-bottom: 10px; border-radius: var(--r-sm);
      background: rgba(255,255,255,0.03); border: 1px solid var(--card-border);
    }
    :root[data-theme="light"] .agg-summary { background: rgba(16,24,40,0.03); }
    .agg-stat { display: flex; flex-direction: column; gap: 1px; }
    .agg-stat-val { font-size: 14px; font-weight: 700; color: var(--d50); letter-spacing: -0.02em; }
    .agg-stat-lbl { font-size: 14px; font-weight: 600; letter-spacing: 0.07em;
      text-transform: uppercase; color: var(--ink-muted); }

    /* Light-mode semantic darkening (matches the .tag rules) */
    :root[data-theme="light"] .ts-verified { color: var(--ok); }
    :root[data-theme="light"] .ts-due      { color: var(--warn); }
    :root[data-theme="light"] .ts-expired  { color: var(--err); }
    :root[data-theme="light"] .ts-superseded { color: var(--info); }
    :root[data-theme="light"] .ts-unverified { background: rgba(16,24,40,0.05); }
    :root[data-theme="light"] .td-row.is-ok   { color: var(--ok); }
    :root[data-theme="light"] .td-row.is-warn { color: var(--warn); }
    :root[data-theme="light"] .td-row.is-err  { color: var(--err); }
    :root[data-theme="light"] .td-action      { color: #1f5fd0; }
    :root[data-theme="light"] .trust-disclosure { background: rgba(16,24,40,0.03); }
    :root[data-theme="light"] .cite-action    { background: rgba(16,24,40,0.04); }
    :root[data-theme="light"] .cite-action:hover { background: rgba(16,24,40,0.08); }
    :root[data-theme="light"] .cp-passage mark { background: rgba(51,105,255,0.14); }


    /* ═══════════════════════════════════════════════
       TYPE CARDS  (Knowledge v2 · G1)

       Eight templates, one fixed governance row.

       The row that never moves — type · trust · title ·
       owner · last verified · one action — is the whole
       point. Someone scanning mixed results must not have
       to relearn where trust lives per type. Everything
       between the title and the governance row is the
       part that varies.

       Type is carried by ICON + LABEL, never colour: a
       card may be cited inside a host whose accent and
       palette differ.
    ═══════════════════════════════════════════════ */
    .type-card {
      display: flex; flex-direction: column;
      background: var(--card-bg); border: 1px solid var(--card-border);
      border-radius: var(--r-xl); overflow: hidden;
      transition: border-color var(--t-base), box-shadow var(--t-base);
    }
    .type-card:hover { border-color: var(--card-border-hover); box-shadow: var(--shadow-md); }

    /* Head — type identity left, trust right. Fixed across all eight. */
    .tc-head {
      display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
      padding: 12px 14px 0;
    }
    .tc-type {
      display: inline-flex; align-items: center; gap: 5px;
      font-size: 14px; font-weight: 700; letter-spacing: 0.07em;
      text-transform: uppercase; color: var(--ink-muted);
    }
    .tc-type svg { width: 12px; height: 12px; flex-shrink: 0; }
    .tc-head .trust-state { margin-left: auto; }

    .tc-title {
      padding: 8px 14px 0; font-size: 14px; font-weight: 700;
      color: var(--d50); line-height: 1.4;
    }
    .tc-summary {
      padding: 6px 14px 0; font-size: 14px; line-height: 1.6; color: var(--ink-muted);
    }

    /* Body — the only zone that differs by type */
    .tc-body { padding: 10px 14px 0; display: flex; flex-direction: column; gap: 7px; }
    .tc-fields { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; align-items: baseline; }
    .tc-field-label {
      font-size: 14px; font-weight: 700; letter-spacing: 0.07em;
      text-transform: uppercase; color: var(--ink-muted); white-space: nowrap;
    }
    .tc-field-val { font-size: 14px; color: var(--d200); line-height: 1.5; min-width: 0; }
    .tc-field-val strong { color: var(--d50); font-weight: 700; }
    .tc-list { display: flex; flex-direction: column; gap: 3px; margin: 0; padding: 0; list-style: none; }
    .tc-list li { display: flex; gap: 7px; font-size: 14px; line-height: 1.5; color: var(--ink-muted); }
    .tc-list li::before { content: "—"; color: var(--ink-muted); flex-shrink: 0; }
    .tc-list.is-negative li::before { content: "×"; color: var(--err); }
    .tc-quote {
      font-size: 14px; line-height: 1.6; color: var(--d200); font-style: italic;
      padding-left: 9px; border-left: 2px solid var(--card-border);
    }
    .tc-tags { display: flex; gap: 5px; flex-wrap: wrap; }

    /* Governance row — fixed position, every template, no exceptions */
    .tc-gov {
      display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
      margin-top: 12px; padding: 9px 14px;
      border-top: 1px solid var(--hairline); background: rgba(255,255,255,0.02);
      font-size: 14px; color: var(--ink-muted);
    }
    :root[data-theme="light"] .tc-gov { background: rgba(16,24,40,0.02); }
    .tc-gov strong { color: var(--ink-muted); font-weight: 700; }
    .tc-gov .tc-gov-sep { color: var(--ink-muted); }

    .tc-action { padding: 10px 14px; border-top: 1px solid var(--hairline); }
    .tc-action .entry-action { width: 100%; justify-content: center; }

    /* Approval state — a SEPARATE field, deliberately not folded into
       trust state. Whether it becomes a sixth trust value is an open
       question; baking it in now would pre-empt that decision. */
    .tc-approval {
      display: inline-flex; align-items: center; gap: 5px;
      font-size: var(--fs-2xs); font-weight: 700;
      padding: 2px 8px; border-radius: var(--r-xs); border: 1px solid transparent;
    }
    .tc-approval svg { width: 10px; height: 10px; flex-shrink: 0; }
    .tc-approval.is-approved { background: var(--ok-bg);   color: var(--ok);   border-color: color-mix(in srgb, var(--ok) 24%, transparent); }
    .tc-approval.is-pending  { background: var(--warn-bg); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 24%, transparent); }
    .tc-approval.is-internal { background: rgba(255,255,255,0.05); color: var(--ink-muted); border-color: var(--card-border); }

    /* Compact form (§8.1) — what survives when cited inside a host with
       far less width. Title, type, trust, one action. Nothing else. */
    .type-card.is-compact { max-width: 300px; }
    .type-card.is-compact .tc-body,
    .type-card.is-compact .tc-summary { display: none; }
    .type-card.is-compact .tc-head { padding: 10px 12px 0; }
    .type-card.is-compact .tc-title { padding: 6px 12px 0; font-size: 16px; }
    .type-card.is-compact .tc-gov { margin-top: 9px; padding: 7px 12px; }
    .type-card.is-compact .tc-action { padding: 8px 12px; }
    .type-card.is-compact .tc-action .entry-action { font-size: 14px; padding: 6px 12px; }


    /* ═══════════════════════════════════════════════
       DOCUMENT VIEWER  (Knowledge v2 · G2)

       Composes what already exists into a reading shell.
       Trust sits in a FIXED position above the body —
       the only ordering that helps someone deciding
       whether to rely on the content before they read it.

       A viewer is not a read-only editor: it is optimised
       for judging and citing, not changing.
    ═══════════════════════════════════════════════ */
    .doc-view {
      background: var(--card-bg); border: 1px solid var(--card-border);
      border-radius: var(--r-xl); overflow: hidden;
    }
    .dv-head { padding: 16px 18px 0; }
    .dv-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 9px; }
    .dv-meta .trust-state { margin-left: auto; }
    .dv-title { font-size: 18px; font-weight: 700; color: var(--d50);
      letter-spacing: -0.01em; line-height: 1.3; margin-bottom: 10px; }

    /* Constant governance chrome */
    .dv-gov {
      display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
      gap: 10px 16px; padding: 11px 18px;
      border-top: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline);
      background: rgba(255,255,255,0.02);
    }
    :root[data-theme="light"] .dv-gov { background: rgba(16,24,40,0.02); }
    .dv-gov-item { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
    .dv-gov-label { font-size: 14px; font-weight: 700; letter-spacing: 0.08em;
      text-transform: uppercase; color: var(--ink-muted); }
    .dv-gov-val { font-size: 14px; font-weight: 600; color: var(--d100);
      overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .dv-gov-val.is-overdue { color: var(--err); }

    /* Exclusion / supersession notice — states the consequence and,
       critically, where the current version is. Never a silent redirect. */
    .dv-notice {
      display: flex; align-items: flex-start; gap: 9px;
      padding: 11px 18px; font-size: 14px; line-height: 1.6;
      border-bottom: 1px solid var(--hairline);
    }
    .dv-notice svg { width: 14px; height: 14px; flex-shrink: 0; margin-top: 1px; }
    .dv-notice .dv-notice-text { color: var(--d200); }
    .dv-notice .dv-notice-text strong { color: var(--d50); font-weight: 700; }
    .dv-notice.is-expired    { background: var(--err-bg);  color: var(--err); }
    .dv-notice.is-superseded { background: var(--info-bg); color: var(--info); }
    .dv-notice .dv-notice-link {
      display: inline-flex; align-items: center; gap: 4px; margin-left: auto;
      font-family: var(--font-sans); font-size: 14px; font-weight: 700;
      color: currentColor; background: none; border: none; cursor: pointer;
      white-space: nowrap; padding: 2px 0; border-bottom: 1px solid transparent;
      transition: border-color var(--t-fast);
    }
    .dv-notice .dv-notice-link:hover { border-bottom-color: currentColor; }
    .dv-notice .dv-notice-link:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

    .dv-body { padding: 16px 18px; font-size: 14px; line-height: 1.75; color: var(--d200); }
    .dv-body p { margin: 0 0 12px; }
    .dv-body p:last-child { margin-bottom: 0; }
    .dv-body h4 { font-size: 16px; font-weight: 700; color: var(--d50);
      margin: 16px 0 7px; letter-spacing: 0.01em; }

    /* Relationships — related · superseded-by · contradicts.
       Named in the object anatomy but absent from the library. */
    .dv-rel { padding: 0 18px 16px; display: flex; flex-direction: column; gap: 8px; }
    .dv-rel-group { display: flex; align-items: flex-start; gap: 9px; flex-wrap: wrap; }
    .dv-rel-label {
      font-size: 14px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
      color: var(--ink-muted); padding-top: 5px; min-width: 86px; flex-shrink: 0;
    }
    .dv-rel-items { display: flex; gap: 6px; flex-wrap: wrap; }
    .dv-rel-item {
      display: inline-flex; align-items: center; gap: 6px;
      padding: 4px 10px; border-radius: var(--r-pill);
      background: rgba(255,255,255,0.04); border: 1px solid var(--card-border);
      font-family: var(--font-sans); font-size: 14px; font-weight: 600; color: var(--d200);
      cursor: pointer; max-width: 240px;
      transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast);
    }
    .dv-rel-item svg { width: 11px; height: 11px; flex-shrink: 0; opacity: 0.7; }
    .dv-rel-item span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .dv-rel-item:hover { background: rgba(255,255,255,0.08); color: var(--d50); }
    .dv-rel-item:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
    :root[data-theme="light"] .dv-rel-item { background: rgba(16,24,40,0.04); }
    :root[data-theme="light"] .dv-rel-item:hover { background: rgba(16,24,40,0.08); }
    /* Contradiction is a finding, not a neighbour — it reads as a problem */
    .dv-rel-item.is-contradiction { background: var(--err-bg); border-color: color-mix(in srgb, var(--err) 28%, transparent); color: var(--err); }
    .dv-rel-item.is-contradiction:hover { background: color-mix(in srgb, var(--err) 20%, transparent); color: var(--err); }
    .dv-rel-item.is-successor { background: var(--ok-bg); border-color: color-mix(in srgb, var(--ok) 28%, transparent); color: var(--ok); }

    .dv-actions {
      display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
      padding: 12px 18px; border-top: 1px solid var(--hairline);
      background: rgba(255,255,255,0.02);
    }
    :root[data-theme="light"] .dv-actions { background: rgba(16,24,40,0.02); }
    .dv-actions .dv-actions-end { margin-left: auto; display: flex; align-items: center; gap: 8px; }


    /* ═══════════════════════════════════════════════
       VERSION HISTORY, COMPARE & RESTORE
       (Knowledge v2 · G3)

       AI edits are ORDINARY VERSIONS WITH AN AI AUTHOR.
       There is no parallel AI history — a separate track
       would let someone review the human history and
       believe they had seen everything.

       Restore is a consequential write: it changes what
       every consuming agent answers from. It commits
       through a structured surface, never a link.
    ═══════════════════════════════════════════════ */
    .ver-list { display: flex; flex-direction: column; }
    .ver-item {
      display: grid; grid-template-columns: 22px 1fr auto; gap: 10px;
      align-items: start; padding: 10px 0;
      border-bottom: 1px solid var(--hairline);
    }
    .ver-item:last-child { border-bottom: none; }
    .ver-item.is-current { background: rgba(var(--accent-rgb),0.06); border-radius: var(--r-sm);
      padding-left: 8px; padding-right: 8px; margin: 0 -8px; }
    .ver-mark {
      width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      background: rgba(255,255,255,0.05); color: var(--ink-muted);
      font-size: 14px; font-weight: 700;
    }
    :root[data-theme="light"] .ver-mark { background: rgba(16,24,40,0.05); }
    /* AI-authored versions are marked, not segregated */
    .ver-item.is-ai .ver-mark { background: rgba(0,102,255,0.12); color: var(--ai-text); }
    .ver-main { min-width: 0; }
    .ver-label { font-size: 16px; font-weight: 600; color: var(--d100); line-height: 1.45; }
    .ver-author { font-size: 14px; color: var(--ink-muted); margin-top: 2px; }
    .ver-author strong { color: var(--ink-muted); font-weight: 700; }
    .ver-side { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
    .ver-time { font-family: var(--font-mono); font-size: 14px; color: var(--ink-muted); white-space: nowrap; }
    .ver-tag {
      font-size: var(--fs-2xs); font-weight: 700;
      padding: 2px 7px; border-radius: var(--r-xs);
      background: var(--accent-dim); color: var(--accent); border: 1px solid rgba(var(--accent-rgb),0.24);
    }

    /* Comparison — reuses the current/proposed diff shape */
    .ver-compare { max-width: 620px; border-radius: var(--r-lg); overflow: hidden;
      border: 1px solid var(--card-border); background: var(--card-bg); }
    .vc-head {
      display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
      padding: 10px 14px; border-bottom: 1px solid var(--hairline);
      background: rgba(255,255,255,0.02); font-size: 14px; color: var(--ink-muted);
    }
    :root[data-theme="light"] .vc-head { background: rgba(16,24,40,0.02); }
    .vc-head strong { color: var(--d100); font-weight: 700; }
    .vc-body {
      padding: 13px 14px; font-size: 14px; line-height: 1.75; color: var(--d200);
    }
    .vc-body del { color: var(--err); background: var(--err-bg); text-decoration: line-through;
      border-radius: 3px; padding: 0 3px; }
    .vc-body ins { color: var(--ok); background: var(--ok-bg); text-decoration: none;
      border-radius: 3px; padding: 0 3px; }
    .vc-stat { display: flex; align-items: center; gap: 12px; margin-left: auto;
      font-family: var(--font-mono); font-size: 14px; }
    .vc-stat .vc-add { color: var(--ok); }
    .vc-stat .vc-del { color: var(--err); }

    /* Restore commit surface — states the effect before it runs */
    .ver-restore {
      max-width: 620px; padding: 14px; border-radius: var(--r-lg);
      background: var(--card-bg-raised); border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent);
    }
    .vr-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 9px;
      font-size: 14px; font-weight: 700; color: var(--d50); }
    .vr-effect { display: flex; align-items: flex-start; gap: 8px; font-size: 14px;
      line-height: 1.55; color: var(--ink-muted); padding: 3px 0; }
    .vr-effect svg { width: 12px; height: 12px; flex-shrink: 0; margin-top: 2px; }
    .vr-effect strong { color: var(--d50); font-weight: 700; }
    .vr-effect.is-warn svg { color: var(--warn); }
    .vr-effect.is-ok svg { color: var(--ok); }
    .vr-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
      margin-top: 12px; padding-top: 11px; border-top: 1px solid var(--hairline); }
    .vr-actions .vr-note { margin-left: auto; font-size: 14px; color: var(--ink-muted);
      display: inline-flex; align-items: center; gap: 5px; }

    /* Light-mode semantic darkening */
    :root[data-theme="light"] .tc-approval.is-approved { color: var(--ok); }
    :root[data-theme="light"] .tc-approval.is-pending  { color: var(--warn); }
    :root[data-theme="light"] .tc-approval.is-internal { background: rgba(16,24,40,0.05); }
    :root[data-theme="light"] .dv-notice.is-expired    { color: var(--err); }
    :root[data-theme="light"] .dv-notice.is-superseded { color: var(--info); }
    :root[data-theme="light"] .dv-rel-item.is-contradiction { color: var(--err); }
    :root[data-theme="light"] .dv-rel-item.is-successor     { color: var(--ok); }
    :root[data-theme="light"] .ver-item.is-ai .ver-mark     { color: #1f5fd0; }
    :root[data-theme="light"] .vc-stat .vc-add { color: var(--ok); }
    :root[data-theme="light"] .vc-stat .vc-del { color: var(--err); }
    :root[data-theme="light"] .vr-effect.is-warn svg { color: var(--warn); }


    /* ═══════════════════════════════════════════════
       STATIC STATE HELPERS — force pseudo/hidden states
       so every state renders (and imports to Figma).
       Mirror the real :hover / :focus / .open rules.
    ═══════════════════════════════════════════════ */
    /* Buttons */
    .btn-brand.is-hover { background: #4d7fff; border-color: #4d7fff; }
    .btn-ghost.is-hover { background: rgba(255,255,255,0.09); color: var(--d50); border-color: rgba(255,255,255,0.16); }
    .btn-err.is-hover   { background: color-mix(in srgb, var(--err) 20%, transparent); }
    .btn.is-active      { transform: translateY(1px); filter: brightness(0.94); }
    .btn.is-focus       { outline: 2px solid var(--brand); outline-offset: 2px; }
    .icon-btn.is-hover  { border-color: var(--card-border-hover); color: var(--accent); }
    /* Inputs */
    .input.is-focus, .field-input.is-focus { border-color: var(--brand); background: rgba(51,105,255,0.05); box-shadow: 0 0 0 3px var(--brand-glow); outline: none; }
    .search-field.is-focus { border-color: var(--card-border-focus); box-shadow: 0 0 0 3px var(--brand-glow); }
    .v2-dropdown-btn.is-focus { outline: 2px solid var(--brand); outline-offset: 2px; }
    /* Navigation */
    .nav-item.is-hover { background: rgba(255,255,255,0.04); color: var(--d200); }
    .tab.is-hover      { background: rgba(255,255,255,0.05); color: var(--d200); }
    .ds-tab.is-hover   { color: var(--d100); }
    .chip.default.is-hover { background: rgba(255,255,255,0.07); color: var(--d200); }
    .menu-item.is-hover { background: var(--card-bg-raised); color: var(--d50); }
    /* Overlays forced visible */
    .tooltip-wrap.is-open .tooltip { opacity: 1; }
    .ai-insight-panel.is-open { display: block; }
    .chart-annotation.is-open .chart-anno-card,
    .chart-annotation.is-open .anno-card { opacity: 1 !important; pointer-events: auto; visibility: visible; }
    /* Contained modal specimen (not full-screen fixed) */
    .modal-backdrop.is-static { position: relative; inset: auto; height: 300px; border-radius: var(--r-lg); z-index: 0; }
    .aimy-toast.is-open { opacity: 1; transform: translateY(0) scale(1); visibility: visible; pointer-events: auto; position: static; }
    /* State-specimen caption */
    .st-cap { font-size: 14px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-muted); margin-bottom: 8px; }
    /* Static helpers for batch-3 components */
    .split-caret.is-hover { filter: brightness(1.12); }
    .tree .tree-leaf.is-hover, .tree summary.is-hover { background: var(--card-bg-raised); }
    .link.is-hover { border-bottom-color: currentColor; }
    .notif.is-hover { background: var(--card-bg-raised); }
    .tag-input.is-focus { border-color: var(--card-border-focus); box-shadow: 0 0 0 3px var(--brand-glow); }
    .time-opt.is-hover { background: var(--card-bg-raised); }
    .cmdk-item.is-hover { background: var(--card-bg-raised); }

    /* Shadow-scale hover specimens (Foundations → Shadows) */
    .lift-demo {
      padding: 14px 20px; border-radius: var(--r-xl);
      background: var(--card-bg); border: 1px solid var(--card-border);
      font-size: 16px; font-weight: 600; color: var(--ink-muted); cursor: pointer;
      transition: transform var(--t-base), border-color var(--t-base), box-shadow var(--t-base);
    }
    .lift-demo:hover { border-color: var(--card-border-hover); }
    .lift-md:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }
    .lift-sm:hover { transform: translateY(-1px); }


    /* ═══════════════════════════════════════════════
       REDUCED MOTION
       Honours the OS preference across the whole system.
       Motion that carries meaning (a spinner saying
       "still working") is reduced to a static indicator
       rather than removed — the signal survives, the
       movement does not.
    ═══════════════════════════════════════════════ */
    @media (prefers-reduced-motion: reduce) {
      *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
      }
      /* The beam is the answer being produced, so it cannot simply stop. The
         sweep goes and the colour stays: the wedge is parked where it lights
         the long bottom edge, and the blobs behind it are pinned there anyway,
         so what is left is a lit border that does not move. */
      .is-generating > .beam { animation: none !important; --beam-angle: 168deg; }
      .is-generating > .beam::before,
      .is-generating > .beam::after { animation: none !important;
        filter: brightness(1.3) saturate(1.2); }
      /* Looping decorative motion — stop outright */
      .signal-dot,
      .stream-cursor,
      .status-dot.pulse::after,
      .coach-dot::after { animation: none !important; opacity: 1 !important; }
      /* Shimmer becomes a flat placeholder tone */
      .skeleton { animation: none !important; background: rgba(255,255,255,0.07) !important; }
      :root[data-theme="light"] .skeleton { background: rgba(16,24,40,0.08) !important; }
      /* Spinners still need to read as "in progress" — hold a partial call */
      .think-spinner,
      .loading-spinner,
      .agent-step .mini-spin { animation: none !important; }
      /* Thinking dots and waveform: keep visible, stop the bounce */
      .ai-thinking .dots span,
      .voice-wave span { animation: none !important; opacity: 0.65 !important; }
      /* Hover lifts and entrance transforms */
      .card:hover,
      .bcard:hover,
      .token-item:hover,
      .lift-demo:hover,
      .btn.is-active { transform: none !important; }
      /* Toast auto-dismiss bar conveys remaining time — leave it filled */
      .aimy-toast-progress-fill { animation: none !important; transform: scaleX(1) !important; }
    }


    /* ═══════════════════════════════════════════════
       THEME TOGGLE — lifted from the design system's TOPBAR section,
       which is otherwise documentation chrome and is dropped.
    ═══════════════════════════════════════════════ */
    .ds-theme-toggle {
      display: inline-flex; align-items: center; justify-content: center;
      width: 32px; height: 32px; border-radius: var(--r-md);
      background: var(--card-bg-raised); border: 1px solid var(--card-border);
      color: var(--ink-muted); cursor: pointer;
      transition: border-color var(--t-fast), color var(--t-fast), background var(--t-fast);
    }
    .ds-theme-toggle:hover { border-color: var(--card-border-hover); color: var(--d50); }
    .ds-theme-toggle svg { width: 16px; height: 16px; display: block; }
    .ds-theme-toggle .icon-moon { display: none; }
    .ds-theme-toggle .icon-sun  { display: block; }
