/* ultimate monitor — operator console.
   Dark terminal palette, monospace, information-first. The layout is a fixed
   chrome (header / subbar / nav) around exactly one scrolling view at a time;
   nothing outside a .view-scroll is ever allowed to scroll the document. */

:root {
  --bg:       #0d1117;
  --surface:  #161b22;
  --surface2: #1c2128;
  --border:   #30363d;
  --border-q: #21262d;   /* quiet border, for chips and inset panels */
  --text:     #c9d1d9;
  --muted:    #8b949e;
  --dim:      #484f58;
  --accent:   #58a6ff;
  --accent-2: #79c0ff;
  --ok:       #3fb950;
  --warn:     #d29922;
  --err:      #f85149;

  --ok-bg:   rgba(63,185,80,0.10);
  --warn-bg: rgba(210,153,34,0.12);
  --err-bg:  rgba(248,81,73,0.12);
  --acc-bg:  rgba(88,166,255,0.10);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: 'Courier New', Courier, monospace;
  font-size: 13px;
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}

.hidden { display: none !important; }
.mobile-only { display: none; }

/* ── Header ─────────────────────────────────────────────────────────────── */
#header {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 6px 12px;
  display: flex;
  align-items: center;
  gap: 12px;
  row-gap: 4px;
  flex-wrap: wrap;
  flex-shrink: 0;
  min-height: 38px;
}
#header h1 {
  font-size: 13px;
  color: var(--accent);
  letter-spacing: 0.05em;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 6px;
}
.stat { color: var(--dim); white-space: nowrap; }
.stat b { color: var(--text); font-weight: normal; }
.host-stat { font-size: 12px; }
#auth-control { margin-left: auto; }

#dot {
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--ok);
  margin-right: 5px;
  vertical-align: middle;
}
#dot.err { background: var(--err); }

.icon-btn {
  background: transparent;
  border: 1px solid var(--border-q);
  color: var(--muted);
  font-size: 13px;
  line-height: 1;
  padding: 0 8px;
  min-height: 28px;
  border-radius: 3px;
  cursor: pointer;
}
.icon-btn:hover { color: var(--text); border-color: var(--border); }

/* Elevation ("sudo mode") indicator. Locked is the resting state: the session
   can read everything but cannot change anything until unlocked. */
.auth-chip {
  font-family: inherit;
  font-size: 11px;
  padding: 2px 8px;
  min-height: 28px;
  border-radius: 10px;
  border: 1px solid var(--border-q);
  background: rgba(255,255,255,0.03);
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
}
.auth-chip.auth-on { color: var(--ok); border-color: #238636; }
.auth-chip.auth-off { color: #6e7681; cursor: default; }

/* Alert badge — the one element that must read the same from every view. */
.alert-badge {
  display: flex;
  align-items: center;
  gap: 5px;
  text-decoration: none;
  padding: 2px 4px;
  border-radius: 10px;
}
.sev-pill {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 1px 7px;
  border-radius: 10px;
  font-size: 11px;
  white-space: nowrap;
}
.sev-pill.crit { color: var(--err);  background: var(--err-bg);  border: 1px solid #6e2020; }
.sev-pill.warn { color: var(--warn); background: var(--warn-bg); border: 1px solid #6b4c10; }
.sev-pill.info { color: var(--accent-2); background: var(--acc-bg); border: 1px solid #1f4b7f; }
.sev-pill.mute { color: var(--dim); background: rgba(255,255,255,0.03); border: 1px solid var(--border-q); }
.sev-pill.calm { color: var(--ok);  background: var(--ok-bg);   border: 1px solid #1f6f31; }
.sev-pill.crit.live { animation: critpulse 1.6s ease-in-out infinite; }
@keyframes critpulse {
  0%,100% { box-shadow: 0 0 0 0 rgba(248,81,73,0.0); }
  50%     { box-shadow: 0 0 0 3px rgba(248,81,73,0.18); }
}

/* ── Subbar: process stats + links to the other proxied UIs ─────────────── */
#subbar {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 3px 12px;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-shrink: 0;
  font-size: 11px;
  min-height: 24px;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
}
#subbar::-webkit-scrollbar { display: none; }
#page-links { display: flex; gap: 8px; margin-left: auto; }
.page-link {
  color: var(--accent-2);
  text-decoration: none;
  padding: 2px 8px;
  border-radius: 10px;
  background: rgba(255,255,255,0.03);
  border: 1px solid var(--border-q);
  white-space: nowrap;
}
.page-link:hover { border-color: var(--border); background: rgba(255,255,255,0.06); }

/* ── Error banner ───────────────────────────────────────────────────────── */
#err-banner {
  background: #2d1313;
  border-bottom: 1px solid #6e2020;
  color: var(--err);
  padding: 4px 12px;
  font-size: 11px;
  display: none;
  flex-shrink: 0;
  word-break: break-word;
}

/* ── Navigation ─────────────────────────────────────────────────────────── */
#nav {
  display: flex;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
#nav::-webkit-scrollbar { display: none; }
.nav-tab {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  color: var(--muted);
  font-family: inherit;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  padding: 7px 14px;
  min-height: 32px;
  cursor: pointer;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 6px;
}
.nav-tab:hover:not(.active) { color: var(--accent); background: transparent; border-color: transparent; }
.nav-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.nav-glyph { font-size: 12px; }
.nav-count {
  font-size: 10px;
  padding: 0 5px;
  border-radius: 8px;
  background: var(--err-bg);
  color: var(--err);
  border: 1px solid #6e2020;
}
.nav-count:empty { display: none; }
.nav-count.warn { background: var(--warn-bg); color: var(--warn); border-color: #6b4c10; }
.nav-count.info { background: var(--acc-bg); color: var(--accent-2); border-color: #1f4b7f; }

/* ── Views ──────────────────────────────────────────────────────────────── */
#main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}
.view { display: none; flex: 1; min-height: 0; flex-direction: column; }
.view.active { display: flex; }
.view-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding-bottom: 24px;
}
.view-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  flex-wrap: wrap;
}
#svc-meta { font-size: 11px; color: var(--dim); margin-left: auto; }

.text-input {
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  font-family: inherit;
  font-size: 12px;
  padding: 4px 8px;
  min-height: 30px;
  border-radius: 3px;
  min-width: 0;
  flex: 1;
  max-width: 320px;
}
.text-input:focus { outline: none; border-color: var(--accent); }

.chips { display: flex; gap: 4px; flex-wrap: wrap; }
.chip {
  background: transparent;
  border: 1px solid var(--border-q);
  color: var(--muted);
  font-family: inherit;
  font-size: 11px;
  padding: 3px 9px;
  min-height: 28px;
  border-radius: 10px;
  cursor: pointer;
  white-space: nowrap;
}
.chip:hover:not(:disabled) { border-color: var(--border); background: rgba(255,255,255,0.05); }
.chip.on { color: var(--accent); border-color: var(--accent); background: var(--acc-bg); }

/* ── Buttons ────────────────────────────────────────────────────────────── */
button {
  background: var(--border-q);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 4px 10px;
  font-family: inherit;
  font-size: 12px;
  cursor: pointer;
  border-radius: 3px;
  white-space: nowrap;
  min-height: 32px;
}
button:hover:not(:disabled) { background: var(--border); border-color: var(--muted); }
button:disabled { opacity: 0.4; cursor: not-allowed; }
.btn-kill, .btn-danger { color: var(--err); border-color: #6e2c2a; }
.btn-kill:hover:not(:disabled), .btn-danger:hover:not(:disabled) {
  background: rgba(248,81,73,0.15); border-color: var(--err);
}
.btn-go { color: var(--ok); border-color: #1f6f31; }
.btn-go:hover:not(:disabled) { background: var(--ok-bg); border-color: var(--ok); }
select {
  background: var(--border-q);
  border: 1px solid var(--border);
  color: var(--text);
  font-family: inherit;
  font-size: 12px;
  padding: 4px 6px;
  border-radius: 3px;
  cursor: pointer;
  min-height: 32px;
  max-width: 100%;
}

/* A write control the current session cannot use. Disabled *and* visibly
   different, with the reason in the tooltip — never a surprise 403. */
.write-blocked { opacity: 0.4; border-style: dashed !important; cursor: not-allowed; }

.write-notice {
  display: none;
  margin: 8px 12px 0;
  padding: 7px 10px;
  border: 1px solid #6b4c10;
  border-left: 3px solid var(--warn);
  background: var(--warn-bg);
  color: var(--warn);
  border-radius: 3px;
  font-size: 11px;
  line-height: 1.5;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.write-notice.on { display: flex; }

/* ── Cards / sections ───────────────────────────────────────────────────── */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  margin: 8px 12px;
  overflow: hidden;
}
.card-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  cursor: pointer;
  user-select: none;
  min-height: 36px;
}
.card-head:hover { background: rgba(255,255,255,0.03); }
.card-title {
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  white-space: nowrap;
}
.card-summary {
  color: var(--dim);
  font-size: 11px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.card-body { padding: 4px 10px 10px; border-top: 1px solid var(--border-q); }
.card.collapsed .card-body { display: none; }
.card.sev-crit { border-left: 3px solid var(--err); }
.card.sev-warn { border-left: 3px solid var(--warn); }
.card.sev-ok   { border-left: 3px solid #1f6f31; }
.card.sev-off  { border-left: 3px solid var(--border); }

.collapse-chevron {
  display: inline-block;
  font-size: 10px;
  color: var(--dim);
  width: 10px;
  text-align: center;
  flex-shrink: 0;
}
.card-head:hover .collapse-chevron { color: var(--muted); }

/* Node/metric strips reused by health, docker disk, backups, overlay. */
.metric-row { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 0; }
.sh-node {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  border-radius: 3px;
  background: rgba(255,255,255,0.03);
  border: 1px solid var(--border-q);
  font-size: 11px;
  max-width: 100%;
  flex-wrap: wrap;
}
.sh-name { color: var(--accent-2); }
.sh-sep  { color: var(--border); margin: 0 2px; }
.sh-dim  { color: var(--dim); }
.sh-ok   { color: var(--ok); }
.sh-warn { color: var(--warn); }
.sh-err  { color: var(--err); }

.kv { display: flex; gap: 8px; padding: 2px 0; font-size: 12px; flex-wrap: wrap; }
.kv-k { color: var(--muted); min-width: 130px; flex-shrink: 0; }
.kv-v { color: var(--text); word-break: break-word; min-width: 0; }
.empty { color: var(--dim); padding: 10px 12px; font-size: 12px; }
.note { color: var(--dim); font-size: 11px; padding: 3px 0; line-height: 1.5; }

/* ── Net / release strips (kept from the previous layout) ───────────────── */
.net-target {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 7px;
  border-radius: 10px;
  font-size: 11px;
}
.net-target::before { content: ''; display: inline-block; width: 6px; height: 6px; border-radius: 50%; }
.net-target.up      { color: var(--ok);  background: var(--ok-bg); }
.net-target.up::before      { background: var(--ok); }
.net-target.down    { color: var(--err); background: var(--err-bg); }
.net-target.down::before    { background: var(--err); }
.net-target.unknown { color: var(--muted); background: rgba(139,148,158,0.1); }
.net-target.unknown::before { background: var(--muted); }
.net-degraded {
  display: inline-flex; align-items: center;
  padding: 2px 7px; border-radius: 10px; font-size: 11px;
  color: var(--warn); background: var(--warn-bg);
}
.net-speed { color: var(--dim); }
.net-speed b { color: var(--muted); font-weight: normal; }

.rel-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; vertical-align: middle; margin-right: 4px; }
.rel-dot.active   { background: var(--ok); }
.rel-dot.inactive { background: var(--dim); }
.rel-dot.spinning { background: var(--warn); animation: pulse 1s ease-in-out infinite; }
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.3} }
.rel-host { color: var(--accent-2); }
.rel-id   { color: var(--text); }
.rel-ok   { color: var(--ok); }
.rel-fail { color: var(--err); }
.rel-dim  { color: var(--dim); }
.rel-err  { color: var(--warn); }

/* ── Jester subsystem status (generic recursive JSON render) ────────────── */
.jst-cards { display: flex; flex-direction: column; }
.jst-card { background: var(--bg); border: 1px solid var(--border-q); border-radius: 3px; padding: 6px 9px; margin-bottom: 6px; }
.jst-card-head { color: var(--accent); font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 4px; }
.jst-row { display: flex; gap: 8px; padding: 1px 0; font-size: 12px; flex-wrap: wrap; }
.jst-key { color: var(--muted); min-width: 130px; flex-shrink: 0; }
.jst-val { color: var(--text); word-break: break-word; min-width: 0; }
.jst-obj, .jst-arr { padding-left: 10px; border-left: 1px solid var(--border-q); }
.jst-dim { color: var(--dim); }

/* ── Overview digest ────────────────────────────────────────────────────── */
#ov-digest { margin: 8px 12px 0; }
.digest {
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 10px 12px;
  background: var(--surface);
}
.digest.crit { border-color: #6e2020; background: linear-gradient(180deg, rgba(248,81,73,0.10), var(--surface)); }
.digest.warn { border-color: #6b4c10; background: linear-gradient(180deg, rgba(210,153,34,0.08), var(--surface)); }
.digest.ok   { border-color: #1f6f31; }
.digest-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 4px; }
.digest-title { font-size: 14px; letter-spacing: 0.03em; }
.digest.crit .digest-title { color: var(--err); }
.digest.warn .digest-title { color: var(--warn); }
.digest.ok   .digest-title { color: var(--ok); }
.digest-line {
  display: flex; gap: 8px; padding: 3px 0;
  font-size: 12px; border-top: 1px solid var(--border-q); align-items: baseline;
}
.digest-line:first-of-type { border-top: none; }
.digest-subject { color: var(--accent-2); white-space: nowrap; }
.digest-summary { color: var(--text); min-width: 0; word-break: break-word; }
.digest-actions { margin-top: 8px; display: flex; gap: 8px; flex-wrap: wrap; }

/* ── Alerts ─────────────────────────────────────────────────────────────── */
.alert-group-head {
  color: var(--dim); font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.09em; padding: 10px 12px 4px;
}
.alert {
  margin: 0 12px 5px;
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: 3px;
  background: var(--surface);
  overflow: hidden;
}
.alert.crit { border-left-color: var(--err); }
.alert.warn { border-left-color: var(--warn); }
.alert.info { border-left-color: var(--accent); }
.alert.silenced { opacity: 0.55; border-left-color: var(--dim); }
.alert-head {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 9px; cursor: pointer; min-height: 40px;
}
.alert-head:hover { background: rgba(255,255,255,0.03); }
.alert-sev { flex-shrink: 0; width: 14px; text-align: center; }
.alert.crit .alert-sev { color: var(--err); }
.alert.warn .alert-sev { color: var(--warn); }
.alert.info .alert-sev { color: var(--accent); }
.alert-subject { color: var(--accent-2); white-space: nowrap; flex-shrink: 0; max-width: 42%; overflow: hidden; text-overflow: ellipsis; }
.alert-summary { color: var(--text); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
.alert-meta { color: var(--dim); font-size: 11px; white-space: nowrap; flex-shrink: 0; }
.alert-body { padding: 2px 9px 9px 9px; border-top: 1px solid var(--border-q); }
.alert.collapsed .alert-body { display: none; }
.alert-detail {
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--muted);
  font-size: 12px;
  background: var(--bg);
  border: 1px solid var(--border-q);
  border-radius: 3px;
  padding: 6px 8px;
  margin: 6px 0;
  max-height: 240px;
  overflow: auto;
}
.labels { display: flex; flex-wrap: wrap; gap: 4px; margin: 5px 0; }
.label-chip {
  font-size: 10px; color: var(--muted);
  border: 1px solid var(--border-q); border-radius: 10px;
  padding: 1px 7px; background: rgba(255,255,255,0.03);
  word-break: break-all;
}
.rem-list { display: flex; flex-direction: column; gap: 5px; margin-top: 6px; }
.rem {
  display: flex; align-items: flex-start; gap: 8px;
  border: 1px solid var(--border-q); border-radius: 3px;
  padding: 6px 8px; background: var(--bg); flex-wrap: wrap;
}
.rem-info { flex: 1; min-width: 160px; }
.rem-label { color: var(--text); font-size: 12px; }
.rem-desc { color: var(--dim); font-size: 11px; line-height: 1.5; margin-top: 2px; }
.risk {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em;
  padding: 1px 6px; border-radius: 3px; white-space: nowrap;
}
.risk.low    { color: var(--ok);   background: var(--ok-bg);   border: 1px solid #1f6f31; }
.risk.medium { color: var(--warn); background: var(--warn-bg); border: 1px solid #6b4c10; }
.risk.high   { color: var(--err);  background: var(--err-bg);  border: 1px solid #6e2020; }
.kind-tag { font-size: 10px; color: var(--dim); border: 1px solid var(--border-q); border-radius: 3px; padding: 1px 5px; }
.rem-actions { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.rem-result {
  margin-top: 5px; font-size: 11px; color: var(--muted);
  border-left: 2px solid var(--accent); padding-left: 8px; word-break: break-word;
}
.silence-row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-top: 8px; }

/* ── Services table → cards on a phone ──────────────────────────────────── */
table { width: 100%; border-collapse: collapse; }
thead th {
  background: var(--surface);
  padding: 5px 12px;
  text-align: left;
  font-size: 11px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  cursor: pointer;
  user-select: none;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  position: sticky;
  top: 0;
  z-index: 5;
}
thead th:hover { color: var(--accent); }
thead th.asc::after  { content: ' ↑'; color: var(--accent); }
thead th.desc::after { content: ' ↓'; color: var(--accent); }
tbody tr.svc-row { border-bottom: 1px solid var(--surface); cursor: pointer; }
tbody tr.svc-row:hover { background: var(--surface); }
tbody tr.svc-row.open { background: var(--surface); }
td { padding: 6px 12px; vertical-align: top; }
.c-name { color: var(--accent); word-break: break-all; }
.c-image { color: var(--muted); font-size: 11px; word-break: break-all; }
.c-node { color: var(--accent-2); }
.s-run  { color: var(--ok); }
.s-warn { color: var(--warn); }
.s-stop { color: var(--err); }
.s-unk  { color: var(--muted); }

.svc-detail td { background: var(--surface2); border-bottom: 1px solid var(--border); }
.svc-actions { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 8px; }
.svc-actions .group {
  display: flex; gap: 6px; align-items: center;
  border: 1px solid var(--border-q); border-radius: 3px; padding: 4px 6px;
  flex-wrap: wrap;
}
.group-label { color: var(--dim); font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; }
.num-input {
  background: var(--bg); border: 1px solid var(--border); color: var(--text);
  font-family: inherit; font-size: 12px; padding: 4px 6px; border-radius: 3px;
  width: 62px; min-height: 32px;
}

/* ── Config ─────────────────────────────────────────────────────────────── */
.cfg-entry {
  display: flex; align-items: center; gap: 8px;
  margin: 0 12px 4px; padding: 7px 9px; min-height: 40px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 3px;
  cursor: pointer;
}
.cfg-entry:hover { border-color: var(--muted); }
.cfg-entry.open { border-color: var(--accent); }
.cfg-name { color: var(--accent); }
.cfg-path { color: var(--dim); font-size: 11px; margin-left: auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.field-row { display: flex; gap: 8px; align-items: flex-start; padding: 5px 0; flex-wrap: wrap; }
.field-label { min-width: 200px; flex-shrink: 0; }
.field-name { color: var(--text); font-size: 12px; word-break: break-all; }
.field-desc { color: var(--dim); font-size: 10px; line-height: 1.4; }
.field-ctl { flex: 1; min-width: 160px; display: flex; flex-direction: column; gap: 3px; }
.field-ctl input, .field-ctl select, .field-ctl textarea {
  background: var(--bg); border: 1px solid var(--border); color: var(--text);
  font-family: inherit; font-size: 12px; padding: 5px 8px; border-radius: 3px;
  min-height: 34px; width: 100%; max-width: 340px;
}
.field-ctl textarea { min-height: 76px; resize: vertical; white-space: pre; overflow-x: auto; }
.field-ctl input:focus, .field-ctl select:focus, .field-ctl textarea:focus { outline: none; border-color: var(--accent); }
.field-ctl input.dirty, .field-ctl select.dirty, .field-ctl textarea.dirty { border-color: var(--warn); }
.field-cur { color: var(--dim); font-size: 10px; word-break: break-all; }

/* Unified diff. Horizontally scrollable inside its own box — the page never
   scrolls sideways, but a long line in a diff must not be silently truncated. */
.diff {
  background: var(--bg);
  border: 1px solid var(--border-q);
  border-radius: 3px;
  margin: 6px 0;
  overflow-x: auto;
  max-height: 380px;
  overflow-y: auto;
  font-size: 12px;
  line-height: 1.45;
}
.diff pre { padding: 6px 0; min-width: min-content; }
.diff .dl { display: block; padding: 0 10px; white-space: pre; }
.diff .d-add  { color: var(--ok);   background: rgba(63,185,80,0.10); }
.diff .d-del  { color: var(--err);  background: rgba(248,81,73,0.10); }
.diff .d-hunk { color: var(--accent); background: var(--acc-bg); }
.diff .d-meta { color: var(--dim); }
.diff .d-ctx  { color: var(--muted); }

.warn-list { margin: 6px 0; padding: 6px 9px; border: 1px solid #6b4c10; border-left: 3px solid var(--warn); background: var(--warn-bg); border-radius: 3px; }
.warn-list div { color: var(--warn); font-size: 11px; line-height: 1.5; word-break: break-word; }
.target-list { color: var(--muted); font-size: 11px; word-break: break-all; }
.actions-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 8px; }
.check-row { display: flex; gap: 6px; align-items: center; color: var(--muted); font-size: 12px; min-height: 32px; }
.check-row input { width: 16px; height: 16px; accent-color: var(--accent); }

/* ── Command panels ─────────────────────────────────────────────────────── */
#cmd-panels {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: row;
}
.cmd-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  border-right: 1px solid var(--border);
}
.cmd-panel:last-child { border-right: none; }
.cmd-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 12px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.cmd-bar h2 { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.1em; flex: 1; }
.cmd-status { font-size: 11px; color: var(--dim); }
.cmd-row {
  display: flex; align-items: center;
  padding: 5px 12px; gap: 8px;
  border-bottom: 1px solid var(--border-q);
  flex-shrink: 0;
  flex-wrap: wrap;
}
.cmd-prefix { color: var(--ok); white-space: nowrap; }
.cmd-input {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  min-width: 90px;
  min-height: 32px;
}
.cmd-output {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding: 5px 12px;
  font-size: 12px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-all;
}
.o-out  { color: var(--text); }
.o-err  { color: var(--warn); }
.o-ok   { color: var(--ok); }
.o-fail { color: var(--err); }
.o-meta { color: var(--dim); }

.cmd-panel.expanded {
  position: fixed; inset: 0; z-index: 100;
  display: flex; flex-direction: column;
  background: var(--bg);
}
.cmd-panel.expanded .cmd-output { flex: 1; max-height: none; }
.expand-btn {
  background: transparent; border: none; color: var(--dim);
  padding: 0 6px; font-size: 14px; cursor: pointer;
  border-radius: 3px; min-height: 32px; line-height: 1;
}
.expand-btn:hover { color: var(--muted); background: rgba(255,255,255,0.06); }

/* ── Job dock ───────────────────────────────────────────────────────────── */
#jobs-dock {
  flex-shrink: 0;
  border-top: 1px solid var(--border);
  background: var(--surface);
  display: flex;
  flex-direction: column;
  max-height: 46vh;
}
#jobs-dock.collapsed { max-height: none; }
#jobs-dock.hidden { display: none !important; }
#jobs-dock-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 12px; cursor: pointer; user-select: none;
  min-height: 36px; flex-shrink: 0;
}
#jobs-dock-bar:hover { background: rgba(255,255,255,0.03); }
.dock-label { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.09em; }
.dock-summary { color: var(--dim); font-size: 11px; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dock-spinner { color: var(--warn); font-size: 11px; }
#jobs-dock.collapsed #jobs-dock-body { display: none; }
#jobs-dock-body { display: flex; flex-direction: column; min-height: 0; border-top: 1px solid var(--border-q); }
#jobs-list { max-height: 130px; overflow-y: auto; flex-shrink: 0; }
.job-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 12px; min-height: 38px; cursor: pointer;
  border-bottom: 1px solid var(--border-q); font-size: 12px;
}
.job-row:hover { background: rgba(255,255,255,0.03); }
.job-row.on { background: var(--surface2); }
.job-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); }
.job-state { font-size: 11px; white-space: nowrap; }
.job-state.running   { color: var(--warn); }
.job-state.succeeded { color: var(--ok); }
.job-state.failed, .job-state.timed_out { color: var(--err); }
.job-state.killed    { color: var(--dim); }
#job-detail { display: none; flex-direction: column; min-height: 0; flex: 1; }
#job-detail.on { display: flex; }
#job-detail-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 12px; background: var(--surface2);
  border-top: 1px solid var(--border-q); border-bottom: 1px solid var(--border-q);
  flex-shrink: 0;
}
#job-detail-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
#job-out { background: var(--bg); min-height: 90px; max-height: 32vh; }

/* ── Modal ──────────────────────────────────────────────────────────────── */
#modal {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(1,4,9,0.75);
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
}
#modal-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 5px;
  max-width: 520px;
  width: 100%;
  max-height: 84vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#modal-title {
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  font-size: 13px;
  letter-spacing: 0.03em;
}
#modal-body {
  padding: 12px 14px;
  overflow-y: auto;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.6;
  word-break: break-word;
}
#modal-actions {
  display: flex; gap: 8px; justify-content: flex-end;
  padding: 10px 14px; border-top: 1px solid var(--border);
}
#modal-actions button { min-height: 40px; padding: 6px 16px; }

/* ── Responsive: 768px and below is treated as "phone-shaped" ───────────── */
@media (max-width: 768px) {
  body { font-size: 13px; }
  .mobile-only { display: initial; }
  .brand-text { display: none; }

  /* Nav becomes a bottom tab bar: last in the flex order, thumb-sized. */
  #nav {
    order: 10;
    border-bottom: none;
    border-top: 1px solid var(--border);
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
  .nav-tab {
    flex: 1;
    flex-direction: column;
    gap: 2px;
    padding: 6px 2px;
    min-height: 52px;
    border-bottom: none;
    border-top: 2px solid transparent;
    justify-content: center;
    font-size: 9px;
    letter-spacing: 0.04em;
  }
  .nav-tab.active { border-bottom-color: transparent; border-top-color: var(--accent); }
  .nav-glyph { font-size: 15px; }
  .nav-count { position: absolute; }
  .nav-tab { position: relative; }
  .nav-count:not(:empty) { top: 3px; right: calc(50% - 26px); }

  #header { gap: 8px; padding: 6px 8px; }
  #header h1 { font-size: 15px; }
  #subbar { padding: 3px 8px; gap: 10px; }
  .view-bar { padding: 5px 8px; }
  .card, .alert, .cfg-entry, #ov-digest, .write-notice { margin-left: 8px; margin-right: 8px; }
  .text-input { max-width: none; }

  /* The service table becomes a stack of cards. Each cell carries its own
     label, the header row is hidden, and #svc-sort takes over sorting. */
  #svc-table, #svc-table tbody, #svc-table tr, #svc-table td { display: block; width: 100%; }
  #svc-table thead { display: none; }
  tbody tr.svc-row {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 3px;
    margin: 0 8px 6px;
    padding: 4px 0;
    width: auto;
  }
  tbody tr.svc-row td { padding: 3px 10px; display: flex; gap: 8px; min-height: 24px; }
  tbody tr.svc-row td::before {
    content: attr(data-label);
    color: var(--dim);
    font-size: 11px;
    min-width: 74px;
    flex-shrink: 0;
  }
  tbody tr.svc-row td.cell-name { min-height: 34px; align-items: center; }
  tr.svc-detail { display: block; margin: 0 8px 8px; width: auto; }
  tr.svc-detail td { display: block; border: 1px solid var(--border); border-radius: 0 0 3px 3px; }
  tr.svc-detail td::before { content: none; }

  #cmd-panels { flex-direction: column; }
  .cmd-panel { border-right: none; border-bottom: 1px solid var(--border); }
  .cmd-panel:last-child { border-bottom: none; }
  .cmd-input { width: 100%; flex-basis: 100%; }
  .cmd-row select, .cmd-row button { min-height: 40px; }

  .field-label { min-width: 0; flex-basis: 100%; }
  .field-ctl input, .field-ctl select, .field-ctl textarea { max-width: none; }
  .kv-k { min-width: 0; flex-basis: 100%; }
  .jst-key { min-width: 0; flex-basis: 100%; }

  /* Anything tappable gets a thumb-sized target. */
  button, select, .chip, .auth-chip, .icon-btn { min-height: 44px; }
  .expand-btn { min-height: 44px; padding: 0 10px; }
  .card-head, .alert-head, .cfg-entry, .job-row, #jobs-dock-bar { min-height: 48px; }
  #jobs-list { max-height: 40vh; }
  #job-out { max-height: 34vh; }
}

@media (max-width: 400px) {
  .alert-subject { max-width: 55%; }
  .alert-meta { display: none; }
  #subbar .stat { font-size: 10px; }
}

/* ── Log scanner health ───────────────────────────────────────────────────── */
/* A scanner reporting zero anomalies looks exactly like one that has silently
   stopped reading — the alert list cannot tell those apart, because an empty
   list is the expected output of both. These numbers are what distinguishes
   them, so they sit above the alert list rather than in a separate view. */
.logscan-card { margin: 8px 12px; }
.ls-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
  gap: 6px;
  padding-top: 6px;
}
.ls-stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px 8px;
  background: var(--bg);
  border: 1px solid var(--border-q);
  border-radius: 3px;
}
.ls-stat-v { color: var(--text); font-size: 15px; font-variant-numeric: tabular-nums; }
.ls-stat-v.ls-bad { color: var(--err); }
.ls-stat-l {
  color: var(--dim);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.ls-warn {
  margin-top: 8px;
  padding: 6px 8px;
  border-left: 3px solid var(--warn);
  background: var(--warn-bg);
  color: var(--warn);
  font-size: 12px;
  line-height: 1.5;
}
