/*
  Vexa Risk Intelligence — Design Tokens v1

  Single source of truth for colour, spacing, radius and shadow. Every
  screen — staff and applicant — pulls from this file instead of carrying
  its own inline <style> block. That duplication was the actual root cause
  behind the earlier "purple Very High badge" and five-different-radius-values
  problem: there was no single place to fix it.

  Served at /tokens.css (see web_app.py). Reachable on both portal surfaces
  and without a session, the same as the pages that link it.
*/

:root{
  /* Brand. --teal (3.39:1 on white) is for fills and surfaces — the primary
     button background, borders, icon strokes. It is NOT for text on white:
     body text or a link set in --teal fails AA (measured 3.39:1, needs 4.5:1).
     Use --teal-dark (5.19:1) for any text or link color instead — same brand,
     legible size. This is the one pattern to copy for every future accent
     colour: a colour strong enough to fill a button is not automatically
     strong enough to read as text on white. */
  --teal:#0D9C93; --teal-dark:#0B7A73; --teal-bright:#2DE0CE;
  --ink:#0A0F1A; --paper:#F7F8FA;

  /* Neutrals */
  --n-50:#F9FAFB; --n-100:#F1F3F6; --n-200:#E4E8EE; --n-300:#D1D7E0;
  --n-500:#6B7280; --n-600:#525C6B; --n-700:#374151; --n-900:#0F1420;

  /* Semantic aliases */
  --background:var(--paper); --foreground:var(--n-900);
  --card:#ffffff; --card-foreground:var(--n-900);
  /* Alias: a lot of index.html's own CSS (search inputs, case/entity rows,
     filter selects) was written against --surface, expecting it to mean
     "the card-level surface colour" — same value as --card, different name.
     Defining it here rather than rewriting every call site. */
  --surface:var(--card);
  --border:var(--n-200); --input:var(--n-200);
  --primary:var(--teal); --primary-foreground:#ffffff;
  --muted:var(--n-100); --muted-foreground:var(--n-500);
  --ring:var(--teal);

  /* Risk severity scale — fixed. Never substitute brand colour for this.
     low-fg and mod-fg were originally #0E9F5B/#B7791F, which measured 3.18:1
     and 3.40:1 against their own badge backgrounds — below the 4.5:1 WCAG AA
     floor for text at badge size (11.5px, nowhere near the 18.66px/14px-bold
     "large text" exemption). Darkened to clear AA; high/crit were already
     compliant (4.61:1 / 5.18:1) and are unchanged. */
  --low-bg:#E8FBF1; --low-fg:#0A7D46; --low-ring:#B7EFD1;
  --mod-bg:#FFF7E0; --mod-fg:#8A5A12; --mod-ring:#FBE6A8;
  --high-bg:#FFEFE3; --high-fg:#C2410C; --high-ring:#FED2AE;
  --crit-bg:#FDECEC; --crit-fg:#C0271F; --crit-ring:#FAC5C1;

  /* Semantic feedback (distinct from risk severity) */
  --success:#0E9F5B; --warning:#B7791F; --error:#C0271F; --info:var(--teal);

  /* Radius */
  --r-sm:7px; --r-md:10px; --r-lg:16px; --r-xl:22px; --r-full:999px;

  /* Shadows */
  --shadow-sm:0 1px 2px rgba(16,24,40,.04),0 1px 1px rgba(16,24,40,.03);
  --shadow-md:0 4px 16px -4px rgba(16,24,40,.08),0 2px 6px -2px rgba(16,24,40,.05);
  --shadow-lg:0 12px 32px -8px rgba(16,24,40,.14);
  --shadow-glow:0 0 0 1px rgba(20,211,196,.22),0 8px 26px -4px rgba(20,211,196,.32);

  /* Motion */
  --duration-fast:150ms; --duration-base:250ms; --duration-slow:400ms;
  --ease-out:cubic-bezier(.16,1,.3,1);

  /* Monospace — reference numbers, case ids, code/config values, and anywhere
     digits line up in a column (pair with .tab-nums for the numeric case). */
  --data:"Cascadia Code","SF Mono",Consolas,"Roboto Mono",monospace;
}

/* Dark-mode base tokens. Until this rule existed, [data-theme="dark"] never
   redefined --card/--border/--foreground/--muted/--surface at all — every
   element styled with only those tokens (no page-specific override) rendered
   its light-mode colour regardless of theme, i.e. dark navy text on a dark
   navy card. Every per-component [data-theme="dark"] rule elsewhere in the
   app hardcodes a literal colour instead of var(...), so it already wins the
   cascade over this block and is completely unaffected by it — this only
   reaches the elements nothing else was styling for dark mode, which is
   exactly where the invisible-text gap was.  Values match the dark palette
   already established ad hoc throughout index.html (#0E1522 card / #0C2438
   border / #e2e8f0 text), just promoted to the shared token layer. */
[data-theme="dark"]{
  --background:#0A0F1A; --foreground:#E2E8F0;
  --card:#0E1522; --card-foreground:#E2E8F0;
  --border:#0C2438; --input:#0C2438;
  --muted:#0C2438; --muted-foreground:#6B8AAA;
}

/* Dark-surface mesh treatment: the one visual language for every place black
   is used — sidebar, compliance cards, command palette, hero. Not four
   different dark backgrounds; one component. */
.mesh{position:relative;background:linear-gradient(165deg,#0A0F1A 0%,#0D1420 55%,#0A1420 100%)}
.mesh::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(420px 260px at 12% 0%, rgba(20,211,196,.32), transparent 65%),
             radial-gradient(360px 300px at 100% 100%, rgba(88,101,242,.16), transparent 60%)}
.mesh::after{content:"";position:absolute;inset:0;pointer-events:none;opacity:.45;
  background-image:radial-gradient(rgba(255,255,255,.05) 1px,transparent 1px);background-size:20px 20px;
  -webkit-mask-image:radial-gradient(ellipse at 15% 10%, black, transparent 68%)}
.mesh > *{position:relative;z-index:1}

.tab-nums{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}

.brand-mark{border-radius:9px;background:linear-gradient(150deg,#2DE0CE,#0B7A73 70%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.4),inset 0 -6px 10px rgba(0,0,0,.25),0 6px 14px -4px rgba(20,211,196,.6);
  display:flex;align-items:center;justify-content:center}
.brand-mark.sm{width:26px;height:26px;border-radius:8px}
.brand-mark.lg{width:52px;height:52px;border-radius:15px}

.badge{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;font-weight:700;
  padding:4px 10px 4px 8px;border-radius:var(--r-full);border:1px solid transparent}
.badge.b-low{background:var(--low-bg);color:var(--low-fg);border-color:var(--low-ring)}
.badge.b-mod{background:var(--mod-bg);color:var(--mod-fg);border-color:var(--mod-ring)}
.badge.b-high{background:var(--high-bg);color:var(--high-fg);border-color:var(--high-ring)}
.badge.b-crit{background:var(--crit-bg);color:var(--crit-fg);border-color:var(--crit-ring)}

/* A coloured stripe on the leading edge of a row, carrying the same four
   severity colours as .badge. Lets a queue read by position and colour
   without parsing a badge on every line — pair with .badge for the label. */
.severity-stripe{width:3px;align-self:stretch;border-radius:0 3px 3px 0;flex:none}
.severity-stripe.b-low{background:var(--low-fg)}
.severity-stripe.b-mod{background:var(--mod-fg)}
.severity-stripe.b-high{background:var(--high-fg)}
.severity-stripe.b-crit{background:var(--crit-fg)}

/* Double-bezel container: an outer tray (hairline + faint gradient) holding an
   inner plate (the real surface, with its own top highlight). Used for any
   card that should read as a raised instrument rather than a flat rectangle —
   stat cards, the case-report dial, the attention stack. Nest .plate directly
   inside .tray; .tray supplies the padding gap between the two. */
.tray{background:linear-gradient(180deg,rgba(10,15,26,.045),rgba(10,15,26,.016));
  border:1px solid var(--border);border-radius:var(--r-xl);padding:6px}
.plate{background:var(--card);border:1px solid var(--border);
  border-radius:calc(var(--r-xl) - 6px);box-shadow:inset 0 1px 0 rgba(255,255,255,.85);overflow:hidden}
[data-theme="dark"] .tray{background:linear-gradient(180deg,rgba(255,255,255,.045),rgba(255,255,255,.014));
  border-color:#0C2438}
[data-theme="dark"] .plate{background:#0E1522;border-color:#0C2438;box-shadow:inset 0 1px 0 rgba(255,255,255,.05)}

/* One row representing a person or an institution — the shared shape for
   Team and Institutions. An icon or initials avatar, a name/subtitle block
   that grows, then right-aligned status and actions. No margin-bottom here
   on purpose: both call sites already lay their rows out with flex `gap` —
   an own-margin on top of that would double the space between rows and
   still leave one under the last row where nothing follows it. */
.entity-row{background:var(--card);border:1px solid var(--border);border-radius:var(--r-md);
  padding:13px 16px;display:flex;align-items:center;gap:13px;flex-wrap:wrap}
.entity-ico{width:36px;height:36px;border-radius:10px;flex:none;display:flex;
  align-items:center;justify-content:center;background:linear-gradient(135deg,var(--teal),#2563eb);color:#fff}
.entity-av{width:34px;height:34px;border-radius:50%;flex:none;display:flex;
  align-items:center;justify-content:center;background:var(--teal);color:#fff;
  font-size:11.5px;font-weight:750}
.entity-n{font-size:13.5px;font-weight:700;color:var(--foreground)}
.entity-s{font-size:11px;color:var(--muted-foreground);margin-top:1px}
[data-theme="dark"] .entity-row{background:#0E1522;border-color:#0C2438}

/* The existing Products & Rates accordion (`<details class="prod-card">`)
   carried these rules as inline styles per-card. Centralised here so every
   product card looks identical and dark mode is handled once. `<details>` is
   used deliberately instead of a JS-toggled div — native keyboard support
   (Space/Enter to open, focus order) with zero extra script. */
.prod-card{border:1px solid var(--border);border-radius:var(--r-md);margin-bottom:10px;
  background:var(--card);overflow:hidden}
.prod-card > summary{padding:13px 16px;cursor:pointer;display:flex;align-items:center;gap:11px;
  font-size:13.5px;font-weight:700;list-style:none;color:var(--foreground)}
.prod-card > summary::-webkit-details-marker{display:none}
.prod-card[open] > summary{border-bottom:1px solid var(--border)}
[data-theme="dark"] .prod-card{background:#0E1522;border-color:#0C2438}
[data-theme="dark"] .prod-card[open] > summary{border-bottom-color:#0C2438}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important}
}
