:root {
  --primary: #1d4ed8; --primary-dark: #1e3a8a;
  --danger: #dc2626; --warn: #f59e0b; --ok: #16a34a; --info: #2563eb;
  --bg: #f1f5f9; --card: #fff; --line: #e2e8f0; --muted: #64748b; --text: #0f172a;
  --dark: #0f172a;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {
  font-family: -apple-system, "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, sans-serif;
  background: var(--bg); color: var(--text); font-size: 14px;
}
.hidden { display: none !important; }
a { color: var(--primary); text-decoration: none; }
button { font-family: inherit; }

/* ===== 轻提示 Toast（默认隐藏，.show 时淡入，2200ms 后自动淡出） ===== */
.toast {
  position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%) translateY(16px);
  max-width: 86vw; padding: 10px 18px; background: rgba(15, 23, 42, .92); color: #fff;
  font-size: 13px; line-height: 1.5; border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, .28);
  opacity: 0; visibility: hidden; pointer-events: none; z-index: 10000;
  transition: opacity .25s ease, transform .25s ease, visibility .25s ease;
}
.toast.show { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }

/* ===== 登录 ===== */
.login-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #0f172a 0%, #1e3a8a 55%, #1d4ed8 100%); padding: 20px; }
.login-card { width: 360px; max-width: 92vw; background: #fff; border-radius: 16px; padding: 36px 30px;
  text-align: center; box-shadow: 0 20px 60px rgba(0,0,0,.35); }
.login-card .logo { font-size: 42px; }
.login-card h1 { font-size: 20px; margin: 10px 0 4px; color: var(--dark); }
.login-card .sub { color: var(--muted); font-size: 13px; margin-bottom: 22px; }
.login-card input { width: 100%; padding: 12px 14px; border: 1px solid var(--line); border-radius: 10px;
  font-size: 15px; margin-bottom: 14px; outline: none; }
.login-card input:focus { border-color: var(--primary); }
.login-card .err { color: var(--danger); font-size: 13px; margin-top: 10px; min-height: 18px; }

/* ===== 布局 ===== */
.app { display: flex; flex-direction: column; min-height: 100vh; }
.topbar { display: flex; align-items: center; gap: 16px; color: #fff;
  background: linear-gradient(90deg, #16273f 0%, #1e3a5c 50%, #16273f 100%);
  box-shadow: 0 1px 0 rgba(255,255,255,.06) inset, 0 2px 8px rgba(10,20,35,.25);
  padding: 0 16px; height: 42px; position: sticky; top: 0; z-index: 50; }
.topbar .brand { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 16px; white-space: nowrap; }
.topbar .brand .logo { font-size: 22px; }
.topbar .nav { display: flex; gap: 4px; flex: 1; overflow-x: auto; scrollbar-width: none; }
.topbar .nav::-webkit-scrollbar { display: none; }
.nav a { color: #f8fafc; padding: 6px 12px; border-radius: 8px; font-size: 15px; font-weight: 600; letter-spacing: .5px; white-space: nowrap; }
.nav a:hover { color: #fff; background: rgba(255,255,255,.14); }
.nav a.on { color: #fff; background: var(--primary); font-weight: 700; }
.air-badge { flex: none; display: inline-flex; align-items: baseline; gap: 4px; padding: 0 12px; font-size: 14px; font-weight: 700; letter-spacing: .5px; white-space: nowrap; }
.air-badge .air-label { color: #fff; }
.air-badge .air-num { color: #ff4d4f; }
.air-badge.blink .air-num { animation: airNumBlink 1s ease-in-out infinite; }
@keyframes airNumBlink {
  0%, 100% { opacity: 1; text-shadow: 0 0 7px rgba(255,77,79,.95); }
  50% { opacity: .22; text-shadow: none; }
}
.air-tip { margin-left: 10px; padding: 2px 10px; border-radius: 999px; background: #dc2626; color: #fff; font-size: 13px; font-weight: 700; letter-spacing: .5px; white-space: nowrap; animation: airTipBlink .9s ease-in-out infinite; }
@keyframes airTipBlink {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 rgba(220,38,38,0); }
  50% { opacity: .4; box-shadow: 0 0 12px rgba(220,38,38,1); }
}
.userbox { display: flex; align-items: center; gap: 10px; white-space: nowrap; }
.role-badge { font-size: 12px; padding: 3px 9px; border-radius: 20px; background: rgba(255,255,255,.15); }
.uname { font-size: 13px; color: #e2e8f0; max-width: 120px; overflow: hidden; text-overflow: ellipsis; }
.icon-btn { background: none; border: none; color: #fff; font-size: 18px; cursor: pointer; padding: 6px; border-radius: 8px; }
.icon-btn:hover { background: rgba(255,255,255,.12); }
.view { flex: 1; padding: 14px; width: 100%; }
.view.full { padding: 0; }

/* ===== 卡片 ===== */
.card { background: var(--card); border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,.08); padding: 16px; margin-bottom: 14px; }
.card .hdr { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
.card .hdr h3 { font-size: 15px; }
.card .hdr .sub { color: var(--muted); font-size: 12px; }
.hdr .sp { margin-left: auto; }

/* ===== 按钮 ===== */
.btn { border: 1px solid transparent; border-radius: 9px; padding: 8px 14px; font-size: 13px; cursor: pointer;
  transition: .15s; display: inline-flex; align-items: center; gap: 5px; }
.btn.primary { background: var(--primary); color: #fff; }
.btn.primary:hover { background: #1e40af; }
.btn.direct { background: #0d9488; color: #fff; }
.btn.direct:hover { background: #0f766e; }
.btn.danger { background: var(--danger); color: #fff; }
.btn.danger:hover { background: #b91c1c; }
.btn.success { background: var(--ok); color: #fff; }
.btn.success:hover { background: #15803d; }
.btn.ghost { background: #fff; border-color: var(--line); color: var(--text); }
.btn.ghost:hover { border-color: var(--primary); color: var(--primary); }
.btn.on { background: var(--ok); border-color: var(--ok); color: #fff; }
.btn.on:hover { background: #15803d; border-color: #15803d; color: #fff; }
.btn.outline { background: #fff; border-color: var(--primary); color: var(--primary); }
.btn.star { background: #d97706; color: #fff; }   /* ★2026-09-25 「收藏」按键（琥珀色） */
.btn.star:hover { background: #b45309; }
.btn.block { width: 100%; justify-content: center; font-size: 15px; padding: 12px; }
.btn.sm { padding: 5px 10px; font-size: 12px; }
.btn.xs { padding: 3px 8px; font-size: 11px; border-radius: 6px; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }

/* ===== 表格 ===== */
table { width: 100%; border-collapse: collapse; font-size: 13px; }
th, td { padding: 9px 10px; text-align: left; border-bottom: 1px solid var(--line); white-space: nowrap; }
th { background: #f8fafc; color: var(--muted); font-weight: 600; position: sticky; top: 0; }
tbody tr:hover { background: #f8fafc; }
.table-wrap { overflow: auto; max-height: 420px; border-radius: 8px; }
/* 表格美化：仅保留表头底色（奇偶列交替底色已按需求去掉） */
.zebra { border-collapse: collapse; width: 100%; }
.zebra th { background: #e2eaf3; color: #334155; font-weight: 700; }
.zebra td, .zebra th { padding: 8px 10px; border-bottom: 1px solid #eef2f7; white-space: nowrap; }
.zebra tbody tr:hover td { background: #e8f0f8 !important; }
.geo { display: inline-block; max-width: 220px; white-space: normal; word-break: break-all; overflow-wrap: anywhere; line-height: 1.4; vertical-align: middle; }
.pager { display: flex; align-items: center; gap: 8px; margin-top: 10px; justify-content: flex-end; font-size: 13px; color: var(--muted); }
.pager button { border: 1px solid var(--line); background: #fff; border-radius: 7px; padding: 4px 11px; cursor: pointer; font-size: 12px; }
.pager button:disabled { opacity: .4; cursor: not-allowed; }

/* ===== 标签 ===== */
.tag { display: inline-block; font-size: 11px; padding: 2px 8px; border-radius: 20px; font-weight: 600; }
.tag.red { background: #fee2e2; color: #b91c1c; }
.tag.blue { background: #dbeafe; color: #1d4ed8; }
.tag.green { background: #dcfce7; color: #15803d; }
.tag.gray { background: #e5e7eb; color: #4b5563; }
.tag.orange { background: #ffedd5; color: #c2410c; }
.tag.white { background: #cffafe; color: #0e7490; }
.tag.black { background: #111827; color: #fff; }
.tag.whitelist { background: #0891b2; color: #fff; }
.tag.frep { background: #e0f2fe; color: #0369a1; border: 1px solid #7dd3fc; }   /* ★2026-09-21 飞行报备（合规） */
.tag.frepbad { background: #dc2626; color: #fff; }                               /* ★2026-09-21 报备违规（醒目） */
.tag.outline { background: #fff; border: 1px solid var(--line); color: var(--muted); }

/* ===== 实时探测 ===== */
.statsbar { display: flex; gap: 10px; flex-wrap: wrap; }
.statsbar .cell { flex: 1; min-width: 90px; background: var(--bg); border-radius: 10px; padding: 10px 14px; }
.statsbar .cell .n { font-size: 22px; font-weight: 700; }
.statsbar .cell .l { font-size: 12px; color: var(--muted); }
.statsbar .cell.red .n { color: var(--danger); } .statsbar .cell.blue .n { color: var(--info); }
.statsbar .cell.green .n { color: var(--ok); } .statsbar .cell.gray .n { color: #6b7280; }
.rt-page { display: flex; flex-direction: column; height: calc(100vh - 56px); gap: 0; padding: 0; }
.rt-stats { flex: 0 0 auto; background: var(--card); border-radius: 12px; padding: 10px 14px; box-shadow: 0 1px 3px rgba(0,0,0,.08); }
.stats-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.stats-head .t { font-size: 13px; font-weight: 700; color: var(--text); }
.rt-stats.collapsed .statsbar { display: none; }
.rt-stats.collapsed { padding: 8px 14px; }
.rt-wrap { flex: 1; display: flex; gap: 0; min-height: 0; }
.rt-map { flex: 1; min-width: 0; position: relative; display: flex; }
.mapbox { flex: 1; height: auto; min-height: 0; border-radius: 0; overflow: hidden; position: relative; }
.rt-side { width: 340px; max-width: 100%; display: flex; flex-direction: column; min-height: 0; transition: width .18s ease; }
.rt-side.collapsed { width: 0; overflow: hidden; min-height: 0; }
.rt-side-card { flex: 1; display: flex; flex-direction: column; min-height: 0; margin-bottom: 0; border-radius: 0; border-left: 1px solid #e3e9f2; background: #fff; box-shadow: -6px 0 20px -12px rgba(15,23,42,.25); }
/* ===== 实时目标面板 ===== */
.rt-side-card .hdr { margin: 0; padding: 13px 16px; gap: 10px; flex-wrap: nowrap; color: #fff;
  background: linear-gradient(180deg, #16294a 0%, #1d3a6e 100%); border-bottom: 1px solid rgba(255,255,255,.08); }
.rt-side-card .hdr h3 { display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 700; letter-spacing: 2px; color: #fff; }
.rt-side-card .hdr h3.clickable { user-select: none; }
.rt-side-card .hdr h3.clickable:hover { color: #38bdf8; }
.rt-side-card .hdr h3::before { content: ''; width: 4px; height: 16px; border-radius: 2px; background: linear-gradient(180deg, #38bdf8, #2563eb); box-shadow: 0 0 6px rgba(56,189,248,.6); }
.rt-side-card .count-badge { background: #e11d48; color: #fff; font-size: 13px; font-weight: 700; padding: 3px 11px; border-radius: 999px; box-shadow: 0 0 0 2px rgba(255,255,255,.15); }
.rt-side-card .count-badge.blink { animation: countBadgeBlink 1s ease-in-out infinite; }
@keyframes countBadgeBlink {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 2px rgba(255,255,255,.15), 0 0 10px rgba(225,29,72,.9); }
  50% { opacity: .3; box-shadow: 0 0 0 2px rgba(255,255,255,.15); }
}
.side-toggle { position: absolute; right: 0; top: 50%; transform: translateY(-50%); z-index: 11; width: 18px; height: 56px;
  border: 1px solid var(--line); border-right: none; background: #fff; border-radius: 6px 0 0 6px; cursor: pointer;
  font-size: 12px; line-height: 1; color: #64748b; padding: 0; box-shadow: -1px 0 4px rgba(0,0,0,.12); }
.side-toggle:hover { background: var(--primary); color: #fff; }
.legend { display: flex; gap: 12px; flex-wrap: wrap; position: absolute; left: 10px; bottom: 10px; z-index: 10;
  background: rgba(255,255,255,.92); border-radius: 8px; padding: 6px 10px; font-size: 12px; box-shadow: 0 1px 4px rgba(0,0,0,.15); }
.legend span { display: inline-flex; align-items: center; gap: 4px; }
.dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.layerswitch { position: absolute; right: 10px; top: 10px; z-index: 10; background: #fff; border-radius: 8px;
  box-shadow: 0 1px 4px rgba(0,0,0,.2); overflow: hidden; display: flex; }
.layerswitch button { border: none; background: #fff; padding: 8px 12px; cursor: pointer; font-size: 12px; }
.layerswitch button.on { background: var(--primary); color: #fff; }
.maptools { position: absolute; right: 10px; bottom: 10px; z-index: 10; background: #fff; border-radius: 8px;
  box-shadow: 0 1px 4px rgba(0,0,0,.2); overflow: hidden; display: flex; }
.maptools button { border: none; background: #fff; padding: 8px 12px; cursor: pointer; font-size: 12px; }
.maptools button.on { background: var(--primary); color: #fff; }
/* 辖区选择（地图左下角） */
.station-picker { position: absolute; left: 10px; bottom: 10px; z-index: 12; display: flex; align-items: center; gap: 6px; }
.station-clear { display: inline-flex; align-items: center; gap: 4px; background: #fff; border: none; border-radius: 8px; padding: 8px 10px; cursor: pointer; font-size: 12px; color: #dc2626; box-shadow: 0 1px 4px rgba(0,0,0,.2); }
.station-clear:hover { background: #fef2f2; }
.station-btn { display: inline-flex; align-items: center; gap: 6px; background: #fff; border: none; border-radius: 8px; padding: 8px 12px; cursor: pointer; font-size: 12px; box-shadow: 0 1px 4px rgba(0,0,0,.2); max-width: 280px; }
.station-btn span { max-width: 236px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.station-btn i { font-style: normal; font-size: 10px; color: #94a3b8; }
.station-btn.on { background: var(--primary); color: #fff; }
.station-btn.on i { color: #fff; }
.station-menu { position: absolute; left: 0; bottom: 46px; width: 276px; max-height: 360px; display: flex; flex-direction: column; background: #fff; border-radius: 10px; box-shadow: 0 6px 24px rgba(0,0,0,.22); overflow: hidden; }
.station-menu input { border: none; border-bottom: 1px solid #e2e8f0; padding: 9px 12px; font-size: 13px; outline: none; }
.station-list { overflow: auto; padding: 4px; }
.station-item { display: flex; justify-content: space-between; gap: 8px; padding: 8px 10px; font-size: 13px; border-radius: 6px; cursor: pointer; }
.station-item:hover { background: #f1f5f9; }
.station-item.on { background: var(--primary); color: #fff; }
.station-item .st-cnt { color: #94a3b8; font-size: 12px; }
.station-item.on .st-cnt { color: #e2e8f0; }
.station-item.clear { color: #dc2626; justify-content: center; }
.tools { position: absolute; right: 10px; top: 10px; z-index: 10; background: #fff; border-radius: 8px;
  box-shadow: 0 1px 4px rgba(0,0,0,.2); overflow: visible; display: flex; align-items: center; }
.tools button { border: none; background: #fff; padding: 8px 12px; cursor: pointer; font-size: 12px; }
.tools button.on { background: var(--primary); color: #fff; }
.tools > button:first-child { border-radius: 8px 0 0 8px; }
/* ★2026-09-25 地图「工具」菜单（测距 / 面积 / 打点） */
.tool-menu { display: none; position: absolute; top: calc(100% + 6px); right: 0; width: 236px; max-width: calc(100vw - 24px);
  background: #fff; border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,.22); padding: 6px; z-index: 130; text-align: left; }
.tool-menu.show { display: block; }
/* ★2026-09-25 工具菜单只留功能名（说明行已按要求去掉） */
.tool-menu .tm-item { display: flex; align-items: center; width: 100%; border: 0; background: transparent;
  text-align: left; padding: 9px 12px; border-radius: 8px; cursor: pointer; }
.tool-menu .tm-item:hover { background: #f1f5f9; }
.tool-menu .tm-item b { font-size: 13.5px; font-weight: 600; color: var(--text); }
.tool-menu .tm-item.on { background: var(--primary); }
.tool-menu .tm-item.on b { color: #fff; }
/* 绘制中只显示一个「✅ 完成」按钮（★按要求不再显示任何文字提示） */
.tool-actions { display: none; position: absolute; left: 50%; transform: translateX(-50%); bottom: 54px; z-index: 12; }
.tool-actions.show { display: block; }
.ts-done { border: 0; background: var(--primary); color: #fff; font-size: 12.5px; padding: 7px 14px; border-radius: 8px;
  cursor: pointer; white-space: nowrap; box-shadow: 0 2px 8px rgba(0,0,0,.25); }
.ts-done:hover { background: var(--primary-dark); }
/* ★2026-09-25 地图悬停提示：鼠标放到（收藏载入的）点位上自动显示收藏名 */
.map-hover-tip { position: absolute; z-index: 2600; transform: translate(-50%, -100%); max-width: 240px;
  background: rgba(15,23,42,.93); color: #fff; font-size: 12px; line-height: 1.35; padding: 5px 9px;
  border-radius: 7px; pointer-events: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  box-shadow: 0 3px 10px rgba(0,0,0,.28); }
/* ★2026-09-25 「⭐ 收藏」面板（点位收藏：可命名 / 载入 / 重命名 / 删除） */
.fav-hint { font-size: 12px; color: var(--muted); line-height: 1.7; margin-bottom: 10px; }
.fav-empty { font-size: 13px; color: var(--muted); line-height: 1.8; padding: 10px 2px; }
.fav-row { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border: 1px solid var(--line);
  border-radius: 10px; margin-bottom: 8px; background: #fff; }
.fav-main { flex: 1 1 auto; min-width: 0; }
.fav-name { font-size: 13.5px; font-weight: 600; color: var(--text); word-break: break-all; }
.fav-meta { font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.fav-ops { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; flex-wrap: wrap; justify-content: flex-end; }
.fav-btn { border: 1px solid var(--line); background: #fff; color: var(--text); font-size: 12px;
  padding: 5px 9px; border-radius: 7px; cursor: pointer; white-space: nowrap; }
.fav-btn:hover { border-color: var(--primary); color: var(--primary); }
.fav-btn.load { background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600; }
.fav-btn.load:hover { background: #1e40af; color: #fff; }
.fav-btn.del { color: #dc2626; border-color: #fecaca; }
.fav-btn.del:hover { background: #fef2f2; border-color: #dc2626; color: #dc2626; }
.fav-confirm { font-size: 12px; color: #dc2626; }
.fav-input { width: 100%; border: 1px solid var(--line); border-radius: 8px; padding: 9px 10px;
  font-size: 13.5px; color: var(--text); outline: none; }
.fav-input:focus { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(29,78,216,.12); }
.fav-input.sm { width: 150px; padding: 5px 8px; font-size: 12.5px; }
/* ★2026-09-25 「🤝 共享空间」面板（多账号协同：点位可选共享，默认不共享） */
.sh-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.sh-toggle { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--text); cursor: pointer; user-select: none; }
.sh-toggle input { width: auto; margin: 0; }
.sh-count { font-size: 12px; color: var(--muted); margin-right: auto; }
.sh-note { font-size: 12px; color: var(--muted); line-height: 1.75; background: #f8fafc; border: 1px solid var(--line);
  border-radius: 9px; padding: 8px 10px; margin-bottom: 10px; }
.sh-note b { color: var(--text); }
.sh-row { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border: 1px solid var(--line);
  border-radius: 10px; margin-bottom: 8px; background: #fff; }
.sh-main { flex: 1 1 auto; min-width: 0; }
.sh-name { font-size: 13.5px; font-weight: 600; color: var(--text); word-break: break-all; }
.sh-meta { font-size: 11.5px; color: var(--muted); margin-top: 3px; line-height: 1.6; word-break: break-all; }
.sh-ops { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; flex-wrap: wrap; justify-content: flex-end; }
.sh-kind { font-size: 11px; color: #b45309; background: #fffbeb; border: 1px solid #fde68a;
  border-radius: 6px; padding: 1px 6px; margin-left: 6px; white-space: nowrap; }
.btn.share { background: #f59e0b; color: #fff; }   /* ★共享按键（橙色，与收藏的琥珀色区分） */
.btn.share:hover { background: #d97706; }
.btn.sh-clearall { background: #fff; border: 1px solid #fecaca; color: #dc2626; }   /* ★市局「清空全部共享」（危险操作，红字） */
.btn.sh-clearall:hover { background: #fef2f2; border-color: #dc2626; color: #dc2626; }
/* ★2026-09-26 态势总览·无人机资讯栏（**浮在地图上**，游走播报） */
.dash-map-panel > .panel-bd { position: relative; }
.news-ticker { position: absolute; top: 10px; left: 10px; right: 10px; z-index: 6;
  display: flex; align-items: center; gap: 8px; height: 32px; padding: 0 10px;
  background: linear-gradient(90deg, rgba(15,23,42,.90) 0%, rgba(30,58,138,.88) 68%, rgba(109,40,217,.86) 100%);
  color: #fff; border-radius: 8px; overflow: hidden; cursor: pointer;
  box-shadow: 0 2px 10px rgba(0,0,0,.35); user-select: none; }
.news-ticker:hover .nt-track { animation-play-state: paused; }
.news-ticker .nt-ico { flex: none; font-size: 14px; }
.news-ticker .nt-view { flex: 1; min-width: 0; overflow: hidden; }
.news-ticker .nt-track { display: inline-block; white-space: nowrap; will-change: transform;
  animation: nt-move var(--nt-dur, 60s) linear infinite; }
.news-ticker .nt-item { padding: 2px 4px; border-radius: 4px; font-size: 13px; letter-spacing: .2px; }
.news-ticker .nt-item:hover { background: rgba(255,255,255,.18); color: #ffe08a; }
.news-ticker .nt-sep { opacity: .45; }
.news-ticker .nt-more { flex: none; font-size: 12px; opacity: .9; white-space: nowrap; padding: 2px 6px; border-radius: 4px; background: rgba(255,255,255,.14); }
.news-ticker .nt-more:hover { background: rgba(255,255,255,.28); }
@keyframes nt-move { from { transform: translateX(0); } to { transform: translateX(-50%); } }
/* ★2026-09-26 态势总览地图控件：单键循环（实时/历史、行政/卫星）+ 新闻字幕开关 + 右下角空域 */
.dash-map-panel h2.clickable { cursor: pointer; }
.dash-map-panel h2.clickable:hover { color: #38bdf8; }
.dash-tg { border: 1px solid rgba(34,211,238,.28); border-radius: 7px; background: transparent; color: #8fb0d8;
  font-size: 11px; line-height: 1; padding: 5px 11px; cursor: pointer; white-space: nowrap; }
.dash-tg:hover { border-color: rgba(34,211,238,.6); color: #22d3ee; }
.dash-tg.on { background: rgba(34,211,238,.18); border-color: rgba(34,211,238,.55); color: #22d3ee; }
.dash-air-btn { position: absolute; right: 12px; bottom: 12px; z-index: 6;
  border: 1px solid rgba(34,211,238,.35); border-radius: 8px; background: rgba(255,255,255,.94);
  color: #0f172a; font-size: 12px; padding: 6px 12px; cursor: pointer; box-shadow: 0 1px 6px rgba(0,0,0,.22); }
.dash-air-btn:hover { border-color: rgba(34,211,238,.8); }
.dash-air-btn.on { background: var(--primary); border-color: var(--primary); color: #fff; }
/* 资讯目录弹窗（点条目看该条详情） */
.news-list { max-height: 56vh; overflow: auto; }
.news-item { padding: 9px 6px; border-bottom: 1px dashed var(--line); cursor: pointer; border-radius: 6px; }
.news-item:hover { background: #f1f5f9; }
.news-item:last-child { border-bottom: 0; }
.news-item .ni-hd { display: flex; gap: 8px; align-items: flex-start; }
.news-item .ni-cat { flex: none; font-size: 11px; color: #fff; background: var(--primary); border-radius: 4px; padding: 1px 6px; margin-top: 2px; }
.news-item .ni-title { font-size: 13.5px; font-weight: 600; color: var(--text); line-height: 1.45; }
.news-item .ni-meta { font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.news-item .ni-sum { font-size: 12px; color: #475569; line-height: 1.55; margin-top: 4px; }
.news-item .ni-link { display: inline-block; font-size: 12px; margin-top: 4px; }
/* 单条资讯详情弹窗 */
.nd-title { font-size: 15px; font-weight: 700; color: var(--text); line-height: 1.55; }
.nd-meta { font-size: 12px; color: var(--muted); margin-top: 6px; }
.nd-sum { font-size: 13px; color: #334155; line-height: 1.8; margin-top: 10px; white-space: pre-wrap; }
.nd-dim { color: var(--muted); }
@media (max-width: 720px) {
  .news-ticker { height: 30px; padding: 0 8px; top: 8px; left: 8px; right: 8px; }
  .news-ticker .nt-item { font-size: 12.5px; }
}
/* 地名搜索框 */
.search-wrap { position: relative; display: flex; align-items: center; background: #fff; border-radius: 0 8px 8px 0; }
.search-wrap button { padding: 6px 8px; border-radius: 6px; }
.search-wrap button:hover { background: #f1f5f9; }
.search-panel { display: none; position: absolute; top: calc(100% + 4px); right: 0; width: 264px; max-width: calc(100vw - 24px); background: #fff; border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,.2); padding: 8px; z-index: 120; text-align: left; }
.search-panel.show { display: block; }
.search-row { display: flex; gap: 6px; align-items: center; }
.search-row input { flex: 1; min-width: 0; border: 1px solid #e2e8f0; outline: none; font-size: 13px; padding: 6px 8px; border-radius: 6px; }
.search-row input:focus { border-color: var(--primary); }
/* 坐标输入坐标系说明（★2026-09-23 经纬度搜索：默认 WGS-84 → 高德） */
.sr-datum { display: flex; align-items: center; gap: 6px; padding: 6px 2px 1px; font-size: 11.5px; color: var(--muted); cursor: pointer; user-select: none; }
.sr-datum input { margin: 0; }
/* ★2026-09-23 「我的位置」图标按钮（铃铛右侧；图标＝地图定位针，红色） */
.myloc-btn {
  border: 0; background: transparent; cursor: pointer; padding: 2px 6px; border-radius: 6px;
  line-height: 1; color: #dc2626; display: inline-flex; align-items: center; justify-content: center;
  width: auto !important; height: auto !important; max-width: 44px; max-height: 34px; flex: 0 0 auto;
}
.myloc-btn svg { display: block; }
.myloc-btn:hover { background: rgba(220, 38, 38, .10); }
.myloc-btn.on { background: rgba(220, 38, 38, .16); box-shadow: inset 0 0 0 1.5px rgba(220, 38, 38, .5); }
.search-row button { border: none; background: #f1f5f9; padding: 6px 10px; cursor: pointer; font-size: 13px; }
.search-row button:hover { background: #e2e8f0; }
.search-results { width: 100%; max-height: 280px; overflow: auto; margin-top: 6px; display: none; }
.search-results.show { display: block; }
.sr-item { padding: 8px 10px; border-bottom: 1px solid var(--line); cursor: pointer; }
.sr-item:hover { background: #f1f5f9; }
.sr-item:last-child { border-bottom: none; }
.sr-item .nm { font-weight: 600; color: #1f2937; font-size: 13px; }
.sr-item .n { display: inline-block; min-width: 16px; text-align: center; color: #fff; background: var(--primary); border-radius: 4px; font-size: 11px; margin-right: 6px; padding: 0 2px; line-height: 16px; }
.sr-item .ad { color: var(--muted); font-size: 11px; margin-top: 2px; }
/* ★2026-09-25 搜索结果行右侧「⭐ 收藏此点位」小按键 */
.sr-item .nm { display: flex; align-items: center; gap: 6px; }
.sr-item .nm-t { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sr-item .sr-fav { flex: none; border: 1px solid var(--line); background: #fff; color: #d97706;
  font-size: 12px; line-height: 1; padding: 4px 7px; border-radius: 7px; cursor: pointer; }
.sr-item .sr-fav:hover { background: #fffbeb; border-color: #d97706; }
.sr-empty { padding: 12px 10px; color: var(--muted); font-size: 12px; }
.sr-foot { padding: 6px; border-top: 1px solid var(--line); }
.sr-clear { width: 100%; border: none; background: #f1f5f9; color: #64748b; padding: 6px; border-radius: 6px; cursor: pointer; font-size: 12px; }
.sr-clear:hover { background: #e2e8f0; color: #334155; }
.measure-lbl { background: #2563eb; color: #fff; font-size: 12px; font-weight: 600; padding: 3px 8px; border-radius: 4px;
  white-space: nowrap; box-shadow: 0 1px 4px rgba(0,0,0,.25); }
/* 遥控器图标 */
.rc-ic { color: #f97316; width: 30px; height: 30px; filter: drop-shadow(0 1px 3px rgba(0,0,0,.3)); }
.rc-ic svg { width: 30px; height: 30px; }
.target-list { flex: 1; overflow: auto; min-height: 0; padding: 12px; background: #f4f6fb; }
.target-item { position: relative; padding: 10px 12px; border: 1px solid #e6ebf3; border-left: 3px solid #2563eb; border-radius: 10px; margin-bottom: 8px; cursor: pointer; background: #fff; box-shadow: 0 1px 2px rgba(15,23,42,.05); transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; }
.target-item:hover { border-color: #2563eb; transform: translateY(-1px); box-shadow: 0 6px 14px -6px rgba(37,99,235,.3); }
.target-item.black { border-color: #fecaca; border-left-color: #dc2626; background: #fef2f2; }
.target-item.black:hover { border-color: #fca5a5; box-shadow: 0 6px 14px -6px rgba(220,38,38,.3); }
.target-item.whitelist { border-color: #a5f3fc; border-left-color: #0891b2; background: #ecfeff; }
.target-item.whitelist:hover { border-color: #67e8f9; box-shadow: 0 6px 14px -6px rgba(8,145,178,.3); }
.target-item .row { display: flex; align-items: center; gap: 8px; }
.target-item .row2 { display: flex; gap: 12px; font-size: 12px; color: var(--muted); margin-top: 5px; flex-wrap: wrap; }

/* ===== 地图标记 ===== */
.mk { width: 30px; height: 30px; border-radius: 50%; border: 2px solid #fff; box-shadow: 0 2px 6px rgba(0,0,0,.35);
  display: flex; align-items: center; justify-content: center; font-size: 15px; cursor: pointer; color: #fff; font-weight: 700; }
.mk-red { background: #ef4444; } .mk-blue { background: #2563eb; } .mk-green { background: #16a34a; }
.mk-gray { background: #9ca3af; } .mk-orange { background: #f97316; } .mk-dev { background: #334155; } .mk-white { background: #0891b2; }
.mk.off { opacity: .45; filter: grayscale(1); }
.mk-wrap { position: relative; }
.mk-lbl { position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); font-size: 10px; font-weight: 400; color: #475569; background: rgba(255,255,255,.72); padding: 0 4px; border-radius: 3px;
  border: 1px solid rgba(100,116,139,.18); white-space: nowrap; margin-bottom: 3px; line-height: 1.5; letter-spacing: .3px; }
.mk-lbl .st { display: inline-block; width: 6px; height: 6px; border-radius: 50%; margin-left: 4px; vertical-align: middle; }
.mk-lbl .st.on { background: #22c55e; } .mk-lbl .st.off { background: #94a3b8; }

/* =====侦测设备图标（方案2 · 信号塔，统一绿色） ===== */
.dev-tower { color: #3b82f6; }
.dev-tower svg { overflow: visible; }
.dev-tower .wave { stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; opacity: 0; }
.dev-tower .w1 { animation: dev-twave 2.2s ease-out infinite; }
.dev-tower .w2 { animation: dev-twave 2.2s ease-out infinite .55s; }
.dev-tower .w3 { animation: dev-twave 2.2s ease-out infinite 1.1s; }
.dev-tower .bulb { fill: currentColor; animation: dev-tblink 1.4s ease-in-out infinite; }
.dev-tower .body { fill: currentColor; }
.dev-tower.off { opacity: .5; filter: grayscale(1); }
.dev-tower.off .bulb { animation: none; }
@keyframes dev-twave { 0% { opacity: 0; transform: scale(.4); } 30% { opacity: .9; } 100% { opacity: 0; transform: scale(1.5); } }
@keyframes dev-tblink { 0%,100% { opacity: 1; } 50% { opacity: .35; } }

/* 车载设备（警车）图标 */
.dev-car { display: inline-block; }
.dev-car svg { display: block; }
.dev-car .car-body { fill: currentColor; }
.dev-car .car-wheel { fill: #1f2937; stroke: currentColor; stroke-width: 1.1; }
.dev-car .car-flash { fill: #ef4444; animation: dev-carflash .7s steps(2, start) infinite; }
.dev-car.off .car-flash { animation: none; }
@keyframes dev-carflash { 0%,100% { fill: #ef4444; } 50% { fill: #3b82f6; } }

/* 多旋翼无人机图标（半透明旋翼，醒目不遮挡） */
.drone-ic { width: 34px; height: 34px; filter: drop-shadow(0 1px 3px rgba(0,0,0,.3)); }
.drone-ic svg { width: 34px; height: 34px; }
.drone-ic.red { color: #dc2626; } .drone-ic.blue { color: #2563eb; } .drone-ic.green { color: #16a34a; } .drone-ic.gray { color: #9ca3af; } .drone-ic.white { color: #0891b2; }

/* 实时目标计数徽章（着重显示） */
.count-badge { background: #dc2626; color: #fff; font-size: 20px; font-weight: 800; line-height: 1;
  padding: 6px 10px; border-radius: 10px; min-width: 30px; text-align: center; }

/* 实时目标列表项 */
.target-item .tag { font-size: 11px; line-height: 16px; padding: 0 7px; border-radius: 9px; }
/* ★2026-09-26 顶行统一排版：性质标签 / 空情等级 / 机型 / 实名 与同一基线、同一节奏（间距 6px）*/
.target-item .ti-top { display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; line-height: 18px; }
.target-item .ti-top > .tag { flex: 0 0 auto; }
.target-item .ti-top b { flex: 1 1 auto; min-width: 0; font-size: 12px; font-weight: 600; color: #1e293b; letter-spacing: .2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 空情等级：与标签同尺寸的「描边胶囊」，颜色随等级（Ⅰ红/Ⅱ橙/Ⅲ灰），不与性质标签撞底 */
.target-item .ti-top .grade-tag { flex: 0 0 auto; margin-left: 0; padding: 0 6px; font-size: 11px; line-height: 14px; font-weight: 800; letter-spacing: .3px; border: 1px solid currentColor; border-radius: 9px; }
.target-item .ti-top > .tag:last-child { margin-left: auto; }   /* 实名/未实名 靠右，顶行左右跳幅平衡 */
.target-item .ti-mid { display: flex; gap: 8px; font-size: 11px; color: var(--muted); margin-top: 4px; flex-wrap: nowrap; }
.target-item .ti-mid span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.target-item .ti-mid span:first-child { flex-shrink: 0; }
.target-item .ti-loc { display: flex; align-items: center; gap: 6px; font-size: 11px; color: #16a34a; margin-top: 3px; }
.target-item .ti-loc .ti-town { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.target-item .ti-loc:empty { display: none; }
.target-item .white-alias { color: #16a34a; font-weight: 600; }
.target-item .ti-btns { display: flex; gap: 5px; margin-top: 6px; }
.target-item .h-badge { font-size: 11px; font-weight: 700; color: var(--primary); white-space: nowrap; flex-shrink: 0; }
.target-item .h-badge .h-max { font-size: 10px; color: var(--muted); font-weight: 600; margin-left: 2px; }
/* 累计侦测次数（单独一行） */
.target-item .ti-visit { display: flex; align-items: center; gap: 10px; font-size: 11px; color: var(--muted); margin-top: 3px; }
.target-item .ti-visit .alias { color: #334155; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 150px; }
.target-item .ti-visit b { color: var(--primary); font-weight: 700; }
.target-item .ti-visit .ti-real { color: #059669; font-weight: 600; font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 150px; }
/* ★2026-09-21 实时目标卡片：报备人 / 单位行（报备机专用，与白名单/普通目标区分） */
.target-item .ti-frep { display: flex; align-items: center; gap: 6px; margin-top: 3px; font-size: 11px; overflow: hidden; }
.target-item .ti-frep .ti-frep-tag { flex: 0 0 auto; background: #ede9fe; color: #6d28d9; border: 1px solid #c4b5fd; border-radius: 4px; padding: 0 4px; font-weight: 700; }
.target-item .ti-frep.bad .ti-frep-tag { background: #fee2e2; color: #b91c1c; border-color: #fca5a5; }
.target-item .ti-frep .ti-frep-txt { color: #5b21b6; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.target-item .ti-frep.bad .ti-frep-txt { color: #b91c1c; }
/* 侧栏收起按钮：桌面隐藏，仅移动端显示在“实时目标”数字旁 */
.side-collapse { display: none; }
.mini-btn { border: 1px solid var(--line); background: #fff; border-radius: 6px; padding: 3px 9px; font-size: 12px; cursor: pointer; }
.mini-btn:hover { border-color: var(--primary); }
.mini-btn.drone { color: #dc2626; } .mini-btn.rc { color: #f97316; } .mini-btn.detail { color: var(--primary); font-weight: 600; } .mini-btn.dispose { color: #16a34a; font-weight: 600; }

/* 黑白名单左右并列 */
.bw-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: start; }
@media (max-width: 900px) { .bw-grid { grid-template-columns: 1fr; } }

/* 事件警情全屏 */
.ev-card { display: flex; flex-direction: column; height: calc(100vh - 84px); margin-bottom: 0; }
@media (max-width: 900px) { .ev-card { height: calc(100vh - 150px); } }

/* ===== 表单 ===== */
.filter-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 10px; }
.case-filter { display: flex; align-items: flex-end; gap: 6px; flex-wrap: wrap; padding: 10px; background: #eef2f7; border: 1px solid var(--line); border-radius: 10px; }
.case-search-card { padding: 0; background: transparent; box-shadow: none; border-radius: 0; margin-bottom: 10px; }
.case-table-card { padding: 0; margin-bottom: 0; }
.view.flexcol { display: flex; flex-direction: column; }
.view.flexcol .case-search-card { flex: 0 0 auto; }
.view.flexcol .case-table-card { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.view.flexcol .case-table-card .table-wrap { flex: 1; min-height: 0; max-height: none; overflow: hidden; }
.case-filter .cf { display: flex; flex-direction: column; }
.case-filter .cf label { font-size: 12px; font-weight: 700; color: #1f2937; margin-bottom: 4px; white-space: nowrap; }
.case-filter .cf input, .case-filter .cf select { padding: 6px 8px; border: 1px solid var(--line); border-radius: 6px; font-size: 12px; outline: none; background: #fff; transition: border-color .15s, box-shadow .15s; }
.case-filter .cf input:focus, .case-filter .cf select:focus { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(37,99,235,.12); }
.case-filter .cf-btns { display: flex; gap: 6px; padding-bottom: 1px; flex: 1 1 100%; }
.case-filter .cf-btns .btn { white-space: nowrap; }
/* 起止时间：下拉面板 */
.case-range-pop { position: relative; width: 100%; }
.case-range-btn { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 6px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 6px; font-size: 12px; background: #fff; color: #1f2937; cursor: pointer; white-space: nowrap; font-family: inherit; }
.case-range-btn i { font-style: normal; font-size: 9px; color: var(--muted); }
.case-range-menu { position: absolute; top: calc(100% + 4px); left: 0; z-index: 60; width: 256px; background: #fff; border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,.16); padding: 10px; }
.crm-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.crm-lab { flex: 0 0 40px; font-size: 12px; color: #374151; white-space: nowrap; }
.case-filter .cf .case-range-menu input,
.case-filter .cf .case-range-menu select { flex: 1; min-width: 0; width: auto; padding: 5px 7px; border: 1px solid var(--line); border-radius: 5px; font-size: 12px; background: #fff; box-shadow: none; }
.crm-actions { display: flex; gap: 6px; justify-content: flex-end; margin-top: 4px; }

/* ===== 空情处置：移动端友好（不影响 PC） ===== */
@media (max-width: 900px) {
  .case-filter .cf { flex: 1 1 calc(50% - 3px) !important; min-width: 0; }
  .case-filter .cf input, .case-filter .cf select { width: 100%; box-sizing: border-box; font-size: 16px; padding: 9px 8px; }
  .case-filter .cf-btns { flex: 1 1 100% !important; }
  .case-filter .cf-btns .btn { flex: 1; padding: 10px 8px; }
  .view.flexcol .case-table-card .table-wrap { overflow: auto; -webkit-overflow-scrolling: touch; }
  .case-table-card table { min-width: 840px; }
  .case-table-card th, .case-table-card td { padding: 11px 12px; }
  .pager button { padding: 9px 15px; font-size: 14px; }
}
.date-wrap { display: flex; align-items: center; gap: 5px; }
.date-wrap input { flex: 1; min-width: 0; }
.date-wrap input::-webkit-calendar-picker-indicator { cursor: pointer; opacity: .7; }
.over-tag { display: inline-block; font-size: 12px; line-height: 1.3; color: #dc2626; font-weight: 700; white-space: nowrap; }
.air-tag { display: inline-block; font-size: 12px; line-height: 1.3; font-weight: 700; white-space: nowrap; }
.air-tag.free { color: #16a34a; }
.air-tag.ctrl { color: #d97706; }
.air-tag.hsr { color: #ea580c; }
.air-tag.bj { color: #dc2626; }
.field label { display: block; font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.field input, .field select, .field textarea { width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 13px; outline: none; font-family: inherit; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--primary); }
.range2 { display: flex; align-items: center; gap: 6px; }
.range2 input { width: 50%; }
.chiprow { display: flex; align-items: center; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.field.btns { display: flex; align-items: flex-end; }
.btngroup { display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; }
.btngroup .btn { white-space: nowrap; }

/* ===== 弹窗 ===== */
.modal-mask { position: fixed; inset: 0; background: rgba(15,23,42,.5); z-index: 3000; display: flex;
  align-items: center; justify-content: center; padding: 16px; }
.modal { background: #fff; border-radius: 14px; width: 560px; max-width: 96vw; max-height: 88vh; display: flex; flex-direction: column; }
.modal.wide { width: 940px; }
.modal.xwide { width: min(1160px, 96vw); height: 92vh; }
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border-bottom: 1px solid var(--line); font-weight: 700; }
.modal-head .close { background: none; border: none; font-size: 18px; cursor: pointer; color: var(--muted); }
.modal-body { padding: 16px 18px; overflow: auto; }
.locblock { border: 1px solid var(--line); border-radius: 10px; padding: 12px; margin-bottom: 10px; }
.locblock.red { border-color: #fecaca; background: #fef2f2; }
.locblock.orange { border-color: #fed7aa; background: #fff7ed; }
.locblock .lhead { display: flex; align-items: center; gap: 8px; font-weight: 700; margin-bottom: 6px; }
.locrow { display: flex; align-items: center; gap: 8px; font-size: 13px; margin: 5px 0; flex-wrap: wrap; }
.locrow .lbl { color: var(--muted); flex: 0 0 auto; }
.navchips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }
.navchips a { font-size: 12px; padding: 4px 10px; border: 1px solid var(--primary); border-radius: 6px; color: var(--primary); }
.dl { display: grid; grid-template-columns: 90px 1fr; row-gap: 6px; font-size: 13px; }
.dl .k { color: var(--muted); }
.copybtn { font-size: 11px; padding: 2px 7px; border: 1px solid var(--line); background: #fff; border-radius: 5px; cursor: pointer; color: var(--primary); }
.copybtn:hover { border-color: var(--primary); }
.bj-dist { color: #dc2626; font-weight: 700; }
.hsr-dist { color: #ea580c; font-weight: 700; }
.warn-tag { color: #dc2626; font-weight: 700; font-size: 12px; }
.pb-warn { color: #dc2626; font-weight: 700; }
.section-title { font-weight: 700; font-size: 14px; margin: 14px 0 8px; padding-left: 8px; border-left: 3px solid var(--primary); }

/* ===== 回放 ===== */
.playbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.pb-btn { width: 40px; height: 40px; border-radius: 50%; border: none; background: var(--primary); color: #fff;
  font-size: 16px; cursor: pointer; }
.pb-btn.stop { background: var(--warn); }
.speed button { border: 1px solid var(--line); background: #fff; padding: 4px 9px; border-radius: 6px; cursor: pointer; font-size: 12px; }
.speed button.on { background: var(--primary); color: #fff; border-color: var(--primary); }
.playbar input[type=range] { flex: 1; min-width: 120px; }
.playmap { position: relative; }
.pb-alt { position: absolute; top: 10px; left: 10px; z-index: 10; background: rgba(15,23,42,.78); color: #fff;
  border-radius: 8px; padding: 6px 12px; font-size: 12px; line-height: 1.5; pointer-events: none; }
.pb-modal-map { height: 340px; border-radius: 12px; overflow: hidden; position: relative; box-shadow: 0 1px 3px rgba(0,0,0,.08); }

/* ===== 轨迹回放整页 ===== */
.pb-page { display: flex; flex-direction: column; height: calc(100vh - 50px); gap: 6px; padding: 8px; }
.pb-head { background: var(--card); border-radius: 12px; padding: 8px 12px; box-shadow: 0 1px 3px rgba(0,0,0,.08);
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }
.pb-title { display: flex; align-items: center; gap: 8px; font-size: 15px; }
.pb-meta { display: flex; gap: 8px 10px; flex-wrap: wrap; font-size: 13.5px; color: var(--text); font-weight: 600; }
.pb-meta > span { background: #eef2f7; border-radius: 6px; padding: 3px 9px; }
.pb-meta .pb-maxalt { color: #dc2626; background: #fdecec; font-weight: 700; }
.pb-real { width: 100%; font-size: 14px; color: var(--text); font-weight: 700; margin-top: 4px; }
.pb-real .pb-ok { color: #16a34a; }
.pb-real .pb-no { color: #dc2626; }
.pb-map-wrap { flex: 1; min-height: 0; position: relative; border-radius: 12px; overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,.08); }
.pb-map-wrap #pbMap { width: 100%; height: 100%; }
.pb-controls { background: var(--card); border-radius: 12px; padding: 6px 12px; box-shadow: 0 1px 3px rgba(0,0,0,.08); }
.pb-actions { display: flex; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
.pb-org { color: var(--primary); font-weight: 600; }
.pb-flow-panel { flex: 0 0 auto; max-height: 32vh; overflow-y: auto; background: var(--card); border-radius: 12px; padding: 10px 14px; box-shadow: 0 1px 3px rgba(0,0,0,.08); }
.pb-flow-title { font-weight: 700; font-size: 13px; margin-bottom: 8px; color: var(--text); }
.flow-item { display: flex; gap: 10px; padding: 7px 0; }
.flow-item + .flow-item { border-top: 1px dashed var(--line); }
.flow-ic { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 14px; background: #eff6ff; }
.flow-bd { flex: 1; min-width: 0; }
.flow-t { font-size: 13px; color: var(--text); overflow-wrap: break-word; }
.flow-m { font-size: 11px; color: var(--muted); margin-top: 2px; }

/* ===== AI ===== */
.ai-box { border: 1px dashed var(--primary); border-radius: 10px; padding: 14px; background: #eff6ff; white-space: pre-wrap;
  font-size: 13px; line-height: 1.7; min-height: 80px; }
.ai-ask { display: flex; gap: 8px; margin-top: 10px; }
.ai-ask input { flex: 1; padding: 9px 12px; border: 1px solid var(--line); border-radius: 8px; outline: none; }

/* ===== 后台 ===== */
.admin-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; }
.admin-tabs button { border: 1px solid var(--line); background: #fff; padding: 8px 16px; border-radius: 8px; cursor: pointer; font-size: 13px; }
.admin-tabs button.on { background: var(--primary); color: #fff; border-color: var(--primary); }
/* ===== 办案中心 ===== */
.cc-flow { display: flex; align-items: stretch; gap: 10px; margin-bottom: 16px; flex-wrap: wrap; }
.cc-stage { flex: 1; min-width: 140px; background: linear-gradient(160deg, #ffffff, #f4f7fb); border: 1px solid var(--line); border-radius: 12px; padding: 16px 14px; display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center; }
.cc-stage-ic { font-size: 30px; line-height: 1; }
.cc-stage b { font-size: 15px; color: #1f2937; }
.cc-stage span { font-size: 11px; color: var(--muted); }
.cc-stage em { font-style: normal; font-size: 22px; font-weight: 700; color: var(--primary); margin-top: 2px; }
.cc-arrow { display: flex; align-items: center; font-size: 20px; color: var(--primary); opacity: .6; }
.cc-stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; margin-bottom: 16px; }
.cc-stat { background: #fff; border: 1px solid var(--line); border-radius: 10px; padding: 12px; display: flex; flex-direction: column; align-items: center; gap: 2px; }
.cc-stat b { font-size: 22px; font-weight: 700; color: #1f2937; }
.cc-stat span { font-size: 11px; color: var(--muted); }
.cc-stat.ok b { color: #16a34a; }
.cc-stat.warn b { color: #d97706; }
.cc-stat.info b { color: #2563eb; }
.cc-desc { font-size: 12.5px; line-height: 1.9; color: #4b5563; padding: 4px 2px; }

/* ===== 底部导航（移动端） ===== */
.bottomnav { display: none; position: fixed; bottom: 0; left: 0; right: 0; z-index: 50;
  background: linear-gradient(90deg, #16273f 0%, #1e3a5c 50%, #16273f 100%); }
.bottomnav a { flex: 1; color: #94a3b8; text-align: center; padding: 8px 2px; font-size: 11px; display: flex;
  flex-direction: column; gap: 2px; align-items: center; }
.bottomnav a .ic { font-size: 18px; }
.bottomnav a.on { color: #fff; }

/* ===== 空状态 ===== */
.empty { text-align: center; color: var(--muted); padding: 30px 10px; font-size: 13px; }

/* ===== 响应式 ===== */
@media (max-width: 900px) {
  .rt-page { height: calc(100vh - 66px); padding: 0; gap: 0; }
  .rt-wrap { flex-direction: column; gap: 0; }
  .rt-map { flex: 1; min-height: 0; }
  .mapbox { flex: 1; height: auto; min-height: 0; border-radius: 0; }
  .rt-side { width: 100%; flex: 0 0 auto; max-height: 46vh; }
  .rt-side.collapsed { width: 100%; }
  .rt-side.collapsed .target-list { display: none; }
  .rt-side-card { flex: 1; min-height: 0; border-radius: 0; border-left: none; border-top: 1px solid #e3e9f2; box-shadow: 0 -6px 20px -12px rgba(15,23,42,.25); }
  .side-toggle { display: none; }
  .side-collapse { margin-left: auto; display: inline-flex; align-items: center; gap: 4px; background: rgba(255,255,255,.14); color: #fff; border: 1px solid rgba(255,255,255,.35); border-radius: 7px; padding: 6px 13px; font-size: 12px; font-weight: 700; letter-spacing: 1px; cursor: pointer; }
  .target-list { max-height: 46vh; }
  .topbar { display: none; }
  .topbar .nav { display: none; }
  .topbar .name { display: none; }
  .bottomnav { display: flex; }
  .bottomnav a { font-size: 10px; padding: 7px 2px; }
  .bottomnav a .ic { font-size: 20px; }
  .view { padding: 10px 10px 66px; }
  .view.full { padding: 0 0 66px; }
  .uname { max-width: 70px; }
  .dl { grid-template-columns: 76px 1fr; }
  /* 更友好的移动端操作 */
  .btn { padding: 10px 15px; }
  .btn.sm { padding: 8px 13px; font-size: 13px; }
  .btn.xs { padding: 7px 11px; font-size: 12px; }
  .mini-btn { padding: 6px 12px; font-size: 13px; }
  .field input, .field select { padding: 11px 10px; font-size: 15px; }
  .card { padding: 12px; }
  /* 弹窗全屏 */
  .modal-mask { padding: 0; }
  .modal { width: 100%; max-width: 100%; height: 100vh; max-height: 100vh; border-radius: 0; }
  .modal-body { flex: 1; }
  /* 轨迹回放整页适配 */
  .pb-page { height: calc(100vh - 50px); padding: 8px; gap: 8px; }
  .pb-head { padding: 10px; gap: 6px 10px; }
  .pb-map-wrap { min-height: 260px; }
  .playbar { gap: 6px; }
  .speed button { padding: 6px 10px; }
}
@media (max-width: 560px) {
  .filter-grid { grid-template-columns: 1fr; }
  .admin-tabs button { padding: 9px 12px; }
  .table-wrap { max-height: 55vh; }
}

/* ===== 数据提取·AI 模块 ===== */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; margin-bottom: 14px; }
.stat-grid .stat { background: var(--card); border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,.08); padding: 14px 16px; }
.stat-grid .stat .n { font-size: 24px; font-weight: 700; color: var(--primary); }
.stat-grid .stat .l { font-size: 12px; color: var(--muted); margin-top: 4px; }

.bar-list { display: flex; flex-direction: column; gap: 8px; }
.bar-item { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.bar-item .bn { flex: 0 0 140px; text-align: right; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-item .bar { flex: 1; background: var(--bg); border-radius: 6px; height: 14px; overflow: hidden; }
.bar-item .bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--primary), #60a5fa); border-radius: 6px; }
.bar-item .bc { flex: 0 0 40px; color: var(--muted); }

.mining-map { height: 380px; border-radius: 10px; border: 1px solid var(--line); margin-bottom: 10px; }

.ai-box.md { white-space: normal; text-align: left; }
.ai-box.md .md-h { margin: 12px 0 6px; color: var(--text); }
.ai-box.md h1 { font-size: 18px; }
.ai-box.md h2 { font-size: 16px; }
.ai-box.md h3 { font-size: 14px; }
.ai-box.md p { margin: 6px 0; }
.ai-box.md .md-li { margin: 3px 0 3px 4px; }
.ai-box.md table.md-table { border-collapse: collapse; width: 100%; margin: 8px 0; }
.ai-box.md table.md-table td { border: 1px solid var(--line); padding: 6px 8px; font-size: 12px; }
.ai-box.md code { background: var(--bg); padding: 1px 5px; border-radius: 4px; font-size: 12px; }

@media (max-width: 560px) {
  .mining-map { height: 280px; }
  .stat-grid { grid-template-columns: repeat(2, 1fr); }
  .bar-item .bn { flex-basis: 96px; }
}

/* 数据提取·AI 紧凑操作栏 */
.mining-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.mining-bar label { font-size: 12px; color: var(--muted); white-space: nowrap; }
.mining-bar select, .mining-bar input[type="datetime-local"], .mining-bar input[type="text"], .mining-bar input[type="number"] {
  padding: 5px 6px; font-size: 12px; border: 1px solid var(--line); border-radius: 6px; background: #fff; color: var(--text);
}
.mining-bar input[type="datetime-local"] { width: 168px; }
.mining-bar select { max-width: 108px; }
.mining-bar input[type="file"] { font-size: 11px; max-width: 180px; }
.clickable { cursor: pointer; }
.clickable:hover td { background: var(--bg); }

/* 数据提取·AI 全屏布局（点位分布大屏地图） */
.mining-page { display: flex; flex-direction: column; height: calc(100vh - 42px); }
.mining-tabs { flex: 0 0 auto; display: flex; gap: 4px; padding: 6px 10px; background: var(--card);
  box-shadow: 0 1px 3px rgba(0,0,0,.08); overflow-x: auto; scrollbar-width: none; }
.mining-tabs::-webkit-scrollbar { display: none; }
.mining-tabs button { border: 1px solid var(--line); background: #fff; padding: 4px 11px; border-radius: 7px;
  cursor: pointer; font-size: 12px; white-space: nowrap; }
.mining-tabs button.on { background: var(--primary); color: #fff; border-color: var(--primary); }
.mining-body { flex: 1; min-height: 0; overflow: auto; padding: 10px; }
.mining-body.points { overflow: hidden; padding: 0; display: flex; flex-direction: column; }
/* 点位分布：操作栏 + 全屏地图 */
.points-bar { flex: 0 0 auto; padding: 6px 10px; background: var(--card); box-shadow: 0 1px 3px rgba(0,0,0,.08); }
.points-map { flex: 1; min-height: 0; height: auto; position: relative; }
.points-map .mining-mapbox { width: 100%; height: 100%; }

@media (max-width: 900px) {
  .mining-page { height: calc(100vh - 66px); }
  .mining-body { padding: 8px; }
  .points-bar { padding: 5px 8px; }
}

/* ===== 态势总览·大屏（深色科技风） ===== */
.mining-body.dash { padding: 0; overflow: auto; background: #050b1e; }
.dash {
  position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 2000;
  display: flex; flex-direction: column; overflow: hidden;
  color: #dbeafe; padding: 10px 14px 10px; animation: dashIn .5s ease;
  background:
    radial-gradient(1200px 520px at 12% -10%, rgba(34,211,238,.14), transparent 60%),
    radial-gradient(1000px 520px at 88% 0%, rgba(59,130,246,.14), transparent 60%),
    linear-gradient(rgba(34,211,238,.035) 1px, transparent 1px),
    linear-gradient(90deg, rgba(34,211,238,.035) 1px, transparent 1px),
    #050b1e;
  background-size: auto, auto, 42px 42px, 42px 42px, auto;
}
.dash::before {
  content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(640px 440px at 18% 6%, rgba(34,211,238,.16), transparent 60%),
    radial-gradient(720px 520px at 84% 94%, rgba(59,130,246,.16), transparent 60%);
  animation: dashAurora 9s ease-in-out infinite;
}
.dash::after {
  content: ''; position: fixed; left: 0; right: 0; top: -160px; height: 160px; z-index: 999; pointer-events: none;
  background: linear-gradient(180deg, transparent, rgba(34,211,238,.09), transparent);
  animation: dashScan 7s linear infinite;
}
@keyframes dashIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes dashAurora { 0%, 100% { opacity: .45; } 50% { opacity: 1; } }
@keyframes dashScan { 0% { transform: translateY(0); } 100% { transform: translateY(calc(100vh + 160px)); } }
.dash-head { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; margin-bottom: 8px; }
.dash-title { display: flex; align-items: center; gap: 14px; }
.dash-logo { font-size: 32px; width: 56px; height: 56px; display: flex; align-items: center; justify-content: center;
  border-radius: 14px; background: linear-gradient(135deg, rgba(34,211,238,.18), rgba(59,130,246,.18));
  border: 1px solid rgba(34,211,238,.4); box-shadow: 0 0 20px rgba(34,211,238,.25); }
.dash-title h1 { font-size: 22px; font-weight: 800; letter-spacing: 1px;
  background: linear-gradient(90deg, #e0f2fe, #7dd3fc, #22d3ee);
  -webkit-background-clip: text; background-clip: text; color: transparent; }
.dash-title p { font-size: 10px; letter-spacing: 3px; color: #5b7aa8; margin-top: 3px; }
.dash-head-right { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.dash-exit { margin-left: 4px; font-size: 12px; color: #a8d8f0; background: rgba(34,211,238,.08);
  border: 1px solid rgba(34,211,238,.28); border-radius: 8px; padding: 5px 11px; cursor: pointer; transition: all .2s; }
.dash-exit:hover { background: rgba(34,211,238,.18); color: #fff; box-shadow: 0 0 10px rgba(34,211,238,.35); }
.dash-stat-chip { font-size: 12px; color: #8fb0d8; border: 1px solid rgba(34,211,238,.25); border-radius: 8px; padding: 5px 10px; background: rgba(13,34,66,.6); }
.dash-stat-chip b { color: #22d3ee; font-variant-numeric: tabular-nums; }
.dash-stat-chip b.red { color: #f87171; } .dash-stat-chip b.cyan { color: #22d3ee; }
.dash-stat-chip i { font-style: normal; color: #5b7aa8; }
.dash-clock { font-size: 15px; font-weight: 700; color: #e0f2fe; letter-spacing: 1px; font-variant-numeric: tabular-nums; }

.dash-kpis { flex: 0 0 auto; display: grid; grid-template-columns: repeat(8, 1fr); gap: 8px; margin-bottom: 8px; }
.kpi { position: relative; display: flex; flex-direction: column; justify-content: center; padding: 5px 10px 6px 12px; border-radius: 10px;
  background: linear-gradient(160deg, rgba(17,38,74,.85), rgba(9,20,44,.85));
  border: 1px solid rgba(56,130,246,.25); overflow: hidden; }
.kpi::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: linear-gradient(180deg, #22d3ee, #3b82f6); box-shadow: 0 0 12px rgba(34,211,238,.6); }
.kpi.warn::before { background: linear-gradient(180deg, #f59e0b, #f97316); box-shadow: 0 0 12px rgba(245,158,11,.6); }
.kpi.danger::before { background: linear-gradient(180deg, #f43f5e, #fb7185); box-shadow: 0 0 12px rgba(244,63,94,.6); }
.kpi-ic { font-size: 20px; opacity: .9; }
.kpi b.num { font-size: 19px; font-weight: 800; line-height: 1; color: #e0f2fe;
  font-variant-numeric: tabular-nums; text-shadow: 0 0 14px rgba(34,211,238,.4); animation: dashGlow 3s ease-in-out infinite; }
.kpi span { font-size: 10px; color: #8fb0d8; margin-top: 1px; display: flex; align-items: baseline; gap: 3px; white-space: nowrap; overflow: hidden; }
.kpi em { font-style: normal; font-size: 9px; }
.kpi em.up { color: #f87171; } .kpi em.down { color: #34d399; } .kpi em.flat { color: #64748b; }
@keyframes dashGlow { 0%, 100% { text-shadow: 0 0 10px rgba(34,211,238,.35); } 50% { text-shadow: 0 0 22px rgba(34,211,238,.75); } }
.kpi-body em { font-style: normal; font-size: 11px; margin-top: 2px; }
.kpi-body em.up { color: #f87171; } .kpi-body em.down { color: #34d399; } .kpi-body em.flat { color: #64748b; }

.dash-main { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: 1fr 1.55fr 1fr; gap: 10px; align-items: stretch; }
.dash-col-side { display: flex; flex-direction: column; gap: 10px; min-height: 0; overflow-y: auto; padding-right: 2px; }
.dash-col-center { min-height: 0; }
.dash-map-panel { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.dash-map-panel .panel-bd { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.dash-map { flex: 1; min-height: 260px; border-radius: 8px; overflow: hidden; position: relative; z-index: 1; }
.dash-map-wrap { position: relative; }
.dash-real-summary { position: absolute; top: 10px; left: 10px; z-index: 120; max-width: 270px;
  background: rgba(6, 16, 34, .85); border: 1px solid rgba(34, 211, 238, .35); border-radius: 10px;
  padding: 10px 12px; box-shadow: 0 0 24px rgba(34, 211, 238, .25); }
.rs-hd { font-size: 12px; font-weight: 700; color: #22d3ee; margin-bottom: 8px; letter-spacing: .5px; }
.rs-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.rs-item { text-align: center; }
.rs-item b { display: block; font-size: 17px; font-weight: 800; color: #e0f2fe; font-variant-numeric: tabular-nums; }
@keyframes violPulse {
  0%, 100% { transform: scale(1); text-shadow: 0 0 6px rgba(255,77,79,.45); }
  50% { transform: scale(1.14); text-shadow: 0 0 20px rgba(255,77,79,1), 0 0 34px rgba(255,77,79,.65); }
}
@keyframes yellowPulse {
  0%, 100% { transform: scale(1); text-shadow: 0 0 6px rgba(250,204,21,.45); }
  50% { transform: scale(1.14); text-shadow: 0 0 20px rgba(250,204,21,1), 0 0 34px rgba(250,204,21,.65); }
}
@keyframes whitePulse {
  0%, 100% { transform: scale(1); text-shadow: 0 0 6px rgba(255,255,255,.4); }
  50% { transform: scale(1.14); text-shadow: 0 0 20px rgba(255,255,255,.95), 0 0 34px rgba(255,255,255,.55); }
}
.rs-item.red b { color: #ff4d4f; font-size: 19px; animation: violPulse 1s ease-in-out infinite; }
.rs-item.red span { color: #fb7185; font-weight: 700; }
.rs-item.yellow b { color: #facc15; font-size: 19px; animation: yellowPulse 1s ease-in-out infinite; }
.rs-item.yellow span { color: #fde047; font-weight: 700; }
/* ★§118 空情等级配色（最高等级）：Ⅰ级红 / Ⅱ级橘 / Ⅲ级黄 */
.rs-item.orange b { color: #fb923c; font-size: 19px; animation: yellowPulse 1s ease-in-out infinite; }
.rs-item.orange span { color: #fdba74; font-weight: 700; }
/* ★2026-10-02 空情等级统一配色（大屏深底）：二级蓝、三级白 */
.rs-item.blue b { color: #38bdf8; font-size: 19px; animation: yellowPulse 1s ease-in-out infinite; }
.rs-item.blue span { color: #7dd3fc; font-weight: 700; }
.rs-item.white b { color: #ffffff; font-size: 19px; animation: whitePulse 1s ease-in-out infinite; }
.rs-item.white span { color: #cbd5e1; font-weight: 700; }
.rs-item span { font-size: 10px; color: #8fb0d8; }
/* ★2026-10-06 实时空情态势统计格可点：点一下 → 地图缩放定位到该起空情的无人机与位置框 */
.rs-item.rs-jump { cursor: pointer; border-radius: 7px; transition: background .15s, box-shadow .15s; }
.rs-item.rs-jump:hover { background: rgba(34, 211, 238, .13); box-shadow: inset 0 0 0 1px rgba(34, 211, 238, .35); }
.rs-item.rs-jump:active { background: rgba(34, 211, 238, .22); }
.rs-line { margin-top: 8px; font-size: 11px; color: #9db8dd; }
.rs-line b { color: #e0f2fe; }
.rs-bars { display: flex; flex-direction: column; gap: 5px; margin: 8px 0; }
.rs-lvl { display: flex; align-items: center; gap: 6px; font-size: 11px; }
.rs-lvl-label { flex: 0 0 52px; color: #9db8dd; display: flex; align-items: center; gap: 5px; }
.rs-lvl-label .dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.rs-lvl-track { flex: 1; height: 8px; background: rgba(255, 255, 255, .07); border-radius: 4px; overflow: hidden; }
.rs-lvl-track i { display: block; height: 100%; border-radius: 4px; }
.rs-lvl b { flex: 0 0 22px; text-align: right; color: #e0f2fe; font-variant-numeric: tabular-nums; }
.rs-rows { display: flex; flex-direction: column; }
.rs-row { display: flex; justify-content: space-between; align-items: center; font-size: 11px; color: #9db8dd; padding: 3px 0; border-bottom: 1px solid rgba(56, 130, 246, .1); }
.rs-row:last-child { border-bottom: none; }
.rs-row b { color: #e0f2fe; font-variant-numeric: tabular-nums; }
.dash-map-ctrl { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dash-seg { display: flex; border: 1px solid rgba(34,211,238,.25); border-radius: 7px; overflow: hidden; }
.dash-seg button { border: none; background: transparent; color: #8fb0d8; font-size: 11px; padding: 3px 9px; cursor: pointer; }
.dash-seg button.on { background: rgba(34,211,238,.2); color: #22d3ee; }
.dash-days { display: flex; gap: 4px; }
.dash-days button { border: 1px solid rgba(34,211,238,.2); border-radius: 7px; background: transparent; color: #8fb0d8; font-size: 11px; padding: 3px 8px; cursor: pointer; }
.dash-days button.on { background: rgba(34,211,238,.2); color: #22d3ee; border-color: rgba(34,211,238,.5); }
.dash-map-legend { position: relative; z-index: 4; display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 9px; font-size: 11px; color: #9db8dd; }
.dash-map-legend .lg { width: 15px; height: 3px; border-radius: 2px; display: inline-block; margin-right: 5px; vertical-align: middle; }
.lg-bj { background: #dc2626; box-shadow: 0 0 6px rgba(220,38,38,.6); }
.lg-cd { background: #16a34a; box-shadow: 0 0 6px rgba(22,163,74,.6); }
/* ★2026-10-06 省级：地市名称（自己定位的 DOM 层，随地图缩放不飘；放大到 9 级自动隐藏） */
.hb-city-lbl-layer { position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; pointer-events: none; z-index: 60; }
.hb-city-lbl {
  position: absolute; left: 0; top: 0; white-space: nowrap; pointer-events: none; user-select: none;
  color: #ffffff; font-size: 12.5px; font-weight: 700; letter-spacing: .5px;
  text-shadow: 0 0 3px rgba(0, 0, 0, .95), 0 0 9px rgba(0, 0, 0, .8);
}
.lg-city { background: #16a34a; height: 2px; box-shadow: 0 0 5px rgba(22,163,74,.5); }
.lg-hsr { background: repeating-linear-gradient(90deg, #dc2626 0 3px, #fff 3px 6px); }
.lg-air { background: #e03131; box-shadow: 0 0 6px rgba(224,49,49,.6); }   /* 管制空域（2026-09-20 新政：天安门圆心 300km 圆） */
.lg-free { background: #0d9488; box-shadow: 0 0 6px rgba(13,148,136,.7); }  /* 适飞空域（仅圆外残余小块，加深色凸显） */

/* ===== 飞行报备（★2026-09-20 提为一级菜单；皮肤改为与平台一致的浅色，不再是深底高反差）===== */
.fr-stats { display: flex; gap: 10px; padding: 12px 14px; margin-bottom: 10px; flex-wrap: wrap; }
.fr-stat { flex: 1 1 130px; background: #f8fafc; border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; text-align: center; }
.fr-stat b { display: block; font-size: 22px; color: var(--text); line-height: 1.3; }
.fr-stat b.ok { color: #16a34a; } .fr-stat b.warn { color: #d97706; } .fr-stat b.bad { color: #dc2626; } .fr-stat b.dim { color: #64748b; }
.fr-stat span { font-size: 12px; color: var(--muted); }
.fr-bar { display: flex; gap: 8px; align-items: center; padding: 12px 14px; margin-bottom: 10px; flex-wrap: wrap; }
.fr-grow { flex: 1 1 auto; }
.fr-inp { min-width: 300px; flex: 1 1 320px; background: #fff; border: 1px solid var(--line); color: var(--text); border-radius: 8px; padding: 8px 10px; font-size: 13px; outline: none; }
.fr-inp:focus { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(37,99,235,.12); }
.fr-sel { background: #fff; border: 1px solid var(--line); color: var(--text); border-radius: 8px; padding: 8px 10px; font-size: 13px; outline: none; }
.fr-sel:focus { border-color: var(--primary); }
.fr-sub { font-size: 11px; color: var(--muted); margin-top: 2px; }
.fr-badge { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 12px; border: 1px solid transparent; }
.fr-badge.ok { background: #dcfce7; color: #15803d; border-color: #86efac; }
.fr-badge.warn { background: #fef3c7; color: #b45309; border-color: #fcd34d; }
.fr-badge.bad { background: #fee2e2; color: #b91c1c; border-color: #fca5a5; }
.fr-badge.dim { background: #f1f5f9; color: #475569; border-color: #e2e8f0; }
.fr-act { white-space: nowrap; } .fr-act .btn { margin: 0 2px 2px 0; }
.fr-pager { padding: 10px 4px 2px; color: var(--muted); font-size: 13px; display: flex; align-items: center; gap: 8px; }
.fr-form { padding: 4px 2px 2px; }
.fr-row { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.fr-f { display: flex; flex-direction: column; gap: 4px; flex: 1 1 200px; min-width: 160px; }
.fr-f span { font-size: 12px; color: #475569; }
.fr-f input, .fr-f select { background: #fff; border: 1px solid var(--line); color: var(--text); border-radius: 8px; padding: 8px 10px; font-size: 13px; outline: none; }
.fr-f input:focus, .fr-f select:focus { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(37,99,235,.12); }
.fr-block { margin-bottom: 12px; }
.fr-lb { font-size: 12px; color: #475569; margin-bottom: 6px; }
.fr-sta-bar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; }
.fr-sta-inp { min-width: 220px; flex: 0 1 320px; }
.fr-chips { display: flex; flex-wrap: wrap; gap: 6px; max-height: 168px; overflow: auto; padding: 8px; border: 1px solid var(--line); border-radius: 8px; background: #f8fafc; }
.fr-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: #334155; background: #fff; border: 1px solid var(--line); border-radius: 999px; padding: 4px 10px; cursor: pointer; }
.fr-chip:hover { border-color: #94a3b8; }
.fr-chip.on { background: #e0ecff; border-color: #2563eb; color: #1d4ed8; font-weight: 600; }
.fr-chip-p { font-style: normal; font-size: 10.5px; color: #94a3b8; }
.fr-sta-none { display: block; width: 100%; padding: 6px 2px; }
.fr-chip.on .fr-chip-p { color: #6086c8; }
.fr-draw { display: flex; align-items: center; gap: 10px; margin-top: 8px; flex-wrap: wrap; }
.fr-tip { font-size: 12.5px; color: #78350f; background: #fffbeb; border: 1px dashed #fcd34d; border-radius: 8px; padding: 8px 10px; margin: 6px 0 12px; line-height: 1.6; }
.fr-tip b { color: #b45309; }
.fr-foot { display: flex; gap: 8px; align-items: center; justify-content: flex-end; margin-top: 6px; }
.fr-coord { margin-top: 10px; }
.fr-coords { width: 100%; min-height: 96px; box-sizing: border-box; background: #fff; border: 1px solid var(--line); color: var(--text); border-radius: 8px; padding: 8px 10px; font-size: 12.5px; font-family: Consolas, "Courier New", monospace; line-height: 1.6; outline: none; resize: vertical; }
.fr-coords:focus { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(37,99,235,.12); }
.fr-draw-wrap { display: flex; flex-direction: column; gap: 8px; }
.fr-draw-tip { font-size: 12.5px; color: #475569; }
.fr-draw-tip b { color: #1d4ed8; }
.fr-draw-map { width: 100%; height: 520px; border-radius: 10px; overflow: hidden; background: #e2e8f0; }
@media (max-width: 900px) {
  .fr-inp { min-width: 0; }
  .fr-sta-inp { flex: 1 1 100%; }
  /* ★2026-09-20 修：flex-direction:column 下 .fr-f 的 flex-basis 会变成“高度”，
     每个输入框被撑到 200px+，手机端表单被拉成几屏。改为不伸缩、满宽。 */
  .fr-row { flex-direction: column; gap: 10px; }
  .fr-f { flex: 0 0 auto; width: 100%; min-width: 0; }
  .fr-bar .btn { flex: 1 1 calc(50% - 4px); }
  .fr-bar .fr-inp, .fr-bar .fr-sel { flex: 1 1 100%; }
  .fr-grow { display: none; }
  .fr-draw-map { height: 360px; }
  .fr-stat { flex: 1 1 44%; }
  .fr-coords { min-height: 120px; }
  .fr-chips { max-height: 210px; }
}
.fr-print { background: #fff; color: #000; padding: 18px 20px; border-radius: 6px; }
.fr-print h1 { text-align: center; font-size: 20px; margin: 4px 0 8px; color: #000; }
.fr-pmeta { text-align: center; font-size: 13px; margin-bottom: 10px; }
.fr-ptbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.fr-ptbl th, .fr-ptbl td { border: 1px solid #333; padding: 7px 8px; color: #000; vertical-align: middle; }
.fr-ptbl th { background: #f2f2f2; width: 116px; text-align: center; font-weight: 600; }
.fr-ptbl td { min-height: 26px; }
.dash-col { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.dash-col-wide { }
.panel { background: linear-gradient(160deg, rgba(15,32,64,.8), rgba(8,18,40,.8));
  border: 1px solid rgba(56,130,246,.22); border-radius: 12px; padding: 10px 12px;
  box-shadow: 0 8px 30px rgba(0,0,0,.35); }
.panel.grow { flex: 1; display: flex; flex-direction: column; }
.panel-hd { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.panel-hd h2 { font-size: 14px; font-weight: 700; color: #cfe3ff; letter-spacing: .5px; }
.panel-hd span { font-size: 11px; color: #5b7aa8; letter-spacing: 1px; }
/* 态势总览：时间范围下拉（实名匹配 / 各县区空情数量） */
.dash-range { position: relative; display: inline-flex; }
.dash-range-btn { font-size: 11px; color: #5b7aa8; letter-spacing: 1px; background: transparent; border: 0; cursor: pointer; padding: 2px 6px; border-radius: 4px; }
.dash-range-btn:hover { color: #38bdf8; background: rgba(56,130,246,.12); }
.dash-range-btn i { font-style: normal; font-size: 9px; margin-left: 3px; }
.dash-range-menu { position: absolute; top: 100%; right: 0; z-index: 40; min-width: 86px; background: #12233f; border: 1px solid rgba(56,130,246,.28); border-radius: 8px; box-shadow: 0 6px 18px rgba(0,0,0,.4); overflow: hidden; }
.dash-range-menu div { padding: 7px 14px; font-size: 12px; color: #cfe3ff; cursor: pointer; white-space: nowrap; }
.dash-range-menu div:hover { background: rgba(56,130,246,.16); color: #38bdf8; }
.dash-range-menu div.on { color: #38bdf8; font-weight: 700; }
.dash-range-custom { display: flex; gap: 5px; padding: 6px 8px; border-top: 1px solid rgba(56,130,246,.18); }
.dash-range-custom input { flex: 1; min-width: 58px; background: rgba(15,32,64,.6); border: 1px solid rgba(56,130,246,.25); border-radius: 5px; color: #cfe3ff; font-size: 12px; padding: 4px 6px; }
.dash-range-custom input:focus { outline: none; border-color: #38bdf8; }
.dash-range-custom button { background: rgba(56,130,246,.22); border: 0; border-radius: 5px; color: #38bdf8; font-size: 12px; padding: 4px 8px; cursor: pointer; }
.dash-range-custom button:hover { background: rgba(56,130,246,.38); }
.panel-bd { min-width: 0; }
.dash-empty { color: #5b7aa8; font-size: 12px; text-align: center; padding: 18px 0; }

.dash-weather { display: flex; flex-direction: column; gap: 8px; }
.wx-item { padding: 5px 10px; border-radius: 10px; border: 1px solid rgba(56, 130, 246, .18); position: relative; overflow: hidden; }
.wx-sunny { background: radial-gradient(circle at 82% 18%, rgba(34, 211, 238, .30), rgba(8, 24, 50, .10) 70%); }
.wx-cloudy { background: linear-gradient(135deg, rgba(59, 130, 246, .16), rgba(34, 211, 238, .05)); }
.wx-overcast { background: linear-gradient(135deg, rgba(100, 116, 139, .22), rgba(100, 116, 139, .05)); }
.wx-rain { background: linear-gradient(135deg, rgba(59, 130, 246, .22), rgba(34, 211, 238, .08)); }
.wx-rain::before { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, transparent, rgba(34, 211, 238, .28)); pointer-events: none; }
.wx-snow { background: linear-gradient(135deg, rgba(224, 242, 254, .20), rgba(148, 163, 184, .05)); }
.wx-thunder { background: linear-gradient(135deg, rgba(129, 140, 248, .22), rgba(99, 102, 241, .07)); }
.wx-fog { background: linear-gradient(135deg, rgba(148, 163, 184, .20), rgba(148, 163, 184, .05)); }
.wx-top { display: flex; align-items: baseline; justify-content: space-between; position: relative; z-index: 1; }
.wx-city { color: #8fb0d8; font-weight: 600; font-size: 12px; }
.wx-cond { color: #e0f2fe; font-size: 18px; font-weight: 700; display: flex; align-items: center; gap: 6px; }
.wx-cond .ic { font-size: 22px; line-height: 1; }
.wx-fly { flex: 0 0 auto; text-align: center; font-size: 16px; font-weight: 800; letter-spacing: 1px; white-space: nowrap; line-height: 1; transform: translateY(-0.75em); }
.wx-fly.ok { color: #4ade80; text-shadow: 0 0 10px rgba(74, 222, 128, .85), 0 0 22px rgba(74, 222, 128, .45); }
.wx-fly.good { color: #22d3ee; text-shadow: 0 0 10px rgba(34, 211, 238, .85), 0 0 22px rgba(34, 211, 238, .45); }
.wx-fly.warn { color: #fb923c; text-shadow: 0 0 10px rgba(251, 146, 60, .85), 0 0 22px rgba(251, 146, 60, .45); }
.wx-fly.no { color: #f87171; text-shadow: 0 0 10px rgba(248, 113, 113, .85), 0 0 22px rgba(248, 113, 113, .45); }
.wx-body { display: flex; align-items: center; gap: 10px; margin-top: 4px; position: relative; z-index: 1; }
.wx-left { flex: 1; display: flex; align-items: center; gap: 8px; }
.wx-right { flex: 1; display: flex; align-items: center; justify-content: flex-end; }
.wx-temp { font-size: 24px; font-weight: 800; color: #e0f2fe; font-variant-numeric: tabular-nums; line-height: 1; }
.wx-temp i { font-style: normal; font-size: 12px; color: #8fb0d8; font-weight: 600; }
.wx-meta { font-size: 11px; color: #8fb0d8; }
.wx-wind { display: flex; align-items: center; gap: 8px; }
.wx-compass { width: 30px; height: 30px; border-radius: 50%; border: 1px solid rgba(34, 211, 238, .45); background: rgba(8, 24, 50, .55); display: flex; align-items: center; justify-content: center; box-shadow: 0 0 10px rgba(34, 211, 238, .28); font-size: 17px; color: #22d3ee; flex: 0 0 auto; text-shadow: 0 0 8px rgba(34, 211, 238, .8); }
.wx-wind-txt { display: flex; flex-direction: column; line-height: 1.15; }
.wx-wind-txt b { color: #7dd3fc; font-size: 13px; font-weight: 700; }
.wx-wind-txt em { font-style: normal; color: #22d3ee; font-size: 14px; font-weight: 800; }

.dbar { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; font-size: 12px; }
.dbar-l { flex: 0 0 76px; color: #9db8dd; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: right; }
.dbar-track { flex: 1; height: 10px; background: rgba(34,211,238,.08); border-radius: 5px; overflow: hidden; }
.dbar-track i { display: block; height: 100%; border-radius: 5px;
  background: linear-gradient(90deg, #3b82f6, #22d3ee); box-shadow: 0 0 8px rgba(34,211,238,.5); }
.dbar-v { flex: 0 0 34px; color: #22d3ee; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }

.dash-donut-wrap { display: flex; align-items: center; gap: 16px; }
.donut { width: 90px; height: 90px; border-radius: 50%; flex: 0 0 auto; position: relative;
  box-shadow: 0 0 22px rgba(34,211,238,.25); }
.donut-hole { position: absolute; inset: 16px; border-radius: 50%; background: #08152a;
  display: flex; align-items: center; justify-content: center; font-size: 20px; font-weight: 800; color: #22d3ee; }
.donut-legend { display: flex; flex-direction: column; gap: 8px; font-size: 12px; color: #9db8dd; }
.donut-legend b { color: #e0f2fe; }
.donut-legend .dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; margin-right: 6px; }
.real-vscroll { flex: 1; min-width: 0; height: 90px; overflow: hidden; border-left: 1px solid rgba(56,130,246,.15); padding-left: 36px; position: relative; }
.real-vscroll-track { will-change: transform; }
.real-name { font-size: 12px; color: #cfe3ff; line-height: 24px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; }
.real-name:hover { color: #38bdf8; text-decoration: underline; }
.real-name.hot { color: #f87171; font-weight: 700; }
.real-name.wl { color: #34d399; font-weight: 600; }   /* ★2026-10-01 白名单（已报备）实名：绿色 */
.real-name.wl:hover { color: #6ee7b7; }
/* ★2026-10-01 值班中队·交接班弹窗（浅色弹窗配色：中性浅底 + 深色文字，保证对比度；胶囊＝筛选按钮） */
.sqd-card { border: 1px solid #dbe4f0; border-radius: 10px; padding: 10px 12px; margin: 10px 0; background: #fbfdff; }
.sqd-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 13px; font-weight: 700; color: #1e3a5f; margin: 0 0 8px; }
.sqd-head .cur { font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 999px; background: #e6f0ff; border: 1px solid #9fc2e8; color: #12507f; }
.sqd-head .win { font-size: 11px; font-weight: 400; color: #64748b; }
.sqd-nums { display: flex; flex-wrap: wrap; gap: 6px 8px; }
.sqd-num { display: inline-flex; align-items: center; justify-content: center; gap: 5px; min-height: 27px; padding: 3px 12px; border-radius: 999px; background: #eef2f7; border: 1px solid #cfdae8; font-size: 12.5px; font-weight: 600; line-height: 1.2; color: #274060; cursor: pointer; white-space: nowrap; }
.sqd-num b { font-size: 15px; font-weight: 800; line-height: 1; color: inherit; font-variant-numeric: tabular-nums; }
.sqd-num:hover { border-color: #9fb4cd; }
.sqd-num.on { background: #dbe7f5; border-color: #8badd6; }
.sqd-num.ok { color: #15803d; }
.sqd-num.warn { color: #c2410c; }
.sqd-num.danger { color: #b91c1c; }
.sqd-list { display: none; margin-top: 9px; max-height: 300px; overflow: auto; -webkit-overflow-scrolling: touch; }
.sqd-list.open { display: block; }
.sqd-item { padding: 6px 0; border-top: 1px solid #e9eff7; }
.sqd-item:first-child { border-top: 0; padding-top: 2px; }
.sqd-hide { display: none !important; }
.sqd-note { margin: 6px 0 2px; font-size: 11.5px; line-height: 1.5; color: #64748b; }
.sqd-line1 { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 12.5px; color: #334155; font-weight: 600; }
.sqd-line2 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 3px; font-size: 11.5px; color: #64748b; }
.sqd-no { color: #334155; font-weight: 600; }
.sqd-m { color: #475569; }
.sqd-p { color: #64748b; }
@media (max-width: 560px) {
  .sqd-card { padding: 8px 9px; }
  .sqd-head { font-size: 12.5px; }
  .sqd-num { min-height: 25px; padding: 2px 10px; font-size: 12px; }
  .sqd-num b { font-size: 14px; }
  .sqd-list { max-height: 260px; }
  .sqd-line1 { font-size: 12px; }
  .sqd-line2 { font-size: 11px; }
}
.real-scroll-empty { color: #5b7aa8; font-size: 12px; white-space: normal; }
.dot.cyan { background: #22d3ee; } .dot.gray { background: #64748b; } .dot.dim { background: #334155; }

.dash-levels { display: flex; flex-direction: column; gap: 8px; }
.lvl { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.lvl-l { flex: 0 0 52px; color: #9db8dd; display: flex; align-items: center; }
.lvl-l .dot { width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; }
.lvl-track { flex: 1; height: 8px; background: rgba(255,255,255,.06); border-radius: 4px; overflow: hidden; }
.lvl-track i { display: block; height: 100%; border-radius: 4px; }
.lvl-v { flex: 0 0 30px; text-align: right; color: #e0f2fe; font-weight: 700; font-variant-numeric: tabular-nums; }
.lvl-viol .lvl-v { color: #ff4d4f; font-weight: 800; animation: violPulse 1s ease-in-out infinite; }

.dash-vbars { display: flex; align-items: flex-end; gap: 4px; height: 130px; }
.vb { flex: 1; min-width: 0; background: linear-gradient(180deg, #22d3ee, #3b82f6); border-radius: 3px 3px 0 0;
  position: relative; transition: height .3s; box-shadow: 0 0 6px rgba(34,211,238,.35); }
.vb:hover { background: linear-gradient(180deg, #7dd3fc, #22d3ee); }
.vb-v { position: absolute; top: -16px; left: 50%; transform: translateX(-50%); font-size: 10px; color: #7dd3fc; }
.vbar-labels { display: flex; justify-content: space-between; font-size: 10px; color: #5b7aa8; margin-top: 6px; }
.dash-districts { display: flex; align-items: flex-start; gap: 5px; }
.dist-col { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; cursor: pointer; }
.dist-col:hover .dist-bar { background: linear-gradient(180deg, #5eead4, #38bdf8); }
.dist-col:hover .dist-l { color: #38bdf8; }
.dist-bar-wrap { height: 122px; width: 100%; display: flex; align-items: flex-end; justify-content: center; }
.dist-bar { width: 66%; max-width: 30px; background: linear-gradient(180deg, #2dd4bf, #0ea5e9); border-radius: 3px 3px 0 0; position: relative; box-shadow: 0 0 8px rgba(45,212,191,.22); transition: height .4s ease; }
.dist-bar:hover { background: linear-gradient(180deg, #5eead4, #38bdf8); }
.dist-v { position: absolute; top: -16px; left: 50%; transform: translateX(-50%); font-size: 10px; color: #7dd3fc; font-weight: 700; white-space: nowrap; }
.dist-l { font-size: 10px; color: #9db8dd; margin-top: 4px; white-space: nowrap; }

.heat-item { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; font-size: 12px; }
.heat-no { flex: 0 0 18px; color: #f59e0b; font-weight: 800; }
.heat-coord { flex: 0 0 106px; color: #9db8dd; font-variant-numeric: tabular-nums; }
.heat-track { flex: 1; height: 10px; background: rgba(245,158,11,.08); border-radius: 5px; overflow: hidden; }
.heat-track i { display: block; height: 100%; border-radius: 5px;
  background: linear-gradient(90deg, #f97316, #f59e0b); box-shadow: 0 0 8px rgba(245,158,11,.5); }
.heat-v { flex: 0 0 30px; color: #fbbf24; font-weight: 700; text-align: right; }

.rank-item { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid rgba(56,130,246,.1); font-size: 12px; cursor: pointer; }
.rank-item:hover .rank-sn { color: #38bdf8; }
.rank-item:last-child { border-bottom: none; }
.rank-no { flex: 0 0 22px; height: 22px; border-radius: 6px; display: flex; align-items: center; justify-content: center;
  background: rgba(56,130,246,.15); color: #8fb0d8; font-weight: 700; font-size: 11px; }
.rank-no.top { background: linear-gradient(135deg, #f59e0b, #ef4444); color: #fff; box-shadow: 0 0 10px rgba(245,158,11,.4); }
.rank-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.rank-sn { color: #cfe3ff; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rank-model { color: #5b7aa8; font-size: 11px; }
.rank-count { color: #22d3ee; font-weight: 700; font-variant-numeric: tabular-nums; }

.dash-ev-status { display: flex; gap: 8px; margin-bottom: 8px; }
.evs { flex: 1; text-align: center; padding: 6px 4px; border-radius: 8px; border: 1px solid rgba(56,130,246,.2); }
.evs b { display: block; font-size: 18px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.evs span { font-size: 10px; color: #8fb0d8; }
.evs.pending b { color: #fbbf24; } .evs.pending { background: rgba(245,158,11,.08); }
.evs.dispatched b { color: #60a5fa; } .evs.dispatched { background: rgba(59,130,246,.08); }
.evs.handled b { color: #34d399; } .evs.handled { background: rgba(52,211,153,.08); }
.dash-ev-types { display: flex; flex-wrap: wrap; gap: 6px; }
.evt { font-size: 10px; color: #9db8dd; background: rgba(56,130,246,.1); border: 1px solid rgba(56,130,246,.2); padding: 2px 8px; border-radius: 14px; }
.evt b { color: #f87171; }

.dash-feed { margin-top: 12px; }
.dash-events { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; }
.dash-events-col { display: flex; flex-direction: column; gap: 6px; }
.dash-events-col .ev-item { display: flex; align-items: center; gap: 8px; padding: 6px 10px; }
.dash-events-col .ev-type { flex: 0 0 auto; }
.dash-events-col .ev-no { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 10px; }
.dash-events-col .ev-addr { flex: 0 0 auto; font-size: 10px; }
.dash-events-col .ev-status { flex: 0 0 auto; }
.ev-item { font-size: 11px; padding: 8px 10px; border-radius: 8px; background: rgba(56,130,246,.08); border: 1px solid rgba(56,130,246,.15); }
.ev-no { color: #60a5fa; font-weight: 700; display: block; }
.ev-dist { flex: 0 0 auto; font-size: 10px; color: #34d399; background: rgba(52,211,153,.12); border: 1px solid rgba(52,211,153,.22); border-radius: 4px; padding: 0 5px; line-height: 16px; white-space: nowrap; }
.ev-type { color: #f87171; display: block; margin-top: 3px; }
.ev-addr { color: #5b7aa8; display: block; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-status { display: inline-block; margin-top: 4px; padding: 1px 7px; border-radius: 10px; font-size: 10px; }
.ev-status.pending { background: rgba(245,158,11,.15); color: #fbbf24; }
.ev-status.dispatched { background: rgba(59,130,246,.15); color: #60a5fa; }
.ev-status.handled { background: rgba(52,211,153,.15); color: #34d399; }
button.ev-status { border: none; cursor: pointer; font-family: inherit; }
button.ev-status:hover { opacity: .85; }

.dash-foot { flex: 0 0 auto; margin-top: 8px; display: flex; flex-wrap: wrap; gap: 8px 20px; justify-content: center;
  padding: 8px 14px; border-radius: 10px; border: 1px solid rgba(56,130,246,.22);
  background: linear-gradient(160deg, rgba(15,32,64,.8), rgba(8,18,40,.8)); }
.dash-foot span { font-size: 12px; color: #8fb0d8; }
.dash-foot b { color: #22d3ee; font-variant-numeric: tabular-nums; }

.dash-loading { position: fixed; inset: 0; z-index: 1999; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px; color: #5b7aa8; background: #050b1e; }
.dash-loading p { font-size: 13px; }
.spinner { width: 46px; height: 46px; border-radius: 50%; border: 3px solid rgba(34,211,238,.15); border-top-color: #22d3ee; animation: dashspin 1s linear infinite; }
@keyframes dashspin { to { transform: rotate(360deg); } }

@media (max-width: 900px) {
  .dash { display: block; overflow-y: auto; overflow-x: hidden; padding: 0 10px 18px; }
  .dash-head {
    position: sticky; top: 0; z-index: 40;
    margin: 0 -10px 8px; padding: 8px 10px;
    background: rgba(5, 11, 30, .95); backdrop-filter: blur(6px);
    border-bottom: 1px solid rgba(34, 211, 238, .15);
    gap: 8px;
  }
  .dash-title { gap: 10px; }
  .dash-title .dash-logo { width: 34px; height: 34px; font-size: 20px; border-radius: 10px; }
  .dash-title h1 { font-size: 15px; letter-spacing: .5px; }
  .dash-title p { display: none; }
  .dash-head-right { gap: 6px; }
  .dash-stat-chip { font-size: 10px; padding: 3px 7px; }
  .dash-clock { font-size: 12px; }
  .dash-exit { font-size: 11px; padding: 4px 9px; margin-left: 0; }
  .dash-kpis { grid-template-columns: repeat(2, 1fr); gap: 6px; margin-bottom: 8px; }
  .kpi { padding: 6px 10px 7px 12px; }
  .kpi b.num { font-size: 18px; }
  .dash-main { grid-template-columns: 1fr; gap: 8px; }
  .dash-col-side { overflow: visible; gap: 8px; }
  .dash-col-center { order: -1; }
  .dash-map-panel { flex: none; }
  .dash-map-panel .panel-bd { flex: none; }
  .dash-map { flex: none; height: 40vh; min-height: 220px; max-height: 340px; }
  .dash-map-ctrl { gap: 5px; }
  .dash-vbars { height: 110px; }
  .dash-foot { gap: 6px 14px; padding: 8px 10px; font-size: 11px; }
}
@media (max-width: 560px) {
  .dash { padding: 0 8px 14px; }
  .dash-head { margin: 0 -8px 8px; }
  .dash-title h1 { font-size: 14px; }
  .dash-clock { display: none; }
  .dash-stat-chip { display: none; }
  /* ★2026-10-02 手机单屏也要看得到「今日值班 X中队」（可点开交接班弹窗）——其余芯片仍隐藏 */
  #dashDutyChip { display: inline-flex; align-items: center; gap: 4px; }
  .rs-item b { font-size: 15px; }
  .dash-map { height: 36vh; min-height: 200px; }
}

/* ===== AI 对话助手 ===== */
.mining-body.chat { overflow: hidden; padding: 0; display: flex; flex-direction: column; }
.chat-page { flex: 1; min-height: 0; display: flex; }
.chat-side { width: 250px; flex: 0 0 auto; display: flex; flex-direction: column; background: var(--card); border-right: 1px solid var(--line); }
.chat-side-hd { display: flex; align-items: center; justify-content: space-between; padding: 10px 12px; border-bottom: 1px solid var(--line); font-size: 13px; font-weight: 700; color: var(--text); }
.chat-side-btns { display: flex; gap: 6px; align-items: center; }
.chat-list { flex: 1; min-height: 0; overflow-y: auto; padding: 8px; }
.chat-item { position: relative; display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-radius: 10px; cursor: pointer; margin-bottom: 6px; border: 1px solid var(--line); background: #fff; transition: all .15s ease; }
.ci-chk { flex: 0 0 auto; display: inline-flex; align-items: center; cursor: pointer; }
.ci-chk input { cursor: pointer; }
.ci-body { flex: 1; min-width: 0; }
.chat-item:hover { border-color: var(--primary); background: var(--bg); transform: translateX(2px); box-shadow: 0 2px 8px rgba(37,99,235,.08); }
.chat-item.on { background: #eff6ff; border-color: var(--primary); box-shadow: inset 3px 0 0 var(--primary); }
.ci-title { font-size: 13px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-right: 20px; }
.ci-gen { display: inline-block; font-size: 10px; color: var(--primary); background: #dbeafe; border-radius: 9px; padding: 0 6px; margin-left: 6px; vertical-align: 1px; animation: ciblink 1.2s ease-in-out infinite; }
.ci-gen-big { color: var(--primary); font-weight: 600; }
@keyframes ciblink { 0%,100% { opacity: 1; } 50% { opacity: .4; } }
.ci-time { font-size: 11px; color: #94a3b8; margin-top: 2px; }
.ci-del { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); border: none; background: transparent; color: #94a3b8; cursor: pointer; font-size: 13px; padding: 2px 4px; border-radius: 4px; }
.ci-del:hover { color: #dc2626; background: #fee2e2; }
.chat-main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; background: var(--bg); }
.chat-hd { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px; background: var(--card); border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.chat-title { font-size: 15px; font-weight: 700; color: var(--text); }
.chat-actions { display: flex; gap: 6px; }
.chat-side-toggle { display: none; }
.chat-body { flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; padding: 14px; }
.msg { display: flex; gap: 10px; margin-bottom: 16px; }
.msg.user { flex-direction: row-reverse; }
.msg-av { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 17px; background: #eff6ff; border: 1px solid var(--line); }
.msg.user .msg-av { background: var(--primary); color: #fff; border-color: var(--primary); }
.msg-bd { max-width: 82%; min-width: 0; }
.msg.user .msg-bd { text-align: right; }
.msg-name { font-size: 11px; color: #94a3b8; margin-bottom: 4px; }
.msg.user .msg-name { text-align: right; }
.msg-content.md { display: inline-block; text-align: left; background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 10px 14px; font-size: 13px; line-height: 1.65; color: var(--text); max-width: 100%; overflow-wrap: break-word; }
.msg.user .msg-content.md { background: var(--primary); color: #fff; border-color: var(--primary); }
.msg-content.md p { margin: 5px 0; }
.msg-content.md h1 { font-size: 17px; margin: 10px 0 6px; }
.msg-content.md h2 { font-size: 15px; margin: 10px 0 6px; }
.msg-content.md h3 { font-size: 14px; margin: 8px 0 5px; }
.msg-content.md .md-li { margin: 3px 0 3px 4px; }
.msg-content.md table.md-table { border-collapse: collapse; width: 100%; margin: 8px 0; font-size: 12px; }
.msg-content.md table.md-table td { border: 1px solid var(--line); padding: 5px 8px; }
.msg.user .msg-content.md table.md-table td { border-color: rgba(255,255,255,.3); }
.msg-content.md code { background: var(--bg); padding: 1px 5px; border-radius: 4px; font-size: 12px; }
.msg.user .msg-content.md code { background: rgba(255,255,255,.2); }
.chat-quick { flex: 0 0 auto; display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 14px; background: var(--card); border-top: 1px solid var(--line); }
.chat-quick .chip { display: inline-flex; align-items: center; gap: 5px; border: 1px solid var(--line); background: #fff; color: var(--text); border-radius: 16px; padding: 5px 12px; font-size: 12px; cursor: pointer; transition: all .15s ease; }
.chat-quick .chip:hover { border-color: var(--primary); color: var(--primary); background: #eff6ff; transform: translateY(-1px); box-shadow: 0 2px 6px rgba(37,99,235,.12); }
.chip-ic { font-size: 13px; }
.chat-input { flex: 0 0 auto; display: flex; align-items: stretch; gap: 10px; padding: 12px 16px; background: var(--card); border-top: 1px solid var(--line); }
.chat-input textarea { flex: 1; resize: none; border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; font-size: 14px; font-family: inherit; line-height: 1.6; min-height: 48px; max-height: 220px; outline: none; background: #fff; transition: border-color .18s ease, box-shadow .18s ease; }
.chat-input textarea:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(29, 78, 216, .12); }
.chat-send-col { display: flex; flex-direction: column; gap: 8px; }
.chat-send-col .btn { flex: 1; min-height: 44px; padding: 0 16px; font-size: 13px; border-radius: 9px; font-weight: 600; white-space: nowrap; transition: transform .12s ease, box-shadow .12s ease, background .15s ease; }
.chat-send-col .btn:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0, 0, 0, .10); }
@media (max-width: 900px) {
  .chat-page { flex-direction: column; }
  .chat-side-toggle { display: inline-flex; }
  .chat-side { display: none; width: 100%; flex: 0 0 auto; max-height: 45vh; border-right: none; border-bottom: 1px solid var(--line); }
  .chat-page.side-open .chat-side { display: flex; }
  .chat-side-hd { padding: 8px 12px; }
  .chat-list { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px; max-height: 30vh; }
  .chat-item { width: calc(50% - 4px); margin-bottom: 0; }
  .chat-hd { padding: 8px 10px; gap: 6px; }
  .chat-title { font-size: 13px; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .chat-actions { gap: 4px; }
  .chat-body { padding: 10px; }
  .msg { gap: 8px; margin-bottom: 12px; }
  .msg-av { width: 28px; height: 28px; font-size: 14px; }
  .msg-bd { max-width: 88%; }
  .chat-quick { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; padding: 8px 10px; }
  .chat-quick::-webkit-scrollbar { display: none; }
  .chat-quick .chip { flex: 0 0 auto; white-space: nowrap; }
  .chat-input { padding: 10px; flex-wrap: wrap; }
  .chat-input textarea { flex: 1 1 100%; min-height: 40px; }
  .chat-send-col { flex: 1 1 100%; flex-direction: row; }
  .chat-send-col .btn { flex: 1; height: 40px; padding: 0 10px; font-size: 12px; }
}

/* ===== AI 助手手机端优化（仅 ≤560px 小屏生效，不影响 PC/平板样式） ===== */
@media (max-width: 560px) {
  /* 高度适配：优先用 dvh，避免手机浏览器地址栏/工具条遮挡底部输入区 */
  .mining-page { height: calc(100dvh - 66px); }
  /* 头部：标题独占一行，操作按钮换行紧凑、触控友好 */
  .chat-hd { padding: 8px; gap: 6px; }
  .chat-title { flex: 1 1 100%; width: 100%; font-size: 14px; }
  .chat-actions { flex: 1 1 100%; width: 100%; flex-wrap: wrap; gap: 6px; }
  .chat-actions .btn { flex: 1 1 auto; min-height: 38px; padding: 0 10px; font-size: 12px; }
  /* 消息气泡：给内容更多宽度、文字更清晰 */
  .chat-body { padding: 8px 10px; }
  .msg { gap: 7px; margin-bottom: 12px; }
  .msg-av { width: 26px; height: 26px; font-size: 13px; }
  .msg-bd { max-width: 90%; }
  .msg-content.md { font-size: 13.5px; padding: 10px 12px; line-height: 1.7; }
  .msg-name { font-size: 10.5px; }
  /* 输入区：16px 字号防 iOS 聚焦缩放，发送按钮大触控 */
  .chat-input { padding: 8px; gap: 8px; }
  .chat-input textarea { font-size: 16px; min-height: 40px; max-height: 160px; padding: 10px 12px; }
  .chat-send-col { gap: 6px; }
  .chat-send-col .btn { height: 46px; font-size: 13.5px; border-radius: 10px; }
  /* 会话列表：单列更易点按 */
  .chat-side { max-height: 65vh; }
  .chat-list { max-height: 40vh; }
  .chat-item { width: 100%; padding: 10px; }
}

/*隐藏高德地图 logo 与版权文字（手机端悬浮遮挡操作）*/
.amap-logo, .amap-copyright { display: none !important; }

/* ===== 数据矩阵（立体光影·深色科技） ===== */
.mining-body.ckmatrix {
  background:
    radial-gradient(1100px 460px at 10% -12%, rgba(34,211,238,.16), transparent 62%),
    radial-gradient(980px 460px at 92% -4%, rgba(59,130,246,.16), transparent 62%),
    radial-gradient(900px 700px at 50% 120%, rgba(139,92,246,.10), transparent 70%),
    linear-gradient(rgba(34,211,238,.032) 1px, transparent 1px),
    linear-gradient(90deg, rgba(34,211,238,.032) 1px, transparent 1px),
    #04091a;
  background-size: auto, auto, auto, 44px 44px, 44px 44px, auto;
  color: #dbeafe;
}
/* 顶栏 */
.ck-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; padding: 10px 14px; border-radius: 14px;
  background: linear-gradient(90deg, rgba(12,28,58,.85), rgba(8,18,40,.55));
  border: 1px solid rgba(56,130,246,.28);
  box-shadow: 0 10px 30px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.07); }
.ck-title { display: flex; align-items: center; gap: 12px; }
.ck-logo { width: 42px; height: 42px; border-radius: 13px; display: flex; align-items: center; justify-content: center; font-size: 21px;
  background: linear-gradient(140deg, rgba(34,211,238,.22), rgba(59,130,246,.16));
  border: 1px solid rgba(34,211,238,.45);
  box-shadow: 0 0 24px rgba(34,211,238,.35), inset 0 1px 0 rgba(255,255,255,.18); }
.ck-title h1 { font-size: 21px; font-weight: 800; letter-spacing: 4px; margin: 0; color: #eaf6ff;
  text-shadow: 0 0 12px rgba(34,211,238,.75), 0 0 32px rgba(34,211,238,.35); }
.ck-title p { font-size: 9px; letter-spacing: 3px; color: #5b7aa8; margin: 3px 0 0; }
.ck-actions { display: flex; gap: 8px; align-items: center; }
.ck-live { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; color: #7dd3fc; letter-spacing: .5px;
  border: 1px solid rgba(34,211,238,.28); background: rgba(34,211,238,.08); border-radius: 8px; padding: 4px 10px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07); }
.ck-live i { width: 7px; height: 7px; border-radius: 50%; background: #34d399; box-shadow: 0 0 8px #34d399; animation: ckPulse 1.8s ease-in-out infinite; }
@keyframes ckPulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .45; transform: scale(.8); } }
.ck-actions .btn.ghost { background: rgba(34,211,238,.08); border-color: rgba(34,211,238,.32); color: #a8d8f0;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06); }
.ck-actions .btn.ghost:hover { background: rgba(34,211,238,.2); color: #fff; box-shadow: 0 0 16px rgba(34,211,238,.35); }

/* 网格 */
.ck-grid { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 12px; }
.ck-loading { grid-column: 1/-1; text-align: center; padding: 46px; color: #5b7aa8; letter-spacing: 2px; }

/* 卡片：立体光影 */
.ck-card {
  position: relative; overflow: hidden; min-height: 196px;
  display: flex; flex-direction: column; cursor: pointer; border-radius: 14px; padding: 12px 13px 10px;
  background:
    radial-gradient(120% 90% at 0% 0%, rgba(34,211,238,.12), transparent 58%),
    radial-gradient(120% 90% at 100% 100%, rgba(59,130,246,.10), transparent 60%),
    linear-gradient(158deg, rgba(24,48,92,.92), rgba(7,15,34,.97));
  border: 1px solid rgba(56,130,246,.3);
  box-shadow:
    0 14px 36px rgba(0,0,0,.55),
    0 2px 0 rgba(255,255,255,.05) inset,
    0 -30px 60px rgba(0,0,0,.35) inset,
    0 0 40px rgba(34,211,238,.05) inset;
  transition: transform .22s cubic-bezier(.2,.7,.3,1), box-shadow .22s, border-color .22s;
}
/* 顶部光带 */
.ck-card::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 2px; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(34,211,238,.95) 30%, rgba(59,130,246,.7) 60%, transparent);
  box-shadow: 0 0 12px rgba(34,211,238,.6);
}
/* 斜向扫光 */
.ck-card::after {
  content: ''; position: absolute; top: -60%; left: -45%; width: 34%; height: 220%; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(190,232,255,.10), transparent);
  transform: rotate(16deg); animation: ckSweep 7s ease-in-out infinite;
}
@keyframes ckSweep { 0%, 62% { left: -45%; } 100% { left: 135%; } }
.ck-card:hover {
  transform: translateY(-6px);
  border-color: rgba(34,211,238,.75);
  box-shadow:
    0 26px 60px rgba(0,0,0,.65),
    0 0 38px rgba(34,211,238,.32),
    0 2px 0 rgba(255,255,255,.12) inset,
    0 -30px 60px rgba(0,0,0,.35) inset;
}
/* 四角装饰 */
.ck-c { position: absolute; width: 12px; height: 12px; border: 2px solid rgba(34,211,238,.5); pointer-events: none; transition: border-color .22s; }
.ck-c.tl { left: 5px; top: 5px; border-right: 0; border-bottom: 0; border-radius: 5px 0 0 0; }
.ck-c.tr { right: 5px; top: 5px; border-left: 0; border-bottom: 0; border-radius: 0 5px 0 0; }
.ck-c.bl { left: 5px; bottom: 5px; border-right: 0; border-top: 0; border-radius: 0 0 0 5px; }
.ck-c.br { right: 5px; bottom: 5px; border-left: 0; border-top: 0; border-radius: 0 0 5px 0; }
.ck-card:hover .ck-c { border-color: rgba(34,211,238,.95); }

/* 卡头 */
.ck-card .panel-hd { border-bottom: 1px solid rgba(56,130,246,.16); padding-bottom: 6px; margin-bottom: 8px; }
.ck-card .panel-hd h2 { font-size: 12.5px; letter-spacing: .6px; }
.ck-hd { display: flex; align-items: center; gap: 6px; }
.ck-hd b { font-size: 8px; font-weight: 800; letter-spacing: 1.2px; color: rgba(34,211,238,.75);
  border: 1px solid rgba(34,211,238,.3); border-radius: 4px; padding: 1px 4px; background: rgba(34,211,238,.07); }
.ck-hd { font-size: 13px; }
.ck-bd { flex: 1; min-height: 0; display: flex; flex-direction: column; justify-content: space-between; gap: 8px; }

/* 大数字 */
.ck-num { font-size: 28px; font-weight: 800; color: #eaf6ff; line-height: 1.05; letter-spacing: -.5px; font-variant-numeric: tabular-nums;
  text-shadow: 0 0 14px rgba(34,211,238,.6), 0 2px 6px rgba(0,0,0,.6); }
.ck-num em { font-style: normal; font-size: 12px; color: #22d3ee; font-weight: 700; margin-left: 3px; text-shadow: 0 0 10px rgba(34,211,238,.6); }
.ck-cap { font-size: 10.5px; color: #8fb0d8; line-height: 1.5; }
.ck-cap b { color: #cfe3ff; }
.ck-up { color: #f87171; font-weight: 700; } .ck-dn { color: #34d399; font-weight: 700; }

/* 火花线 / 曲线 */
.ck-spark { width: 100%; height: 34px; display: block; }
.ck-line-wrap { display: flex; flex-direction: column; }
.ck-line { width: 100%; height: 58px; display: block; }
.ck-axis { display: flex; justify-content: space-between; font-size: 9px; color: #5b7aa8; margin-top: 2px; }

/* 饼图 */
.ck-pie-wrap { display: flex; align-items: center; gap: 11px; }
.ck-pie { width: 98px; height: 98px; border-radius: 50%; flex: none; position: relative;
  box-shadow: 0 0 22px rgba(34,211,238,.3), inset 0 0 18px rgba(0,0,0,.5); }
.ck-pie-hole { position: absolute; inset: 18px; border-radius: 50%; background: #071229;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  box-shadow: inset 0 0 14px rgba(0,0,0,.7); }
.ck-pie-hole b { font-size: 19px; font-weight: 800; color: #22d3ee; line-height: 1; text-shadow: 0 0 10px rgba(34,211,238,.7); }
.ck-pie-hole i { font-style: normal; font-size: 9px; color: #5b7aa8; margin-top: 1px; }
.ck-legend { display: flex; flex-direction: column; gap: 6px; font-size: 11px; color: #9db8dd; min-width: 0; flex: 1; }
.ck-legend > div { display: flex; align-items: center; gap: 5px; white-space: nowrap; }
.ck-legend .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; box-shadow: 0 0 8px currentColor; }
.ck-legend b { color: #e0f2fe; margin-left: auto; font-variant-numeric: tabular-nums; }

/* 热力格条 */
.ck-heat { display: flex; gap: 2px; height: 16px; }
.ck-heat i { flex: 1; min-width: 0; border-radius: 3px; transition: filter .15s; }
.ck-heat i:hover { filter: brightness(1.6); }
/* 今/昨 对比双条 */
.ck-dual { display: flex; flex-direction: column; gap: 6px; }
.ck-dual-row { display: flex; align-items: center; gap: 7px; font-size: 10.5px; }
.ck-dual-row .k { flex: 0 0 30px; color: #9db8dd; }
.ck-dual-row .bars { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.ck-dual-row .bars i { display: block; height: 5px; border-radius: 3px; }
.ck-dual-row .bars .now { background: linear-gradient(90deg,#22d3ee,#3b82f6); box-shadow: 0 0 7px rgba(34,211,238,.55); }
.ck-dual-row .bars .prev { background: rgba(148,163,184,.45); }
.ck-dual-row .v { flex: 0 0 62px; text-align: right; font-variant-numeric: tabular-nums; }
.ck-dual-row .v b { color: #eaf6ff; }
.ck-dual-row .v em { font-style: normal; color: #64748b; font-size: 9.5px; }
/* 3 列 KPI 格 */
.ck-grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.ck-grid3 > div { background: linear-gradient(150deg, rgba(56,130,246,.13), rgba(12,26,52,.5)); border: 1px solid rgba(56,130,246,.2);
  border-radius: 9px; padding: 8px 7px; text-align: center; box-shadow: inset 0 1px 0 rgba(255,255,255,.07); }
.ck-grid3 b { display: block; font-size: 14px; font-weight: 800; color: #eaf6ff; font-variant-numeric: tabular-nums; line-height: 1.25; }
.ck-grid3 span { font-size: 9.5px; color: #8fb0d8; }
.ck-hbar .v em.pct { font-style: normal; color: #22d3ee; font-size: 9px; margin-left: 3px; }

/* 环形仪表 */
.ck-ring-wrap { display: flex; align-items: center; gap: 12px; }
.ck-ring { width: 96px; height: 96px; border-radius: 50%; flex: none; position: relative;
  box-shadow: 0 0 22px rgba(34,211,238,.28), inset 0 0 16px rgba(0,0,0,.5); }
.ck-ring-hole { position: absolute; inset: 13px; border-radius: 50%; background: #071229; display: flex; flex-direction: column; align-items: center; justify-content: center; box-shadow: inset 0 0 12px rgba(0,0,0,.7); }
.ck-ring-hole b { font-size: 18px; font-weight: 800; color: #eaf6ff; line-height: 1; }
.ck-ring-hole i { font-style: normal; font-size: 9px; color: #5b7aa8; margin-top: 1px; }

/* 柱状 */
.ck-bars { display: flex; align-items: flex-end; gap: 3px; margin: 2px 0 0; }
.ck-bars i { flex: 1; min-width: 0; border-radius: 2px 2px 0 0; position: relative;
  background: linear-gradient(180deg,#22d3ee,#3b82f6); box-shadow: 0 0 7px rgba(34,211,238,.45), inset 0 1px 0 rgba(255,255,255,.25); }
.ck-bars i:hover { filter: brightness(1.35); }
.ck-bars i u { position: absolute; top: 2px; left: 50%; transform: translateX(-50%); font-size: 8px; color: #eaf6ff; text-decoration: none; text-shadow: 0 1px 3px rgba(0,0,0,.9); }

/* 横向条 */
.ck-hbars { display: flex; flex-direction: column; gap: 6px; }
.ck-hbar { display: flex; align-items: center; gap: 7px; font-size: 11px; }
.ck-hbar .lbl { flex: 0 0 58px; color: #9db8dd; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ck-hbar .trk { flex: 1; height: 7px; background: rgba(255,255,255,.06); border-radius: 4px; overflow: hidden; box-shadow: inset 0 1px 2px rgba(0,0,0,.5); }
.ck-hbar .trk i { display: block; height: 100%; border-radius: 4px; background: linear-gradient(90deg,#22d3ee,#3b82f6);
  box-shadow: 0 0 8px rgba(34,211,238,.5), inset 0 1px 0 rgba(255,255,255,.3); }
.ck-hbar .v { flex: 0 0 46px; text-align: right; color: #e0f2fe; font-weight: 700; font-variant-numeric: tabular-nums; }
.ck-hbars.ck-mini { flex: 1; gap: 7px; }
.ck-hbars.ck-mini .ck-hbar .lbl { flex: 0 0 40px; font-size: 10px; }

/* 排行 */
.ck-ranks { display: flex; flex-direction: column; gap: 1px; }
.ck-ranks .rank-item { padding: 2.5px 0; font-size: 11px; border-bottom: 1px solid rgba(56,130,246,.08); }
.ck-ranks .rank-item:last-child { border-bottom: 0; }
.ck-ranks .rank-no { flex: 0 0 18px; height: 18px; font-size: 10px; border-radius: 5px;
  background: rgba(56,130,246,.14); color: #8fb0d8; box-shadow: inset 0 1px 0 rgba(255,255,255,.06); }
.ck-ranks .rank-no.top { background: linear-gradient(135deg,#f59e0b,#ef4444); color: #fff; box-shadow: 0 0 10px rgba(245,158,11,.5); }
.ck-ranks .rank-no.hi { background: rgba(34,211,238,.2); color: #7dd3fc; }
.ck-ranks .rank-model { font-size: 9.5px; }
.ck-rank-bar { flex: 0 0 44px; height: 5px; background: rgba(255,255,255,.06); border-radius: 3px; overflow: hidden; margin-right: 2px; }
.ck-rank-bar i { display: block; height: 100%; border-radius: 3px; background: linear-gradient(90deg,#38bdf8,#22d3ee); box-shadow: 0 0 7px rgba(34,211,238,.5); }
.rank-bar { flex: 0 0 44px; height: 5px; background: rgba(255,255,255,.06); border-radius: 3px; overflow: hidden; margin-right: 2px; }
.rank-bar i { display: block; height: 100%; border-radius: 3px; background: linear-gradient(90deg,#38bdf8,#22d3ee); box-shadow: 0 0 7px rgba(34,211,238,.5); }

/* KPI 格 */
.ck-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.ck-grid2 > div { background: linear-gradient(150deg, rgba(56,130,246,.13), rgba(12,26,52,.5)); border: 1px solid rgba(56,130,246,.2);
  border-radius: 9px; padding: 9px 10px; box-shadow: inset 0 1px 0 rgba(255,255,255,.07); }
.ck-grid2 b { display: block; font-size: 15px; font-weight: 800; color: #eaf6ff; font-variant-numeric: tabular-nums; line-height: 1.25; }
.ck-grid2 span { font-size: 9.5px; color: #8fb0d8; }
.ck-kv3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; text-align: center; }
.ck-kv3 > div { background: rgba(56,130,246,.09); border: 1px solid rgba(56,130,246,.16); border-radius: 8px; padding: 8px 2px; box-shadow: inset 0 1px 0 rgba(255,255,255,.06); }
.ck-kv3 b { display: block; font-size: 13.5px; font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1.25; }
.ck-kv3 span { font-size: 9px; color: #8fb0d8; }

/* 堆叠条 */
.ck-stack { display: flex; height: 8px; border-radius: 5px; overflow: hidden; background: rgba(255,255,255,.06); box-shadow: inset 0 1px 2px rgba(0,0,0,.5); }
.ck-stack i { display: block; height: 100%; box-shadow: inset 0 1px 0 rgba(255,255,255,.35); }

/* 徽标 */
.ck-flag { display: flex; gap: 7px; }
.ck-flag .f { flex: 1; text-align: center; padding: 10px 4px; border-radius: 9px; border: 1px solid rgba(56,130,246,.24);
  background: linear-gradient(160deg, rgba(56,130,246,.14), rgba(10,22,46,.5)); box-shadow: inset 0 1px 0 rgba(255,255,255,.08); }
.ck-flag .f b { display: block; font-size: 22px; font-weight: 800; line-height: 1.15; font-variant-numeric: tabular-nums; }
.ck-flag .f span { font-size: 9.5px; color: #8fb0d8; }
.ck-flag .f.bj b { color: #f87171; text-shadow: 0 0 10px rgba(248,113,113,.6); } .ck-flag .f.bj { background: linear-gradient(160deg, rgba(248,113,113,.16), rgba(40,12,18,.4)); border-color: rgba(248,113,113,.35); }
.ck-flag .f.hsr b { color: #fbbf24; text-shadow: 0 0 10px rgba(251,191,36,.6); } .ck-flag .f.hsr { background: linear-gradient(160deg, rgba(245,158,11,.16), rgba(40,26,8,.4)); border-color: rgba(245,158,11,.35); }
.ck-flag .f.warn b { color: #fb923c; text-shadow: 0 0 10px rgba(251,146,60,.6); } .ck-flag .f.warn { background: linear-gradient(160deg, rgba(251,146,60,.14), rgba(40,22,10,.4)); border-color: rgba(251,146,60,.32); }
.ck-flag .f.ok b { color: #34d399; text-shadow: 0 0 10px rgba(52,211,153,.6); } .ck-flag .f.ok { background: linear-gradient(160deg, rgba(52,211,153,.16), rgba(8,36,28,.4)); border-color: rgba(52,211,153,.35); }

/* 弹窗明细（深色） */
.ck-detail { background: linear-gradient(160deg, #0d1b36, #081226); border: 1px solid rgba(56,130,246,.28); border-radius: 12px; padding: 12px 14px; max-height: 62vh; overflow: auto; color: #cfe3ff;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06), 0 10px 30px rgba(0,0,0,.5); }
.ck-detail-big { font-size: 22px; font-weight: 800; margin-bottom: 8px; color: #22d3ee; text-shadow: 0 0 12px rgba(34,211,238,.6); }
.ck-tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.ck-tbl th { text-align: left; color: #8fb0d8; font-weight: 600; font-size: 12px; padding: 7px 9px; border-bottom: 1px solid rgba(56,130,246,.3); position: sticky; top: 0; background: #0d1b36; }
.ck-tbl td { padding: 7px 9px; border-bottom: 1px solid rgba(56,130,246,.12); }
.ck-tbl tr:hover td { background: rgba(56,130,246,.1); }
.ck-detail .sub { color: #8fb0d8; font-size: 12px; }
@media (max-width: 1180px) { .ck-grid { grid-template-columns: repeat(3, minmax(0,1fr)); } }
@media (max-width: 880px) { .ck-grid { grid-template-columns: repeat(2, minmax(0,1fr)); } }

/* 数据矩阵：区间切换 */
.ck-range { display: inline-flex; border: 1px solid rgba(34,211,238,.3); border-radius: 9px; overflow: hidden; background: rgba(34,211,238,.06); }
.ck-range button { border: 0; background: transparent; color: #8fb0d8; font-size: 11px; padding: 5px 11px; cursor: pointer; transition: all .15s; }
.ck-range button:hover { color: #eaf6ff; background: rgba(34,211,238,.12); }
.ck-range button.on { background: linear-gradient(140deg, rgba(34,211,238,.3), rgba(59,130,246,.28)); color: #fff; font-weight: 700; box-shadow: inset 0 1px 0 rgba(255,255,255,.15); }
.ck-ranks .rank-count { min-width: 34px; }

/* ===== 数据矩阵：全屏大屏模式 ===== */
.mining-body.ckfull {
  position: fixed; inset: 0; z-index: 2000; padding: 8px 12px 6px;
  display: flex; flex-direction: column; overflow: hidden;
  animation: ckIn .45s ease;
}
@keyframes ckIn { from { opacity: .55; transform: scale(.998); } to { opacity: 1; transform: none; } }
.mining-body.ckfull::after {
  content: ''; position: fixed; left: 0; right: 0; top: -180px; height: 180px; pointer-events: none; z-index: 5;
  background: linear-gradient(180deg, transparent, rgba(34,211,238,.10), transparent);
  animation: ckScan 8s linear infinite;
}
@keyframes ckScan { 0% { transform: translateY(0); } 100% { transform: translateY(calc(100vh + 180px)); } }
.mining-body.ckfull .ck-head { flex: 0 0 auto; margin-bottom: 8px; padding: 8px 12px; }
.mining-body.ckfull .ck-title h1 { font-size: 19px; }
.mining-body.ckfull .ck-grid {
  flex: 1 1 auto; min-height: 0;
  grid-template-columns: repeat(4, minmax(0,1fr));
  grid-template-rows: repeat(4, minmax(0,1fr));
}
.mining-body.ckfull .ck-card { min-height: 0; height: auto; padding: 8px 11px 6px; overflow: hidden; }
.mining-body.ckfull .ck-card .panel-hd { padding-bottom: 4px; margin-bottom: 5px; }
.mining-body.ckfull .ck-card .panel-hd h2 { font-size: 12px; }
.mining-body.ckfull .ck-bd { justify-content: space-between; gap: 4px; overflow: hidden; }
.mining-body.ckfull .ck-num { font-size: 24px; }
.mining-body.ckfull .ck-pie { width: 76px; height: 76px; }
.mining-body.ckfull .ck-pie-hole { inset: 14px; }
.mining-body.ckfull .ck-pie-hole b { font-size: 15px; }
.mining-body.ckfull .ck-ring { width: 74px; height: 74px; }
.mining-body.ckfull .ck-ring-hole { inset: 10px; }
.mining-body.ckfull .ck-ring-hole b { font-size: 15px; }

.mining-body.ckfull .ck-heat { height: 12px; }
.mining-body.ckfull .ck-line { height: 40px; }
.mining-body.ckfull .ck-spark { height: 22px; }
.mining-body.ckfull .ck-legend { gap: 3px; font-size: 10px; }
.mining-body.ckfull .ck-hbars { gap: 4px; }
.mining-body.ckfull .ck-hbar { font-size: 10px; }
.mining-body.ckfull .ck-ranks .rank-item { padding: 1px 0; font-size: 10px; }
.mining-body.ckfull .ck-ranks .rank-no { flex: 0 0 16px; height: 16px; font-size: 9px; }
.mining-body.ckfull .ck-grid2 { gap: 4px; }
.mining-body.ckfull .ck-grid2 > div { padding: 6px 7px; }
.mining-body.ckfull .ck-grid2 b { font-size: 13px; }
.mining-body.ckfull .ck-grid3 { gap: 4px; }
.mining-body.ckfull .ck-grid3 > div { padding: 5px 4px; }
.mining-body.ckfull .ck-grid3 b { font-size: 12.5px; }
.mining-body.ckfull .ck-kv3 { gap: 4px; }
.mining-body.ckfull .ck-kv3 > div { padding: 5px 2px; }
.mining-body.ckfull .ck-kv3 b { font-size: 12px; }
.mining-body.ckfull .ck-cap { font-size: 10px; margin-top: 0; }
.mining-body.ckfull .ck-flag .f { padding: 7px 3px; }
.mining-body.ckfull .ck-flag .f b { font-size: 18px; }
.mining-body.ckfull .ck-axis { font-size: 8px; }
.mining-body.ckfull .panel-hd span { font-size: 12px; }
/* 实时空情胶囊（逻辑同顶栏徒标） */
.ck-chips .chip.live, .ck-actions .chip.live { border-color: rgba(248,113,113,.45); background: rgba(248,113,113,.12); }
.ck-chips .chip.live b, .ck-actions .chip.live b { color: #ff4d4f; font-weight: 800; }
.ck-chips .chip.live.blink b, .ck-actions .chip.live.blink b { animation: ckAirBlink 1s ease-in-out infinite; }
@keyframes ckAirBlink { 0%, 100% { opacity: 1; text-shadow: 0 0 8px rgba(255,77,79,.95); } 50% { opacity: .22; text-shadow: none; } }
.ck-air-tip { margin-left: 6px; padding: 2px 9px; border-radius: 999px; background: #dc2626; color: #fff; font-size: 11px; font-weight: 700; white-space: nowrap; animation: ckAirTip 1s ease-in-out infinite; }
@keyframes ckAirTip { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
/* 术语释义（弹窗） */
.ck-gloss { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; padding: 10px 12px; border-radius: 10px;
  background: rgba(56,130,246,.08); border: 1px solid rgba(56,130,246,.2); }
.ck-gloss > div { display: flex; gap: 8px; font-size: 12px; line-height: 1.55; }
.ck-gloss b { flex: 0 0 98px; color: #7dd3fc; font-weight: 700; }
.ck-gloss span { color: #9db8dd; flex: 1; }
.modal:has(.ck-detail) .ck-gloss { background: rgba(56,130,246,.1); }
/* 态势总览底部 → 数据矩阵入口（与 .dash-exit / .dash-stat-chip 风格一致） */
.dash-foot .dash-matrix {
  background: rgba(34,211,238,.08);
  border: 1px solid rgba(34,211,238,.3);
  color: #a8d8f0;
  font-size: 12px; font-weight: 600; letter-spacing: .5px;
  border-radius: 8px; padding: 4px 12px; cursor: pointer;
  transition: background .16s, color .16s, box-shadow .16s, border-color .16s;
}
.dash-foot .dash-matrix:hover {
  background: rgba(34,211,238,.2); color: #fff; border-color: rgba(34,211,238,.6);
  box-shadow: 0 0 10px rgba(34,211,238,.35);
}
/* 顶栏按钮 */
.ck-btn { background: rgba(34,211,238,.09); border: 1px solid rgba(34,211,238,.32); color: #a8d8f0; border-radius: 9px; padding: 5px 11px; font-size: 12px; cursor: pointer; transition: all .16s; }
.ck-btn:hover { background: rgba(34,211,238,.2); color: #fff; box-shadow: 0 0 14px rgba(34,211,238,.35); }
.ck-exit { background: linear-gradient(140deg, rgba(248,113,113,.24), rgba(239,68,68,.16)); border: 1px solid rgba(248,113,113,.5); color: #fca5a5; border-radius: 9px; padding: 5px 13px; font-size: 12px; font-weight: 700; cursor: pointer; transition: all .16s; }
.ck-exit:hover { background: rgba(248,113,113,.4); color: #fff; border-color: #f87171; box-shadow: 0 0 18px rgba(248,113,113,.5); }
/* 顶栏状态胶囊组 */
.ck-chips { display: inline-flex; gap: 6px; align-items: center; }
.ck-chips .chip { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; color: #8fb0d8;
  border: 1px solid rgba(56,130,246,.26); background: rgba(56,130,246,.09); border-radius: 8px; padding: 4px 9px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06); }
.ck-chips .chip b { color: #eaf6ff; font-variant-numeric: tabular-nums; }
.ck-chips .chip i { width: 6px; height: 6px; border-radius: 50%; background: #22d3ee; box-shadow: 0 0 7px #22d3ee; }
.ck-chips .chip.warn { border-color: rgba(251,191,36,.35); background: rgba(245,158,11,.1); }
.ck-chips .chip.warn b { color: #fbbf24; }
.ck-chips .chip.hot { border-color: rgba(248,113,113,.38); background: rgba(248,113,113,.1); }
.ck-chips .chip.hot b { color: #f87171; }
.ck-chips .chip.ok { border-color: rgba(52,211,153,.35); background: rgba(52,211,153,.1); }
.ck-chips .chip.ok b { color: #34d399; }
.ck-chips .chip.scope, .ck-actions .chip.scope { border-color: rgba(167,139,250,.42); background: rgba(167,139,250,.12); }
.ck-chips .chip.scope b, .ck-actions .chip.scope b { color: #c4b5fd; }
/* 顶栏按钮 hover 保持深底亮字 */
.ck-btn:hover { background: rgba(34,211,238,.28); color: #fff; }
/* ⑨ 三栏：环 / 指标 / 滚动名单 */
.ck-real-split { flex: 1 1 auto; min-height: 0; display: flex; gap: 9px; align-items: center; }
.ck-real-ring { flex: 0 0 auto; display: flex; align-items: center; }
.ck-real-kv { flex: 0 0 76px; display: flex; flex-direction: column; justify-content: center; gap: 5px; font-size: 10.5px; }
.ck-real-kv > div { display: flex; justify-content: space-between; gap: 5px; color: #8fb0d8; }
.ck-real-kv b { color: #eaf6ff; font-variant-numeric: tabular-nums; }
.ck-real-split .ck-marquee { flex: 1 1 auto; margin-top: 0; }
.ck-mq-hd { font-size: 9.5px; color: #5b7aa8; letter-spacing: 1px; padding: 0 3px 4px; border-bottom: 1px solid rgba(56,130,246,.15); }
/* 重点人员滚动 */
.ck-marquee { flex: 1 1 auto; min-height: 0; overflow: hidden; position: relative; margin-top: 4px;
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 14%, #000 86%, transparent);
  mask-image: linear-gradient(180deg, transparent, #000 14%, #000 86%, transparent); }
.ck-marquee-track { animation: ckUp 22s linear infinite; }
.ck-marquee:hover .ck-marquee-track { animation-play-state: paused; }
@keyframes ckUp { from { transform: translateY(0); } to { transform: translateY(-50%); } }
.ck-mq-item { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 11px;
  padding: 4px 5px; color: #9db8dd; cursor: pointer; border-bottom: 1px solid rgba(56,130,246,.08); transition: background .12s, color .12s; border-radius: 4px; }
.ck-mq-item:hover { color: #eaf6ff; background: rgba(34,211,238,.18); }
.ck-mq-item .n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ck-mq-item.hot .n { color: #f87171; font-weight: 700; }
.ck-mq-item .c { flex: none; color: #22d3ee; font-variant-numeric: tabular-nums; }
/* 弹窗整体深色（消除白底与蓝色面板的反差） */
.modal:has(.ck-detail) {
  background: linear-gradient(160deg, #10203f, #081226);
  border: 1px solid rgba(56,130,246,.35);
  box-shadow: 0 26px 70px rgba(0,0,0,.72), 0 0 44px rgba(34,211,238,.14);
  height: auto; max-height: 90vh;
}
.modal:has(.ck-detail) .modal-head { border-bottom: 1px solid rgba(56,130,246,.25); color: #eaf6ff; }
.modal:has(.ck-detail) .modal-head .close { color: #8fb0d8; }
.modal:has(.ck-detail) .modal-head .close:hover { color: #fff; }
.ck-detail { background: transparent; border: 0; box-shadow: none; padding: 0; max-height: 68vh; }
/* 覆盖全局浅色行 hover（深色环境下保持深底亮字；全局有 tbody tr:hover{background:#f8fafc}） */
.modal:has(.ck-detail) tbody tr:hover,
.ckmatrix tbody tr:hover { background: transparent !important; }
.modal:has(.ck-detail) tbody tr:hover td,
.ckmatrix tbody tr:hover td { background: rgba(56,130,246,.2) !important; }
.modal:has(.ck-detail) tbody tr:hover td,
.ckmatrix tbody tr:hover td { color: #eaf6ff; }
.modal:has(.ck-detail) .ck-tbl th { background: #10203f; }
.ck-detail .ck-tbl tr:hover td { background: rgba(56,130,246,.2); }
/* 深色滚动条（弹窗与矩阵区域） */
.modal:has(.ck-detail) .modal-body::-webkit-scrollbar,
.ckmatrix::-webkit-scrollbar,
.ckmatrix ::-webkit-scrollbar { width: 8px; height: 8px; }
.modal:has(.ck-detail) .modal-body::-webkit-scrollbar-track,
.ckmatrix::-webkit-scrollbar-track,
.ckmatrix ::-webkit-scrollbar-track { background: rgba(56,130,246,.08); border-radius: 4px; }
.modal:has(.ck-detail) .modal-body::-webkit-scrollbar-thumb,
.ckmatrix::-webkit-scrollbar-thumb,
.ckmatrix ::-webkit-scrollbar-thumb { background: rgba(56,130,246,.45); border-radius: 4px; }
.modal:has(.ck-detail) .modal-body::-webkit-scrollbar-thumb:hover,
.ckmatrix ::-webkit-scrollbar-thumb:hover { background: rgba(34,211,238,.65); }
/* 人员弹窗 */
.ck-pilot-hd { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 10px; padding: 8px 12px; border-radius: 10px;
  background: linear-gradient(140deg, rgba(34,211,238,.12), rgba(59,130,246,.08)); border: 1px solid rgba(34,211,238,.28); }
.ck-pilot-hd b { color: #eaf6ff; font-size: 15px; }
.ck-pilot-hd .pi { font-size: 12px; color: #8fb0d8; }
.ck-pilot-hd .pi b { color: #22d3ee; font-size: 13px; }
.ck-link { color: #38bdf8; text-decoration: none; font-size: 12px; }
.ck-link:hover { color: #bae6fd; text-decoration: underline; }
.ck-detail .muted { color: #7c93b8; font-size: 11px; }
.modal:has(.ck-detail) .sub { color: #8fb0d8; }
/* 底部状态条 */
.ck-foot { flex: 0 0 auto; display: flex; justify-content: space-between; align-items: center; gap: 14px; margin-top: 7px; padding: 5px 12px;
  font-size: 11px; color: #5b7aa8; letter-spacing: .5px; border-top: 1px solid rgba(56,130,246,.18);
  background: linear-gradient(90deg, rgba(12,28,58,.55), rgba(8,18,40,.35)); border-radius: 0 0 10px 10px; }
.ck-foot span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ck-foot #ckFootInfo { color: #7dd3fc; flex: 1; text-align: center; }

/* 北京一侧起飞：预警/说明统一为客观表述（橙色，区别于我方责任的红字违规） */
/* 北京一侧起飞：红字、无底色（不加红底，避免与"我方责任"混淆） */
.bj-takeoff-tag { color: #dc2626; font-weight: 700; background: none; border: 0; padding: 0; white-space: nowrap; }
.bj-takeoff-tag.red-strike { border-bottom: 1px dashed rgba(220,38,38,.5); }
/* ==================== 态势总览视觉升级 v2（装饰强化 · 性能友好） ==================== */
/* 面板：单层渐变 + 细描边 + 轻投影（无大模糊 inset，切换不卡） */
.dash .panel {
  position: relative;
  background: linear-gradient(158deg, rgba(22,44,86,.92), rgba(7,14,32,.95));
  border: 1px solid rgba(56,130,246,.3);
  border-left: 2px solid rgba(34,211,238,.45);
  border-radius: 12px;
  box-shadow: 0 6px 18px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.07);
}
/* 顶部光带（1.5px，几乎零成本） */
.dash .panel::before {
  content: ''; position: absolute; left: 12%; right: 12%; top: 0; height: 1.5px; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(34,211,238,.9), rgba(59,130,246,.55), transparent);
}
/* 右下角科技角标（单伪元素，零成本装饰） */
.dash .panel::after {
  content: ''; position: absolute; right: 6px; bottom: 6px; width: 11px; height: 11px; pointer-events: none;
  border-right: 2px solid rgba(34,211,238,.45); border-bottom: 2px solid rgba(34,211,238,.45);
  border-bottom-right-radius: 3px;
}
/* hover：仅改描边色（最省，不触发阴影重算） */
.dash .panel:hover { border-color: rgba(34,211,238,.62); border-left-color: #22d3ee; }
/* 地图面板：去掉投影，避免与高德地图合成时重绘变慢 */
.dash-map-panel { box-shadow: none !important; }
.dash-map-panel::after { display: none; }
/* 面板标题：左侧发光光条 */
.dash .panel-hd h2 { position: relative; padding-left: 10px; }
.dash .panel-hd h2::before {
  content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 3px; height: 12px; border-radius: 2px;
  background: linear-gradient(180deg, #22d3ee, #3b82f6); box-shadow: 0 0 6px rgba(34,211,238,.6);
}
/* 数字发光 */
.dash .kpi b.num { text-shadow: 0 0 12px rgba(34,211,238,.45); }
.dash .panel-bd b, .dash .rank-count, .dash .donut-hole b, .dash .vb-v { text-shadow: 0 0 10px rgba(34,211,238,.3); }
/* KPI 卡：轻立体 */
.dash .kpi {
  background: linear-gradient(150deg, rgba(20,40,80,.88), rgba(8,18,40,.92));
  border: 1px solid rgba(56,130,246,.22);
  box-shadow: 0 3px 10px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.06);
}
.dash .kpi:hover { border-color: rgba(34,211,238,.5); }
.dash .kpi::before { box-shadow: 0 0 10px rgba(34,211,238,.55); }
/* 排行榜 hover */
.dash .rank-item:hover { background: rgba(34,211,238,.1); border-radius: 6px; }
/* 状态胶囊 */
.dash .dash-stat-chip { background: rgba(13,26,52,.75); box-shadow: inset 0 1px 0 rgba(255,255,255,.06); }
.dash .dash-stat-chip:hover { border-color: rgba(34,211,238,.6); }
/* 标题发光 */
.dash-title h1 { text-shadow: 0 0 18px rgba(34,211,238,.42); }
/* 底部状态条（只加视觉） */
.dash-foot { border-radius: 10px; background: linear-gradient(90deg, rgba(13,26,52,.6), rgba(7,14,32,.35)); border: 1px solid rgba(56,130,246,.18); }
/* 深色滚动条 */
.dash-col-side::-webkit-scrollbar { width: 7px; }
.dash-col-side::-webkit-scrollbar-track { background: rgba(56,130,246,.07); border-radius: 4px; }
.dash-col-side::-webkit-scrollbar-thumb { background: rgba(56,130,246,.42); border-radius: 4px; }
.dash-col-side::-webkit-scrollbar-thumb:hover { background: rgba(34,211,238,.6); }

/* 态势总览 · 辖区选择器（与图例同款，位于图例行内） */
.dstation-inline { position: relative; left: auto; right: auto; top: auto; bottom: auto; z-index: auto; float: none; display: inline; margin: 0 0 0 12px; }
.dstation-inline .station-btn { background: none; border: none; padding: 0; margin: 0; color: inherit; font: inherit; cursor: pointer; display: inline; vertical-align: baseline; }
.dstation-inline .station-btn:hover { color: #7dd3fc; }
.dstation-inline .station-btn.on { color: #22d3ee; font-weight: 700; }
.dstation-inline .station-btn span { max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dstation-inline .station-clear { background: none; border: none; padding: 0; margin: 0 0 0 2px; color: #fca5a5; font: inherit; font-size: inherit; cursor: pointer; }
.dstation-inline .station-clear:hover { color: #ff6b6b; text-decoration: underline; }
.dstation-inline .station-menu { position: absolute; left: auto; right: 0; bottom: 18px; width: 276px; max-height: 340px; display: flex; flex-direction: column; background: #0b1a34; border: 1px solid rgba(56,130,246,.42); border-radius: 10px; box-shadow: 0 14px 34px rgba(0,0,0,.65); overflow: hidden; z-index: 30; }
.dstation-inline .station-menu input { background: transparent; color: #cfe3ff; border: none; border-bottom: 1px solid rgba(56,130,246,.25); padding: 9px 12px; font-size: 13px; outline: none; }
.dstation-inline .station-item { display: flex; justify-content: space-between; gap: 8px; padding: 8px 10px; font-size: 13px; color: #cfe3ff; cursor: pointer; }
.dstation-inline .station-item:hover { background: rgba(34,211,238,.14); }
.dstation-inline .station-item.on { background: rgba(34,211,238,.3); color: #fff; }
.dstation-inline .station-item .st-cnt { color: #7f9ec4; font-size: 12px; }
.dstation-inline .station-item.clear { color: #fca5a5; justify-content: center; }

.dash-foot .dash-btncol .dash-exit { font-size: 12px; padding: 4px 12px; font-weight: 600; letter-spacing: .5px; border-radius: 8px; }

/* 态势总览顶栏右上角：数据矩阵 + 进入主页（左右并排，进入主页在最右；单行不撑高顶栏） */
.dash-head-right .dash-btncol { display: flex; flex-direction: row; align-items: center; gap: 6px; flex: 0 0 auto; }
.dash-head-right .dash-btncol .dash-matrix,
.dash-head-right .dash-btncol .dash-exit { flex: 0 0 auto; margin: 0; display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 600; letter-spacing: .4px; line-height: 1.4; padding: 5px 11px; border-radius: 8px; white-space: nowrap; }
.dash-head-right .dash-btncol .dash-matrix { background: rgba(34,211,238,.08); border: 1px solid rgba(34,211,238,.3); color: #a8d8f0; cursor: pointer; transition: background .16s, color .16s, border-color .16s; }
.dash-head-right .dash-btncol .dash-matrix:hover { background: rgba(34,211,238,.2); color: #fff; border-color: rgba(34,211,238,.6); }
.dash-head-right .dash-btncol .dash-exit { background: rgba(34,211,238,.08); border: 1px solid rgba(34,211,238,.28); color: #a8d8f0; cursor: pointer; transition: all .2s; }
.dash-head-right .dash-btncol .dash-exit:hover { background: rgba(34,211,238,.18); color: #fff; box-shadow: 0 0 10px rgba(34,211,238,.35); }

/* ===== 实时目标卡片：底色=同色系浅渐变；左侧竖条=同色系深色「竖向渐变」 =====
   违规=红  黑名单=黑  白名单=蓝  合规=绿  报备=青
   实现说明：border 不支持渐变，故左侧竖条改用 ::before 伪元素绘制 */
.target-item { position: relative; border-left: none; padding-left: 14px; }
.target-item.black,
.target-item.whitelist { border-left: none; }

/* 底色（左深右浅 -> 白） */
.target-item[data-lv="red"]   { background: linear-gradient(90deg, #ffe4e6 0%, #fff1f2 55%, #ffffff 100%); }  /* 违规 → 红 */
.target-item[data-lv="green"] { background: linear-gradient(90deg, #dcfce7 0%, #f0fdf4 55%, #ffffff 100%); }  /* 合规 → 绿 */
.target-item[data-lv="white"] { background: linear-gradient(90deg, #cffafe 0%, #ecfeff 55%, #ffffff 100%); }  /* 报备 → 青 */
.target-item.whitelist        { background: linear-gradient(90deg, #dbeafe 0%, #eff6ff 55%, #ffffff 100%); }  /* 白名单 → 蓝 */
.target-item.black            { background: linear-gradient(90deg, #e5e7eb 0%, #f3f4f6 55%, #ffffff 100%); }  /* 黑名单 → 黑(浅底) */

/* 左侧竖条：同色系深色，自上而下由深到稍浅 */
.target-item::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  border-radius: 9px 0 0 9px; pointer-events: none;
  background: linear-gradient(180deg, #2563eb 0%, #60a5fa 100%);   /* 默认（无性质）：蓝 */
}
.target-item[data-lv="red"]::before   { background: linear-gradient(180deg, #b91c1c 0%, #f87171 100%); }   /* 违规 → 深红 */
.target-item[data-lv="green"]::before { background: linear-gradient(180deg, #15803d 0%, #4ade80 100%); }   /* 合规 → 深绿 */
.target-item[data-lv="white"]::before { background: linear-gradient(180deg, #0e7490 0%, #22d3ee 100%); }   /* 报备 → 深青 */
.target-item.whitelist::before        { background: linear-gradient(180deg, #1d4ed8 0%, #60a5fa 100%); }   /* 白名单 → 深蓝 */
.target-item.black::before            { background: linear-gradient(180deg, #111827 0%, #6b7280 100%); }   /* 黑名单 → 深黑 */

/* ===== AI 助手页面装修美化（与平台主色板统一） ===== */
/* 左侧会话栏：标题、空态 */
.chat-side-title { font-weight: 700; font-size: 13px; color: var(--text); letter-spacing: .3px; }
.chat-side-empty { padding: 22px 10px; font-size: 12px; line-height: 1.9; color: var(--muted); text-align: center; }
/* 会话列表项：更柔和的悬停与选中态 */
.chat-item { border: 1px solid transparent; background: #fbfdff; }
.chat-item.on { background: linear-gradient(90deg,#eff6ff 0%,#f8fbff 100%); }
/* 消息操作条：默认隐藏，悬停该条消息时淡入 */
.msg-ops { display: flex; gap: 6px; margin-top: 8px; opacity: 0; transform: translateY(-2px); transition: opacity .16s ease, transform .16s ease; }
.msg:hover .msg-ops { opacity: 1; transform: translateY(0); }
.msg-ops button { border: 1px solid var(--line); background: #fff; color: var(--muted); font-size: 12px; padding: 3px 9px; border-radius: 7px; cursor: pointer; transition: all .14s ease; }
.msg-ops button:hover { border-color: var(--primary); color: var(--primary); background: #eff6ff; }
.msg-ops button.del:hover { border-color: var(--danger); color: var(--danger); background: #fef2f2; }
.msg.user .msg-ops { justify-content: flex-end; }
/* 消息气泡：圆角与投影统一 */
.msg-bd { border-radius: 12px; }
.msg.ai .msg-content.md { border-radius: 12px; padding: 12px 14px; box-shadow: 0 1px 3px rgba(15,23,42,.04); }
.msg.user .msg-content.md { background: linear-gradient(135deg,#1d4ed8 0%,#2563eb 100%); border-color: transparent; border-radius: 12px; padding: 12px 14px; box-shadow: 0 2px 8px rgba(29,78,216,.18); }
.msg.user .msg-content.md a { color: #dbeafe; }
/* 头像统一 */
.msg-av { box-shadow: 0 2px 8px rgba(29,78,216,.15); }
/* 顶栏按钮组：更紧凑整齐 */
.chat-actions { flex-wrap: wrap; }
/* 输入区：圆角与主色聚焦 */
.chat-input textarea { border-radius: 10px; transition: border-color .15s ease, box-shadow .15s ease; }
.chat-input textarea:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(29,78,216,.10); }
/* 侧栏滚动条美化 */
.chat-list::-webkit-scrollbar, .chat-body::-webkit-scrollbar { width: 8px; }
.chat-list::-webkit-scrollbar-thumb, .chat-body::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 999px; }
.chat-list::-webkit-scrollbar-thumb:hover, .chat-body::-webkit-scrollbar-thumb:hover { background: #94a3b8; }

/* ══════════════════════════════════════════════════════════════════
   移动端适配（最终版）
   设计原则（吸取前几次教训）：
     1) 绝不触碰 flex 布局 —— 上次把 .view 的 flex 改掉，导致满屏页面塌陷；
     2) 不修改任何已有规则，只在文件末尾"追加覆盖"；
     3) 只做两件确定安全的事：① 开启纵向滚动；② 宽网格改单列；
     4) 用 !important 保证覆盖生效，但选择器严格限定在"内容型容器"，
        不动 .dash / .rt-page / .mining-page 这些满屏看板，
        也不动 .app / .view 的布局属性。
   仅 ≤900px 生效，PC 端完全不受影响。
   ══════════════════════════════════════════════════════════════════ */
@media (max-width: 900px) {

  /* ---------- ① 开启纵向滚动（只加 overflow，不改布局） ---------- */
  body, #app, .app { overflow-y: auto; -webkit-overflow-scrolling: touch; }
  .view, .card, .table-wrap, .modal-body,
  .pb-page, .ev-card, .ck-bd, .dash, .mining-body {
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }
  /* 内容型容器：允许滚动（数据矩阵 / 轨迹回放 / 历史空情 / 弹窗内容） */
  body.ckfull, .ckfull, .pb-page, .ev-card, .modal-body, .table-wrap, .ck-bd { overflow-y: auto !important; overflow-x: hidden; }
  /* 内容型容器：取消固定高度，交给内容与滚动 */

  .modal-body { min-height: 0 !important; }

  /* ---------- ② 所有宽网格在手机上一律改单列 ---------- */
  .ck-grid, .ck-grid2, .ck-grid3, .ck-kv3, .ck-flag, .ck-dual,
  .stat-grid, .dash-kpis, .filter-grid, .bw-grid, .admin-tabs, .rt-wrap {
    grid-template-columns: 1fr !important;
  }
  body.ckfull .ck-grid,
  body.ckfull .ck-grid2,
  body.ckfull .ck-grid3 { grid-template-columns: 1fr !important; grid-template-rows: none !important; flex: none !important; }
  /* 数据矩阵卡片：取消固定高度，内容完整显示 */
  body.ckfull .ck-card { overflow: visible !important; padding: 12px 12px 10px; }
  body.ckfull .ck-num { font-size: 28px; }
  body.ckfull .ck-card .panel-hd h2 { font-size: 14px; }

  body.ckfull .ck-line { height: 64px; }
  body.ckfull .ck-legend { font-size: 11px; gap: 5px; }
  body.ckfull .ck-head { flex-wrap: wrap; gap: 6px; }
  body.ckfull .ck-actions { flex-wrap: wrap; gap: 6px; }
  body.ckfull .ck-btn, body.ckfull .ck-exit,
  body.ckfull .ck-range button { min-height: 36px; padding: 6px 12px; font-size: 12px; }
  body.ckfull .ck-foot { position: static !important; }

  /* ---------- ③ 底部留出固定导航栏 + 系统安全区 ---------- */
  body.ckfull, .pb-page, .view { padding-bottom: calc(70px + env(safe-area-inset-bottom, 0px)) !important; }
  .pb-page { padding-top: 8px !important; }
  body.ckfull .ck-foot { margin-bottom: 4px; }

  /* ---------- ④ 弹窗（详情/轨迹回放所在） ---------- */
  .modal-mask { padding: 0; align-items: stretch; }
  .modal {
    width: 100% !important;
    max-width: 100% !important;
    height: 100dvh !important;
    max-height: 100dvh !important;
    border-radius: 0 !important;
  }
  .modal-head { padding: 12px 14px; }
  .modal-head .close { font-size: 22px; padding: 6px 12px; min-height: 40px; }

  /* ---------- ⑤ 表格：不挤压，可横向滑动 ---------- */
  .table-wrap { max-height: none !important; }
  .table-wrap > table { min-width: 720px; }
  .table-wrap th, .table-wrap td { white-space: nowrap; }

  /* ---------- ⑥ 分页条固定可见 ---------- */
  .ev-card > .pager { flex: 0 0 auto; position: sticky; bottom: 0; margin-top: 8px; }
  .ev-card > .pager button { flex: 1; min-height: 40px; }

  /* ---------- ⑦ 触摸友好 ---------- */
  .btn, .mini-btn, .copybtn, .ico-btn, #loginBtn { min-height: 42px; }
  input, select, textarea { font-size: 16px !important; }
  .bottomnav a { min-height: 44px; }
}

/* 折叠屏展开态（561~900px）：内容型网格用两列，比单列更利用宽度 */
@media (min-width: 561px) and (max-width: 900px) {
  .ck-grid, .stat-grid, .dash-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  body.ckfull .ck-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}

/* 横屏（高度受限）：压缩纵向留白 */
@media (max-width: 900px) and (orientation: landscape) and (max-height: 520px) {
  body.ckfull, .pb-page { padding-bottom: calc(52px + env(safe-area-inset-bottom, 0px)) !important; }

  body.ckfull .ck-line { height: 44px; }
  .modal { height: 100dvh !important; }
}

/* ==============================================================
   登录卡片：修正手机端溢出
   原因：.login-card { width:360px; padding:36px 30px } 未设 box-sizing，
        实际占宽 360+60 = 420px，超过 390px 的手机屏 → 右侧被裁切。
   做法：改为 border-box + 自适应宽度，仅手机端生效。
   ============================================================== */
@media (max-width: 900px) {
  .login-card {
    box-sizing: border-box;
    width: min(360px, calc(100vw - 32px));
    max-width: calc(100vw - 32px);
    padding: 28px 20px;
  }
  .login-wrap { padding: 16px; }
  .login-card .logo { font-size: 36px; }
  .login-card h1 { font-size: 18px; }
  .login-card input { font-size: 16px; padding: 13px 14px; }
  #loginBtn { min-height: 46px; font-size: 15px; }
}


/* ==============================================================
   数据矩阵顶部芯片：强制按内容宽度（终极修正）
   前一轮 flex:0 0 auto 未完全生效，芯片仍被压窄导致文字竖排。
   本轮用 min-width:max-content + display:inline-flex 强约束。
   ============================================================== */
@media (max-width: 900px) {
  body.ckfull .ck-chips .chip,
  body.ckfull .ck-actions .chip { flex: 0 0 auto !important; white-space: nowrap !important; word-break: keep-all !important; display: inline-flex !important; align-items: center !important; writing-mode: horizontal-tb !important; text-orientation: mixed !important; }
  body.ckfull .ck-chips .chip span,
  body.ckfull .ck-actions .chip span,
  body.ckfull .ck-chips .chip b,
  body.ckfull .ck-actions .chip b { white-space: nowrap !important; writing-mode: horizontal-tb !important; }
  body.ckfull .ck-live,
  body.ckfull .ck-range,
  body.ckfull .ck-btn,
  body.ckfull .ck-exit,
  body.ckfull .ck-range button { flex: 0 0 auto !important; white-space: nowrap !important; writing-mode: horizontal-tb !important; }
  /* 操作区整体：换行排列，不压缩子项 */
  body.ckfull .ck-actions { flex-wrap: wrap !important; align-items: center !important; overflow: visible !important; }
  body.ckfull .ck-chips { display: flex !important; flex-wrap: wrap !important; align-items: center !important; }
}




/* ==============================================================
   ★ 表格区"劫持"纵向滚动 —— 手机上手指按在表格上滑不动
   现象：点住页面上半部分能滑，点住表格区域不行。
   原因：.table-wrap { overflow:auto } 使其成为独立滚动容器，
        纵向内容未超出时自身滚不动，也不把滚动链传给页面。
   修复：手机端让表格只负责"横向滑动"，纵向手势交还页面。
        · overflow-y: clip（不支持则回退 hidden），避免捕获纵向滚动；
        · touch-action: pan-y 让纵向手势透传；
        · 取消 max-height，表格完整显示，由页面统一纵向滚动。
   仅 ≤900px 生效，PC 端不变。
   ============================================================== */
@media (max-width: 900px) {
  /* ★ 修正：touch-action 必须允许横向(pan-x)，否则左右滑动失效；
       纵向改用 overflow-y: clip —— clip 与 hidden 的关键区别是
       "不创建滚动容器"，因此纵向手势可以穿透到页面。 */
  .table-wrap, .ev-card > .table-wrap, .case-table-card .table-wrap {
    max-height: none !important;
    height: auto !important;
    overflow-x: auto !important;
    overflow-y: hidden !important;
    touch-action: pan-x pan-y !important;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
  }
  /* 老浏览器不支持 overflow-y:clip 时的回退 */
  @supports not (overflow-y: clip) {
    .table-wrap, .ev-card > .table-wrap, .case-table-card .table-wrap {
      overflow-y: hidden !important;
    }
  }
  /* 表格本身：给足宽度以便横向滑动，不换行 */
  .ev-card .table-wrap > table { min-width: 820px !important; }
  .table-wrap > table { min-width: 720px; }
  .table-wrap th, .table-wrap td { white-space: nowrap; }
  /* 卡片与内容区不参与纵向滚动接管 */
  .ev-card { overflow: visible !important; }
  .ev-card > .table-wrap { flex: 0 0 auto !important; }
}

@media (max-width: 900px) {
  @supports not (overflow-y: clip) {
    .table-wrap, .ev-card > .table-wrap { overflow-y: hidden !important; }
  }
  /* 明细区允许双向手势 */
  .ev-card > .table-wrap, .table-wrap > table { touch-action: pan-x pan-y !important; }
}


/* ==============================================================
   数据矩阵手机端 —— 对齐"态势总览"的简单思路
   态势总览的做法：容器块级化 + 单列 + 让卡片自然撑开，不写死任何尺寸。
   原先我给它加了很多 min-height / font-size / 图表宽高，导致卡片畸变，已全部清除。
   本段只做三件事：① 容器可滚动；② 网格单列；③ 卡片高度自适应。
   ============================================================== */
@media (max-width: 900px) {
  .mining-body.ckfull {
    display: block;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    padding: 8px 10px calc(72px + env(safe-area-inset-bottom, 0px));
  }
  .mining-body.ckfull .ck-grid {
    grid-template-columns: 1fr;
    grid-template-rows: none;
    flex: none;
  }
  .mining-body.ckfull .ck-card {
    height: auto;
    min-height: 0;
    max-height: none;
    overflow: visible;
  }
  .mining-body.ckfull .ck-bd {
    flex: none;
    min-height: 0;
    overflow: visible;
  }
  .mining-body.ckfull .ck-head {
    flex-wrap: wrap;
  }
  .mining-body.ckfull .ck-actions {
    flex-wrap: wrap;
    align-items: center;
  }
}

/* ==============================================================
   数据矩阵手机端：卡片宽高随屏幕自适应
   要点：
     · box-sizing: border-box —— 让 padding 计入宽度，卡片不会被撑出屏幕；
     · width/max-width: 100% —— 卡片宽度始终等于内容区宽度；
     · 高度 auto + 温和下限 —— 内容少的卡片不至于太空，内容多的自然撑高；
     · 内部块一律限宽、图表自适应宽度，避免横向溢出。
   仅 ≤900px 生效；PC 端不变。
   ============================================================== */
@media (max-width: 900px) {
  .mining-body.ckfull .ck-grid {
    gap: 10px;
    width: 100%;
    max-width: 100%;
  }
  .mining-body.ckfull .ck-card {
    box-sizing: border-box;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    height: auto;
    max-height: none;
    min-height: 120px;
    padding: 12px 12px 10px;
    overflow: visible;
  }
  .mining-body.ckfull .ck-card > * {
    box-sizing: border-box;
    max-width: 100%;
    min-width: 0;
  }
  .mining-body.ckfull .ck-bd {
    box-sizing: border-box;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    height: auto;
    min-height: 0;
    overflow: visible;
  }
  /* 内部网格块：随卡片宽度自适应 */
  .mining-body.ckfull .ck-grid2,
  .mining-body.ckfull .ck-grid3,
  .mining-body.ckfull .ck-kv3,
  .mining-body.ckfull .ck-flag,
  .mining-body.ckfull .ck-dual {
    width: 100%;
    max-width: 100%;
    min-width: 0;
  }
  /* 图表类：宽度铺满，不超出卡片 */
  .mining-body.ckfull .ck-line-wrap,
  .mining-body.ckfull .ck-bars,
  .mining-body.ckfull .ck-heat,
  .mining-body.ckfull .ck-hbars,
  .mining-body.ckfull .ck-stack,
  .mining-body.ckfull .ck-pie-wrap,
  .mining-body.ckfull .ck-legend {
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
  }
  /* 头部信息区也不超出 */
  .mining-body.ckfull .ck-head { width: 100%; max-width: 100%; box-sizing: border-box; }
  .mining-body.ckfull .ck-foot { width: 100%; max-width: 100%; box-sizing: border-box; }
}

/* ==============================================================
   数据矩阵手机端：列表类卡片"长度收敛"（与 PC 端滚动逻辑一致）
   问题：实名核验栏把所有姓名纵向铺开，卡片被拉得很长。
   原因：PC 端卡片高度由 4×4 网格固定，.ck-marquee / .ck-real-split 靠
        flex:1 + min-height:0 在有限高度内滚动；手机端改为 height:auto 后
        失去高度约束，列表全部展开。
   做法：手机端给这些"滚动列表"容器明确的最大高度并开启内部滚动，
        恢复与 PC 一致的"限高 + 内部滚动"体验。
   仅 ≤900px 生效；PC 端不变。
   ============================================================== */
@media (max-width: 900px) {
  /* 滚动列表容器（实名核验的姓名走马灯） */
  .mining-body.ckfull .ck-marquee {
    max-height: 168px;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    /* PC 端靠 mask 做上下淡出，限高滚动时保留同样观感 */
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 6%, #000 94%, transparent);
            mask-image: linear-gradient(180deg, transparent, #000 6%, #000 94%, transparent);
  }
  /* 实名核验卡片：圆环 + 指标 + 走马灯，横向排布保持，整体高度收敛 */
  .mining-body.ckfull .ck-real-split {
    min-height: 0;
    align-items: stretch;
  }
  .mining-body.ckfull .ck-real-ring { flex: 0 0 auto; }
  .mining-body.ckfull .ck-real-kv { flex: 0 0 auto; }

  /* 同类的长列表容器一并收敛（区县排行/派出所排行等若使用滚动区） */
  .mining-body.ckfull .ck-ranks,
  .mining-body.ckfull .ck-list,
  .mining-body.ckfull .ck-scroll {
    max-height: 200px;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }

  /* 这类"带内部滚动"的卡片：整体高度也随之收敛，不再被内容拉长 */
  .mining-body.ckfull .ck-card:has(.ck-marquee),
  .mining-body.ckfull .ck-card:has(.ck-real-split) {
    min-height: 0;
    height: auto;
    max-height: none;
  }
}

/* ==============================================================
   数据矩阵手机端：卡片长度收敛（与 PC 端一致）
   两个要点：
     ① 卡片内部的小网格保持多列（PC 就是 2~3 列），不要改成单列，
        否则 8 个指标块纵向排开会把卡片拉到近千像素；
     ② 卡片本身设高度上限，超出部分内部滚动 —— 与 PC 端 .ck-marquee
        的"限高 + 内部滚动"逻辑一致。
   仅 ≤900px；PC 端不变。
   ============================================================== */
@media (max-width: 900px) {
  /* ① 内部小网格保持多列（只对"卡内小网格"，最外层 .ck-grid 仍是单列） */
  .mining-body.ckfull .ck-card .ck-grid2 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  .mining-body.ckfull .ck-card .ck-kv3 { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
  .mining-body.ckfull .ck-card .ck-grid3 { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
  .mining-body.ckfull .ck-card .ck-flag { grid-template-columns: repeat(auto-fit, minmax(72px, 1fr)) !important; }

  /* ② 卡片高度上限 + 超出内部滚动（与 PC 同逻辑） */
  .mining-body.ckfull .ck-card {
    max-height: 420px !important;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }
  /* 带内嵌滚动列表的卡片（实名核验等）用更矮的上限，避免双重滚动条 */
  .mining-body.ckfull .ck-card:has(.ck-marquee) {
    max-height: 300px !important;
    overflow-y: visible;
  }
  /* 卡片头部在内部滚动时保持可见 */
  .mining-body.ckfull .ck-card > .panel-hd {
    position: sticky;
    top: 0;
    z-index: 2;
    background: inherit;
    backdrop-filter: blur(4px);
  }
}

/* ==============================================================
   数据矩阵手机端：取消"卡片内部滚动"，统一由整屏滚动
   用户要求：手指滑动时应该是整个页面在滚，而不是卡片内部滚。
   做法：
     · 去掉卡片的 max-height / overflow-y（不再拦截手势）；
     · 内容全部展开，交给外层 .mining-body.ckfull 的整屏滚动；
     · 实名核验的长名单改为"多列铺开"，用排版降低高度，
       而不是靠内部滚动条（既满足"缩短"，又不产生内部滚动）。
   仅 ≤900px；PC 端不变。
   ============================================================== */
@media (max-width: 900px) {
  /* ① 卡片不再做内部滚动，手柄交给页面 */
  .mining-body.ckfull .ck-card {
    max-height: none !important;
    overflow: visible !important;
    overflow-y: visible !important;
  }
  .mining-body.ckfull .ck-card:has(.ck-marquee) {
    max-height: none !important;
    overflow: visible !important;
  }
  /* 卡片头部不再需要 sticky（没有内部滚动了） */
  .mining-body.ckfull .ck-card > .panel-hd {
    position: static !important;
    backdrop-filter: none !important;
  }

  /* ② 实名核验姓名列表：多列铺开，降低高度（无内部滚动） */
/* 已移除：不应把走马灯改成网格全展开 */
  .mining-body.ckfull .ck-mq-item { padding: 3px 4px; }

  /* ③ 排行/列表类容器同样不做内部滚动 */
  .mining-body.ckfull .ck-ranks,
  .mining-body.ckfull .ck-list,
  .mining-body.ckfull .ck-scroll {
    max-height: none !important;
    overflow: visible !important;
  }

  /* ④ 外层容器负责整屏滚动（保持可滚） */
  .mining-body.ckfull {
    overflow-y: auto !important;
    overflow-x: hidden !important;
    -webkit-overflow-scrolling: touch;
  }
}


/* ==============================================================
   "实名核验"卡片：手机端恢复 PC 的"走马灯"逻辑
   PC 端机制（原设计，卡片并不会变长）：
     .ck-marquee       → flex:1 + min-height:0 + overflow:hidden + 上下 mask 渐变
     .ck-marquee-track → animation: ckUp 22s linear infinite   （名字自动向上轮播）
     :hover            → 暂停
   我此前把它改成 display:grid 平铺，导致 40 个名字全部展开、卡片高达 969px 且排版异常。
   现改为完全沿用 PC 逻辑，只给手机端一个合适的高度上限。
   选择器限定在含走马灯的卡片内，其他卡片不受影响；PC 端不变。
   ============================================================== */
@media (max-width: 900px) {
  .mining-body.ckfull .ck-card:has(.ck-marquee) .ck-marquee {
    display: block !important;
    max-height: 168px !important;
    overflow: hidden !important;
    -webkit-overflow-scrolling: auto;
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 14%, #000 86%, transparent) !important;
            mask-image: linear-gradient(180deg, transparent, #000 14%, #000 86%, transparent) !important;
  }
  /* 确保轮播动画在手机端生效 */
  .mining-body.ckfull .ck-card:has(.ck-marquee) .ck-marquee-track {
    animation: ckUp 22s linear infinite !important;
  }
  /* 单项单行，避免长名换行把轨道撑高 */
  .mining-body.ckfull .ck-card:has(.ck-marquee) .ck-mq-item {
    padding: 4px 6px !important;
    font-size: 11.5px !important;
  }
  .mining-body.ckfull .ck-card:has(.ck-marquee) .ck-mq-item .n {
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
  }
  /* 圆环与指标不被拉伸 */
  .mining-body.ckfull .ck-card:has(.ck-marquee) .ck-real-split {
    align-items: flex-start !important;
  }
}
@media (prefers-reduced-motion: reduce) {
  .mining-body.ckfull .ck-card:has(.ck-marquee) .ck-marquee-track { animation: none !important; }
}


/* ==============================================================
   态势总览「📍 辖区」弹层：手机上底部显示不全 —— 最小修正
   实测：菜单位于底部工具栏上方（bottom≈900 超出视口 844），
        原 max-height:340px 使菜单底边到 882px，超出屏幕 38px。
   做法：只压缩菜单的最大高度（用视口比例），不改定位方式，
        列表区内部滚动，保证 61 个选项可达且菜单完整落在屏内。
   仅 ≤900px；PC 端与其他组件不变。
   ============================================================== */
@media (max-width: 900px) {
  .dstation-inline .station-menu,
  .station-menu {
    max-height: calc(100vh - 260px) !important;
    max-height: calc(100dvh - 260px - env(safe-area-inset-bottom, 0px)) !important;
    min-height: 220px;
  }
  .dstation-inline .station-list,
  .station-list {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }
  .dstation-inline .station-item,
  .station-item { min-height: 38px; }
}

/* ==============================================================
   态势总览「📍 辖区」弹层：手机端改为"屏幕居中显示"
   用户要求：无论"辖区"按钮在屏幕什么位置，弹层都应出现在屏幕中央。
   做法：手机端用 position:fixed + translate(-50%,-50%) 居中，
        并加半透明遮罩（点击遮罩关闭），彻底摆脱"贴着按钮弹、被裁切"的问题。
   仅 ≤900px；PC 端保持原样（贴着按钮弹出）。
   ============================================================== */
@media (max-width: 900px) {
  /* 遮罩：让弹层有独立层级、点击外部关闭 */
  .dstation-inline .station-menu::before,
  .station-menu::before {
    content: '';
    position: fixed;
    left: 0; right: 0; top: 0; bottom: 0;
    background: rgba(2, 8, 20, .55);
    z-index: -1;
  }
  .dstation-inline .station-menu,
  .station-menu {
    position: fixed !important;
    left: 50% !important;
    top: 50% !important;
    right: auto !important;
    bottom: auto !important;
    transform: translate(-50%, -50%) !important;
    width: min(340px, calc(100vw - 40px)) !important;
    max-height: min(70vh, calc(100dvh - 120px)) !important;
    z-index: 3200 !important;
    margin: 0 !important;
  }
  /* 列表区在弹层内滚动 */
  .dstation-inline .station-list,
  .station-list {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }
  .dstation-inline .station-item,
  .station-item { min-height: 40px; }
}

/* ==============================================================
   AI 助手（手机端）：界面精简为微信风格
   现状：顶部 6 个按钮占两行（会话/帮助/导出报告/Word/PDF/新对话），
        加上输入区两个大按钮，屏幕显得很满。
   目标（用户要求）：屏幕干净，需要功能时再点开调取。
   做法：手机端顶部只保留「标题 + ⋯ + ＋新对话」，
        其余按钮收进 ⋯ 展开面板；输入区按钮改为紧凑一行。
   仅 ≤900px 生效；PC 端（>900px）完全保持原样。
   ============================================================== */
@media (max-width: 900px) {
  /* ---------- 顶部：一行放下 ---------- */
  .chat-hd {
    flex-wrap: nowrap;
    gap: 8px;
    padding: 8px 10px;
    align-items: center;
  }
  .chat-title {
    flex: 1 1 auto;
    min-width: 40px;
    font-size: 13.5px;
    font-weight: 700;
    letter-spacing: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .chat-actions {
    flex: 0 0 auto;
    gap: 6px;
    flex-wrap: nowrap;
    align-items: center;
  }
  /* 默认只显示「⋯」和「＋新对话」 */
  .chat-hd:not(.open) .chat-actions > button:not(.chat-new):not(#chatMoreBtn) { display: none !important; }
  #chatMoreBtn {
    display: inline-flex !important;
    flex: 0 0 auto !important;      /* 不被拉伸，标题才有位置 */
    align-items: center;
    justify-content: center;
    width: 38px;
    min-width: 38px;
    min-height: 34px;
    padding: 0;
    font-size: 18px;
    line-height: 1;
    font-weight: 700;
  }
  .chat-actions > .chat-new {
    display: inline-flex !important;
    min-height: 34px;
    padding: 6px 12px;
    font-size: 12.5px;
  }
  /* 展开后：按钮换行铺开，仍然整齐 */
  .chat-hd.open { flex-wrap: wrap; }
  .chat-hd.open .chat-actions {
    flex-wrap: wrap;
    width: 100%;
    justify-content: flex-start;
    padding-top: 4px;
    border-top: 1px solid var(--line);
    margin-top: 4px;
  }
  .chat-hd.open .chat-actions > button:not(#chatMoreBtn),
  .chat-hd.open .chat-actions > button {
    display: inline-flex !important;
    flex: 1 1 calc(50% - 3px);
    justify-content: center;
    min-height: 36px;
  }
  .chat-hd.open #chatMoreBtn { order: 99; flex: 0 0 auto !important; width: auto; padding: 0 14px; }
  #chatMoreBtn::after { content: ' 收起'; font-size: 11px; font-weight: 500; letter-spacing: 0; }
  .chat-hd:not(.open) #chatMoreBtn::after { content: ''; }

  /* ---------- 输入区：两个大按钮改为紧凑一行 ---------- */
  .chat-input {
    padding: 8px 10px;
    gap: 8px;
    align-items: flex-end;
  }
  .chat-input textarea { min-height: 38px; max-height: 96px; font-size: 15px; padding: 9px 11px; }
  .chat-send-col {
    flex: 0 0 auto;
    flex-direction: row;
    gap: 6px;
  }
  .chat-send-col .btn {
    min-height: 36px;
    padding: 0 12px;
    font-size: 12.5px;
    white-space: nowrap;
  }
  /* 快捷提问条更紧凑，占位更小 */
  .chat-quick { padding: 6px 10px; gap: 5px; }
  .chat-quick .chip { padding: 4px 10px; font-size: 12px; }

  /* ---------- 消息区留白更自然 ---------- */
  .chat-body { padding: 10px 10px 4px; }
}

/* ==============================================================
   AI 助手（手机端）：输入区改为微信风格
   用户要求：把「直接回答 / 检索回答」两个按钮调整进输入框，只保留一个，
            发送键做成微信那样的小图标。
   做法：手机端输入框改为胶囊形，右侧内嵌圆形发送键（＝检索回答）；
        原两个大按钮在手机端隐藏（"直接回答"仍可用 Shift+回车 或长按调起）。
   PC 端（>900px）完全保持原样：新元素隐藏，原有两个按钮照旧。
   ============================================================== */
@media (max-width: 900px) {
  .chat-input {
    display: block;
    padding: 8px 10px;
    gap: 0;
  }
  /* 胶囊容器：输入框与发送键合为一体 */
  .chat-input-box {
    display: flex;
    align-items: flex-end;
    gap: 6px;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 22px;
    padding: 5px 5px 5px 14px;
    box-shadow: 0 1px 2px rgba(0,0,0,.04);
  }
  .chat-input-box textarea {
    flex: 1 1 auto;
    min-width: 0;
    border: none !important;
    box-shadow: none !important;
    background: transparent !important;
    padding: 7px 0 !important;
    margin: 0;
    min-height: 34px;
    max-height: 100px;
    font-size: 15px;
    line-height: 1.5;
    resize: none;
    outline: none;
  }
  /* 微信风格圆形发送键 */
  .chat-send-fab {
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: none;
    background: var(--primary);
    color: #fff;
    font-size: 15px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    padding: 0;
    transition: transform .12s ease, opacity .12s ease;
  }
  .chat-send-fab:active { transform: scale(.92); opacity: .85; }
  .chat-send-fab:disabled { opacity: .45; }
  /* 原两个大按钮在手机端隐藏 */
  .chat-send-col { display: none !important; }
  /* 快捷提问条上移一点，避免紧贴输入框 */
  .chat-quick { padding: 6px 10px 2px; }
}
/* ---------- PC 端：新元素隐藏，布局保持原样 ---------- */
@media (min-width: 901px) {
  /* 手机端专用元素在 PC 一律隐藏，保持原样 */
  .chat-send-fab { display: none !important; }
  #chatMoreBtn { display: none !important; }
  .chat-input-box { display: contents; }   /* 让 textarea 仍作为 .chat-input 的直接子项参与原布局 */
}

/* ==============================================================
   手机端：底部主菜单改为"隐藏 + 悬浮键调出"模式
   用户要求：底部主菜单平时隐藏、不占屏幕空间；需要时点击调出，用完收起。
   做法：
     · 手机端 .bottomnav 默认移到屏幕外（translateY(100%)），点击悬浮键滑出；
     · 右下角新增悬浮圆钮 #navFab（☰），点开后变 ✕；
     · 选中菜单项或点击别处自动收起；
     · 页面底部不再为导航预留 60px 空间，可视区域变大。
   PC 端（>900px）：.bottomnav 本就 display:none，#navFab 同步隐藏，完全不受影响。
   ============================================================== */
@media (max-width: 900px) {
  /* ① 底部导航：默认滑出屏幕外 */
  .bottomnav {
    display: flex !important;
    transform: translateY(110%);
    transition: transform .26s cubic-bezier(.32,.72,.35,1);
    box-shadow: 0 -8px 28px rgba(0, 0, 0, .32);
    z-index: 2100;
  }
  .bottomnav.open { transform: translateY(0); }
  .bottomnav a { color: #94a3b8; }
  .bottomnav a.on { color: #fff; }

  /* ② 悬浮菜单键（右下角） */
  .nav-fab {
    display: flex;
    position: fixed;
    right: auto;
    bottom: auto;
    left: calc(100vw - 54px - env(safe-area-inset-right, 0px));
    top: calc(100vh - 120px - env(safe-area-inset-bottom, 0px));
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: none;
    align-items: center;
    justify-content: center;
    background: linear-gradient(140deg, rgba(29,78,216,.82), rgba(14,165,233,.82));
    color: #fff;
    font-size: 18px;
    line-height: 1;
    box-shadow: 0 3px 12px rgba(0, 0, 0, .30);
    z-index: 2200;
    cursor: pointer;
    opacity: .62;                       /* 平时半透明，不抢视线 */
    backdrop-filter: blur(3px);
    transition: transform .18s ease, opacity .18s ease;
    -webkit-tap-highlight-color: transparent;
  }
  .nav-fab:active { transform: scale(.9); }
  /* 触摸/悬停时变清晰 */
  .nav-fab:hover, .nav-fab:focus, .nav-fab:active { opacity: 1; }
  /* 展开状态：完全不透明，便于看到 ✕ */
  .nav-fab.open { opacity: 1; background: linear-gradient(140deg, #334155, #475569); }

  /* ③ 页面底部不再为导航预留空间 */
  .view { padding-bottom: calc(16px + var(--sa-bottom, 0px)) !important; }
  .view.full { padding-bottom: calc(8px + var(--sa-bottom, 0px)) !important; }
  /* 全屏看板类页面底部也收紧 */
  .dash { padding-bottom: calc(16px + var(--sa-bottom, 0px)) !important; }
  .mining-body.ckfull { padding-bottom: calc(20px + var(--sa-bottom, 0px)) !important; }
  .ev-card { margin-bottom: 0; }
  /* 悬浮键与页面内容重叠时，给可能出现的长列表留出右下角安全距离 */
  .chat-body, .table-wrap { padding-bottom: 4px; }
  .toast { bottom: calc(84px + var(--sa-bottom, 0px)); }
}
/* ---------- PC 端：悬浮键隐藏，其余保持不变 ---------- */
@media (min-width: 901px) {
  .nav-fab { display: none !important; }
}

/* ==============================================================
   修正：底部导航"隐藏后仍占空间" + 悬浮球可拖动
   实测根因：.bottomnav 高度被撑到 700px（整屏），
            虽设置 translateY(110%)，但因高度过大且受其他规则影响，
            实际只移出 62.7px，形成一块覆盖整屏的透明层，
            挡住该区域内容与点击 —— 即用户所说"空间没释放"。
   修正：给导航明确高度（56px + 安全区），隐藏时彻底移出屏幕外；
        悬浮球支持拖动，可放到任意位置，仅占一个球的面积。
   仅 ≤900px；PC 端不变。
   ============================================================== */
@media (max-width: 900px) {
  .bottomnav {
    display: flex !important;
    height: auto !important;
    min-height: 0 !important;
    max-height: none !important;
    /* 明确的自身高度，避免被拉伸到整屏 */
    box-sizing: border-box;
    padding-bottom: env(safe-area-inset-bottom, 0px);
    transform: translateY(120%) !important;
    transition: transform .26s cubic-bezier(.32,.72,.35,1);
    z-index: 2100;
    will-change: transform;
  }
  .bottomnav > a { flex: 1; min-height: 52px; }
  .bottomnav.open { transform: translateY(0) !important; }
  /* 隐藏时彻底不接收事件，避免透明层挡住下面内容 */
  .bottomnav:not(.open) { pointer-events: none; visibility: hidden; }
  .bottomnav.open { pointer-events: auto; visibility: visible; }

  /* 悬浮球：改为可拖动（拖动逻辑在 JS），并保证只占一个球的面积 */
  .nav-fab {
    touch-action: none;            /* 允许拖动而不触发页面滚动 */
    user-select: none;
    -webkit-user-drag: none;
  }
}

/* ==============================================================
   修正：实时探测 / 数据研判 页面底部仍留 66px 空白
   根因：这两个页面在 ≤900px 下高度写作 calc(100vh - 66px)，
        66px 原本是给底部导航预留的；导航改为隐藏后，
        这块预留就成了永久空白（用户反馈"还在占用"）。
   修正：只保留 8px 呼吸间距，内容铺满到底。
   仅 ≤900px；PC 端不变。
   ============================================================== */
@media (max-width: 900px) {
  .rt-page,
  .mining-page {
    height: calc(100vh - 8px) !important;
    height: calc(100dvh - 8px) !important;
    max-height: none !important;
  }
  /* 页面容器底部不再为导航留白 */
  .view {
    padding-bottom: 8px !important;
  }
  /* 数据矩阵为满屏 fixed 层，同步收紧底部内边距 */
  .mining-body.ckfull {
    padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px)) !important;
  }
}

/* ==============================================================
   点位分布（手机端）：上部检索栏改为"可收起"
   用户要求：手机端把检索栏菜单也做成隐藏模式，需要时调出。
   做法：手机端检索栏默认收起，顶部显示一条可点击的标题条；
        点标题条或地图上的「🔍 筛选」按钮可展开/收起；
        查询、导出后自动收起。PC 端保持原样。
   ============================================================== */
/* PC 端：标题条不显示（保持既有布局） */
.points-bar-head { display: none; }
.pts-filter-btn { display: none; }

@media (max-width: 900px) {
  /* 标题条：手机端出现，可点击切换 */
  .points-bar-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 10px 12px;
    margin: 0 0 6px;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 10px;
    box-shadow: 0 1px 3px rgba(0,0,0,.08);
    font-size: 13px;
    color: var(--text);
    cursor: pointer;
    user-select: none;
    -webkit-tap-highlight-color: rgba(29,78,216,.10);
  }
  .points-bar-head .pbb-title { font-weight: 700; letter-spacing: .5px; color: var(--text); }
  .points-bar-head .pbb-toggle { font-size: 12px; color: var(--primary); }
  .points-bar-head.open {
    border-bottom-left-radius: 0; border-bottom-right-radius: 0;
    margin-bottom: 0; box-shadow: none;
    border-bottom-color: transparent;
  }

  /* 检索栏：默认收起，展开时显示 */
  .points-bar.mining-bar {
    display: none !important;
  }
  .points-bar.mining-bar.open {
    display: flex !important;
    flex-wrap: wrap;
    gap: 6px;
    padding: 10px 12px;
    border-top-left-radius: 0;
    border-top-right-radius: 0;
  }
  /* 展开时输入控件自适应宽度，避免溢出 */
  .points-bar.mining-bar > select,
  .points-bar.mining-bar > input { flex: 1 1 calc(50% - 3px); min-width: 0; max-width: 100%; }
  .points-bar.mining-bar > input#ptSn { flex: 1 1 100%; width: auto !important; }
  /* "起 / 止"标签与随后的日期框同一行成对显示 */
  .points-bar.mining-bar > label {
    flex: 0 0 auto;
    font-size: 12px;
    align-self: center;
    color: var(--muted);
    margin-right: -2px;
  }
  /* 让 label 与其后的 input 组成一对：label 占半行的左端 */
  .points-bar.mining-bar > label + input {
    flex: 1 1 auto;
    min-width: 0;
  }
  .points-bar.mining-bar > .btn { flex: 1 1 calc(50% - 3px); min-height: 38px; }

  /* 地图上的「筛选」按钮 */
  .pts-filter-btn { display: inline-flex; }

  /* 收起后地图占满剩余空间 */
  .points-map { flex: 1 1 auto; min-height: 0; }
}

/* ==============================================================
   历史空情（手机端）：上部检索栏同样改为"可收起"
   用户要求：与点位分布一样做优化（收起 + 浅色协调）。
   做法：手机端 .hdr 里的检索/筛选区（.sp）默认收起，
        标题「警情流转」变为可点击的展开/收起入口；
        检索或筛选后自动收起。PC 端保持原样。
   ============================================================== */
.hdr-toggle { display: none; }          /* PC 端不显示提示 */

@media (max-width: 900px) {
  /* 标题可点击 + 右侧提示 */
  .ev-card .hdr {
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 10px;
    padding: 10px 12px;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 10px;
    box-shadow: 0 1px 3px rgba(0,0,0,.08);
    cursor: pointer;
  }
  .ev-card .hdr h3 {
    display: flex; align-items: center; gap: 8px;
    font-size: 14px; font-weight: 700; color: var(--text);
    cursor: pointer;
  }
  .ev-card .hdr .sub { color: var(--muted); font-size: 12px; margin-left: auto; }
  .ev-card .hdr .hdr-toggle {
    display: inline-block;
    font-size: 12px; font-weight: 400;
    color: var(--primary);
  }
  /* 检索/筛选区：默认收起 */
  .ev-card .hdr .sp {
    display: none !important;
    width: 100%;
    margin-left: 0 !important;
    flex: 1 1 100%;
  }
  .ev-card .hdr.open {
    flex-wrap: wrap;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    box-shadow: none;
    border-bottom-color: transparent;
  }
  .ev-card .hdr.open .sp {
    display: flex !important;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px dashed var(--line);
  }
  /* 展开后：检索框整行，按钮等分两列 */
  .ev-card .hdr.open .sp input#evSearch {
    width: 100% !important;
    min-width: 0;
    padding: 8px 10px !important;
    font-size: 13px;
    border: 1px solid var(--line) !important;
    border-radius: 8px !important;
    background: #fff;
  }
  .ev-card .hdr.open .sp .btn { flex: 1 1 calc(33.33% - 4px); min-height: 36px; }
  /* 展开时表格区随之下移，整体仍由页面统一滚动 */
  .ev-card { height: auto !important; }
}

/* ==============================================================
   历史空情（手机端）：上部"案件检索"面板改为可收起
   用户要求：与点位分布同样处理（收起 + 浅色协调）。
   做法：手机端 .case-filter 默认收起；卡片顶部显示可点击的
        「🔍 案件检索 / 展开▾」标题条；PC 端保持原样。
   ============================================================== */
.case-filter-head { display: none; }        /* PC 端不显示 */

@media (max-width: 900px) {
  /* 卡片本体改为可滚动的普通卡片 */
  .case-search-card { padding: 10px; }

  .case-filter-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 10px 12px;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 10px;
    box-shadow: 0 1px 3px rgba(0,0,0,.08);
    font-size: 13px;
    color: var(--text);
    cursor: pointer;
    user-select: none;
    -webkit-tap-highlight-color: rgba(29,78,216,.10);
  }
  .case-filter-head .cfh-title { font-weight: 700; letter-spacing: .5px; color: var(--text); }
  .case-filter-head .cfh-toggle { font-size: 12px; color: var(--primary); }
  .case-filter-head.open {
    border-bottom-left-radius: 0; border-bottom-right-radius: 0;
    box-shadow: none; border-bottom-color: transparent;
  }

  /* 筛选面板：默认收起 */
  .case-search-card .case-filter { display: none !important; }
  .case-search-card .case-filter.open {
    display: flex !important;
    flex-wrap: wrap;
    gap: 8px;
    padding: 10px 12px;
    background: var(--card);
    border: 1px solid var(--line);
    border-top: none;
    border-bottom-left-radius: 10px;
    border-bottom-right-radius: 10px;
  }
  /* 展开后每个筛选项占半行（.cf 原本是固定像素宽，这里放开） */
  .case-search-card .case-filter.open > .cf,
  .case-search-card .case-filter.open > div.cf {
    flex: 1 1 calc(50% - 4px) !important;
    min-width: 0 !important;
    max-width: 100%;
  }
  .case-search-card .case-filter.open > .cf label { font-size: 12px; color: var(--muted); }
  .case-search-card .case-filter.open > .cf select,
  .case-search-card .case-filter.open > .cf input {
    width: 100% !important; max-width: 100%; min-width: 0;
    font-size: 13px;
  }
  .case-search-card .case-filter.open .btn.btn-sm,
  .case-search-card .case-filter.open > .cf .btn { min-height: 36px; }
}

/* ==============================================================
   态势总览（手机端）：卡片顺序调整
   用户要求：① 环首都地区空情态势 ② 实时空情态势 ③ 实名匹配，其余次序不限。
   做法：≤900px 时把三列用 display:contents 打散，卡片成为 .dash-main
        的直接子项，再用 order 指定先后。PC 端完全不受影响。
   ============================================================== */
@media (max-width: 900px) {
  .dash-main {
    display: flex !important;
    flex-direction: column;
    gap: 12px;
  }
  /* 打散三列，让其中的卡片直接参与排序 */
  .dash-main > .dash-col {
    display: contents !important;
  }
  /* 默认次序（其余卡片） */
  .dash-main > .dash-col > .panel { order: 50; }

  /* 指定前三：地图 → 实时空情态势 → 实名匹配 */
  .dash-main > .dash-col > .dash-map-panel { order: 1; }
  .dash-main > .dash-col > #dashRealPanel { order: 2; }
  .dash-main > .dash-col > #dashRealMatchPanel { order: 3; }

  /* 地图卡片在手机上高度合适一些（原来只有 40vh，放大后更好看） */
  .dash-map-panel .panel-bd,
  .dash-map-panel #dashMap { min-height: 46vh; }
}

/* ==============================================================
   态势总览（手机端）：让"环首都地区空情态势"真正置顶
   上一轮只调了 .dash-main 内部顺序，但 .dash-kpis（今日飞行批次等
   8 个数值卡片）是 .dash-main 的兄弟节点，仍占据最上方。
   本轮把 .dash 也变成 flex 列容器，用 order 让 KPI 区排到后面。
   最终顺序：标题 → 地图 → 实时空情态势 → 实名匹配 → KPI → 其余
   仅 ≤900px；PC 端不受影响。
   ============================================================== */
@media (max-width: 900px) {
  .dash {
    display: flex !important;
    flex-direction: column;
  }
  .dash-head  { order: 0; flex: 0 0 auto; }   /* 标题栏保持最上 */
  .dash-main  { order: 1; }                    /* 地图 / 实时空情 / 实名匹配 … */
  .dash-kpis  { order: 2; margin-top: 12px; }  /* 8 个数值卡片挪到后面 */
}

/* 补充：把"底部累计统计条"也移到地图之后（手机端）
   .dash 直接子元素顺序统一由 order 控制：
     head 0 → main(含地图) 1 → kpis 2 → foot 3 */
@media (max-width: 900px) {
  .dash-foot { order: 3; margin-top: 12px; }
}

/* ==============================================================
   态势总览（手机端）最终版：KPI 紧凑成 3 行，置于"实时空情态势"上方
   问题回顾：
     · .dash-kpis 是 .dash 的直接子项、.dash-main 的兄弟，故单纯调
       .dash-main 内部顺序无法让地图置顶；
     · 且早期规则把 .dash-kpis 覆盖成 grid-template-columns:1fr，
       8 个 KPI 竖成一列（8 行），既占空间又像"被压到下面"。
   本轮：
     · .dash 与 .dash-main / .dash-col 全部打通为同一排序层（display:contents）；
     · 顺序：标题0 → 地图1 → KPI 2 → 实时空情3 → 实名匹配4 → 其余50 → 统计条99；
     · KPI 恢复网格并改为 3 列（8 项 ≈ 3 行），卡片同步缩小。
   仅 ≤900px；PC 端不受影响。
   ============================================================== */
@media (max-width: 900px) {
  .dash {
    display: flex !important;
    flex-direction: column;
    gap: 10px;
  }
  .dash-head { order: 0; flex: 0 0 auto; }

  /* 打通层级：所有卡片统一在 .dash 层参与 order 排序 */
  .dash-main { display: contents !important; }
  .dash-main > .dash-col { display: contents !important; }

  /* ① 环首都地区空情态势（地图） */
  .dash-main > .dash-col > .dash-map-panel { order: 1; }

  /* ② KPI：3 列网格，8 项排 3 行，紧凑 */
  .dash-kpis {
    order: 2;
    display: grid !important;
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    grid-auto-rows: auto;
    gap: 6px !important;
    margin: 0 !important;
  }
  .dash-kpis > .kpi {
    padding: 5px 8px 6px 10px !important;
    border-radius: 8px !important;
  }
  .dash-kpis > .kpi b.num { font-size: 17px !important; line-height: 1.05; }
  .dash-kpis > .kpi span  { font-size: 9px !important; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .dash-kpis > .kpi em    { font-size: 9px !important; }

  /* ③ 实时空情态势  ④ 实名匹配 */
  .dash-main > .dash-col > #dashRealPanel { order: 3; }
  .dash-main > .dash-col > #dashRealMatchPanel { order: 4; }

  /* 其余卡片 */
  .dash-main > .dash-col > .panel { order: 50; }

  /* 底部累计统计条 */
  .dash-foot { order: 99; margin: 0 !important; }
}

/* ==============================================================
   态势总览（手机端）：修正 KPI 3 行排布 + 地图置顶（第二轮）
   上一轮问题：
     · .dash-map-panel 的 order 选择器过于严格，未生效 → 地图落到最后；
     · .dash-kpis 用 grid 但其子项被拉伸（grid-auto-rows 未限制），
       KPI 卡片被撑成 ~270px，8 项共 2186px 高。
   本轮：
     · 放宽选择器并统一加 !important；
     · KPI 卡片设固定高度（44px），grid-auto-rows: auto 且 align-items: start。
   仅 ≤900px。
   ============================================================== */
@media (max-width: 900px) {
  /* 地图卡片置顶（放宽选择器） */
  .dash .dash-map-panel,
  .dash-main .dash-map-panel,
  .dash-main > .dash-col > .dash-map-panel {
    order: 1 !important;
  }

  /* KPI：3 列、卡片固定高度，避免被拉伸 */
  .dash .dash-kpis,
  .dash > .dash-kpis {
    order: 2 !important;
    display: grid !important;
    grid-template-columns: repeat(4, minmax(0, 1fr)) !important;  /* 8 项 = 2 行 */
    grid-auto-rows: 42px !important;
    gap: 6px !important;
    margin: 0 !important;
    align-items: stretch;
  }
  .dash-kpis > .kpi {
    height: 42px !important;
    min-height: 0 !important;
    max-height: 42px !important;
    padding: 0 8px 0 10px !important;
    border-radius: 8px !important;
    display: flex !important;
    flex-direction: column;
    justify-content: center;
    overflow: hidden;
  }
  .dash-kpis > .kpi b.num { font-size: 15px !important; line-height: 1.02 !important; }
  .dash-kpis > .kpi span  { font-size: 9.5px !important; line-height: 1.1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 0 !important; }
  .dash-kpis > .kpi em    { font-size: 9px !important; }

  /* 实时空情态势 / 实名匹配 */
  .dash .dash-main #dashRealPanel,
  .dash-main > .dash-col > #dashRealPanel { order: 3 !important; }
  .dash .dash-main #dashRealMatchPanel,
  .dash-main > .dash-col > #dashRealMatchPanel { order: 4 !important; }

  /* 其余 */
  .dash-main > .dash-col > .panel { order: 50 !important; }
  .dash .dash-foot { order: 99 !important; }
}

/* ==============================================================
   态势总览（手机端）：地图置顶 —— 修正选择器特异性
   问题：.dash-main > .dash-col > .panel { order:50 } 的特异性 (0,3,0)
        高于 .dash .dash-map-panel (0,2,0)；两者都带 !important 时，
        按特异性决胜 → 地图被压回 order:50。
   修正：把地图/实时空情/实名匹配的规则提到 (0,4,0)，稳压默认规则。
   ============================================================== */
@media (max-width: 900px) {
  /* ③ 实时空情态势 / ④ 实名匹配 —— 先写，便于确认顺序 */
  .dash .dash-main > .dash-col > #dashRealPanel { order: 3 !important; }
  .dash .dash-main > .dash-col > #dashRealMatchPanel { order: 4 !important; }

  /* ① 地图置顶（特异性 0,4,0，高于默认 0,3,0） */
  .dash .dash-main > .dash-col > .dash-map-panel { order: 1 !important; }

  /* ② KPI 排在两者之间 */
  .dash > .dash-kpis { order: 2 !important; }
}

/* ==============================================================
   地图片卡（手机端）：标题行铺满 + 图例与辖区合并为一行
   问题：① .panel-hd 里标题与 .dash-map-ctrl 挤在左侧，右侧留大片空白；
        ② .dash-map-ctrl / .dash-map-legend 均为 flex-wrap:wrap，
           且 .station-btn span 上限 190px，手机宽度不足时挤成两行。
   修正：
     · 标题行不换行，功能键组 flex:1 靠右铺开（内容过多时可横向滑动）；
     · 图例条不换行、间距与图标缩小、"辖区"文案限宽，保证一行放下。
   仅 ≤900px；PC 端不受影响。
   ============================================================== */
@media (max-width: 900px) {
  /* ---------- ① 标题 + 功能键 ---------- */
  .dash-map-panel .panel-hd {
    flex-wrap: nowrap !important;
    gap: 6px !important;
    padding-bottom: 6px;
  }
  .dash-map-panel .panel-hd h2 {
    flex: 0 0 auto;
    font-size: 12.5px !important;
    letter-spacing: .3px;
    white-space: nowrap;
  }
  .dash-map-ctrl {
    flex: 1 1 auto !important;
    flex-wrap: nowrap !important;
    justify-content: flex-end;      /* 靠右铺开，填补右侧空白 */
    gap: 4px !important;
    min-width: 0;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .dash-map-ctrl::-webkit-scrollbar { display: none; }
  .dash-map-ctrl .dash-seg button,
  .dash-map-ctrl .dash-days button {
    padding: 2px 6px !important;
    font-size: 10.5px !important;
    min-height: 24px;
    white-space: nowrap;
  }
  .dash-map-ctrl .dash-days { gap: 3px !important; }

  /* ---------- ② 图例 + 辖区 合并一行 ---------- */
  .dash-map-legend {
    flex-wrap: nowrap !important;
    gap: 7px !important;
    margin-top: 6px !important;
    font-size: 10px !important;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding-bottom: 1px;
  }
  .dash-map-legend::-webkit-scrollbar { display: none; }
  .dash-map-legend > span {
    flex: 0 0 auto;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
  }
  .dash-map-legend .lg {
    width: 11px !important;
    height: 3px !important;
    margin-right: 3px !important;
  }
  /* "辖区"按钮收紧，保证与四个图例同排 */
  .dash-map-legend .station-picker,
  .dash-map-legend .dstation-inline { flex: 0 0 auto; }
  .dash-map-legend .station-btn span,
  .dstation-inline .station-btn span { max-width: 96px !important; }
  .dash-map-legend .station-btn { white-space: nowrap; }
}

/* ==============================================================
   登录卡片（手机端）：修正横向溢出
   原因：.login-card { width:360px; padding:36px 30px } 未设 box-sizing，
        内容宽 360 + 左右 padding 60 = 420px > 手机宽度 390px，
        卡片右侧被裁掉。
   修正：box-sizing:border-box 让 padding 计入宽度，并按屏宽约束。
   仅 ≤900px。
   ============================================================== */
@media (max-width: 900px) {
  .login-card {
    box-sizing: border-box !important;
    width: auto !important;
    min-width: 0 !important;
    max-width: calc(100vw - 32px) !important;
    margin: 0 16px !important;
    padding: 26px 20px !important;
  }
  .login-card input,
  .login-card button,
  .login-card .btn {
    box-sizing: border-box !important;
    max-width: 100% !important;
  }
}

/* ==============================================================
   态势总览（手机端）：把"环首都地区空情态势"卡片做高，显示更多地图内容
   现状：.dash-map { height:40vh; max-height:340px } —— 最大只有 340px，
        在手机上显得偏矮，地图可看范围小。
   调整（仅 ≤900px）：高度提到 58vh，放开 max-height 上限，
        并同步 .dash-map-panel #dashMap 的最小高度；
        同时保证卡片本身不因固定高度而溢出（.dash-map-panel 保持 flex:none）。
   PC 端不受影响。
   ============================================================== */
@media (max-width: 900px) {
  .dash-map-panel .dash-map,
  .dash-map-panel #dashMap {
    height: 58vh !important;
    min-height: 340px !important;
    max-height: none !important;
  }
  /* 卡片内部留白同步微调，避免标题/图例被挤压 */
  .dash-map-panel .panel-hd { padding-bottom: 5px !important; }
}

/* ==============================================================
   态势总览（手机端）：隐藏顶部「📊 数据矩阵」「🏠 进入主页」两个按钮
   用户要求：手机端不显示这两个按键，统一用右下角悬浮菜单操作；PC 端保留。
   说明：
     · 「进入主页」= 实时探测页 —— 悬浮球菜单里已有「实时探测」入口；
     · 「数据矩阵」是数据研判页内的 tab，可从悬浮球菜单「数据研判」进入。
   仅 ≤900px；PC 端完全不受影响。
   ============================================================== */
@media (max-width: 900px) {
  .dash-head .dash-btncol,
  .dash-btncol {
    display: none !important;
  }
}

/* ==============================================================
   悬浮球菜单（手机端）：支持左右滑动，退出键不再被挤出屏幕
   原因：.bottomnav a { flex: 1 } 让所有项平分宽度，项数增多后每项被压窄，
        最右侧的「退出」会被挤出可视区。
   修正：每项改为固定宽度、菜单整体横向滚动，并隐藏滚动条。
   仅 ≤900px；PC 端（.nav 侧栏）不受影响。
   ============================================================== */
@media (max-width: 900px) {
  .bottomnav {
    overflow-x: auto !important;
    overflow-y: hidden !important;
    flex-wrap: nowrap !important;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;          /* Firefox 隐藏滚动条 */
    justify-content: flex-start !important;
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .bottomnav::-webkit-scrollbar { display: none; width: 0; height: 0; }
  .bottomnav a {
    flex: 0 0 auto !important;      /* 不再平分，按内容定宽 */
    min-width: 62px !important;
    white-space: nowrap;
  }
}

/* ==============================================================
   AI 对话页（手机端）：收起顶部「AI助手 / 点位分布 / 数据矩阵」三 tab
   原因：这三个键常驻占一行高度，在对话页很碍事。
   做法：仅当数据研判页停在 AI 页签时隐藏该行（用 :has 精准限定），
        另两个入口移到右上角「⋯」更多菜单里（.chat-goto）。
        点位分布 / 数据矩阵 页签自身仍保留该行，可正常切回。
   仅 ≤900px；PC 端三 tab 原样保留。
   ============================================================== */
@media (max-width: 900px) {
  .mining-page:has(> .mining-body.chat) > .mining-tabs { display: none !important; }
}
/* PC 端不显示「⋯」菜单里的两个跳转键（PC 有常驻 tab 行） */
@media (min-width: 901px) {
  .chat-actions .chat-goto { display: none !important; }
}

/* ==============================================================
   AI 对话页头部（手机端）：只留一个"机器人"图标做「更多」入口
   改动前：头部同时有 ① 被截断的标题"🤖…"（机器人+省略号）
                    ② 矩形「⋯」更多键  —— 两个"三个点"看着重复。
   改动后：① 手机端隐藏残缺标题（PC 端标题照常显示）；
           ② 隐藏矩形「⋯」键；
           ③ 新增的 #chatHdFab（🤖）独占左上角，点击＝展开/收起更多菜单。
   注意：#chatHdFab 放在 .chat-actions 之外，因此不受
        .chat-hd:not(.open) .chat-actions > button 的隐藏规则影响，收起态也常驻。
   仅 ≤900px；PC 端头部完全不变（标题 + 帮助/导出/Word/PDF/新对话）。
   ============================================================== */
@media (max-width: 900px) {
  .chat-hd > .chat-title { display: none !important; }
  .chat-hd #chatMoreBtn { display: none !important; }
  .chat-hd .chat-hd-fab {
    display: inline-flex !important;
    flex: 0 0 auto !important;
    align-items: center; justify-content: center;
    width: 38px; min-width: 38px; min-height: 34px;
    padding: 0; font-size: 17px; line-height: 1;
  }
  /* 菜单展开时给机器人键一个"选中"反馈 */
  .chat-hd.open .chat-hd-fab {
    border-color: var(--primary) !important;
    color: var(--primary) !important;
    background: #eff6ff !important;
  }
}
/* PC 端不显示机器人键（PC 头部布局不变） */
@media (min-width: 901px) {
  .chat-hd .chat-hd-fab { display: none !important; }
}

/* ==============================================================
   数据矩阵（手机端）：顶部 KPI 胶囊统一格式，排成"三整行"
   改动前：6 个 .chip 高矮胖瘦不一 —— 实时空情 69x19 / 数据范围 88x19
          （这两个没有基础样式，看起来像纯文字），
          区间情警 99x40 / 待处理 80x40 / 违规率 74x40 / 实名率 80x40。
   改动后：包一层 .ck-kpis，电脑端 display:contents（=不参与布局，PC 零变化）；
          手机端改为 2 列网格，.ck-chips 用 display:contents 把 4 个 chip
          "提升"到同一网格 → 6 个胶囊 = 3 行 x 2 列，等宽等高。
   仅 ≤900px 生效。
   ============================================================== */
.mining-body.ckfull .ck-kpis { display: contents; }

@media (max-width: 900px) {
  .mining-body.ckfull .ck-actions > .ck-kpis {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 6px !important;
    width: 100% !important;
    flex: 1 1 100% !important;
    margin: 0 !important;
  }
  .mining-body.ckfull .ck-kpis > .ck-chips { display: contents !important; }
  .mining-body.ckfull .ck-kpis .chip {
    box-sizing: border-box !important;
    width: 100% !important; min-width: 0 !important; max-width: 100% !important;
    height: 36px !important; min-height: 36px !important; max-height: 36px !important;
    display: flex !important;
    align-items: center !important; justify-content: center !important;
    gap: 5px !important;
    margin: 0 !important; padding: 0 8px !important;
    border: 1px solid rgba(56,130,246,.26) !important;
    background: rgba(56,130,246,.09) !important;
    border-radius: 8px !important;
    font-size: 12px !important; line-height: 1 !important;
    color: #8fb0d8 !important;
    white-space: nowrap !important;
    overflow: hidden !important;
  }
  .mining-body.ckfull .ck-kpis .chip b { font-size: 13px !important; color: #eaf6ff !important; }
  /* 保留原有的配色语义（红色实时空情 / 紫色数据范围） */
  .mining-body.ckfull .ck-kpis .chip.live {
    border-color: rgba(248,113,113,.45) !important;
    background: rgba(248,113,113,.12) !important;
  }
  .mining-body.ckfull .ck-kpis .chip.live b { color: #ff4d4f !important; }
  .mining-body.ckfull .ck-kpis .chip.scope {
    border-color: rgba(167,139,250,.42) !important;
    background: rgba(167,139,250,.12) !important;
  }
  .mining-body.ckfull .ck-kpis .chip.scope b { color: #c4b5fd !important; }
}

/* ==============================================================
   数据矩阵（手机端）KPI 胶囊 · 再压缩：3 行 x 2 列 → 2 行 x 3 列
   3 列时每格宽约 111px，故字号 12→11、内边距 8→6、行高 36→34，
   保证"区间情警 1,304""数据范围 全市"这类最长文本不被切。
   仅 ≤900px；PC 端不受影响（.ck-kpis 在 PC 仍是 display:contents）。
   ============================================================== */
@media (max-width: 900px) {
  .mining-body.ckfull .ck-actions > .ck-kpis {
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    gap: 5px !important;
  }
  .mining-body.ckfull .ck-kpis .chip {
    height: 34px !important; min-height: 34px !important; max-height: 34px !important;
    font-size: 11px !important;
    padding: 0 6px !important;
    gap: 4px !important;
  }
  .mining-body.ckfull .ck-kpis .chip b { font-size: 11.5px !important; }
}

/* ==============================================================
   实时探测页（手机端）地图显示不全 —— 根因修复
   现象：进入实时探测时地图只画一部分、下半块空白，刷新一次才正常。
   根因：手机端 .rt-page 仍是 height: calc(100vh - 66px)：
         ① 100vh 取的是"地址栏收起"时的最大高度，比实际可视区更大；
         ② 减 66px 是给早已废弃的底部导航留的位（现已是悬浮球，不再占位）。
         容器高度因此与实际不符；高德在 new AMap.Map 那一刻就把画布尺寸定死，
         之后容器对不上 → 只渲染一部分。刷新后地址栏状态变化恰好对上 → 好了。
   修复：与 .mining-page 完全对齐 —— 用 dvh 跟随真实可视高度，扣掉 .view 的 8px 内边距。
   仅 ≤900px；PC 端 .rt-page 规则不动。
   ============================================================== */
@media (max-width: 900px) {
  .rt-page {
    height: calc(100vh - 8px) !important;
    height: calc(100dvh - 8px) !important;
    max-height: none !important;
  }
}

/* 禁飞空域徽标（红）：比一般管制更强，用于"点在禁飞多边形内" */
.air-tag.nf { color: #991b1b; }

/* ==============================================================
   实时探测 · 实时目标卡片：手机端改为【横向左右滑动】
   原来 .target-list 是 flex:1 + overflow:auto（纵向上下滚）；
   手机端改成一行横排、横向滚动、卡片懒吸附。
   仅 ≤900px 生效；PC 端规则一字未动。
   ============================================================== */
@media (max-width: 900px) {
  /* :not(.collapsed) 是关键——否则 !important 会盖掉系统的 .rt-side.collapsed .target-list{display:none} */
  .rt-side:not(.collapsed) .target-list {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    overflow-y: hidden !important;
    gap: 8px !important;
    padding: 8px 10px !important;
    -webkit-overflow-scrolling: touch;
    touch-action: pan-x;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
  }
  .rt-side .target-list > .target-item {
    flex: 0 0 auto !important;
    width: min(76vw, 300px) !important;
    max-width: 76vw !important;
    margin: 0 !important;
    scroll-snap-align: start;
  }
  /* 横向时不需要底部外边距（否则把容器撑高） */
  .rt-side .target-list > .target-item:last-child { margin-right: 0 !important; }
  .rt-side .target-list::-webkit-scrollbar { height: 0 !important; display: none !important; }
  .rt-side .target-list > .empty { width: 100% !important; }
}

/* ==============================================================
   实时探测 · 实时目标卡片：手机端【整卡可点】
   单击 = 地图定位到无人机（等同点卡片里的 🚁）
   双击 = 查看详情（等同点卡片里的「详情」）
   说明：原先这里设了 pointer-events:none（整卡点击不弹详情、防误操作），
        现按需求放开——横向滑动不会误触发 click（滑动中浏览器不派发 click），
        且单击动作只是“定位”，即使误触也无破坏性。
   仅 ≤900px 生效；PC 端本就可点，行为一致。
   ============================================================== */
@media (max-width: 900px) {
  .rt-side .target-list > .target-item { pointer-events: auto !important; }
  .rt-side .target-list > .target-item .mini-btn { pointer-events: auto !important; }
}

/* ==============================================================
   点位分布检索栏里的"时间弹层"：把历史空情同款样式复制一份到 .points-bar 作用域
   （原样式被限定在 .case-filter 里，点位栏不是该容器，导致无样式）
   ============================================================== */
.points-bar .cf .case-range-menu input, .points-bar .cf .case-range-menu select { flex: 1; min-width: 0; width: auto; padding: 5px 7px; border: 1px solid var(--line); border-radius: 5px; font-size: 12px; background: #fff; box-shadow: none; }

/* ==============================================================
   点位时间弹层：宽度/定位约束
   （.case-range-pop 原为 width:100% + 按钮 width:100%，那是给历史空情整行布局用的；
     点位检索栏是 flex 多列布局，必须收窄，否则会独占一整行、看着像"乱码/错位"）
   ============================================================== */
.points-bar .case-range-pop { width: auto !important; flex: 0 0 auto !important; position: relative !important; }
.points-bar .case-range-btn { width: auto !important; min-width: 96px !important; max-width: 168px !important; white-space: nowrap !important; height: 30px !important; }
.points-bar .case-range-btn > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.points-bar .case-range-menu { z-index: 4000 !important; }
/* 手机端：检索栏 2 列排布时也放得下 */
@media (max-width: 900px) {
  .points-bar .case-range-pop { width: 100% !important; }
  .points-bar .case-range-btn { width: 100% !important; max-width: none !important; }
}

/* ==============================================================
   点位分布检索栏：统一美化（仅作用 .points-bar，PC/手机均生效，不影响历史空情）
   目标：控件同高同宽、间距均匀、底部对齐、标题加粗、交互态统一
   ============================================================== */
.points-bar {
  display: flex !important;
  flex-wrap: wrap !important;
  align-items: flex-end !important;      /* 有标题的列与无标题的控件底部对齐 */
  gap: 8px 14px !important;
  padding: 12px 14px !important;
  background: #fff !important;
  border-bottom: 1px solid #e6ecf3 !important;
}
.points-bar > * { margin: 0 !important; }
/* 标题：加粗、加深，带小间距 */
.points-bar > label,
.points-bar .cf > label,
.points-bar label {
  display: block !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  color: #475569 !important;
  letter-spacing: .2px !important;
  margin: 0 0 5px 0 !important;
  line-height: 1.2 !important;
}
/* 输入框 / 下拉：同高、同圆角、同边框、同字号 */
.points-bar select,
.points-bar input[type="text"],
.points-bar input:not([type]):not([type="hidden"]),
.points-bar input[type="datetime-local"] {
  height: 34px !important;
  min-height: 34px !important;
  padding: 0 10px !important;
  font-size: 13px !important;
  line-height: 32px;
  color: #0f172a !important;
  background: #fff !important;
  border: 1px solid #d7dee8 !important;
  border-radius: 8px !important;
  box-shadow: 0 1px 2px rgba(15,23,42,.04) !important;
  outline: none !important;
  transition: border-color .15s, box-shadow .15s !important;
}
.points-bar select:hover, .points-bar input:hover { border-color: #b9c6d6 !important; }
.points-bar select:focus, .points-bar input:focus {
  border-color: #2563eb !important;
  box-shadow: 0 0 0 3px rgba(37,99,235,.12) !important;
}
/* 时间弹层触发按钮：与其它控件同高同款 */
.points-bar .case-range-btn {
  height: 34px !important;
  padding: 0 10px !important;
  font-size: 13px !important;
  color: #0f172a !important;
  background: #fff !important;
  border: 1px solid #d7dee8 !important;
  border-radius: 8px !important;
  box-shadow: 0 1px 2px rgba(15,23,42,.04) !important;
  transition: border-color .15s, box-shadow .15s !important;
}
.points-bar .case-range-btn:hover { border-color: #b9c6d6 !important; }
.points-bar .case-range-btn i { color: #94a3b8 !important; font-size: 11px !important; }
/* 操作按钮：统一高度与圆角，主按钮强调 */
.points-bar button:not(.case-range-btn),
.points-bar .btn {
  height: 34px !important;
  padding: 0 14px !important;
  font-size: 13px !important;
  border-radius: 8px !important;
  white-space: nowrap !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 4px !important;
}
.points-bar .btn.primary,
.points-bar button.primary {
  background: #2563eb !important;
  border-color: #2563eb !important;
  color: #fff !important;
  box-shadow: 0 2px 6px rgba(37,99,235,.28) !important;
}
.points-bar .btn.primary:hover { background: #1d4ed8 !important; border-color: #1d4ed8 !important; }
/* 手机端：控件撑满所在网格单元 */
@media (max-width: 900px) {
  .points-bar { gap: 8px 10px !important; padding: 10px 12px !important; }
  .points-bar select,
  .points-bar input[type="text"],
  .points-bar input:not([type]):not([type="hidden"]),
  .points-bar .case-range-pop,
  .points-bar .case-range-btn,
  .points-bar button:not(.case-range-btn) { width: 100% !important; max-width: none !important; }
}

/* ==============================================================
   点位分布检索栏：标题居中 + 整体紧凑（覆盖前面的美化段）
   ============================================================== */
.points-bar {
  gap: 6px 8px !important;          /* 行 6px、列 8px，明显更紧凑 */
  padding: 10px 12px !important;
}
.points-bar .cf {
  display: flex !important;
  flex-direction: column !important;
  justify-content: flex-end !important;
  margin: 0 !important;
}
/* 标题：居中（原来靠左，看着不在控件中间） */
.points-bar .cf > label,
.points-bar > label,
.points-bar label {
  text-align: center !important;
  display: block !important;
  width: 100% !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  color: #475569 !important;
  margin: 0 0 4px 0 !important;
  line-height: 16px !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}
/* 单元格内的控件占满该格宽度 */
.points-bar .cf > select,
.points-bar .cf > input,
.points-bar .cf > .case-range-pop { width: 100% !important; }
/* 按钮组：与其它单元格同基线 */
.points-bar .cf-acts { flex: 0 0 auto !important; }
.points-bar .cf-acts > label { visibility: hidden; }   /* 占位，保证按钮与控件底部对齐 */
.points-bar .cf-acts-row { display: flex !important; align-items: center !important; gap: 6px !important; }
.points-bar .cf-acts-row .btn { height: 34px !important; padding: 0 12px !important; font-size: 13px !important; border-radius: 8px !important; }
@media (max-width: 900px) {
  .points-bar { gap: 8px 8px !important; }
}

/* ==============================================================
   点位检索栏：时间格与其按钮对齐（第一格原为 170px 而按钮仅 ~130px
   → 按钮未填满格子，标题居中在格子上看着偏、格间距显得大）
   ============================================================== */
.points-bar .cf-range { flex: 0 0 132px !important; }
.points-bar .cf-range .case-range-pop { width: 100% !important; }
.points-bar .cf-range .case-range-btn {
  width: 100% !important;
  max-width: none !important;
  min-width: 0 !important;
  justify-content: space-between !important;
  padding: 0 8px !important;
}
.points-bar .cf-range .case-range-btn > span { flex: 1 1 auto; text-align: left; overflow: hidden; text-overflow: ellipsis; }
/* 目标是：所有格子间距一致，且标题都居中在控件正上方 */
.points-bar { gap: 6px 8px !important; }

/* ==============================================================
   点位检索栏：统一格宽（所有单元格等宽）
   原因：之前每格 flex-basis 不同（104~132px），格宽不齐 →
         间隔看着不一致、标题相对控件也显得没居中。
   ============================================================== */
.points-bar { gap: 6px 8px !important; align-items: flex-end !important; }
.points-bar .cf { flex: 0 0 118px !important; min-width: 0 !important; }
.points-bar .cf-range { flex: 0 0 128px !important; }          /* 时间（按钮+箭头略宽） */
.points-bar .cf:has(#ptSn) { flex: 0 0 152px !important; }     /* 目标标识（输入框略宽） */
.points-bar .cf-acts { flex: 0 0 auto !important; }
/* 所有控件填满各自格子，标题才能真正居中在控件上方 */
.points-bar .cf > select,
.points-bar .cf > input,
.points-bar .cf > .case-range-pop { width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; }
.points-bar .cf > label { text-align: center !important; width: 100% !important; }
@media (max-width: 900px) {
  .points-bar .cf, .points-bar .cf-range, .points-bar .cf:has(#ptSn) { flex: 1 1 calc(50% - 8px) !important; }
  .points-bar .cf-acts { flex: 1 1 100% !important; }
}

/* ==============================================================
   #ptsBar 用 Grid 固定列宽 —— 彻底解决"列宽不齐 / 间隔不一致 / 标题不居中"
   之前的 flex-basis 会被页面自带的检索栏样式（含 grid）覆盖，怎么调都不齐；
   Grid 固定列宽 + 固定 gap 可保证：每列等宽（个别列指定更宽）、列间距完全一致。
   顺序：时间范围 / 目标标识 | 目标类型 飞行高度 案件性质 空域性质 行政区划 探测设备 管辖单位 | 按钮组
   ============================================================== */
#ptsBar {
  display: grid !important;
  grid-template-columns: 128px 152px repeat(7, 120px) auto !important;
  gap: 6px 8px !important;
  align-items: end !important;
  justify-content: start !important;
  padding: 10px 12px !important;
}
#ptsBar > .cf { display: flex !important; flex-direction: column !important; min-width: 0 !important; width: auto !important; }
#ptsBar > .cf > label {
  display: block !important;
  width: 100% !important;
  text-align: center !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  color: #475569 !important;
  margin: 0 0 5px 0 !important;
  line-height: 16px !important;
}
#ptsBar > .cf > select,
#ptsBar > .cf > input,
#ptsBar > .cf > .case-range-pop { width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; }
#ptsBar > .cf-acts { grid-column: auto !important; }
@media (max-width: 900px) {
  #ptsBar { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  #ptsBar > .cf-acts { grid-column: 1 / -1 !important; }
}

/* ==============================================================
   #ptsBar 禁止单元格被内容撑宽（Grid 列里某项 min-content 过大会把整列撑开，
   导致该列与相邻列的"间隔"看起来不一致；SN 输入框就是这种）
   ============================================================== */
#ptsBar, #ptsBar * { min-width: 0 !important; box-sizing: border-box !important; }
#ptsBar > .cf { overflow: visible !important; }
#ptsBar > .cf > label,
#ptsBar > .cf > select,
#ptsBar > .cf > input,
#ptsBar > .cf > .case-range-pop,
#ptsBar > .cf > .case-range-pop > .case-range-btn {
  width: 100% !important;
  max-width: 100% !important;
  min-width: 0 !important;
  box-sizing: border-box !important;
}
#ptsBar > .cf > select { width: 100% !important; }
/* 兜底：除"目标标识/按钮组"外，任何列都被限制在 120px 内，防止被内容撑开 */
#ptsBar > .cf:not(.cf-range):not(.cf-acts):not(:has(#ptSn)) { max-width: 120px !important; }
#ptsBar > .cf:has(#ptSn) { max-width: 152px !important; }
#ptsBar > .cf-range { max-width: 128px !important; }
/* 文字不被压成两行 */
#ptsBar > .cf > select, #ptsBar > .cf > input { white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; }

/* ==============================================================
   检索栏显隐交还给 .open（修复手机端"收起"失效）
   原因：后面美化时写的 #ptsBar{display:grid !important}（ID 选择器）优先级高于系统原本的
        .points-bar.mining-bar{display:none !important} → 任何状态都显示，收起键无效。
   ============================================================== */
@media (max-width: 900px) {
  #ptsBar { display: none !important; }
  #ptsBar.open { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  #ptsBar.open > .cf-acts { grid-column: 1 / -1 !important; }
}
@media (min-width: 901px) {
  #ptsBar { display: grid !important; }
}

/* 点位分布 · 检索概要（常驻显示，清除时一起清） */
.pt-summary {
  position: absolute; left: 12px; top: 12px; z-index: 900;
  background: rgba(255,255,255,.96); border: 1px solid var(--line, #e2e8f0);
  border-radius: 10px; box-shadow: 0 4px 16px rgba(15,23,42,.14);
  padding: 10px 12px; min-width: 200px; max-width: 78vw; pointer-events: none;
  font-size: 12px; line-height: 1.65; color: var(--text, #0f172a);
}
.pt-summary .pts-hd { font-weight: 600; font-size: 12.5px; margin-bottom: 4px; color: #1d4ed8; }
.pt-summary .pts-line { white-space: nowrap; }
.pt-summary .pts-dim { color: var(--muted, #64748b); font-size: 11.5px; }
@media (max-width: 900px) {
  .pt-summary { left: 8px; top: 8px; padding: 8px 10px; font-size: 11.5px; max-width: 88vw; }
}

/* ==============================================================
   检索概要：位置改到【左下、地图图层按钮上方】；加强背景，醒目
   （原因：原来在左上角盖住了菜单，且背景太淡不显眼）
   ============================================================== */
.pt-summary {
  position: absolute !important;
  left: 12px !important;
  top: auto !important;
  bottom: 58px !important;              /* 抬高到图层按钮（底部约 44px）之上 */
  z-index: 1200 !important;
  background: #ffffff !important;        /* 实底，醒目 */
  border: 1px solid #cbd5e1 !important;
  border-left: 4px solid #2563eb !important;   /* 蓝色标识条 */
  border-radius: 10px !important;
  box-shadow: 0 8px 24px rgba(15,23,42,.22) !important;
  padding: 10px 14px !important;
  min-width: 210px; max-width: 78vw;
  pointer-events: none;
  font-size: 12.5px; line-height: 1.7;
  color: #0f172a;
  opacity: 1 !important;
}
.pt-summary .pts-hd { font-weight: 700; font-size: 13.5px; margin-bottom: 5px; color: #1d4ed8; letter-spacing: .3px; }
.pt-summary .pts-line b { color: #b91c1c; font-size: 14px; }
.pt-summary .pts-dim { color: #64748b; font-size: 11.5px; }
@media (max-width: 900px) {
  .pt-summary { left: 8px !important; bottom: 52px !important; padding: 8px 10px !important; font-size: 11.5px; max-width: 84vw; }
  .pt-summary .pts-hd { font-size: 12.5px; }
}

/* 态势总览 KPI 下钻弹框：今日飞行批次 / 今日发现目标 */
.dd-wrap { font-size: 13px; }
.dd-count { padding: 0 2px 10px; color: #334155; }
.dd-count b { color: #0f172a; font-size: 15px; }
.dd-real { font-weight: 600; }
.dd-real.ok { color: #16a34a; }
.dd-real.no { color: #dc2626; }
.dd-link { color: #2563eb; text-decoration: none; cursor: pointer; }
.dd-link:hover { text-decoration: underline; }
.dd-mapbtn { white-space: nowrap; }
/* 「点位上图」弹窗：大图 + 返回列表 */
.modal.ddmap .modal-body { padding: 0; overflow: hidden !important; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
/* ★态势总览下钻「点位上图」（点位多）→ PC 用更大的地图弹窗；手机≤900px 仍沿用原有的满屏弹窗（不横向溢出、触控友好） */
@media (min-width: 901px) {
  .modal.ddmap.ddmap-big { width: min(1560px, 97vw); height: 94vh; max-height: 94vh; }
}
.ddmap-wrap { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.ddmap-bar { display: flex; align-items: center; gap: 10px; padding: 9px 14px; border-bottom: 1px solid #e2e8f0; flex: 0 0 auto; }
.ddmap-info { color: #475569; font-size: 13px; }
.ddmap-box { position: relative; overflow: hidden; flex: 1 1 auto; min-height: 0; width: 100%; }
.dd-hint { display: none; }
@media (max-width: 900px) { .dd-hint { display: inline; margin-left: 8px; color: #94a3b8; font-size: 11.5px; font-weight: 400; } }
.dd-scroll { max-height: 62vh; overflow: auto; -webkit-overflow-scrolling: touch; }
/* 下钻弹框用 xwide 宽度以容纳整行；高度随内容收缩，不强制 92vh */
.modal.xwide:has(.dd-wrap) { height: auto; max-height: 90vh; }
.dd-tbl { width: 100%; border-collapse: collapse; }
.dd-tbl th { position: sticky; top: 0; background: #f1f5f9; color: #475569; font-weight: 600; text-align: left; padding: 9px 10px; border-bottom: 1px solid #e2e8f0; white-space: nowrap; }
.dd-tbl td { padding: 9px 10px; border-bottom: 1px solid #eef2f7; color: #1e293b; white-space: nowrap; }
.dd-tbl tbody tr:hover { background: #f8fafc; }
/* ★§106 弹窗表格：实名过长折行显示（限宽 + 居中，不拉长整列/撑宽弹窗）
   ⚠ 仅 PC：手机端表格是「固定最小宽 + 左右滑动」，格子很窄，折行会把行高撑得很高 */
@media (min-width: 901px) {
.modal-body .dd-realbox {
  display: inline-block;
  max-width: 122px;
  white-space: normal;
  word-break: break-word;
  overflow-wrap: anywhere;
  line-height: 1.35;
  text-align: center;
  vertical-align: middle;
}
.modal-body .dd-realbox .dd-link,
.modal-body .dd-realbox .dd-real { display: inline; white-space: normal; }
}

/* ===== 点位图弹窗：卫星图切换 + 点位详情卡片 ===== */
.ddmap-wrap { position: relative; }
.ddpt-card { position: absolute; left: 14px; bottom: 14px; width: 306px; max-height: calc(100% - 28px); display: none; background: #fff; border: 1px solid #e2e8f0; border-radius: 10px; box-shadow: 0 10px 30px rgba(15,23,42,.22); z-index: 50; overflow: hidden; }
.ddpt-head { display: flex; align-items: center; justify-content: space-between; padding: 9px 12px; font-weight: 700; font-size: 13.5px; color: #0f172a; background: #f8fafc; border-bottom: 1px solid #eef2f7; }
.ddpt-x { background: none; border: none; font-size: 15px; line-height: 1; color: #64748b; cursor: pointer; padding: 2px 4px; }
.ddpt-x:hover { color: #0f172a; }
.ddpt-body { padding: 8px 12px 11px; overflow: auto; max-height: 46vh; }
.ddpt-row { display: flex; gap: 8px; font-size: 13px; line-height: 1.7; color: #1e293b; }
.ddpt-row b { flex: 0 0 46px; color: #64748b; font-weight: 600; }
.ddpt-row > span { flex: 1 1 auto; word-break: break-all; }
.ddpt-dim { color: #94a3b8; font-weight: 400; }
.ddpt-src { margin-left: 8px; font-size: 12px; }
.ddpt-nav { display: flex; gap: 8px; margin-top: 9px; flex-wrap: wrap; }
.ddpt-nav a { font-size: 12.5px; color: #2563eb; text-decoration: none; border: 1px solid #dbeafe; background: #eff6ff; border-radius: 6px; padding: 3px 9px; }
.ddpt-nav a:hover { background: #dbeafe; }
.ddpt-actions { margin-top: 10px; }
.ddpt-copybtn { width: 100%; }
/* 点位图圆点（复用实时探测光晕图）+ 弹窗标题栏右侧动作按钮 */
.dd-dot-img { display: block; }
#modalTitle { flex: 1 1 auto; min-width: 0; }
.mh-flex { display: flex; align-items: center; gap: 10px; width: 100%; min-width: 0; }
.mh-txt { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mh-flex .btn { flex: 0 0 auto; margin-right: 18px; }
@media (max-width: 900px) {
  .ddmap-bar { flex-wrap: wrap; row-gap: 6px; }
  .ddpt-card { left: 8px; right: 8px; bottom: 8px; width: auto; max-height: 60%; }
  .ddpt-body { max-height: none; }
}

/* ==============================================================
   轨迹回放（手机端）：铺满整屏 + 把高度让给地图
   现象（实测 390×844）：.pb-page 高度写成 calc(100vh - 50px)，
        又叠加了 70px 底部内边距（那是给早已改成“滑出式”的底部导航预留的），
        于是屏幕下部空出约 89px；而且内容总高超出容器 → 地图被压在 min-height 260px。
   做法：高度按可视高度铺满、底部只留 8px + 安全区；头部信息与按钮区收紧、
        操作按钮两列排列，省下来的高度全部给地图（flex 撑满）。
   仅 ≤900px 生效，PC 端完全不变。
   ============================================================== */
@media (max-width: 900px) {
  .pb-page {
    height: calc(100vh - 8px) !important;
    height: calc(100dvh - 8px) !important;
    max-height: none !important;
    padding: 8px 8px calc(8px + var(--sa-bottom, 0px)) !important;
    gap: 6px !important;
  }
  /* 头部信息块：收紧内边距 / 间距 / 字号 */
  .pb-head { padding: 8px 10px !important; gap: 5px 8px !important; border-radius: 10px !important; }
  .pb-title { font-size: 14px !important; gap: 6px !important; }
  .pb-meta { font-size: 12px !important; gap: 4px 6px !important; }
  .pb-meta > span { padding: 2px 7px !important; }
  .pb-real { font-size: 13px !important; margin-top: 2px !important; }
  /* 播放控制区：收紧 */
  .pb-controls { padding: 6px 10px !important; border-radius: 10px !important; }
  .pb-controls .playbar { margin-bottom: 6px !important; gap: 6px !important; }
  .pb-actions { gap: 6px !important; margin-top: 6px !important; }
  /* 操作按钮：两列铺排（避免参差不齐的多行），高度略收 */
  .pb-actions .btn { flex: 1 1 calc(50% - 3px) !important; min-height: 40px !important; padding: 0 8px !important; font-size: 13px !important; }
  /* 地图：吃掉剩余高度（放宽 min-height，避免被压成固定 260px） */
  .pb-map-wrap { flex: 1 1 auto !important; min-height: 200px !important; }
  /* 手机端隐藏地图左上角的「实时高度 / 时间」浮层：屏幕小、很占地方；
     高度与起止时间在头部信息块里已有（最高高度 / 起止），不影响使用。PC 端照常显示。 */
  .pb-alt { display: none !important; }
}

/* ==============================================================
   未来 7 天天气预报弹窗（态势总览「气象要素」点城市打开）
   配色沿用态势总览大屏：深蓝底 + 青色点缀，卡片底色直接复用 .wx-* 渐变
   ============================================================== */
.modal.wxweek {
  height: auto; max-height: 90vh; background: #050b1e;
  border: 1px solid rgba(56, 130, 246, .28); box-shadow: 0 18px 50px rgba(0, 0, 0, .55);
}
.modal.wxweek .modal-head {
  color: #e0f2fe; border-bottom: 1px solid rgba(56, 130, 246, .22);
  background: linear-gradient(160deg, rgba(15, 32, 64, .96), rgba(8, 18, 40, .96));
}
.modal.wxweek .modal-head .close { color: #8fb0d8; }
.modal.wxweek .modal-head .close:hover { color: #22d3ee; }
.modal.wxweek .modal-body {
  padding: 14px 16px;
  background:
    radial-gradient(900px 380px at 10% -10%, rgba(34, 211, 238, .14), transparent 60%),
    radial-gradient(760px 380px at 92% 0%, rgba(59, 130, 246, .14), transparent 60%),
    #050b1e;
}
.wxw-loading { color: #5b7aa8; font-size: 12.5px; text-align: center; padding: 26px 0; }
.wxw-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; font-size: 12.5px; color: #8fb0d8; }
.wxw-head b { color: #e0f2fe; }
.wxw-src { color: #5b7aa8; font-size: 11.5px; letter-spacing: .5px; }
.wxw-days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 10px; }
.wxw-day {
  position: relative; overflow: hidden; display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 11px 8px 9px; border-radius: 12px; border: 1px solid rgba(56, 130, 246, .18);
}
.wxw-day.today { border-color: rgba(34, 211, 238, .55); box-shadow: 0 0 18px rgba(34, 211, 238, .18); }
.wxw-dow { font-size: 12.5px; font-weight: 700; color: #e0f2fe; text-align: center; line-height: 1.25; position: relative; z-index: 1; }
.wxw-dow i { font-style: normal; display: block; font-size: 10.5px; color: #5b7aa8; font-weight: 600; }
.wxw-mid { display: flex; flex-direction: column; align-items: center; gap: 2px; position: relative; z-index: 1; }
.wxw-ic { font-size: 26px; line-height: 1; }
.wxw-cnd { font-size: 12px; color: #cfe3ff; white-space: nowrap; }
.wxw-temp { font-size: 15.5px; font-weight: 800; color: #e0f2fe; font-variant-numeric: tabular-nums; position: relative; z-index: 1; white-space: nowrap; }
.wxw-temp b { color: #e0f2fe; }
.wxw-temp span { color: #8fb0d8; font-weight: 600; margin-left: 6px; }
.wxw-extra { display: flex; flex-direction: column; align-items: center; gap: 2px; font-size: 11px; color: #8fb0d8; position: relative; z-index: 1; text-align: center; }
.wxw-rain { color: #7dd3fc; }
.wxw-sun { color: #5b7aa8; font-size: 10.5px; }
.wxw-day .wx-fly { transform: none; font-size: 12px; margin-top: 2px; position: relative; z-index: 1; }
/* 气象卡片可点击（态势总览里） */
.wx-click { cursor: pointer; transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; }
.wx-click:hover { transform: translateY(-1px); box-shadow: 0 6px 20px rgba(34, 211, 238, .22); border-color: rgba(34, 211, 238, .5); }
.wx-click:active { transform: translateY(0); }

@media (max-width: 900px) {
  /* 弹窗全屏：每天一行，阅读更舒服 */
  .modal.wxweek { max-height: 100dvh; }
  .modal.wxweek .modal-body { padding: 10px 12px calc(14px + var(--sa-bottom, 0px)); }
  .wxw-head { font-size: 12px; margin-bottom: 10px; }
  .wxw-days { grid-template-columns: 1fr; gap: 8px; }
  .wxw-day { flex-direction: row; align-items: center; gap: 8px; padding: 9px 10px; }
  .wxw-dow { flex: 0 0 54px; text-align: left; }
  .wxw-mid { flex: 1 1 auto; flex-direction: row; align-items: center; gap: 6px; }
  .wxw-ic { font-size: 22px; }
  .wxw-temp { flex: 0 0 auto; font-size: 15px; }
  .wxw-extra { flex: 0 0 auto; align-items: flex-end; gap: 1px; font-size: 10.5px; }
  .wxw-day .wx-fly { flex: 0 0 auto; font-size: 11.5px; margin-top: 0; }
}


/* ==============================================================
   ★ 弹窗内容自适应（仅 PC 端，2026-09-17）
   PC 端要求：一个弹窗内把内容完整显示出来，不再横向溢出、不把内容挤出框口；
   「违规情形」这类长文本（多条违规用「、」连成长串）在单元格内自动换行；
   按钮 / 标题 / 标注等排版保持原样（功能键文字不拆行、不变形）。
   手机端（≤900px）保持原有「表格不换行 + 左右滑动」，不挤压、不变形。
   ============================================================== */
@media (min-width: 901px) {
  /* --- 表格：宽度不超过弹窗，单元格内长文本自动换行 --- */
  .modal-body .table-wrap > table,
  .modal-body > table { width: 100%; min-width: 0; table-layout: auto; }
  .modal-body th, .modal-body td {
    white-space: normal;
    word-break: normal;
    overflow-wrap: break-word;
    vertical-align: top;
  }
  .modal-body th { white-space: nowrap; word-break: keep-all; overflow-wrap: normal; } /* 表头保持原样、不拆字 */
  .modal-body table .btn { white-space: nowrap; } /* 表格里的功能键文字保持整行 */
  /* --- 单元格内的标签 / 徽标：允许换行，且不超出父格 --- */
  .modal-body .tag, .modal-body .air-tag, .modal-body .warn-tag, .modal-body .bj-takeoff-tag,
  .modal-body .over-tag, .modal-body .ev-dist, .modal-body .real-tag, .modal-body .ck-air-tip {
    white-space: normal;
    max-width: 100%;
    overflow-wrap: anywhere;
  }
  /* --- 定义列表 / 位置块：值列可收缩换行，长地址不撑破弹窗 --- */
  .modal-body .dl { min-width: 0; }
  .modal-body .dl > * { min-width: 0; overflow-wrap: anywhere; word-break: break-word; }
  .modal-body .locblock, .modal-body .locrow > * { min-width: 0; overflow-wrap: anywhere; word-break: break-word; }
  /* --- 媒体 / 代码块 / 表单：自适应，不撑破弹窗 ---
         （注意：不碰 img/canvas/iframe —— 高德地图的瓦片与图层画布就是它们，
           任何 max-width/height 覆盖都可能造成地图图层错位，故此处只保留代码块与表单。） --- */
  .modal-body pre, .modal-body code { white-space: pre-wrap; word-break: break-word; }
  .modal-body input, .modal-body select, .modal-body textarea { max-width: 100%; box-sizing: border-box; }
}

/* ★ 无人机信息标签层（可拖动文字框 + 很细的连线指向机头尖；行政图/卫星图都清晰）
   文字排版：字号加大、笔画变细（字重 400）、开启字型反走样与几何精度渲染 → 清秀清晰；
   行序（用户指定）：空域性质 / 高度·最高 / 速度·最快 / 位置 / 实名（＋时长·批次，无数据时不显示） */
.uav-lbl-layer { position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; pointer-events: none; z-index: 130; }
.uav-lbl-lines { position: absolute; left: 0; top: 0; overflow: visible; }
.uav-lbl { position: absolute; left: 0; top: 0; pointer-events: auto; touch-action: none; }
/* ★文字框按等级着色（2026-09-19）：默认深红底（违规）；合规（绿）单独用绿色底 + 深绿按钮 */
.uav-lbl.lv-green .uav-lbl-in { background: rgba(22,163,74,.80); }
.uav-lbl.lv-green .uav-lbl-btn { background: #14532d; }
.uav-lbl.lv-green .uav-lbl-btn:hover { background: #1a6b3a; border-color: #fff; }
.uav-lbl.lv-green .uav-lbl-btn:active { background: #0f3d21; }
/* ★2026-09-19 深夜补充（用户要求：文字框与飞机图标同色）：
   报备（白名单）目标的飞机图标是青色 LEVELS.white #0891b2 → 文字框也改青色（原来错用深红底）；
   无效（gray）目标当前不显示文字框（uavLabelItems 已过滤 level==='gray'），此条仅为规则完整 */
.uav-lbl.lv-white .uav-lbl-in { background: rgba(8,145,178,.82); }
.uav-lbl.lv-white .uav-lbl-btn { background: #0e7490; }
.uav-lbl.lv-white .uav-lbl-btn:hover { background: #155e75; border-color: #fff; }
.uav-lbl.lv-white .uav-lbl-btn:active { background: #0c4a6e; }
/* ★2026-09-21 报备（紫）与报备违规（红）的文字框底色：与飞机图标同色，且与白名单（青）、合规（绿）区分 */
.uav-lbl.lv-frep .uav-lbl-in { background: rgba(124,58,237,.84); }
.uav-lbl.lv-frep .uav-lbl-btn { background: #5b21b6; }
.uav-lbl.lv-frep .uav-lbl-btn:hover { background: #6d28d9; border-color: #fff; }
.uav-lbl.lv-frep .uav-lbl-btn:active { background: #4c1d95; }
.uav-lbl.lv-frepbad .uav-lbl-in { background: rgba(185,28,28,.86); }
.uav-lbl.lv-frepbad .uav-lbl-btn { background: #7f1d1d; }
.uav-lbl.lv-frepbad .uav-lbl-btn:hover { background: #991b1b; border-color: #fff; }
.uav-lbl.lv-frepbad .uav-lbl-btn:active { background: #601313; }
.uav-lbl.lv-gray .uav-lbl-in { background: rgba(107,114,128,.88); }
.uav-lbl.lv-gray .uav-lbl-btn { background: #4b5563; }
.uav-lbl.lv-gray .uav-lbl-btn:hover { background: #6b7280; border-color: #fff; }
.uav-lbl.lv-gray .uav-lbl-btn:active { background: #374151; }
.uav-lbl-in { display: inline-block; background: rgba(180,26,32,.78); border: 1px solid rgba(255,255,255,.95); border-radius: 7px;
  padding: 3px 8px 4px; color: #fff; font-size: 12px; line-height: 16px; font-weight: 400; letter-spacing: .2px;
  font-family: 'PingFang SC', 'Microsoft YaHei', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
  white-space: nowrap; text-align: left; text-shadow: 0 .5px 1px rgba(0,0,0,.30);
  box-shadow: 0 1px 4px rgba(0,0,0,.35); cursor: grab;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility;
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.uav-lbl.dragging .uav-lbl-in { cursor: grabbing; box-shadow: 0 2px 8px rgba(0,0,0,.5); }
.uav-lbl-r { display: block; white-space: nowrap; }
.uav-lbl-r.air { font-weight: 500; letter-spacing: .4px; }
.uav-lbl-r.real { font-weight: 500; }
.uav-lbl-r.dim { font-size: 11px; line-height: 14px; opacity: .9; }
/* ★2026-09-21 报备人/单位行：在报备（紫）文字框里用淡紫白字加粗，一眼能认出是报备机 */
.uav-lbl-r.frep { font-weight: 600; color: #f3e8ff; }
.uav-lbl-r1 { display: block; font-weight: 500; }
.uav-lbl-r2 { display: block; font-weight: 400; }


/* ★ 无人机文字框末行的「派警」按钮（在「飞行时长 · 批次」文本右侧，不另起一行）
   配色：白字 + 文字框同色系的深红实底（比框底色 rgba(180,26,32,.78) 更深一档），白描边，整体协调 */
.uav-lbl-r.has-btn { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.uav-lbl-r.has-btn .uav-lbl-t { flex: 0 1 auto; }
.uav-lbl-btn { flex: 0 0 auto; padding: 1px 7px; font: inherit; font-size: 11px; line-height: 14px; font-weight: 600;
  color: #fff; background: #7d1113; border: 1px solid rgba(255,255,255,.55); border-radius: 5px; cursor: pointer;
  letter-spacing: .2px; text-shadow: 0 .5px 1px rgba(0,0,0,.35);
  transition: background .15s ease, border-color .15s ease; }
.uav-lbl-btn:hover { background: #9b171b; border-color: #fff; }
.uav-lbl-btn:active { background: #610d0f; transform: translateY(1px); }

/* ★2026-09-20 实时目标文字框：末行「派警」左侧的星标（与「历史空情」序号旁星标同一份数据 flights.focus）
   交互与历史空情一致（默认空心☆，点击变实心★，再点恢复，点一次就落库、后台可按「重点关注」筛出）；
   样式：**不要外圈**，只要正五角星；靠「空心暗白☆ ↔ 实心亮金★（带暗描边、略放大）」区分两种状态 */
/* ★星号本体：**不要外圈**，只要正五角星（用户 2026-09-19 深夜指定）——
   区分选中/未选靠三件事叠加：字形（空心☆ / 实心★）+ 明暗（暗白 / 亮金）+ 大小（实心时略放大）；
   另加暗描边/投影，保证在深红、青、墨绿底上都清晰 */
.uav-lbl-star { display: inline-block; padding: 0 2px; font-size: 15px; line-height: 15px;
  color: rgba(255,255,255,.62); cursor: pointer; user-select: none; -webkit-user-select: none;
  text-shadow: 0 1px 2px rgba(0,0,0,.65);
  transition: color .12s ease, text-shadow .12s ease, transform .12s ease; }
.uav-lbl-star:hover { color: #fff; transform: scale(1.16); }
.uav-lbl-star.on { color: #fbbf24; transform: scale(1.18);
  text-shadow: -1px 0 0 rgba(74,37,0,.9), 1px 0 0 rgba(74,37,0,.9), 0 -1px 0 rgba(74,37,0,.9), 0 1px 0 rgba(74,37,0,.9), 0 0 5px rgba(0,0,0,.8); }
.uav-lbl-star.on:hover { color: #fcd34d; }
/* 只放行「布局」属性（右侧靠拢、与派警同排），不重复写颜色 */
.uav-lbl-r.has-btn .uav-lbl-star { flex: 0 0 auto; margin-left: auto; margin-right: -1px; }
/* 手机端：星标放大（手指点得准） */
@media (max-width: 900px) {
  .uav-lbl-star { font-size: 19px; line-height: 19px; padding: 0 4px; }
  .uav-lbl-r.has-btn .uav-lbl-star { margin-right: -2px; }
}

/* ★点位分布「管辖单位」：可输入检索的下拉（2026-09-19）
   收起时与旁边下拉同宽同高；展开后第一栏就是检索输入框，下面实时筛选派出所 */
.ssel { position: relative; width: 100%; }
.ssel-txt { width: 100%; box-sizing: border-box; padding: 8px; border: 1px solid var(--line); border-radius: 6px;
  font-size: 13px; background: #fff; color: var(--text); cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ssel-txt::after { content: '▾'; float: right; color: var(--muted); margin-left: 6px; }
.ssel-pop { position: absolute; left: 0; top: calc(100% + 4px); width: 240px; z-index: 60; background: #fff;
  border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 10px 24px rgba(15,23,42,.18); display: none; overflow: hidden; }
.ssel.open .ssel-pop { display: block; }
.ssel-kw { display: block; width: 100%; box-sizing: border-box; padding: 8px; border: 0; border-bottom: 1px solid var(--line);
  font-size: 13px; outline: none; background: #fff; color: var(--text); }
.ssel-kw::placeholder { color: var(--muted); }
.ssel-list { max-height: 240px; overflow: auto; }
.ssel-item { padding: 7px 10px; font-size: 13px; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--text); }
.ssel-item:hover { background: rgba(37,99,235,.10); }
.ssel-item.on { background: rgba(37,99,235,.16); font-weight: 600; }
.ssel-p { color: var(--muted); }
.ssel-empty { padding: 10px; font-size: 12px; color: var(--muted); }
@media (max-width: 900px) {
  .ssel-txt { font-size: 16px; }
  .ssel-pop { position: static; width: 100%; margin-top: 4px; box-shadow: none; }
  .ssel-kw { font-size: 16px; }
  .ssel-item { font-size: 14px; white-space: normal; line-height: 1.35; }
}

/* ★2026-09-20 历史空情「重点关注」：序号旁的星标（默认线轮廓☆，点击变红实心★）+ 整行浅色底 */
.ca-no { white-space: nowrap; }
.ca-star { display: inline-block; min-width: 15px; margin-right: 3px; font-size: 14px; line-height: 1; color: #94a3b8;
  cursor: pointer; user-select: none; -webkit-user-select: none; transition: color .12s ease, transform .12s ease; }
.ca-star:hover { color: #ef4444; transform: scale(1.18); }
.ca-star.on { color: #ef4444; }
tr.ca-focus, tr.ca-focus > td { background: #fef7e6; }
/* ★2026-09-23 历史空情表格：整行所有列内容上下居中 */
#caTbody td { vertical-align: middle; }
tr.ca-focus:hover, tr.ca-focus:hover > td { background: #fdefd3; }

/* ============================================================================
   ★2026-09-21 飞行报备 · 新增/修改表单重排
     用户反馈：要填的东西本来就多，但看着不清晰；填写的文字与标题栏/标签很相近，整体不舒服。
     做法：① 按语义分 5 组，组标题＝编号圆牌 + 标题 + 分隔线（与字段标签彻底拉开层次）；
           ② 组内用 CSS 栅格对齐（PC 2~3 列，手机 1 列），不再是一坨同质行；
           ③ 标签＝11.5px 半粗灰字 #64748b；值＝白底深字 13.5px 中黑 #0f172a，
             输入框描边加深到 #cbd5e1 + 聚焦蓝色光圈，占位符更浅 → 标签与内容一眼分得开；
           ④ 有效期 / 每日时段做成"起 至 止"一体控件，紧凑且语义清楚；
           ⑤ 底部操作条常驻（sticky），必填项红色星号 + 左下角"* 为必填项"说明。
   ============================================================================ */
.fr-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; padding: 2px 0 0; }
.fr-form > .span2 { grid-column: 1 / -1; }
.fr-grp { min-width: 0; background: #fff; border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px 14px; box-shadow: 0 1px 2px rgba(15,23,42,.04); }
.fr-gt { display: flex; align-items: center; gap: 7px; margin: 0 0 11px; padding-bottom: 8px; border-bottom: 1px solid #eef2f7; font-size: 13.5px; font-weight: 700; color: #0f172a; }
.fr-gt i { flex: 0 0 auto; width: 19px; height: 19px; border-radius: 50%; background: #e8efff; color: #1d4ed8; font-size: 11.5px; font-weight: 700; font-style: normal; display: inline-flex; align-items: center; justify-content: center; }
.fr-gt-tip { font-size: 11.5px; font-weight: 400; color: var(--muted); }
.fr-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 11px 12px; }
.fr-grid.c3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.fr-f.sp2 { grid-column: span 2; }
.fr-f > span { font-size: 11.5px; font-weight: 600; color: #64748b; letter-spacing: .3px; }
.fr-f input, .fr-f select { width: 100%; box-sizing: border-box; background: #fff; border: 1px solid #cbd5e1; color: #0f172a; border-radius: 7px; padding: 7px 9px; font-size: 13.5px; font-weight: 500; outline: none; transition: border-color .15s, box-shadow .15s; }
.fr-f input::placeholder { color: #9aa8bb; font-weight: 400; }
.fr-f input:focus, .fr-f select:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(37,99,235,.13); }
.fr-req { color: #dc2626; font-style: normal; margin-left: 3px; }
.fr-hint { font-size: 10.5px; line-height: 1.45; color: #94a3b8; font-style: normal; }
.fr-range { display: flex; align-items: center; gap: 6px; }
.fr-range em { flex: 0 0 auto; font-style: normal; font-size: 12px; color: #94a3b8; }
.fr-range input { flex: 1 1 0; min-width: 0; }
.fr-sub2 { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; margin: 13px 0 7px; font-size: 12.5px; font-weight: 600; color: #334155; }
.fr-gt + .fr-sub2 { margin-top: 0; }
.fr-sub2 span { font-size: 11.5px; font-weight: 400; color: var(--muted); }
.fr-grp .fr-sta-bar { margin-bottom: 7px; }
.fr-grp .fr-chips { background: #f8fafc; }
.fr-grp .fr-inp, .fr-grp .fr-coords { border-color: #cbd5e1; }
.fr-reqnote { font-size: 12px; color: var(--muted); }
.fr-reqnote .fr-req { margin: 0 3px 0 0; }
.fr-tip { border-style: solid; border-color: #fcd34d; border-left: 4px solid #f59e0b; color: #78350f; }
.fr-foot { position: sticky; bottom: 0; z-index: 3; background: #fff; padding: 10px 0 4px; border-top: 1px solid var(--line); }
@media (max-width: 900px) {
  .fr-form, .fr-grid, .fr-grid.c3 { grid-template-columns: 1fr; }
  .fr-f.sp2 { grid-column: auto; }
  .fr-grp { padding: 10px 11px 12px; }
  .fr-gt { font-size: 13px; }
}

/* ★2026-09-21 飞行区域「三选一」：分段选择器 + 只显示选中的填写面板
   （原来三种方式全铺一排，容易被误认为都要填） */
.fr-seg { display: flex; gap: 4px; flex-wrap: wrap; background: #f1f5f9; border: 1px solid var(--line); border-radius: 9px; padding: 3px; margin-bottom: 12px; }
.fr-seg button { flex: 1 1 auto; min-width: 132px; border: 0; background: transparent; color: #475569; font-size: 12.5px; font-weight: 600; padding: 7px 10px; border-radius: 7px; cursor: pointer; transition: background .15s, color .15s, box-shadow .15s; }
.fr-seg button:hover { color: #1d4ed8; }
.fr-seg button.on { background: #fff; color: #1d4ed8; box-shadow: 0 1px 3px rgba(15,23,42,.14); }
.fr-pane { min-width: 0; }
.fr-pane > .fr-sub2:first-child { margin-top: 0; }
@media (max-width: 900px) { .fr-seg button { min-width: 0; flex: 1 1 100%; text-align: left; padding: 9px 10px; } }

/* ============================================================================
   ★2026-09-21 飞行报备表单：让 5 步「一眼分得开、填得顺」
     用户反馈：步与步区分不明显（尤其 3、4 步容易搞混）、字段标题不明显、步数不清晰；
               可以加颜色元素但必须协调。
     做法：① 每步一个专属主色（与全站已有语义色同族：蓝/青/紫/琥珀/绿），
             同一个色只用在三处——左侧色条、标题色带、编号圆牌 —— 协调又有区分度；
           ② 标题做成**色带**（浅色底 + 底边线 + 右上角「第 N 步」），步与步之间一眼断开；
           ③ 顶部加**步骤导航条**：1 2 3 4 5 可点击跳转并短暂高亮，长表单不再迷路；
           ④ 字段标题加深加重（12px/700/#334155），与输入内容层次拉开。
   ============================================================================ */
.fr-steps { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; padding: 7px 9px; background: #f8fafc; border: 1px solid var(--line); border-radius: 10px; }
.fr-steps button { display: inline-flex; align-items: center; gap: 5px; border: 0; background: transparent; color: #475569; font-size: 12px; font-weight: 600; padding: 5px 9px; border-radius: 7px; cursor: pointer; transition: background .15s, color .15s; }
.fr-steps button:hover { background: #e9eff8; color: #1d4ed8; }
.fr-steps button i { width: 16px; height: 16px; border-radius: 50%; background: #dde6f3; color: #334155; font-size: 10.5px; font-weight: 700; font-style: normal; display: inline-flex; align-items: center; justify-content: center; }
.fr-steps-tip { margin-left: auto; font-size: 11px; color: #94a3b8; }
/* 每步一个主色（同一色只出现在：左侧色条 / 标题色带 / 编号圆牌） */
.fr-grp.s1 { --ac: #2563eb; --ac-bg: #eef4ff; --ac-line: #d7e4fd; }
.fr-grp.s2 { --ac: #0891b2; --ac-bg: #ecf9fc; --ac-line: #cdedf5; }
.fr-grp.s3 { --ac: #7c3aed; --ac-bg: #f5f1ff; --ac-line: #e2d8fd; }
.fr-grp.s4 { --ac: #d97706; --ac-bg: #fff7ec; --ac-line: #f8e2c2; }
.fr-grp.s5 { --ac: #059669; --ac-bg: #edfaf4; --ac-line: #cbeadd; }
.fr-grp { padding: 0 14px 14px; border-color: var(--ac-line, var(--line)); border-left: 3px solid var(--ac, #64748b); }
.fr-gt { margin: 0 -14px 12px; padding: 10px 14px 9px; border-bottom: 1px solid var(--ac-line, #eef2f7); border-radius: 9px 9px 0 0; background: var(--ac-bg, #f8fafc); gap: 8px; }
.fr-gt i { background: var(--ac, #1d4ed8); color: #fff; width: 20px; height: 20px; font-size: 12px; }
.fr-step { margin-left: auto; font-size: 11px; font-weight: 600; color: var(--ac, #64748b); opacity: .9; letter-spacing: .3px; }
.fr-grp.fr-flash { box-shadow: 0 0 0 3px var(--ac-bg, #eef4ff), 0 2px 10px rgba(15,23,42,.10); }
/* 字段标题加深加重：与输入内容层次更清楚 */
.fr-f > span { font-size: 12px; font-weight: 700; color: #334155; letter-spacing: .2px; }
@media (max-width: 900px) {
  .fr-grp { padding: 0 11px 12px; }
  .fr-gt { margin: 0 -11px 11px; padding: 9px 11px 8px; }
  .fr-steps-tip { display: none; }
  .fr-steps button { font-size: 11.5px; padding: 5px 7px; }
}

/* ============================================================================
   ★2026-09-21 派出所辖区：下拉树选择器（fr-pick）
     用户反馈：不要把 179 个派出所全摆出来；希望「下拉框式」展示 + 关键字检索，
               或者按分局/县局用「＋」逐级展开查找。
     做法：收起时只占一行（显示已选摘要）；点开是一个下拉面板：
           顶部检索框（同时匹配派出所名与分局名）→ 工具条 → 按分局分组的树，
           每条分局前有 ＋/− 逐级展开；选中的派出所以可 × 的标签列在下面。
   ============================================================================ */
.fr-pick { position: relative; }
.fr-pick-box { display: flex; align-items: center; gap: 8px; min-height: 38px; padding: 8px 10px; background: #fff; border: 1px solid #cbd5e1; border-radius: 8px; cursor: pointer; transition: border-color .15s, box-shadow .15s; }
.fr-pick-box:hover { border-color: #94a3b8; }
.fr-pick.open .fr-pick-box { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(37,99,235,.13); }
.fr-pick-sel { flex: 1 1 auto; min-width: 0; font-size: 13px; font-weight: 500; color: #0f172a; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fr-pick-sel.ph { color: #9aa8bb; font-weight: 400; }
.fr-pick-arrow { flex: 0 0 auto; color: #64748b; font-size: 12px; line-height: 1; transition: transform .15s; }
.fr-pick.open .fr-pick-arrow { transform: rotate(180deg); }
.fr-pick-pop { display: none; position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 30; background: #fff; border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 12px 30px rgba(15,23,42,.18); padding: 10px; }
.fr-pick.open .fr-pick-pop { display: block; }
.fr-pick-kw { width: 100%; box-sizing: border-box; padding: 8px 10px; border: 1px solid #cbd5e1; border-radius: 7px; font-size: 13px; outline: none; }
.fr-pick-kw:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(37,99,235,.13); }
.fr-pick-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 8px 2px 6px; }
.fr-pick-list { max-height: min(46vh, 340px); overflow: auto; border-top: 1px solid #eef2f7; padding-top: 7px; }
.fr-pick-empty { padding: 16px 6px; text-align: center; font-size: 12.5px; color: var(--muted); }
.fr-tr-grp { border: 1px solid #eef2f7; border-radius: 8px; margin-bottom: 6px; overflow: hidden; }
.fr-tr-grp:last-child { margin-bottom: 0; }
.fr-tr-grp.open { border-color: #d9e6f9; }
.fr-tr-ph { display: flex; align-items: center; gap: 8px; padding: 8px 10px; background: #f8fafc; cursor: pointer; user-select: none; -webkit-user-select: none; }
.fr-tr-grp.open .fr-tr-ph { background: #eff5ff; }
.fr-tr-ph:hover { background: #eaf1fb; }
.fr-tr-plus { flex: 0 0 auto; width: 18px; height: 18px; border-radius: 5px; background: #fff; border: 1px solid #cbd5e1; color: #1d4ed8; font-size: 12px; font-weight: 700; line-height: 1; display: inline-flex; align-items: center; justify-content: center; }
.fr-tr-grp.open .fr-tr-plus { background: #1d4ed8; border-color: #1d4ed8; color: #fff; }
.fr-tr-pname { font-size: 12.5px; font-weight: 700; color: #0f172a; }
.fr-tr-pnum { margin-left: auto; font-size: 11.5px; color: var(--muted); }
.fr-tr-pnum b { color: #1d4ed8; }
.fr-tr-items { display: flex; flex-wrap: wrap; gap: 6px; padding: 9px 10px; background: #fff; }
.fr-tr-it { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: #334155; background: #fff; border: 1px solid var(--line); border-radius: 999px; padding: 4px 10px; cursor: pointer; }
.fr-tr-it:hover { border-color: #94a3b8; }
.fr-tr-it.on { background: #e0ecff; border-color: #2563eb; color: #1d4ed8; font-weight: 600; }
.fr-pick-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.fr-pick-tag { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: #1d4ed8; background: #e8efff; border: 1px solid #c9dcfb; border-radius: 999px; padding: 3px 8px; }
.fr-pick-tag .fr-tag-x { cursor: pointer; font-weight: 700; color: #2563eb; padding: 0 1px; }
.fr-pick-tag .fr-tag-x:hover { color: #b91c1c; }
@media (max-width: 900px) {
  .fr-pick-pop { position: static; margin-top: 6px; padding: 8px; box-shadow: none; }
  .fr-pick-list { max-height: 260px; }
}

/* ===== 报警提示音开关（实时探测目标栏 / 态势总览顶栏）★2026-09-21 ===== */
.alarm-btn { border: 0; background: transparent; cursor: pointer; padding: 2px 5px; border-radius: 6px; line-height: 1;
  font-size: 16px; color: inherit; display: inline-flex; align-items: center; gap: 4px;
  /* ★防御：按钮不得继承/被撞上任何定位/尺寸规则（曾因类名撞 .dash 全屏容器被撑成整屏）*/
  position: static !important; inset: auto !important; width: auto !important; height: auto !important;
  max-width: 170px; max-height: 40px; flex: 0 0 auto; }
.alarm-btn:hover { background: rgba(37, 99, 235, .10); }
.alarm-btn.off { opacity: .45; filter: grayscale(1); }
.alarm-btn.ringing { animation: alarmPulse 1s ease-in-out infinite; }
@keyframes alarmPulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.18); } }
/* ★2026-09-21：铃铛图标改为内联 SVG（emoji 🔔/🔕 无法渲染成红色）：开启=**红色**实心铃，关闭=灰色描边铃+斜杠 */
.alarm-btn .ab-ico { display: inline-flex; align-items: center; justify-content: center; width: 17px; height: 17px; }
.alarm-btn .ab-ico .ab-svg { width: 17px; height: 17px; display: block; color: #ff4d4f; }
.alarm-btn:not(.off) .ab-ico .ab-svg { filter: drop-shadow(0 0 4px rgba(255, 77, 79, .55)); }
.alarm-btn.off .ab-ico .ab-svg { color: #94a3b8; }
.alarm-btn.ringing .ab-ico .ab-svg { filter: drop-shadow(0 0 7px rgba(255, 77, 79, .95)); }
.dash-btncol .alarm-btn { font-family: inherit; font-size: 13px; padding: 6px 10px; border-radius: 8px;
  border: 1px solid rgba(34, 211, 238, .40); background: rgba(34, 211, 238, .12); color: #67e8f9; }
.dash-btncol .alarm-btn:hover { background: rgba(34, 211, 238, .20); }
.dash-btncol .alarm-btn.off { border-color: rgba(148, 163, 184, .30); background: rgba(148, 163, 184, .08); color: #7c8aa3; }
@media (max-width: 900px) {
  .alarm-btn { font-size: 15px; padding: 4px 7px; }
  .alarm-btn .ab-ico, .alarm-btn .ab-ico .ab-svg { width: 19px; height: 19px; }
  .dash-btncol .alarm-btn .ab-txt { display: none; }
}

/* ===== ★2026-09-21 历史空情筛选栏：可检索下拉（管辖派出所）与同排 select/input 尺寸保持一致 =====
   原因：同排控件是 .case-filter .cf input/select { font-size:12px; padding:6px 8px }（实测 30px 高），
   而 .ssel-txt 是 13px + 8px 内边距（实测 36px）→ 这个框比别的明显大一圈。这里按同排规格对齐。*/
.case-filter .cf .ssel-txt { padding: 6px 8px; font-size: 12px; line-height: 16px; }
.case-filter .cf .ssel-txt::after { margin-left: 4px; }
.case-filter .cf .ssel-kw { padding: 6px 8px; font-size: 12px; }
.case-filter .cf .ssel-item { padding: 6px 9px; font-size: 12px; }
.case-filter .cf .ssel-empty { padding: 8px; font-size: 12px; }
@media (max-width: 900px) {
  /* 手机端同排控件是 16px + 9px/8px（实测 39px）*/
  .case-filter .cf .ssel-txt { padding: 9px 8px; font-size: 16px; line-height: 19px; }
  .case-filter .cf .ssel-kw { padding: 9px 8px; font-size: 16px; }
  .case-filter .cf .ssel-item { padding: 8px 9px; font-size: 14px; }
}

/* ===== ★2026-09-21 §99 空情等级标签（Ⅰ级/Ⅱ级/Ⅲ级）=====
   依据《空情分级（三级）判定规则》；改为**无底色、仅彩色文字**（用户要求“不必有红色底色，写清楚就行”） */
.grade-tag { display: inline-block; padding: 0; margin-left: 5px; border: none; background: none;
  font-size: 11.5px; line-height: 16px; font-weight: 700; vertical-align: middle; white-space: nowrap; letter-spacing: .3px; }
.grade-tag.g1 { color: #c81e1e; }
.grade-tag.g2 { color: #1d4ed8; }
.grade-tag.g3 { color: #475569; }
@media (max-width: 900px) { .grade-tag { font-size: 10.5px; line-height: 15px; margin-left: 4px; } }

/* ===== 危急空情【强制告警】横幅 ★2026-09-21 =====
   仅作提示，不拦截操作：pointer-events:none（不得遮挡地图/按钮的点击，参见 §85 教训）*/
.crit-alert { position: fixed; left: 50%; top: 58px; z-index: 3000;
  display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
  transform: translateX(-50%); padding: 8px 14px; border-radius: 10px;
  font-size: 13px; font-weight: 600; line-height: 1.35; color: #fff; text-align: left;
  max-width: min(92vw, 900px);
  background: linear-gradient(180deg, rgba(190, 18, 40, .97), rgba(136, 8, 26, .97));
  border: 1px solid rgba(255, 130, 130, .85);
  box-shadow: 0 6px 22px rgba(190, 18, 40, .55), 0 0 0 3px rgba(255, 60, 60, .18);
  opacity: 0; visibility: hidden; transition: opacity .16s ease-out;
  pointer-events: none !important; }
.crit-alert.on { opacity: 1; visibility: visible; animation: critAlertPulse 1s ease-in-out infinite; }
@keyframes critAlertPulse {
  0%, 100% { box-shadow: 0 6px 22px rgba(190, 18, 40, .55), 0 0 0 3px rgba(255, 60, 60, .18); }
  50% { box-shadow: 0 6px 26px rgba(190, 18, 40, .85), 0 0 0 6px rgba(255, 60, 60, .32); }
}
.crit-alert .ca-ico { font-size: 16px; line-height: 1; animation: critAlertBlink .8s steps(2, end) infinite; }
@keyframes critAlertBlink { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
.crit-alert .ca-tx b { color: #ffe08a; margin-right: 6px; }
/* ★2026-10-06 横幅上的「定位现场」：容器 pointer-events:none，本按钮单独放行 */
.crit-alert .ca-loc { pointer-events: auto; cursor: pointer; font-family: inherit; font-size: 12px; font-weight: 700;
  color: #fff; background: rgba(255, 255, 255, .18); border: 1px solid rgba(255, 255, 255, .55);
  border-radius: 8px; padding: 3px 10px; line-height: 1.2; transition: background .15s, border-color .15s; }
.crit-alert .ca-loc:hover { background: rgba(255, 255, 255, .32); border-color: #fff; }
.crit-alert .ca-hint { font-weight: 400; font-size: 11.5px; color: #ffd6d6; opacity: .92; }
@media (max-width: 900px) {
  .crit-alert { top: 54px; font-size: 12px; padding: 6px 10px; max-width: 94vw; }
  .crit-alert .ca-hint { width: 100%; }
}

.dash-county { display: flex; flex-direction: column; gap: 2px; max-height: 172px; overflow-y: auto; }
.dash-county::-webkit-scrollbar { width: 5px; }
.dash-county::-webkit-scrollbar-thumb { background: rgba(56, 130, 246, .3); border-radius: 3px; }
.dc-row { display: flex; align-items: center; gap: 6px; padding: 3.5px 7px; border-radius: 7px;
  font-size: 12px; line-height: 1.35; color: #9fb6d6; border: 1px solid transparent; }
.dc-row.on { background: linear-gradient(90deg, rgba(34, 211, 238, .12), rgba(34, 211, 238, 0)); border-color: rgba(34, 211, 238, .18); }
.dc-dot { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: #3b5273; box-shadow: 0 0 0 2px rgba(59, 82, 115, .22); }
.dc-row.on .dc-dot { background: #22d3ee; box-shadow: 0 0 8px rgba(34, 211, 238, .85); }
.dc-org { flex: 1 1 auto; min-width: 0; color: #dbeafe; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dc-user { flex: 0 0 auto; color: #5b7aa8; font-size: 11px; }
.dc-time { flex: 0 0 auto; min-width: 54px; text-align: right; color: #5b7aa8; font-size: 11px; }
.dc-row.on .dc-time { color: #67e8f9; }
.dash-county-sub b { color: #67e8f9; font-weight: 600; }
@media (max-width: 900px) {
  .dash-county { max-height: 210px; }
  .dc-row { font-size: 12.5px; padding: 5px 8px; }
  .dc-time { min-width: 62px; }
}

/* ==============================================================
   ★§108（2026-09-21）历史空情 / 点位分布 检索栏统一
   背景：两页检索项都已很多，但标签小而灰、框口高矮/圆角/边框不一 → 辨识度差。
   统一：① 标签 13px / 700 / 深藏青 #0f172a / 字距 .3px / 居中在控件正上方
        ② 框口（输入框 / 下拉 / 派出所选择器 / 时间按钮）PC 高 34px、圆角 8px、
           字号 13px、边框 #d7dee8、聚焦蓝色描边（与点位分布原有现代样式完全对齐）
        ③ 两页检索栏容器内边距 / 圆角一致
   注意：手机端字号仍保持 16px（防 iOS 聚焦缩放），只统一边框与圆角。
   ============================================================== */
/* ① 标签：更醒目，两页完全一致（字号 / 字重 / 颜色 / 字距 / 对齐） */
.case-search-card .case-filter .cf > label,
.points-bar .cf > label,
#ptsBar > .cf > label {
  display: block !important;
  width: 100% !important;
  font-size: 15px !important;
  font-weight: 700 !important;
  color: #000 !important;
  letter-spacing: 1px !important;
  text-align: center !important;
  line-height: 18px !important;
  margin: 0 0 5px 0 !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}
/* ② 框口（PC） */
@media (min-width: 901px) {
  .case-search-card .case-filter .cf > input,
  .case-search-card .case-filter .cf > select,
  .case-search-card .case-filter .cf .ssel > .ssel-txt,
  .case-search-card .case-filter .cf .case-range-btn,
  #ptsBar > .cf > input,
  #ptsBar > .cf > select,
  #ptsBar > .cf .ssel > .ssel-txt,
  #ptsBar > .cf .case-range-btn {
    height: 34px !important;
    min-height: 34px !important;
    padding: 0 10px !important;
    font-size: 13px !important;
    font-weight: 500 !important;
    color: #0f172a !important;
    background: #fff !important;
    border: 1px solid #d7dee8 !important;
    border-radius: 8px !important;
    box-shadow: 0 1px 2px rgba(15, 23, 42, .04) !important;
    outline: none !important;
    box-sizing: border-box !important;
    width: 100% !important;
  }
  .case-search-card .case-filter .cf .ssel > .ssel-txt,
  #ptsBar > .cf .ssel > .ssel-txt { line-height: 32px !important; padding: 0 10px !important; }
  .case-search-card .case-filter .cf .case-range-btn {
    display: inline-flex !important; align-items: center !important; justify-content: space-between !important;
  }
  .case-search-card .case-filter .cf > input:hover,
  .case-search-card .case-filter .cf > select:hover,
  .case-search-card .case-filter .cf .ssel > .ssel-txt:hover,
  #ptsBar > .cf > input:hover,
  #ptsBar > .cf > select:hover,
  #ptsBar > .cf .ssel > .ssel-txt:hover { border-color: #b9c6d6 !important; }
  .case-search-card .case-filter .cf > input:focus,
  .case-search-card .case-filter .cf > select:focus,
  #ptsBar > .cf > input:focus,
  #ptsBar > .cf > select:focus {
    border-color: #2563eb !important;
    box-shadow: 0 0 0 3px rgba(37, 99, 235, .12) !important;
  }
}
/* ③ 手机端：字号统一 16px（防 iOS 聚焦缩放），高度统一 40px（触控友好），边框/圆角/宽度也统一 */
@media (max-width: 900px) {
  .case-search-card .case-filter .cf > input,
  .case-search-card .case-filter .cf > select,
  .case-search-card .case-filter .cf .ssel > .ssel-txt,
  .case-search-card .case-filter .cf .case-range-btn,
  #ptsBar > .cf > input,
  #ptsBar > .cf > select,
  #ptsBar > .cf .ssel > .ssel-txt,
  #ptsBar > .cf .case-range-btn {
    font-size: 16px !important;
    height: 40px !important;
    min-height: 40px !important;
    line-height: normal !important;
    padding: 0 10px !important;
    border: 1px solid #d7dee8 !important;
    border-radius: 8px !important;
    background: #fff !important;
    box-sizing: border-box !important;
    width: 100% !important;
  }
}
/* ④ 两页检索栏容器：内边距 / 圆角一致 */
.case-search-card .case-filter { padding: 10px 12px !important; border-radius: 10px !important; }
#ptsBar.points-bar.mining-bar { padding: 10px 12px !important; border-radius: 10px !important; }

/* ==============================================================
   ★§112（2026-09-22）点位分布检索栏自适应：放大 / 窄屏不再相互挤压重叠
   原因：原用「固定列宽网格」128px 152px repeat(7,120px) auto，整行约需 1540px；
         窗口放大（Ctrl+）或本就 1366 等窄屏时，最后的按钮列被压成 0 宽，
         按钮溢出压到相邻下拉框上 → 视觉重叠。
   做法：≥1560px 保持原固定列宽（观感与之前一致）；
         ≤1559px 改用 auto-fit 自适应列（每列 ≥118px，放不下自动换行），按钮组独占一行。
   ============================================================== */
@media (min-width: 1560px) {
  #ptsBar { grid-template-columns: 128px 152px repeat(7, 120px) auto !important; }
}
@media (min-width: 901px) and (max-width: 1559px) {
  #ptsBar { grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)) !important; }
  #ptsBar > .cf-acts { grid-column: 1 / -1 !important; }
  #ptsBar > .cf.cf-acts .cf-acts-row { justify-content: flex-start !important; flex-wrap: wrap !important; gap: 8px !important; }
}

/* ==============================================================
   ★§113（2026-09-22）点位分布检索栏：排列 / 尺寸 / 间距完全对齐历史空情
   用户意见：历史空情那栏顺眼、也好操作 → 点位分布改成同一套：
     · 容器：flex + flex-wrap、gap 6px、padding 10px 12px、浅灰底 + 描边 + 圆角（.case-filter 同款）
     · 每格：定宽（与历史空情各字段同口径）、label 在上居中（§108 已统一字号/颜色）
     · 按钮组 .cf-btns：独占一行（flex: 1 1 100%）、靠左、间距 6px（与历史空情 .cf-btns 同款）
   ⚠ 仅 PC：手机端保持原「2 列 + 默认收起」不变
   ============================================================== */
@media (min-width: 901px) {
  #ptsBar.points-bar.mining-bar {
    display: flex !important;
    flex-wrap: wrap !important;
    align-items: flex-end !important;
    gap: 6px !important;
    padding: 10px 12px !important;
    background: #eef2f7 !important;
    border: 1px solid var(--line) !important;
    border-radius: 10px !important;
  }
  #ptsBar > .cf { 
    display: flex !important;
    flex-direction: column !important;
    justify-content: flex-end !important;
    align-items: stretch !important;
    min-width: 0 !important;
    margin: 0 !important;
  }
  /* ★旧「兜底防撑开」规则给这些格加了 max-width:120px/128px/152px（网格时代遗留），
     会把下面 §113 的定宽压回去（实测：时间范围被压到 128、后 4 个被压到 120）→ 此处一并重置 */
  #ptsBar > .cf:not(.cf-range):not(.cf-acts):not(:has(#ptSn)),
  #ptsBar > .cf:has(#ptSn),
  #ptsBar > .cf.cf-range,
  #ptsBar > .cf { max-width: none !important; }
  /* 定宽（与历史空情字段同口径）：时间范围 150 / 目标标识 132 / 目标类型 105 / 空情等级 105 /
     案件性质 92 / 空域性质 128 / 行政区划 136 / 探测设备 150 / 管辖单位 150 */
  #ptsBar > .cf:nth-child(1) { flex: 0 0 150px !important; }
  #ptsBar > .cf:nth-child(2) { flex: 0 0 132px !important; }
  #ptsBar > .cf:nth-child(3) { flex: 0 0 105px !important; }
  #ptsBar > .cf:nth-child(4) { flex: 0 0 105px !important; }
  #ptsBar > .cf:nth-child(5) { flex: 0 0 92px !important; }
  #ptsBar > .cf:nth-child(6) { flex: 0 0 128px !important; }
  #ptsBar > .cf:nth-child(7) { flex: 0 0 136px !important; }
  #ptsBar > .cf:nth-child(8) { flex: 0 0 150px !important; }
  #ptsBar > .cf:nth-child(9) { flex: 0 0 150px !important; }
  #ptsBar > .cf > select,
  #ptsBar > .cf > input,
  #ptsBar > .cf > .case-range-pop { width: 100% !important; }
  /* 按钮组：绘制区域/导出 不再独占一行（跟着字段尾后，即「上一行」） */
  #ptsBar > .cf-btns {
    display: flex !important;
    flex-wrap: wrap !important;
    gap: 6px !important;
    padding-bottom: 1px !important;
    flex: 0 0 auto !important;
    align-items: center !important;
    margin: 0 !important;
  }
  #ptsBar > .cf-btns .btn { flex: 0 0 auto !important; white-space: nowrap !important; }
  /* 绘制区域 / 导出：对齐平台 .btn.sm 尺寸（旧「.points-bar button 高 34px」规则把这两个撑大了） */
  #ptsBar > .cf-btns .btn.sm {
    height: auto !important;
    min-height: 0 !important;
    padding: 5px 10px !important;
    font-size: 12px !important;
    border-radius: 9px !important;
    display: inline-flex !important;
    align-items: center !important;
    gap: 5px !important;
  }
  @media (max-width: 900px) {
    #ptsBar > .cf-btns .btn.sm { padding: 8px 13px !important; font-size: 13px !important; }
  }
  /* 地图图层工具条里的「查询」按钮：轻强调（与筛选区分） */
  .maptools button.pt-query { color: var(--primary); font-weight: 600; }
}

/* ==============================================================
   ★§115（2026-09-22）点位分布：查询 / 清除 浮在地图左上角
   样式**向历史空情看齐**：直接用平台同款小按钮 btn.sm（primary / ghost），
   不自定义大块渐变；图标改为细线 SVG（放大镜 / 叉），不用彩色 emoji。
   ============================================================== */
.pt-actions {
  position: absolute; left: 12px; top: 14px; z-index: 1300;
  display: flex; gap: 6px; align-items: center;
}
.pt-actions .btn {
  display: inline-flex; align-items: center; gap: 5px;
  box-shadow: 0 2px 8px rgba(15, 23, 42, .16);
}
.pt-actions .btn .ico { width: 13px; height: 13px; flex: 0 0 auto; display: block; }
@media (max-width: 900px) {
  .pt-actions { left: 8px; top: 8px; }
}

/* ==============================================================
   ★§117（2026-09-22）轨迹回放头部：实名信息紧跟「机型」同行，不再单独占一行
   （原 .pb-real 整行已从 HTML 移除；手机端空间不够时可换行，不挤压标题）
   ============================================================== */
.pb-title .pb-real-inline {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 700; color: var(--text);
  min-width: 0; flex: 0 1 auto;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pb-title .pb-real-inline .pb-ok { color: #16a34a; }
.pb-title .pb-real-inline .pb-no { color: #dc2626; }
.pb-title .pb-real-inline .pb-rname { color: #0f172a; }
.pb-title .pb-real-inline .pb-rphone { color: var(--muted); font-weight: 600; letter-spacing: .2px; }
@media (max-width: 900px) {
  .pb-title { flex-wrap: wrap; }
  .pb-title .pb-real-inline { font-size: 12px; gap: 4px; }
}
.case-search-card .case-filter .cf-btns, .points-bar .cf-acts-row { align-items: center !important; }

/* ==============================================================
   ★§109（2026-09-21）长列收窄折行：发现位置 / 属地·派出所（仅 PC）
   限宽 + 居中折行，不把表格与弹窗撑宽（与 §106 实名同一套做法）
   手机端保持原样：表格固定最小宽 + 左右滑动，不折行（否则窄格内会折成很多行、行高爆炸）
   ============================================================== */
@media (min-width: 901px) {
/* 发现位置：历史空情主表 / 无人机飞行记录弹窗 / 空情串并，均为 <span class="geo">地址</span> */
.table-wrap .geo,
.modal-body .geo {
  display: inline-block;
  max-width: 150px;
  white-space: normal;
  word-break: break-word;
  overflow-wrap: anywhere;
  line-height: 1.35;
  text-align: left;
  vertical-align: middle;
}
/* 属地 / 派出所（态势总览下钻弹窗） */
.modal-body .dd-lbox {
  display: inline-block;
  max-width: 150px;
  white-space: normal;
  word-break: break-word;
  overflow-wrap: anywhere;
  line-height: 1.35;
  text-align: center;
  vertical-align: middle;
}
}
/* ===== 处置预案弹窗（分级标准处置动作）★2026-09-22 ===== */
.disp-rule {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-left: 4px solid #c81e1e;
  border-radius: 8px;
  background: #fafafa;
  margin-bottom: 4px;
}
.disp-rule b { font-size: 14px; white-space: nowrap; }
.disp-rule span { color: var(--muted); font-size: 12.5px; }
.disp-steps { display: flex; flex-direction: column; gap: 7px; }
.disp-step {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 8px 11px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 13px;
  line-height: 1.55;
  cursor: pointer;
  background: #fff;
}
.disp-step:hover { border-color: var(--primary); }
.disp-step input[type=checkbox] { margin-top: 3px; flex: none; }
.disp-step input[type=checkbox]:checked + span { color: var(--primary); font-weight: 600; }
.disp-talk {
  width: 100%;
  box-sizing: border-box;
  min-height: 88px;
  max-height: 560px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 12.5px;
  line-height: 1.75;
  color: var(--text);
  background: #fbfdff;
  resize: vertical;
  font-family: inherit;
}
.disp-empty { padding: 16px; color: var(--muted); font-size: 13px; text-align: center; }
/* ★2026-09-23 处置提示卡片·飞手实名电话行（三级电话提示场景） */
.disp-phone {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 8px;
  padding: 9px 12px; margin: 8px 0 2px;
  border: 1px solid #fde68a; background: #fffbeb; border-radius: 8px; font-size: 13px;
}
.disp-phone b { color: #b45309; letter-spacing: .5px; }
.disp-phone .disp-call {
  color: #1d4ed8; text-decoration: none; border: 1px solid #bfdbfe; background: #eff6ff;
  border-radius: 5px; padding: 2px 8px; font-size: 12px;
}
.disp-phone-none { color: var(--muted); background: #f8fafc; border-color: var(--line); }
/* 一级空情：市局情指联动专席电话（红框突出） */
.disp-phone.disp-hotline { border-color: #fecaca; background: #fef2f2; }
.disp-phone.disp-hotline b { color: #c81e1e; }
/* ★2026-09-28 一/二级空情：企业微信转发属地专班联络员（蓝框；同一分局可多人，每人一行） */
.disp-phone.disp-duty { border-color: #bfdbfe; background: #eff6ff; flex-wrap: wrap; }
.disp-phone.disp-duty b { color: #1d4ed8; }
.disp-duty-line { flex: 1 1 100%; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.disp-phone .disp-duty-sub { color: #475569; font-size: 12px; }
/* ★2026-09-28 一/二级空情：属地派出所行（值班 / 所长电话直接印在指引单上） */
.disp-phone.disp-pst { border-color: #cbd5e1; background: #f8fafc; }
.disp-phone.disp-pst b { color: #0f172a; }
/* ★2026-09-28 处置指引最上方「X级空情处置」栏：右侧「📋 复制空情信息」按钮 */
.disp-rule .disp-copyinfo { margin-left: auto; flex: 0 0 auto; white-space: nowrap; }
.disp-rule span { flex: 1 1 auto; min-width: 0; }
@media (max-width: 900px) {
  .disp-rule { flex-wrap: wrap; row-gap: 6px; }
  .disp-rule .disp-copyinfo { margin-left: auto; }
}

/* ===== 派出所联系方式（★2026-09-23）===== */
.ps-link { color: var(--primary); cursor: pointer; border-bottom: 1px dashed var(--primary); }
.ps-link:hover { color: #1e40af; border-bottom-style: solid; }
.ps-card { display: flex; flex-direction: column; gap: 3px; padding: 4px 0 10px; }
.ps-name { font-size: 16px; font-weight: 700; }
.ps-sub { color: var(--muted); font-size: 12px; }
.ps-row {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border: 1px solid var(--line); border-radius: 8px; margin-bottom: 8px; font-size: 13px;
}
.ps-k { color: var(--muted); width: 76px; flex: none; }
.ps-v { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ps-v b { color: #b45309; letter-spacing: .5px; font-size: 14px; }
.ps-call {
  color: #1d4ed8; text-decoration: none; border: 1px solid #bfdbfe; background: #eff6ff;
  border-radius: 5px; padding: 2px 8px; font-size: 12px;
}
/* 实时文字框内「辖区」行可点击 */
.uav-lbl-ps { cursor: pointer; }
.uav-lbl-ps:hover .uav-lbl-t { color: var(--primary); text-decoration: underline dotted; }

/* ==== ★2026-10-01 大屏：实时空情态势（下区）＋今日空情态势（右栏卡片）==== */
/* 左卡（下区/字幕区）统一 108px；右卡为「统计胶囊 + 3 行 AI 研判 + 行动建议」，故整体更高 */
/* ★2026-10-02 实时空情态势：空情信息块与上方统计格拉开间距（原预警行自带 margin-top，移入块内后顶部过挤） */
#dashInfoBox { margin-top: 10px; }
.rs-info { min-height: 108px; border-radius: 8px; padding: 9px 12px; display: flex; flex-direction: column; justify-content: space-between; cursor: pointer; }
.rs-info:hover { filter: brightness(1.15); }
.rs-info-hd { display: flex; align-items: center; gap: 8px; font-size: 12.5px; line-height: 18px; }
.rs-info-hd b { font-size: 13.5px; }
.rs-info-idx { color: #7f9fc9; font-size: 11px; flex: 0 0 auto; }
.rs-info-badge { border-radius: 9px; padding: 1px 6px; font-size: 11px; font-weight: 700; flex: 0 0 auto; }
.rs-info-dots { margin-left: auto; color: #6d8cb5; font-size: 11px; letter-spacing: 2px; flex: 0 0 auto; }
.rs-info-air { color: #8fb0d8; font-size: 11px; flex: 0 0 auto; }
/* ★2026-10-02 空情等级/预警已并入「空情信息」块最后一行（不再单独占一行）：继承 .rs-info-row 的普通字体 */
.rs-info-note { margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rs-info-row { font-size: 12px; line-height: 18px; color: #a9c2e2; }
.rs-info-row b { color: #eaf4ff; font-size: 12.5px; }
.rs-info-idle { font-size: 12.5px; color: #cfe3ff; font-weight: 600; }
/* ★2026-10-02：正文硬性 3 行以内（line-clamp），简练高密度；去掉底部换页指示，卡高收紧 */
.rs-tick { min-height: 126px; display: flex; flex-direction: column; }
.rs-tick-main { flex: 1; min-height: 94px; display: flex; flex-direction: column; justify-content: center; gap: 6px; }
.rs-tick-h { font-size: 14px; line-height: 1.62; color: #e6f0ff; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.rs-tick-h b { color: #ffd85e; font-size: 15px; font-weight: 800; line-height: 20px; background: rgba(251,191,36,.16); border-radius: 4px; padding: 0 3px; text-shadow: 0 0 9px rgba(251,191,36,.5), 0 1px 1px rgba(0,0,0,.55); }
.rs-tick-h .wk { color: #fbbf24; font-weight: 700; }
.rs-tick-h .ok { color: #34d399; font-weight: 700; }
.rs-tick-tip { font-size: 13px; line-height: 1.55; color: #f5d08a; }
.rs-tick-tip b { color: #ffffff; font-size: 13.5px; font-weight: 800; line-height: 18px; background: rgba(255,255,255,.15); border-radius: 4px; padding: 0 3px; text-shadow: 0 1px 1px rgba(0,0,0,.5); }
.rs-tick-anim { animation: rsTickIn .55s ease-out; }
@keyframes rsTickIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.tk-nums { display: flex; flex-wrap: wrap; gap: 5px 6px; margin: 0 0 7px; }
.tk-num { display: inline-flex; align-items: center; gap: 4px; padding: 2px 10px; border-radius: 999px; background: rgba(148,178,220,.12); border: 1px solid rgba(148,178,220,.22); font-size: 12.5px; color: #b9cde6; white-space: nowrap; font-family: inherit; cursor: pointer; transition: background .15s, border-color .15s; }
.tk-num:hover { background: rgba(148,178,220,.24); border-color: rgba(148,178,220,.45); }
.tk-num b { font-size: 15.5px; font-weight: 800; color: #eaf4ff; font-variant-numeric: tabular-nums; }
.tk-num.ok { color: #7ee2b8; border-color: rgba(52,211,153,.3); }
.tk-num.ok b { color: #34d399; }
.tk-num.warn { color: #e8cf8a; border-color: rgba(251,191,36,.32); }
.tk-num.warn b { color: #fbbf24; }
.tk-num.danger { color: #f0a9a9; border-color: rgba(248,113,113,.32); }
.tk-num.danger b { color: #f87171; }
/* ★2026-10-02 空情等级一级：红色罗马数字「Ⅰ级」*/ 
.tk-num.lv1 { color: #ff8b8b; border-color: rgba(255,77,79,.55); background: rgba(255,77,79,.14); }
.tk-num.lv1 b { color: #ff4d4f; }
.rs-tick-h .lv1, .rs-tick-tip .lv1 { color: #ff4d4f; font-weight: 800; }
.rs-tick-h .lv2, .rs-tick-tip .lv2 { color: #38bdf8; font-weight: 800; }
.rs-tick-h .lv3, .rs-tick-tip .lv3 { color: #ffffff; font-weight: 800; }

/* ★2026-10-01 实时空情态势：空情等级 + 预警内容合并同一行（不换行，过长省略、悬停看全文） */

/* ==============================================================
   ★2026-10-02 态势总览（手机端）：今日空情态势卡片紧接「实时空情态势」下方
   —— 用户要求把「今日空情态势」放到「实时空情态势」卡片下面；实名匹配顺延到其后。
      仅 ≤900px 生效（大屏三列布局不受影响）；用同特异性选择器 + 后置覆盖原 order:4。
   ============================================================== */
@media (max-width: 900px) {
  .dash .dash-main > .dash-col > #dashTickPanel { order: 4 !important; }
  .dash .dash-main > .dash-col > #dashRealMatchPanel { order: 5 !important; }
}
