/* ============================================================
   指挥调度中心模板（tech）· v1.1.0.154
   ------------------------------------------------------------------
   来源：设计稿「消防指挥调度系统 FIRE COMMAND CENTER」（1920×1080 舞台，
   6 屏：首页总览 / 作战地图 / 力量调派详情 / 力量部署 / 联勤联动台账 /
   部署模板管理 —— 后三者为新增的后台管理模块）。
   由设计稿 <style> 整体迁移并作用域化（body.tpl-tech 前缀）：
   · 本模板**自包含**——不加载 common/dashboard 等任何站点 CSS，
     避免与站点 .panel/.btn/.tag/.chip 等同名类冲突；
   · 配色即设计稿原始令牌（--bg:#0A1220 全局底 / --red:#E5484D 主红 /
     --blue:#3E8BFF 次蓝 / --cyan/--green/--yellow 语义色……），
     与主题色卡「原皮-科技感」（yuanpi）的角色色一一对应（见 helpers.php）；
   · 模板视觉固定为设计稿效果，不随站点色卡变化（模板 = 固定视觉）。
   ⚠ 仅前台（frontend）支持；登录页 / 后台回落默认模板。
   ============================================================ */


/* ============ 设计令牌（取自设计稿） ============ */
body.tpl-tech{
  --bg:#0A1220;            /* 全局底色 */
  --panel:#111B2E;         /* 面板 */
  --panel2:#0D1626;        /* 次级面板 / 顶栏 / 导航 */
  --map-bg:#0C1526;        /* 地图 / 画布底 */
  --line:#223047;          /* 面板描边 */
  --line2:#1B2942;         /* 顶栏描边 */
  --slot:#1A2740;          /* 进度槽 / 次按钮 / 输入框 */
  --red:#E5484D; --red-t:#FF8C93; --red-bg:#3A1F26; --red-bg2:#3D1217; --red-alarm:#FF5C33;
  --orange:#FF8A3C; --orange-t:#FFB48A; --orange-bg:#33200F;
  --blue:#3E8BFF; --blue-t:#8FC0FF; --blue-bg:#12233F;
  --cyan:#4DD8E4; --cyan-bg:#0E3A3F; --cyan-line:#37C7CC;
  --yellow:#FFB224; --yellow-bg:#332B0D; --yellow-t:#FFD44D;
  --green:#30C463; --green-t:#7BE0A0; --green-bg:#0F331F;
  --txt:#F2F5FA; --txt1:#EEF2F8; --txt2:#D5DCE8; --txt3:#9AA8BF; --txt4:#5E6C84; --txt5:#5A6B84;
  --mono-car:#8FA3C0;
  --fz:'Noto Sans SC',sans-serif;
  --fm:'JetBrains Mono',monospace;
  /* v1.1.0.178：共享角色面板（assets/css/user-panel.css）用到的通用变量别名 ——
     本模板自包含（不加载 common.css），故在此把设计稿令牌映射成通用名，
     使后台 / 前台 / 指挥调度中心三处角色卡面板**外观完全一致**。 */
  --acc:#E5484D;            /* 主色（= 设计稿主红） */
  --acc-text:#FFFFFF;       /* 主色底上的文字色 */
  --sub:#9AA8BF;            /* 辅助文字（= --txt3） */
  --panel-2:#0D1626;        /* 次级面（= --panel2） */
  --panel-3:#1A2740;        /* 三级面（= --slot） */
  --line-2:#1B2942;         /* 次级描边（= --line2） */
  --bg-2:#0D1626;           /* 输入框底（= --panel2） */
}
body.tpl-tech, body.tpl-tech *{margin:0;padding:0;box-sizing:border-box}
body.tpl-tech{height:100%;background:#0A1220;overflow:hidden;font-family:var(--fz)}      /* v1.1.0.165：body 背景与舞台同色，空隙无缝 */
/* ============================================================================
   v1.1.0.185：全局缩放基准（模块一 / 模块二 / 模块三 统一）
   ----------------------------------------------------------------------------
   需求：原先按 100% 渲染时界面偏大、臃肿；用户手动把**浏览器**缩放到 75%
   后视觉更舒适 → 希望把这套观感「烘焙」进项目：界面标称 100%，实际渲染
   尺寸为原来的 75%。

   实现选型（实测三方案后确定）：
     ✗ transform: scale()  —— v1.1.0.178 已废弃：双轴非等比会拉伸变形，
                               且 transform 不改布局尺寸，必须额外补偿宽高，
                               容易出现偏移与留白。
     ✗ body{zoom} + 宽高补偿 —— 实测 #stage 高度补偿后仍留 220px 空白
                               （zoom 会让 dvh/vw 重新按缩放后的视口计算，
                                补偿量难以一次算准）。
     ✅ #stage{zoom} + 视口单位补偿 —— 实测 1920×880 下铺满、零留白、
        零横向滚动；内嵌 iframe 的内部视口同步按新基准放大
        （模块一/二 的地图因此显示更多内容，正是想要的效果）。

   ⚠ 为什么用 zoom 而不是 transform：zoom 会**重新计算布局**，
     所以内部所有百分比宽度、flex 分配、媒体查询都按新基准走，
     地图/图表等按容器尺寸自适应的组件不会错位；transform 只是视觉缩放，
     布局仍是旧尺寸 → 文字被拉小、留白、地图裁切。

   ⚠ 视口单位必须同步补偿：zoom 会把 100dvh 解释为「缩放后的视口高度」，
     直接写 height:100dvh 会让舞台只占 75% 高度、底部留白。
     故用 calc(100dvh / var(--xf-scale)) 抵消。

   ⚠ 媒体查询不受 zoom 影响（仍按真实视口宽度判定）→ 断点逻辑保持原样，
     不会因为缩放而误触发手机档。

   ⚠ 用户手动切换浏览器缩放（Ctrl+滚轮）依然完全有效：浏览器缩放作用于
     本层之上，与项目基准正交叠加，两种缩放互不干扰。
   ============================================================================ */
body.tpl-tech{
  /* 缩放基准：界面标称 100% 时，实际渲染尺寸为原来的 75%。
     三个模块（首页总览 / 作战地图 / 力量部署）同属 #stage → 天然共用同一基准。 */
  --xf-scale: 0.75;
}
body.tpl-tech #stage{
  width:100%;
  /* 视口单位按 zoom 补偿：舞台实际铺满视口，不留白、不裁切 */
  height:calc(100dvh / var(--xf-scale));
  min-height:calc(100vh / var(--xf-scale));
  zoom:var(--xf-scale);
  background:var(--bg);position:relative;display:flex;flex-direction:column;overflow:hidden;
}
/* 1920×1080 舞台，等比缩放适配窗口 */
/* v1.1.0.178：舞台**铺满视口**（不再固定 1920×1080 再整体缩放）——
   旧做法双轴非等比缩放会拉伸变形，且小屏下所有字号被一起缩小（用户反馈「模块与字体偏小」）。
   内部为 flex 布局，地图按容器实际尺寸铺满 → 无拉伸 / 无偏移 / 无缩放失真。
   ⚠ v1.1.0.185：上方已叠加全局缩放基准（--xf-scale），此处不再重复声明尺寸。 */
/* ⚠ v1.1.0.184：.screen 原为 `width:100%` —— 它是 .body（display:flex）里
   与 .sidenav（200px 固定宽）并列的 flex item，width:100% 等于「整个视口宽」，
   再叠加侧栏 200px → 内容整体右移 200px，超出视口的部分被 #stage 的
   overflow:hidden **硬裁掉**（用户截图实证：右栏「现场部署清单」与顶部
   「在线编辑/导出部署图」按钮被切掉一半）。
   ⚠ 为何只有力量部署屏出事：另外两屏内容最小宽度小，flex 收缩（flex-shrink）
     恰好把它拉回 1400px，看起来正常；力量部署屏的最小内容宽度达 1722px
     （三栏定宽 220+320 + 画布最小宽 + 内边距），收缩不动 → 必然溢出。
   ✅ 正确写法：让 .screen 用 flex 占据侧栏右侧的**剩余空间**，并允许收缩到 0。
       flex:1 1 0 + min-width:0 是 flex 布局的标准写法（min-width:auto 会
       让子项拒绝收缩到内容最小宽度以下，正是这里收缩不动的直接原因）。 */
body.tpl-tech .screen{display:none;flex-direction:column;flex:1 1 0;min-width:0;height:100%}
body.tpl-tech .screen.active{display:flex}

/* ============ 顶栏 ============ */
body.tpl-tech .topbar{height:64px;flex:none;background:var(--panel2);border-bottom:1px solid var(--line2);display:flex;align-items:center;gap:16px;padding:0 24px}
body.tpl-tech .topbar .logo{width:28px;height:28px;flex:none}
body.tpl-tech .topbar .sys{font-size:20px;font-weight:700;color:var(--txt)}
body.tpl-tech .topbar .en{font-family:var(--fm);font-size:10px;color:var(--txt4);letter-spacing:1px;margin-top:2px}
body.tpl-tech .topbar .sp{flex:1}
body.tpl-tech .topbar .date{font-size:13px;color:var(--txt3)}
body.tpl-tech .topbar .time{font-family:var(--fm);font-weight:500;font-size:22px;color:var(--yellow)}
body.tpl-tech .topbar .weather{font-size:13px;color:var(--txt3)}
body.tpl-tech .topbar .bell{width:20px;height:20px;color:var(--red)}
body.tpl-tech .topbar .user{display:flex;align-items:center;gap:8px;background:var(--slot);border-radius:20px;padding:6px 12px}
body.tpl-tech .topbar .avatar{width:24px;height:24px;border-radius:50%;background:var(--blue)}
body.tpl-tech .topbar .uname{font-size:13px;font-weight:500;color:#EEF2F8}

/* ============ 主体布局 ============ */
body.tpl-tech .body{flex:1;display:flex;min-height:0}
body.tpl-tech .sidenav{width:200px;flex:none;background:var(--panel2);display:flex;flex-direction:column;gap:8px;padding:16px 12px 12px}
body.tpl-tech .nav-tab{height:48px;flex:none;border-radius:8px;background:var(--panel);display:flex;align-items:center;gap:12px;padding:0 16px;font-size:15px;font-weight:500;color:var(--txt3);cursor:pointer;border:1px solid transparent;transition:background .15s}
body.tpl-tech .nav-tab svg{width:20px;height:20px;flex:none;stroke:var(--txt3)}
body.tpl-tech .nav-tab:hover{background:#16233A}
body.tpl-tech .nav-tab.on{background:var(--red-bg);border-color:var(--red);color:#FFF;font-weight:600}
body.tpl-tech .nav-tab.on svg{stroke:var(--red)}
body.tpl-tech .nav-back{margin-top:auto;border:1px dashed var(--line);background:transparent}
body.tpl-tech .nav-back:hover{background:var(--panel)}
body.tpl-tech .content{flex:1;min-width:0;padding:24px;display:flex;flex-direction:column;gap:16px;overflow:auto}
body.tpl-tech .content.row{flex-direction:row;overflow:hidden}
body.tpl-tech .panel{background:var(--panel);border:1px solid var(--line);border-radius:12px}
body.tpl-tech .phead{display:flex;align-items:center;gap:8px}
body.tpl-tech .phead .t{font-size:15px;font-weight:600;color:var(--txt1)}
body.tpl-tech .phead .more{font-size:12px;color:var(--blue);cursor:pointer}
body.tpl-tech .badge{display:inline-flex;align-items:center;border-radius:4px;padding:2px 8px;font-size:11px;font-weight:700}

/* ============ 屏幕1 首页 ============ */
body.tpl-tech .kpis{display:flex;gap:16px}
body.tpl-tech .kpi{flex:1;background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:20px;display:flex;flex-direction:column;gap:10px}
body.tpl-tech .kpi .row{display:flex;justify-content:space-between;align-items:center}
body.tpl-tech .kpi .name{font-size:13px;color:var(--txt3)}
body.tpl-tech .kpi .delta{font-family:var(--fm);font-size:12px}
body.tpl-tech .kpi .val{font-family:var(--fm);font-weight:500;font-size:48px;line-height:1.1;color:var(--txt)}
body.tpl-tech .dash{flex:1;display:flex;gap:16px;min-height:0}
body.tpl-tech .card{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:20px;display:flex;flex-direction:column}
body.tpl-tech .alarm-line{display:flex;align-items:center;gap:12px;padding:8px 8px 8px 8px;margin-top:6px}
body.tpl-tech .alarm-line .tm{font-family:var(--fm);font-size:12px;color:var(--txt4);width:52px;flex:none}
body.tpl-tech .dot{width:8px;height:8px;border-radius:50%;flex:none}
body.tpl-tech .alarm-line .pos{flex:1;font-size:13px;color:var(--txt2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
body.tpl-tech .alarm-line .st{font-size:12px;font-weight:500;flex:none}
body.tpl-tech .cat-line{display:flex;align-items:center;gap:12px;margin-top:10px}
body.tpl-tech .cat-line .c{width:64px;flex:none;font-size:12px;color:var(--txt3)}
body.tpl-tech .slotbar{flex:1;height:6px;border-radius:3px;background:var(--slot);overflow:hidden}
body.tpl-tech .slotbar i{display:block;height:100%;border-radius:3px}
body.tpl-tech .cat-line .v{width:40px;flex:none;font-family:var(--fm);font-size:12px;color:var(--txt2);text-align:right}
body.tpl-tech .duty-line{display:flex;align-items:center;gap:10px;padding:6px;margin-top:4px}
body.tpl-tech .duty-line .st{flex:1;font-size:13px;color:var(--txt2)}
body.tpl-tech .duty-line .pw{font-family:var(--fm);font-size:12px;color:var(--txt3)}

/* ============ 屏幕2 作战地图 ============ */
body.tpl-tech #screen-map .content{flex-direction:row}
body.tpl-tech .unit-panel{width:300px;flex:none;display:flex;flex-direction:column;gap:12px;padding:16px;overflow:hidden}
body.tpl-tech .search{height:36px;border-radius:8px;background:var(--slot);display:flex;align-items:center;gap:8px;padding:0 12px}
body.tpl-tech .search svg{width:16px;height:16px;stroke:var(--txt4);flex:none}
body.tpl-tech .search input{background:none;border:none;outline:none;color:var(--txt2);font-size:12px;font-family:var(--fz);width:100%}
body.tpl-tech .search input::placeholder{color:var(--txt4)}
body.tpl-tech .list-title{font-size:13px;font-weight:500;color:var(--txt3)}
body.tpl-tech .unit-row{display:flex;align-items:center;gap:8px;border-radius:8px;padding:10px;cursor:pointer}
body.tpl-tech .unit-row:hover{background:#16233A}
body.tpl-tech .unit-row.on{background:var(--red-bg);border:1px solid var(--red)}
body.tpl-tech .unit-row .nm{flex:1;font-size:13px;color:var(--txt2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
body.tpl-tech .unit-row.on .nm{color:#FFF;font-weight:500}
body.tpl-tech .unit-row .km{font-family:var(--fm);font-size:11px;color:var(--txt3)}
body.tpl-tech .unit-row.on .km{color:var(--yellow)}
body.tpl-tech .unit-panel .tip{font-size:11px;color:var(--txt4);margin-top:auto;line-height:16px}
body.tpl-tech .map-wrap{flex:1;min-width:0;background:var(--map-bg);border:1px solid var(--line);border-radius:12px;position:relative;overflow:hidden}
body.tpl-tech .map-svg{position:absolute;left:0;top:0}
body.tpl-tech .map-tag{position:absolute;display:flex;gap:6px;border-radius:6px;background:var(--bg);padding:5px 10px;font-family:var(--fm);font-size:11px;white-space:nowrap}
body.tpl-tech .map-tag.b{border:1px solid var(--red);color:var(--red-t)}
body.tpl-tech .map-tag.o{border:1px solid var(--orange);color:var(--orange-t)}
body.tpl-tech .map-tag.u{border:1px solid var(--blue);color:var(--blue-t)}
body.tpl-tech .target-tag{position:absolute;background:var(--red);border-radius:8px;padding:8px 14px;display:flex;flex-direction:column;gap:2px}
body.tpl-tech .target-tag .n{font-size:13px;font-weight:600;color:#FFF}
body.tpl-tech .target-tag .g{font-size:10px;color:#FFD9DC}
body.tpl-tech .legend{position:absolute;left:16px;bottom:8px;display:flex;gap:14px;background:var(--bg);border-radius:8px;padding:8px 14px}
body.tpl-tech .legend .li{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--txt3)}
body.tpl-tech .task-panel{width:360px;flex:none;display:flex;flex-direction:column;gap:14px;padding:20px;overflow:auto}
body.tpl-tech .task-head{display:flex;align-items:center;justify-content:space-between}
body.tpl-tech .btn-red{background:var(--red);border-radius:6px;padding:7px 12px;display:flex;align-items:center;gap:6px;font-size:12px;font-weight:500;color:#FFF;cursor:pointer;border:none}
body.tpl-tech .task-panel .obj{font-size:12px;color:var(--txt3)}
body.tpl-tech .sum{display:flex;gap:12px;background:var(--panel2);border-radius:8px;padding:12px 14px}
body.tpl-tech .sum .i{display:flex;flex-direction:column;gap:2px;margin-right:12px}
body.tpl-tech .sum .v{font-family:var(--fm);font-weight:500;font-size:22px;color:var(--txt);line-height:1.1}
body.tpl-tech .sum .v.y{color:var(--yellow)}
body.tpl-tech .sum .n{font-size:10px;color:var(--txt4)}
body.tpl-tech .task-card{background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:14px;display:flex;flex-direction:column;gap:10px}
body.tpl-tech .task-card .hd{display:flex;justify-content:space-between;align-items:baseline}
body.tpl-tech .task-card .stn{font-size:13px;font-weight:600;color:#FFF}
body.tpl-tech .task-card .km{font-family:var(--fm);font-size:11px}
body.tpl-tech .task-card .tags{display:flex;flex-wrap:wrap;gap:6px}
body.tpl-tech .tagchip{border-radius:4px;padding:4px 8px;font-size:11px}
body.tpl-tech .task-card .force{font-family:var(--fm);font-size:11px;color:var(--txt2)}
body.tpl-tech .task-card .todo{font-size:11px;color:var(--txt3);line-height:17px}

/* ============ 屏幕3 / 4 信息头 ============ */
/* v1.1.0.184：允许换行 + 左侧文字区可收缩 —— 原来 .l 是 flex:1 但没有 min-width:0，
   长标题/下拉框会把右侧操作按钮（「上传平面图 / 在线编辑 / 导出部署图」）挤出视口
   （用户截图实证：按钮被切掉一半）。 */
body.tpl-tech .info-head{display:flex;align-items:center;gap:16px;padding:20px;flex-wrap:wrap}
body.tpl-tech .info-head .l{display:flex;flex-direction:column;gap:4px;flex:1 1 260px;min-width:0}
body.tpl-tech .info-head .nrow{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
body.tpl-tech .info-head .t{font-size:20px;font-weight:700;color:var(--txt)}
body.tpl-tech .info-head .lv{background:var(--red-bg);border-radius:4px;padding:3px 8px;font-size:11px;font-weight:500;color:var(--red-t)}
body.tpl-tech .info-head .mode{display:flex;align-items:center;gap:6px;background:var(--blue-bg);border-radius:4px;padding:3px 8px;font-size:11px;color:var(--blue-t)}
body.tpl-tech .info-head .sub{font-size:12px;color:var(--txt4)}
body.tpl-tech .info-head .ops{display:flex;gap:10px}
body.tpl-tech .btn{border-radius:8px;padding:9px 16px;font-size:13px;font-weight:500;cursor:pointer;border:none}
body.tpl-tech .btn.p{background:var(--red);color:#FFF}
body.tpl-tech .btn.s{background:var(--slot);color:var(--txt3)}
body.tpl-tech .btn.s.w{color:var(--txt1)}
body.tpl-tech .deploy-main{display:flex;gap:16px;flex:none}
body.tpl-tech .grade-sec{display:flex;flex-direction:column;gap:10px;flex:1}
body.tpl-tech .sec-head{display:flex;align-items:center;gap:8px}
body.tpl-tech .sec-head .lv{border-radius:4px;padding:2px 8px;font-size:12px;font-weight:700;color:#FFF}
body.tpl-tech .sec-head .d{font-size:13px;font-weight:600;color:var(--txt1)}
body.tpl-tech .sec-head .c{font-family:var(--fm);font-size:11px;color:var(--txt4)}
body.tpl-tech .squad-row{display:flex;gap:12px}
body.tpl-tech .squad{flex:1;background:var(--panel2);border-radius:10px;padding:14px;display:flex;flex-direction:column;gap:8px}
body.tpl-tech .squad.b{border:1px solid var(--blue)} .squad.o{border:1px solid var(--orange)} .squad.r{border:1px solid var(--red)}
body.tpl-tech .squad .nm{font-size:14px;font-weight:600;color:var(--txt)}
body.tpl-tech .squad .fc{font-family:var(--fm);font-size:11px;color:var(--txt2)}
body.tpl-tech .squad .tk{font-size:12px;color:var(--txt3);line-height:18px}
body.tpl-tech .squad .stt{font-size:12px;font-weight:500}
body.tpl-tech .summary-panel{width:320px;flex:none;display:flex;flex-direction:column;gap:14px;padding:20px;align-self:flex-start}
body.tpl-tech .summary-panel .hd .t{font-size:15px;font-weight:600;color:var(--txt1)}
body.tpl-tech .summary-panel .hd .s{font-size:12px;color:var(--txt3);margin-top:2px}
body.tpl-tech .ratio-line{display:flex;align-items:center;gap:10px}
body.tpl-tech .ratio-line .lv{width:36px;flex:none;font-size:12px;color:var(--txt2)}
body.tpl-tech .ratio-line .v{width:36px;flex:none;font-family:var(--fm);font-size:11px;color:var(--txt2);text-align:right}
body.tpl-tech .link-line{display:flex;align-items:center;gap:8px;padding:4px 0}
body.tpl-tech .link-line .u{flex:1;font-size:12px;color:var(--txt2)}
body.tpl-tech .link-line .s{font-size:11px}
body.tpl-tech .sec-sub{font-size:13px;font-weight:500;color:var(--txt3)}
body.tpl-tech .joint-zone{flex:1;display:flex;flex-direction:column;gap:10px;min-height:0}
body.tpl-tech .joint-row{display:flex;gap:12px}
body.tpl-tech .joint-card{flex:1;background:var(--panel2);border:1px solid var(--cyan-line);border-radius:10px;padding:14px;display:flex;flex-direction:column;gap:7px}
body.tpl-tech .joint-card .n{font-size:13px;font-weight:600;color:var(--txt)}
body.tpl-tech .joint-card .f{font-family:var(--fm);font-size:11px;color:var(--txt2)}
body.tpl-tech .joint-card .k{font-size:11px;color:var(--txt3);line-height:17px}
body.tpl-tech .joint-card .s{font-size:12px;font-weight:500}

/* ============ 屏幕4 力量部署 ============ */
body.tpl-tech #screen-deploy .content{overflow:hidden}
body.tpl-tech .layer-panel{width:220px;flex:none;display:flex;flex-direction:column;gap:12px;padding:16px;overflow:auto}
body.tpl-tech .pt{font-size:13px;font-weight:600;color:var(--txt1)}
body.tpl-tech .lg-line{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--txt2)}
body.tpl-tech .layer-item{display:flex;align-items:center;gap:8px;border-radius:8px;padding:8px 10px;cursor:pointer}
body.tpl-tech .layer-item.on{background:var(--blue-bg)}
body.tpl-tech .layer-item .ln{flex:1;font-size:12px;color:var(--txt3)}
body.tpl-tech .layer-item.on .ln{color:#FFF;font-weight:500}
body.tpl-tech .layer-item .lc{font-family:var(--fm);font-size:10px;color:var(--txt4)}
body.tpl-tech .layer-item.on .lc{color:var(--blue-t);font-size:10px}
body.tpl-tech .divider{height:1px;background:var(--slot);flex:none}
body.tpl-tech .tool-grid{display:flex;flex-wrap:wrap;gap:8px}
body.tpl-tech .tool-chip{border-radius:6px;padding:7px 10px;font-size:11px;background:var(--slot);color:var(--txt2)}
body.tpl-tech .tool-chip.on{background:var(--red-bg);color:var(--red-t)}
/* v1.1.0.184：三栏容器（部署图层 / 画布 / 现场部署清单）——
   桌面为横向三栏；≤1100 与 ≤900 的媒体查询会把 display 改成 grid 做纵向堆叠。
   ⚠ 布局属性必须写在 CSS 里：早前放在 HTML 内联样式上（display:flex），
     其特异度高于 class，导致媒体查询里的 grid 完全失效（实测 900 宽时画布仅剩 76px）。 */
body.tpl-tech #screen-deploy .dp-main{display:flex;flex-direction:row;gap:16px}
body.tpl-tech .canvas-wrap{flex:1;min-width:0;background:var(--map-bg);border:1px solid var(--line);border-radius:12px;position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center}
/* v1.1.0.184：富平面图（1100×844 手绘 SVG）改为**等比缩放适配容器**。
   ⚠ 原来固定 width:1100px;height:844px —— 画布容器窄于 1100px 时被 overflow:hidden
     裁掉右侧一大块（用户反馈「没有做自适应」的另一半）。
   ⚠ 为什么用 transform: scale 而不是给 SVG 加 viewBox：
     平面图里的房间标签/力量标签（.room-lb / .map-tag）是**绝对定位的像素坐标**，
     只缩 SVG 会让标签与图错位；整体缩放容器才能让 SVG 与所有标签同步等比。
   ⚠ 为什么改成 absolute：transform 不改变布局尺寸，若仍留在 flex 流里，
     那个 1100px 的布局盒仍会把容器撑宽（等于没修）。改为绝对定位 + translate 居中，
     布局不再占位，缩放后自然完整可见。 */
body.tpl-tech .floorplan{position:absolute;left:50%;top:50%;width:1100px;height:844px;flex:none;
  transform:translate(-50%,-50%) scale(var(--fp-scale,1));transform-origin:center center}
/* v1.1.0.184：真实部署模板上传的平面图（#dpEmbed）也必须能铺满容器 ——
   原 .floorplan.embed 的 width/height:100% 被上面 `body.tpl-tech .floorplan`
   的 1100px 覆盖（前者特异度 0,2,0 < 后者 0,2,1）→ 一直按 1100px 渲染、窄屏必裁。 */
body.tpl-tech .floorplan.embed{position:absolute;inset:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center;background:#0D1626;border-radius:10px;transform:none}
body.tpl-tech .floorplan.embed svg{width:100%;height:100%}
/* ⚠ v1.1.0.184：必须显式让 [hidden] 真正隐藏 ——
   上一条规则里的 display:flex 特异度高于 UA 的 `[hidden]{display:none}`，
   于是 hidden=true 的 #dpEmbed 依然显示，且因它在 DOM 里排在 #floorplan 之后
   而**盖在富平面图上面**（实测：选中单位后画布仍显示「未选择重点单位」空态）。
   两个视图靠 hidden 属性互斥，故这里必须把 hidden 的语义补回来。 */
body.tpl-tech .floorplan[hidden]{display:none}
body.tpl-tech .room-lb{position:absolute;font-size:12px;color:var(--txt4);white-space:nowrap}
/* v1.1.0.184：标签字号/内边距**反缩放补偿** ——
   平面图整体被 transform 缩小后，标签若跟着缩，12px 会变成 7px（实测 1920 宽时
   scale≈0.6）→ 完全不可读。这里按 1/scale 反算字号与内边距，让标签始终保持可读尺寸。
   ⚠ 上限 15px：极窄屏（scale≈0.4）时若无上限，字号会飙到 28px、标签互相重叠。
   ⚠ !important：部分标签在 HTML 上带内联 font-size/padding，不覆盖会失效。 */
body.tpl-tech .floorplan .room-lb{
  font-size:min(calc(12px / var(--fp-scale,1)), 15px) !important;
  padding:min(calc(3px / var(--fp-scale,1)), 5px) min(calc(8px / var(--fp-scale,1)), 13px);
}
body.tpl-tech .floorplan .map-tag{
  font-size:min(calc(11px / var(--fp-scale,1)), 14px) !important;
  padding:min(calc(5px / var(--fp-scale,1)), 8px) min(calc(10px / var(--fp-scale,1)), 16px);
}
body.tpl-tech .zoom-ctl{position:absolute;right:24px;top:16px;background:var(--bg);border:1px solid var(--line);border-radius:8px;display:flex;flex-direction:column;gap:2px;overflow:hidden}
body.tpl-tech .zoom-ctl div{width:40px;height:32px;display:flex;align-items:center;justify-content:center;font-family:var(--fm);color:var(--txt2);cursor:pointer;font-size:16px}
body.tpl-tech .zoom-ctl div:hover{background:var(--slot)}
body.tpl-tech .status-bar{position:absolute;left:16px;bottom:16px;display:flex;align-items:center;gap:10px;background:var(--bg);border-radius:6px;padding:7px 12px;font-size:11px;color:var(--txt3)}
body.tpl-tech .clue-panel{width:320px;flex:none;display:flex;flex-direction:column;gap:10px;padding:20px;overflow:auto}
body.tpl-tech .clue-panel .hd .t{font-size:15px;font-weight:600;color:var(--txt1)}
body.tpl-tech .clue-panel .hd .s{font-size:12px;color:var(--txt3);margin-top:2px}
body.tpl-tech .sel-card{background:var(--panel2);border:1px solid var(--red);border-radius:10px;padding:14px;display:flex;flex-direction:column;gap:8px}
body.tpl-tech .sel-card .hd{display:flex;align-items:center;justify-content:space-between}
body.tpl-tech .sel-card .n{font-size:13px;font-weight:600;color:#FFF}
body.tpl-tech .sel-card .lv{background:var(--red);border-radius:4px;padding:2px 7px;font-size:10px;font-weight:700;color:#FFF}
body.tpl-tech .sel-card .loc{font-size:11px;color:var(--txt3)}
body.tpl-tech .sel-card .fc{font-family:var(--fm);font-size:11px;color:var(--txt2)}
body.tpl-tech .sel-card .ops{display:flex;gap:8px}
body.tpl-tech .btn-mini{border-radius:5px;padding:5px 10px;font-size:11px;cursor:pointer;border:none}
body.tpl-tech .btn-mini.s{background:var(--slot);color:var(--txt2)}
body.tpl-tech .btn-mini.p{background:var(--red);color:#FFF}
body.tpl-tech .group-head{display:flex;align-items:center;gap:8px;padding-bottom:3px}
body.tpl-tech .group-head .stn{border-radius:4px;padding:2px 8px;font-size:11px;font-weight:700;color:#FFF}
body.tpl-tech .group-head .d{font-size:12px;font-weight:600;color:var(--txt1)}
body.tpl-tech .group-head .c{font-family:var(--fm);font-size:10px;color:var(--txt4)}
body.tpl-tech .point-row{display:flex;align-items:center;gap:8px;border-radius:6px;padding:4px 10px;cursor:pointer}
body.tpl-tech .point-row.on{background:var(--blue-bg)}
body.tpl-tech .point-row .n{flex:1;font-size:12px;color:var(--txt2)}
body.tpl-tech .point-row.on .n{color:#FFF;font-weight:500}
body.tpl-tech .point-row .p{font-size:10px;color:var(--txt4)}
body.tpl-tech .point-row.on .p{color:var(--blue-t)}
body.tpl-tech .veh-line{padding:4px 4px 0 25px;font-family:var(--fm);font-size:10px;color:var(--mono-car)}
body.tpl-tech .todo-line{padding:5px 4px 0 25px;font-size:10px;color:var(--txt4)}

/* ============ 屏幕5 台账 ============ */
body.tpl-tech .page-head{display:flex;justify-content:space-between;align-items:flex-start}
body.tpl-tech .page-head .l{display:flex;flex-direction:column;gap:4px}
body.tpl-tech .page-head .nrow{display:flex;align-items:center;gap:10px}
body.tpl-tech .page-head .t{font-size:20px;font-weight:700;color:var(--txt)}
body.tpl-tech .page-head .scope{background:var(--blue-bg);border-radius:4px;padding:3px 8px;font-size:11px;font-weight:500;color:var(--blue-t)}
body.tpl-tech .page-head .d{font-size:12px;color:var(--txt4)}
body.tpl-tech .filter-row{display:flex;align-items:center;gap:10px}
body.tpl-tech .chip{border-radius:6px;padding:7px 14px;font-size:12px;background:var(--panel);color:var(--txt3);cursor:pointer;border:none}
body.tpl-tech .chip.on{background:var(--blue);color:#FFF;font-weight:500}
body.tpl-tech .filter-row .sp{flex:1}
body.tpl-tech .grid-sec{display:flex;flex-direction:column;gap:12px}
body.tpl-tech .sec-head2{display:flex;align-items:center;gap:8px}
body.tpl-tech .sec-head2 .n{font-size:14px;font-weight:600;color:var(--txt)}
body.tpl-tech .sec-head2 .c{font-family:var(--fm);font-size:11px;color:var(--blue)}
body.tpl-tech .sec-head2 .sp{flex:1}
body.tpl-tech .sec-head2 .fold{font-size:11px;color:var(--blue);cursor:pointer}
body.tpl-tech .ledger-grid{display:flex;flex-wrap:wrap;gap:10px}
body.tpl-tech .ledger-card{width:300px;height:158px;background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:10px 12px;display:flex;flex-direction:column;justify-content:space-between;flex:none}
body.tpl-tech .ledger-card .hd{display:flex;align-items:center;gap:8px}
body.tpl-tech .ledger-card .cat{border-radius:4px;padding:2px 8px;font-size:11px;font-weight:700;flex:none}
body.tpl-tech .ledger-card .nm{flex:1;font-size:14px;font-weight:600;color:var(--txt);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
body.tpl-tech .ledger-card .ed{font-size:11px;color:var(--blue);cursor:pointer;flex:none}
body.tpl-tech .ledger-card .ct{font-family:var(--fm);font-size:12px;color:var(--txt2)}
body.tpl-tech .ledger-card .ad{font-size:11px;color:var(--txt4)}
body.tpl-tech .ledger-card .gd{font-family:var(--fm);font-size:11px;color:var(--txt3);line-height:15px;white-space:pre-line}
body.tpl-tech .ledger-card .mt{display:flex;justify-content:space-between;font-family:var(--fm);font-size:11px}
body.tpl-tech .ledger-card .mt .tec{color:var(--blue-t)}
body.tpl-tech .ledger-card .mt .veh{color:var(--yellow)}
body.tpl-tech .ledger-card .mt .veh.none{color:var(--txt4)}
body.tpl-tech .district-group{display:flex;flex-wrap:wrap;gap:10px}
body.tpl-tech .district-bar{width:931px;height:44px;background:var(--panel);border:1px solid var(--line);border-radius:10px;display:flex;align-items:center;gap:10px;padding:0 14px;cursor:pointer;flex:none}
body.tpl-tech .district-bar .ar{font-family:var(--fm);font-size:12px;color:#5A6B84}
body.tpl-tech .district-bar.open .ar{color:var(--blue)}
body.tpl-tech .district-bar .n{font-size:13px;font-weight:600;color:var(--txt)}
body.tpl-tech .district-bar .c{font-family:var(--fm);font-size:11px;color:var(--blue)}
body.tpl-tech .district-bar .sp{flex:1}
body.tpl-tech .district-bar .h{font-size:11px;color:var(--txt5)}
body.tpl-tech .district-cards{width:100%;display:none;flex-wrap:wrap;gap:10px}
body.tpl-tech .district-block.open .district-cards{display:flex}
body.tpl-tech .district-block{display:flex;flex-wrap:wrap;gap:10px;width:1872px}
body.tpl-tech .note-bar{background:var(--panel2);border-radius:8px;padding:10px 14px;display:flex;align-items:center;gap:10px;flex:none}
body.tpl-tech .note-bar .dotc{width:6px;height:6px;border-radius:50%;background:var(--cyan);flex:none}
body.tpl-tech .note-bar .x{font-size:11px;color:var(--txt3)}
/* 台账后台页无左侧导航（与设计稿一致，内容宽 1872） */
body.tpl-tech #stage[data-screen="ledger"] .sidenav{display:none}
body.tpl-tech #stage[data-screen="tpl"] .sidenav{display:none}

/* ============ 屏幕6 部署模板管理 ============ */
body.tpl-tech .tpl-grid{display:flex;flex-wrap:wrap;gap:21px}
body.tpl-tech .tpl-card{width:610px;height:260px;background:var(--panel);border:1px solid var(--line);border-radius:12px;display:flex;gap:14px;padding:14px;flex:none}
body.tpl-tech .tpl-thumb{width:240px;flex:none;display:flex;flex-direction:column;gap:6px}
body.tpl-tech .tpl-thumb .img{width:240px;height:200px;border-radius:8px;overflow:hidden;background:var(--map-bg)}
body.tpl-tech .tpl-thumb .img svg{display:block}
body.tpl-tech .floor-tabs{display:flex;flex-wrap:wrap;gap:4px}
body.tpl-tech .ftab{border:none;border-radius:4px;padding:3px 8px;font-size:9px;font-family:var(--fz);background:var(--slot);color:var(--txt3);cursor:pointer}
body.tpl-tech .ftab.on{background:var(--blue);color:#FFF;font-weight:500}
body.tpl-tech .tpl-info{flex:1;display:flex;flex-direction:column;gap:8px;min-width:0}
body.tpl-tech .tpl-info .r1{display:flex;align-items:center;gap:8px}
body.tpl-tech .tpl-info .nm{font-size:14px;font-weight:600;color:var(--txt)}
body.tpl-tech .badge{border-radius:4px;padding:2px 8px;font-size:10px;font-weight:500}
body.tpl-tech .badge.pub{background:var(--green-bg);color:var(--green-t)}
body.tpl-tech .badge.edit{background:var(--orange-bg);color:#FFB224}
body.tpl-tech .badge.draft{background:var(--slot);color:var(--txt4)}
body.tpl-tech .tpl-info .meta{font-family:var(--fm);font-size:11px;color:var(--txt4)}
body.tpl-tech .tpl-info .meta2{font-family:var(--fm);font-size:11px;color:var(--txt3)}
body.tpl-tech .tpl-info .bind{font-size:11px;color:var(--txt3)}
body.tpl-tech .tpl-info .flx{flex:1}
body.tpl-tech .tpl-info .r5{display:flex;align-items:center;gap:10px}
body.tpl-tech .tpl-info .r5 .tm{font-family:var(--fm);font-size:10px;color:var(--txt4)}
body.tpl-tech .tpl-info .r5 .sp{flex:1}
body.tpl-tech .tpl-info .r5 .ops{font-size:11px;color:var(--blue);cursor:pointer}
body.tpl-tech .group-sec{display:flex;flex-direction:column;gap:10px}
body.tpl-tech .group-head{display:flex;align-items:center;gap:10px}
body.tpl-tech .group-head .n{font-size:13px;font-weight:600;color:var(--txt)}
body.tpl-tech .group-head .d{font-size:11px;color:var(--txt4)}
body.tpl-tech .group-head .sp{flex:1}
body.tpl-tech .group-head .add{font-size:11px;font-weight:500;color:var(--blue);cursor:pointer}
body.tpl-tech .group-row{display:flex;gap:12px}
body.tpl-tech .g-card{width:302px;height:188px;background:var(--panel);border:1px solid var(--line);border-radius:10px;display:flex;gap:10px;padding:12px;flex:none}
body.tpl-tech .g-card.cur{border-color:var(--blue)}
body.tpl-tech .g-card .img{width:120px;height:164px;border-radius:6px;overflow:hidden;background:var(--map-bg);flex:none}
body.tpl-tech .g-card .img svg{display:block}
body.tpl-tech .g-info{flex:1;display:flex;flex-direction:column;gap:6px;min-width:0}
body.tpl-tech .g-info .r1{display:flex;align-items:center;gap:6px}
body.tpl-tech .g-info .fn{font-size:12px;font-weight:600;color:var(--txt)}
body.tpl-tech .g-info .use{font-size:10px;color:var(--txt4)}
body.tpl-tech .g-info .pt{font-family:var(--fm);font-size:10px;color:var(--txt3)}
body.tpl-tech .g-info .flx{flex:1}
body.tpl-tech .g-info .r5{display:flex;align-items:center;justify-content:space-between}
body.tpl-tech .g-info .r5 .tm{font-family:var(--fm);font-size:9px;color:var(--txt4)}
body.tpl-tech .g-info .r5 .up{font-size:10px;font-weight:500;color:var(--blue);cursor:pointer}


/* ============ v1.1.0.156：力量部署 · 单位 / 楼层切换 ============ */
/* 原「部署模板管理」屏能力并入：选重点单位 → 切楼层（布局相同楼层共用一张平面图） */
.dp-switch { flex: none; display: flex; flex-direction: column; gap: 8px; padding: 10px 14px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); }
.dp-row { display: flex; align-items: center; gap: 10px; min-height: 30px; }
/* v1.1.0.184：单位选择下拉可收缩（原来 max-width:340px 但无 min-width:0，
   窄屏时会把信息头整行撑宽、把右侧按钮挤出视口） */
.dp-row select { min-width: 0; }
.dp-lb { flex: none; font-size: 11px; letter-spacing: 2px; color: var(--txt3); font-family: var(--fz); }
.dp-units, .dp-floors { display: flex; gap: 6px; flex-wrap: wrap; }
.dchip { padding: 5px 12px; border-radius: 7px; border: 1px solid var(--line); background: transparent; color: var(--txt2); font-size: 12px; font-family: var(--fz); cursor: pointer; transition: all .15s ease; }
.dchip:hover { border-color: var(--blue); color: var(--txt); }
.dchip.on { background: rgba(62,139,255,.16); border-color: var(--blue); color: var(--blue-t); font-weight: 500; }
.fchip { position: relative; padding: 5px 12px; border-radius: 7px; border: 1px solid var(--line); background: transparent; color: var(--txt2); font-size: 12px; font-family: var(--fm); cursor: pointer; transition: all .15s ease; }
.fchip:hover { border-color: var(--blue); color: var(--txt); }
.fchip.on { background: rgba(229,72,77,.14); border-color: var(--red); color: var(--red-t); font-weight: 500; }
.fchip i { font-style: normal; margin-left: 6px; font-size: 9.5px; padding: 1px 5px; border-radius: 999px; background: rgba(77,216,228,.14); color: #4DD8E4; font-family: var(--fz); }
.layer-item .sh { margin-left: 8px; font-size: 9.5px; padding: 1px 6px; border-radius: 999px; background: rgba(77,216,228,.14); color: #4DD8E4; font-family: var(--fz); vertical-align: 1px; }
/* 非富平面图视图：已上传平面图缩略 SVG 等比铺满画布
   ⚠ v1.1.0.184：此处原有的无前缀 `.floorplan.embed` 规则已删除 ——
     它被 `body.tpl-tech .floorplan`（特异度 0,2,1）反向覆盖，
     导致 #dpEmbed 一直按 1100px 渲染。改由前文带前缀的规则接管。 */

/* ============ v1.1.0.157：真实组件内嵌（iframe 同源） ============ */
/* 模块一 = 站点默认模板首页（embed=home）；模块二地图 = 站点同款地图（embed=map）。
   iframe 与主页面同源、共享登录态；舞台 1920×1080 等比缩放时内嵌页同样缩放。 */
.embed-host { padding: 0 !important; }
.embed-frame { display: block; width: 100%; height: 100%; border: 0; background: #0D1626; }
#screen-home .embed-frame { border-radius: 0; }

/* ============ v1.1.0.160：力量部署图例条 + 空态 ============ */
/* 图例条：恒显于画布底部（任何视图模式：富平面图 / 上传图片 / 空态），修复图例显示不完全 */
.dp-legendbar { position: absolute; left: 12px; right: 12px; bottom: 10px; z-index: 5;
  display: flex; flex-wrap: wrap; gap: 6px 16px; align-items: center;
  padding: 7px 12px; border-radius: 8px;
  background: rgba(10, 18, 32, .82); border: 1px solid #223047;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.dp-legendbar span { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; color: #D5DCE8; font-family: var(--fz); white-space: nowrap; }
.dp-legendbar .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
/* 空态（调派面板 / 平面图 / 部署清单通用） */
.dp-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; text-align: center; padding: 22px 16px; }
.dp-empty.small { padding: 16px 10px; }
.dp-empty .e-ico { font-size: 26px; opacity: .85; }
.dp-empty .e-t { font-size: 13px; font-weight: 600; color: var(--txt1, #F2F5FA); }
.dp-empty .e-d { font-size: 11.5px; line-height: 1.7; color: var(--txt4, #9AA8BF); max-width: 260px; }
.dp-empty .btn-red { margin-top: 4px; display: inline-flex; align-items: center; gap: 6px; padding: 7px 16px; text-decoration: none; }

/* ============ v1.1.0.161：行进路线按钮 + 进入管理后台入口 ============ */
.task-head .sp { flex: 1; }
.btn-route { display: inline-flex; align-items: center; gap: 6px; padding: 7px 13px; border-radius: 7px;
  border: 1px solid rgba(62,139,255,.55); background: rgba(62,139,255,.16); color: #7FB1FF;
  font-size: 12px; font-family: var(--fz); cursor: pointer; transition: background .15s ease; }
.btn-route:hover { background: rgba(62,139,255,.30); }
.btn-route:disabled { opacity: .6; cursor: default; }
.admin-entry { display: inline-flex; align-items: center; gap: 6px; padding: 6px 13px; border-radius: 999px;
  border: 1px solid rgba(229,72,77,.55); background: rgba(229,72,77,.10); color: #FF8A8F;
  font-size: 11.5px; font-family: var(--fz); text-decoration: none; white-space: nowrap; }
.admin-entry:hover { background: rgba(229,72,77,.24); color: #FFB3B6; }
.admin-entry svg { width: 14px; height: 14px; }

/* ============ v1.1.0.162：力量部署标注层 / 工具配色 / 图例动态 ============ */
.dp-canvas-inner { position: relative; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; }
.dp-canvas-inner > img { max-width: 96%; max-height: 96%; object-fit: contain; user-select: none; }
.dp-points { position: absolute; inset: 0; }
.dp-pt { position: absolute; transform: translate(-50%, -50%); cursor: default; }
.dp-pt.point { display: flex; flex-direction: column; align-items: center; gap: 3px; }
.dp-pt.point i { width: 14px; height: 14px; border-radius: 50%; border: 2px solid #FFF; display: block; }
.dp-pt.point span, .dp-pt.rect span { font-size: 10px; padding: 2px 6px; border-radius: 4px; background: rgba(10,18,32,.85); white-space: nowrap; font-family: var(--fz); }
.dp-pt.rect { transform: none; border: 2px dashed; border-radius: 6px; }
.dp-pt.rect span { position: absolute; left: 0; top: -20px; }
.dp-pt.text { font-size: 13px; font-weight: 600; white-space: nowrap; text-shadow: 0 1px 3px rgba(0,0,0,.8); font-family: var(--fz); }
.dp-pt.drawing { pointer-events: none; }
.dp-colors { display: flex; gap: 8px; flex-wrap: wrap; }
.dp-colors .c { width: 22px; height: 22px; border-radius: 6px; cursor: pointer; display: inline-block; border: 2px solid transparent; }
.dp-colors .c.on { border-color: #FFF; box-shadow: 0 0 0 2px rgba(255,255,255,.35); }
.dp-legendbar { flex-wrap: wrap; }

/* v1.1.0.162：顶栏角色卡与后台入口尺寸统一（胶囊等高） */
.topbar .user.admin-link { text-decoration: none; }
.topbar .admin-entry { padding: 8px 14px; }
.topbar .user { padding: 4px 6px; }

/* v1.1.0.163：行进路线 / 详细任务分工按钮间距（用户反馈过近） */
.task-head { gap: 10px; }
.task-head .btn-route { margin-right: 6px; }

/* ============ v1.1.0.163：前台角色卡面板（不跳后台） ============ */
/* v1.1.0.181：**外壳已并入全站统一弹窗规范**（.mask / .modal*，唯一来源 user-panel.css）。
   原先这里自写一套 .tu-mask / .tu-panel（硬编码色值 #0D1626 / #223047 / #1C2A42），
   与其它弹窗观感不一致 → 现只保留**内容区**样式（字段 / 分组 / 提示 / 按钮外观），
   外壳（遮罩、面板、标题、关闭键、底部按钮区）一律用统一的 .mask/.modal*。
   ⚠ 因此 .tu-head / .tu-body / .tu-close / .tu-btn 现在只是**语义标记**，
     视觉全部继承统一规范，不再自带尺寸与配色（避免两套规则打架）。 */
.tu-panel { width: 100%; max-width: 620px; }
.tu-head .t { text-align: left; }
.tu-tabs { display: flex; gap: 4px; padding: 10px 18px 0; }
.tu-tab { padding: 7px 16px; border-radius: 8px 8px 0 0; border: 1px solid transparent; border-bottom: none;
  background: transparent; color: var(--sub); font-size: 12.5px; cursor: pointer; font-family: var(--fz); }
.tu-tab.on { background: var(--panel-2); border-color: var(--line-2); color: var(--txt); font-weight: 600; }
.tu-body { /* 外壳已给出内边距与滚动区，这里不再重复设置 */ }
.tu-sec { display: flex; flex-direction: column; gap: 10px; }
.tu-sec h4 { margin: 4px 0 0; font-size: 12px; letter-spacing: 2px; color: var(--sub); font-family: var(--fz); font-weight: 600; }
.tu-field { display: flex; flex-direction: column; gap: 4px; }
.tu-field label { font-size: 11.5px; color: var(--sub); }
.tu-field input { padding: 8px 11px; border-radius: 8px; border: 1px solid var(--line-2); background: var(--bg-2, var(--panel-2)); color: var(--txt); font-size: 13px; font-family: var(--fz); }
.tu-field input:focus { outline: none; border-color: var(--acc); }
.tu-field input[readonly] { color: var(--sub); background: var(--panel-2); cursor: not-allowed; }
.tu-btn { /* 尺寸与配色继承 .btn / .btn-primary */ }
.tu-msg { min-height: 18px; font-size: 12px; color: var(--acc); }
.tu-msg.err { color: var(--tx-coral, var(--acc)); }
.tu-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 8px; }
.tu-card { padding: 9px; border-radius: 10px; border: 2px solid transparent; cursor: pointer; text-align: left; background: #0D1626; }
.tu-card.sel { border-color: #3E8BFF; }
.tu-card .sw { height: 34px; border-radius: 6px; margin-bottom: 6px; border: 1px solid rgba(255,255,255,.14); }
.tu-card .nm { font-size: 11.5px; color: #F2F5FA; }
.tu-card .hx { font-size: 10px; color: #9AA8BF; font-family: var(--fm); }

/* ============ v1.1.0.164：角色卡与后台 .user-chip 同构同交互 ============ */
/* 悬停点亮（面板底 + 描边）与后台 user-panel.css 的 .user-chip:hover 一致；
   头像 = 姓名首字 + 主题红底；两行文字（姓名 / 角色）。 */
.topbar .user.user-chip { background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.10); border-radius: 999px; padding: 4px 12px 4px 5px; cursor: pointer; }
.topbar .user.user-chip:hover { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.28); }
.topbar .user.user-chip:active { background: rgba(255,255,255,.20); }
.topbar .user.user-chip .av { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center;
  background: var(--red); color: #FFF; font-size: 12.5px; font-weight: 700; }
.topbar .user.user-chip .uinfo { text-align: left; line-height: 1.3; }
.topbar .user.user-chip .unm { font-size: 12.5px; color: #F2F5FA; font-weight: 600; }
.topbar .user.user-chip .url { font-size: 10.5px; color: #9AA8BF; }

/* ============ v1.1.0.164：力量调派详情在线编辑弹窗 ============ */
.de-grp { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px; border: 1px solid #223047; border-radius: 10px; margin-bottom: 10px; background: #0D1626; }
.de-grp .de-t { font-size: 12.5px; font-weight: 700; color: #F2F5FA; }
/* v1.1.0.188：在线编辑弹窗 —— 按队站逐辆登记的车辆行 */
.tu-hint { font-size: 11.5px; color: var(--sub); margin-bottom: 10px; line-height: 1.7; }
.de-vlist { display: flex; flex-direction: column; gap: 6px; }
/* v1.1.0.188：分组头 = 队站名 + 站级「主站/增援」下拉（行内不再逐车选角色） */
.de-grp-h {
  display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap;
  margin-bottom: 8px;
}
.de-rolebox {
  display: flex; align-items: center; gap: 6px;
  font-size: 11.5px; color: var(--sub);
}
.de-rolebox select {
  padding: 5px 8px; border-radius: 7px;
  border: 1px solid var(--line-2); background: var(--bg-2, var(--panel-2));
  color: var(--txt); font-size: 12.5px; font-family: var(--fz);
}
.de-rolebox select.de-srole { min-width: 78px; cursor: pointer; }
.de-rolebox select:focus { outline: none; border-color: var(--acc); }
.de-vrow {
  display: grid;
  grid-template-columns: 92px minmax(110px, 1fr) minmax(104px, .8fr) 78px minmax(140px, 1.4fr) 58px;
  gap: 8px; align-items: center;
}
.de-vrow .de-vno {
  font-family: var(--fm); font-size: 11.5px; color: var(--txt3);
  padding: 7px 8px; border-radius: 7px;
  background: var(--panel2); border: 1px solid var(--line-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.de-vrow select, .de-vrow input {
  padding: 7px 9px; border-radius: 7px;
  border: 1px solid var(--line-2); background: var(--bg-2, var(--panel-2));
  color: var(--txt); font-size: 12.5px; font-family: var(--fz);
  min-width: 0;
}
.de-vrow select:focus, .de-vrow input:focus { outline: none; border-color: var(--acc); }
.de-vadd { align-self: flex-start; margin-top: 8px; }

/* v1.1.0.178：顶栏「适应窗口 / 原始 100%」比例切换按钮已删除 ——
   舞台改为视口自适应后不再需要「换个视角」，按钮与相关逻辑一并移除。 */

/* v1.1.0.168：运行版本徽标（右下角小字，核对线上文件版本用） */
.tech-ver { position: fixed; right: 10px; bottom: 6px; z-index: 60; font-family: var(--fm);
  font-size: 10px; color: #4A5A72; letter-spacing: .3px; pointer-events: none; user-select: none; }

/* ============================================================
   三端自适应（v1.1.0.178）
   ------------------------------------------------------------
   舞台改为视口自适应后，**不再整体缩放**，因此字号保持设计稿的绝对值 ——
   这在桌面上正好，但手机上 11~13px 不可读。故按断点分三档：
     ≥1281 桌面：设计稿原值
     ≤1280 平板：收窄两侧面板，保证地图仍有可用宽度
     ≤900  手机：作战地图屏纵向堆叠 + 关键文字放大
   ============================================================ */
@media (max-width: 1280px) {
  body.tpl-tech .content { padding: 14px; gap: 12px; }
  body.tpl-tech .unit-panel { width: 240px; padding: 12px; gap: 10px; }
  body.tpl-tech .task-panel { width: 290px; padding: 14px; gap: 12px; }
  body.tpl-tech .topbar { padding: 0 14px; gap: 10px; }
  body.tpl-tech .task-card .km, body.tpl-tech .task-card .stn { font-size: 12.5px; }
  /* v1.1.0.184：力量部署三栏同步收窄 —— 否则 1280 宽时画布只剩 480px */
  body.tpl-tech #screen-deploy .layer-panel { width: 190px; padding: 12px; gap: 10px; }
  body.tpl-tech #screen-deploy .clue-panel { width: 270px; padding: 14px; }
}
/* 平板竖屏（≤1100）：作战地图屏改为纵向堆叠 —— 两侧面板并排会把地图挤到
   200 余像素（实测 1024 宽时地图仅 242px），堆叠后地图可占满整宽。 */
@media (max-width: 1100px) {
  body.tpl-tech #screen-map .content { flex-direction: column; }
  body.tpl-tech .unit-panel, body.tpl-tech .task-panel { width: auto; max-height: 38vh; }
  body.tpl-tech .map-wrap { min-height: 56vh; }
  /* v1.1.0.184：力量部署三栏同样纵向堆叠 ——
     实测 900 宽时并排三栏会把画布挤到只剩 100px（平面图几乎不可见）。
     堆叠后：图层与清单并排一行、画布独占下方一行。 */
  body.tpl-tech #screen-deploy .content { overflow: auto; }
  body.tpl-tech #screen-deploy .dp-main {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: auto minmax(320px, 1fr);
    grid-template-areas: "layer clue" "canvas canvas";
    gap: 12px;
    min-height: 0;
  }
  body.tpl-tech #screen-deploy .layer-panel { grid-area: layer; width: auto; max-height: 30vh; }
  body.tpl-tech #screen-deploy .clue-panel { grid-area: clue; width: auto; max-height: 30vh; }
  body.tpl-tech #screen-deploy .canvas-wrap { grid-area: canvas; min-height: 46vh; }
  /* 信息头：标题区与操作按钮在窄屏改为上下排（原来横排会把按钮挤出视口） */
  body.tpl-tech #screen-deploy .info-head { flex-wrap: wrap; }
  body.tpl-tech #screen-deploy .info-head .ops { flex-wrap: wrap; }
}
@media (max-width: 900px) {
  body.tpl-tech .topbar { height: auto; min-height: 52px; padding: 8px 12px; flex-wrap: wrap; }
  body.tpl-tech .nav-tab { height: 40px; font-size: 14px; padding: 0 12px; }
  body.tpl-tech .map-wrap { min-height: 54vh; }
  /* 关键文字放大（设计稿 11~13px 在手机上不可读） */
  body.tpl-tech .list-title, body.tpl-tech .unit-row .nm { font-size: 14.5px; }
  body.tpl-tech .unit-panel .tip, body.tpl-tech .unit-row .km { font-size: 12.5px; }
  body.tpl-tech .task-panel .obj, body.tpl-tech .task-card .stn { font-size: 14px; }
  body.tpl-tech .phead .t { font-size: 16px; }
  body.tpl-tech .btn-red, body.tpl-tech .btn-route { font-size: 13.5px; padding: 9px 14px; }
  body.tpl-tech .badge { font-size: 12px; }
  /* v1.1.0.184：力量部署在 ≤900 时三栏改为单列纵向排（平板竖屏单列更易读） */
  body.tpl-tech #screen-deploy .dp-main {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(300px, 1fr) auto;
    grid-template-areas: "canvas" "layer" "clue";
  }
  body.tpl-tech #screen-deploy .canvas-wrap { min-height: 42vh; }
  body.tpl-tech #screen-deploy .layer-panel,
  body.tpl-tech #screen-deploy .clue-panel { max-height: 26vh; }
}
@media (max-width: 640px) {
  body.tpl-tech .content { padding: 10px; gap: 10px; }
  body.tpl-tech .map-wrap { min-height: 48vh; }
  body.tpl-tech .topbar .sys { font-size: 17px; }
  body.tpl-tech .topbar .time { font-size: 19px; }
  /* 手机：左侧导航改为**顶部横向条** —— 竖排 200px 的导航栏会把内容区压到
     200 余像素（实测 390 宽时内容区仅 277px，地图只剩 257px）。 */
  body.tpl-tech #stage { flex-direction: column; }
  /* .body 也要转纵向 —— 否则横向导航条仍占满整行，内容区被推到视口之外 */
  body.tpl-tech .body { flex-direction: column; }
  body.tpl-tech .sidenav {
    width: auto; flex-direction: row; gap: 8px; padding: 8px 10px;
    overflow-x: auto; border-right: 0; border-bottom: 1px solid var(--line2);
  }
  body.tpl-tech .sidenav .nav-tab { flex: none; height: 40px; padding: 0 14px; font-size: 14px; }
  body.tpl-tech .sidenav .nav-tab svg { width: 18px; height: 18px; }
}

/* ============================================================
   v1.1.0.188：导出任务分工单的专用样式（只在外导出的图片里用）
   · .exp-* 任务分工单的标题 / 汇总 / 分组 / 队站 / 卡片
   ============================================================ */
.exp-root { display: flex; flex-direction: column; gap: 16px; }
.exp-head { padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.exp-head .exp-t { font-size: 22px; font-weight: 700; color: var(--txt); letter-spacing: .5px; }
.exp-head .exp-sub { margin-top: 6px; font-size: 12.5px; color: var(--txt3); }
.exp-sum { display: flex; gap: 12px; }
.exp-sum .i {
  flex: 1; text-align: center; padding: 12px 8px;
  background: var(--panel2); border: 1px solid var(--line); border-radius: 10px;
}
.exp-sum .i .v { display: block; font-family: var(--fm); font-size: 22px; font-weight: 700; color: var(--cyan); }
.exp-sum .i .n { display: block; margin-top: 3px; font-size: 11.5px; color: var(--txt3); }
.exp-group { display: flex; flex-direction: column; gap: 10px; }
.exp-group-h { display: flex; align-items: center; gap: 10px; }
.exp-group-h .lv { font-size: 12px; font-weight: 700; color: #fff; padding: 3px 10px; border-radius: 4px; }
.exp-group-h .d { font-size: 12px; color: var(--txt3); }
.exp-st { padding: 12px 14px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); }
.exp-st-h { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; font-size: 13.5px; color: var(--txt); }
.exp-st-n { margin-left: auto; font-size: 11.5px; color: var(--txt3); }
.exp-card-row { display: flex; flex-wrap: wrap; gap: 12px; }
.exp-card { flex: 1 1 240px; min-width: 220px; max-width: 360px; }
.exp-card .n { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.exp-card .s { color: var(--cyan); font-size: 12px; font-weight: 500; }

/* v1.1.0.188：在线编辑弹窗在窄屏降列（6 列 → 2 列网格），
   否则车辆行会横向溢出弹窗、字段被裁掉。 */
@media (max-width: 900px) {
  .de-vrow { grid-template-columns: 1fr 1fr; gap: 6px 8px; }
  .de-vrow .de-vno { grid-column: 1 / -1; }
  .de-vrow .de-vdel { justify-self: end; }
}
@media (max-width: 640px) {
  .de-vrow { grid-template-columns: 1fr; }
}


/* ============================================================
   v1.1.0.188：力量调派与任务分工（一体化）
   · .dp-simple*   屏幕2 右侧**简易版**：队站名 + 主站/增援标识 + 车辆与人数
   · .dpd-group*   屏幕3 **详细分工页**：按主站 / 增援分两组，组内按队站列车辆
   ============================================================ */
.dp-simple { display: flex; flex-direction: column; gap: 10px; }
.dp-simple-st {
  padding: 9px 11px; border-radius: 8px;
  background: color-mix(in srgb, var(--panel2) 55%, transparent);
  border: 1px solid var(--line2);
}
.dp-simple-h {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  margin-bottom: 6px;
}
.dp-simple-h b { font-size: 13.5px; color: var(--txt1); }
.dp-simple-n { margin-left: auto; font-size: 12px; color: var(--sub); }
/* v1.1.0.188：队站组织编码徽标（02-01） */
.dp-st-code {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 11px; line-height: 1; letter-spacing: .3px;
  padding: 3px 7px; border-radius: 4px;
  color: var(--tx-teal);
  background: color-mix(in srgb, var(--c-luodian) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--c-luodian) 35%, transparent);
}
.dp-role-chip {
  font-size: 11px; line-height: 1; padding: 3px 7px; border-radius: 4px;
  border: 1px solid transparent;
}
.dp-role-chip.main {
  color: var(--red-t); border-color: color-mix(in srgb, var(--red) 40%, transparent);
  background: color-mix(in srgb, var(--red) 16%, transparent);
}
.dp-role-chip.add {
  color: var(--orange-t); border-color: color-mix(in srgb, var(--orange) 40%, transparent);
  background: color-mix(in srgb, var(--orange) 16%, transparent);
}
.dp-simple-v { display: flex; flex-direction: column; gap: 4px; }
.dp-simple-vr {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 12px; color: var(--txt2);
  padding: 3px 0; border-top: 1px dashed var(--line2);
}
.dp-simple-vr:first-child { border-top: 0; }
.dp-simple-vr .no {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 11.5px; color: var(--sub); min-width: 62px;
}
/* v1.1.0.188：车辆名称（车辆编号之后） */
.dp-simple-vr .vt {
  font-size: 11.5px; color: var(--txt1);
  padding: 1px 6px; border-radius: 4px;
  background: color-mix(in srgb, var(--cyan) 13%, transparent);
  border: 1px solid color-mix(in srgb, var(--cyan) 30%, transparent);
  white-space: nowrap;
}
.dp-simple-vr .vt:empty { display: none; }
.dp-simple-vr .vn { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dp-simple-vr .pm { color: var(--sub); min-width: 44px; text-align: right; }

/* 详细分工页：主站 / 增援 两组 */
.dpd-group { margin-bottom: 16px; }
.dpd-group-h {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 9px;
}
.dpd-group-h .lv {
  font-size: 12px; font-weight: 700; color: #fff;
  padding: 3px 10px; border-radius: 4px;
}
.dpd-group-h .d { font-size: 12px; color: var(--sub); }
.dpd-group-h .c { margin-left: auto; font-size: 12px; color: var(--txt2); }
.dpd-group-st {
  padding: 9px 12px; margin-bottom: 9px;
  border-radius: 8px; border: 1px solid var(--line2);
  background: color-mix(in srgb, var(--panel2) 45%, transparent);
}
.dpd-gst-h { margin-bottom: 6px; font-size: 13.5px; color: var(--txt1); }
/* v1.1.0.188：实施力量改为联勤同款卡片模式 —— 队站下逐辆一张卡 */
.dpd-card-row {
  display: flex; flex-wrap: wrap; gap: 12px;
  margin-top: 8px;
}
.dpd-card {
  flex: 1 1 220px; min-width: 200px; max-width: 340px;
  border-color: var(--line);
  background: var(--panel2);
}
.dpd-card .n {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.dpd-card-code {
  font-family: var(--fm); font-size: 11px; font-weight: 500;
  color: var(--txt3);
  padding: 2px 6px; border-radius: 4px;
  background: color-mix(in srgb, var(--cyan) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--cyan) 30%, transparent);
}
/* v1.1.0.188：车辆名称徽标（水罐车 / 大吨位 / 抢险救援 …） */
.dpd-card-name {
  font-size: 11.5px; font-weight: 600;
  color: var(--txt1);
  padding: 2px 7px; border-radius: 4px;
  background: color-mix(in srgb, var(--cyan) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--cyan) 32%, transparent);
}
.dpd-gst-n {
  margin-left: auto; font-size: 11.5px; color: var(--txt3);
}
.dpd-gst-v {
  display: grid; grid-template-columns: 76px minmax(140px, 1.1fr) 62px minmax(150px, 1.4fr);
  gap: 10px; align-items: baseline;
  padding: 5px 0; font-size: 12.5px; color: var(--txt2);
  border-top: 1px dashed var(--line2);
}
.dpd-gst-v:first-of-type { border-top: 0; }
.dpd-gst-v .no {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 11.5px; color: var(--sub);
}
.dpd-gst-v .pm { color: var(--sub); text-align: right; }
.dpd-gst-v .tk { color: var(--txt1); }
