/* ============================================================
   opgate design system — TOKENS
   ------------------------------------------------------------
   The single source of design values. Light is default; dark is
   at parity via [data-theme="dark"] on <html> (or any ancestor).
   Link this first, then components.css.

   Voice: Blueprint crispness on the cool ground · Avenir display ·
   the logo's slash · colour rationed to meaning. The load-bearing
   security semantics live in the verdict / gate / sensitivity
   token groups below — restyle surfaces freely, never their roles.
   ============================================================ */


/* ===================== LIGHT (default) ===================== */
:root{
  /* ---- brand (locked: two colours, nothing else identity-level) ---- */
  --blue:#1f22e8;          /* electric royal — scarce, load-bearing */
  --blue-700:#181acc;      /* hover */
  --blue-300:#6e70ef;
  --blue-tint:#eeeefd;     /* pale wash */
  --ink:#231f20;           /* off-black — wordmark + structure */

  /* ---- surfaces: Steel cool ground, Blueprint crisp panels ---- */
  --bg:#eef1f7;            /* the cool ground */
  --bg-room-1:#f7f9ff;     /* top-left cool glow (page gradient) */
  --bg-room-2:#e6ebf7;     /* top-right cool */
  --bg-room-3:#e9edf5;     /* base */
  --panel:#ffffff;         /* card / panel */
  --panel-2:#f6f8fc;       /* nested surface */
  --panel-inset:#eef1f7;   /* recessed well */
  --field:#ffffff;         /* inputs */

  /* ---- lines + elevation (hairlines carry structure) ---- */
  --border:rgba(40,46,78,.12);
  --hairline:rgba(40,46,78,.10);
  --border-strong:rgba(40,46,78,.22);
  --shadow-1:0 1px 2px rgba(35,40,70,.05);     /* card */
  --shadow-2:0 4px 14px -6px rgba(35,40,70,.18); /* popover */
  --shadow-3:0 12px 30px -8px rgba(35,40,70,.24);
  --shadow-pop:0 16px 40px -10px rgba(35,40,70,.30); /* modal */

  /* ---- text ---- */
  --t1:#1a1d2b;  /* primary */
  --t2:#41465c;  /* secondary */
  --t3:#5d6378;  /* tertiary / metadata */
  --t-dis:#9aa0b4;
  --on-accent:#ffffff;
  --link:var(--blue);

  /* ---- accent = opportunity / interactive / selected (never risk) ---- */
  --accent:var(--blue); --accent-700:var(--blue-700); --accent-soft:var(--blue-tint);

  /* ---- VERDICT (event channel): allowed / prompted / denied ---- */
  /* "Verdict" because "decision" is kept for choices people make (README → Decisions). */
  --verdict-allow:#15a34a;  --verdict-allow-bg:#e7f6ec;
  --verdict-prompt:#e0a800; --verdict-prompt-bg:#fbf2d8;    /* yellow, not orange */
  --verdict-deny:#d92d20;   --verdict-deny-bg:#fbe5e3;
  /* Old names kept as aliases because opgate/web still reads them. */
  --allow:var(--verdict-allow);   --allow-bg:var(--verdict-allow-bg);
  --prompt:var(--verdict-prompt); --prompt-bg:var(--verdict-prompt-bg);
  --deny:var(--verdict-deny);     --deny-bg:var(--verdict-deny-bg);
  --viz:#15a34a;                            /* throughput / "flowed clean" */
  /* extended verdict states (console) */
  --tainted:#7c2d12; --tainted-bg:#fbe9dc;  /* rust */
  --verified:var(--blue); --verified-bg:var(--blue-tint);
  --expired:#737373; --expired-bg:#ececea;
  --inflight:#1e40af; --inflight-bg:#e0e7ff;

  /* ---- GATE POSTURE (carried by SHAPE; colour only reinforces) ---- */
  --hard:#3a4a78;   /* cool steel — authority, NOT alarm (not red) */
  --soft:#e0a800;   /* amber — permitted but judged */
  --watch:#8a8f9e;  /* desaturated ghost */

  /* ---- SENSITIVITY — the ONLY warm/saturated mark (secret/NDA/PII) ---- */
  --sens:#b3261e; --sens-fg:#9a1b14; --sens-bg:rgba(179,38,30,.08); --sens-border:rgba(179,38,30,.30);

  /* ---- SEVERITY — distinct hue + value + glyph, never one ramp ---- */
  --sev-crit:#7c0a0a; --sev-crit-bg:#fbe9e9;   /* oxblood ◆ */
  --sev-high:#b91c1c; --sev-high-bg:#fdecec;   /* red ▲ */
  --sev-med:#b45309;  --sev-med-bg:#fef6e7;    /* amber ■ */
  --sev-low:#4d5c2e;  --sev-low-bg:#f3f5e8;    /* olive ● (deliberately not green) */
  --sev-info:#525252; --sev-info-bg:#ececea;   /* graphite (never blue) */

  /* ---- friction meter — its own neutral channel ---- */
  --fill:#6b7188; --fill-track:rgba(40,46,78,.12);

  /* ---- mlld syntax highlighting ---- */
  --syn-bg:#f6f8fc; --syn-fg:#1a1d2b; --syn-comment:#8a90a4; --syn-kw:#7c2d12;
  --syn-str:#1f5f3a; --syn-num:#4d5c2e; --syn-builtin:var(--blue); --syn-var:#5b21b6;

  /* ---- radius (restrained: max 6px; pills excepted) ---- */
  --r-1:3px; --r-2:4px; --r-3:6px; --r-pill:999px;

  /* ---- spacing (4px base) ---- */
  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:20px; --s-6:24px; --s-8:32px; --s-10:40px;

  /* ---- type ---- */
  --display:"Avenir Next","Avenir","Inter Tight",system-ui,sans-serif; /* headings */
  --body:"Inter Tight",system-ui,-apple-system,sans-serif;             /* body + UI */
  --mono:"JetBrains Mono",ui-monospace,monospace;                      /* code, ids, tabular */
  --serif:"Charter","Iowan Old Style","Georgia",serif;                 /* quoted people only: a voice that isn't ours */
  --fs-display:32px; --fs-h1:24px; --fs-h2:19px; --fs-h3:16px;
  --fs-body:15px; --fs-sm:13px; --fs-cap:12px; --fs-eyebrow:10.5px;
  /* responsive display sizes (marketing / hero surfaces) */
  --fs-hero:clamp(2.5rem,6vw,4.25rem); --fs-h1-fluid:clamp(2rem,4vw,3.25rem); --fs-h2-fluid:clamp(1.5rem,2.4vw,2.25rem);

  /* ---- density (comfortable default; compact/dense opt-in per container) ---- */
  --row-h:44px; --row-pad-x:16px;

  /* ---- motion (adopted from tailor; all sub-300ms) ---- */
  --ease-out:cubic-bezier(.22,1,.36,1);     /* arrivals */
  --ease-spring:cubic-bezier(.34,1.25,.64,1); /* toggle thumb only */
  --ease-in-out:cubic-bezier(.45,0,.25,1);  /* dismissals */
  --dur-1:120ms; --dur-2:180ms; --dur-3:260ms;

  /* ---- the slash (logo cut → system motif) ---- */
  --slash:repeating-linear-gradient(135deg,
     color-mix(in srgb,var(--blue) 50%,transparent) 0 1.5px, transparent 1.5px 7px);
}

/* ===================== DARK (parity) ===================== */
[data-theme="dark"]{
  --bg:#0b0c10;
  --bg-room-1:#141826; --bg-room-2:#0e1018; --bg-room-3:#0a0a0d;
  --panel:#14161d; --panel-2:#181b24; --panel-inset:#101218; --field:#161922;

  --border:rgba(180,190,225,.13);
  --hairline:rgba(180,190,225,.09);
  --border-strong:rgba(180,190,225,.26);
  --shadow-1:0 1px 2px rgba(0,0,0,.5);
  --shadow-2:0 4px 14px -6px rgba(0,0,0,.6);
  --shadow-3:0 12px 30px -8px rgba(0,0,0,.6);
  --shadow-pop:0 16px 40px -10px rgba(0,0,0,.7);

  --t1:#e9eaf2; --t2:#a8adc1; --t3:#80869c; --t-dis:#565c70;
  --on-accent:#0b0c10;  /* dark text on the dark-mode accent reads at 5.1:1; white is 3.8:1 */

  --blue:#6e72ff; --blue-700:#5a5ef5; --blue-300:#9b9eff; --blue-tint:rgba(110,114,255,.16);
  --accent:var(--blue); --accent-700:var(--blue-700); --accent-soft:var(--blue-tint);

  --verdict-allow:#45c97f;  --verdict-allow-bg:rgba(69,201,127,.13);
  --verdict-prompt:#f1c049; --verdict-prompt-bg:rgba(241,192,73,.14);
  --verdict-deny:#f3796b;   --verdict-deny-bg:rgba(243,121,107,.14);
  /* Re-declared so a dark subtree resolves the aliases against its own verdict values, not the light ones inherited from :root. */
  --allow:var(--verdict-allow);   --allow-bg:var(--verdict-allow-bg);
  --prompt:var(--verdict-prompt); --prompt-bg:var(--verdict-prompt-bg);
  --deny:var(--verdict-deny);     --deny-bg:var(--verdict-deny-bg);
  --viz:#45c97f;
  --tainted:#fb923c; --tainted-bg:rgba(251,146,60,.12);
  --verified:#9b9eff; --verified-bg:rgba(110,114,255,.16);
  --expired:#767c92; --expired-bg:rgba(118,124,146,.16);
  --inflight:#93c5fd; --inflight-bg:rgba(147,197,253,.12);

  --hard:#8fa0d6; --soft:#f1c049; --watch:#8a8f9e;

  --sens:#ff7a6e; --sens-fg:#ff8f84; --sens-bg:rgba(255,122,110,.12); --sens-border:rgba(255,122,110,.34);

  --sev-crit:#fb7185; --sev-crit-bg:rgba(251,113,133,.12);
  --sev-high:#f87171; --sev-high-bg:rgba(248,113,113,.12);
  --sev-med:#fbbf24;  --sev-med-bg:rgba(251,191,36,.12);
  --sev-low:#c5cf9c;  --sev-low-bg:rgba(197,207,156,.10);
  --sev-info:#a3a3a3; --sev-info-bg:rgba(163,163,163,.12);

  --fill:#8089a3; --fill-track:rgba(180,190,225,.13);

  --syn-bg:#101218; --syn-fg:#e9eaf2; --syn-comment:#767c92; --syn-kw:#fb923c;
  --syn-str:#86efac; --syn-num:#c5cf9c; --syn-builtin:#9b9eff; --syn-var:#c4b5fd;
}

/* ===================== DECISIONS =====================
   Tokens for the decision-review screens (README → Decisions).
   Accent and the blocking yellow reuse --accent and --verdict-prompt so a
   decision UI and the console never disagree on what those mean.
   Green is split from --verdict-allow on purpose: in decision review it only
   ever means "your own pick" or a GitHub PR state, and keeping it a
   separate token stops it drifting into a generic "success" colour. */
:root{
  /* Blocking: the dot and the thing being blocked (a PR address, a plan title). */
  --blocking:var(--verdict-prompt);
  /* Yellow text on white fails contrast, so text takes a deeper amber in light. */
  --blocking-fg:#8a6200;

  /* A reviewer's own pick on a decision that is still open. A step deeper than GitHub's green so it holds 4.5:1 on its own tint. */
  --yours:#18762f; --yours-bg:#e8f3eb;

  /* GitHub's own PR state colours, so a PR reads the way it does on GitHub. */
  --gh-open:#1a7f37; --gh-draft:#59636e; --gh-merged:#8250df; --gh-closed:#d1242f;

  /* The dark-mode accent and green are light, so a check drawn on them flips to dark to stay visible. */
  --on-mark:#ffffff;

  /* Agent sessions: one colour per session, dark type on top for both themes. */
  --agent-1:#7f84f5; --agent-2:#5aa3d4; --agent-3:#b67ad4;
  --agent-4:#949fb3; --agent-5:#7ea3ba; --agent-6:#a294d6;
  --on-agent:#0b0c10;

  /* People: one colour per person, white initials. Mid-value so they hold on both grounds. */
  --on-person:#ffffff;
  --person-1:#5b5fd9; --person-2:#3e7cb1; --person-3:#8a4fa3;
  --person-4:#5c6b82; --person-5:#a25a72; --person-6:#4f7f8c;

  /* Tag (label) palette. Tags are labels people define, so they are the one exception to colour rationing:
     the palette has blues next to the accent and reds, greens and yellows near the signal colours, and that is accepted.
     A tag colour names a topic; never use one to signal status. */
  --tag-1:#6e8bff; --tag-2:#c58be0; --tag-3:#4fb3c9; --tag-4:#e08b6e;
  --tag-5:#d98bb0; --tag-6:#8fb86e; --tag-7:#b8a36e; --tag-8:#a5b0c2;
  --tag-9:#e06e6e; --tag-10:#9a8be0; --tag-11:#6ec9a0; --tag-12:#c9b46e;
  /* Light grounds need the label ink darkened toward text colour to stay readable. */
  --tag-ink-mix:52%; --tag-fill-mix:14%; --tag-line-mix:45%;
}
[data-theme="dark"]{
  --blocking:var(--verdict-prompt); --blocking-fg:var(--verdict-prompt);
  --yours:#3fb950; --yours-bg:rgba(63,185,80,.10);
  --gh-open:#3fb950; --gh-draft:#8b949e; --gh-merged:#a371f7; --gh-closed:#f85149;
  --on-mark:#0b0c10;
  --agent-1:#8e92ff; --agent-2:#6fb4e0; --agent-3:#c58be0;
  --agent-4:#a5b0c2; --agent-5:#8fb3c9; --agent-6:#b4a6e0;
  --tag-ink-mix:100%; --tag-fill-mix:18%; --tag-line-mix:45%;
}

/* ===================== GROUNDS =====================
   Cool is the default ground. Paper is the warm alternative from the pitch
   decks: set data-ground="paper" on any container (a page, a deck, one slide).
   data-ground="cool" puts a container back on the default inside a paper one.
   A ground swaps surfaces and text only, so every signal colour keeps its
   meaning. Both pair with data-theme="dark". */
[data-ground="paper"]{
  --bg:#f4f3ef;
  --bg-room-1:#f8f7f4; --bg-room-2:#f1f0ea; --bg-room-3:#f2f1ec;
  --panel:#fbfaf7; --panel-2:#f7f6f2; --panel-inset:#ecebe5; --field:#fdfcfa;
  --border:rgba(35,31,32,.10); --hairline:rgba(35,31,32,.08); --border-strong:rgba(35,31,32,.20);
  --shadow-1:0 1px 2px rgba(35,31,32,.04); --shadow-2:0 4px 14px -6px rgba(35,31,32,.16);
  --shadow-3:0 12px 30px -8px rgba(35,31,32,.22); --shadow-pop:0 16px 40px -10px rgba(35,31,32,.28);
  --t1:#121110; --t2:#3b3a37; --t3:#6d6c67; --t-dis:#a3a19a;
  --fill:#6d6c67; --fill-track:rgba(35,31,32,.10); --syn-bg:#f7f6f2;
}
[data-ground="paper"][data-theme="dark"],
[data-theme="dark"] [data-ground="paper"],
[data-ground="paper"] [data-theme="dark"]{
  --bg:#16171b;
  --bg-room-1:#1b1c21; --bg-room-2:#15161a; --bg-room-3:#131417;
  --panel:#1e1f24; --panel-2:#23242a; --panel-inset:#121316; --field:#1e1f24;
  --border:rgba(236,234,226,.12); --hairline:rgba(236,234,226,.08); --border-strong:rgba(236,234,226,.24);
  --t1:#f5f4f0; --t2:#c9c7c0; --t3:#8f8d86; --t-dis:#5f5e59;
  --fill:#8f8d86; --fill-track:rgba(236,234,226,.12); --syn-bg:#121316;
}
[data-ground="cool"]{
  --bg:#eef1f7;
  --bg-room-1:#f7f9ff; --bg-room-2:#e6ebf7; --bg-room-3:#e9edf5;
  --panel:#ffffff; --panel-2:#f6f8fc; --panel-inset:#eef1f7; --field:#ffffff;
  --border:rgba(40,46,78,.12); --hairline:rgba(40,46,78,.10); --border-strong:rgba(40,46,78,.22);
  --shadow-1:0 1px 2px rgba(35,40,70,.05); --shadow-2:0 4px 14px -6px rgba(35,40,70,.18);
  --shadow-3:0 12px 30px -8px rgba(35,40,70,.24); --shadow-pop:0 16px 40px -10px rgba(35,40,70,.30);
  --t1:#1a1d2b; --t2:#41465c; --t3:#5d6378; --t-dis:#9aa0b4;
  --fill:#6b7188; --fill-track:rgba(40,46,78,.12); --syn-bg:#f6f8fc;
}
[data-ground="cool"][data-theme="dark"],
[data-theme="dark"] [data-ground="cool"],
[data-ground="cool"] [data-theme="dark"]{
  --bg:#0b0c10;
  --bg-room-1:#141826; --bg-room-2:#0e1018; --bg-room-3:#0a0a0d;
  --panel:#14161d; --panel-2:#181b24; --panel-inset:#101218; --field:#161922;
  --border:rgba(180,190,225,.13); --hairline:rgba(180,190,225,.09); --border-strong:rgba(180,190,225,.26);
  --t1:#e9eaf2; --t2:#a8adc1; --t3:#767c92; --t-dis:#565c70;
  --fill:#8089a3; --fill-track:rgba(180,190,225,.13); --syn-bg:#101218;
}

/* ===================== DENSITY (apply to a container) ===================== */
[data-density="comfortable"]{--row-h:44px; --row-pad-x:16px}  /* forms, settings, reading */
[data-density="compact"]{--row-h:36px; --row-pad-x:12px}      /* primary tables, log viewers */
[data-density="dense"]{--row-h:28px; --row-pad-x:8px}         /* power-user, toggleable, never default */

/* ===================== MOTION KEYFRAMES ===================== */
@keyframes view-in{from{opacity:0;transform:translateY(6px)}}
@keyframes line-in{from{opacity:0;transform:translateY(4px)}}
@keyframes pop-in{from{opacity:0;transform:translateY(4px) scale(.98)}}
@keyframes toast-in{from{opacity:0;transform:translate(0,12px)}}
@keyframes row-out{to{opacity:0;max-height:0;padding-top:0;padding-bottom:0}}
@keyframes shimmer{from{background-position:200% 0}to{background-position:-200% 0}}
@keyframes stroke-in{to{stroke-dashoffset:0}}
@keyframes pulse{50%{transform:scale(1.5);opacity:.35}}
@keyframes ty{40%{transform:translateY(-3px);opacity:1}}
@keyframes spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001ms !important;transition-duration:.001ms !important}
}

/* ===================== BASE RESET + PAGE GROUND ===================== */
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  font-family:var(--body);color:var(--t1);background:var(--bg);
  font-size:var(--fs-body);-webkit-font-smoothing:antialiased;
  background-image:
    radial-gradient(120% 720px at 12% 0%, var(--bg-room-1) 0%, transparent 60%),
    radial-gradient(120% 760px at 100% 0%, var(--bg-room-2) 0%, transparent 62%),
    linear-gradient(180deg, var(--bg) 0%, var(--bg-room-3) 60%);
  background-repeat:no-repeat;min-height:100vh;
}

/* ===================== TYPE HELPERS ===================== */
.t-hero{font-family:var(--display);font-weight:800;font-size:var(--fs-hero);letter-spacing:-.025em;line-height:1.04}     /* marketing hero */
.t-h1-fluid{font-family:var(--display);font-weight:700;font-size:var(--fs-h1-fluid);letter-spacing:-.02em;line-height:1.08}
.t-display{font-family:var(--display);font-weight:700;font-size:var(--fs-display);letter-spacing:-.02em;line-height:1.08}
.t-h1{font-family:var(--display);font-weight:700;font-size:var(--fs-h1);letter-spacing:-.02em;line-height:1.12}
.t-h2{font-family:var(--display);font-weight:700;font-size:var(--fs-h2);letter-spacing:-.015em}
.t-h3{font-family:var(--display);font-weight:600;font-size:var(--fs-h3);letter-spacing:-.01em}
.t-body{font-size:var(--fs-body)}
.t-sm{font-size:var(--fs-sm)}
.t-cap{font-size:var(--fs-cap);color:var(--t3)}
.t-eyebrow{font-family:var(--mono);font-size:var(--fs-eyebrow);font-weight:500;letter-spacing:.10em;text-transform:uppercase;color:var(--t3)}
.t-mono{font-family:var(--mono);font-variant-numeric:tabular-nums}
.t-num{font-variant-numeric:tabular-nums}
