/* Kappino Control Center — operator console.
 *
 * Dark-first on purpose: this screen is read at 2am and left open on a wall
 * display. The light variant exists for daytime desks and is a re-mapping of
 * the same tokens, not an inversion — status colours are re-picked per ground
 * so amber stays legible on white.
 *
 * Status colour is reserved EXCLUSIVELY for state. The interactive accent is a
 * different hue so "this is clickable" can never be mistaken for "this is fine".
 */
:root {
  --bg:#0d1014; --panel:#141920; --panel-2:#1a2029; --raised:#1f2731;
  --line:#232b36; --line-2:#2f3947;
  --ink:#dfe5ec; --muted:#8a95a5; --faint:#5d6773;
  --accent:#4d9fff; --accent-dim:#16283f;
  --ok:#3fb950; --ok-bg:#122117;
  --warn:#d29922; --warn-bg:#20180a;
  --degraded:#db8a3c; --degraded-bg:#211609;
  --crit:#f85149; --crit-bg:#241214;
  --unknown:#6e7681; --unknown-bg:#181c22;
  --mono:ui-monospace,"SFMono-Regular","JetBrains Mono","Menlo","Consolas",monospace;
  --sans:system-ui,-apple-system,"Segoe UI","Inter",sans-serif;
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg:#f4f6f8; --panel:#ffffff; --panel-2:#f7f9fb; --raised:#eef2f6;
    --line:#dde3ea; --line-2:#c8d2dd;
    --ink:#12181f; --muted:#5b6774; --faint:#8492a1;
    --accent:#0b62d0; --accent-dim:#e3edfb;
    --ok:#1a7f37; --ok-bg:#e8f5ec;
    --warn:#8a6100; --warn-bg:#fdf3dd;
    --degraded:#9a5417; --degraded-bg:#fdeede;
    --crit:#c02c26; --crit-bg:#fdeceb;
    --unknown:#6b7683; --unknown-bg:#eef1f4;
  }
}
:root[data-theme="light"] {
  --bg:#f4f6f8; --panel:#ffffff; --panel-2:#f7f9fb; --raised:#eef2f6;
  --line:#dde3ea; --line-2:#c8d2dd;
  --ink:#12181f; --muted:#5b6774; --faint:#8492a1;
  --accent:#0b62d0; --accent-dim:#e3edfb;
  --ok:#1a7f37; --ok-bg:#e8f5ec; --warn:#8a6100; --warn-bg:#fdf3dd;
  --degraded:#9a5417; --degraded-bg:#fdeede; --crit:#c02c26; --crit-bg:#fdeceb;
  --unknown:#6b7683; --unknown-bg:#eef1f4;
}

* { box-sizing:border-box; }
html,body { height:100%; }
body {
  margin:0; background:var(--bg); color:var(--ink);
  font-family:var(--sans); font-size:14px; line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
button,input,select { font:inherit; color:inherit; }
a { color:var(--accent); }
:focus-visible { outline:2px solid var(--accent); outline-offset:2px; border-radius:3px; }
.num { font-family:var(--mono); font-variant-numeric:tabular-nums; }
.hidden { display:none !important; }

/* ---------- environment banner ---------------------------------------- */
/* Permanently visible, per the rule that nobody should ever be unsure which
 * environment they are operating on. Production is the loud one. */
#envbar {
  height:4px; background:var(--crit);
}
#envbar[data-env="staging"] { background:var(--warn); }
#envbar[data-env="development"] { background:var(--accent); }

/* ---------- auth ------------------------------------------------------- */
#auth {
  min-height:calc(100vh - 4px); display:grid; place-items:center; padding:24px;
}
.card {
  width:100%; max-width:420px; background:var(--panel); border:1px solid var(--line);
  border-radius:8px; padding:32px;
}
.card h1 {
  margin:0 0 4px; font-size:19px; letter-spacing:-.01em;
}
.card .sub { margin:0 0 24px; color:var(--muted); font-size:13px; }
.field { display:block; margin-bottom:14px; }
.field span {
  display:block; font-size:11px; text-transform:uppercase; letter-spacing:.09em;
  color:var(--faint); margin-bottom:6px;
}
.field input {
  width:100%; padding:10px 12px; background:var(--bg); border:1px solid var(--line-2);
  border-radius:5px; font-size:14px;
}
.field input:focus { border-color:var(--accent); outline:none; }
.field input.code { font-family:var(--mono); font-size:22px; letter-spacing:.3em; text-align:center; }
.btn {
  width:100%; padding:11px; border:0; border-radius:5px; background:var(--accent);
  color:#fff; font-weight:600; cursor:pointer;
}
.btn:hover { filter:brightness(1.08); }
.btn:disabled { opacity:.5; cursor:not-allowed; }
.btn.ghost { background:transparent; border:1px solid var(--line-2); color:var(--ink); font-weight:500; }
.err {
  margin:0 0 16px; padding:10px 12px; border-radius:5px; font-size:13px;
  background:var(--crit-bg); color:var(--crit); border:1px solid var(--crit);
}
.note {
  margin:16px 0 0; padding:12px; border-radius:5px; font-size:12.5px; line-height:1.55;
  background:var(--panel-2); border:1px solid var(--line); color:var(--muted);
}
.qr { display:block; margin:0 auto 14px; border-radius:6px; background:#fff; padding:8px; }
.secret {
  font-family:var(--mono); font-size:13px; word-break:break-all; text-align:center;
  background:var(--bg); border:1px solid var(--line-2); border-radius:5px; padding:10px; margin-bottom:16px;
}
.codes { display:grid; grid-template-columns:1fr 1fr; gap:6px; margin:14px 0; }
.codes code {
  font-family:var(--mono); font-size:12.5px; background:var(--bg); border:1px solid var(--line-2);
  border-radius:4px; padding:7px; text-align:center;
}

/* ---------- shell ------------------------------------------------------ */
#shell { display:grid; grid-template-rows:auto 1fr; min-height:calc(100vh - 4px); }
header {
  display:flex; align-items:center; gap:16px; padding:0 18px; height:52px;
  background:var(--panel); border-bottom:1px solid var(--line);
}
.brand { font-weight:600; letter-spacing:-.01em; white-space:nowrap; }
.brand em { font-style:normal; color:var(--faint); font-weight:400; }
.envtag {
  font-family:var(--mono); font-size:10.5px; font-weight:700; letter-spacing:.12em;
  padding:3px 8px; border-radius:3px; border:1px solid currentColor;
  background:var(--crit-bg); color:var(--crit);
}
/* Production is the loud one; anything else must not borrow its urgency, or
 * the badge stops meaning anything. */
.envtag[data-env="staging"]     { background:var(--warn-bg);    color:var(--warn); }
.envtag[data-env="development"] { background:var(--accent-dim); color:var(--accent); }
.envtag[data-env="test"]        { background:var(--unknown-bg); color:var(--unknown); }
header .spacer { flex:1; }
.hdr-meta { display:flex; align-items:center; gap:14px; font-size:12px; color:var(--muted); }
.hdr-meta .num { color:var(--ink); }
.iconbtn {
  background:transparent; border:1px solid var(--line-2); border-radius:5px;
  padding:5px 9px; cursor:pointer; font-size:12px; color:var(--muted);
}
.iconbtn:hover { color:var(--ink); border-color:var(--line-2); }

main { display:grid; grid-template-columns:196px 1fr; min-height:0; }
nav {
  background:var(--panel); border-right:1px solid var(--line); padding:12px 0;
  display:flex; flex-direction:column; gap:1px;
}
nav button {
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  background:transparent; border:0; border-left:2px solid transparent;
  padding:8px 16px; text-align:left; cursor:pointer; color:var(--muted); font-size:13.5px;
}
nav button:hover { color:var(--ink); background:var(--panel-2); }
nav button[aria-current="true"] {
  color:var(--ink); border-left-color:var(--accent); background:var(--panel-2); font-weight:500;
}
nav .count {
  font-family:var(--mono); font-size:11px; padding:1px 6px; border-radius:9px;
  background:var(--raised); color:var(--muted);
}
nav .count.crit { background:var(--crit-bg); color:var(--crit); }
nav .count.warn { background:var(--warn-bg); color:var(--warn); }
nav .sep { height:1px; background:var(--line); margin:10px 16px; }

#view { padding:20px 24px 60px; overflow-y:auto; }

/* ---------- status ----------------------------------------------------- */
.statusbar {
  display:flex; align-items:center; gap:14px; padding:14px 18px; border-radius:8px;
  border:1px solid var(--line); background:var(--panel); margin-bottom:18px;
}
.statusbar[data-s="HEALTHY"] { border-color:var(--ok); background:var(--ok-bg); }
.statusbar[data-s="WARNING"] { border-color:var(--warn); background:var(--warn-bg); }
.statusbar[data-s="DEGRADED"]{ border-color:var(--degraded); background:var(--degraded-bg); }
.statusbar[data-s="HIGH"]    { border-color:var(--degraded); background:var(--degraded-bg); }
.statusbar[data-s="CRITICAL"]{ border-color:var(--crit); background:var(--crit-bg); }
.statusbar[data-s="UNKNOWN"] { border-color:var(--unknown); background:var(--unknown-bg); }
.statusbar .word {
  font-family:var(--mono); font-size:17px; font-weight:700; letter-spacing:.06em;
}
.statusbar[data-s="HEALTHY"] .word { color:var(--ok); }
.statusbar[data-s="WARNING"] .word { color:var(--warn); }
.statusbar[data-s="DEGRADED"] .word,
.statusbar[data-s="HIGH"] .word { color:var(--degraded); }
.statusbar[data-s="CRITICAL"] .word { color:var(--crit); }
.statusbar[data-s="UNKNOWN"] .word { color:var(--unknown); }
.statusbar .why { flex:1; font-size:13px; color:var(--ink); opacity:.85; }

/* ---------- cards ------------------------------------------------------ */
.grid { display:grid; gap:12px; margin-bottom:18px; }
.grid.k4 { grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); }
.grid.k2 { grid-template-columns:repeat(auto-fit,minmax(340px,1fr)); }
.tile {
  background:var(--panel); border:1px solid var(--line); border-radius:7px; padding:13px 15px;
  position:relative; overflow:hidden;
}
.tile::before {
  content:""; position:absolute; left:0; top:0; bottom:0; width:3px; background:transparent;
}
.tile[data-s="ok"]::before { background:var(--ok); }
.tile[data-s="warn"]::before { background:var(--warn); }
.tile[data-s="crit"]::before { background:var(--crit); }
.tile[data-s="unknown"]::before { background:var(--unknown); }
.tile .label {
  font-size:10.5px; text-transform:uppercase; letter-spacing:.1em; color:var(--faint);
  margin-bottom:7px; display:flex; justify-content:space-between; align-items:center;
}
.tile .value { font-family:var(--mono); font-size:24px; font-weight:600; line-height:1.1; }
.tile .value small { font-size:13px; font-weight:400; color:var(--muted); margin-left:3px; }
.tile .sub { font-size:12px; color:var(--muted); margin-top:5px; }

.panel {
  background:var(--panel); border:1px solid var(--line); border-radius:7px; margin-bottom:18px;
}
.panel > h2 {
  margin:0; padding:12px 16px; font-size:12px; text-transform:uppercase; letter-spacing:.1em;
  color:var(--faint); border-bottom:1px solid var(--line); font-weight:600;
  display:flex; justify-content:space-between; align-items:center; gap:10px;
}
.panel > h2 .hint { text-transform:none; letter-spacing:0; font-weight:400; font-size:11.5px; }
.panel .body { padding:14px 16px; }
.panel .body.flush { padding:0; }

/* ---------- tables ----------------------------------------------------- */
.tw { overflow-x:auto; }
table { width:100%; border-collapse:collapse; font-size:13px; }
thead th {
  text-align:left; font-size:10.5px; text-transform:uppercase; letter-spacing:.09em;
  color:var(--faint); font-weight:600; padding:9px 14px; border-bottom:1px solid var(--line);
  white-space:nowrap; background:var(--panel-2);
}
tbody td { padding:9px 14px; border-bottom:1px solid var(--line); vertical-align:top; }
tbody tr:last-child td { border-bottom:0; }
tbody tr:hover { background:var(--panel-2); }
td.n, th.n { text-align:right; font-family:var(--mono); font-variant-numeric:tabular-nums; }
td .dim { color:var(--muted); }
td .wrap { max-width:520px; word-break:break-word; color:var(--muted); font-size:12.5px; }

.pill {
  display:inline-block; font-family:var(--mono); font-size:10px; font-weight:700;
  letter-spacing:.07em; padding:2px 7px; border-radius:3px; white-space:nowrap;
  background:var(--unknown-bg); color:var(--unknown); border:1px solid transparent;
}
.pill.ok   { background:var(--ok-bg); color:var(--ok); }
.pill.warn { background:var(--warn-bg); color:var(--warn); }
.pill.deg  { background:var(--degraded-bg); color:var(--degraded); }
.pill.crit { background:var(--crit-bg); color:var(--crit); }

/* ---------- incidents -------------------------------------------------- */
.inc { display:flex; gap:12px; padding:12px 16px; border-bottom:1px solid var(--line); }
.inc:last-child { border-bottom:0; }
.inc .rail { width:3px; border-radius:2px; background:var(--unknown); flex:none; }
.inc[data-sev="CRITICAL"] .rail { background:var(--crit); }
.inc[data-sev="HIGH"] .rail { background:var(--degraded); }
.inc[data-sev="WARNING"] .rail { background:var(--warn); }
.inc .main { flex:1; min-width:0; }
.inc .top { display:flex; align-items:center; gap:9px; margin-bottom:3px; flex-wrap:wrap; }
.inc .id { font-family:var(--mono); font-size:12.5px; font-weight:600; }
.inc .msg { font-size:13px; }
.inc .impact { font-size:12.5px; color:var(--muted); margin-top:4px; }
.inc .when { font-family:var(--mono); font-size:11.5px; color:var(--faint); white-space:nowrap; }

/* ---------- spark ------------------------------------------------------ */
.spark { display:block; width:100%; height:34px; margin-top:8px; overflow:visible; }
.spark path.line { fill:none; stroke:var(--accent); stroke-width:1.5; }
.spark path.area { fill:var(--accent); opacity:.13; stroke:none; }
.spark circle.tip { fill:var(--accent); }
.chart { display:block; width:100%; height:170px; }
.chart .grid-l { stroke:var(--line); stroke-width:1; }
.chart .lbl { fill:var(--faint); font-family:var(--mono); font-size:9.5px; }

.empty { padding:26px 16px; text-align:center; color:var(--faint); font-size:13px; }
.loading { padding:26px 16px; text-align:center; color:var(--faint); font-size:13px; }

@media (max-width:820px) {
  main { grid-template-columns:1fr; }
  nav { flex-direction:row; overflow-x:auto; border-right:0; border-bottom:1px solid var(--line); padding:0; }
  nav button { border-left:0; border-bottom:2px solid transparent; white-space:nowrap; }
  nav button[aria-current="true"] { border-left-color:transparent; border-bottom-color:var(--accent); }
  nav .sep { display:none; }
  #view { padding:16px 14px 48px; }
}
@media (prefers-reduced-motion:reduce) { * { animation:none !important; transition:none !important; } }

/* ---------- tenants (Phase 2) ------------------------------------------ */
.toolbar {
  display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-bottom:14px;
}
.toolbar input[type="search"] {
  flex:1; min-width:200px; max-width:360px; padding:8px 11px; background:var(--panel);
  border:1px solid var(--line-2); border-radius:5px; font-size:13.5px;
}
.chip {
  background:var(--panel); border:1px solid var(--line-2); color:var(--muted);
  border-radius:14px; padding:5px 12px; font-size:12.5px; cursor:pointer; white-space:nowrap;
}
.chip:hover { color:var(--ink); }
.chip[aria-pressed="true"] { background:var(--accent-dim); border-color:var(--accent); color:var(--accent); }

/* Load score as a bar AND a number. The bar is what makes a table of scores
 * scannable; the number is what makes it quotable. */
.load { display:flex; align-items:center; gap:9px; min-width:132px; }
.load .track {
  flex:1; height:6px; border-radius:3px; background:var(--raised); overflow:hidden;
}
/* display:block is load-bearing. Both of these are <span>s: the track is
 * blockified by being a flex/grid item, but the fill inside it is not, and an
 * inline element ignores width entirely — so every bar rendered as an empty
 * track that looked plausible in a screenshot and measured 0%. */
.load .fill { display:block; height:100%; background:var(--ok); border-radius:3px; }
.load[data-sev="warn"] .fill { background:var(--warn); }
.load[data-sev="crit"] .fill { background:var(--crit); }
.load[data-sev="unknown"] .fill { background:var(--unknown); }
.load .n {
  font-family:var(--mono); font-variant-numeric:tabular-nums; font-size:13px;
  font-weight:600; min-width:26px; text-align:right;
}
tr.rowlink { cursor:pointer; }
tr.rowlink:hover td:first-child { color:var(--accent); }

.backlink {
  background:transparent; border:0; color:var(--muted); cursor:pointer; padding:0;
  font-size:13px; margin-bottom:10px;
}
.backlink:hover { color:var(--accent); }

.detail-head {
  display:flex; align-items:flex-start; gap:16px; flex-wrap:wrap; margin-bottom:16px;
}
.detail-head h1 { margin:0; font-size:23px; letter-spacing:-.015em; }
.detail-head .meta {
  font-family:var(--mono); font-size:12px; color:var(--faint); margin-top:4px;
  display:flex; gap:14px; flex-wrap:wrap;
}
.detail-head .actions { margin-left:auto; display:flex; gap:8px; }

/* Component breakdown of the score. An unmeasured row is visibly struck out
 * rather than shown as a zero-length bar — a bar at zero reads as "measured and
 * idle", which is the confusion this whole model exists to avoid. */
.comp { display:grid; grid-template-columns:150px 1fr 58px 46px; gap:10px; align-items:center; padding:5px 0; }
.comp .name { font-size:13px; }
.comp .track { display:block; height:6px; border-radius:3px; background:var(--raised); overflow:hidden; }
.comp .fill { display:block; height:100%; background:var(--accent); border-radius:3px; }
.comp .share, .comp .sc {
  font-family:var(--mono); font-size:12px; font-variant-numeric:tabular-nums; text-align:right; color:var(--muted);
}
.comp.unmeasured .name { color:var(--faint); text-decoration:line-through; text-decoration-thickness:1px; }
.comp.unmeasured .track { background:repeating-linear-gradient(135deg,var(--raised) 0 4px,transparent 4px 8px); }
.comp.unmeasured .sc { color:var(--faint); }

.banner {
  display:flex; gap:12px; align-items:flex-start; padding:12px 16px; border-radius:7px;
  border:1px solid var(--warn); background:var(--warn-bg); margin-bottom:16px; font-size:13px;
}
.banner .t { font-weight:600; color:var(--warn); }
.banner button { margin-left:auto; }

/* ---------- action dialog ---------------------------------------------- */
dialog.modal {
  border:1px solid var(--line-2); border-radius:8px; background:var(--panel); color:var(--ink);
  padding:0; width:min(460px,92vw); box-shadow:0 24px 60px -20px rgba(0,0,0,.6);
}
dialog.modal::backdrop { background:rgba(0,0,0,.55); }
dialog.modal .head { padding:18px 22px 0; }
dialog.modal h2 { margin:0 0 6px; font-size:17px; }
dialog.modal .desc { margin:0; color:var(--muted); font-size:13px; line-height:1.55; }
dialog.modal .body { padding:16px 22px 0; }
dialog.modal .foot { display:flex; gap:8px; padding:18px 22px 20px; }
dialog.modal .foot .btn { flex:1; }
dialog.modal .tier {
  display:inline-block; font-family:var(--mono); font-size:10px; font-weight:700; letter-spacing:.08em;
  padding:2px 7px; border-radius:3px; background:var(--warn-bg); color:var(--warn); margin-bottom:8px;
}
dialog.modal .tier[data-tier="control"] { background:var(--crit-bg); color:var(--crit); }

/* ---------- phase 3 ----------------------------------------------------- */
/* Mode is the most consequential word on these screens: it decides whether a
 * rule refuses traffic or merely watches it. It gets its own visual weight. */
.mode {
  display:inline-block; font-family:var(--mono); font-size:10px; font-weight:700;
  letter-spacing:.08em; padding:2px 7px; border-radius:3px; white-space:nowrap;
  border:1px solid transparent;
}
.mode[data-m="off"]     { background:var(--unknown-bg); color:var(--unknown); }
.mode[data-m="shadow"]  { background:var(--warn-bg); color:var(--warn); border-color:var(--warn); }
.mode[data-m="enforce"] { background:var(--crit-bg); color:var(--crit); border-color:var(--crit); }

/* A named check with its verdict and evidence. The score is the sum; this is
 * what a reader argues with. */
.check {
  display:grid; grid-template-columns:20px 1fr auto; gap:11px; align-items:start;
  padding:11px 0; border-bottom:1px solid var(--line);
}
.check:last-child { border-bottom:0; }
.check .dot2 { width:9px; height:9px; border-radius:50%; margin-top:6px; background:var(--unknown); }
.check[data-v="pass"] .dot2 { background:var(--ok); }
.check[data-v="warn"] .dot2 { background:var(--warn); }
.check[data-v="fail"] .dot2 { background:var(--crit); }
/* display:block on both: they are <span>s, and an inline element ignores
 * margin-top and refuses to start a new line — so the label and its evidence
 * ran together into one sentence. Third instance of this in the console; the
 * browser test now measures line boxes rather than trusting the markup. */
.check .lbl { display:block; font-size:13.5px; font-weight:500; }
.check .det { display:block; font-size:12.5px; color:var(--muted); margin-top:2px; }
.check .wt {
  font-family:var(--mono); font-size:11px; color:var(--faint); white-space:nowrap; padding-top:2px;
}

/* Incident timeline. The rail is what makes a sequence read as a sequence. */
.tl { position:relative; padding-left:22px; }
.tl::before { content:""; position:absolute; left:5px; top:6px; bottom:6px; width:1px; background:var(--line-2); }
.tl-item { position:relative; padding:8px 0; }
.tl-item::before {
  content:""; position:absolute; left:-21px; top:14px; width:9px; height:9px;
  border-radius:50%; background:var(--panel); border:2px solid var(--line-2);
}
.tl-item[data-k="opened"]::before { border-color:var(--warn); }
.tl-item[data-k="status_changed"]::before { border-color:var(--accent); }
.tl-item[data-k="note"]::before { border-color:var(--muted); }
.tl-item .when { font-family:var(--mono); font-size:11px; color:var(--faint); }
.tl-item .what { font-size:13px; margin-top:2px; }
.tl-item .who { font-size:12px; color:var(--muted); }

/* Rollout control. A percentage is a promise about a population, so the count
 * it resolves to sits right next to it. */
.rollout { display:flex; align-items:center; gap:10px; }
.rollout input[type="range"] { flex:1; accent-color:var(--accent); }
.rollout .pct { font-family:var(--mono); font-size:12px; min-width:38px; text-align:right; }

.stack { display:flex; flex-direction:column; gap:2px; }
.mono-sm { font-family:var(--mono); font-size:11.5px; color:var(--muted); }
.stackbar { display:flex; height:8px; border-radius:4px; overflow:hidden; background:var(--raised); }
.stackbar span { display:block; height:100%; }
.trace {
  font-family:var(--mono); font-size:11.5px; line-height:1.5; white-space:pre-wrap;
  background:var(--bg); border:1px solid var(--line); border-radius:5px;
  padding:11px 13px; max-height:260px; overflow:auto; color:var(--muted);
}
