/* ============================================================================
   Connect Next — one token file + primitives.   Spec: docs/DESIGN_SYSTEM.md
   Ticket E3.2. Load this FIRST, before any page <style>.

   Rules (see §8 of the spec):
     - No page defines its own :root. A page may alias legacy names (§ COMPAT).
     - No numeric z-index. Use the scale.
     - !important is a bug.
     - One button system: .btn + one variant + optional size.
   ========================================================================== */

:root {
  /* ---- Ink ------------------------------------------------------------- */
  --bg:            #0B0C0E;
  --bg-2:          #131417;
  --bg-3:          #1B1D21;
  --bg-4:          #202227;   /* fifth layer: landing cards on --bg-3 */
  --border:        #24262B;
  --chip:          #1F2126;
  --fg:            #ECEDEE;
  --muted:         #9BA1A8;
  --accent:        #7FB2E8;
  --accent-ink:    #0B0C0E;

  /* Named aliases of the same four dark layers. Prefer --bg/-2/-3/--border. */
  --ink-900: var(--bg);
  --ink-800: var(--bg-2);
  --ink-700: var(--bg-3);
  --ink-600: var(--border);

  /* ---- Model identity: the brand. An information channel, not decoration. */
  --gpt:      #74AA9C;
  --claude:   #D8A869;
  --grok:     #9D7CCE;
  --gemini:   #4285F4;
  --deepseek: #FF6B6B;
  /* Deprecated spellings kept so the migration didn't touch every rule. */
  --gpt-color:    var(--gpt);
  --claude-color: var(--claude);
  --grok-color:   var(--grok);
  --google-color: var(--gemini);
  --deepseek-color: var(--deepseek);

  /* ---- Semantic -------------------------------------------------------- */
  --success: #46C16B;
  --warn:    #F5C542;
  --danger:  #FF6B6B;
  --verdict-ok:      var(--success);
  --verdict-watch:   var(--warn);
  --verdict-dispute: var(--danger);

  /* Chat-surface accents (index) */
  --cursor: #9BE0FF;
  --hl:     #233B55;

  /* ---- Type ------------------------------------------------------------ */
  --font-display: 'Space Grotesk', system-ui, -apple-system, sans-serif;
  --font-body:    'Geist', 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --t-xs:   11px;
  --t-sm:   12.5px;
  --t-base: 14px;
  --t-md:   16px;
  --t-lg:   20px;
  --t-xl:   26px;
  --t-2xl:  34px;
  --t-3xl:  46px;
  --measure: 72ch;

  /* ---- Space / radius / depth ------------------------------------------ */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px;

  --r-sm: 6px; --r-md: 10px; --r-lg: 16px; --r-full: 999px;

  --shadow-panel: 0 12px 40px rgba(0,0,0,.45);
  --shadow-pop:   0 6px 20px rgba(0,0,0,.35);

  /* ---- z-index scale. Never write a number. ----------------------------
     A backdrop always sits exactly one layer under the thing it dims. */
  --z-base: 0;
  --z-layer-1: 1;          /* inside one component's own stacking context */
  --z-layer-2: 2;
  --z-raised: 10;          /* sticky row inside a scroller */
  --z-sticky: 100;         /* topbar, composer */
  --z-drawer-backdrop: 150;
  --z-drawer: 200;         /* sidebar, fixed page nav */
  --z-dropdown: 300;       /* overflow menu, mention picker */
  --z-panel-backdrop: 450;
  --z-panel: 500;          /* trace / Council / cost / settings panels */
  --z-modal-backdrop: 550;
  --z-modal: 600;          /* dialogs, upgrade modal, lightbox */
  --z-toast: 700;
  --z-tooltip: 800;        /* mode tips, citation popovers */

  /* ---- Motion ---------------------------------------------------------- */
  --dur-1: 120ms;
  --dur-2: 240ms;
  --ease: cubic-bezier(.2,.7,.2,1);
}

/* Light is defined, not exposed: no page ships a toggle. Inspect with
   <html data-theme="light">. Component rules that hardcode rgba(255,255,255,…)
   overlays have NOT been audited against it — see spec §1. */
:root[data-theme="light"] {
  --bg: #FBFBFC;  --bg-2: #F3F4F6; --bg-3: #E9EAEE; --bg-4: #DFE1E6;
  --border: #D8DAE0; --chip: #ECEDF1;
  --fg: #14161A;  --muted: #5C636D;
  --accent: #2C6FB5; --accent-ink: #FFFFFF;
  --gpt: #3F6E63; --claude: #8A6320; --grok: #6A4E96;
  /* Semantics darken too — the dark-mode greens/ambers are invisible on white.
     Values chosen to clear AA on --bg AND on --bg-3. */
  --success: #26743D; --warn: #7E5D06; --danger: #C62828;
  --shadow-panel: 0 12px 40px rgba(20,22,26,.16);
  --shadow-pop:   0 6px 20px rgba(20,22,26,.12);
}

/* ============================================================================
   Base
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: var(--t-base);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, .u-display { font-family: var(--font-display); font-weight: 600; }
h1 { font-size: var(--t-2xl); line-height: 1.15; }
h2 { font-size: var(--t-xl);  line-height: 1.25; }
h3 { font-size: var(--t-lg);  line-height: 1.35; }

pre, code, kbd, samp { font-family: var(--font-mono); }

/* Numbers a user compares must align. */
.u-num, .cost, .tokens, .latency {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.u-eyebrow {
  font-family: var(--font-display);
  font-size: var(--t-xs);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
}

a { color: var(--accent); }

button { font: inherit; cursor: pointer; }

/* One focus style in the product. Never removed. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}
:focus:not(:focus-visible) { outline: none; }

/* A hard requirement, not a nicety. Every state must be legible statically. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================================
   Button — .btn + variant + size. Nothing else.
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  height: 34px;
  padding: 0 var(--sp-4);
  font-family: var(--font-body);
  font-size: var(--t-base);
  font-weight: 500;
  color: var(--fg);
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  cursor: pointer;
  transition: background var(--dur-1) var(--ease),
              border-color var(--dur-1) var(--ease),
              transform var(--dur-1) var(--ease);
  white-space: nowrap;
}
.btn:hover { border-color: var(--muted); }
.btn:active { transform: translateY(1px); }

.btn-primary {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: transparent;
  font-weight: 600;
}
.btn-primary:hover { filter: brightness(1.08); border-color: transparent; }
.btn-primary:active { filter: brightness(.94); }

.btn-danger { background: transparent; color: var(--danger); border-color: var(--danger); }
.btn-danger:hover { background: var(--danger); color: #fff; }

.btn-sm { height: 28px; padding: 0 var(--sp-3); font-size: var(--t-sm); }
.btn-lg { height: 42px; padding: 0 var(--sp-5); font-size: var(--t-md); }

.btn-icon { width: 34px; height: 34px; padding: 0; }
.btn-icon.btn-sm { width: 28px; height: 28px; }

.btn[disabled], .btn[aria-disabled="true"] {
  opacity: .45;
  cursor: not-allowed;
  pointer-events: none;
}

/* Loading keeps the label so the button never changes width. */
.btn[aria-busy="true"] { pointer-events: none; }
.btn[aria-busy="true"]::before {
  content: "";
  width: 12px; height: 12px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: var(--r-full);
  animation: ui-spin .7s linear infinite;
}
@keyframes ui-spin { to { transform: rotate(360deg); } }

/* Gated ≠ disabled: a tier-locked control must stay clickable, because the
   click is what opens the upgrade modal. Disabled is for *temporarily*
   unavailable. See spec §5. */
.is-gated {
  opacity: .4;
  cursor: not-allowed;
}

@media (pointer: coarse) {
  .btn { min-height: 40px; }
  .btn-icon { min-width: 40px; }
}

/* ============================================================================
   Input / Card / Chip / Modal
   ========================================================================== */

.input {
  width: 100%;
  height: 34px;
  padding: 0 var(--sp-3);
  color: var(--fg);
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font-family: var(--font-body);
  font-size: var(--t-base);
  transition: border-color var(--dur-1) var(--ease);
}
.input:hover { border-color: var(--muted); }
.input:focus-visible { border-color: var(--accent); }
.input::placeholder { color: var(--muted); }
.input[disabled] { opacity: .5; cursor: not-allowed; }
.input[aria-invalid="true"] { border-color: var(--danger); }

/* Colour is never the only signal — pair with a role="alert" sibling. */
.input-error { color: var(--danger); font-size: var(--t-sm); margin-top: var(--sp-1); }

.card {
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-4);
}
.card-link { cursor: pointer; transition: border-color var(--dur-1) var(--ease); }
.card-link:hover { border-color: var(--muted); }
.card-empty { color: var(--muted); text-align: center; padding: var(--sp-6) var(--sp-4); }
.card-empty h3 { color: var(--fg); margin: 0 0 var(--sp-2); }
.card-error { border-top: 1px solid var(--danger); }

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: 2px var(--sp-2);
  background: var(--chip);
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  font-size: var(--t-xs);
  color: var(--muted);
}
.chip-ok      { color: var(--verdict-ok);      border-color: color-mix(in srgb, var(--verdict-ok) 40%, var(--border)); }
.chip-watch   { color: var(--verdict-watch);   border-color: color-mix(in srgb, var(--verdict-watch) 40%, var(--border)); }
.chip-dispute { color: var(--verdict-dispute); border-color: color-mix(in srgb, var(--verdict-dispute) 40%, var(--border)); }

.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,.6);
  z-index: var(--z-modal-backdrop);
}
.modal {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: min(560px, calc(100vw - var(--sp-6)));
  max-height: calc(100vh - var(--sp-6));
  overflow-y: auto;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-panel);
  padding: var(--sp-5);
  z-index: var(--z-modal);
}

/* ============================================================================
   Shared header (E3.1)
   ========================================================================== */

.app-header {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  height: 52px;
  padding: 0 var(--sp-4);
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
}
.app-header .brand {
  display: flex; align-items: center; gap: var(--sp-2);
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--fg);
  text-decoration: none;
}
/* The council mark: three models, one answer. */
.brand-dots { display: inline-flex; gap: 3px; }
.brand-dots i { width: 7px; height: 7px; border-radius: var(--r-full); display: block; }
.brand-dots i:nth-child(1) { background: var(--gpt); }
.brand-dots i:nth-child(2) { background: var(--claude); }
.brand-dots i:nth-child(3) { background: var(--grok); }

.app-header nav { display: flex; gap: var(--sp-1); margin-left: var(--sp-3); }
.app-header nav a {
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  color: var(--muted);
  text-decoration: none;
  font-size: var(--t-base);
}
.app-header nav a:hover { color: var(--fg); background: var(--bg-2); }
.app-header nav a[aria-current="page"] { color: var(--fg); background: var(--bg-3); }

.app-header .spacer { flex: 1; }

.user-pill {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-2) var(--sp-1) var(--sp-1);
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  color: var(--fg);
  text-decoration: none;
  font-size: var(--t-sm);
}
.user-pill:hover { border-color: var(--muted); }
.user-pill img, .user-pill .avatar {
  width: 24px; height: 24px; border-radius: var(--r-full);
  display: grid; place-items: center;
  background: var(--bg-3); color: var(--muted);
  font-size: var(--t-xs); font-weight: 600;
  object-fit: cover;
}
.tier-badge {
  font-size: var(--t-xs);
  padding: 1px var(--sp-2);
  border-radius: var(--r-full);
  background: var(--chip);
  color: var(--muted);
}
.tier-badge[data-tier="pro"] { background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--accent); }

@media (max-width: 640px) {
  .app-header nav { display: none; }
  .app-header { gap: var(--sp-2); }
}

/* Utilities */
.u-hidden { display: none !important; }         /* the one legitimate !important */
.u-sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.u-scroll-x { overflow-x: auto; }
