/* İ.Z.A.N. shared UI: design tokens. This is the only file with raw colors, font names, spacing steps, radii and
   shadows. Every page of the product (the campus, İZAN Server's admin and city) reads them as custom properties,
   so a theme swap is a swap of this one file. A page overrides a token on its own element (`#x { --sea: … }`),
   never by editing a copy. A test (test/shared-ui.test.ts) fails when a raw hex color shows up in another
   stylesheet.

   Direction B "Canlı Kontrol" (2026-10-22) on palette A "Nizam": a dark-first command centre with a full light
   twin. Navy (light) and periwinkle (dark) carry the one primary; lime, periwinkle, amber and red carry meaning
   only (done, working, waiting, late).

   Theme: `<html data-theme="light|dark|system">`. `system` (or no attribute) follows prefers-color-scheme. The
   campus writes the attribute from an inline script in campus.html before the first paint and keeps the choice
   in localStorage (`izan.campus.theme`). `body.night` holds the dark values too: the campus sets it for the dark
   scene looks (night, mockup).

   Layers:
     1) palette: raw values (--paper … --slate), light here and the dark twin below; edit only these to restyle.
     2) semantic tokens, the names new code uses:
        surfaces   --surface-0 (ground) --surface-1 (card) --surface-2 (sunken, hover, segment track)
                   --surface-3 (sheet, menu, popover; always opaque)
        text       --text-1 (body) --text-2 (secondary, AA) --text-3 (tertiary, AA on surface-0/1)
        lines      --hairline (decorative) --border (card edge) --border-strong (input edge, 3:1)
        accent     --primary --on-primary (the one filled button) --accent-ink (links, selection, eyebrow)
                   --accent-soft (selected row, summary) --focus-ring
        status     --success --success-soft --success-dot · --warn --warn-soft --warn-dot
                   --danger --danger-soft --danger-dot · --info --info-soft · --live (pulse dot)
        risk       --risk-low --risk-med --risk-high --risk-crit (strip colours; always with a text label)
        glass      --glass-bg --glass-border --glass-blur (solid fallback below)
        elevation  --elev-0 … --elev-3 · radius --radius-xs … --radius-xl --radius-pill
        spacing    --space-1 … --space-8 (4 8 12 16 24 32 48 72)
        motion     --dur-1 --dur-2 --dur-3 --ease --pulse (zero under prefers-reduced-motion)
     3) aliases the existing stylesheets use (--bg, --text, --accent, --panel, --r, --s1 …), each one mapped to
        layer 2. Layers 2 and 3 are declared on `:root, body`, so `body.night` re-derives them from its palette. */

/* ——— Fonts ——— */
/* IBM Plex (SIL OFL 1.1, licence in src/web/assets/IBM-Plex-OFL.txt). The woff2 files ship with the bridge and are
   served from /assets/, so the page never calls out; a copy installed on the device wins (`local()`). */
@font-face {
  font-family: 'IBM Plex Sans';
  font-weight: 400;
  src:
    local('IBM Plex Sans'),
    local('IBMPlexSans-Regular'),
    url('/assets/IBMPlexSans-Regular.woff2') format('woff2');
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-weight: 500;
  src:
    local('IBM Plex Sans Medium'),
    local('IBMPlexSans-Medium'),
    url('/assets/IBMPlexSans-Medium.woff2') format('woff2');
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-weight: 600;
  src:
    local('IBM Plex Sans SemiBold'),
    local('IBMPlexSans-SemiBold'),
    url('/assets/IBMPlexSans-SemiBold.woff2') format('woff2');
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-weight: 400;
  src:
    local('IBM Plex Mono'),
    local('IBMPlexMono-Regular'),
    url('/assets/IBMPlexMono-Regular.woff2') format('woff2');
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-weight: 500;
  src:
    local('IBM Plex Mono Medium'),
    local('IBMPlexMono-Medium'),
    url('/assets/IBMPlexMono-Medium.woff2') format('woff2');
  font-display: swap;
}

/* ——— Layer 1: palette, light (default) ——— */
:root {
  color-scheme: light;
  --paper: #eef1f7; /* ground: blue-grey */
  --surface: #ffffff; /* card */
  --sunk: #e6e9f1; /* sunken area, segment track, table head */
  --raised: #f7f8fb; /* opaque twin of a glass card, for the fallback */
  --ink: #121830; /* text */
  --muted: #47506b; /* secondary text (7:1 on paper) */
  --faint: #565f78; /* tertiary text (5.6:1 on paper) */
  --line: #dde1ea; /* hairline */
  --edge: #8a93a6; /* input border (3:1) */
  --sea: #1c2558; /* the one primary: navy (filled buttons, mark) */
  --sea-soft: #e6eafd;
  --info: #3347b8; /* "working", links, selection, upcoming */
  --info-soft: #e6eafd;
  /* Status dots and bar segments only, never text. Each reaches 3:1 on white and on paper (WCAG 1.4.11; the
     brighter lime #8fb01d and amber #d99420 were 2.5:1 on a card, measured 2026-10-29). */
  --dot-done: #789418; /* lime */
  --dot-working: #7584e3; /* periwinkle */
  --dot-waiting: #bb7f1c; /* amber */
  --amber: #8a5300; /* "waiting for you" */
  --amber-soft: #fbeed0;
  --green: #3f5f0b; /* "done" */
  --green-soft: #e8f4c9;
  --red: #b3261e; /* "error, rejected, late" */
  --red-soft: #fde9e7;
  --slate: #565f78; /* "idle" */
  --live-dot: #4d8a12; /* the pulse dot on a light ground */
  /* Traffic on the agent network: a call, an answer, a wait for the owner, a failure (streaks and legend only). */
  --flow-call: #3b6df0;
  --flow-answer: #22a06b;
  --flow-wait: #e08a00;
  --flow-fail: #e03e3e;
  --on-sea: #ffffff; /* text on a --sea fill */
  --on-amber: #ffffff; /* text on an --amber fill */
  --white: #ffffff; /* fixed, for overlays and gradients; not a surface */
  --black: #000000;
  --shade: #14222b; /* tint of shadows and hairlines */
  --sheen: #ffffff; /* the top inner highlight of a card */
  --seg-on: #ffffff; /* the chosen part of a segmented control */
  --glow-a: #7c8cf230; /* ground light, top left */
  --glow-b: #b5d33422; /* ground light, bottom right */
  --grid-dot: #1218300d; /* the dot grid of the ground */
  --shadow: 0 1px 0 #ffffff inset, 0 10px 30px -12px #141b3a40;
  --shadow-pop: 0 18px 48px #141b3a2e;
}

/* ——— Layer 1: palette, dark ———
   The same block twice: the system preference (unless light is forced) and the explicit dark choice or the
   campus night class. CSS has no shared block; edit both together. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    color-scheme: dark;
    --paper: #070a14;
    --surface: #121624;
    --sunk: #191e2e;
    --raised: #161b2b;
    --ink: #e9edf8;
    --muted: #a6afc6;
    --faint: #8f98b0;
    --line: #22283a;
    --edge: #6b7488;
    --sea: #8d9bff;
    --sea-soft: #1d2350;
    --info: #8d9bff;
    --info-soft: #1b2148;
    --dot-done: #b5d334;
    --dot-working: #8494f0;
    --dot-waiting: #f4bb55;
    --amber: #f4bb55;
    --amber-soft: #2a2112;
    --green: #c6e24a;
    --green-soft: #1b2410;
    --red: #ff7b6e;
    --red-soft: #2e1416;
    --slate: #8f98b0;
    --on-sea: #0a0e1f;
    --on-amber: #0e1519;
    --shade: #000000;
    --sheen: #ffffff0f;
    --seg-on: #ffffff1f;
    --glow-a: #7c8cf233;
    --glow-b: #b5d33414;
    --grid-dot: #ffffff0d;
    --shadow: 0 1px 0 #ffffff0f inset, 0 20px 40px -20px #00000099;
    --shadow-pop: 0 18px 48px #00000099;
    --live-dot: #b5d334;
    --flow-call: #6f93ff;
    --flow-answer: #3ccf8e;
    --flow-wait: #f4a53a;
    --flow-fail: #ff6b6b;
  }
}
:root[data-theme='dark'],
body.night {
  color-scheme: dark;
  --paper: #070a14;
  --surface: #121624;
  --sunk: #191e2e;
  --raised: #161b2b;
  --ink: #e9edf8;
  --muted: #a6afc6;
  --faint: #8f98b0;
  --line: #22283a;
  --edge: #6b7488;
  --sea: #8d9bff;
  --sea-soft: #1d2350;
  --info: #8d9bff;
  --info-soft: #1b2148;
  --dot-done: #b5d334;
  --dot-working: #8494f0;
  --dot-waiting: #f4bb55;
  --amber: #f4bb55;
  --amber-soft: #2a2112;
  --green: #c6e24a;
  --green-soft: #1b2410;
  --red: #ff7b6e;
  --red-soft: #2e1416;
  --slate: #8f98b0;
  --on-sea: #0a0e1f;
  --on-amber: #0e1519;
  --shade: #000000;
  --sheen: #ffffff0f;
  --seg-on: #ffffff1f;
  --glow-a: #7c8cf233;
  --glow-b: #b5d33414;
  --grid-dot: #ffffff0d;
  --shadow: 0 1px 0 #ffffff0f inset, 0 20px 40px -20px #00000099;
  --shadow-pop: 0 18px 48px #00000099;
  --live-dot: #b5d334;
  --flow-call: #6f93ff;
  --flow-answer: #3ccf8e;
  --flow-wait: #f4a53a;
  --flow-fail: #ff6b6b;
}

/* ——— Layer 2: semantic tokens ——— */
:root,
body {
  /* Surfaces: 0 is the ground, 1 a card, 2 sunken (hover, track), 3 an opaque sheet or menu. */
  --surface-0: var(--paper);
  --surface-1: var(--surface);
  --surface-2: var(--sunk);
  --surface-3: var(--surface);
  --ground-image:
    radial-gradient(900px 500px at 10% -10%, var(--glow-a), transparent 60%),
    radial-gradient(700px 500px at 110% 110%, var(--glow-b), transparent 60%),
    radial-gradient(var(--grid-dot) 1px, transparent 1.2px);
  --ground-size: auto, auto, 18px 18px;

  /* Text: every level passes AA (4.5:1) on surface-0 and surface-1 in both themes. */
  --text-1: var(--ink);
  --text-2: var(--muted);
  --text-3: var(--faint);

  /* Lines */
  --hairline: var(--line);
  --border: color-mix(in srgb, var(--ink) 9%, transparent);
  --border-strong: var(--edge);

  /* Accent: one filled primary per surface; the accent ink marks links, selection and the eyebrow. */
  --primary: var(--sea);
  --on-primary: var(--on-sea);
  --primary-fill: linear-gradient(180deg, color-mix(in srgb, var(--sea) 88%, var(--white)), var(--sea));
  --primary-glow: 0 6px 20px -8px var(--sea);
  --accent-ink: var(--info);
  --accent-soft: color-mix(in srgb, var(--info) 12%, transparent);
  --focus-ring: 0 0 0 2px var(--surface-0), 0 0 0 4px var(--info);

  /* Status scales: text colour, soft fill and dot (dots and bars only, never text). */
  --success: var(--green);
  --success-soft: var(--green-soft);
  --success-dot: var(--dot-done);
  --warn: var(--amber);
  --warn-soft: var(--amber-soft);
  --warn-dot: var(--dot-waiting);
  --danger: var(--red);
  --danger-soft: var(--red-soft);
  --danger-dot: var(--red);
  --live: var(--live-dot);

  /* Risk: the strip on an approval card. A colour never stands alone; the card names the level in words. */
  --risk-low: var(--dot-done);
  --risk-med: var(--dot-waiting);
  --risk-high: var(--red);
  --risk-crit: var(--red);

  /* Glass: small floating surfaces over the scene (top bar, side cards, sticky bars). Never on a long list. */
  --glass-bg: color-mix(in srgb, var(--surface) 80%, transparent);
  --glass-border: color-mix(in srgb, var(--ink) 9%, transparent);
  --glass-blur: blur(18px) saturate(140%);

  /* Elevation */
  --elev-0: none;
  --elev-1: var(--shadow);
  --elev-2: 0 1px 0 var(--sheen) inset, 0 14px 36px -14px color-mix(in srgb, var(--shade) 45%, transparent);
  --elev-3: var(--shadow-pop);

  /* Radius */
  --radius-xs: 6px;
  --radius-s: 8px;
  --radius-m: 10px;
  --radius-l: 16px;
  --radius-xl: 28px;
  --radius-pill: 999px;

  /* Spacing */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 72px;
  --topbar-h: 50px;

  /* Motion */
  --dur-1: 120ms;
  --dur-2: 200ms;
  --dur-3: 320ms;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --pulse: 1.8s;

  /* Type */
  --font: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;
  --mono: 'IBM Plex Mono', 'SF Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Status map: the same five states everywhere (chip, dot, rail, scene) */
  --working: var(--info);
  --waiting: var(--amber);
  --done: var(--green);
  --error: var(--red);
  --idle: var(--slate);
}

/* Glass falls back to the opaque surface where blur is missing or the person asks for less transparency. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  :root,
  body {
    --glass-bg: var(--raised);
    --glass-blur: none;
  }
}
@media (prefers-reduced-transparency: reduce) {
  :root,
  body {
    --glass-bg: var(--raised);
    --glass-blur: none;
  }
}
/* A phone gets no glass: every blurred surface (top bar, cards, the sheet's action bar) is composited again each
   time the WebGL canvas behind it draws, and the canvas draws all the time. The opaque twin takes its place. */
@media (max-width: 760px) {
  :root,
  body {
    --glass-bg: var(--raised);
    --glass-blur: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  :root,
  body {
    --dur-1: 0ms;
    --dur-2: 0ms;
    --dur-3: 0ms;
    /* A pulse that never ends is the kind of motion the setting asks to stop; the dot stays, still. */
    --pulse: 0s;
  }
}

/* ——— Layer 3: aliases for the existing stylesheets ——— */
:root,
body {
  --bg: var(--surface-0);
  --text: var(--text-1);
  --panel: var(--glass-bg);
  --solid: var(--surface-3);
  --chip: color-mix(in srgb, var(--surface) 72%, transparent);
  --accent: var(--primary);
  --accentsoft: color-mix(in srgb, var(--sea) 9%, transparent);
  --r: var(--radius-m);
  --r-s: var(--radius-xs);
  --r-l: var(--radius-l);
  --r-xl: var(--radius-xl);
  --r-pop: var(--radius-l);
  --s1: var(--space-1);
  --s2: var(--space-2);
  --s3: var(--space-3);
  --s4: var(--space-4);
  --s5: var(--space-5);
  --s6: var(--space-6);
  --s7: var(--space-7);
  --s8: var(--space-8);
  --space-xs: var(--space-1);
  --space-s: 6px;
  --space-m: 10px;
  --space-l: var(--space-3);
}
