/* ==========================================================================
   KilgoreAI — design tokens
   Single source of truth for /chat/, / (landing) and /api-docs.
   Load this BEFORE any page stylesheet.
   ========================================================================== */

/* ============ fonts (self-hosted, OFL — static/fonts/LICENSE-geist*.txt) ==== */

@font-face {
  font-family: "Geist Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/chat/fonts/geist-latin.woff2") format("woff2-variations");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/chat/fonts/geist-vietnamese.woff2") format("woff2-variations");
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
    U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9,
    U+20AB;
}
@font-face {
  font-family: "Geist Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/chat/fonts/geist-latin-ext.woff2") format("woff2-variations");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Geist Mono Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/chat/fonts/geist-mono-latin.woff2") format("woff2-variations");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist Mono Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/chat/fonts/geist-mono-vietnamese.woff2") format("woff2-variations");
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
    U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9,
    U+20AB;
}
@font-face {
  font-family: "Geist Mono Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/chat/fonts/geist-mono-latin-ext.woff2") format("woff2-variations");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ============ scales (theme-independent) ============ */
:root {
  /* type — every step carries its own tracking + leading */
  --fs-display: 46px;   --lh-display: 1.01;  --tr-display: -0.04em;
  --fs-h1: 30px;        --lh-h1: 1.1;        --tr-h1: -0.03em;
  --fs-h2: 20px;        --lh-h2: 1.2;        --tr-h2: -0.025em;
  --fs-lg: 17px;        --lh-lg: 1.25;       --tr-lg: -0.02em;
  --fs-h3: 15.5px;      --lh-h3: 1.3;        --tr-h3: -0.015em;
  --fs-h4: 13.5px;      --lh-h4: 1.4;
  --fs-body: 15px;      --lh-body: 1.6;      --tr-body: 0;
  --fs-sm: 13.5px;      --lh-sm: 1.5;
  --fs-xs: 12px;        --lh-xs: 1.45;
  --fs-micro: 11px;     --lh-micro: 1.4;     --tr-micro: 0.02em;
  --fs-label: 10.5px;                        --tr-label: 0.09em;
  --fs-nano: 9.5px;                          /* uppercase status pills only */
  --lh-code: 1.65;      /* code blocks want more air than prose */
  --tr-badge: 0.04em;   /* uppercase mono verb badges */
  --wt-regular: 400; --wt-medium: 500; --wt-semi: 600; --wt-bold: 700;
  --measure: 65ch;
  --measure-tight: 56ch;      /* deck copy / subtitles */

  /* spacing — 4px base, plus two named optical half-steps so the
     sub-4px values stop being sprinkled as literals */
  --sp-05: 2px; --sp-1-5: 6px; --sp-2-5: 10px; --sp-3-5: 14px;
  --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-16: 64px;
  --sp-18: 72px;
  --sp-20: 80px;
  --content-w: 800px;
  --doc-w: 900px;
  --sidebar-w: 264px;
  --rail-w: 172px;            /* docs table-of-contents rail */
  --modal-w: 460px;           /* consent gate / single-column dialogs */
  --tap: 44px;                /* WCAG 2.5.5 minimum touch target */

  /* radius — --r-2xs is for hairline markers (scroll thumbs, 3px accent bars),
     not a general step. 50% circles stay literal. */
  --r-2xs: 2px;
  --r-xs: 5px; --r-sm: 8px; --r-md: 12px; --r-lg: 16px; --r-xl: 22px; --r-pill: 999px;

  /* z-index — named layers. Toast sits above modals on purpose. */
  --z-jump: 100;
  --z-dropdown: 200;
  --z-scrim: 300;
  --z-sidebar: 310;
  --z-modal: 400;
  --z-lightbox: 500;
  --z-drop: 600;
  --z-toast: 700;
  --z-consent: 800;  /* first-visit privacy gate — above everything */

  /* motion — three interaction speeds plus two entrance speeds. Entrances are
     deliberately slower than any hover/press: they play once, on arrival. */
  --ease: cubic-bezier(0.32, 0.72, 0, 1);
  --dur-fast: 0.12s;
  --dur: 0.18s;
  --dur-slow: 0.28s;
  --dur-reveal: 0.5s;         /* scroll-reveal fade + rise */
  --dur-enter: 0.8s;          /* first-paint hero entrance */
  --stagger-step: 0.08s;      /* multiplied by index for sequenced reveals */

  /* typefaces */
  --font: "Geist Variable", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --mono: "Geist Mono Variable", ui-monospace, "Cascadia Mono", "SF Mono", Consolas, monospace;
}

/* ============ theme: warm (default) ============ */
:root,
body[data-theme="warm"] {
  --bg: #1d1d1b;
  --bg-elev: #242422;
  --bg-elev-2: #2b2b29;
  --bg-hover: #2e2e2c;
  --border: #343432;
  --border-strong: #42423f;
  --text: #f0efec;
  --text-dim: #a9a7a0;
  --text-faint: #949188;
  --accent: #d97757;
  --accent-strong: #e08667;
  --accent-rgb: 217 119 87;
  --accent-soft: rgb(var(--accent-rgb) / 0.12);
  --accent-faint: rgb(var(--accent-rgb) / 0.04);
  --accent-border: rgb(var(--accent-rgb) / 0.28);
  --accent-border-strong: rgb(var(--accent-rgb) / 0.55);
  --accent-focus-ring: rgb(var(--accent-rgb) / 0.28);
  --user-bg: #2a2a27;
  --ok: #46a758;
  --ok-rgb: 70 167 88;
  --warn: #f5a524;
  --warn-rgb: 245 165 36;
  --err: #e5484d;
  --err-strong: #ff6369;
  --err-rgb: 229 72 77;
  --err-soft: rgb(var(--err-rgb) / 0.12);
  --err-border: rgb(var(--err-rgb) / 0.5);
  --err-bubble: rgb(var(--err-rgb) / 0.06);
  --err-bubble-border: rgb(var(--err-rgb) / 0.3);
  --err-code-bg: rgb(var(--err-rgb) / 0.12);
  --code-bg: #1a1a18;
  --code-head-bg: #1f1f1d;
  --code-inline-bg: rgb(255 255 255 / 0.06);
  --code-btn-hover: #55554f;
  --scroll-thumb: #3a3a37;
  --scroll-thumb-hover: #4a4a46;
  --btn-disabled-bg: #3a3a37;
  --on-accent: #1d1d1b;
  --logo-plate: #f2f1ee;
  --logo-plate-dark: #1d1d1b;
  --lb-bg: rgb(12 10 8 / 0.93);
  --scrim: rgb(12 10 8 / 0.6);
  --shadow-rgb: 20 16 12;
}

/* HTTP verb colours — one set per theme so the docs badges stay legible.
   Dark themes share a palette; `paper` overrides it below. */
:root,
body[data-theme="warm"],
body[data-theme="midnight"],
body[data-theme="amoled"] {
  --verb-get: #6fc276;         --verb-get-border: #2f5a36;    --verb-get-bg: rgb(111 194 118 / 0.08);
  --verb-post: #e8a85f;        --verb-post-border: #6b4a20;   --verb-post-bg: rgb(232 168 95 / 0.08);
  --verb-put: #c79ae8;         --verb-put-border: #4d2f6b;    --verb-put-bg: rgb(199 154 232 / 0.08);
  --verb-patch: #7fb0e8;       --verb-patch-border: #274a75;  --verb-patch-bg: rgb(127 176 232 / 0.08);
  --verb-delete: #e87a7f;      --verb-delete-border: #6b272b; --verb-delete-bg: rgb(232 122 127 / 0.08);
}

/* ============ theme: midnight (cool dark) ============ */
body[data-theme="midnight"] {
  --bg: #0f1216;
  --bg-elev: #151a20;
  --bg-elev-2: #1b2128;
  --bg-hover: #1e252d;
  --border: #232b34;
  --border-strong: #2e3945;
  --text: #e8ecf1;
  --text-dim: #9aa7b4;
  --text-faint: #8896a4;
  --accent: #4c9eea;
  --accent-strong: #6fb3f2;
  --accent-rgb: 76 158 234;
  --accent-soft: rgb(var(--accent-rgb) / 0.14);
  --accent-faint: rgb(var(--accent-rgb) / 0.05);
  --accent-border: rgb(var(--accent-rgb) / 0.32);
  --accent-border-strong: rgb(var(--accent-rgb) / 0.6);
  --accent-focus-ring: rgb(var(--accent-rgb) / 0.28);
  --user-bg: #1a2027;
  --err-strong: #ff6369;
  --err-soft: rgb(var(--err-rgb) / 0.14);
  --err-bubble: rgb(var(--err-rgb) / 0.07);
  --err-bubble-border: rgb(var(--err-rgb) / 0.35);
  --err-code-bg: rgb(var(--err-rgb) / 0.14);
  --code-bg: #0b0e12;
  --code-head-bg: #11151a;
  --code-inline-bg: rgb(255 255 255 / 0.07);
  --code-btn-hover: #3d4a58;
  --scroll-thumb: #2a3440;
  --scroll-thumb-hover: #3a4755;
  --btn-disabled-bg: #262f39;
  --on-accent: #0b1117;
  --lb-bg: rgb(4 8 14 / 0.93);
  --scrim: rgb(4 8 14 / 0.62);
  --shadow-rgb: 4 8 14;
}

/* ============ theme: amoled (pure black) ============ */
body[data-theme="amoled"] {
  --bg: #000000;
  --bg-elev: #0a0a0a;
  --bg-elev-2: #141414;
  --bg-hover: #181818;
  --border: #1c1c1c;
  --border-strong: #2a2a2a;
  --text: #f2f2f2;
  --text-dim: #9b9b9b;
  --text-faint: #7f7f7f;
  --accent: #d97757;
  --accent-strong: #e08667;
  --accent-soft: rgb(var(--accent-rgb) / 0.14);
  --accent-faint: rgb(var(--accent-rgb) / 0.05);
  --accent-border: rgb(var(--accent-rgb) / 0.3);
  --accent-border-strong: rgb(var(--accent-rgb) / 0.6);
  --accent-focus-ring: rgb(var(--accent-rgb) / 0.28);
  --user-bg: #101010;
  --err-strong: #ff6369;
  --err-soft: rgb(var(--err-rgb) / 0.15);
  --err-bubble: rgb(var(--err-rgb) / 0.08);
  --err-bubble-border: rgb(var(--err-rgb) / 0.4);
  --err-code-bg: rgb(var(--err-rgb) / 0.16);
  --code-bg: #080808;
  --code-head-bg: #101010;
  --code-inline-bg: rgb(255 255 255 / 0.08);
  --code-btn-hover: #3a3a3a;
  --scroll-thumb: #222222;
  --scroll-thumb-hover: #333333;
  --btn-disabled-bg: #1e1e1e;
  --on-accent: #000000;
  --lb-bg: rgb(0 0 0 / 0.95);
  --scrim: rgb(0 0 0 / 0.7);
  --shadow-rgb: 0 0 0;
}

/* ============ theme: paper (light) ============
   Light done as a real composition, not an inverted dark: a deeper cream
   stage so warm-white surfaces genuinely elevate, one saturated rust accent,
   borders with actual presence, and shadows tinted warm-dark instead of grey. */
body[data-theme="paper"] {
  --bg: #f4f1ea;
  --bg-elev: #fffefb;
  --bg-elev-2: #ebe6dc;
  --bg-hover: #f0ece4;
  --border: #d9d2c4;
  --border-strong: #beb5a2;
  --text: #211e19;
  --text-dim: #5a554a;
  --text-faint: #6f6a5e;
  --accent: #bf4d26;
  --accent-strong: #a63e1c;
  --accent-rgb: 191 77 38;
  --accent-soft: rgb(var(--accent-rgb) / 0.1);
  --accent-faint: rgb(var(--accent-rgb) / 0.04);
  --accent-border: rgb(var(--accent-rgb) / 0.25);
  --accent-border-strong: rgb(var(--accent-rgb) / 0.5);
  --accent-focus-ring: rgb(var(--accent-rgb) / 0.28);
  --user-bg: #eae4d8;
  --ok: #2f9e44;
  --ok-rgb: 47 158 68;
  --warn: #b45309;
  --warn-rgb: 180 83 9;
  --err: #dc2626;
  --err-strong: #b91c1c;
  --err-rgb: 220 38 38;
  --err-soft: rgb(var(--err-rgb) / 0.1);
  --err-border: rgb(var(--err-rgb) / 0.45);
  --err-bubble: rgb(var(--err-rgb) / 0.05);
  --err-bubble-border: rgb(var(--err-rgb) / 0.3);
  --err-code-bg: rgb(var(--err-rgb) / 0.1);
  --code-bg: #eeeae1;
  --code-head-bg: #e6e1d5;
  --code-inline-bg: rgb(0 0 0 / 0.06);
  --code-btn-hover: #d6cfbf;
  --scroll-thumb: #c4bcae;
  --scroll-thumb-hover: #ada492;
  --btn-disabled-bg: #ded7c9;
  --on-accent: #ffffff;
  --logo-plate: #e9e6e1;
  --logo-plate-dark: #26241f;
  --lb-bg: rgb(31 30 28 / 0.9);
  --scrim: rgb(60 48 38 / 0.42);
  --shadow-rgb: 74 62 45;

  /* Glass needs near-opaque surfaces in light mode — the translucent recipe
     tuned for dark themes reads as a smudge over cream. */
  --glass-bg: color-mix(in srgb, var(--bg-elev) 90%, transparent);

  --verb-get: #1a6b33;    --verb-get-border: #a8d4b2;    --verb-get-bg: rgb(26 107 51 / 0.07);
  --verb-post: #8a4c07;   --verb-post-border: #e0c193;   --verb-post-bg: rgb(138 76 7 / 0.07);
  --verb-put: #5b2d82;    --verb-put-border: #d0b8e4;    --verb-put-bg: rgb(91 45 130 / 0.07);
  --verb-patch: #16457f;  --verb-patch-border: #a9c6e6;  --verb-patch-bg: rgb(22 69 127 / 0.07);
  --verb-delete: #9b1c1c; --verb-delete-border: #e5b4b4; --verb-delete-bg: rgb(155 28 28 / 0.07);
}

/* ============ elevation — shadows tinted by the theme's own hue ============ */
:root {
  --e1: 0 1px 2px rgb(var(--shadow-rgb) / 0.18);
  --e2: 0 4px 12px rgb(var(--shadow-rgb) / 0.22), 0 1px 2px rgb(var(--shadow-rgb) / 0.16);
  --e3: 0 12px 32px rgb(var(--shadow-rgb) / 0.32), 0 2px 6px rgb(var(--shadow-rgb) / 0.2);
  --e4: 0 20px 48px rgb(var(--shadow-rgb) / 0.4), 0 4px 12px rgb(var(--shadow-rgb) / 0.24);
  /* glassmorphism */
  --glass-bg: color-mix(in srgb, var(--bg-elev) 72%, transparent);
  --glass-border: color-mix(in srgb, var(--border-strong) 60%, transparent);
  --glass-blur: 14px;
  /* Lightbox chrome always sits on the dark --lb-bg scrim, so its buttons are
     white-on-dark in every theme. Declared once instead of per rule. */
  --lb-chrome-bg: rgb(255 255 255 / 0.06);
  --lb-chrome-bg-hover: rgb(255 255 255 / 0.16);
  --lb-chrome-border: rgb(255 255 255 / 0.2);
  --lb-chrome-fg: #fff;
  --lb-chrome-dim: rgb(255 255 255 / 0.7);
  --lb-count-bg: rgb(0 0 0 / 0.4);
  /* Composer geometry, published so the jump button and toast can sit above it
     without re-encoding its rendered height. */
  --composer-h: 88px;
  /* Fixed brand colours — Discord's own palette, identical in every theme, and
     the white that saturated fills (error badges, generated avatars) need
     regardless of the surface under them. */
  --discord: #5865F2;
  --discord-strong: #4752C4;
  --discord-rgb: 88 101 242;
  --on-solid: #fff;
}

/* ============ base reset ============ */
* { box-sizing: border-box; }

::selection { background: var(--accent-soft); color: var(--text); }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: 6px; border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover); }
::-webkit-scrollbar-track { background: transparent; }

html { scroll-behavior: smooth; }

/* ============ utility: monospace ============
   Was defined only as `.tbl .mono` / `.model-row .mono` inside admin.html, so
   the same class silently did nothing outside those two scopes. */
.mono { font-family: var(--mono); }

/* ============ utility: screen-reader-only text ============ */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ============ utility: stagger delays for scroll reveals ============ */
/* Was six --stagger custom properties that nothing ever read. This version is
   a real utility: put .stagger on the container and its children sequence
   themselves off --stagger-step, so the rhythm lives in one token. */
.stagger > *:nth-child(1) { transition-delay: 0s; }
.stagger > *:nth-child(2) { transition-delay: calc(var(--stagger-step) * 1); }
.stagger > *:nth-child(3) { transition-delay: calc(var(--stagger-step) * 2); }
.stagger > *:nth-child(4) { transition-delay: calc(var(--stagger-step) * 3); }
.stagger > *:nth-child(5) { transition-delay: calc(var(--stagger-step) * 4); }
.stagger > *:nth-child(6) { transition-delay: calc(var(--stagger-step) * 5); }
.stagger > *:nth-child(7) { transition-delay: calc(var(--stagger-step) * 6); }
.stagger > *:nth-child(n + 8) { transition-delay: calc(var(--stagger-step) * 7); }

/* Single focus contract for the whole product. Never remove an outline
   without putting one back — five places used to do exactly that. */
:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

.skip-link {
  position: absolute; left: var(--sp-2); top: var(--sp-2);
  z-index: var(--z-toast);
  transform: translateY(-200%);
  background: var(--bg-elev-2); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: var(--r-sm);
  padding: var(--sp-2) var(--sp-4);
  font: var(--wt-semi) var(--fs-sm) / 1 var(--font);
  text-decoration: none;
  transition: transform var(--dur) var(--ease);
}
.skip-link:focus-visible { transform: none; }

/* ============ grain overlay — breaks digital flatness, no external asset ==== */
.grain {
  position: fixed; inset: 0; z-index: 1;
  pointer-events: none; opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}
body[data-theme="paper"] .grain { opacity: 0.03; mix-blend-mode: multiply; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
