/* C 平台样式 · 对齐 B（物泊业务后台 / iView 设计语言）
 *
 * 取值来自 B 后台真实截图采样（不是凭感觉配色）：
 *   主色 var(--brand-500)（B 的"查询/全部"按钮就是它）· 深色导航 #2D3049 / #343951
 *   页面底 #FAFAFA · 分隔 #F0F2F5 · 边框 #DCDFE6 · 标题字 #17233D · 正文 #515A6E
 *   圆角 4px（控件）/ 6px（卡片）· 阴影几乎为零，靠 1px 边框分层
 *
 * 色系锁 B：主色 var(--brand-500) · 深侧栏 #2D3049/#343951。禁止另开色板。
 * 毛玻璃与炫弹窗：按产品要求叠回（半透明层 + backdrop-filter），表格区仍偏实色保可读。
 */

:root {
  /* 主色（B 的绿，iView success） */
  --primary: var(--brand-500);
  --primary-dark: var(--brand-600);
  --primary-light: var(--brand-400);
  --primary-lighter: var(--brand-300);
  --primary-soft: var(--brand-50);
  --primary-line: var(--brand-200);
  --accent-pale: var(--brand-100);
  --scroll: #C5C8CE;
  --scroll-hover: #A8B0BE;

  /* 中性（iView 灰阶） */
  --bg: #FAFAFA;
  --panel: #FFFFFF;
  --line: #E8EAEC;
  --line-strong: #DCDFE6;
  --text: #17233D;
  --text-2: #515A6E;
  --muted: #808695;
  --muted-2: #A8B0BE;

  /* 语义色（iView error / warning / primary-info） */
  --danger: #ED4014;
  --warn: #FF9900;
  --ok: var(--brand-500);
  --info: #2D8CF0;

  /* 状态色（车辆/单据）——三档可辨识，不与品牌绿混淆 */
  --s10: #808695;
  --s20: #FF9900;
  --s30: #2D8CF0;

  /* 兼容旧变量名（有些内联样式还在用） */
  --accent: var(--brand-500);
  --accent-soft: #F0F9EB;

  --radius: 4px;
  --radius-lg: 6px;
  --radius-pill: 999px;
  --shadow-sm: 0 1px 2px rgba(23, 35, 61, .05);
  --shadow: 0 1px 3px rgba(23, 35, 61, .06);
  --shadow-lg: 0 6px 20px rgba(23, 35, 61, .12);
  --grad-brand: var(--brand-500);
  --grad-brand-hover: var(--brand-600);
  --grad-page: #FAFAFA;
  --grad-glass: rgba(255, 255, 255, .72);
  --grad-glass-strong: rgba(255, 255, 255, .86);
  --blur: blur(16px) saturate(1.55);
}


* { box-sizing: border-box; }

/* 页面里大量用 hidden 属性控制显隐，但 .modal/.playbar 等自身带 display:flex，
   会盖掉浏览器默认的 [hidden]{display:none}。统一在根上兜住，避免"一进页面就弹窗"。 */
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0; height: 100%;
  background: var(--bg);
  color: var(--text);
  font: 13px/1.5 -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* 页底：纯浅灰。B 的后台没有渐变也没有柔光——底图越安静，表格越好读。 */
body::before {
  content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: var(--bg);
}

body.console { display: flex; flex-direction: column; overflow: hidden; }

button, input, select { font: inherit; color: inherit; }

.muted { color: var(--muted); }
.small { font-size: 12px; }
.spacer { flex: 1; }

/* 滚动条：细、圆、绿 */
* { scrollbar-width: thin; scrollbar-color: var(--scroll) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-thumb { background: var(--scroll); border-radius: var(--r-sm); }
*::-webkit-scrollbar-thumb:hover { background: var(--scroll-hover); }
*::-webkit-scrollbar-track { background: transparent; }

/* ------------------------------------------------------------ 顶栏 */

.topbar {
  display: flex; align-items: center; gap: 14px;
  padding: 9px 16px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .78) 0%, rgba(255, 255, 255, .62) 100%);
  -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  border-bottom: 1px solid rgba(255, 255, 255, .9);
  box-shadow: 0 6px 24px rgba(11, 125, 69, .07);
  min-height: 52px; flex: 0 0 auto; z-index: 30;
}
.brand { display: flex; align-items: center; gap: 9px; font-size: 14px; white-space: nowrap; }
.brand strong { letter-spacing: .2px; }
.brand .dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--grad-brand);
  box-shadow: var(--focus-ring);
}

.filters { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.filters input#q { width: 180px; }
.daterange { display: flex; align-items: center; gap: 6px; }
.userbox { margin-left: auto; display: flex; align-items: center; gap: 8px; white-space: nowrap; flex-shrink: 0; }
.filters { min-width: 0; flex: 1; }
.filters button, .filters .seg { flex-shrink: 0; white-space: nowrap; }
.brand #projectName { max-width: 240px; overflow: hidden; text-overflow: ellipsis; }

.toast {
  background: var(--grad-glass-strong);
  -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  border: 1px solid rgba(255, 255, 255, .9);
  border-radius: var(--radius);
  padding: 10px 16px; box-shadow: var(--shadow-lg);
  max-width: min(720px, 85vw);
}

/* 表单控件：白玻璃、细绿边、聚焦绿环 */
input[type="text"], input[type="date"], input:not([type]), select {
  padding: 6px 10px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, .92);
  outline: none; transition: .15s;
}
input:focus, select:focus {
  border-color: var(--primary-light);
  box-shadow: var(--focus-ring);
  background: #fff;
}
select { cursor: pointer; }

.btn {
  padding: 6px 13px;
  border: 1px solid var(--line-strong);
  background: rgba(255, 255, 255, .9);
  border-radius: var(--radius);
  cursor: pointer; transition: .15s;
  color: var(--text-2);
}
.btn:hover {
  border-color: var(--primary-light); color: var(--primary-dark);
  background: #fff; box-shadow: 0 4px 14px rgba(11, 125, 69, .10);
}
.btn.primary {
  background: var(--grad-brand); border-color: transparent; color: #fff;
  box-shadow: 0 6px 18px rgba(15, 163, 91, .28);
}
.btn.primary:hover { background: var(--grad-brand-hover); color: #fff; box-shadow: 0 8px 22px rgba(15, 163, 91, .34); }
.btn.ghost { border-color: transparent; background: transparent; }
.btn.ghost:hover { background: rgba(25, 190, 109, .10); box-shadow: none; }
.btn.sm { padding: 4px 10px; font-size: 12px; }
.btn:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; }

.seg {
  display: inline-flex; border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill); overflow: hidden;
  background: rgba(255, 255, 255, .8); padding: 2px;
}
.seg button { border: 0; background: transparent; padding: 4px 13px; cursor: pointer; border-radius: var(--radius-pill); color: var(--text-2); transition: .15s; }
.seg button.on { background: var(--grad-brand); color: #fff; box-shadow: 0 3px 10px rgba(15, 163, 91, .3); }

.chk { display: inline-flex; align-items: center; gap: 5px; color: var(--muted); white-space: nowrap; }
.chk input { accent-color: var(--primary); }
.link { border: 0; background: none; color: var(--primary-dark); cursor: pointer; padding: 0 4px; font-size: 12px; }
.link:hover { color: var(--primary); text-decoration: underline; }

/* ------------------------------------------------------------ 指标条 */

.metrics {
  display: flex; gap: 10px;
  padding: 10px 14px 4px;
  overflow-x: auto; flex: 0 0 auto;
}
.metric {
  padding: 8px 14px 9px;
  min-width: 96px; display: flex; flex-direction: column; gap: 2px;
  border-radius: var(--radius);
  background: var(--grad-glass);
  -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  border: 1px solid rgba(255, 255, 255, .8);
  box-shadow: var(--shadow-sm);
  position: relative; overflow: hidden;
}
.metric::after {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--primary-line);
}
.metric .k { font-size: 11px; color: var(--muted); white-space: nowrap; }
.metric .v {
  font-size: 19px; font-weight: 650; font-variant-numeric: tabular-nums;
  color: var(--text); letter-spacing: -.2px;
}
.metric .v small { font-size: 11px; font-weight: 400; color: var(--muted); margin-left: 3px; }
.metric.alert::after { background: var(--danger); }
.metric.alert .v { color: var(--danger); }
.metric.dim .v { color: var(--muted); }

/* ------------------------------------------------------------ 主区 */

.workspace {
  flex: 1 1 auto; display: grid;
  grid-template-columns: 300px minmax(0, 1fr) 326px;
  /* 行高必须显式给 minmax(0,1fr)：默认的 auto 行会被树的内容撑高，
     结果地图绝对定位后画到底部表格上面去（已经踩过一次）。 */
  grid-template-rows: minmax(0, 1fr);
  gap: 10px; min-height: 0; overflow: hidden;
  padding: 6px 14px 10px;
}
.tree, .panel {
  display: flex; flex-direction: column; min-height: 0;
  border-radius: var(--radius-lg);
  background: var(--grad-glass);
  -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  border: 1px solid rgba(255, 255, 255, .85);
  box-shadow: var(--shadow);
  overflow: hidden;
}

.pane-head {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
  font-weight: 600; color: var(--text);
  font-size: 12.5px;
}
.pane-head .tree-actions { display: flex; gap: 2px; align-items: center; }
.tree-body { overflow: auto; padding: 4px 0 20px; }

/* 树：货主可折叠（点标题整行），组内存放货源单 */
.owner { border-bottom: 1px solid var(--line); }
.owner:last-child { border-bottom: 0; }
.owner-head {
  display: flex; align-items: center; gap: 7px;
  padding: 9px 12px; cursor: pointer; user-select: none;
  transition: background .15s;
}
.owner-head:hover { background: rgba(25, 190, 109, .07); }
.owner-head .caret {
  width: 12px; color: var(--primary); font-size: 10px;
  transition: transform .18s; display: inline-block;
}
.owner-head .name {
  font-weight: 650; font-size: 12.5px; flex: 1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--text);
}
.owner-head .name .login { font-weight: 400; color: var(--muted); font-size: 11px; margin-left: 4px; }
.owner-head .edit {
  border: 0; background: none; cursor: pointer; color: var(--muted-2);
  font-size: 11px; padding: 0 2px; opacity: 0; transition: .15s;
}
.owner-head:hover .edit { opacity: 1; }
.owner-head .edit:hover { color: var(--primary); }
.badge {
  font-size: 10.5px; padding: 1px 7px; border-radius: var(--radius-pill);
  background: var(--primary-soft); color: var(--primary-dark);
  border: 1px solid var(--primary-line);
}
.badge.mode { background: rgba(255, 255, 255, .7); color: var(--muted); border-color: var(--line-strong); }

.pub {
  display: grid; grid-template-columns: 15px minmax(0, 1fr);
  gap: 8px; align-items: start;
  padding: 8px 11px 8px 14px; cursor: pointer;
  border-left: 2px solid transparent;
  transition: background .15s, border-color .15s;
}
.pub:hover { background: rgba(25, 190, 109, .07); }
.pub.on { background: rgba(25, 190, 109, .13); border-left-color: var(--primary); }
.pub input[type="checkbox"] { margin: 2px 0 0; accent-color: var(--primary); }
.pub .body { min-width: 0; }
.pub .route {
  font-size: 12px; line-height: 1.4;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pub .route b { font-weight: 600; }
.pub .meta {
  font-size: 11px; color: var(--muted); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pub .meta .sur { color: var(--primary-dark); font-weight: 600; }
.pub .foot {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-top: 5px;
}
.pub .nums { font-size: 10.5px; color: var(--muted); white-space: nowrap; margin-left: auto; }
.pub .nums .hot { color: var(--sem-warn-text); font-weight: 600; }
.pub .nums .bad { color: var(--danger); font-weight: 600; }

/* 吨位三分列：待发 / 已装 / 已收 */
.tons {
  display: flex; gap: 4px; margin-top: 4px; flex-wrap: wrap;
}
.ton {
  display: inline-flex; align-items: baseline; gap: 2px;
  font-size: 10.5px; padding: 1px 6px; border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, .78); border: 1px solid var(--line);
  color: var(--text-2); font-variant-numeric: tabular-nums;
}
.ton i { font-style: normal; color: var(--muted); font-size: 10px; }
.ton b { font-weight: 600; }
.ton.todo { border-color: #F0DCBF; background: rgba(255, 244, 224, .8); }
.ton.todo b { color: #9A6200; }
.ton.loaded { border-color: #CFE3DA; background: rgba(240, 247, 244, .9); }
.ton.loaded b { color: var(--primary-dark); }
.ton.recv { border-color: #CFDDE8; background: rgba(235, 243, 249, .85); }
.ton.recv b { color: #3D6E93; }
.ton.est { border-style: dashed; }

/* 地图 */
.mapwrap {
  position: relative; min-width: 0;
  border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: var(--shadow);
  border: 1px solid rgba(255, 255, 255, .85);
}
#map { position: absolute; inset: 0; background: #E8EFEB; }

.map-tools {
  position: absolute; top: 12px; left: 54px; z-index: 500;
  background: var(--grad-glass-strong);
  -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  border: 1px solid rgba(255, 255, 255, .9);
  border-radius: var(--radius-pill);
  padding: 6px 12px; display: flex; gap: 11px; align-items: center;
  box-shadow: var(--shadow);
}
.legend {
  position: absolute; bottom: 12px; left: 12px; z-index: 500;
  background: var(--grad-glass-strong);
  -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  border: 1px solid rgba(255, 255, 255, .9);
  border-radius: var(--radius-pill);
  padding: 6px 12px; display: flex; gap: 11px;
  font-size: 11px; color: var(--muted); box-shadow: var(--shadow);
}
.lg { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 3px; }
.lg.s10 { background: var(--s10); } .lg.s20 { background: var(--s20); }
.lg.s30 { background: var(--s30); } .lg.stale { background: #F0B429; }
.lg.unlocated { background: var(--ink-400); } .lg.anomaly { background: var(--danger); }
.mapstate {
  position: absolute; right: 12px; bottom: 48px; z-index: 500; max-width: calc(100% - 24px);
  background: var(--grad-glass-strong);
  -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  border: 1px solid rgba(255, 255, 255, .9);
  border-radius: var(--radius-pill);
  padding: 5px 11px; font-size: 11px; color: var(--muted);
  box-shadow: var(--shadow-sm);
}

/* 车辆标记 */
.vmark { position: relative; display: flex; align-items: center; justify-content: center; }
.vmark .pin {
  width: 22px; height: 22px; border-radius: 50% 50% 50% 4px;
  transform: rotate(-45deg); border: 2px solid #fff;
  box-shadow: 0 2px 6px rgba(42, 51, 48, .3);
}
.vmark .pin.st10 { background: var(--s10); }
.vmark .pin.st20 { background: var(--s20); }
.vmark .pin.st30 { background: var(--s30); }
.vmark .pin.unlocated { background: var(--ink-400); border-style: dashed; }
.vmark .pin.stale { opacity: .7; }
.vmark .flag {
  position: absolute; top: -6px; right: -6px;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--danger); border: 1.5px solid #fff;
  box-shadow: 0 0 0 2px rgba(217, 68, 78, .18);
}
.vmark .plate {
  position: absolute; top: 20px; left: 50%; transform: translateX(-50%);
  font-size: 10px; background: rgba(255, 255, 255, .94);
  padding: 0 4px; border-radius: var(--r-xs);
  white-space: nowrap; color: var(--text);
  box-shadow: 0 1px 4px rgba(42, 51, 48, .12);
}
.cluster {
  display: flex; align-items: center; justify-content: center;
  background: var(--grad-brand); color: #fff; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .95); font-weight: 650; font-size: 12px;
  box-shadow: 0 4px 14px rgba(15, 163, 91, .38);
}

/* 播放条 */
.playbar {
  position: absolute; left: 50%; bottom: 78px; transform: translateX(-50%);
  z-index: 600; display: flex; align-items: center; gap: 9px;
  background: var(--grad-glass-strong);
  -webkit-backdrop-filter: var(--glass-blur-lg); backdrop-filter: var(--glass-blur-lg);
  border: 1px solid rgba(255, 255, 255, .92);
  border-radius: var(--radius-pill);
  padding: 7px 14px; box-shadow: var(--shadow-lg);
  max-width: min(780px, 92%);
}
.playinfo { font-size: 12px; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.playbar input[type="range"] { width: 220px; accent-color: var(--primary); }

/* 右面板 */
.tabs {
  display: flex; align-items: center; gap: 3px;
  border-bottom: 1px solid var(--line); padding: 4px 10px; min-height: 38px;
}
.tabs button {
  border: 0; background: none; padding: 7px 11px; cursor: pointer;
  color: var(--muted); border-radius: var(--radius-pill); transition: .15s;
}
.tabs button:hover { background: rgba(25, 190, 109, .08); }
.tabs button.on { color: #fff; background: var(--grad-brand); font-weight: 600; box-shadow: 0 3px 10px rgba(15, 163, 91, .28); }
.tabs b { font-weight: 600; color: var(--danger); margin-left: 3px; }
.tabs button.on b { color: #fff; }
.panel-body { overflow: auto; padding: 10px; }

.anom {
  border: 1px solid var(--line); border-left: 3px solid var(--muted);
  border-radius: var(--radius); padding: 8px 10px; margin-bottom: 8px;
  background: rgba(255, 255, 255, .82); cursor: pointer;
  transition: .15s;
}
.anom:hover { border-color: var(--primary-light); box-shadow: var(--shadow-sm); background: #fff; }
.anom.lvl-A { border-left-color: var(--danger); }
.anom.lvl-B { border-left-color: var(--warn); }
.anom.lvl-C { border-left-color: var(--s30); }
.anom.lvl-D { border-left-color: var(--ink-400); }
.anom .t { display: flex; justify-content: space-between; gap: 6px; font-weight: 600; }
.anom .meta { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.anom .sug { font-size: 11.5px; color: var(--text-2); margin-top: 5px; line-height: 1.5; }
.anom .acts { display: flex; gap: 6px; margin-top: 7px; }

.kv { display: grid; grid-template-columns: 88px 1fr; gap: 4px 8px; font-size: 12px; }
.kv .k { color: var(--muted); }
.section-title { font-weight: 650; margin: 12px 0 7px; color: var(--text); }
.pill {
  display: inline-block; padding: 1px 8px; border-radius: var(--radius-pill); font-size: 11px;
  background: var(--primary-soft); color: var(--text-2); border: 1px solid var(--line);
}
.pill.warn { background: #FFF4E0; color: #9A6200; border-color: #F0DCBF; }
.pill.bad { background: #FDECEC; color: #B23B37; border-color: #F5CFCF; }
.pill.ok { background: var(--primary-soft); color: var(--primary-dark); border-color: var(--primary-line); }
.empty { color: var(--muted); text-align: center; padding: 32px 12px; line-height: 1.7; }

/* 页面兜底空态：待补齐 / 加载失败。结构一致，只换文案，避免有的页空白、有的页报错 */
.page-pending { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 64px 12px; }
.page-pending b { font-size: 14px; font-weight: 600; color: var(--text, var(--muted)); }
.page-pending span { font-size: 12px; color: var(--muted-2); }

/* 底部表 */
.bottom {
  flex: 0 0 auto; display: flex; flex-direction: column;
  position: relative; z-index: 20;
  margin: 0 14px 12px;
  border-radius: var(--radius-lg);
  background: var(--grad-glass-strong);
  -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  border: 1px solid rgba(255, 255, 255, .9);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.bottom.collapsed .tablewrap { display: none; }
.tablewrap { overflow: auto; max-height: 250px; }
table.grid { width: 100%; border-collapse: collapse; font-size: 12px; }
table.grid th, table.grid td { padding: 6px 10px; border-bottom: 1px solid var(--line); text-align: left; white-space: nowrap; }
table.grid th {
  position: sticky; top: 0; z-index: 1; cursor: default;
  background: linear-gradient(180deg, #F2F7F4 0%, #E5EEE9 100%);
  color: var(--text-2); font-weight: 600;
}
table.grid tbody tr { cursor: pointer; transition: background .12s; }
table.grid tbody tr:hover { background: rgba(25, 190, 109, .07); }
table.grid tbody tr.on { background: rgba(25, 190, 109, .14); }
.num { text-align: right; font-variant-numeric: tabular-nums; }

.pager { display: flex; gap: 8px; align-items: center; padding: 7px 12px; border-top: 1px solid var(--line); }

/* 弹窗：遮罩 + 玻璃卡 */
.modal {
  position: fixed; inset: 0; z-index: 2000;
  display: flex; align-items: center; justify-content: center;
  background: rgba(42, 51, 48, .38);
  -webkit-backdrop-filter: var(--glass-blur-xs); backdrop-filter: var(--glass-blur-xs);
  animation: fadeIn .16s ease-out;
}
/* display:flex 的优先级高于浏览器默认的 [hidden]{display:none}，必须显式盖回来，
   否则页面一加载就会把空弹窗显示出来。 */
.modal[hidden] { display: none; }
.modal-card {
  width: min(780px, 92vw); max-height: 86vh;
  display: flex; flex-direction: column;
  border-radius: var(--radius-lg);
  background: linear-gradient(158deg, rgba(255, 255, 255, .96) 0%, rgba(252, 254, 253, .93) 100%);
  -webkit-backdrop-filter: var(--glass-blur-lg); backdrop-filter: var(--glass-blur-lg);
  border: 1px solid rgba(255, 255, 255, .95);
  box-shadow: 0 24px 60px rgba(11, 125, 69, .26), inset 0 1px 0 #fff;
  animation: popIn .18s cubic-bezier(.2, .9, .3, 1.2);
}
.modal-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 12px 16px; border-bottom: 1px solid var(--line);
}
.modal-head strong { font-size: 13.5px; }
.modal-body { padding: 16px; overflow: auto; }
.modal-body h4 { margin: 14px 0 7px; font-size: 13px; color: var(--text); }

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes popIn { from { opacity: 0; transform: translateY(8px) scale(.985); } to { opacity: 1; transform: none; } }

/* 登录页 */
body.login {
  display: flex; align-items: center; justify-content: center;
  background: var(--grad-page);
}
.login-card {
  width: 356px; padding: 28px 26px;
  border-radius: 20px;
  background: var(--grad-glass);
  -webkit-backdrop-filter: var(--glass-blur-lg); backdrop-filter: var(--glass-blur-lg);
  border: 1px solid rgba(255, 255, 255, .9);
  box-shadow: var(--shadow-lg);
}
.login-card h1 { font-size: 18px; margin: 0 0 5px; letter-spacing: .3px; }
.login-card p { color: var(--muted); font-size: 12px; margin: 0 0 20px; }
.login-card label { display: block; font-size: 12px; color: var(--text-2); margin: 11px 0 5px; }
.login-card input { width: 100%; padding: 9px 11px; }
.login-card .btn { width: 100%; margin-top: 20px; padding: 9px; }
.err { color: var(--danger); font-size: 12px; min-height: 16px; margin-top: 9px; }

/* 后台 */
body.admin { overflow: auto; }
.admin-wrap { max-width: 1180px; margin: 0 auto; padding: 20px; }
.admin-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.admin-head h2 { font-size: 17px; margin: 0; }
.cards { display: grid; grid-template-columns: 290px 1fr; gap: 16px; align-items: start; }
.card {
  border-radius: var(--radius-lg); padding: 16px;
  background: var(--grad-glass);
  -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  border: 1px solid rgba(255, 255, 255, .85);
  box-shadow: var(--shadow);
}
.card h3 { margin: 0 0 11px; font-size: 13px; color: var(--text); }
.card h4 { margin: 16px 0 8px; font-size: 12.5px; color: var(--text-2); }
.row { display: flex; gap: 8px; align-items: center; margin-bottom: 9px; flex-wrap: wrap; }
.projlist { display: flex; flex-direction: column; gap: 7px; }
.projitem {
  padding: 9px 11px; border-radius: var(--radius);
  border: 1px solid var(--line); cursor: pointer;
  background: rgba(255, 255, 255, .7); transition: .15s;
}
.projitem:hover { border-color: var(--primary-light); box-shadow: var(--shadow-sm); }
.projitem.on { border-color: var(--primary); background: rgba(240, 247, 244, .95); box-shadow: 0 4px 14px rgba(15, 163, 91, .14); }
.projitem .n { font-weight: 600; }
.projitem .m { font-size: 11.5px; color: var(--muted); }
.chips { display: flex; gap: 7px; flex-wrap: wrap; }
.chip {
  border: 1px solid var(--line-strong); border-radius: var(--radius-pill);
  padding: 4px 12px; font-size: 12px; cursor: pointer;
  background: rgba(255, 255, 255, .85); color: var(--text-2); transition: .15s;
}
.chip:hover { border-color: var(--primary-light); color: var(--primary-dark); }
.chip.on { background: var(--grad-brand); border-color: transparent; color: #fff; box-shadow: 0 3px 10px rgba(15, 163, 91, .28); }
table.mini { width: 100%; border-collapse: collapse; font-size: 12px; }
table.mini th, table.mini td { text-align: left; padding: 6px 7px; border-bottom: 1px solid var(--line); }
table.mini th { color: var(--muted); font-weight: 600; }
table.mini tbody tr:hover { background: rgba(25, 190, 109, .06); }
/* 正在配置的账号：淡绿底 + 左侧竖条。账号一多最容易犯的错就是"配到了别人头上" */
table.mini tr.sel, table.mini tr.sel:hover { background: var(--primary-soft); }
table.mini tr.sel td:first-child { box-shadow: inset 3px 0 0 var(--primary); }

/* 变更记录 30 条全铺开会把页面拉得很长，限高滚动，要看再滚 */
.audit-box { max-height: 220px; overflow: auto; padding-right: 4px; line-height: 1.7; }
.progress { height: 6px; background: rgba(207, 227, 218, .6); border-radius: var(--r-xs); overflow: hidden; }
.progress > i { display: block; height: 100%; background: var(--grad-brand); width: 0; transition: .3s; }

/* 全屏：藏掉外壳（顶栏 / 指标条 / 底部明细 / 右侧异常面板），
   但**保留左侧线路看板** —— 待发、已装、已收和仓库折叠正是上墙要看的东西，
   连它一起藏等于把核心信息丢掉了。 */
body.console.is-fullscreen .topbar,
body.console.is-fullscreen .metrics,
body.console.is-fullscreen .bottom,
body.console.is-fullscreen .panel { display: none; }
body.console.is-fullscreen .workspace {
  grid-template-columns: 312px minmax(0, 1fr);
  gap: 0; padding: 0;
}
body.console.is-fullscreen .tree {
  border-radius: 0; border: 0; box-shadow: none;
  border-right: 1px solid rgba(11, 125, 69, .12);
  padding-top: 6px;   /* 贴边太紧，上墙看着像被裁掉一截 */
}
body.console.is-fullscreen .mapwrap { border-radius: 0; border: 0; box-shadow: none; }
body.console.is-fullscreen .fs-exit { display: inline-flex !important; }
/* 全屏时工具条要往下让，否则和左上角的"退出全屏"叠在一起 */
body.console.is-fullscreen .map-tools { top: 54px; left: 12px; }

/* 全屏时浮在左上角的返回按钮（平时隐藏） */
.fs-exit {
  display: none; position: absolute; top: 12px; left: 12px; z-index: 700;
  align-items: center; gap: 6px;
  background: var(--grad-glass-strong);
  -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  border: 1px solid rgba(255, 255, 255, .9);
  border-radius: var(--radius-pill); padding: 6px 13px;
  box-shadow: var(--shadow); cursor: pointer; font-size: 12px;
}

/* 工作台体验：按任务分层，保留物泊绿 */
.app-header{height:72px;display:flex;align-items:center;justify-content:space-between;padding:0 36px;background:#ffffffdc;border-bottom:1px solid var(--line);flex-shrink:0}
.experience .brand #projectName{max-width:420px;font-size:12px;margin-left:16px}
.eyebrow{font-size:10px;letter-spacing:2px;color:var(--primary-dark);font-weight:650}
h1{font-size:28px;font-weight:650;letter-spacing:-.6px;margin:6px 0 8px}h2{font-size:23px;margin:6px 0}p{line-height:1.7}
.console-heading,.page-heading{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:26px 36px 18px;flex-shrink:0}
.console-heading p,.page-heading p{margin:0;color:var(--muted);font-size:13px}.heading-actions{display:flex;gap:14px;align-items:center}.heading-actions #syncHint{max-width:230px}
.workspace-nav{display:flex;gap:28px;margin:0 36px;border-bottom:1px solid var(--line-strong);flex-shrink:0}.workspace-nav button{border:0;background:none;color:var(--muted);font-size:14px;padding:14px 2px;cursor:pointer;border-bottom:2px solid transparent}.workspace-nav button.active{color:var(--primary-dark);font-weight:650;border-color:var(--primary)}#navAnomalyCount{background:var(--primary-soft);border-radius: var(--r-sm);padding:2px 6px;font-size:11px}
.data-notice{margin:16px 36px 0;padding:11px 16px;background:#fff;border:1px solid var(--line);border-radius: var(--r-sm);font-size:12px;color:var(--muted);flex-shrink:0}.data-notice.needs-attention{background:#fffaf0;border-color:#eddfc3;color:#826333}
.experience .metrics{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));padding:18px 36px;gap:16px;overflow:visible}.experience .metric{background:#fff;box-shadow:none;padding:17px 20px;border:1px solid var(--line);border-radius: var(--r-md);min-width:0}.experience .metric::after{display:none}.experience .metric .k{font-size:12px}.experience .metric .v{font-size:30px;line-height:1.3;margin-top:6px}.experience .metric .v small{display:block;font-size:11px;line-height:1.5;margin:8px 0 0}
.workspace-filters{padding:18px 36px 0;gap:12px;flex:0 0 auto}.workspace-filters #q{width:240px}.experience .workspace{padding:0 36px 28px;grid-template-columns:280px minmax(0,1fr);gap:18px;min-height:250px}.experience .tree,.experience .mapwrap,.experience .panel{background:#fff;box-shadow:none;border:1px solid var(--line-strong)}.experience .panel{display:none}.experience .tree .tons,.experience .pub .foot{display:none}.experience .pub{padding:13px 16px}.experience .owner-head{padding:15px 16px}.experience .bottom{display:none;box-shadow:none;background:white;margin:20px 36px 28px}.experience .workspace-filters{display:none}
.experience[data-view=orders] .workspace,.experience[data-view=orders] .metrics{display:none}.experience[data-view=orders] .workspace-filters{display:flex}.experience[data-view=orders] .bottom{display:flex;flex:1;min-height:180px}.experience[data-view=orders] .tablewrap{max-height:none;flex:1}.experience table.grid td{padding:15px 16px;font-size:13px}.experience table.grid th{padding:13px 16px;font-size:12px;background:#f6f9f7}
.experience[data-view=anomalies] .metrics{display:none}.experience[data-view=anomalies] .workspace{grid-template-columns:1fr;margin-top:20px}.experience[data-view=anomalies] .tree,.experience[data-view=anomalies] .mapwrap{display:none}.experience[data-view=anomalies] .panel{display:flex}.experience[data-view=anomalies] #panelTabs{display:none}.experience[data-view=anomalies] .panel-body{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px;padding:22px;align-content:start}.experience .anom{padding:18px;background:#fff}.experience .anom .t{font-size:14px}.experience .anom .meta{margin-top:9px;line-height:1.7}.experience .anom .sug{font-size:13px;line-height:1.8;margin-top:12px}.experience .anom .acts{margin-top:16px}.experience .anom .acts button{padding:7px 13px}.experience .vehicle-detail-open{}
.experience.vehicle-detail-open[data-view=overview] .panel{display:flex;position:fixed;right:28px;top:230px;bottom:28px;width:340px;z-index:1100;box-shadow:var(--shadow-lg)}.detail-dismiss{display:block;margin-left:auto}.tools-menu{position:relative}.tools-menu summary{list-style:none}.tools-menu>div{position:absolute;right:0;top:42px;background:white;padding:10px;min-width:180px;border:1px solid var(--line);border-radius: var(--r-md);z-index:1400;box-shadow:var(--shadow)}.tools-menu>div button{display:block;width:100%;text-align:left;margin:4px 0}
.redesigned .admin-wrap{max-width:1320px;padding:0 36px 40px}.redesigned .page-heading{padding:32px 0 26px}.account-layout{display:grid;grid-template-columns:290px minmax(0,1fr);gap:24px}.redesigned .card{background:#fff;box-shadow:none;border:1px solid var(--line-strong);padding:24px}.account-sidebar{padding:20px!important}.field-label{display:block;font-size:12px;font-weight:650;margin-bottom:12px}#accountSearch{width:100%;margin-bottom:16px}.account-item{display:flex;align-items:center;gap:12px;width:100%;padding:16px 10px;border:0;background:transparent;text-align:left;border-radius: var(--r-md);cursor:pointer;margin-bottom:6px}.account-item:hover,.account-item.active{background:var(--primary-soft)}.account-item.active{box-shadow:inset 3px 0 var(--primary)}.account-item strong{display:block;font-size:13px}.account-item small{display:block;color:var(--muted);font-size:11px;margin-top:5px}.account-avatar{display:grid;place-items:center;width:36px;height:36px;background:#e6f1eb;border-radius: var(--r-md);color:var(--primary-dark);font-weight:650}.account-arrow{margin-left:auto;color:var(--muted)}.permission-heading{display:flex;justify-content:space-between;align-items:center;padding:0 0 20px;border-bottom:1px solid var(--line);margin-bottom:26px}.permission-heading p{margin-bottom:0}.permission-detail #grantBox>h3{font-size:17px;margin-bottom:8px}.permission-detail #ownerQ{min-width:200px;padding:12px 14px}.permission-detail #btnSearchOwner{padding:11px 18px;background:var(--primary);color:white;border:0}.permission-detail #ownerHits,.permission-detail #pubHits{display:flex;flex-wrap:wrap;gap:8px;margin:12px 0}.permission-detail table.mini td{padding:15px 10px}.permission-detail table.mini th{padding:12px 10px;background:#f7faf8}.advanced-settings{margin-top:30px;border-top:1px solid var(--line);padding-top:20px}.advanced-settings summary{color:var(--muted);cursor:pointer;font-size:12px}.advanced-settings .chips{margin-top:20px}.account-form{width:min(460px,92vw)}.account-form label{display:block;font-size:12px;color:var(--text-2);margin:18px 0}.account-form input{display:block;width:100%;margin-top:8px;padding:11px 12px}.account-form [type=submit]{width:100%;padding:12px}
@media(max-width:1000px){.app-header{padding:0 20px}.experience .brand #projectName{max-width:240px}.console-heading,.page-heading{padding:20px}.heading-actions #syncHint{display:none}.workspace-nav{margin:0 20px}.data-notice{margin:12px 20px 0}.experience .metrics{padding:16px 20px;gap:10px}.experience .metric{padding:14px}.experience .workspace{padding:0 20px 20px;grid-template-columns:230px minmax(0,1fr)}.experience .bottom{margin:16px 20px}.workspace-filters{padding:16px 20px 0}.account-layout{grid-template-columns:230px minmax(0,1fr)}.redesigned .admin-wrap{padding:0 20px 30px}}
@media(max-width:700px){.experience .brand #projectName{display:none}.console-heading{align-items:flex-start}.console-heading h1{font-size:23px}.console-heading p{max-width:210px}.heading-actions{gap:5px}.heading-actions .tools-menu{display:none}.experience .metrics{grid-template-columns:repeat(2,minmax(0,1fr))}.experience .metric .v{font-size:25px}.experience .workspace{grid-template-columns:1fr}.experience .tree{display:none}.experience[data-view=anomalies] .panel-body{grid-template-columns:1fr}.account-layout{grid-template-columns:1fr}.account-sidebar{max-height:250px;overflow:auto}.redesigned .page-heading{align-items:flex-start}.redesigned .page-heading h1{font-size:23px}.experience .legend{max-width:94%;flex-wrap:wrap;gap:6px}.experience .workspace-filters{flex-wrap:wrap}.experience .vehicle-detail-open[data-view=overview] .panel{left:12px;right:12px;width:auto}}

.anomaly-toolbar{display:none}.experience[data-view=anomalies] .anomaly-toolbar{display:flex;justify-content:space-between;align-items:center;padding:20px 22px 0;gap:20px}.anomaly-toolbar h3{font-size:17px;margin:0 0 5px}.anomaly-toolbar p{margin:0}.experience .metric.actionable{cursor:pointer}.experience .metric.actionable:hover{border-color:var(--primary)}.experience .metric.actionable:focus-visible{outline:3px solid var(--primary-light)}.experience[data-view=overview] .panel .anomaly-toolbar{display:none}.experience[data-view=overview] .panel .tabs{display:none}

.route-picker{display:none}@media(max-width:700px){body.console.experience{overflow:auto;height:auto;min-height:100vh}.experience .workspace{min-height:420px;flex:none}.experience[data-view=orders] .bottom{min-height:500px}.route-picker{display:block}.experience.route-picker-open .tree{display:flex;position:fixed;inset:170px 16px 24px;z-index:1400;box-shadow:var(--shadow-lg)}.experience .map-tools{gap:6px;padding:6px;font-size:11px}.experience .legend{font-size:10px}.experience .playbar{left:8px;right:8px;transform:none;max-width:none;gap:5px;padding:7px}.experience .playbar input[type=range]{width:80px}.experience .playinfo{min-width:0;flex:1}}
.experience .heading-actions{flex-shrink:0}.experience .heading-actions button{white-space:nowrap}

/* ============================================================================
   B 版对齐层（物泊业务后台 / iView 设计语言）
   ----------------------------------------------------------------------------
   上面是历次迭代叠出来的规则，这一层只做三件事：
     ① 去掉毛玻璃与重阴影（B 的表格底下从不透光）；
     ② 圆角收到 4/6px、边框用 #DCDFE6、字号回到 12–13px（B 的密度）；
     ③ 补本轮新增的组件：状态徽标、树内分组、后台项目条。
   只改表现，不动布局骨架——结构一旦动，前面调好的信息层级就白调了。
   ========================================================================== */

/* ① 毛玻璃叠回（仍用 B 色板；表格/树保持较实以免发灰） */
.topbar, .app-header {
  background: var(--grad-glass-strong);
  -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  border-bottom: 1px solid var(--line-strong);
  box-shadow: 0 1px 0 rgba(255,255,255,.6);
}
.metric, .panel, .bottom, .data-notice, .card, .playbar,
.map-tools, .legend, .mapstate, .tools-menu > div {
  background: var(--grad-glass-strong);
  -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  box-shadow: var(--shadow-sm);
}
.tree { background: rgba(255,255,255,.92); box-shadow: none; } /* 左树偏实，保扫读 */

/* ② 圆角与边框：B 的控件是 4px，容器 6px，全站没有 10px 以上的角 */
.btn, .chip, .pill, .seg, .seg button, input, select, textarea,
.account-item, .account-avatar, .modal-card, .tools-menu > div, .data-notice {
  border-radius: var(--r-xs);
}
.metric, .tree, .panel, .mapwrap, .bottom, .card, .login-card { border-radius: var(--r-sm); }
.modal-card { border: 1px solid rgba(255,255,255,.8); }
.pill { border-radius: var(--r-xs); }

/* 顶栏：B 是"左侧深色 logo 块 + 白色工具条" */
.app-header { min-height: 50px; padding: 0 20px; }
.app-header .brand { gap: 10px; }
.app-header .brand .dot {
  width: 22px; height: 22px; border-radius: var(--r-xs); background: #2D3049;
  box-shadow: inset 0 0 0 4px #2D3049, inset 0 0 0 9px var(--primary);
}

/* 顶部导航：做成 B 的 tab 条（白底 + 绿色下划线），不再是胶囊 */
.workspace-nav { gap: 26px; border-bottom: 1px solid var(--line-strong); }
.workspace-nav button { font-size: 13.5px; padding: 12px 0; color: var(--text-2); }
.workspace-nav button:hover { color: var(--primary-dark); }
.workspace-nav button.active { color: var(--primary-dark); font-weight: 600; border-bottom: 2px solid var(--primary); }
#navAnomalyCount { background: #FFF1E8; color: var(--danger); border-radius: var(--r-xs); }

/* 指标卡：B 的"合计条"是浅灰底 + 一个数字，这里保留卡片但压扁、去装饰 */
.experience .metrics { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; padding: 16px 36px 4px; }
.experience .metric { padding: 12px 16px; border: 1px solid var(--line-strong); border-radius: var(--r-sm); }
.experience .metric .k { font-size: 12px; color: var(--text-2); }
.experience .metric .v { font-size: 26px; line-height: 1.25; margin-top: 2px; color: var(--text); }
.experience .metric .v small { font-size: 11px; color: var(--muted); margin-top: 4px; }
.experience .metric.alert { border-color: #FFD6CC; background: #FFF9F7; }
.experience .metric.alert .v { color: var(--danger); }
.experience .metric.actionable:hover { border-color: var(--primary); background: var(--primary-soft); }

/* 按钮：B 的绿是实心、扁平的，没有渐变也没有浮起 */
.btn { border-radius: var(--r-xs); border: 1px solid var(--line-strong); background: #fff; color: var(--text-2); padding: 6px 13px; }
.btn:hover { border-color: var(--primary); color: var(--primary-dark); background: #fff; }
.btn.primary { background: var(--primary); border-color: var(--primary); color: #fff; }
.btn.primary:hover { background: var(--primary-dark); border-color: var(--primary-dark); color: #fff; }
.btn.ghost { border-color: transparent; background: transparent; color: var(--text-2); }
.btn.ghost:hover { background: #F5F7FA; border-color: transparent; color: var(--primary-dark); }
.btn.ghost.danger { color: var(--danger); }
.btn.ghost.danger:hover { background: #FFF1EC; color: var(--danger); }
.btn:disabled, .btn:disabled:hover { background: #F7F8FA; border-color: var(--line); color: var(--muted-2); cursor: not-allowed; }
.seg { border: 1px solid var(--line-strong); background: #fff; padding: 2px; border-radius: var(--r-xs); }
.seg button { border-radius: var(--r-xs); color: var(--text-2); }
.seg button.on { background: var(--primary); color: #fff; }
input, select { border: 1px solid var(--line-strong); border-radius: var(--r-xs); background: #fff; }
input:focus, select:focus { border-color: var(--primary); box-shadow: var(--focus-ring); }

/* 左侧树：恢复吨位三列（上一版把它们藏了），加状态分组标题 */
.experience .tree .tons { display: flex; }
.experience .tree .pub .foot { display: block; }
.tree-summary {
  display: flex; gap: 14px; align-items: center;
  padding: 8px 14px; border-bottom: 1px solid var(--line);
  background: #FCFCFD; font-size: 12px; color: var(--text-2);
}
.tree-summary .tcount b { font-size: 13px; color: var(--primary-dark); }
.tree-group {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 14px; background: #F7F8FA;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  font-size: 11.5px; color: var(--text-2); letter-spacing: .3px;
}
.tree-group .n { color: var(--muted); }
.tree-group.closed { color: var(--muted); background: #FAFAFA; }
.owner-head { padding: 10px 13px; }
.owner-head .name { font-size: 13px; }
.pub { padding: 9px 13px; border-radius: var(--r-xs); border: 1px solid transparent; }
.pub:hover { background: #F7F8FA; }
.pub.on { background: var(--primary-soft); border-color: var(--primary-line); box-shadow: inset 2px 0 0 var(--primary); }
.pub.closed { opacity: .78; }
.pub.closed .route b { color: var(--text-2); }

/* 状态徽标：颜色只表达一件事——还能不能动手 */
.state {
  display: inline-block; margin-left: 6px; padding: 0 5px;
  font-size: 10.5px; line-height: 16px; border-radius: var(--r-xs); font-weight: 600;
  vertical-align: 1px; white-space: nowrap;
}
.state.s-running  { background: var(--brand-100); color: #0E8F52; border: 1px solid #C8EAD3; }
.state.s-open     { background: #EAF4FF; color: #1677C8; border: 1px solid #CFE4F8; }
.state.s-paused   { background: #FFF7E6; color: #B36B00; border: 1px solid #FFE2A8; }
.state.s-full     { background: #F2F3F5; color: #515A6E; border: 1px solid #E1E3E8; }
.state.s-expired  { background: #F2F3F5; color: #808695; border: 1px solid #E1E3E8; }
.state.s-terminated { background: #FFF1EC; color: #D13B0C; border: 1px solid #FFD6CC; }
.state.s-void     { background: #F7F7F8; color: #A8B0BE; border: 1px solid #ECEDEF; }

/* 表格：B 的密度——表头浅灰、12.5px、行高 40 上下 */
table.grid th { background: #F8F8F9; color: var(--text-2); font-weight: 600; font-size: 12px; border-bottom: 1px solid var(--line-strong); }
table.grid th, table.grid td { border-bottom: 1px solid #EBEEF5; }
table.grid tbody tr:hover { background: #F7FAFC; }
table.grid tbody tr.on { background: var(--primary-soft); }
.experience table.grid td { padding: 10px 14px; font-size: 12.5px; }
.experience table.grid th { padding: 9px 14px; background: #F8F8F9; }
table.grid tbody tr.closed-row { color: var(--muted); background: #FCFCFD; }
table.grid tbody tr.closed-row:hover { background: #F7F8FA; }

/* 后台：项目条（一层一条线，先选项目再选账号） */
.project-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  margin: 18px 0 0; padding: 10px 14px; background: #fff;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
}
.project-bar-main { display: flex; align-items: center; gap: 12px; min-width: 0; }
.project-bar-label { font-size: 12px; color: var(--muted); white-space: nowrap; }
.project-tabs { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 2px; }
.project-tab {
  display: flex; align-items: center; gap: 8px; padding: 7px 12px;
  border: 1px solid var(--line-strong); border-radius: var(--r-xs); background: #fff;
  cursor: pointer; white-space: nowrap; font-size: 12.5px; color: var(--text-2);
}
.project-tab:hover { border-color: var(--primary); color: var(--primary-dark); }
.project-tab.on { border-color: var(--primary); background: var(--primary-soft); color: var(--primary-dark); box-shadow: inset 0 0 0 1px var(--primary); }
.project-tab.stopped strong { color: var(--muted); text-decoration: line-through; }
.project-tab .dot { width: 6px; height: 6px; border-radius: 50%; flex: 0 0 auto; }
.project-tab .dot.live { background: var(--primary); }
.project-tab .dot.off { background: var(--muted-2); }
.project-bar-actions { display: flex; gap: 8px; flex: 0 0 auto; }
.danger-note {
  background: #FFF1EC; border: 1px solid #FFD6CC; color: #B32A0B;
  padding: 10px 12px; border-radius: var(--r-xs); font-size: 12.5px; line-height: 1.7; margin: 0 0 12px;
}
.redesigned .admin-wrap, body.admin .admin-wrap { max-width: 1360px; margin: 0 auto; padding: 0 24px 40px; }
body.admin .page-heading { padding: 18px 0 14px; }
body.admin .page-heading h1 { font-size: 20px; letter-spacing: -.2px; }
body.admin .page-heading .eyebrow { font-size: 10px; }
.account-layout { grid-template-columns: 280px minmax(0, 1fr); gap: 16px; }
.account-item { border-radius: var(--r-xs); padding: 10px; }
.account-item:hover, .account-item.active { background: var(--primary-soft); }
.account-item.active { box-shadow: inset 3px 0 0 var(--primary); }
.account-avatar { border-radius: var(--r-xs); width: 30px; height: 30px; background: #EDF7F1; color: var(--primary-dark); font-size: 13px; }
body.admin .card { border: 1px solid var(--line-strong); border-radius: var(--r-sm); padding: 18px; }
body.admin .permission-heading { padding-bottom: 14px; margin-bottom: 18px; }
body.admin .permission-heading h2 { font-size: 18px; margin: 2px 0 4px; }
table.mini th { background: #F8F8F9; font-size: 12px; }
table.mini td { padding: 10px; }
.chip { border: 1px solid var(--line-strong); border-radius: var(--r-xs); background: #fff; padding: 5px 10px; font-size: 12.5px; }
.chip.on { border-color: var(--primary); background: var(--primary-soft); color: var(--primary-dark); }
.chips { gap: 8px; }
.audit-box { max-height: 220px; overflow: auto; line-height: 1.9; }

/* ---------------------------------------------------------------------------
   树内排版修正（窄栏 280px 的硬约束）
   一行里塞「起点 → 终点 + 状态徽标」必然挤，所以：
     · 路线用 flex + 省略号，徽标固定不被压缩；
     · 吨位改三列等宽、标签在数字上方（横排三个标签在 280px 里放不下）；
     · 趟次/车/异常放最后一行，不加粗不抢眼。
   --------------------------------------------------------------------------- */
.pub .route { display: flex; align-items: center; gap: 4px; }
.pub .route b { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 0 1 auto; }
.pub .route .state { flex: 0 0 auto; margin-left: auto; }
.experience .tree .tons { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin-top: 6px; }
.experience .tree .ton {
  display: block; padding: 3px 6px; border: 1px solid var(--line);
  border-radius: var(--r-xs); background: #FBFCFD; text-align: left;
}
.experience .tree .ton i { display: block; font-size: 10px; color: var(--muted); line-height: 1.5; }
.experience .tree .ton b { display: block; font-size: 12.5px; line-height: 1.4; color: var(--text); }
.experience .tree .ton.todo { border-color: #F0E0C4; background: #FFFAF2; }
.experience .tree .ton.todo b { color: #A2650A; }
.experience .tree .ton.loaded { border-color: #D5EDDF; background: #F6FCF8; }
.experience .tree .ton.loaded b { color: var(--primary-dark); }
.experience .tree .ton.recv { border-color: #D6E5F3; background: #F7FBFF; }
.experience .tree .ton.recv b { color: #1C6BA8; }
.experience .tree .pub .foot { display: block; }
.experience .tree .pub .nums { display: block; margin: 5px 0 0; font-size: 11px; }

/* 弹窗：毛玻璃遮罩 + 层次阴影（色仍锁 B；危险按钮必须是红的） */
.modal {
  background: rgba(23, 35, 61, .42);
  -webkit-backdrop-filter: var(--glass-blur-sm);
  backdrop-filter: var(--glass-blur-sm);
  transition: opacity .18s ease;
}
.modal-card {
  background: linear-gradient(160deg, rgba(255,255,255,.96), rgba(240,249,235,.92));
  border: 1px solid rgba(255,255,255,.85);
  border-radius: var(--r-md);
  box-shadow: 0 28px 64px rgba(23, 35, 61, .28), 0 0 0 1px rgba(25,190,109,.08), inset 0 1px 0 #fff;
  -webkit-backdrop-filter: var(--glass-blur-lg);
  backdrop-filter: var(--glass-blur-lg);
  animation: popIn .2s cubic-bezier(.2,.9,.3,1.15);
}
.modal-card .modal-head { border-bottom: 1px solid rgba(220,223,230,.7); padding: 14px 18px; }
.modal-card .modal-body { padding: 18px; }
.tools-menu > div {
  border-radius: 10px !important;
  box-shadow: 0 16px 40px rgba(23,35,61,.18) !important;
  border: 1px solid rgba(255,255,255,.8);
}
.btn.primary.danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn.primary.danger:hover { background: #C9300B; border-color: #C9300B; }
/* 表格里的吨位不要换行成两行：B 的列宽是按最长数字留的 */
table.grid td.num { white-space: nowrap; }

/* 左侧栏加宽到 320px：三块吨位 + 路线 + 徽标挤在 280px 里必然互相压 */
@media (min-width: 1001px) {
  .experience .workspace { grid-template-columns: 320px minmax(0, 1fr); }
}
.experience .tree .pub .route { font-size: 12.5px; }
.experience .tree .pub .route .state { font-size: 10px; padding: 0 4px; }
.experience .tree .ton.none b { color: var(--muted-2); font-weight: 500; }

/* 登录页：左品牌右表单（B 的版式），品牌面板用主色实心，不加渐变光斑 */
body.login { background: #F5F6F8; }
body.login .login-card {
  display: grid; grid-template-columns: 220px 300px; gap: 0;
  width: auto; padding: 0; overflow: hidden; background: #fff;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  box-shadow: 0 4px 18px rgba(23, 35, 61, .08);
}
body.login .login-brand {
  display: flex; flex-direction: column; justify-content: center; gap: 10px;
  padding: 34px 22px; background: var(--primary); color: #fff;
}
body.login .login-logo {
  width: 38px; height: 38px; border-radius: var(--r-sm); background: rgba(255, 255, 255, .18);
  display: grid; place-items: center; font-size: 20px; font-weight: 700; letter-spacing: 1px;
}
body.login .login-brand strong { font-size: 16px; letter-spacing: .5px; }
body.login .login-brand span { font-size: 11.5px; line-height: 1.7; opacity: .88; }
body.login .login-form { padding: 30px 26px 26px; }
body.login .login-form h1 { font-size: 19px; font-weight: 650; margin: 0 0 18px; letter-spacing: 0; }
body.login .login-form label { display: block; font-size: 12px; color: var(--text-2); margin: 12px 0 5px; }
body.login .login-form input { width: 100%; padding: 8px 10px; }
body.login .login-form .btn { width: 100%; margin-top: 20px; padding: 9px; font-size: 13.5px; letter-spacing: 2px; }
body.login .err { color: var(--danger); font-size: 12px; margin-top: 10px; min-height: 16px; }
@media (max-width: 560px) {
  body.login .login-card { grid-template-columns: 1fr; }
  body.login .login-brand { padding: 20px; flex-direction: row; align-items: center; gap: 12px; }
  body.login .login-brand span { display: none; }
}


/* 菜单减法：概览主路径不堆底部明细条（明细走顶部「运输明细」） */
.experience[data-view=overview] .bottom { display: none; }
.experience[data-view=orders] .bottom { display: flex; }

/* ===== B 整壳 20261110v =====
 * 客户前台按 B 在途监控整页复刻（浅色壳）。
 * 顶栏产品区「监控中心」+ 地图上绿页签；左栏车牌密列表贴顶栏下沿。
 * 只作用于 body.console.b-shell。主色 var(--brand-500) · 毛玻璃 KPI · 炫弹窗保留。
 */
body.console.b-shell {
  --primary: var(--brand-500);
  --primary-dark: #0e8f56;
  --primary-soft: #e8f8ef;
  --shell-header: 50px;
  --shell-aside: 300px;
  height: 100vh;
  max-height: 100vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: #fff;
  color: #303133;
}
body.console.b-shell .console-heading,
body.console.b-shell .eyebrow { display: none !important; }

/* ---- 顶栏：左 Logo · 中产品区 · 右报警/账号，48–56px ---- */
body.console.b-shell .app-header {
  height: var(--shell-header);
  min-height: 48px;
  max-height: 56px;
  padding: 0 16px;
  display: flex;
  align-items: center;
  gap: 24px;
  flex-shrink: 0;
  background: #fff;
  border-bottom: 1px solid #EEEEEE;
  box-shadow: none;
  overflow: visible;
  z-index: 2000;
}
body.console.b-shell .app-header .brand {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
body.console.b-shell .app-header .brand strong {
  font-size: 15px;
  font-weight: 650;
  letter-spacing: 0;
  color: #303133;
}
body.console.b-shell .app-header .brand .dot {
  width: 22px;
  height: 22px;
  border-radius: var(--r-sm);
  background: var(--brand-500);
  box-shadow: none;
}
body.console.b-shell .primary-nav,
body.console.b-shell .workspace-nav {
  display: flex;
  align-items: stretch;
  gap: 0;
  flex: 1;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
  height: 100%;
  justify-content: flex-start;
}
body.console.b-shell .nav-item {
  position: relative;
  display: flex;
  align-items: stretch;
  height: 100%;
}
body.console.b-shell .nav-top {
  border: 0;
  background: transparent;
  color: #303133;
  font-size: 14px;
  padding: 0 14px;
  height: 100%;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  line-height: 1;
}
body.console.b-shell .nav-item.has-menu .nav-top::after {
  content: "";
  width: 0;
  height: 0;
  border-left: 3px solid transparent;
  border-right: 3px solid transparent;
  border-top: 4px solid currentColor;
  margin-left: 6px;
  opacity: .55;
}
body.console.b-shell .nav-item.on .nav-top {
  color: var(--brand-700);
  background: rgba(25, 190, 109, .08);
  font-weight: 600;
}
body.console.b-shell .nav-top:hover { color: var(--brand-700); }
body.console.b-shell .nav-drop {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 160px;
  background: #fff;
  border: 1px solid #EEEEEE;
  box-shadow: 0 6px 16px rgba(23, 35, 61, .08);
  z-index: 40;
  padding: 6px 0;
}
body.console.b-shell .nav-item:hover .nav-drop,
body.console.b-shell .nav-item.open .nav-drop { display: block; }
body.console.b-shell .nav-drop button {
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  background: #fff;
  color: #303133;
  font-size: 13px;
  padding: 8px 16px;
  cursor: pointer;
  white-space: nowrap;
}
body.console.b-shell .nav-drop button:hover,
body.console.b-shell .nav-drop button.on {
  color: var(--brand-700);
  background: var(--brand-50);
}
body.console.b-shell .header-right {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-shrink: 0;
  margin-left: auto;
}

/* 报警胶囊：白色圆角卡片，两行数字 + 右侧「去处理」，按 B 实站顶栏形态 */
body.console.b-shell .alarm-caps {
  display: inline-grid;
  grid-template-areas: "today go" "open go";
  grid-template-columns: auto auto;
  align-items: center;
  row-gap: 2px;
  column-gap: 8px;
  height: 36px;
  padding: 0 8px 0 10px;
  border: 1px solid #F0F1F3;
  border-radius: var(--r-sm);
  background: #fff;
  box-shadow: 0 1px 3px rgba(23, 35, 61, .04);
  cursor: pointer;
  font-family: inherit;
}
body.console.b-shell .alarm-caps:hover { border-color: #E2F5EB; }
body.console.b-shell .alarm-caps .cap {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: auto;
  padding: 0;
  font-size: 12px;
  line-height: 15px;
  color: var(--brand-600);
  background: transparent;
  border: 0;
  white-space: nowrap;
}
body.console.b-shell .alarm-caps .cap b { font-size: 12px; font-weight: 700; color: var(--brand-600); }
/* 两行竖排：今日报警在上，今日未处理在下 */
body.console.b-shell .alarm-caps .cap.today { grid-area: today; }
body.console.b-shell .alarm-caps .cap.open { grid-area: open; }
body.console.b-shell .alarm-caps .cap-ico {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  display: inline-block;
  flex: 0 0 auto;
}
body.console.b-shell .alarm-caps .cap-ico.warn { background: #FF9F43; }
body.console.b-shell .alarm-caps .cap-ico.danger { background: #F56C6C; }
body.console.b-shell .alarm-caps .cap.go {
  grid-area: go;
  align-self: center;
  color: var(--brand-600);
  background: var(--brand-50);
  border-radius: var(--r-xs);
  padding: 3px 8px;
  font-size: 12px;
  line-height: 15px;
}
body.console.b-shell .alarm-caps:hover .cap.go { background: #E6F7EF; }
body.console.b-shell .alarm-caps .cap-arrow { font-style: normal; margin-left: 2px; }

/* 账号区：一行名字 + 下拉箭头，账号与退出收进下拉，按 B 实站 */
body.console.b-shell .account { position: relative; }
body.console.b-shell .account-name {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 240px;
  padding: 4px 6px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: #303133;
  font-family: inherit;
  font-size: 13px;
  cursor: pointer;
}
body.console.b-shell .account-name:hover { background: #F5F7FA; }
body.console.b-shell .account-text {
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
body.console.b-shell .account-caret { color: #909399; flex: 0 0 auto; }
body.console.b-shell .account-drop {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  min-width: 168px;
  padding: 4px;
  background: #fff;
  border: 1px solid #EBEEF5;
  border-radius: var(--r-sm);
  box-shadow: 0 6px 20px rgba(23, 35, 61, .08);
  z-index: 2100;
}
body.console.b-shell .account-user {
  padding: 6px 10px 8px;
  color: #909399;
  font-size: 12px;
  border-bottom: 1px solid #F5F7FA;
  margin-bottom: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
body.console.b-shell .account-drop button {
  display: block;
  width: 100%;
  padding: 7px 10px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: #303133;
  font-family: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}
body.console.b-shell .account-drop button:hover { background: var(--brand-50); color: var(--brand-700); }

/* ---- 主骨架：左栏贴顶栏下沿 | 右栏地图铺满 ---- */
body.console.b-shell .shell-body {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: var(--shell-aside) minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  background: #fff;
}
body.console.b-shell.tree-collapsed .shell-body {
  grid-template-columns: 0 minmax(0, 1fr);
}
body.console.b-shell .shell-main {
  position: relative;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: #fff;
}
body.console.b-shell .data-notice { display: none !important; }

/* 概览：页签浮在地图上沿（B 式绿胶囊），不占左栏、不垫高地图 */
body.console.b-shell[data-view=overview] .subtabs {
  position: absolute;
  top: 8px;
  left: 8px;
  right: 200px;
  height: 28px;
  max-height: none;
  padding: 0;
  background: transparent;
  border: 0;
  z-index: 600;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  pointer-events: none;
}
body.console.b-shell[data-view=overview] .subtab-list,
body.console.b-shell[data-view=overview] .subtab-actions,
body.console.b-shell[data-view=overview] .subtab,
body.console.b-shell[data-view=overview] .subtab-actions > * { pointer-events: auto; }
body.console.b-shell .subtab-list { display: flex; align-items: center; height: 100%; gap: 6px; }
body.console.b-shell .subtab {
  height: 26px;
  padding: 0 12px;
  border: 0;
  background: #fff;
  color: #606266;
  font-size: 13px;
  border-radius: var(--r-xs);
  box-shadow: var(--sh-1);
  cursor: pointer;
  border-bottom: 0;
  line-height: 26px;
  display: inline-flex;
  align-items: center;
}
body.console.b-shell .subtab .tab-close {
  margin-left: 6px;
  font-size: 13px;
  line-height: 1;
  opacity: .7;
  font-weight: 400;
}
body.console.b-shell .subtab .tab-close:hover { opacity: 1; }
body.console.b-shell .subtab:hover { color: var(--brand-700); }
body.console.b-shell .subtab.on {
  color: #fff;
  font-weight: 600;
  background: var(--brand-500);
  box-shadow: 0 1px 4px rgba(25,190,109,.35);
}
body.console.b-shell #navAnomalyCount {
  background: #fff;
  color: var(--brand-700);
  border-radius: var(--r-sm);
  padding: 0 5px;
  font-size: 11px;
  line-height: 16px;
  margin-left: 4px;
}
body.console.b-shell .subtab.on #navAnomalyCount { background: rgba(255,255,255,.9); color: var(--brand-700); }
body.console.b-shell #navAnomalyCount:empty { display: none; }
body.console.b-shell .subtab-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
body.console.b-shell .subtab-actions .seg { display: inline-flex; border: 1px solid #EAEAEA; border-radius: var(--r-xs); overflow: hidden; background: #fff; }
body.console.b-shell .subtab-actions .seg button {
  border: 0;
  background: #fff;
  height: 26px;
  padding: 0 10px;
  font-size: 12px;
  color: #606266;
  cursor: pointer;
}
body.console.b-shell .subtab-actions .seg button.on { background: var(--primary-soft); color: var(--brand-700); font-weight: 600; }
body.console.b-shell .daterange { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: #909399; background: #fff; padding: 0 6px; border-radius: var(--r-xs); }
body.console.b-shell .daterange input[type=date] { height: 26px; font-size: 12px; padding: 0 6px; }
body.console.b-shell[data-view=overview] .subtab-actions .btn,
body.console.b-shell[data-view=overview] #syncHint {
  background: #fff;
  box-shadow: var(--sh-1);
  border-radius: var(--r-xs);
  height: 26px;
  line-height: 26px;
  padding: 0 8px;
  font-size: 12px;
}

/* 明细/报警：页签收成顶栏下一条（B 历史监控单据：已打开页签 + 当前绿底） */
body.console.b-shell[data-view=orders] .subtabs,
body.console.b-shell[data-view=anomalies] .subtabs {
  position: relative;
  top: auto; left: auto; right: auto;
  height: 36px;
  max-height: 40px;
  padding: 0 12px;
  background: #fff;
  border-bottom: 1px solid #EEEEEE;
  flex-shrink: 0;
  pointer-events: auto;
  box-shadow: none;
}
body.console.b-shell[data-view=orders] .subtab,
body.console.b-shell[data-view=anomalies] .subtab {
  height: 28px;
  margin-top: auto;
  border-radius: 4px 4px 0 0;
  box-shadow: none;
  background: none;
  border-bottom: 0;
  line-height: 28px;
  padding: 0 12px;
}
body.console.b-shell[data-view=orders] .subtab.on,
body.console.b-shell[data-view=anomalies] .subtab.on {
  color: #fff;
  background: var(--brand-500);
  box-shadow: none;
  font-weight: 600;
}
body.console.b-shell[data-view=orders] .subtab.on #navAnomalyCount,
body.console.b-shell[data-view=anomalies] .subtab.on #navAnomalyCount {
  background: rgba(255,255,255,.9); color: var(--brand-700);
}

/* ---- 左栏：车牌密列表，与地图齐顶 ---- */
body.console.b-shell .tree {
  min-width: 0;
  width: auto;
  max-width: none;
  background: #fff;
  border: 0;
  border-right: 1px solid #EEEEEE;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  box-shadow: none;
  border-radius: 0;
}
body.console.b-shell.tree-collapsed .tree { visibility: hidden; pointer-events: none; }
body.console.b-shell .pane-head {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 10px 6px;
  border-bottom: 1px solid #F0F0F0;
  flex-shrink: 0;
  background: #fff;
}
body.console.b-shell .tree-filters {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 8px;
}
body.console.b-shell .tree-filters #q,
body.console.b-shell #q {
  flex: 1 1 100%;
  min-width: 0;
  height: 28px;
  padding: 0 8px;
  font-size: 12px;
  border: 1px solid #E4E7ED;
  border-radius: var(--r-xs);
  background: #fff;
}
body.console.b-shell .tree-filters .chk {
  font-size: 12px;
  color: #606266;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 0;
  white-space: nowrap;
}
body.console.b-shell .tree-filters .link,
body.console.b-shell .owner-filter-actions .link,
body.console.b-shell .tree-actions .link {
  border: 0;
  background: none;
  color: var(--brand-700);
  font-size: 12px;
  cursor: pointer;
  padding: 0;
}
body.console.b-shell .tree-summary {
  padding: 2px 10px 6px;
  font-size: 12px;
  color: #909399;
  display: flex;
  gap: 10px;
  flex-shrink: 0;
  background: #fff;
  border-radius: 0;
}
body.console.b-shell .tree-summary .tcount b { font-size: 12px; color: var(--brand-700); }
body.console.b-shell .tree-summary .tcount.bad b,
body.console.b-shell .tree-summary .tcount.bad { color: #E6A23C; }

/* 线路筛选：折叠面板，不占主列表 */
body.console.b-shell .owner-filter {
  flex: 0 1 auto;
  max-height: 42%;
  overflow: hidden;
  border-bottom: 1px solid #F0F0F0;
  background: #FAFAFA;
}
body.console.b-shell .owner-filter > summary {
  list-style: none;
  cursor: pointer;
  padding: 6px 10px;
  font-size: 12px;
  color: #606266;
  display: flex;
  align-items: center;
  gap: 6px;
}
body.console.b-shell .owner-filter > summary::-webkit-details-marker { display: none; }
body.console.b-shell .owner-filter > summary::before { content: "▸"; color: #c0c4cc; font-size: 11px; }
body.console.b-shell .owner-filter[open] > summary::before { content: "▾"; }
body.console.b-shell .owner-filter #ownerFilterHint { color: #909399; font-weight: 400; }
body.console.b-shell .owner-filter-actions {
  display: flex;
  gap: 10px;
  padding: 0 10px 6px;
}
body.console.b-shell .owner-filter-body {
  overflow: auto;
  max-height: 220px;
  padding: 0 0 8px;
}
body.console.b-shell .owner { margin: 0; border: 0; }
body.console.b-shell .owner-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  cursor: pointer;
  font-size: 12px;
}
body.console.b-shell .owner-head:hover { background: var(--brand-50); }
body.console.b-shell .owner-head .name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
body.console.b-shell .owner-head .login { font-weight: 400; color: #909399; margin-left: 4px; font-size: 11px; }
body.console.b-shell .owner-head .edit { border: 0; background: none; color: #c0c4cc; cursor: pointer; padding: 0 2px; }
body.console.b-shell .owner-head .count { font-size: 12px; color: #909399; margin-left: auto; }
body.console.b-shell .tree-group {
  display: flex;
  justify-content: space-between;
  padding: 2px 10px 2px 20px;
  font-size: 11px;
  color: #909399;
  background: transparent;
  border: 0;
}
body.console.b-shell .pub {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px 3px 16px;
  border: 0;
  border-radius: 0;
  background: transparent;
  margin: 0;
  cursor: pointer;
  min-height: 26px;
}
body.console.b-shell .pub .tons,
body.console.b-shell .pub .foot,
body.console.b-shell .pub .meta { display: none !important; }
body.console.b-shell .pub .body { display: flex; align-items: center; gap: 8px; min-width: 0; flex: 1; }
body.console.b-shell .pub .route {
  flex: 1; min-width: 0; font-size: 12px; line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
body.console.b-shell .pub .nums { flex-shrink: 0; font-size: 11px; color: #909399; }
body.console.b-shell .pub .nums .hot { color: var(--brand-700); font-weight: 650; }
body.console.b-shell .pub .nums .bad { color: #c45656; }
body.console.b-shell .pub.on { background: var(--brand-50); }
body.console.b-shell .pub.closed { opacity: .7; }
body.console.b-shell .pub .state { margin-left: 6px; font-size: 11px; padding: 0 5px; height: 18px; line-height: 18px; border-radius: var(--r-xs); background: #e8f8ef; color: var(--brand-700); display: inline-block; vertical-align: middle; }

/* 车牌密列表（对标 B：勾选 + 车牌 + 状态/定位小标） */
body.console.b-shell .veh-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  background: #fff;
  padding: 0 0 12px;
}
body.console.b-shell .veh-group-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 10px 5px;
  font-size: 13px;
  font-weight: 650;
  color: #303133;
  cursor: pointer;
  background: #fff;
  position: sticky;
  top: 0;
  z-index: 1;
}
body.console.b-shell .veh-group-head:hover { background: #fafafa; }
body.console.b-shell .veh-group-head .caret { color: #c0c4cc; font-size: 11px; width: 12px; }
body.console.b-shell .veh-group-head .name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.console.b-shell .veh-group-head .count { color: #909399; font-weight: 400; font-size: 12px; }
body.console.b-shell .veh-row {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  padding: 0 10px 0 22px;
  font-size: 13px;
  cursor: pointer;
  white-space: nowrap;
  color: #303133;
}
body.console.b-shell .veh-row:hover,
body.console.b-shell .veh-row.on { background: var(--brand-50); }
body.console.b-shell .veh-row input[type=checkbox] { margin: 0; flex-shrink: 0; accent-color: var(--brand-700); }
body.console.b-shell .veh-plate {
  font-weight: 500;
  min-width: 76px;
  color: #303133;
}
body.console.b-shell .veh-speed {
  color: var(--brand-700);
  font-size: 12px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
body.console.b-shell .veh-marks {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}
body.console.b-shell .veh-mark {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 11px;
  line-height: 1;
  color: #909399;
  white-space: nowrap;
}
body.console.b-shell .veh-mark::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}
body.console.b-shell .veh-mark.stale { color: #F56C6C; }
body.console.b-shell .veh-mark.unloc { color: #909399; }
body.console.b-shell .veh-mark.anom { color: #E6A23C; }
body.console.b-shell .veh-mark.arrive { color: var(--brand-700); }
body.console.b-shell .veh-list .empty { padding: 24px 16px; font-size: 12px; color: #909399; text-align: center; }
body.console.b-shell .tree-reopen {
  display: none;
  position: absolute;
  left: 8px;
  top: calc(var(--shell-header) + 8px);
  z-index: 700;
  height: 26px;
  padding: 0 10px;
  border: 1px solid #EAEAEA;
  background: #fff;
  color: var(--brand-700);
  border-radius: var(--r-xs);
  font-size: 12px;
  cursor: pointer;
  box-shadow: var(--sh-1);
}
body.console.b-shell.tree-collapsed .tree-reopen { display: inline-flex; align-items: center; }

/* 地图：上沿贴顶栏（页签浮层不占位），占满右栏 */
body.console.b-shell .workspace {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  gap: 0;
  padding: 0;
  margin: 0;
  background: #fff;
}
body.console.b-shell .mapwrap,
body.console.b-shell .panel {
  border-radius: 0;
  box-shadow: none;
  background: #fff;
}
body.console.b-shell .mapwrap {
  position: relative;
  min-height: 0;
  border: 0;
  background: #fff;
}
body.console.b-shell .mapwrap #map { position: absolute; inset: 0; }
body.console.b-shell[data-view=overview] .mapstate { display: none; }
body.console.b-shell .map-tools {
  position: absolute;
  top: 8px;
  right: 52px;
  left: auto;
  display: flex;
  align-items: center;
  gap: 0;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  z-index: 500;
  font-size: 12px;
}
body.console.b-shell .map-tools .chk,
body.console.b-shell .map-tools .btn {
  margin: 0;
  color: #303133;
  background: #fff;
  border: 1px solid #EAEAEA;
  border-right-width: 0;
  height: 28px;
  padding: 0 10px;
  display: inline-flex;
  align-items: center;
  box-shadow: var(--sh-1);
  font-size: 12px;
  border-radius: 0;
}
body.console.b-shell .map-tools .chk:first-child { border-radius: 4px 0 0 4px; }
body.console.b-shell .map-tools .btn,
body.console.b-shell .map-tools :last-child {
  border-right-width: 1px;
  border-radius: 0 4px 4px 0;
}

/* KPI：地图底单行条，数字贴 B（主项绿色 16–18px） */
body.console.b-shell .metrics,
body.console.b-shell.experience .metrics {
  position: absolute;
  left: 12px;
  right: 72px;
  bottom: 10px;
  top: auto;
  height: 44px;
  max-height: 48px;
  min-height: 0;
  display: flex !important;
  grid-template-columns: none;
  align-items: center;
  gap: 0;
  padding: 0 8px;
  margin: 0;
  overflow: hidden;
  background: rgba(255,255,255,.92);
  -webkit-backdrop-filter: var(--glass-blur-sm);
  backdrop-filter: var(--glass-blur-sm);
  border: 1px solid #EAEAEA;
  border-radius: var(--r-xs);
  box-shadow: 0 2px 8px rgba(23, 35, 61, .06);
  z-index: 500;
}
body.console.b-shell .metric,
body.console.b-shell.experience .metric {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 0 14px;
  margin: 0;
  min-width: 0;
  background: transparent !important;
  border: 0;
  border-right: 0;
  border-radius: 0 !important;
  box-shadow: none !important;
}
body.console.b-shell .metric::after { display: none !important; }
body.console.b-shell .metric .k,
body.console.b-shell.experience .metric .k {
  font-size: 12px;
  color: #909399;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
}
body.console.b-shell .metric .v,
body.console.b-shell.experience .metric .v {
  font-size: 18px;
  font-weight: 700;
  line-height: 1;
  margin: 0;
  color: var(--brand-700);
  white-space: nowrap;
}
body.console.b-shell .metric .v small,
body.console.b-shell.experience .metric .v small {
  display: inline;
  font-size: 12px;
  font-weight: 400;
  color: #909399;
  margin: 0 0 0 6px;
  line-height: 1;
}
body.console.b-shell .metric.actionable:hover { background: var(--brand-50) !important; }
body.console.b-shell .metric.alert .v { color: #F56C6C; }
body.console.b-shell .kpi-toggle {
  position: absolute;
  right: 12px;
  bottom: 16px;
  z-index: 510;
  height: 28px;
  padding: 0 10px;
  background: #fff;
  border: 1px solid #EAEAEA;
  border-radius: var(--r-xs);
}
body.console.b-shell .legend { display: none !important; }
body.console.b-shell .metric .k .lg {
  width: 8px; height: 8px; border-radius: 50%; display: inline-block;
}

body.console.b-shell .playbar {
  left: 12px;
  right: 12px;
  bottom: 62px;
  transform: none;
  max-width: none;
  width: auto;
}

/* 详情抽屉：贴顶栏下，禁止 top:230 */
body.console.b-shell.vehicle-detail-open[data-view=overview] .panel,
body.console.b-shell.experience.vehicle-detail-open[data-view=overview] .panel {
  display: flex;
  position: fixed;
  top: calc(var(--shell-header) + 8px);
  right: 12px;
  bottom: 66px;
  left: auto;
  width: 360px;
  z-index: 1100;
  background: rgba(255,255,255,.94);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  border: 1px solid #EAEAEA;
  border-radius: var(--r-sm);
  box-shadow: 0 8px 28px rgba(23, 35, 61, .12);
}
body.console.b-shell[data-view=overview] .panel { display: none; }
body.console.b-shell[data-view=overview] .panel .anomaly-toolbar,
body.console.b-shell[data-view=overview] .panel .tabs { display: none; }

body.console.b-shell[data-view=overview] .bottom {
  display: flex;
  position: fixed;
  left: calc(var(--shell-aside) + 12px);
  right: 12px;
  bottom: 62px;
  top: auto;
  max-height: 36vh;
  margin: 0;
  background: rgba(255,255,255,.94);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  border: 1px solid #EAEAEA;
  border-radius: var(--r-sm);
  z-index: 520;
  box-shadow: 0 8px 24px rgba(23, 35, 61, .1);
}
body.console.b-shell[data-view=overview] .bottom.collapsed { display: none; }
body.console.b-shell.tree-collapsed[data-view=overview] .bottom { left: 12px; }

/* ---- 明细页 ---- */
body.console.b-shell .workspace-filters {
  display: none;
  align-items: center;
  gap: 10px;
  padding: 8px 16px;
  margin: 0;
  flex: 0 0 auto;
  background: #fff;
  border-bottom: 1px solid #EEEEEE;
}
body.console.b-shell .workspace-filters #qSlot { display: flex; min-width: 240px; }
body.console.b-shell .workspace-filters #q { width: 240px; flex: 0 0 240px; }
body.console.b-shell[data-view=orders] .tree,
body.console.b-shell[data-view=anomalies] .tree,
body.console.b-shell[data-view=orders] .tree-reopen,
body.console.b-shell[data-view=anomalies] .tree-reopen { display: none !important; }
body.console.b-shell[data-view=orders] .shell-body,
body.console.b-shell[data-view=anomalies] .shell-body { grid-template-columns: 1fr; }
body.console.b-shell[data-view=orders] .workspace { display: none; }
body.console.b-shell[data-view=orders] .workspace-filters { display: flex; }
body.console.b-shell[data-view=orders] .bottom {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
  position: relative;
  left: auto; right: auto; bottom: auto;
  max-height: none;
  flex-direction: column;
  background: #fff;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
body.console.b-shell[data-view=orders] .bottom.collapsed { display: flex; }
body.console.b-shell[data-view=orders] .tablewrap { max-height: none; flex: 1; }
body.console.b-shell[data-view=orders] table.grid td { padding: 8px 12px; font-size: 13px; }
body.console.b-shell[data-view=orders] table.grid th { padding: 8px 12px; font-size: 12px; background: #FAFAFA; }
body.console.b-shell[data-view=orders] .kpi-toggle { display: none; }

/* ---- 异常页 ---- */
body.console.b-shell[data-view=anomalies] .mapwrap { display: none; }
body.console.b-shell[data-view=anomalies] .workspace {
  display: grid;
  grid-template-columns: 1fr;
  flex: 1;
  min-height: 0;
}
body.console.b-shell[data-view=anomalies] .panel {
  display: flex;
  flex-direction: column;
  border: 0;
  background: #fff;
  position: relative;
  width: auto;
  top: auto; right: auto; bottom: auto; left: auto;
}
body.console.b-shell[data-view=anomalies] #panelTabs { display: none; }
body.console.b-shell[data-view=anomalies] .anomaly-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 16px;
  gap: 16px;
  border-bottom: 1px solid #EEEEEE;
}
body.console.b-shell[data-view=anomalies] .anomaly-toolbar h3 { font-size: 14px; margin: 0 0 2px; }
body.console.b-shell[data-view=anomalies] .panel-body {
  display: block;
  padding: 0;
  overflow: auto;
}
body.console.b-shell[data-view=anomalies] .anom {
  padding: 8px 16px;
  margin: 0;
  border: 0;
  border-bottom: 1px solid #F0F0F0;
  border-radius: 0;
  background: #fff;
  box-shadow: none;
}
body.console.b-shell[data-view=anomalies] .anom .t { font-size: 13px; }
body.console.b-shell[data-view=anomalies] .kpi-toggle,
body.console.b-shell[data-view=anomalies] .bottom { display: none; }

/* 全屏：只留地图 */
body.console.b-shell.is-fullscreen .app-header,
body.console.b-shell.is-fullscreen .subtabs,
body.console.b-shell.is-fullscreen .metrics,
body.console.b-shell.is-fullscreen .kpi-toggle,
body.console.b-shell.is-fullscreen .bottom,
body.console.b-shell.is-fullscreen .panel,
body.console.b-shell.is-fullscreen .tree,
body.console.b-shell.is-fullscreen .tree-reopen { display: none !important; }
body.console.b-shell.is-fullscreen .shell-body { grid-template-columns: 1fr; }
body.console.b-shell.is-fullscreen .workspace { grid-template-columns: 1fr; flex: 1; }
body.console.b-shell.is-fullscreen .mapwrap { border: 0; }
body.console.b-shell.is-fullscreen .fs-exit { display: inline-flex !important; }
body.console.b-shell.is-fullscreen .map-tools { top: 54px; left: 12px; right: auto; }

body.console.b-shell .modal-card {
  border-radius: var(--r-sm);
  background: #fff;
  box-shadow: 0 12px 40px rgba(23, 35, 61, .18), 0 0 0 1px rgba(25,190,109,.12);
}
body.console.b-shell .cluster {
  background: var(--brand-500);
  color: #fff;
}

@media (max-width: 1000px) {
  body.console.b-shell { --shell-aside: 280px; }
  body.console.b-shell .app-header { padding: 0 12px; gap: 12px; }
  body.console.b-shell .account-text { max-width: 120px; }
  body.console.b-shell .alarm-caps { column-gap: 6px; height: 34px; }
  body.console.b-shell .alarm-caps .cap { font-size: 11px; }
  body.console.b-shell .alarm-caps .cap.go { padding: 2px 6px; }
}
@media (max-width: 700px) {
  body.console.b-shell { overflow: auto; height: auto; min-height: 100vh; }
  body.console.b-shell .shell-body { grid-template-columns: 1fr; min-height: 60vh; }
  body.console.b-shell .tree { display: none; }
  body.console.b-shell.route-picker-open .tree {
    display: flex;
    visibility: visible;
    pointer-events: auto;
    position: fixed;
    inset: calc(var(--shell-header) + 8px) 12px 12px;
    z-index: 1400;
    max-width: none;
    width: auto;
    background: #fff;
    box-shadow: 0 8px 28px rgba(23, 35, 61, .16);
  }
  body.console.b-shell[data-view=overview] .bottom { left: 8px; right: 8px; }
  body.console.b-shell .tools-menu { display: none; }
  body.console.b-shell[data-view=overview] .subtabs { right: 8px; }
}

/* ---------- B 复刻：整栏收起、三层树、独立页、深色大屏 ---------- */
body.console.b-shell.page-mode .tree,
body.console.b-shell.page-mode .tree-reopen { display: none !important; }
body.console.b-shell.page-mode .shell-body { grid-template-columns: 1fr; }
body.console.b-shell.page-mode .workspace-filters,
body.console.b-shell.page-mode .kpi-toggle { display: none !important; }
body.console.b-shell.page-mode .subtabs { position: relative; left: 0; right: 0; top: 0; }

body.console.b-shell .page-host {
  flex: 1;
  min-height: 0;
  overflow: auto;
  background: #F5F7F8;
  padding: 12px 16px 20px;
}
body.console.b-shell .page-head { display: flex; align-items: center; gap: 16px; margin-bottom: 12px; }
body.console.b-shell .page-head h1 { margin: 0; font-size: 16px; font-weight: 600; color: #303133; }
body.console.b-shell .page-tabs { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
body.console.b-shell .page-q { height: 32px; border: 1px solid #DCDFE6; border-radius: var(--r-xs); padding: 0 10px; min-width: 200px; }
body.console.b-shell .page-table-wrap { background: #fff; border: 1px solid #EEEEEE; border-radius: var(--r-xs); overflow: auto; }
body.console.b-shell table.page-grid { width: 100%; border-collapse: collapse; }
body.console.b-shell table.page-grid th { background: #FAFAFA; font-size: 12px; font-weight: 600; color: #606266; padding: 10px 12px; border-bottom: 1px solid #EBEEF5; text-align: left; }
body.console.b-shell table.page-grid td { font-size: 13px; color: #303133; padding: 9px 12px; border-bottom: 1px solid #F2F6FC; }
body.console.b-shell table.page-grid td.empty { text-align: center; color: #909399; padding: 48px 12px; }

body.console.b-shell .scope-tree { flex: 1; overflow: auto; padding: 0 0 12px; }
body.console.b-shell .tree-actions { display: flex; gap: 10px; padding: 4px 10px 8px; font-size: 12px; }
body.console.b-shell .owner-head { display: flex; align-items: center; gap: 6px; padding: 6px 10px; cursor: pointer; font-size: 13px; }
body.console.b-shell .owner-head .name { flex: 1; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.console.b-shell .owner-head .login { margin-left: 6px; color: #909399; font-weight: 400; font-size: 11px; }
body.console.b-shell .owner-head .edit,
body.console.b-shell .pub .edit { border: 0; background: none; color: #909399; cursor: pointer; padding: 0 4px; }
body.console.b-shell .owner-head .edit:hover,
body.console.b-shell .pub .edit:hover { color: var(--brand-700); }
body.console.b-shell .pub { display: grid; grid-template-columns: 16px 16px 1fr; gap: 4px; align-items: start; padding: 4px 8px 4px 18px; cursor: pointer; }
body.console.b-shell .pub .body { grid-column: 3; min-width: 0; }
body.console.b-shell .pub .route { display: flex; align-items: center; gap: 4px; font-size: 12.5px; }
body.console.b-shell .pub .place { margin-top: 1px; }
body.console.b-shell .pub-vehicles { padding: 0 8px 6px 36px; }
body.console.b-shell .pub-vehicles .empty.tiny { font-size: 11px; color: #909399; padding: 4px 0; }
body.console.b-shell .scope-tree .veh-row {
  display: grid; grid-template-columns: 16px 88px 1fr auto; gap: 4px; align-items: center;
  height: 26px; font-size: 12px; padding: 0 4px; border-radius: var(--r-xs); cursor: pointer;
}
body.console.b-shell .scope-tree .veh-row:hover { background: var(--brand-50); }
body.console.b-shell .scope-tree .veh-row.on { background: var(--brand-50); color: var(--brand-700); }
body.console.b-shell .scope-tree .veh-plate { font-weight: 600; letter-spacing: .3px; }
body.console.b-shell .scope-tree .veh-speed { color: var(--brand-700); font-size: 11px; white-space: nowrap; }
body.console.b-shell.panel-collapsed .panel { display: none !important; }
body.console.b-shell .panel-reopen {
  display: none; position: fixed; right: 12px; top: 50%; z-index: 40;
  border: 1px solid #EAEAEA; background: #fff; color: var(--brand-700); padding: 8px 10px; border-radius: var(--r-xs);
}
body.console.b-shell.panel-collapsed .panel-reopen { display: inline-flex; }
body.console.b-shell .panel-toggle { position: absolute; right: 10px; top: 8px; z-index: 2; }

/* ---------- 三处整改：去旧工具条、地图白钮、分组密表、轨迹回放 ---------- */
body.console.b-shell .workspace-filters,
body.console.b-shell[data-view=orders] .workspace-filters { display: none !important; }

body.console.b-shell[data-view=overview] .subtabs,
body.console.b-shell[data-view=monitor-vehicles] .subtabs,
body.console.b-shell[data-view=monitor-track] .subtabs {
  position: absolute;
  top: 8px;
  left: 8px;
  right: auto;
  height: 28px;
  max-height: none;
  padding: 0;
  background: transparent;
  border: 0;
  z-index: 600;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 10px;
  pointer-events: none;
}
body.console.b-shell[data-view=overview] .subtab-list,
body.console.b-shell[data-view=monitor-vehicles] .subtab-list,
body.console.b-shell[data-view=monitor-track] .subtab-list,
body.console.b-shell[data-view=overview] .subtab,
body.console.b-shell[data-view=monitor-vehicles] .subtab,
body.console.b-shell[data-view=monitor-track] .subtab { pointer-events: auto; }

body.console.b-shell .map-tools {
  position: absolute;
  top: 8px;
  right: 12px;
  left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0;
  background: transparent;
  border: 0;
  box-shadow: none;
  z-index: 520;
}
body.console.b-shell .map-tool {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 10px;
  background: #fff;
  border: 1px solid #EAEAEA;
  border-radius: var(--r-xs);
  box-shadow: var(--sh-1);
  color: #303133;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
}
body.console.b-shell .map-tool:hover { border-color: #cfe9dc; }
body.console.b-shell .map-tool-ico { display: inline-flex; }
body.console.b-shell .map-tool-state {
  display: inline-block;
  min-width: 32px;
  height: 18px;
  line-height: 18px;
  padding: 0 6px;
  margin-left: 2px;
  border-radius: var(--r-xs);
  background: #F4F4F5;
  color: #909399;
  font-size: 11px;
  text-align: center;
}
body.console.b-shell .map-tool-state.on,
body.console.b-shell .map-tool.on .map-tool-state {
  background: var(--brand-50);
  color: var(--brand-700);
}

/* 信息中心：筛选 + pill + 分组密表 */
body.console.b-shell .page-host { display: flex; flex-direction: column; }
body.console.b-shell .b-page { display: flex; flex-direction: column; gap: 10px; flex: 1; min-height: 0; }
body.console.b-shell .b-filters { flex-shrink: 0; }
body.console.b-shell .b-filters {
  background: #fff;
  border: 1px solid #EEEEEE;
  border-radius: var(--r-xs);
  padding: 12px 14px 10px;
}
body.console.b-shell .b-filters .b-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  margin-bottom: 8px;
}
body.console.b-shell .b-filters .b-row:last-child { margin-bottom: 0; }
body.console.b-shell .b-field {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: #606266;
}
body.console.b-shell .b-field input,
body.console.b-shell .b-field select {
  height: 32px;
  border: 1px solid #DCDFE6;
  border-radius: var(--r-xs);
  padding: 0 8px;
  min-width: 140px;
  font-size: 12px;
  color: #303133;
  background: #fff;
}
body.console.b-shell .b-field input.wide { min-width: 220px; }
body.console.b-shell .b-actions { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; }
body.console.b-shell .b-btn {
  height: 32px;
  padding: 0 16px;
  border-radius: var(--r-xs);
  font-size: 13px;
  cursor: pointer;
  border: 1px solid #DCDFE6;
  background: #fff;
  color: #303133;
}
body.console.b-shell .b-btn.primary { background: var(--brand-500); border-color: var(--brand-700); color: #fff; }
body.console.b-shell .b-btn.linkish { border: 0; background: transparent; color: var(--brand-700); padding: 0 6px; }
body.console.b-shell .b-status-pills { display: inline-flex; align-items: center; gap: 0; }
body.console.b-shell .b-status-pills button {
  height: 28px;
  padding: 0 12px;
  border: 1px solid #DCDFE6;
  background: #fff;
  color: #606266;
  font-size: 12px;
  cursor: pointer;
  margin-left: -1px;
}
body.console.b-shell .b-status-pills button:first-child { border-radius: 4px 0 0 4px; margin-left: 0; }
body.console.b-shell .b-status-pills button:last-child { border-radius: 0 4px 4px 0; }
body.console.b-shell .b-status-pills button.on { background: var(--brand-500); border-color: var(--brand-700); color: #fff; z-index: 1; }

body.console.b-shell .b-sheet {
  background: #fff;
  border: 1px solid #EEEEEE;
  border-radius: var(--r-xs);
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1;
  overflow: hidden;
}
body.console.b-shell .b-sheet .page-table-wrap { flex: 1; min-height: 0; overflow: auto; }
body.console.b-shell .b-sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  font-size: 14px;
  font-weight: 600;
  color: #303133;
  border-bottom: 1px solid #F0F0F0;
}
body.console.b-shell .b-type-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  padding: 8px 12px 4px;
  font-size: 12px;
  color: #303133;
}
body.console.b-shell .b-type-pills label { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; white-space: nowrap; }
body.console.b-shell .b-type-pills input { accent-color: var(--brand-700); }
body.console.b-shell .b-stat {
  display: flex;
  flex-wrap: wrap;
  gap: 16px 22px;
  padding: 8px 12px;
  font-size: 12px;
  color: #606266;
  border-bottom: 1px solid #F0F0F0;
}
body.console.b-shell .b-stat b { color: var(--brand-700); font-size: 14px; margin-left: 4px; font-weight: 600; }
body.console.b-shell .b-group-table { width: 100%; border-collapse: collapse; }
body.console.b-shell .b-group-table thead th {
  background: #FAFAFA;
  font-size: 12px;
  font-weight: 600;
  color: #303133;
  padding: 8px 10px;
  border-bottom: 1px solid #EBEEF5;
  text-align: left;
  white-space: nowrap;
}
body.console.b-shell .b-group-table td {
  vertical-align: top;
  padding: 10px 10px;
  border-bottom: 1px solid #F2F6FC;
  font-size: 12px;
  color: #303133;
  line-height: 1.7;
}
body.console.b-shell .b-kv .k { color: #909399; margin-right: 4px; }
body.console.b-shell .b-tag {
  display: inline-block;
  font-size: 11px;
  padding: 0 6px;
  height: 18px;
  line-height: 18px;
  border-radius: var(--r-xs);
  margin: 0 4px 2px 0;
  vertical-align: middle;
}
body.console.b-shell .b-tag.ok { background: var(--brand-50); color: var(--brand-700); }
body.console.b-shell .b-tag.info { background: #ECF5FF; color: #409EFF; }
body.console.b-shell .b-tag.warn { background: #FEF0F0; color: #F56C6C; }
body.console.b-shell .b-tag.muted { background: #F4F4F5; color: #909399; }
body.console.b-shell .b-act { color: var(--brand-700); background: none; border: 0; cursor: pointer; padding: 0 6px 0 0; font-size: 12px; }
body.console.b-shell .b-act:hover { text-decoration: underline; }
body.console.b-shell .b-empty { text-align: center; color: #909399; padding: 48px 12px; }
body.console.b-shell .b-pager {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  font-size: 12px;
  color: #606266;
  border-top: 1px solid #F0F0F0;
}
body.console.b-shell .b-pager .pg {
  min-width: 28px;
  height: 28px;
  border: 1px solid #DCDFE6;
  background: #fff;
  border-radius: var(--r-xs);
  cursor: pointer;
}
body.console.b-shell .b-pager .pg.on { background: var(--brand-500); color: #fff; border-color: var(--brand-700); }
body.console.b-shell .b-pager select { height: 28px; border: 1px solid #DCDFE6; border-radius: var(--r-xs); }

/* 轨迹回放：左查询栏 + 地图 + 底时间轴 */
body.console.b-shell.track-mode .tree-filters,
body.console.b-shell.track-mode .tree-summary,
body.console.b-shell.track-mode .tree-actions,
body.console.b-shell.track-mode .scope-tree,
body.console.b-shell.track-mode #vehicleList,
body.console.b-shell.track-mode #ownerFilter,
body.console.b-shell.track-mode .metrics,
body.console.b-shell.track-mode .kpi-toggle,
body.console.b-shell.track-mode .panel,
body.console.b-shell.track-mode .panel-reopen,
body.console.b-shell.track-mode .map-tools,
body.console.b-shell.track-mode .bottom,
body.console.b-shell.track-mode .legend,
body.console.b-shell.track-mode .playbar,
body.console.b-shell.track-mode .mapstate,
body.console.b-shell.track-mode .tree-reopen { display: none !important; }
body.console.b-shell.track-mode #trackPane {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px 14px;
  height: 100%;
  background: #fff;
  overflow: auto;
}
body.console.b-shell.track-mode .tree { background: #fff; }
body.console.b-shell .track-query[hidden] { display: none !important; }
body.console.b-shell .tq-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
  color: #303133;
}
body.console.b-shell .tq-field .req { color: #F56C6C; margin-right: 2px; }
body.console.b-shell .tq-field input {
  height: 32px;
  border: 1px solid #DCDFE6;
  border-radius: var(--r-xs);
  padding: 0 8px;
  width: 100%;
  font-size: 12px;
}
body.console.b-shell .tq-stay {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: #606266;
}
body.console.b-shell .tq-stay input { width: 48px; height: 28px; text-align: center; border: 1px solid #DCDFE6; border-radius: var(--r-xs); }
body.console.b-shell .tq-stay .step {
  width: 28px; height: 28px; border: 1px solid #DCDFE6; background: #fff; border-radius: var(--r-xs); cursor: pointer;
}
body.console.b-shell .tq-actions { display: flex; gap: 8px; }
body.console.b-shell .tq-actions .btn { min-width: 72px; height: 32px; }
body.console.b-shell .tq-hint { margin: 0; min-height: 18px; }
body.console.b-shell .track-timeline {
  position: absolute;
  left: 24%;
  right: 16%;
  bottom: 16px;
  z-index: 530;
  background: #fff;
  border-radius: var(--r-xs);
  box-shadow: 0 2px 10px rgba(23, 35, 61, .12);
  padding: 8px 14px 10px;
}
body.console.b-shell .track-timeline[hidden] { display: none !important; }
body.console.b-shell.track-mode .track-timeline { display: block; }
body.console.b-shell .tt-hours {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: #909399;
  padding: 0 2px 4px;
}
body.console.b-shell .tt-bar { position: relative; height: 16px; }
body.console.b-shell .tt-progress {
  position: absolute;
  left: 0; top: 5px;
  height: 4px;
  width: 0;
  background: #F56C6C;
  border-radius: var(--r-xs);
  z-index: 1;
  pointer-events: none;
}
body.console.b-shell .tt-bar::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 5px;
  height: 4px;
  background: #E4E7ED;
  border-radius: var(--r-xs);
}
body.console.b-shell .tt-bar input[type=range] {
  position: relative;
  z-index: 2;
  width: 100%;
  margin: 0;
  accent-color: #F56C6C;
  background: transparent;
}
body.console.b-shell .tt-ctrl {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 8px;
  margin-top: 4px;
  font-size: 12px;
  color: #606266;
}
body.console.b-shell .tt-ctrl select { height: 26px; border: 1px solid #DCDFE6; border-radius: var(--r-xs); }
/* 按钮与下拉不许被压缩：否则标签一长，"播放"两个字会被挤成两行 */
body.console.b-shell .tt-ctrl > button,
body.console.b-shell .tt-ctrl > select { flex: 0 0 auto; }
/* 时间标签会随点数变长（"第 211/211 点"），让它独占剩余宽度并省略 */
body.console.b-shell .tt-ctrl .tt-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 回放图例：线型即语义。三条线的颜色/虚实与 console.js 的 paintTrackData 一一对应，
   改一处必须两处一起改，否则图例会说谎。 */
body.console.b-shell .tt-legend {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px dashed #EBEEF5;
  font-size: 11px;
  color: #909399;
}
body.console.b-shell .tt-legend[hidden] { display: none !important; }
/* 图例项用 .key 而不是 .lg：`.lg` 是全站已有的「9px 状态圆点」（styles.css:355），
   同名会把这个 span 压成 9px 宽、文字逐字竖排。这条坑实测踩过一次。 */
body.console.b-shell .tt-legend .key {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  gap: 5px;
  white-space: nowrap;
}
body.console.b-shell .tt-legend .key i {
  display: inline-block;
  flex: 0 0 22px;
  width: 22px;
  height: 0;
  border-top-style: solid;
}
body.console.b-shell .tt-legend .key-base i { border-top: 2px dashed #E23A3A; opacity: .8; }
body.console.b-shell .tt-legend .key-pre i { border-top: 3px dashed #E6A23C; }
body.console.b-shell .tt-legend .key-in i { border-top: 3px solid #19BE6D; }
body.console.b-shell .tt-legend .key-after i { border-top: 3px dashed #8A94A6; opacity: .8; }

/* 还没装上货的车：轨迹入口置灰（README §21.11）。禁用态要一眼能看出是"不让点"
   而不是"加载中"，所以除了让底色变灰，还把边框改成虚线、光标改成禁止。 */
body.console.b-shell .btn.is-blocked,
body.console.b-shell .btn.is-blocked:hover,
body.console.b-shell .b-act:disabled {
  background: #F7F8FA;
  border: 1px dashed var(--line);
  color: var(--muted-2);
  box-shadow: none;
  cursor: not-allowed;
}

body.console.b-shell .leaflet-bottom.leaflet-right { margin-bottom: 58px; margin-right: 8px; }
body.console.b-shell.track-mode .leaflet-bottom.leaflet-right { margin-bottom: 88px; }

body.console.b-shell input.b-dt,
body.console.b-shell .tq-field input.b-dt,
body.console.b-shell .b-field input.b-dt {
  font-variant-numeric: tabular-nums;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Courier New", monospace;
  box-sizing: content-box;
  width: 20ch;
  min-width: 20ch;
  padding-left: 8px;
  padding-right: 8px;
  letter-spacing: 0;
  flex: 0 0 auto;
}

/* ------------------------------------------------------------------
   安全看板两个大屏（B 实站 secureDashboard/liveMonitorCenter、manageAnalyseCenter）
   与 B 的唯一差别：B 是整屏深色、顶栏左栏页签全隐藏；
   这里保留外壳，深色只作用于内容区，靠 theme 类切换 page-host 的底色。
   ------------------------------------------------------------------ */
body.console.b-shell.dash-theme .page-host {
  padding: 0;
  background:
    radial-gradient(1200px 500px at 50% -10%, rgba(25,190,109,.12), transparent 55%),
    linear-gradient(180deg, var(--surface) 0%, #0a0b0c 100%);
  color: var(--ink-700);
  overflow: auto;
}
body.console.b-shell .dash-hud { min-height: 100%; padding: 16px 20px 24px; }
body.console.b-shell .dash-top {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; margin-bottom: 16px;
}
body.console.b-shell .dash-title {
  margin: 0; text-align: center; font-size: 26px; letter-spacing: 6px; font-weight: 700;
  background: linear-gradient(180deg, var(--brand-300), var(--brand-500));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
body.console.b-shell .dash-jumps { display: flex; gap: 8px; }
body.console.b-shell .dash-btn,
body.console.b-shell .dash-range button {
  background: var(--surface); border: 1px solid var(--line-200); color: var(--ink-500); padding: 4px 12px;
  border-radius: var(--r-xs); font-size: 12px; cursor: pointer; font-family: inherit;
}
body.console.b-shell .dash-btn:hover { background: #14403f; }
body.console.b-shell .dash-range { justify-self: end; display: flex; gap: 6px; }
body.console.b-shell .dash-range button.on { background: var(--brand-500); color: #FFFFFF; border-color: var(--brand-700); }
body.console.b-shell .dash-panel {
  background: rgba(8, 24, 32, .78);
  border: 1px solid rgba(30, 201, 168, .35);
  box-shadow: inset 0 0 20px rgba(25,190,109,.05), 0 0 16px rgba(23, 35, 61, .25);
  border-radius: var(--r-xs); padding: 12px 14px; min-height: 160px;
}
body.console.b-shell .dash-panel h2 {
  margin: 0 0 10px; font-size: 13px; font-weight: 600; color: var(--brand-700);
  letter-spacing: 1px; display: flex; align-items: center; gap: 6px;
}
body.console.b-shell .dash-panel h2::before { content: ""; width: 8px; height: 8px; border: 2px solid var(--brand-500); transform: rotate(45deg); }
body.console.b-shell .dash-live-grid {
  display: grid; grid-template-columns: 260px minmax(0, 1.4fr) 320px; grid-template-rows: 1fr 220px; gap: 12px;
  min-height: calc(100vh - var(--shell-header) - 130px);
}
body.console.b-shell .dash-live-grid .dash-span { grid-column: 1 / -1; min-height: 180px; }
body.console.b-shell .dash-stat-col { display: flex; flex-direction: column; gap: 18px; }
body.console.b-shell .dash-stat { display: flex; align-items: center; gap: 12px; }
body.console.b-shell .dash-stat b { display: block; font-size: 22px; color: var(--ink-900); }
body.console.b-shell .dash-stat span { color: var(--ink-400); font-size: 12px; }
body.console.b-shell .dash-ring {
  width: 72px; height: 72px; border-radius: 50%;
  background: conic-gradient(var(--brand-500) calc(var(--p) * 1%), var(--line-100) 0);
  display: grid; place-items: center; position: relative; flex: 0 0 72px;
}
body.console.b-shell .dash-ring::after {
  content: ""; position: absolute; inset: 8px; border-radius: 50%; background: var(--surface);
}
body.console.b-shell .dash-ring b { position: relative; z-index: 1; font-size: 14px; color: var(--brand-700); }
body.console.b-shell .dash-video-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; height: calc(100% - 28px); }
body.console.b-shell .dash-video-tile {
  background: var(--surface-soft); border: 1px solid var(--line-200); display: grid; place-items: center; color: var(--ink-400); min-height: 120px;
}
body.console.b-shell .dash-table { width: 100%; border-collapse: collapse; font-size: 12px; }
body.console.b-shell .dash-table th { color: var(--brand-700); font-weight: 500; padding: 6px 4px; border-bottom: 1px solid var(--line-200); text-align: left; }
body.console.b-shell .dash-table td { color: var(--ink-700); padding: 6px 4px; border-bottom: 1px solid var(--line-100); }
body.console.b-shell .dash-table td.empty { text-align: center; color: var(--ink-400); padding: 24px 8px; }
body.console.b-shell .dash-plate { display: inline-block; background: #FDF3D8; color: #8A5A00; padding: 0 6px; border-radius: var(--r-xs); font-weight: 700; }
body.console.b-shell .dash-bars { display: flex; align-items: flex-end; gap: 10px; height: 140px; padding: 8px 4px 0; }
body.console.b-shell .dash-bar { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; }
body.console.b-shell .dash-bar i { display: block; width: 70%; max-width: 36px; background: linear-gradient(var(--brand-300), var(--brand-500)); border-radius: 2px 2px 0 0; }
body.console.b-shell .dash-bar span { margin-top: 6px; font-size: 11px; color: var(--ink-400); }
body.console.b-shell .dash-kpis { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 10px; margin-bottom: 12px; }
body.console.b-shell .dash-kpi {
  background: rgba(8, 24, 32, .78); border: 1px solid rgba(30,201,168,.35); border-radius: var(--r-xs); padding: 14px 10px; text-align: center;
}
body.console.b-shell .dash-kpi b { display: block; font-size: 24px; color: var(--ink-900); }
body.console.b-shell .dash-kpi b small { font-size: 12px; margin-left: 4px; color: var(--ink-400); font-weight: 400; }
body.console.b-shell .dash-kpi span { color: var(--ink-400); font-size: 12px; }
body.console.b-shell .dash-ops-grid { display: grid; grid-template-columns: 1.1fr 1fr 1fr; grid-template-rows: auto auto; gap: 12px; }
body.console.b-shell .dash-ops-grid .dash-panel:nth-child(4),
body.console.b-shell .dash-ops-grid .dash-panel:nth-child(5) { grid-column: span 1; min-height: 180px; }
body.console.b-shell .dash-donut-wrap { display: flex; align-items: center; gap: 16px; min-height: 160px; }
body.console.b-shell .dash-donut { width: 120px; height: 120px; border-radius: 50%; position: relative; flex: 0 0 120px; }
body.console.b-shell .dash-donut::after { content: ""; position: absolute; inset: 28px; border-radius: 50%; background: var(--surface); }
body.console.b-shell .dash-legend { list-style: none; margin: 0; padding: 0; font-size: 12px; color: var(--ink-500); }
body.console.b-shell .dash-legend li { margin: 6px 0; }
body.console.b-shell .dash-legend i { display: inline-block; width: 8px; height: 8px; background: var(--brand-500); margin-right: 6px; }
body.console.b-shell .dash-line-empty { color: var(--ink-500); padding: 20px 4px; }
body.console.b-shell .dash-line-empty span { display: block; color: var(--ink-400); font-size: 12px; margin-top: 8px; }
body.console.b-shell .dash-panel .empty { color: var(--ink-400); text-align: center; padding: 28px 8px; }

/* ---- B 风格管理页：区间日期连接符、行内文字操作、车辆分组左右分栏 ---- */
body.console.b-shell .b-range-dash { color: #C0C4CC; padding: 0 4px; }
body.console.b-shell .b-op {
  border: 0; background: transparent; color: var(--brand-700);
  font-family: inherit; font-size: 12px; padding: 0 4px; cursor: pointer;
}
body.console.b-shell .b-op:hover { text-decoration: underline; }
body.console.b-shell .b-group-page { flex-direction: row; gap: 0; align-items: stretch; }
body.console.b-shell .b-gtree {
  width: 250px; flex: 0 0 250px; border-right: 1px solid #EEEEEE;
  display: flex; flex-direction: column; gap: 2px; padding: 10px 8px; overflow: auto;
}
body.console.b-shell .b-gtree-head { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
body.console.b-shell .b-gtree-head input {
  flex: 1; min-width: 0; height: 28px; border: 1px solid #DCDFE6; border-radius: var(--r-xs); padding: 0 8px; font-size: 12px;
}
body.console.b-shell .b-gtree-item {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  padding: 7px 10px; border: 0; border-radius: var(--r-xs); background: transparent;
  font-family: inherit; font-size: 13px; color: #303133; text-align: left; cursor: pointer;
}
body.console.b-shell .b-gtree-item em { font-style: normal; color: #909399; font-size: 12px; }
body.console.b-shell .b-gtree-item:hover { background: #F5F7FA; }
body.console.b-shell .b-gtree-item.on { background: var(--brand-50); color: var(--brand-700); }
body.console.b-shell .b-gtree-item.on em { color: var(--brand-700); }
body.console.b-shell .b-gmain { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 10px; padding: 10px 12px; }

/* KPI 条右侧给「收起/展开」按钮让位：该按钮是绝对定位在地图右下角，
   之前会直接压在最后一个指标（定位异常）上面。 */
body.console.b-shell .metrics { padding-right: 92px; }

/* C-05 页签溢出：页签开多了原本会换行把页面标题压住。
   改成不换行 + 横向滚动，滚动条自己藏起来（鼠标滚轮/触控板仍可滚）。 */
body.console.b-shell .subtab-list {
  flex-wrap: nowrap;
  overflow-x: auto;
  overflow-y: hidden;
  white-space: nowrap;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
body.console.b-shell .subtab-list::-webkit-scrollbar { height: 0; display: none; }
body.console.b-shell .subtab-list .subtab { flex: 0 0 auto; }

/* 「待数据源」角标：界面已照 B 铺齐，但后端没有对应接口，表体恒为空。
   有它是为了区分"做完了"和"等着接数据"。 */
.cf-stub {
  display: block; width: fit-content; align-self: flex-start;
  margin: 0 0 8px 0;
  padding: 2px 8px; border-radius: var(--r-xs);
  background: #FFF7E6; color: #D48806;
  border: 1px solid #FFE0A3;
  font-size: 12px; line-height: 18px;
}

/* ---------------------------------------------------------------- 左树线路行（简洁态）
 * 客户要求：「只显示线路简称即可，例如"五举矿到灵台电厂"，去掉冗长的 HY 开头编码」。
 * 一条线路行只有 300px 宽，线路名（8 个汉字）必须先占到位置：
 *   - 状态徽标从正文撤掉（数字行里已经有"43 趟在途"，信息不丢，只去重）；
 *   - 改名按钮平时不显示，悬停才出现，避免常驻挤占 16px；
 *   - 车牌列表里的车才需要看状态，线路行不需要重复一遍。
 */
body.console.b-shell .pub .route {
  display: flex; align-items: center; gap: 4px; min-width: 0;
}
body.console.b-shell .pub .route b {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
body.console.b-shell .pub .route .state { display: none; }
body.console.b-shell .pub .route .edit {
  flex: 0 0 auto; opacity: 0; transition: opacity .12s ease;
}
body.console.b-shell .pub:hover .route .edit,
body.console.b-shell .pub.on .route .edit { opacity: 1; }
body.console.b-shell .pub .nums { white-space: nowrap; }
