:root {
  --bg:#f3f6fb;
  --panel:#fff;
  --line:#e6ebf2;
  --text:#243043;
  --muted:#7c8aa0;
  --brand:#1f3b5b;
  --brand-2:#2e5278;
  --active:#1d8cf8;
  --ok:#13ce66;
  --warn:#faad14;
  --err:#f56c6c;
}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--text);font-family:"PingFang SC","Microsoft YaHei","Segoe UI",sans-serif}
a{text-decoration:none;color:inherit}
.app{min-height:100vh;display:grid;grid-template-columns:250px 1fr}
.sidebar{background:linear-gradient(180deg,var(--brand),var(--brand-2));color:#dbe8f6;display:grid;grid-template-rows:56px 1fr 48px}
.logo{display:flex;align-items:center;padding:0 16px;font-weight:700;border-bottom:1px solid rgba(255,255,255,.1)}
.menu{padding:10px 0;overflow:auto}
.menu-group-title{padding:8px 16px;color:#a7b8cb;font-size:12px}
.menu a,.menu button{display:block;width:100%;border:0;background:transparent;color:#dbe8f6;text-align:left;padding:10px 16px;cursor:pointer}
.menu a.sub{padding-left:32px;color:#b9c9dc;font-size:13px}
.menu a.active{background:rgba(29,140,248,.2);border-left:3px solid var(--active);padding-left:13px;color:#fff}
.main{display:grid;grid-template-rows:56px 1fr}
.topbar{background:#fff;border-bottom:1px solid var(--line);display:flex;justify-content:space-between;align-items:center;padding:0 16px}
.content{padding:12px;overflow:auto}
.panel{background:var(--panel);border:1px solid var(--line);margin-bottom:10px}
.toolbar,.search-row{display:flex;gap:8px;align-items:end;padding:10px;border-bottom:1px solid #f1f4f8;flex-wrap:wrap}
.search-stack{display:flex;flex-direction:column}
.filter-row{display:grid;gap:10px;padding:10px;border-bottom:1px solid #f1f4f8}
.filter-row.cols-2{grid-template-columns:repeat(2,minmax(320px,1fr))}
.filter-row.cols-3{grid-template-columns:repeat(3,minmax(220px,1fr))}
.filter-row.cols-actions{grid-template-columns:minmax(180px,240px) minmax(180px,220px) 1fr}
.field{min-width:0}
.field-inline{display:flex;gap:8px;align-items:end;flex-wrap:wrap}
.time-combo{display:grid;grid-template-columns:1fr 112px;gap:8px;align-items:center}
.time-picker-hidden{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.hint{font-size:12px;color:var(--muted);margin-top:4px}
.table-wrap{overflow:auto}
table{width:100%;border-collapse:collapse;min-width:780px}
th,td{border-bottom:1px solid #f0f3f8;padding:8px 10px;font-size:13px;text-align:left}
input,select{height:34px;padding:0 10px;border:1px solid #dce3ed;border-radius:3px}
.field select[multiple]{height:auto;min-height:164px;padding:6px 10px}
label{font-size:12px;color:var(--muted);display:block;margin-bottom:4px}
.btn{height:34px;border:none;padding:0 12px;border-radius:3px;color:#fff;cursor:pointer}
.btn.primary{background:#1d8cf8}.btn.success{background:#13ce66}.btn.warn{background:#faad14}.btn.danger{background:#f56c6c}.btn.outline{background:#fff;color:#55657d;border:1px solid #dce3ed}
.btn-compact{height:30px;padding:0 10px;font-size:12px;white-space:nowrap}
.badge{display:inline-block;padding:2px 8px;border-radius:999px;font-size:12px;background:#eef2f8;color:#54657c}
.badge.ok{background:#eafaf1;color:#10a254}.badge.warn{background:#fff6e5;color:#d28700}.badge.err{background:#fdecec;color:#d14242}
.kpi-strip{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;margin-bottom:10px}
.kpi{background:#fff;border:1px solid var(--line);padding:10px}.kpi .k{font-size:12px;color:var(--muted)}.kpi .v{font-size:24px;font-weight:700;margin-top:6px}
.msg{display:none;margin:10px;padding:8px 10px;border-radius:4px;font-size:13px}
.msg.show{display:block}.msg.ok{background:#ecfbf3;color:#16995a}.msg.err{background:#fdeeee;color:#cb3f3f}
.login-bg{min-height:100vh;display:grid;place-items:center;background:linear-gradient(130deg,#244161,#1f2f42)}
.login-wrap{width:min(420px,92vw);background:#fff;border-radius:8px;padding:24px}
.login-title{font-size:28px;font-weight:700;text-align:center;margin:0 0 10px;color:#2d3b50}
.login-form{display:grid;gap:10px}
.cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
.card{background:#fff;border:1px solid var(--line);padding:16px}
.map-canvas{height:540px}
.json-inspector{display:flex;flex-direction:column}
.json-toolbar{display:flex;gap:8px;align-items:center;padding:10px;border-bottom:1px solid #f1f4f8;flex-wrap:wrap}
.json-tab.active{background:#1d8cf8;color:#fff;border-color:#1d8cf8}
.json-spacer{flex:1}
.json-pane{display:none}
.json-pane.active{display:block}
.json-pre{
  margin:0;
  padding:12px;
  white-space:pre-wrap;
  overflow:auto;
  line-height:1.5;
  font-family:"JetBrains Mono","Cascadia Code","Fira Code","Consolas","Menlo","Monaco",monospace;
  font-size:13px;
  background:#fbfdff;
}
.j-key{color:#9b2c2c}
.j-string{color:#1a7f37}
.j-number{color:#1f6feb}
.j-boolean{color:#7a3e9d;font-weight:600}
.j-null{color:#6b7280;font-style:italic}
.j-tree{padding:10px 12px 12px}
.j-tree-node{margin:2px 0}
.j-tree-node summary{cursor:pointer;user-select:none}
.j-tree-children{margin-left:16px;padding-left:10px;border-left:1px dashed #dce3ed}
.j-tree-key{color:#1f3b5b;font-weight:600}
.j-tree-type{color:#6b7280}
.j-tree-leaf{margin:4px 0}
.j-tree-empty{color:#9aa6b2;font-style:italic;margin:4px 0}
.media-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;padding:10px}
.media-block{border:1px solid var(--line);background:#fff}
.media-head{display:flex;justify-content:space-between;align-items:center;padding:10px;border-bottom:1px solid #f1f4f8}
.media-title{font-size:14px;font-weight:700}
.media-sub{font-size:12px;color:var(--muted)}
.media-block table{min-width:100%}
.legend-row{display:flex;gap:14px;align-items:center;flex-wrap:wrap}
.legend-item{display:inline-flex;gap:6px;align-items:center;font-size:12px;color:#5e6d82}
.point-dot{display:inline-block;width:10px;height:10px;border-radius:50%}
.dot-media{background:#ff8a00}
.dot-cam{background:#1e88e5}
.check-grid{display:grid;grid-template-columns:repeat(5,minmax(140px,1fr));gap:8px;padding:10px;border-bottom:1px solid #f1f4f8}
.check-item{display:flex;align-items:center;gap:6px;font-size:12px;color:#4d5e76}
.check-item input{height:auto}
.col-picker{position:relative;display:flex;align-items:center;gap:8px}
.col-picker-panel{
  position:absolute;
  top:40px;
  left:0;
  width:min(420px,88vw);
  max-height:420px;
  overflow:auto;
  background:#fff;
  border:1px solid #dce3ed;
  border-radius:8px;
  box-shadow:0 8px 24px rgba(18,37,63,.18);
  padding:10px;
  display:none;
  z-index:30;
}
.col-picker.open .col-picker-panel{display:block}
.col-picker-title{font-weight:700;color:#1f3b5b;margin:2px 0 8px 2px}
.col-check-list{display:grid;grid-template-columns:1fr;gap:6px}
.col-check-list .check-item{font-size:15px;line-height:1.25;color:#16395f}
.col-check-list .check-item input{transform:scale(1.05)}
.pager{display:flex;align-items:center;gap:8px;padding:10px;border-top:1px solid #f1f4f8}
.pager .meta{color:var(--muted);font-size:12px}
.mono{font-family:"JetBrains Mono","Cascadia Code","Fira Code","Consolas","Menlo","Monaco",monospace}
.action-wrap{display:flex;align-items:center;justify-content:flex-start;white-space:nowrap}
.split-2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.row-click{cursor:pointer}
.row-click:hover{background:#f7fbff}
.drawer-mask{position:fixed;inset:0;background:rgba(20,28,38,.35);z-index:1000;display:none}
.drawer-mask.show{display:block}
.drawer{position:fixed;top:0;right:0;height:100vh;width:min(960px,92vw);background:#fff;box-shadow:-10px 0 30px rgba(0,0,0,.16);transform:translateX(100%);transition:transform .2s ease;z-index:1001;display:grid;grid-template-rows:56px 1fr}
.drawer.show{transform:translateX(0)}
.drawer-head{display:flex;align-items:center;justify-content:space-between;padding:0 12px;border-bottom:1px solid var(--line)}
.drawer-body{padding:10px;overflow:auto}
.log-stream{
  margin:0;
  padding:12px;
  min-height:360px;
  max-height:56vh;
  overflow:auto;
  white-space:pre-wrap;
  word-break:break-word;
  line-height:1.5;
  background:#fbfdff;
  border-top:1px solid #f1f4f8;
  border-bottom:1px solid #f1f4f8;
  font-family:"JetBrains Mono","Cascadia Code","Fira Code","Consolas","Menlo","Monaco",monospace;
  font-size:13px;
}
@media (max-width:960px){
  .app{grid-template-columns:220px 1fr}
  .sidebar{display:grid}
  .kpi-strip,.cards{grid-template-columns:1fr}
}
@media (max-width:1200px){
  .filter-row.cols-2,.filter-row.cols-3,.filter-row.cols-actions{grid-template-columns:1fr}
  .time-combo{grid-template-columns:1fr}
  .media-grid{grid-template-columns:1fr}
  .check-grid,.split-2{grid-template-columns:1fr}
}
