/* carbus/web/style.css —— 大屏驾驶舱（12 列网格 / 高密度 / 无外部资源） */

*,
*::before,
*::after { box-sizing: border-box; }

:root {
  --barh: 34px;
  --pad: 8px;
  --gap: 8px;
  --rows: 8;
  --rowh: calc((100vh - var(--barh) - 2 * var(--pad) - (var(--rows) - 1) * var(--gap)) / var(--rows));

  --bg: #070b10;
  --panel: #0f1821;
  --panel-hi: #14202b;
  --line: #1b2934;
  --line-2: #2a4051;
  --fg: #dce9f3;
  --fg-2: #a8bccb;
  --dim: #6d8292;
  --accent: #38bdf8;
  --ok: #34d399;
  --warn: #fbbf24;
  --danger: #fb7185;
  --violet: #a78bfa;
  --mono: ui-monospace, "Cascadia Mono", "SFMono-Regular", Consolas, monospace;
}

html, body { height: 100%; }

body {
  margin: 0;
  overflow: hidden;
  color: var(--fg);
  background:
    radial-gradient(1100px 620px at 12% -12%, #10325066, transparent 62%),
    radial-gradient(900px 560px at 104% -6%, #1b2b4555, transparent 58%),
    var(--bg);
  font: 12px/1.32 -apple-system, "Segoe UI", "Microsoft YaHei", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  user-select: none;
}

/* ---------- 顶部状态条 ---------- */
#topbar {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 120;
  display: flex;
  align-items: stretch;
  height: var(--barh);
  padding: 0 10px 0 12px;
  background: linear-gradient(180deg, #0e1a24, #0a1219);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 1px 0 #0009, 0 6px 18px #0005;
}

.brand {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-right: 12px;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.3px;
  color: #eaf6ff;
  white-space: nowrap;
}
.brand-logo { color: var(--accent); font-size: 14px; text-shadow: 0 0 10px #38bdf888; }
.brand-sub { color: var(--dim); font-weight: 500; font-size: 11px; letter-spacing: 0.5px; }

.tb {
  display: flex;
  align-items: baseline;
  gap: 6px;
  height: 100%;
  padding: 0 12px;
  border-left: 1px solid var(--line);
  white-space: nowrap;
}
.tb-k { color: var(--dim); font-size: 10.5px; letter-spacing: 0.4px; }
.tb-v {
  color: var(--fg);
  font-size: 12px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}
.tb.tone-ok .tb-v { color: var(--ok); }
.tb.tone-warn .tb-v { color: var(--warn); }
.tb.tone-bad .tb-v { color: var(--danger); }
.tb.tone-dim .tb-v { color: var(--dim); }
#tb-estop.tone-bad { background: #fb718514; box-shadow: inset 0 0 12px #fb718522; }
#tb-estop.tone-bad .tb-v { text-shadow: 0 0 8px #fb718588; }
.tb-spacer { flex: 1; }
.tb-clock { border-left: 1px solid var(--line); color: var(--fg-2); }
.tb-clock .tb-v { font-family: var(--mono); font-weight: 500; color: var(--fg-2); }

.tbtn {
  align-self: center;
  margin-left: 8px;
  height: 22px;
  padding: 0 9px;
  border: 1px solid var(--line-2);
  border-radius: 5px;
  background: #0e1a23;
  color: var(--fg-2);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}
.tbtn:hover { color: var(--fg); border-color: var(--accent); background: #122434; }

/* ---------- 网格 ---------- */
#grid {
  position: fixed;
  inset: var(--barh) 0 0 0;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-auto-rows: var(--rowh);
  grid-auto-flow: row dense;
  gap: var(--gap);
  padding: var(--pad);
  overflow-y: auto;
  overflow-x: hidden;
}

/* ---------- 面板外壳 ---------- */
.panel {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  background: linear-gradient(180deg, #111c26 0%, #0d151d 100%);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: inset 0 1px 0 #ffffff08, 0 6px 16px #00000055;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.panel:hover { border-color: #233747; }

.ph {
  flex: 0 0 26px;
  height: 26px;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0 5px 0 8px;
  background: linear-gradient(180deg, #17242f, #111a23);
  border-bottom: 1px solid var(--line);
  cursor: grab;
  touch-action: none;
}
.ph:active { cursor: grabbing; }
.ph-grip {
  flex: 0 0 9px;
  width: 9px;
  height: 12px;
  opacity: 0.45;
  background-image: radial-gradient(circle, #93aab9 1px, transparent 1.3px);
  background-size: 4px 4px;
}
.ph-title {
  margin: 0;
  font-size: 11.5px;
  font-weight: 650;
  letter-spacing: 0.35px;
  color: #cfe2f0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ph-badge {
  margin-left: auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--dim);
  font-size: 10.5px;
  font-variant-numeric: tabular-nums;
}
.ph-badge.tone-ok { color: var(--ok); }
.ph-badge.tone-warn { color: var(--warn); }
.ph-badge.tone-bad { color: var(--danger); }
.ph-actions { display: flex; gap: 2px; flex: 0 0 auto; }
.ph-btn {
  width: 20px;
  height: 18px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 4px;
  background: transparent;
  color: var(--dim);
  font: inherit;
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
}
.ph-btn:hover { color: var(--fg); background: #ffffff14; border-color: var(--line-2); }
.ph-btn:active { background: #38bdf828; }

.pb {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding: 6px 8px;
}

.panel[data-id="video"] .pb { padding: 0; overflow: hidden; }

/* ---------- 浮动 / 最大化 / 拖拽 ---------- */
#overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
}
.panel.popup,
.panel.maxed,
.panel.dragging { pointer-events: auto; }
.panel.popup,
.panel.maxed {
  box-shadow: 0 26px 70px #000000cc, 0 0 0 1px #38bdf855;
  border-color: #38bdf877;
}
.panel.popup { position: fixed; min-width: 280px; min-height: 160px; }
.panel.maxed {
  position: fixed;
  top: calc(var(--barh) + var(--pad));
  right: var(--pad);
  bottom: var(--pad);
  left: var(--pad);
}
.panel.dragging {
  pointer-events: none;
  opacity: 0.96;
  border-color: var(--accent);
  box-shadow: 0 28px 64px #000000cc, 0 0 0 1px #38bdf877;
  will-change: transform;
  transition: none;
}
/* 拖拽落位占位 */
.panel-ph {
  border: 1.5px dashed #38bdf8aa;
  border-radius: 8px;
  background: #38bdf812;
  box-shadow: inset 0 0 26px #38bdf81c;
  transition: background 120ms ease;
}
/* 右下角缩放柄（仅小窗） */
.panel-rsz {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 5;
  width: 16px;
  height: 16px;
  cursor: nwse-resize;
  touch-action: none;
  opacity: 0.75;
  background:
    linear-gradient(135deg, transparent 44%, #557084 44%, #557084 52%, transparent 52%),
    linear-gradient(135deg, transparent 62%, #557084 62%, #557084 70%, transparent 70%),
    linear-gradient(135deg, transparent 80%, #557084 80%, #557084 88%, transparent 88%);
}
.panel-rsz:hover { opacity: 1; }
body.dragging-active { cursor: grabbing; }
body.dragging-active .panel:not(.dragging) { transition: none; }

/* ---------- 通用控件 ---------- */
.btn {
  height: 26px;
  padding: 0 10px;
  border: 1px solid var(--line-2);
  border-radius: 5px;
  background: linear-gradient(180deg, #16232e, #101a22);
  color: var(--fg-2);
  font: inherit;
  font-size: 11.5px;
  font-weight: 550;
  cursor: pointer;
  white-space: nowrap;
  transition: background 100ms ease, color 100ms ease, border-color 100ms ease;
}
.btn:hover:not(:disabled) { color: var(--fg); border-color: #3d6076; background: #17293a; }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: 0.42; cursor: not-allowed; }
.btn.tiny { height: 21px; padding: 0 7px; font-size: 10.5px; }
.btn.danger { border-color: #7f2b38; color: #ffb3bd; background: linear-gradient(180deg, #3a1620, #281017); }
.btn.danger:hover:not(:disabled) { border-color: var(--danger); color: #fff; background: #4a1a26; }
.btn.warn { border-color: #6b5320; color: #ffd980; }
.btn.ok { border-color: #24624a; color: #86efc4; }
.btn.on { border-color: var(--accent); color: #d7f2ff; background: #123244; }
.btn.pending { border-color: var(--warn); color: var(--warn); box-shadow: 0 0 0 1px #fbbf2433 inset; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 18px;
  padding: 0 6px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: #0d1720;
  color: var(--fg-2);
  font-size: 10.5px;
  font-weight: 550;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.chip.on { border-color: var(--accent); color: #d5f0ff; background: #123142; }
.chip.tone-ok { border-color: #1f6b4f; color: var(--ok); background: #0e2a20; }
.chip.tone-warn { border-color: #7a5a12; color: var(--warn); background: #2a210c; }
.chip.tone-bad { border-color: #7f2b38; color: var(--danger); background: #2a1117; }
.chip.tone-dim { color: var(--dim); }

.dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--dim);
  box-shadow: 0 0 0 2px #ffffff0a;
}
.dot.ok { background: var(--ok); box-shadow: 0 0 7px #34d39988; }
.dot.warn { background: var(--warn); box-shadow: 0 0 7px #fbbf2488; }
.dot.bad { background: var(--danger); box-shadow: 0 0 7px #fb718588; }

.num { font-variant-numeric: tabular-nums; }
.dim { color: var(--dim); }
.ok-t { color: var(--ok); }
.warn-t { color: var(--warn); }
.bad-t { color: var(--danger); }
.hint { color: var(--dim); font-size: 10.5px; line-height: 1.45; }
.empty { display: grid; place-items: center; height: 100%; color: var(--dim); font-size: 11px; text-align: center; padding: 8px; }

.kv-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; padding: 2px 0; border-bottom: 1px dashed #16232d; }
.kv-row:last-child { border-bottom: 0; }
.kv-k { color: var(--dim); font-size: 10.5px; white-space: nowrap; }
.kv-v { color: var(--fg-2); font-size: 11px; font-variant-numeric: tabular-nums; text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- toast / banner / login ---------- */
#toasts {
  position: fixed;
  right: 12px;
  bottom: 12px;
  z-index: 300;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  pointer-events: none;
}
.toast {
  max-width: 460px;
  padding: 7px 11px;
  border: 1px solid var(--line-2);
  border-left: 3px solid var(--accent);
  border-radius: 6px;
  background: #0e1b25ee;
  color: var(--fg);
  font-size: 11.5px;
  box-shadow: 0 10px 26px #000a;
  opacity: 1;
  transform: translateY(0);
  transition: opacity 180ms ease, transform 180ms ease;
}
.toast.tone-ok { border-left-color: var(--ok); }
.toast.tone-warn { border-left-color: var(--warn); }
.toast.tone-bad { border-left-color: var(--danger); }
.toast.out { opacity: 0; transform: translateY(6px); }

#banner {
  position: fixed;
  top: calc(var(--barh) + 10px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 130;
  max-width: min(820px, 80vw);
  padding: 6px 14px;
  border: 1px solid #7a5a12;
  border-radius: 999px;
  background: #241b08ee;
  color: #ffd980;
  font-size: 11.5px;
  box-shadow: 0 8px 22px #0009;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#banner.tone-bad { border-color: #7f2b38; background: #2a1117ee; color: #ffb3bd; }
#banner.tone-ok { border-color: #1f6b4f; background: #0e2a20ee; color: #86efc4; }
#banner[hidden] { display: none; }

.login-mask {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: grid;
  place-items: center;
  background:
    radial-gradient(700px 420px at 50% 8%, #12325099, transparent 65%),
    #05090dee;
  backdrop-filter: blur(3px);
}
.login-mask[hidden] { display: none; }
.login-card {
  width: min(420px, calc(100vw - 40px));
  padding: 26px 26px 20px;
  border: 1px solid var(--line-2);
  border-radius: 12px;
  background: linear-gradient(180deg, #111d27, #0b1319);
  box-shadow: 0 30px 80px #000c, inset 0 1px 0 #ffffff0c;
}
.login-card h1 { margin: 0; font-size: 19px; letter-spacing: 0.4px; color: #eaf7ff; }
.login-logo { color: var(--accent); }
.login-sub-title { color: var(--dim); font-size: 13px; font-weight: 500; }
.login-sub { margin: 6px 0 18px; color: var(--dim); font-size: 11.5px; }
.login-field { display: block; margin-bottom: 12px; }
.login-field span { display: block; margin-bottom: 5px; color: var(--dim); font-size: 10.5px; letter-spacing: 0.4px; }
.login-field input {
  width: 100%;
  height: 36px;
  padding: 0 11px;
  border: 1px solid var(--line-2);
  border-radius: 6px;
  background: #0a1218;
  color: var(--fg);
  font: inherit;
  font-size: 14px;
  letter-spacing: 1px;
  outline: none;
}
.login-field input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px #38bdf822; }
.login-btn {
  width: 100%;
  height: 38px;
  border: 1px solid #1b6d93;
  border-radius: 6px;
  background: linear-gradient(180deg, #0f4a68, #0b3448);
  color: #e6f8ff;
  font: inherit;
  font-size: 13.5px;
  font-weight: 650;
  letter-spacing: 0.5px;
  cursor: pointer;
}
.login-btn:hover { background: linear-gradient(180deg, #125b7f, #0d3f57); }
.login-err { min-height: 16px; margin: 10px 0 0; color: var(--danger); font-size: 11.5px; }
.login-note { margin: 6px 0 0; color: var(--dim); font-size: 10.5px; }

/* ---------- 视频 ---------- */
.vid-wrap { position: relative; width: 100%; height: 100%; background: #000; overflow: hidden; }
.vid-canvas,
.vid-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
.vid-img[hidden], .vid-canvas[hidden] { display: none; }
.vid-top {
  position: absolute;
  top: 6px;
  left: 6px;
  right: 6px;
  display: flex;
  align-items: center;
  gap: 6px;
  pointer-events: none;
}
.vid-cam { color: #cfe0ee; font-size: 10.5px; font-family: var(--mono); text-shadow: 0 1px 3px #000; }
.vid-stats {
  position: absolute;
  left: 6px;
  bottom: 6px;
  padding: 2px 7px;
  border-radius: 4px;
  background: #000000a8;
  color: #a9c0d0;
  font-size: 10.5px;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.vid-tools {
  position: absolute;
  top: 6px;
  right: 6px;
  display: flex;
  gap: 5px;
}
.vid-btn {
  height: 21px;
  padding: 0 8px;
  border: 1px solid #ffffff26;
  border-radius: 4px;
  background: #00000099;
  color: #dbeaf5;
  font: inherit;
  font-size: 10.5px;
  cursor: pointer;
}
.vid-btn:hover { background: #38bdf833; border-color: #38bdf8aa; }
.vid-empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: #7c8f9d;
  font-size: 11.5px;
  text-align: center;
  padding: 16px;
}
.vid-empty[hidden] { display: none; }

/* 视频右侧 HUD：利用 4:3 画面在宽面板里的黑边 */
.vid-hud {
  position: absolute;
  top: 32px;
  right: 6px;
  bottom: 34px;
  width: 196px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 5px 8px;
  border: 1px solid #ffffff14;
  border-radius: 6px;
  background: linear-gradient(180deg, #00000099, #00000066);
  pointer-events: none;
  overflow: hidden;
  font-size: 10px;
  color: #9fb4c4;
}
.vid-wrap.narrow .vid-hud { display: none; }
.vid-hud-h {
  margin-top: 2px;
  padding-bottom: 1px;
  border-bottom: 1px solid #ffffff14;
  color: #6f8494;
  font-size: 9px;
  letter-spacing: 0.6px;
}
.vid-hud-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 1px 0;
  border-bottom: 1px dashed #ffffff0f;
}
.vid-hud-row .k { color: #7f95a5; white-space: nowrap; }
.vid-hud-row .v {
  color: #dbeaf5;
  font-family: var(--mono);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vid-hud-events { margin-top: 2px; display: flex; flex-direction: column; gap: 1px; min-height: 0; overflow: hidden; }
.vid-hud-ev { display: flex; gap: 6px; font-size: 9.5px; color: #a9c0d0; white-space: nowrap; overflow: hidden; }
.vid-hud-ev .t { color: #6f8494; font-family: var(--mono); }
.vid-hud-ev .n { overflow: hidden; text-overflow: ellipsis; }
.vid-hud-ev.bad .n { color: var(--danger); }
.vid-hud-empty { color: #5c7282; font-size: 9.5px; }

/* ---------- 通道 / 驾驶 ---------- */
.ch-body { display: flex; flex-direction: column; height: 100%; min-height: 0; gap: 5px; }
.drive { display: flex; gap: 10px; align-items: stretch; flex: 0 0 auto; }
.thr-col { flex: 0 0 64px; display: flex; flex-direction: column; align-items: center; gap: 3px; }
.ctl-col { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.sl-cap { color: var(--dim); font-size: 10px; letter-spacing: 0.5px; white-space: nowrap; }
.sl-val { font-family: var(--mono); font-size: 11px; color: #bfe6ff; font-variant-numeric: tabular-nums; }

.vslider { width: 38px; height: 132px; display: grid; place-items: center; cursor: ns-resize; touch-action: none; }
.vs-track {
  position: relative;
  width: 12px;
  height: 100%;
  border: 1px solid var(--line-2);
  border-radius: 7px;
  background: #0a131a;
  overflow: hidden;
}
.vs-zero { position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: #ffffff26; }
.vs-fill { position: absolute; left: 0; right: 0; top: 50%; height: 0; background: linear-gradient(180deg, #38bdf866, #38bdf822); }
.vs-knob {
  position: absolute;
  left: -3px;
  right: -3px;
  top: 50%;
  height: 8px;
  margin-top: -4px;
  border-radius: 3px;
  background: linear-gradient(180deg, #c9ecff, #6fc6ee);
  box-shadow: 0 0 8px #38bdf888;
  transition: none;
}
.vslider.active .vs-track { border-color: var(--accent); }
.vslider.locked { opacity: 0.45; cursor: not-allowed; }

.hslider { height: 22px; display: flex; align-items: center; cursor: ew-resize; touch-action: none; }
.hs-track {
  position: relative;
  width: 100%;
  height: 10px;
  border: 1px solid var(--line-2);
  border-radius: 6px;
  background: #0a131a;
  overflow: hidden;
}
.hs-zero { position: absolute; top: 0; bottom: 0; left: 50%; width: 1px; background: #ffffff26; }
.hs-fill { position: absolute; top: 0; bottom: 0; left: 50%; width: 0; background: linear-gradient(90deg, #38bdf822, #38bdf866); }
.hs-knob {
  position: absolute;
  top: -2px;
  bottom: -2px;
  left: 50%;
  width: 8px;
  margin-left: -4px;
  border-radius: 3px;
  background: linear-gradient(180deg, #c9ecff, #6fc6ee);
  box-shadow: 0 0 8px #38bdf888;
}
.hslider.active .hs-track { border-color: var(--accent); }
.hslider.locked { opacity: 0.45; cursor: not-allowed; }
.hslider.mini-sl { height: 16px; flex: 1; }
.hslider.mini-sl .hs-track { height: 8px; }

.sl-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.mini-row { display: flex; gap: 10px; }
.mini { display: flex; align-items: center; gap: 5px; flex: 1; min-width: 0; }
.mini-k { color: var(--dim); font-size: 9.5px; white-space: nowrap; }
.mini-v { font-family: var(--mono); font-size: 10px; color: var(--fg-2); min-width: 30px; text-align: right; }
.sw-row { display: flex; gap: 4px; flex-wrap: wrap; }

.chan-list { flex: 1; min-height: 0; overflow: auto; margin-top: 2px; }
.chan-head,
.chan-row {
  display: grid;
  grid-template-columns: 106px 32px 1fr 56px 50px 56px;
  align-items: center;
  gap: 6px;
  padding: 1px 4px;
  font-size: 11px;
}
.chan-head { color: var(--dim); border-bottom: 1px solid var(--line); font-size: 10px; letter-spacing: 0.3px; position: sticky; top: 0; background: #0d161e; z-index: 1; }
.chan-row { border-bottom: 1px solid #14212b; height: 21px; }
.chan-row:last-child { border-bottom: 0; }
.chan-name { color: var(--fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chan-name b { color: var(--fg); font-weight: 600; }
.chan-name .dim { font-size: 9px; font-family: var(--mono); }
.chan-pin { color: var(--dim); font-family: var(--mono); }
.chan-bar { position: relative; height: 9px; border-radius: 4px; background: #0a131a; border: 1px solid #172531; overflow: hidden; }
.chan-bar::after { content: ""; position: absolute; top: 0; bottom: 0; left: 50%; width: 1px; background: #ffffff20; }
.chan-bar i { position: absolute; top: 0; bottom: 0; left: 50%; width: 0; background: #38bdf8aa; }
.chan-bar i.pos { background: #38bdf8cc; }
.chan-bar i.neg { background: #a78bfacc; }
.chan-bar i.sw { background: #34d399cc; }
.chan-norm, .chan-pulse, .chan-src { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chan-src { color: var(--dim); }
.locked-hint { color: var(--warn); font-size: 10px; }

/* ---------- 权威 / 接管 ---------- */
.auth-wrap { display: flex; flex-direction: column; gap: 6px; height: 100%; min-height: 0; }
.auth-head { display: flex; align-items: center; gap: 10px; }
.auth-badge {
  display: inline-grid;
  place-items: center;
  min-width: 84px;
  height: 30px;
  padding: 0 12px;
  border: 1px solid var(--line-2);
  border-radius: 7px;
  background: #0b151d;
  font-size: 15px;
  font-weight: 750;
  letter-spacing: 1px;
  color: var(--fg);
}
.auth-badge.tone-ok { border-color: #1f6b4f; color: var(--ok); background: #0d241c; }
.auth-badge.tone-warn { border-color: #7a5a12; color: var(--warn); background: #241c0b; }
.auth-badge.tone-bad { border-color: #7f2b38; color: var(--danger); background: #2a1016; animation: none; }
.auth-badge.tone-dim { color: var(--dim); }
.auth-badge.pending { box-shadow: 0 0 0 2px #fbbf2444 inset; }
.auth-sub { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.auth-sub b { font-size: 11px; font-weight: 600; color: var(--fg-2); }
.auth-sub span { font-size: 10px; color: var(--dim); font-family: var(--mono); }
.btn-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 5px; }
.btn-grid .btn { width: 100%; height: 27px; }
.btn-grid .span2 { grid-column: span 2; }
.btn-grid .full { grid-column: 1 / -1; }
.mini-log { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.mini-log-h { color: var(--dim); font-size: 9.5px; letter-spacing: 0.3px; padding-bottom: 2px; border-bottom: 1px solid var(--line); }
.mini-log-rows { flex: 1; min-height: 0; overflow: auto; }
.mini-ev {
  display: grid;
  grid-template-columns: 58px 64px 1fr;
  gap: 6px;
  padding: 1px 0;
  font-size: 10px;
  color: var(--fg-2);
  border-bottom: 1px dashed #14212b;
}
.mini-ev .t { color: var(--dim); font-family: var(--mono); }
.mini-ev .n { color: var(--accent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mini-ev .d { color: var(--dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- 事件流 ---------- */
.ev-wrap { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.ev-bar { display: flex; align-items: center; gap: 4px; flex-wrap: nowrap; overflow-x: auto; padding-bottom: 3px; }
.ev-bar .chip { cursor: pointer; }
.ev-count { margin-left: auto; color: var(--dim); font-size: 10px; font-family: var(--mono); white-space: nowrap; }
.ev-head,
.ev-row {
  display: grid;
  grid-template-columns: 72px 44px 56px 1fr 1.35fr;
  gap: 6px;
  align-items: center;
  font-size: 10.5px;
  padding: 0 3px;
}
.ev-head { color: var(--dim); font-size: 9.5px; border-bottom: 1px solid var(--line); height: 14px; letter-spacing: 0.3px; position: sticky; top: 0; background: #0d161e; z-index: 1; }
.ev-rows { flex: 1; min-height: 0; overflow: auto; font-variant-numeric: tabular-nums; }
.ev-row { height: 15px; border-bottom: 1px solid #111d26; }
.ev-row:hover { background: #ffffff06; }
.ev-t { color: var(--dim); font-family: var(--mono); font-size: 9.5px; }
.ev-src { color: var(--fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-type { color: var(--accent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 9.5px; }
.ev-name { color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-detail { color: var(--dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--mono); font-size: 9.5px; }
.ev-row.t-error .ev-type, .ev-row.t-error .ev-name { color: var(--danger); }
.ev-row.t-authority .ev-type { color: var(--warn); }
.ev-row.t-trigger .ev-type { color: var(--violet); }
.ev-row.t-action .ev-type { color: var(--ok); }
.ev-paused { color: var(--warn); }

/* ---------- 模块卡片 ---------- */
.mod-wrap { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.mod-head { display: flex; align-items: center; gap: 8px; padding-bottom: 3px; }
.mod-count { color: var(--fg-2); font-size: 10.5px; font-weight: 600; }
.mod-hint { color: var(--dim); font-size: 9.5px; margin-left: auto; }
.mod-grid {
  flex: 1;
  min-height: 0;
  overflow: auto;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(206px, 1fr));
  gap: 5px;
  align-content: start;
}
.mod-card {
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #0b141b;
  padding: 4px 6px 5px;
  min-width: 0;
}
.mod-card.warn { border-color: #6f5411; background: #171307; }
.mod-card.stale { border-color: #6f2630; background: #1a0d11; }
.mod-top { display: flex; align-items: baseline; gap: 5px; min-width: 0; }
.mod-label { font-size: 10.5px; font-weight: 650; color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mod-id { color: var(--dim); font-size: 9px; font-family: var(--mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mod-age { margin-left: auto; font-family: var(--mono); font-size: 9.5px; color: var(--dim); white-space: nowrap; }
.mod-card.warn .mod-age { color: var(--warn); }
.mod-card.stale .mod-age { color: var(--danger); }
.mod-kv { display: grid; grid-template-columns: auto 1fr; gap: 0 6px; margin-top: 2px; }
.mod-kk { color: var(--dim); font-size: 9.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mod-vv { color: var(--fg-2); font-size: 9.5px; text-align: right; font-family: var(--mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mod-vv.num { color: #bfe6ff; }
.mod-more { grid-column: 1 / -1; margin-top: 2px; height: 15px; padding: 0; border: 0; background: none; color: var(--accent); font: inherit; font-size: 9px; cursor: pointer; text-align: left; }
.mod-more:hover { text-decoration: underline; }
.mod-lane-bar { position: relative; height: 7px; margin: 3px 0 2px; border-radius: 4px; background: #0a131a; border: 1px solid #172531; overflow: hidden; }
.mod-lane-bar i { position: absolute; top: 0; bottom: 0; left: 50%; width: 6px; margin-left: -3px; border-radius: 2px; background: var(--accent); box-shadow: 0 0 6px #38bdf888; }
.mod-lane-bar::after { content: ""; position: absolute; top: 0; bottom: 0; left: 50%; width: 1px; background: #ffffff30; }
.mod-lane-bar.lost i { background: var(--danger); }
.mod-flat { display: flex; align-items: baseline; gap: 6px; margin-top: 2px; font-size: 10px; }
.mod-flat b { color: #bfe6ff; font-family: var(--mono); font-weight: 600; }
.mod-flat span { color: var(--dim); font-size: 9.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mod-empty { color: var(--dim); font-size: 10.5px; line-height: 1.6; }
.mod-empty code { color: var(--fg-2); font-family: var(--mono); font-size: 10px; background: #0a131a; border: 1px solid #172531; border-radius: 3px; padding: 0 4px; }

/* ---------- 自主 / 状态机 ---------- */
.auto-wrap { display: flex; gap: 12px; height: 100%; min-height: 0; }
.auto-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; min-height: 0; }
.auto-side {
  flex: 0 0 42%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding-left: 10px;
  border-left: 1px solid var(--line);
}
.auto-side-h { color: var(--dim); font-size: 9.5px; letter-spacing: 0.4px; padding-bottom: 2px; border-bottom: 1px solid var(--line); }
.auto-side-rows { flex: 1; min-height: 0; overflow: auto; }
.auto-ev {
  display: grid;
  grid-template-columns: 56px 62px 1fr;
  gap: 6px;
  padding: 1px 0;
  border-bottom: 1px dashed #14212b;
  font-size: 10px;
  color: var(--fg-2);
}
.auto-ev .t { color: var(--dim); font-family: var(--mono); font-size: 9.5px; }
.auto-ev .n { color: var(--accent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.auto-ev .d { color: var(--dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 9.5px; }
.auto-head { display: flex; align-items: center; gap: 6px; }
.auto-chip {
  display: inline-grid;
  place-items: center;
  min-width: 64px;
  height: 24px;
  padding: 0 9px;
  border: 1px solid var(--line-2);
  border-radius: 6px;
  background: #0b151d;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--fg-2);
}
.auto-chip.tone-ok { border-color: #1f6b4f; color: var(--ok); }
.auto-chip.tone-warn { border-color: #7a5a12; color: var(--warn); }
.auto-chip.tone-bad { border-color: #7f2b38; color: var(--danger); }
.auto-sub { color: var(--dim); font-size: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.auto-grid { display: flex; flex-direction: column; gap: 0; }
.auto-bar { display: flex; align-items: center; gap: 6px; }
.auto-bar .k { width: 34px; color: var(--dim); font-size: 9.5px; }
.auto-bar .track { position: relative; flex: 1; height: 7px; border-radius: 4px; background: #0a131a; border: 1px solid #172531; overflow: hidden; }
.auto-bar .track i { position: absolute; top: 0; bottom: 0; left: 50%; width: 0; background: #38bdf8aa; }
.auto-bar .v { width: 44px; text-align: right; font-family: var(--mono); font-size: 9.5px; color: #bfe6ff; }
.auto-note { color: var(--dim); font-size: 10px; line-height: 1.45; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.auto-wait { color: var(--dim); font-size: 10px; line-height: 1.7; }
.auto-wait code { color: var(--fg-2); font-family: var(--mono); font-size: 9.5px; background: #0a131a; border: 1px solid #172531; border-radius: 3px; padding: 0 4px; }

/* ---------- 相机 ---------- */
.cam-list { display: flex; flex-direction: column; gap: 4px; }
.cam-item { border: 1px solid #16242e; border-radius: 5px; padding: 3px 6px; background: #0b141b; }
.cam-top { display: flex; align-items: center; gap: 6px; }
.cam-name { font-family: var(--mono); font-size: 10.5px; color: var(--fg); }
.cam-state { margin-left: auto; font-size: 9.5px; color: var(--dim); }
.cam-meta { display: flex; gap: 10px; color: var(--dim); font-size: 9.5px; font-family: var(--mono); margin-top: 1px; }
.cam-meta b { color: var(--fg-2); font-weight: 600; }
.cam-health { font-size: 9.5px; }

/* ---------- 系统 / 隧道 ---------- */
.sys-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 12px; }
.sys-cell { display: flex; align-items: baseline; justify-content: space-between; gap: 6px; padding: 0; border-bottom: 1px dashed #14212b; font-size: 9.5px; line-height: 1.25; min-width: 0; }
.sys-k { color: var(--dim); white-space: nowrap; }
.sys-v { color: var(--fg-2); font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--mono); font-size: 9.5px; }

.tun-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 12px; }
.tun-row { display: flex; align-items: center; gap: 6px; padding: 1px 0; border-bottom: 1px dashed #14212b; font-size: 10px; min-width: 0; }
.tun-name { color: var(--fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tun-state { margin-left: auto; color: var(--dim); font-size: 9.5px; white-space: nowrap; }
.tun-note { grid-column: 1 / -1; color: var(--dim); font-size: 9.5px; padding-top: 3px; line-height: 1.4; }

/* ---------- 滚动条 ---------- */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: #0a1218; }
::-webkit-scrollbar-thumb { background: #24343f; border-radius: 5px; border: 2px solid #0a1218; }
::-webkit-scrollbar-thumb:hover { background: #334b5b; }
* { scrollbar-width: thin; scrollbar-color: #24343f #0a1218; }

/* ---------- 动效降级 ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0ms !important;
    animation-duration: 0ms !important;
    animation-iteration-count: 1 !important;
  }
}
