/* Spectrum AI design tokens (from the designer's design system), fonts self-hosted for the CSP. */
/* =========================================================================
   Array Spectrum AI, Foundations
   Tokens for color, type, spacing, radius, shadow.
   Light + dark scopes. Geist is the primary face for all roles.

   ─── Obra shadcn alignment ───
   Component tokens here mirror the Obra shadcn_ui Figma kit (Tailwind v4
   neutrals, 5 red stops in use, 1 blue stop, dark destructive #9E4042).
   Geist is canonical for ALL roles, labels, body, mono, replacing the
   Inter / Geist split that ships in the Obra file. The Array prism gradient
   is the ONE chromatic addition; Obra's purple accent (#9747FF) is reserved
   for Figma layout markers and is intentionally NOT exposed as a runtime
   token here.
   ========================================================================= */

@font-face{font-family:"Geist";font-style:normal;font-weight:100 900;font-display:swap;src:url("fonts/Geist-Variable.woff2") format("woff2")}
@font-face{font-family:"Geist Mono";font-style:normal;font-weight:100 900;font-display:swap;src:url("fonts/GeistMono-Variable.woff2") format("woff2")}
@font-face{font-family:"Good Times";font-style:normal;font-weight:400;font-display:swap;src:url("fonts/good-times.otf") format("opentype")}

/* Geist Mono, pulled from Google Fonts. Replace with a self-hosted TTF
   in /fonts/ when the team supplies one (drop a Geist-Mono-VariableFont.ttf
   and swap the src below). */


/* ---------- LIGHT mode (default) ---------- */
/* Also matches [data-theme="light"] so a light island can reclaim light tokens
   even when nested inside a dark-themed ancestor (e.g. the DS tab in dark mode). */
:root, [data-theme="light"], .theme-light {
  /* Brand prism gradient, pink → magenta → indigo → teal.
     This single gradient is the *only* place chromatic color enters the UI.
     Use it as a 1px border, a logo background, a chip glow, or a thin underline
     to draw attention to AI surfaces. Never as a full-bleed page background. */
  --prism: linear-gradient(135deg,
            rgb(255, 6, 249)   0%,
            rgb(126, 40, 245) 42%,
            rgb(57,  4, 253)  75%,
            rgb(48, 170, 182) 100%); /* @kind color */
  --prism-stop-pink:   rgb(255, 6, 249);
  --prism-stop-violet: rgb(126, 40, 245);
  --prism-stop-indigo: rgb(57,  4, 253);
  --prism-stop-teal:   rgb(48, 170, 182);

  /* Neutral scale, pulled from the Common Library Figma. */
  --neutral-0:    rgb(255, 255, 255);
  --neutral-50:   rgb(250, 250, 250);
  --neutral-100:  rgb(245, 245, 245);
  --neutral-200:  rgb(229, 229, 229);
  --neutral-300:  rgb(212, 212, 212);
  --neutral-400:  rgb(163, 163, 163);
  --neutral-500:  rgb(115, 115, 115);
  --neutral-600:  rgb( 82,  82,  82);
  --neutral-700:  rgb( 64,  64,  64);
  --neutral-750:  rgb( 51,  51,  51);
  --neutral-800:  rgb( 38,  38,  38);
  --neutral-900:  rgb( 23,  23,  23);
  --neutral-950:  rgb( 10,  10,  10);

  /* Semantic, borrowed from shadcn defaults the Common Library extends.
     "Danger" matches Tailwind red-600 (#DC2626); the dark theme overrides it
     to a desaturated #9E4042 to match Obra's destructive treatment. */
  --success:        rgb( 11, 110,  39);
  --success-soft:   rgb(214, 245, 222);
  --warning:        rgb(212, 114,   2);
  --warning-soft:   rgb(253, 245, 206);
  --danger:         rgb(220,  38,  38);   /* Tailwind red-600 */
  --danger-strong:  rgb(185,  28,  28);   /* Tailwind red-700, hover */
  --danger-soft:    rgb(254, 226, 226);   /* Tailwind red-100, soft fill */
  --danger-fg:      rgb(220,  38,  38);   /* foreground on light surfaces */
  --info:           rgb( 48, 170, 182);

  /* Surfaces (LIGHT) */
  --bg-app:        var(--neutral-100);     /* outer canvas */
  --bg-panel:      var(--neutral-0);       /* cards / panels */
  --bg-elevated:   var(--neutral-50);      /* chat bubbles, inputs */
  --bg-muted:      var(--neutral-100);     /* table zebra, hover */
  --bg-inverse:    var(--neutral-950);
  --avatar-bg:     var(--neutral-200);     /* avatar fill (flips in dark) */

  /* Foreground (LIGHT) */
  --fg-1:    var(--neutral-950);   /* primary copy */
  --fg-2:    var(--neutral-700);   /* body, secondary */
  --fg-3:    var(--neutral-500);   /* labels, captions, placeholders */
  --fg-4:    var(--neutral-400);   /* disabled / hint */
  --fg-inverse: var(--neutral-50); /* text on --bg-inverse (flips in dark) */
  --fg-on-prism: var(--neutral-50);

  /* Borders (LIGHT) */
  --border-1: var(--neutral-200);   /* default */
  --border-2: var(--neutral-300);   /* input outlines, separators in tables */
  --border-strong: var(--neutral-700);

  /* Radii, aligned to the Obra shadcn kit.
     Buttons, inputs, badges, cards, alerts ALL use 8 (--r-md).
     Switches use a soft 12-px pill on a 18-px track (NOT 9999).
     Checkboxes use 4. Pills (the chip-shaped "Round" variant) use 9999.  */
  --r-xs:  4px;    /* checkbox, kbd, tiny chips */
  --r-sm:  6px;    /* nothing in the canonical set, reserved */
  --r-md:  8px;    /* buttons, inputs, badges, cards, alerts, tabs */
  --r-lg: 12px;    /* switch track, small surfaces grouping primitives */
  --r-xl: 16px;    /* large panels, modals */
  --r-2xl: 24px;   /* hero / section cards */
  --r-pill: 9999px;

  /* Shadows, matched to Obra spec.
     `shadow-input` is the standardised resting state for inputs/buttons-outline.
     `shadow-card` is the standardised resting state for cards/checkbox.
     `shadow-prism-glow` is Array's brand-specific glow behind AI surfaces. */
  --shadow-input: 0 1px 2px 0 rgba(0,0,0,.05);                                     /* Obra input shadow */
  --shadow-outline:0 2px 2px 0 rgba(0,0,0,.05);                                    /* Obra outline-button shadow */
  --shadow-card:  0 1px 2px -1px rgba(0,0,0,.10), 0 1px 3px 0 rgba(0,0,0,.10);     /* Obra card shadow */
  --shadow-1: var(--shadow-input);
  --shadow-2: var(--shadow-card);
  --shadow-3: 0 8px 24px -4px rgba(0,0,0,.16), 0 4px 8px -2px rgba(0,0,0,.08);
  --shadow-prism-glow: 0 0 0 1px transparent, 0 0 24px -8px rgba(126,40,245,.45);

  /* Input focus ring, Obra spec uses a 3-px halo of #CECECE on neutral-400 border. */
  --ring-input: 0 0 0 3px rgb(206, 206, 206);
  --ring-input-border: var(--neutral-400);

  /* Spacing scale (4-pt) */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 20px; --s-6: 24px; --s-8: 32px; --s-10: 40px;
  --s-12: 48px; --s-16: 64px;

  /* Type families, Geist canonical for ALL roles. */
  --font-sans: "Geist", "IBM Plex Sans Arabic", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-display: "Geist", ui-sans-serif, sans-serif;
  --font-mono: "Geist Mono", "Geist", ui-monospace, "JetBrains Mono", Menlo, monospace;
  --font-wordmark: "Geist", ui-sans-serif, sans-serif;

  /* ─── Interaction state tokens (LIGHT)
     Mirrored from the Obra Button spec. Light-theme primary = darkest neutral;
     hover/active step LIGHTER by ~3 stops (950 → 700). The dark theme below
     does the opposite (50 → 300) so on dark surfaces the primary white-fill
     "darkens-toward-cool" on hover. */
  --btn-primary-bg:           var(--neutral-950);
  --btn-primary-fg:           var(--neutral-50);
  --btn-primary-bg-hover:     var(--neutral-700);
  --btn-primary-bg-active:    var(--neutral-700);

  --btn-secondary-bg:         var(--neutral-100);
  --btn-secondary-fg:         var(--neutral-900);
  --btn-secondary-bg-hover:   var(--neutral-200);
  --btn-secondary-bg-active:  var(--neutral-300);

  --btn-outline-bg:           var(--neutral-0);
  --btn-outline-fg:           var(--neutral-950);
  --btn-outline-bd:           var(--neutral-200);
  --btn-outline-bg-hover:     var(--neutral-100);
  --btn-outline-bg-active:    var(--neutral-200);

  --btn-ghost-bg:             transparent;
  --btn-ghost-fg:             var(--neutral-700);
  --btn-ghost-bg-hover:       rgba(0, 0, 0, 0.04);
  --btn-ghost-bg-active:      rgba(0, 0, 0, 0.08);

  --btn-danger-bg:            rgb(220, 38, 38);   /* Tailwind red-600 */
  --btn-danger-fg:            #FFFFFF;
  --btn-danger-bg-hover:      rgb(185, 28, 28);   /* red-700 */
  --btn-danger-bg-active:     rgb(153, 27, 27);   /* red-800 */

  --focus-ring:               var(--neutral-950);

  /* Skeleton (loading placeholder) */
  --skeleton-base:    color-mix(in srgb, var(--neutral-200) 60%, var(--neutral-100) 40%);
  --skeleton-shimmer: var(--neutral-50);

  /* ─── Accent tokens, use SPARINGLY for non-AI emphasis.
     These pull from the prism gradient's two cooler stops. Reserved for
     things like a selected-row left-edge tick, a chart series accent, or
     a single nav-rail highlight. Never use as a button fill or page bg. */
  --accent-violet: var(--prism-stop-violet);    /* #7E28F5, focus / highlight */
  --accent-teal:   var(--prism-stop-teal);      /* #30AAB6, info / data */
  --accent-violet-soft: rgba(126, 40, 245, 0.10);
  --accent-teal-soft:   rgba( 48, 170, 182, 0.12);

  /* ─── Chart series palette (LIGHT) ───
     Five categorical series colors, tuned from the prism gradient so data-viz
     stays on-brand without using the raw neon stops (which vibrate on charts).
     Consumed by the Chart component's ChartConfig as var(--chart-1..5). */
  --chart-1: #6E3AE0;   /* violet   */
  --chart-2: #1C989E;   /* teal (re-tuned to 3:1 on every light surface) */
  --chart-3: #3B5BDB;   /* indigo   */
  --chart-4: #D9418C;   /* magenta  */
  --chart-5: #C77618;   /* amber (re-tuned to 3:1 on every light surface) */
}

/* ─── Interaction state overrides (DARK) ───
   On the dark Obra docs page primary = #F5F5F5, hover & active = #D4D4D4.
   Destructive shifts to a desaturated muted red (#9E4042) so it doesn't
   scream against the neutral panel. */
[data-theme="dark"], [data-theme="midnight"], .theme-dark, .theme-midnight {
  --btn-primary-bg:           var(--neutral-100);
  --btn-primary-fg:           var(--neutral-950);
  --btn-primary-bg-hover:     var(--neutral-300);
  --btn-primary-bg-active:    var(--neutral-300);

  --btn-secondary-bg:         var(--neutral-800);
  --btn-secondary-fg:         var(--neutral-50);
  --btn-secondary-bg-hover:   var(--neutral-700);
  --btn-secondary-bg-active:  var(--neutral-700);

  --btn-outline-bg:           rgba(255, 255, 255, 0.05);
  --btn-outline-fg:           var(--neutral-50);
  --btn-outline-bd:           var(--neutral-700);
  --btn-outline-bg-hover:     rgba(255, 255, 255, 0.08);
  --btn-outline-bg-active:    rgba(255, 255, 255, 0.10);

  --btn-ghost-bg:             transparent;
  --btn-ghost-fg:             var(--neutral-300);
  --btn-ghost-bg-hover:       rgba(255, 255, 255, 0.06);
  --btn-ghost-bg-active:      rgba(255, 255, 255, 0.10);

  --btn-danger-bg:            rgb(158, 64, 66);   /* Obra dark-destructive */
  --btn-danger-fg:            #FFFFFF;
  --btn-danger-bg-hover:      rgb(180, 78, 80);
  --btn-danger-bg-active:     rgb(200, 92, 94);

  --focus-ring:               var(--neutral-50);

  /* Skeleton (loading placeholder, dark) */
  --skeleton-base:    var(--neutral-800);
  --skeleton-shimmer: var(--neutral-700);

  /* Surfaces (DARK), already defined further down for legacy callers;
     keep both copies in sync. */
  --bg-app:      var(--neutral-800);
  --bg-panel:    var(--neutral-900);
  --bg-elevated: rgba(255,255,255,0.06);
  --bg-muted:    rgba(255,255,255,0.04);
  --bg-inverse:  var(--neutral-50);
  --avatar-bg:   var(--neutral-750);

  --fg-1:   var(--neutral-50);
  --fg-2:   rgb(212, 212, 212);
  --fg-3:   var(--neutral-400);
  --fg-4:   var(--neutral-500);
  --fg-inverse: var(--neutral-950);
  --fg-on-prism: var(--neutral-50);

  --border-1: rgba(255,255,255,0.10);
  --border-2: rgba(255,255,255,0.18);
  --border-strong: rgba(255,255,255,0.40);

  /* Input focus ring on dark, slightly stronger. */
  --ring-input: 0 0 0 3px rgba(255,255,255,0.18);
  --ring-input-border: var(--neutral-500);

  --shadow-input:  0 1px 2px 0 rgba(0,0,0,.40);
  --shadow-outline:0 2px 2px 0 rgba(0,0,0,.40);
  --shadow-card:   0 1px 2px -1px rgba(0,0,0,.50), 0 1px 3px 0 rgba(0,0,0,.40);
  --shadow-1: var(--shadow-input);
  --shadow-2: var(--shadow-card);
  --shadow-3: 0 12px 32px -6px rgba(0,0,0,.55), 0 4px 8px -2px rgba(0,0,0,.40);
  --shadow-prism-glow: 0 0 24px -6px rgba(126,40,245,.55);

  /* Chart series palette (DARK), lifted for contrast on the dark panel. */
  --chart-1: #9B6BFF;
  --chart-2: #4CC7D4;
  --chart-3: #6A86F0;
  --chart-4: #EE6FAC;
  --chart-5: #EDA85C;
}

/* Legacy dark mode block consolidated above. */

/* ---------- Semantic typography (use these in markup) ----------
   ─── Obra alignment ───
   Type ladder matches the Obra Typography page: Geist 600 for h1 (48 / line 1 / -0.01em),
   tapering through h2 (24 / -0.02em) and h3 (20). Body roles follow Obra's
   "paragraph regular / medium / bold / small" pattern at 14 px with `letter-spacing
   .005em` and line-height 1.5. Display + display-uppercase remain Array's
   product-specific styles for thumbnails and brand mark surfaces. */
:where(.ds-display, .ds-h1, .ds-h2, .ds-h3, .ds-h4, .ds-body, .ds-body-md, .ds-body-bold, .ds-body-sm, .ds-body-mini, .ds-caption, .ds-label, .ds-eyebrow, .ds-kpi, .ds-code) {
  font-family: var(--font-sans);
  color: var(--fg-1);
  margin: 0;
}

.ds-display    { font-family: var(--font-display); font-weight: 600; font-size: 100px; line-height: 1.0;  letter-spacing: 0.08em; text-transform: uppercase; }
.ds-h1         { font-weight: 600; font-size: 48px; line-height: 1.00; letter-spacing: -0.01em; }      /* Obra h1 */
.ds-h2         { font-weight: 600; font-size: 24px; line-height: 1.20; letter-spacing: -0.02em; }      /* Obra h2 (Section header) */
.ds-h3         { font-weight: 600; font-size: 20px; line-height: 1.20; letter-spacing: -0.02em; }      /* Obra h3 */
.ds-h4         { font-weight: 600; font-size: 16px; line-height: 1.30; }
.ds-eyebrow    { font-weight: 500; font-size: 12px; line-height: 1.50; letter-spacing: 0.015em; color: var(--fg-3); text-transform: uppercase; }
.ds-body       { font-weight: 400; font-size: 14px; line-height: 1.50; letter-spacing: 0.005em; color: var(--fg-2); }   /* paragraph regular */
.ds-body-md    { font-weight: 500; font-size: 14px; line-height: 1.50; letter-spacing: 0.005em; color: var(--fg-1); }   /* paragraph medium */
.ds-body-bold  { font-weight: 600; font-size: 14px; line-height: 1.50; letter-spacing: 0.005em; color: var(--fg-1); }   /* paragraph bold */
.ds-body-sm    { font-weight: 400; font-size: 12px; line-height: 1.50; letter-spacing: 0.015em; color: var(--fg-2); }   /* paragraph small */
.ds-body-mini  { font-weight: 400; font-size: 11px; line-height: 1.45; letter-spacing: 0.020em; color: var(--fg-3); }   /* paragraph mini */
.ds-label      { font-weight: 500; font-size: 14px; line-height: 1.50; letter-spacing: 0.005em; color: var(--fg-1); }
.ds-caption    { font-weight: 400; font-size: 12px; line-height: 1.50; letter-spacing: 0.015em; color: var(--fg-3); }
.ds-kpi        { font-weight: 600; font-size: 30px; line-height: 1.00; letter-spacing: -0.02em; color: var(--fg-1); }
.ds-code       { font-family: var(--font-mono); font-size: 13px; line-height: 1.45; color: var(--fg-1); background: var(--bg-muted); padding: 0 4px; border-radius: var(--r-xs); }

/* ---------- Prism border utility ----------
   Apply to any element to give it the signature 1px gradient outline.
   It draws the gradient via background-clip masks; works on any radius. */
.prism-border {
  position: relative;
  isolation: isolate;
  background: var(--bg-panel);
}
.prism-border::before {
  content: "";
  position: absolute;
  inset: 0;
  padding: 1px;                                    /* the stroke width */
  border-radius: inherit;
  background: var(--prism);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
}
.prism-border-2::before { padding: 2px; }

/* Subtle prism halo used behind AI-affordance buttons */
.prism-halo {
  position: relative;
}
.prism-halo::after {
  content: "";
  position: absolute;
  inset: -8px;
  border-radius: inherit;
  background: var(--prism);
  filter: blur(18px);
  opacity: 0.35;
  z-index: -1;
}

/* ---------- Brand backdrop ----------
   Mesh-gradient backdrop reserved for BRAND-FORWARD pages only, login,
   homepage / suite control panel, splash, marketing. Never used on data-
   dense product surfaces. Layers (bottom → top):
     1. dark navy base (rgb 16 34 44)
     2. soft radial blooms of the prism colors
     3. light + dark noise PNGs at 50% opacity */
.mesh-bg {
  position: relative;
  background-color: rgb(16, 34, 44);
  background-image:
    radial-gradient(circle at 14% 30%, rgba(255,  6,249, .35) 0%, transparent 38%),
    radial-gradient(circle at 78% 22%, rgba(126, 40,245, .50) 0%, transparent 44%),
    radial-gradient(circle at 84% 84%, rgba( 48,170,182, .35) 0%, transparent 42%),
    radial-gradient(circle at  8% 80%, rgba( 57,  4,253, .35) 0%, transparent 42%);
  isolation: isolate;
}
.mesh-bg::before,
.mesh-bg::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background-size: 256px 256px;
  mix-blend-mode: overlay;
  opacity: 0.35;
  z-index: 0;
}
.mesh-bg::before { background-image: none; }
.mesh-bg::after  { background-image: url("assets/mesh-noise-dark.png"); opacity: 0.25; }
.mesh-bg > * { position: relative; z-index: 1; }

/* The brand wordmark utility, Geist 600 ALLCAPS for the SPECTRUM AI lockup. */
.brand-wordmark {
  font-family: var(--font-wordmark);
  font-weight: 600;
  letter-spacing: 0.08em;
}
html, body { background: var(--bg-app); color: var(--fg-1); font-family: var(--font-sans); }
body { margin: 0; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }


/* =========================================================================
   DENSE SYSTEM · Phase 1 Foundations (Investigation + ERP)
   Source of truth: uploads/Dense Design System Spec Investigation + ERP.md
   Layered on top of the tokens above. Existing names are kept; values for
   surfaces, text and borders are re-tuned so light and dark are designed as
   a pair. All text tokens are contrast-checked at 4.5:1 on every surface.
   ========================================================================= */

/* ---------- Density (nestable via data-density) ---------- */
:root, [data-density="default"] {
  --control-h: 32px; --control-h-sm: 28px; --row-h: 32px; --pad-x: 10px; --gap: 8px;
  --panel-pad: 12px; --font-body: 13px; --lh-body: 18px; --icon: 16px; --radius: 6px;
  --ai-outline-width: 2px; --panel-header-h: 32px; --topbar-h: 48px;
}
[data-density="compact"] {
  --control-h: 28px; --control-h-sm: 24px; --row-h: 24px; --pad-x: 8px; --gap: 4px;
  --panel-pad: 8px; --font-body: 12px; --lh-body: 16px; --icon: 14px; --radius: 4px;
  --ai-outline-width: 1.5px; --panel-header-h: 28px; --topbar-h: 40px;
}

[data-density="comfortable"] {
  --control-h: 36px; --control-h-sm: 32px; --row-h: 40px; --pad-x: 12px; --gap: 12px;
  --panel-pad: 16px; --font-body: 14px; --lh-body: 20px; --icon: 16px; --radius: 8px;
  --ai-outline-width: 2px; --panel-header-h: 36px; --topbar-h: 48px;
}
[data-density] { font-size: var(--font-body); line-height: var(--lh-body); }

/* ---------- Spacing (half steps, named by px) and type scale ---------- */
:root {
  --sp-2: 2px; --sp-4: 4px; --sp-6: 6px; --sp-8: 8px; --sp-10: 10px;
  --sp-12: 12px; --sp-16: 16px; --sp-20: 20px; --sp-24: 24px; --sp-32: 32px;

  --text-2xs: 11px;  --text-2xs-lh: 14px;
  --text-xs: 12px;   --text-xs-lh: 16px;
  --text-sm: 13px;   --text-sm-lh: 18px;
  --text-base: 14px; --text-base-lh: 20px;
  --text-lg: 16px;   --text-lg-lh: 22px;
  --text-xl: 20px;   --text-xl-lh: 26px;
  --text-2xl: 24px;  --text-2xl-lh: 30px;
  --weight-regular: 400; --weight-medium: 500; --weight-semibold: 600;

  --motion-fast: 100ms; /* @kind other */
  --motion-base: 150ms; /* @kind other */
  --motion-slow: 250ms; /* @kind other */
  --ease-standard: cubic-bezier(.2, 0, 0, 1); /* @kind other */
  --highlight-fade: 1.5s; /* @kind other */

  --focus-ring-width: 2px; --focus-ring-offset: 1px;
  --ai-outline-speed: 6s; /* @kind other */
  --ai-angle: 0deg; /* @kind other */
}
@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-fast: 0ms; /* @kind other */
    --motion-base: 0ms; /* @kind other */
    --motion-slow: 0ms; /* @kind other */
  }
}

/* ---------- Semantic + surface values: LIGHT ---------- */
:root, [data-theme="light"], .theme-light {
  --surface-0:#F4F4F4;--surface-1:#FFFFFF;--surface-2:#FFFFFF;--surface-3:#FFFFFF;
  --border-subtle:#ECECEC;--border-default:#E1E1E1;--border-strong:#C8C8C8;--border-control:#8C8C8C;
  --text-primary:#0A0A0A;--text-secondary:#3D3D3D;--text-muted:#616161;--text-disabled:#8F8F8F;--on-solid:#FFFFFF;
  /* severity */
  --critical-fg:#972527;--critical-bg:#FFEDEB;--critical-border:#FCC0BA;--critical-solid:#BE222A;
  --high-fg:#933000;--high-bg:#FFEFE5;--high-border:#F8C4AA;--high-solid:#B23E00;
  --medium-fg:#814500;--medium-bg:#FDF2E1;--medium-border:#EBCC9D;--medium-solid:#975A00;
  --low-fg:#0056A4;--low-bg:#E7F5FF;--low-border:#AFD5FE;--low-solid:#006BBB;
  --info-fg:#006566;--info-bg:#E1F9F9;--info-border:#9AE0DF;--info-solid:#007A7B;
  /* status */
  --draft-fg:#555555;--draft-bg:#F3F3F3;--draft-border:#D1D1D1;--draft-solid:#696969;
  --pending-fg:#814500;--pending-bg:#FDF2E1;--pending-border:#EBCC9D;--pending-solid:#975A00;
  --in-review-fg:#643B9A;--in-review-bg:#F6F0FF;--in-review-border:#D8C7F9;--in-review-solid:#7A4ABA;
  --approved-fg:#006925;--approved-bg:#E8F9EB;--approved-border:#B1DFB9;--approved-solid:#0A7E3A;
  --rejected-fg:#972527;--rejected-bg:#FFEDEB;--rejected-border:#FCC0BA;--rejected-solid:#BE222A;
  --posted-fg:#3A4AA7;--posted-bg:#EDF3FF;--posted-border:#C1CFFF;--posted-solid:#495CC9;
  --cancelled-fg:#555555;--cancelled-bg:#F3F3F3;--cancelled-border:#D1D1D1;--cancelled-solid:#696969;
  --overdue-fg:#952345;--overdue-bg:#FFEDF0;--overdue-border:#FBBFC8;--overdue-solid:#B72855;
  /* system */
  --live-fg:#006925;--live-bg:#E8F9EB;--live-border:#B1DFB9;--live-solid:#0A7E3A;
  --stale-fg:#814500;--stale-bg:#FDF2E1;--stale-border:#EBCC9D;--stale-solid:#975A00;
  --syncing-fg:#0056A4;--syncing-bg:#E7F5FF;--syncing-border:#AFD5FE;--syncing-solid:#006BBB;
  --offline-fg:#555555;--offline-bg:#F3F3F3;--offline-border:#D1D1D1;--offline-solid:#696969;
  --error-fg:#972527;--error-bg:#FFEDEB;--error-border:#FCC0BA;--error-solid:#BE222A;
  /* change */
  --added-fg:#006925;--added-bg:#E8F9EB;--added-border:#B1DFB9;--added-solid:#0A7E3A;
  --modified-fg:#0056A4;--modified-bg:#E7F5FF;--modified-border:#AFD5FE;--modified-solid:#006BBB;
  --removed-fg:#972527;--removed-bg:#FFEDEB;--removed-border:#FCC0BA;--removed-solid:#BE222A;
  /* entity (desaturated, categorical) */
  --entity-1-fg:#3B5876;--entity-1-bg:#ECF5FE;--entity-1-border:#C0D3E8;--entity-1-solid:#496C90;
  --entity-2-fg:#256060;--entity-2-bg:#E8F7F7;--entity-2-border:#B8D9D8;--entity-2-solid:#2F7675;
  --entity-3-fg:#4E5B36;--entity-3-bg:#F1F6EA;--entity-3-border:#CCD5BD;--entity-3-solid:#607043;
  --entity-4-fg:#644A6A;--entity-4-bg:#F8F0FA;--entity-4-border:#DCCAE0;--entity-4-solid:#7B5C82;
  --entity-5-fg:#6D4E31;--entity-5-bg:#FCF1E9;--entity-5-border:#E2CCBA;--entity-5-solid:#86603D;
  --entity-6-fg:#2C5C6E;--entity-6-bg:#E9F6FC;--entity-6-border:#BAD6E2;--entity-6-solid:#377187;
  --entity-7-fg:#6F475A;--entity-7-bg:#FDEFF5;--entity-7-border:#E4C8D4;--entity-7-solid:#88586F;
  --entity-8-fg:#35604A;--entity-8-bg:#EBF7F0;--entity-8-border:#BED8C9;--entity-8-solid:#42755B;
  /* selection */
  --selection-bg:#EEEBFF;--selection-border:#6C4BCC;--hover-bg:#F0F0F0;--linked-highlight:#D6F8F9;
  /* trend */
  --trend-positive-fg:#006925;--trend-negative-fg:#972527;--trend-neutral-fg:#616161;
  --bg-elevated: #F7F7F7; --bg-muted: #EFEFEF;
  --ai-prism: conic-gradient(from var(--ai-angle), #E005D9, #7E28F5, #3904FD, #1F8C96, #E005D9);
  --shadow-surface-2: 0 4px 12px -2px rgba(0,0,0,.10), 0 2px 4px -2px rgba(0,0,0,.06);
  --shadow-surface-3: 0 16px 40px -8px rgba(0,0,0,.18), 0 4px 12px -4px rgba(0,0,0,.08);
}

/* ---------- Semantic + surface values: DARK (designed, not inverted) ----------
   Near-black neutral base; panels step UP in lightness instead of using
   shadows. Muted text stays >= 5.5:1 on the highest surface. */
[data-theme="dark"], [data-theme="midnight"], .theme-dark, .theme-midnight {
  --surface-0:#0E0E10;--surface-1:#16161A;--surface-2:#1E1E23;--surface-3:#26262C;
  --border-subtle:#202025;--border-default:#2A2A30;--border-strong:#3A3A42;--border-control:#6E6E78;
  --text-primary:#EDEDEF;--text-secondary:#C6C6CC;--text-muted:#9C9CA4;--text-disabled:#686870;--on-solid:#0E0E10;
  /* severity */
  --critical-fg:#FFA59D;--critical-bg:#381C1A;--critical-border:#763D39;--critical-solid:#FF716B;
  --high-fg:#FFAC7E;--high-bg:#371E11;--high-border:#734126;--high-solid:#FE843D;
  --medium-fg:#EFBA64;--medium-bg:#312209;--medium-border:#684A12;--medium-solid:#DE9D16;
  --low-fg:#86CAFF;--low-bg:#13273A;--low-border:#2A527A;--low-solid:#58B0FF;
  --info-fg:#6CD9D8;--info-bg:#002C2C;--info-border:#005D5D;--info-solid:#50BFBE;
  /* status */
  --draft-fg:#C4C4C4;--draft-bg:#252525;--draft-border:#505050;--draft-solid:#ABABAB;
  --pending-fg:#EFBA64;--pending-bg:#312209;--pending-border:#684A12;--pending-solid:#DE9D16;
  --in-review-fg:#D0B2FF;--in-review-bg:#292038;--in-review-border:#574575;--in-review-solid:#BC8FFF;
  --approved-fg:#89DA9B;--approved-bg:#142B19;--approved-border:#2C5C38;--approved-solid:#62C37A;
  --rejected-fg:#FFA59D;--rejected-bg:#381C1A;--rejected-border:#763D39;--rejected-solid:#FF716B;
  --posted-fg:#A9BFFF;--posted-bg:#1E243B;--posted-border:#404C7C;--posted-solid:#86A1FF;
  --cancelled-fg:#C4C4C4;--cancelled-bg:#252525;--cancelled-border:#505050;--cancelled-solid:#ABABAB;
  --overdue-fg:#FFA3B5;--overdue-bg:#381B21;--overdue-border:#743C47;--overdue-solid:#FF7395;
  /* system */
  --live-fg:#89DA9B;--live-bg:#142B19;--live-border:#2C5C38;--live-solid:#62C37A;
  --stale-fg:#EFBA64;--stale-bg:#312209;--stale-border:#684A12;--stale-solid:#DE9D16;
  --syncing-fg:#86CAFF;--syncing-bg:#13273A;--syncing-border:#2A527A;--syncing-solid:#58B0FF;
  --offline-fg:#C4C4C4;--offline-bg:#252525;--offline-border:#505050;--offline-solid:#ABABAB;
  --error-fg:#FFA59D;--error-bg:#381C1A;--error-border:#763D39;--error-solid:#FF716B;
  /* change */
  --added-fg:#89DA9B;--added-bg:#142B19;--added-border:#2C5C38;--added-solid:#62C37A;
  --modified-fg:#86CAFF;--modified-bg:#13273A;--modified-border:#2A527A;--modified-solid:#58B0FF;
  --removed-fg:#FFA59D;--removed-bg:#381C1A;--removed-border:#763D39;--removed-solid:#FF716B;
  /* entity (desaturated, categorical) */
  --entity-1-fg:#AAC8E7;--entity-1-bg:#1D2630;--entity-1-border:#415263;--entity-1-solid:#8FAED0;
  --entity-2-fg:#9BD0CF;--entity-2-bg:#182928;--entity-2-border:#395656;--entity-2-solid:#7DB7B6;
  --entity-3-fg:#BCCBA4;--entity-3-bg:#23271B;--entity-3-border:#4B533E;--entity-3-solid:#A2B289;
  --entity-4-fg:#D5B9DB;--entity-4-bg:#2A222C;--entity-4-border:#594A5C;--entity-4-solid:#BC9FC3;
  --entity-5-fg:#DFBDA0;--entity-5-bg:#2D231A;--entity-5-border:#5E4C3C;--entity-5-solid:#C7A384;
  --entity-6-fg:#9ECCDF;--entity-6-bg:#19282D;--entity-6-border:#3B545E;--entity-6-solid:#82B3C8;
  --entity-7-fg:#E1B6C9;--entity-7-bg:#2E2127;--entity-7-border:#5F4852;--entity-7-solid:#C99CB0;
  --entity-8-fg:#A6D0B8;--entity-8-bg:#1C2922;--entity-8-border:#3F5649;--entity-8-solid:#8AB79E;
  /* selection */
  --selection-bg:#2E274E;--selection-border:#AA9AFC;--hover-bg:#222228;--linked-highlight:#073234;
  /* trend */
  --trend-positive-fg:#89DA9B;--trend-negative-fg:#FFA59D;--trend-neutral-fg:#9C9CA4;
  --bg-elevated: #1E1E23; --bg-muted: #1B1B20;
  --ai-prism: conic-gradient(from var(--ai-angle), #FF2BF8, #9B5CFF, #6B5BFF, #30AAB6, #FF2BF8);
  --shadow-surface-2: 0 6px 16px -4px rgba(0,0,0,.60);
  --shadow-surface-3: 0 18px 44px -8px rgba(0,0,0,.70);
}

/* ---------- Mapping: existing Array names + shadcn names read the new values.
   Declared on every theme scope so nested themes resolve locally. ---------- */
:root, [data-theme], .theme-light, .theme-dark, .theme-midnight {
  --bg-app: var(--surface-0); --bg-panel: var(--surface-1);
  --fg-1: var(--text-primary); --fg-2: var(--text-secondary); --fg-3: var(--text-muted); --fg-4: var(--text-disabled);
  --border-1: var(--border-default); --border-2: var(--border-control);
  --success: var(--approved-fg); --warning: var(--pending-fg); --danger: var(--critical-fg); --info: var(--info-fg);

  /* shadcn/ui token names (additive aliases) */
  --background: var(--surface-0); --foreground: var(--text-primary);
  --card: var(--surface-1); --card-foreground: var(--text-primary);
  --popover: var(--surface-2); --popover-foreground: var(--text-primary);
  --primary: var(--btn-primary-bg); --primary-foreground: var(--btn-primary-fg);
  --secondary: var(--btn-secondary-bg); --secondary-foreground: var(--btn-secondary-fg);
  --muted: var(--bg-muted); --muted-foreground: var(--text-muted);
  --accent: var(--hover-bg); --accent-foreground: var(--text-primary);
  --destructive: var(--btn-danger-bg); --destructive-foreground: var(--btn-danger-fg);
  --border: var(--border-default); --input: var(--border-control); --ring: var(--focus-ring);
}

/* ---------- Utilities ---------- */
.num, input[type="number"] { font-variant-numeric: tabular-nums; }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }

/* Live-update highlight: fades over 1.5s; static marker under reduced motion. */
@keyframes dsChangeFade { from { background-color: var(--added-bg); } to { background-color: transparent; } }
.change-flash { animation: dsChangeFade var(--highlight-fade) var(--ease-standard) 1; }
@media (prefers-reduced-motion: reduce) {
  .change-flash { animation: none; box-shadow: inset 2px 0 0 var(--added-border); }
}

/* Critical arrival: a single pulse, never looping. */
@keyframes dsCriticalPulse { 0% { box-shadow: 0 0 0 0 var(--critical-border); } 100% { box-shadow: 0 0 0 6px transparent; } }
.critical-arrive { animation: dsCriticalPulse 600ms ease-out 1; }
@media (prefers-reduced-motion: reduce) { .critical-arrive { animation: none; } }

/* AI content outline. Provenance, not importance. Pair with an "AI generated" label.
   data-ai-state: generating (rotates) · complete (one rotation, then static) · idle (static). */
@property --ai-angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
/* The dsAiSpin keyframes (to { --ai-angle: 360deg }) are injected by the component
   that uses the outline, so this sheet stays token-only. See preview/dense-surfaces.html. */
.ai-outline { position: relative; isolation: isolate; }
.ai-outline::before {
  content: ""; position: absolute; inset: 0; padding: var(--ai-outline-width); border-radius: inherit;
  background: var(--ai-prism);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude; pointer-events: none;
}
.ai-outline[data-ai-state="generating"]::before { animation: dsAiSpin var(--ai-outline-speed) linear infinite; }
.ai-outline[data-ai-state="complete"]::before { animation: dsAiSpin var(--ai-outline-speed) linear 1; }
@media (prefers-reduced-motion: reduce) { .ai-outline::before { animation: none !important; } }


/* =========================================================================
   ENTERPRISE PROFILE · rev. 2 additions
   Source: uploads/Dense_Design_System_Spec_Enterprise_Profile.md
   New semantic sets (Action lifecycle, Match, Run state) and chart-6..8.
   Values derived with the same method as the sets above and contrast-checked:
   every -fg >= 4.5:1 on its -bg and on surface-0..3; on-solid text >= 4.5:1;
   chart series >= 3:1 against every surface.
   ========================================================================= */
:root, [data-theme="light"], .theme-light {
  /* action */
  --suggested-fg:#7E288B;--suggested-bg:#FEEDFF;--suggested-border:#EAC0F1;--suggested-solid:#9836A8;
  --accepted-fg:#006566;--accepted-bg:#E1F9F9;--accepted-border:#9AE0DF;--accepted-solid:#007A7B;
  --assigned-fg:#3A4AA7;--assigned-bg:#EDF3FF;--assigned-border:#C1CFFF;--assigned-solid:#495CC9;
  --in-progress-fg:#0056A4;--in-progress-bg:#E7F5FF;--in-progress-border:#AFD5FE;--in-progress-solid:#006BBB;
  --resolved-fg:#006925;--resolved-bg:#E8F9EB;--resolved-border:#B1DFB9;--resolved-solid:#0A7E3A;
  --dismissed-fg:#555555;--dismissed-bg:#F3F3F3;--dismissed-border:#D1D1D1;--dismissed-solid:#696969;
  /* match */
  --matched-fg:#006925;--matched-bg:#E8F9EB;--matched-border:#B1DFB9;--matched-solid:#0A7E3A;
  --within-tolerance-fg:#006566;--within-tolerance-bg:#E1F9F9;--within-tolerance-border:#9AE0DF;--within-tolerance-solid:#007A7B;
  --partial-fg:#814500;--partial-bg:#FDF2E1;--partial-border:#EBCC9D;--partial-solid:#975A00;
  --unmatched-fg:#555555;--unmatched-bg:#F3F3F3;--unmatched-border:#D1D1D1;--unmatched-solid:#696969;
  --exception-fg:#933000;--exception-bg:#FFEFE5;--exception-border:#F8C4AA;--exception-solid:#B23E00;
  /* run */
  --queued-fg:#555555;--queued-bg:#F3F3F3;--queued-border:#D1D1D1;--queued-solid:#696969;
  --running-fg:#0056A4;--running-bg:#E7F5FF;--running-border:#AFD5FE;--running-solid:#006BBB;
  --succeeded-fg:#006925;--succeeded-bg:#E8F9EB;--succeeded-border:#B1DFB9;--succeeded-solid:#0A7E3A;
  --failed-fg:#972527;--failed-bg:#FFEDEB;--failed-border:#FCC0BA;--failed-solid:#BE222A;
  --skipped-fg:#555555;--skipped-bg:#F3F3F3;--skipped-border:#D1D1D1;--skipped-solid:#696969;
  --awaiting-approval-fg:#814500;--awaiting-approval-bg:#FDF2E1;--awaiting-approval-border:#EBCC9D;--awaiting-approval-solid:#975A00;
  /* chart 6 to 8 (series identity only) */
  --chart-6:#348F4F;
  --chart-7:#0087B2;
  --chart-8:#928A07;
}
[data-theme="dark"], [data-theme="midnight"], .theme-dark, .theme-midnight {
  /* action */
  --suggested-fg:#ECA7F6;--suggested-bg:#301D34;--suggested-border:#673E6D;--suggested-solid:#DC83EA;
  --accepted-fg:#6CD9D8;--accepted-bg:#002C2C;--accepted-border:#005D5D;--accepted-solid:#50BFBE;
  --assigned-fg:#A9BFFF;--assigned-bg:#1E243B;--assigned-border:#404C7C;--assigned-solid:#86A1FF;
  --in-progress-fg:#86CAFF;--in-progress-bg:#13273A;--in-progress-border:#2A527A;--in-progress-solid:#58B0FF;
  --resolved-fg:#89DA9B;--resolved-bg:#142B19;--resolved-border:#2C5C38;--resolved-solid:#62C37A;
  --dismissed-fg:#C4C4C4;--dismissed-bg:#252525;--dismissed-border:#505050;--dismissed-solid:#ABABAB;
  /* match */
  --matched-fg:#89DA9B;--matched-bg:#142B19;--matched-border:#2C5C38;--matched-solid:#62C37A;
  --within-tolerance-fg:#6CD9D8;--within-tolerance-bg:#002C2C;--within-tolerance-border:#005D5D;--within-tolerance-solid:#50BFBE;
  --partial-fg:#EFBA64;--partial-bg:#312209;--partial-border:#684A12;--partial-solid:#DE9D16;
  --unmatched-fg:#C4C4C4;--unmatched-bg:#252525;--unmatched-border:#505050;--unmatched-solid:#ABABAB;
  --exception-fg:#FFAC7E;--exception-bg:#371E11;--exception-border:#734126;--exception-solid:#FE843D;
  /* run */
  --queued-fg:#C4C4C4;--queued-bg:#252525;--queued-border:#505050;--queued-solid:#ABABAB;
  --running-fg:#86CAFF;--running-bg:#13273A;--running-border:#2A527A;--running-solid:#58B0FF;
  --succeeded-fg:#89DA9B;--succeeded-bg:#142B19;--succeeded-border:#2C5C38;--succeeded-solid:#62C37A;
  --failed-fg:#FFA59D;--failed-bg:#381C1A;--failed-border:#763D39;--failed-solid:#FF716B;
  --skipped-fg:#C4C4C4;--skipped-bg:#252525;--skipped-border:#505050;--skipped-solid:#ABABAB;
  --awaiting-approval-fg:#EFBA64;--awaiting-approval-bg:#312209;--awaiting-approval-border:#684A12;--awaiting-approval-solid:#DE9D16;
  /* chart 6 to 8 (series identity only) */
  --chart-6:#6FC082;
  --chart-7:#54B8E1;
  --chart-8:#9A9725;
}

/* ---------- Profiles ----------
   One core system, profiles layered on top via data-profile (nestable).
   enterprise  · primary profile; core values above ARE the Enterprise values.
   prof-saas   · shares Default and Comfortable densities (spec). Root density is
                 already Default, so no overrides yet.
   consumer    · hook only. Values come from the Consumer App profile spec;
                 nothing is invented here.
   Recommended density by mode (set data-density on the container):
   Investigation workspaces compact · Insight & Action overviews default with grids
   and queues compact · Transactional forms default, grids and queues compact ·
   Data Operations configuration default, run logs compact. */
:root, [data-profile="enterprise"] { --profile-name: "enterprise"; /* @kind other */ }
[data-profile="prof-saas"] { --profile-name: "prof-saas"; /* @kind other */ }
[data-profile="consumer"] { --profile-name: "consumer"; /* @kind other */ }

/* ---------- Right-to-left ----------
   Layout mirrors via logical properties and dir="rtl". Numbers, IDs, amounts,
   codes and time stay left-to-right inside an isolated run. */
.mono, code, kbd, samp { unicode-bidi: isolate; direction: ltr; }
.num { unicode-bidi: isolate; }
/* RTL: numeric columns keep end alignment (which mirrors with the layout); digits stay LTR. Time axes never mirror. */
[dir="rtl"] .time-axis, [dir="rtl"] [data-time-axis] { direction: ltr; }

/* Spec naming aliases for Change tokens (spec writes change-added-bg). */
:root, [data-theme] {
  --change-added-fg: var(--added-fg); --change-added-bg: var(--added-bg); --change-added-border: var(--added-border); --change-added-solid: var(--added-solid);
  --change-modified-fg: var(--modified-fg); --change-modified-bg: var(--modified-bg); --change-modified-border: var(--modified-border); --change-modified-solid: var(--modified-solid);
  --change-removed-fg: var(--removed-fg); --change-removed-bg: var(--removed-bg); --change-removed-border: var(--removed-border); --change-removed-solid: var(--removed-solid);
}

/* Shortcut and key chips stay LTR in RTL layouts (⌘S never renders as S⌘). */
kbd, .ds-menu-kbd, .ds-cmd-k, .ds-ctx-shortcut, .ds-menubar-kbd, .ds-btn-kbd, .ds-tip-kbd, [data-shortcut], .mono, .num { direction: ltr; unicode-bidi: isolate; }

/* ---------- Midnight theme ----------
   A navy dark theme. Inherits every Dark token (semantic sets, chart, motion, AI
   outline) and replaces the neutral surfaces with a blue-black ramp. Source: the
   Vendor Intelligence prototype (navy variant 3). Use data-theme="midnight".
   All text tokens re-checked on the four navy surfaces: text >= 4.5:1,
   control borders and focus >= 3:1 (control border measured 3.39:1 on surface-3). */
[data-theme="midnight"], .theme-midnight {
  --surface-0:#0A1020;--surface-1:#101831;--surface-2:#17213F;--surface-3:#1F2B50;
  --border-subtle:#18223F;--border-default:#202C50;--border-strong:#2E3C68;--border-control:#767E8F;
  --text-disabled:#94949C;
  --bg-muted:#131C38;--bg-elevated:#17213F;
  --hover-bg:#243157;
  --accent-violet:#A47BFF;
  --linked-highlight:#073234;
  --skeleton-base:#1A2548;
}
