/* ================= iMaster MAE 浅色主题（贴近真实截图） ================= */
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
  /* 报文/示例这类**靠空格对齐**的等宽文本专用字体（2026-10-08 用户报障「'=' 能不能对齐」）：
     服务端按「中文 = 2 个半角宽」补空格（mb_strwidth 口径），字体就必须真满足这个 2:1，
     否则中文落不到偶数格上、'=' 对不齐。实测（12px）：
       Consolas           空格 6.598px / 中文 12px = 1.819 倍  ✗
       "Courier New"      空格 7.201px / 中文 12px = 1.666 倍  ✗
       NSimSun / SimSun   空格 6.000px / 中文 12px = 2.000 倍  ✓
       "MS Gothic"        空格 6.000px / 中文 12px = 2.000 倍  ✓
     所以这里必须让「自带 ASCII 的 1:2 中文字体」排在最前 —— 把 Consolas 放前面就前功尽弃
     （ASCII 走 Consolas、中文走 fallback，比例又变成 1.82）。NSimSun 是 Windows 自带且简繁汉字齐全，
     比 MS Gothic 稳（日文字体缺部分简体字，缺字会再 fallback 破坏对齐）。
     仅用于**显示报文**的区域；输入框、命令名等仍用 Consolas（那里不需要空格对齐）。 */
  --mono-align: NSimSun, SimSun, "MS Gothic", "Sarasa Mono SC", Consolas, "Courier New", monospace;
  /* 背景层 */
  --bg: #f5f7fa;
  --panel: #ffffff;
  --panel-2: #fafbfc;
  --panel-3: #f0f3f8;
  --hover: #eef4ff;
  /* 文本 */
  --text: #1f2329;
  --text-dim: #4e5969;
  --text-faint: #8c959e;
  --text-on-dark: #ffffff;
  --text-on-dark-dim: #c0c4cc;
  /* 边线 */
  --border: #e4e7ed;
  --border-light: #ebeef5;
  --border-strong: #d6d9de;
  /* 顶栏（黑色） */
  --topbar: #1f1f1f;
  --topbar-text: #ffffff;
  --topbar-text-dim: #c0c4cc;
  --topbar-hover: rgba(255,255,255,.08);
  /* 主色（华为蓝） */
  --accent: #2673e5;
  --accent-hover: #1a5fc8;
  --accent-soft: #e8f0fe;
  --accent-border: #b9d2f5;
  /* 状态色 */
  --critical: #f5222d;
  --critical-bg: #ffeded;
  --critical-bg-strong: #ffe0e0;
  --major: #fa8c16;
  --major-bg: #fff3e0;
  --minor: #fadb14;
  --minor-bg: #fffbe6;
  --warning: #1890ff;
  --warning-bg: #e6f4ff;
  --success: #52c41a;
  --success-bg: #f6ffed;
  --gray-soft: #f5f5f5;
  /* 徽标/状态 */
  --status-running: #1890ff;
  --status-completed: #52c41a;
  --status-failed: #f5222d;
  --status-waiting: #faad14;
  --status-paused: #fa8c16;
  /* MML 页分隔条尺寸（拖动改变） */
  --mml-left-w: 360px;       /* 左侧网元栏宽 */
  --mml-tree-h: 200px;       /* mml-left-body 内 tree 框高（剩余给命令导航） */
  --mml-bottom-h: 280px;     /* 编辑命令区高 */
  --meb-detail-h: 34px;      /* 编辑命令区内详细命令框高（分隔条拖动改变） */
}
html, body { height: 100%; }
body {
  font-family: "Microsoft YaHei", "PingFang SC", "Segoe UI", -apple-system, sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 13px;
}
.hidden { display: none !important; }
button, input, select, textarea { font-family: inherit; }

/* ================= 登录页（全屏蓝底 + 左 SVG/标语 + 右浮白卡） ================= */
.login-view {
  position: fixed; inset: 0; z-index: 50; overflow: hidden;
  background: #08245c;
}
.login-view.hidden { display: none; }

/* —— 全屏蓝色背景（径向渐变 + 网格） —— */
.login-bg {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(80% 60% at 35% 45%, #1e6bd9 0%, #10428f 55%, #08245c 100%),
    radial-gradient(70% 50% at 50% 0%,  rgba(120,190,255,.28), transparent 60%),
    radial-gradient(60% 35% at 50% 100%, rgba(60,140,230,.30), transparent 65%);
  background-blend-mode: normal, screen, screen;
}
.login-bg::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(rgba(255,255,255,.045) 1px, transparent 1px) 0 0/40px 40px,
    linear-gradient(90deg, rgba(255,255,255,.045) 1px, transparent 1px) 0 0/40px 40px;
}

/* —— 左半屏：自绘 SVG 插画 + 标语 —— */
.login-svg {
  position: absolute;
  left: 50%; top: 48%;
  transform: translate(-110%, -50%);
  width: min(58vw, 720px); height: auto; max-height: 70vh;
  filter: drop-shadow(0 10px 28px rgba(0,40,110,.45));
  animation: loginFloat 6s ease-in-out infinite;
}
@keyframes loginFloat {
  0%, 100% { transform: translate(-110%, calc(-50% + 0px)); }
  50%      { transform: translate(-110%, calc(-50% - 6px)); }
}
.login-tagline {
  position: absolute;
  left: calc(50% - 22vw); bottom: 13%;
  transform: translateX(-50%);
  font-size: 18px; letter-spacing: 4px; color: #cfe3ff; white-space: nowrap;
  text-shadow: 0 1px 2px rgba(0,30,80,.45);
}

/* —— 登录卡片：右浮动、垂直居中、不到屏幕右边缘 —— */
.login-card {
  position: absolute;
  right: 5%; top: 50%; transform: translateY(-50%);
  width: 360px; padding: 44px 36px 36px;
  background: #ffffff; border-radius: 4px;
  box-shadow: 0 16px 48px rgba(0,16,56,.30), 0 2px 6px rgba(0,16,56,.08);
}
.login-brand {
  display: flex; align-items: center; gap: 10px; margin-bottom: 36px;
}
.brand-mark { flex: none; }
.brand-text { font-size: 20px; color: #1f2329; letter-spacing: .5px; }
.brand-text b { font-weight: 700; }
.brand-text sup { font-size: 12px; font-weight: 600; color: #1f2329; margin-left: 4px; letter-spacing: .5px; }

.login-form { display: flex; flex-direction: column; gap: 18px; }
/* 右侧带图标按钮的输入框，留出按钮宽度 */
.login-user-wrap input, .login-pass-wrap input { padding-right: 34px; }

/* 浮动 label 输入 */
.field-float { position: relative; }
.field-float input {
  width: 100%; height: 44px; padding: 14px 0 8px;
  background: transparent; border: 0; border-bottom: 1px solid #d9dde3;
  outline: 0; font-size: 14px; color: #1f2329;
  transition: border-color .15s;
}
.field-float input:focus { border-bottom-color: #2673e5; }
.field-float label {
  position: absolute; left: 0; top: 14px;
  font-size: 14px; color: #8a9099; pointer-events: none;
  transition: transform .15s, font-size .15s, color .15s;
}
.field-float input:focus + label,
.field-float input:not(:placeholder-shown) + label {
  transform: translateY(-14px); font-size: 12px; color: #2673e5;
}
.field-float input:focus + label { color: #2673e5; }

/* 记住复选框行 */
.login-row { display: flex; align-items: center; min-height: 22px; margin-top: 2px; }
.check { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px; color: #4a5158; user-select: none; }
.check input { position: absolute; opacity: 0; width: 0; height: 0; }
.check-box {
  width: 14px; height: 14px; border: 1.5px solid #b8c0c8; border-radius: 2px;
  display: inline-block; position: relative; transition: all .15s; flex: none;
}
.check input:checked + .check-box { background: #2673e5; border-color: #2673e5; }
.check input:checked + .check-box::after {
  content: ''; position: absolute; left: 3px; top: 0;
  width: 4px; height: 8px;
  border: solid #fff; border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.login-error { color: #d9534f; font-size: 12px; min-height: 14px; margin: 2px 0 -4px; }
.login-error.hidden { display: none; }

/* 满宽蓝色登录按钮 */
.btn-login {
  margin-top: 12px; height: 42px; width: 100%;
  border: 0; border-radius: 4px; cursor: pointer;
  background: linear-gradient(180deg, #2c84f0 0%, #2673e5 100%);
  color: #fff; font-size: 16px; letter-spacing: 8px; font-weight: 500;
  box-shadow: 0 2px 8px rgba(38,115,229,.25);
  transition: transform .08s, box-shadow .15s, filter .15s;
}
.btn-login:hover { filter: brightness(1.06); box-shadow: 0 4px 12px rgba(38,115,229,.35); }
.btn-login:active { transform: translateY(1px); }
.btn-login:disabled { opacity: .55; cursor: not-allowed; filter: none; }

/* —— 响应式：窄屏时登录卡铺满 —— */
@media (max-width: 760px) {
  .login-svg { width: 90vw; opacity: .4; transform: translate(-50%, -50%); }
  .login-tagline { left: 50%; bottom: 24%; transform: translateX(-50%); font-size: 14px; }
  .login-card { right: 5%; left: 5%; width: auto; padding: 36px 24px; }
  @keyframes loginFloat { 0%, 100% { transform: translate(-50%, -50%); } 50% { transform: translate(-50%, calc(-50% - 6px)); } }
}

.btn {
  padding: 7px 14px; border-radius: 4px; border: 1px solid var(--border-strong);
  background: #fff; color: var(--text); cursor: pointer; font-size: 13px;
  transition: all .15s; white-space: nowrap; line-height: 1.4;
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: #fff; }
.btn-danger { background: #fff; border-color: var(--critical); color: var(--critical); }
.btn-danger:hover { background: var(--critical-bg); }
.btn-sm { padding: 3px 10px; font-size: 12px; border-radius: 3px; }
.btn-block { width: 100%; padding: 10px; font-size: 15px; }
.btn-icon { padding: 5px 10px; font-size: 12px; gap: 4px; display: inline-flex; align-items: center; }

/* ================= 主框架 ================= */
.app { display: flex; flex-direction: column; height: 100vh; overflow: hidden; }

/* 黑色顶栏 */
.topbar {
  height: 48px; flex: none; display: flex; align-items: center;
  padding: 0 16px; background: #1a1a1a; color: rgba(255,255,255,.7);
  border-bottom: 1px solid #000;
  position: relative;   /* 作为 hover 子菜单面板的定位参照 */
}
.topbar-left { display: flex; align-items: center; gap: 8px; min-width: 220px; }
.topbar-logo {
  display: flex; align-items: center; gap: 8px; color: #fff;
}
.topbar-logo .logo-icon { display: block; }
.topbar-logo .brand-name { font-size: 16px; font-weight: 600; color: #fff; letter-spacing: .3px; }
.topbar-logo .brand-cat { font-size: 13px; color: rgba(255,255,255,.7); padding-left: 6px; }

/* 一级导航（主页隐藏） */
.top-nav { display: flex; align-items: center; gap: 0; height: 100%; margin-left: 24px; flex: 1; }
.top-nav-item {
  height: 100%; display: flex; align-items: center; padding: 0 18px;
  font-size: 13px; color: var(--topbar-text-dim); cursor: pointer; position: relative;
  transition: color .15s;
}
.top-nav-item:hover { color: #fff; background: var(--topbar-hover); }
.top-nav-item.active { color: #fff; font-weight: 500; }
.top-nav-item.active::after {
  content: ''; position: absolute; left: 18px; right: 18px; bottom: 0; height: 2px;
  background: var(--accent);
}

/* 板块语境下顶部导航一律居中 —— 必须同时覆盖「板块主页」和「板块子页」，
   否则同一板块内会出现「主页居中、子页靠左」的割裂（.top-nav 默认是 flex-start 左对齐）。 */
#app-view.mode-card-home .top-nav,
.app.mode-card-home .top-nav,
#app-view.mode-section-sub .top-nav,
.app.mode-section-sub .top-nav {
  justify-content: center !important;
  margin-left: 0 !important;
}

/* ================= 一级导航 hover 子菜单面板（巨型菜单） ================= */
.nav-mega {
  position: absolute;
  top: 100%;
  left: 0;
  display: flex;
  align-items: stretch;
  gap: 0;
  background: #fff;
  border: 1px solid var(--border-light);
  border-top: 2px solid var(--accent);
  border-radius: 0 0 6px 6px;
  box-shadow: 0 8px 22px rgba(0,0,0,.16);
  z-index: 800;
  padding: 4px 6px;
  white-space: nowrap;
  max-height: calc(100vh - 100px);
  overflow: auto;
}
.nav-mega.hidden { display: none; }
.nav-mega-col {
  min-width: 150px;
  padding: 8px 10px 12px;
  border-right: 1px solid var(--border-light);
}
.nav-mega-col:last-child { border-right: 0; }
.nav-mega-group {
  font-size: 12px; font-weight: 600; color: var(--accent);
  padding: 6px 8px 4px; margin-bottom: 4px;
}
.nav-mega-item {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--text-dim);
  padding: 5px 8px; border-radius: 3px; cursor: pointer;
  line-height: 1.5;
}
.nav-mega-item:hover { background: var(--hover); color: var(--accent); }
.nav-mega-item .nm-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-mega-item .nm-fav {
  flex: none; width: 16px; height: 16px; display: inline-flex;
  align-items: center; justify-content: center; cursor: pointer;
  color: var(--accent); opacity: 0; transition: opacity .12s, transform .1s;
}
.nav-mega-item:hover .nm-fav { opacity: 1; }
.nav-mega-item .nm-fav.faved { opacity: 1; }
.nav-mega-item .nm-fav:active { transform: scale(.88); }

/* 顶栏右侧 */
.topbar-right { display: flex; align-items: center; gap: 12px; margin-left: auto; color: rgba(255,255,255,.7); }
.tb-icon { width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; border-radius: 50%; cursor: pointer; color: rgba(255,255,255,.65); font-size: 14px; transition: all .15s; }
.tb-icon:hover { background: rgba(255,255,255,.12); color: #fff; }
.tb-icon svg { display: block; }
/* 帮助图标：圈问号改成 SVG 后，圆由 SVG 自己画 → 原来的 border 要撤掉（否则双圈）；
   尺寸沿用 20×20（比其它 tb-icon 小一号），字形相关的 font-size/weight 不再需要 */
.tb-icon.help { width: 20px; height: 20px; }

.user-menu { position: relative; }
.user-chip { display: flex; align-items: center; gap: 5px; cursor: pointer; padding: 3px 8px 3px 6px; border-radius: 14px; background: rgba(255,255,255,.08); color: rgba(255,255,255,.85); transition: background .15s; }
.user-chip:hover { background: rgba(255,255,255,.16); color: #fff; }
.user-chip .user-icon { width: 16px; height: 16px; display: flex; align-items: center; justify-content: center; color: rgba(255,255,255,.7); }
.avatar {
  width: 24px; height: 24px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: #fff; font-size: 11px; font-weight: 600;
}
.user-name { font-size: 12px; padding-right: 2px; }
.user-dropdown {
  position: absolute; right: 0; top: 38px; width: 140px; z-index: 40;
  background: #fff; border: 1px solid var(--border); border-radius: 4px;
  box-shadow: 0 6px 18px rgba(0,0,0,.12); overflow: hidden;
}
.dropdown-item { padding: 9px 14px; cursor: pointer; font-size: 13px; color: var(--text); }
.dropdown-item:hover { background: var(--hover); color: var(--accent); }
.dropdown-item.danger { color: var(--critical); }
.dropdown-sep { height: 1px; background: var(--border-light); margin: 2px 0; }

/* 主页工作台下拉条 */
.workspace-bar {
  display: none; align-items: center; gap: 6px; flex: none;
  height: 36px; padding: 0 16px; background: #1a1a1a;
  border-bottom: 1px solid #000; color: rgba(255,255,255,.7); font-size: 13px;
}
.workspace-bar .ws-home { color: rgba(255,255,255,.55); display: flex; align-items: center; cursor: pointer; }
.workspace-bar .ws-home:hover { color: #fff; }
.workspace-bar .ws-sep { color: rgba(255,255,255,.35); margin: 0 4px; font-size: 12px; }
.workspace-bar .ws-name { color: rgba(255,255,255,.9); font-weight: 500; cursor: pointer; }
/* 下拉箭头由字符 ▾ 改为 SVG：字形尺寸不再管用，靠 inline-flex 居中 */
.workspace-bar .ws-caret { display: inline-flex; align-items: center; color: rgba(255,255,255,.5); margin-left: 2px; cursor: pointer; }
.workspace-bar .ws-caret svg { display: block; }
.workspace-bar .ws-clock { margin-left: auto; display: flex; align-items: center; cursor: default; }
.workspace-bar .ws-time { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.2; font-size: 12px; color: rgba(255,255,255,.85); }
.workspace-bar .ws-time .t { font-size: 14px; font-weight: 500; color: #fff; }
.workspace-bar .ws-time .d { font-size: 10px; color: rgba(255,255,255,.55); }
.workspace-bar .ws-page { margin-left: 10px; font-size: 13px; color: rgba(255,255,255,.9); cursor: pointer; }
.workspace-bar .ws-page:hover { color: #fff; }
.app.mode-home .workspace-bar { display: flex; }
.app.mode-card-home .workspace-bar { display: flex; }
.app.mode-section-sub .workspace-bar { display: flex; }

/* 板块内多开页面页签（ws-sub）：一排 chip，可切换/关闭 */
.workspace-bar .ws-sub {
  display: none; align-items: center; gap: 5px;
  margin-left: 10px; min-width: 0;
  height:100%;
  /* 弹性占据剩余空间（原为 max-width:52% 硬上限，会把超出的页签藏进不可见的滚动区） */
  flex: 1 1 auto; max-width: none; overflow-x: auto; scrollbar-width: none;
}
.workspace-bar .ws-sub::-webkit-scrollbar { display: none; }
/* 有溢出时：右边缘渐隐（提示「后面还有页签」）+ 压缩 chip，尽量多显示 */
.workspace-bar .ws-sub.overflowing {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 20px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 20px), transparent);
  padding-right: 4px;
}
.workspace-bar .ws-sub.overflowing .ws-chip {
  max-width: 116px; font-size: 11px; padding: 1px 3px 1px 6px; gap: 4px;
}
.workspace-bar .ws-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 1px 4px 1px 8px;
  height:100%;
  font-size: 12px; color: rgba(255,255,255,.92);
  cursor: pointer; white-space: nowrap; user-select: none;
  flex: none; max-width: 180px;
  position: relative;   /* ::before 分隔线的定位基准 */
}
/* 页签分隔线「|」：画在每个 chip 的左侧（落在相邻两 chip 的间隙正中，不占布局宽，
   所以不影响 chip 宽度与溢出判定）。高度 = chip 高度的 80%（上/下各让出 10%）。 */
.workspace-bar .ws-chip::before {
  content: ''; position: absolute; left: -3px; top: 10%; bottom: 10%;
  width: 1px; background: rgba(255,255,255,.3);
}
/* 第 1 个 chip 前面没有间隙，用 -3px 会落到 ws-sub 滚动区左侧之外被 overflow 裁掉 → 贴左缘画。
   它同样遵守「不是 active 就有线」。 */
.workspace-bar .ws-chip:first-child::before { left: 0; }
/* active chip 与它左右相邻的 chip 之间不画
   （线归「两个 chip 之间」，故判定 = 自己 active，或左邻 active）。 */
.workspace-bar .ws-chip.active::before,
.workspace-bar .ws-chip.active + .ws-chip::before { display: none; }
.workspace-bar .ws-chip i { font-style: normal; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.workspace-bar .ws-chip:hover { background: rgba(255,255,255,.22); }
.workspace-bar .ws-chip.active {
  background: rgba(255,255,255,.28); border-color: rgba(255,255,255,.55); color: #fff;
}
.workspace-bar .ws-chip b {
  cursor: pointer; color: rgba(255,255,255,.6); font-weight: 400;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 1px 2px; border-radius: 2px;
}
.workspace-bar .ws-chip b svg { display: block; }
.workspace-bar .ws-chip b:hover { color: #fff; background: rgba(255,255,255,.18); }


.workspace-wrap { position: relative; }   /* 作为下拉面板的定位基准 */

.workspace-dropdown {
  position: absolute; top: 100%; left: 52px; z-index: 50;   /* 顶边贴 workspace-wrap 下沿，不遮住深色条 */
  width: 210px; background: #fff; border: 1px solid var(--border);
  border-radius: 6px; box-shadow: 0 8px 24px rgba(0,0,0,.12);
  overflow: hidden; padding-bottom: 6px;
}
.workspace-dropdown .ws-list { list-style: none; margin: 0; padding: 8px 0; }
.workspace-dropdown .ws-item {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 14px; font-size: 13px; color: var(--text); cursor: pointer;
}
.workspace-dropdown .ws-item:hover { background: var(--hover); }
.workspace-dropdown .ws-label { flex: 1; }

.body { flex: 1; display: flex; min-height: 0; background: var(--bg); }

/* ================= 侧边栏（二级功能树） ================= */
.sidebar {
  width: 180px; flex: none; overflow-y: auto; padding: 8px 0 20px;
  background: #fff; border-right: 1px solid var(--border);
}
.sidebar::-webkit-scrollbar { width: 6px; }
.sidebar::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
.nav-empty { padding: 16px; font-size: 12px; color: var(--text-faint); }
.nav-item {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 16px 9px 18px; cursor: pointer; color: var(--text-dim);
  font-size: 13px; border-left: 3px solid transparent; transition: all .15s;
}
.nav-item:hover { color: var(--accent); background: var(--hover); }
.nav-item.active {
  color: var(--accent); background: var(--accent-soft);
  border-left-color: var(--accent); font-weight: 500;
}
.nav-item .ico { width: 16px; text-align: center; font-size: 13px; color: var(--text-faint); }
.nav-item.active .ico { color: var(--accent); }

/* ================= 主内容区 + 页签栏 ================= */
/* position:relative 只服务一件事：#menu-drawer（ws-home 菜单抽屉）要「上/左/下与 main-wrap 重合」，
   靠绝对定位对齐比自己算偏移稳（sidebar 在 home/板块主页/板块子页/404 四种模式下都是 display:none，
   main-wrap 左缘会变）。页面内的绝对定位元素都有更近的定位祖先（.mml-page/.alm-bar/.home-mie/.region-map…），
   不受影响 —— 见 tools/_test_menudrawer.js 与实机核查。 */
.main-wrap { position: relative; flex: 1; display: flex; flex-direction: column; min-width: 0; overflow: hidden; }

/* 主内容区 */
.main { flex: 1; overflow-y: auto; padding: 16px 20px 24px; min-width: 0; background: var(--bg); }
.main::-webkit-scrollbar { width: 8px; height: 8px; }
.main::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }

/* 页面常驻容器：功能页 host 填满内容区（页面模板如 .mml-page 依赖 100% 父高）；主页等 live 自适应可滚 */
#main-content > .page-host { height: 100%; min-height: 0; }
#main-content > #page-host-live { min-height: 100%; }

.page-title { font-size: 18px; font-weight: 600; margin-bottom: 4px; color: var(--text); }
.page-sub { font-size: 12px; color: var(--text-faint); margin-bottom: 16px; }

/* 面板 */
.panel {
  background: #fff; border: 1px solid var(--border);
  border-radius: 6px; padding: 14px 16px; margin-bottom: 14px;
}
.panel-title { font-size: 14px; font-weight: 600; margin-bottom: 12px; display: flex; align-items: center; gap: 8px; color: var(--text); }
.panel-title::before { content: ''; width: 3px; height: 13px; background: var(--accent); border-radius: 2px; }
.panel-head { display: flex; align-items: center; margin-bottom: 12px; gap: 12px; }
.panel-head .panel-title { margin-bottom: 0; }
.panel-head .spacer { flex: 1; }

/* 表格 */
table.tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.tbl th {
  text-align: left; padding: 9px 10px; font-weight: 500; color: var(--text);
  background: #fafbfc; border-bottom: 1px solid var(--border);
  white-space: nowrap; font-size: 12px;
}
.tbl td { padding: 9px 10px; border-bottom: 1px solid var(--border-light); white-space: nowrap; color: var(--text); }
.tbl tbody tr:hover { background: var(--hover); }
.tbl tbody tr.clickable { cursor: pointer; }
.tbl .muted { color: var(--text-faint); }
.tbl .col-op { display: flex; gap: 6px; align-items: center; color: var(--accent); font-size: 12px; }
.tbl .col-op span { cursor: pointer; padding: 0 2px; }
.tbl .col-op span:hover { color: var(--accent-hover); text-decoration: underline; }
.tbl .checkbox-cell { width: 32px; }

/* 告警表格行级染色 */
.tbl.alarms tbody tr td { padding: 6px 10px; }
.tbl.alarms tbody tr.row-critical { background: var(--critical-bg-strong); }
.tbl.alarms tbody tr.row-critical:hover { background: #ffd6d6; }
.tbl.alarms tbody tr.row-major { background: var(--major-bg); }
.tbl.alarms tbody tr.row-major:hover { background: #ffe1bf; }
.tbl.alarms tbody tr.row-minor { background: var(--minor-bg); }
.tbl.alarms tbody tr.row-minor:hover { background: #fff2b3; }
.tbl.alarms tbody tr.row-warning { background: var(--warning-bg); }
.tbl.alarms tbody tr.row-warning:hover { background: #cfeaff; }

/* 级别单元格（无行染时的兜底） */
.sev-cell { display: inline-flex; align-items: center; gap: 6px; padding: 1px 8px; border-radius: 3px; font-size: 12px; font-weight: 500; }
.sev-cell.critical { color: var(--critical); background: var(--critical-bg-strong); }
.sev-cell.major    { color: var(--major);    background: var(--major-bg); }
.sev-cell.minor    { color: #d4b106;         background: var(--minor-bg); }
.sev-cell.warning  { color: var(--warning);  background: var(--warning-bg); }

/* 徽标 */
.badge { display: inline-block; padding: 2px 8px; border-radius: 10px; font-size: 11px; }
.badge-sev-critical { background: var(--critical-bg-strong); color: var(--critical); }
.badge-sev-major    { background: var(--major-bg); color: var(--major); }
.badge-sev-minor    { background: var(--minor-bg); color: #b58800; }
.badge-sev-warning  { background: var(--warning-bg); color: var(--warning); }
.badge-status-unconfirmed { background: var(--major-bg); color: var(--major); }
.badge-status-confirmed   { background: var(--warning-bg); color: var(--warning); }
.badge-status-cleared     { background: var(--success-bg); color: var(--success); }

/* 状态徽标（胶囊状） */
.status-pill {
  display: inline-flex; align-items: center; gap: 4px; padding: 1px 10px; border-radius: 10px;
  font-size: 12px; line-height: 1.5; font-weight: 500;
}
.status-pill.running   { background: var(--warning-bg); color: var(--status-running); }
.status-pill.completed { background: var(--success-bg); color: var(--status-completed); }
.status-pill.failed    { background: var(--critical-bg); color: var(--status-failed); }
.status-pill.waiting   { background: var(--minor-bg); color: var(--status-waiting); }
.status-pill.paused    { background: var(--major-bg); color: var(--status-paused); }

.badge-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; }
.dot-critical { background: var(--critical); }
.dot-major    { background: var(--major); }
.dot-minor    { background: var(--minor); }
.dot-warning  { background: var(--warning); }

/* 工具栏 */
.toolbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 12px; }
.toolbar select, .toolbar input[type=text] {
  padding: 5px 10px; border-radius: 4px; background: #fff;
  border: 1px solid var(--border-strong); color: var(--text); outline: none; font-size: 13px;
  height: 28px;
}
.toolbar select:focus, .toolbar input[type=text]:focus { border-color: var(--accent); }
.toolbar .spacer { flex: 1; }

/* 统计卡 */
.stat-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; margin-bottom: 14px; }
.stat-card {
  background: #fff; border: 1px solid var(--border); border-radius: 6px;
  padding: 12px 14px; display: flex; align-items: center; justify-content: space-between;
}
.stat-card .num { font-size: 22px; font-weight: 700; line-height: 1; }
.stat-card .label { font-size: 12px; color: var(--text-dim); }
.stat-card.critical { border-left: 3px solid var(--critical); }
.stat-card.critical .num { color: var(--critical); }
.stat-card.major { border-left: 3px solid var(--major); }
.stat-card.major .num { color: var(--major); }
.stat-card.minor { border-left: 3px solid var(--minor); }
.stat-card.minor .num { color: #b58800; }
.stat-card.warning { border-left: 3px solid var(--warning); }
.stat-card.warning .num { color: var(--warning); }
.stat-card.info .num { color: var(--accent); }
.stat-card.info { border-left: 3px solid var(--accent); }

/* 弹窗（2026-09-21 二修：拆遮罩层 + 浮层两个兄弟节点）
   三层序：遮罩 44 < 过滤贴边面板 45 < 弹窗浮层 46 —— 从过滤面板打开的居中弹窗（选择告警源）
   不再把面板压暗/挡住，点面板也不会误关弹窗；弹窗本体仍盖在面板之上。
   浮层 pointer-events:none：点弹窗外的空白穿透到遮罩 → 关闭；点面板 → 面板自己响应。 */
.modal-mask {
  position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 44;
}
.modal-float {
  position: fixed; inset: 0; z-index: 46;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;   /* 空白区穿透 → 下面的遮罩接住（关闭）；弹窗本体恢复接收 */
}
/* 叠加弹窗（.modal-stack，2026-10-05）：盖在当前弹窗之上而不关闭它（如向导里勾无权限类型 → 警告窗）。
   层级要高于底层弹窗的 44/46；关闭只收本层，下层弹窗与其输入状态原样保留。
   遮罩略浅：下层弹窗仍隐约可见，观感上是「叠了一层」而不是「换了个窗」。 */
.modal-stack .modal-mask { z-index: 54; background: rgba(0,0,0,.28); }
.modal-stack .modal-float { z-index: 56; }
.modal {
  pointer-events: auto;   /* 浮层整体穿透，只有弹窗本体接收点击 */
  width: 640px; max-width: 92vw; max-height: 86vh; display: flex; flex-direction: column;
  background: #fff; border: 1px solid var(--border); border-radius: 6px;
  box-shadow: 0 16px 40px rgba(0,0,0,.18);
}
.modal-header { padding: 12px 18px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; }
.modal-title { font-size: 15px; font-weight: 600; color: var(--text); }
/* 关闭按钮：图标由内联 SVG 画，这里只负责尺寸与居中（不再用字号控制大小） */
.modal-close { cursor: pointer; color: var(--text-faint); display: inline-flex; align-items: center; justify-content: center; padding: 0 2px; }
.modal-close svg { display: block; }
.modal-close:hover { color: var(--text); }
.modal-body { padding: 16px 18px; overflow-y: auto; font-size: 13px; line-height: 1.7; }
.modal-body .kv { display: flex; padding: 6px 0; border-bottom: 1px dashed var(--border-light); }
.modal-body .kv .k { width: 120px; flex: none; color: var(--text-dim); }
.modal-body .kv .v { flex: 1; }
.modal-foot { padding: 12px 18px; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; gap: 8px; background: #fafbfc; }

/* toast */
#toast-root { position: fixed; top: 60px; right: 20px; z-index: 90; display: flex; flex-direction: column; gap: 8px; }
.toast {
  min-width: 220px; padding: 10px 16px; border-radius: 4px; font-size: 13px;
  background: #fff; border: 1px solid var(--border); color: var(--text);
  box-shadow: 0 6px 18px rgba(0,0,0,.12); animation: slideIn .25s ease;
}
.toast.success { border-left: 3px solid var(--success); }
.toast.error { border-left: 3px solid var(--critical); }
.toast.info { border-left: 3px solid var(--accent); }
@keyframes slideIn { from { transform: translateX(30px); opacity: 0; } to { transform: none; opacity: 1; } }

/* 进度条 */
.progress { height: 8px; background: #f0f3f8; border-radius: 4px; overflow: hidden; min-width: 120px; }
.progress > i { display: block; height: 100%; background:#61cab2; border-radius: 4px; transition: width .4s; }

/* ================= 拓扑页 ================= */
.topo-wrap { display: flex; gap: 14px; }
.topo-svg-box {
  flex: 1; min-width: 0; background: #fff; border: 1px solid var(--border); border-radius: 6px; padding: 10px; overflow: auto;
}
.topo-svg-box svg { display: block; width: 100%; min-width: 720px; }
.topo-detail { width: 300px; flex: none; }
.topo-site { cursor: pointer; }
.topo-site:hover circle.node { stroke: var(--accent); }
.topo-link { stroke: var(--border-strong); stroke-width: 1.2; fill: none; }
.topo-link.down { stroke: var(--critical); stroke-dasharray: 5 4; fill: none; }
.topo-zone { fill: rgba(38,115,229,.04); stroke: rgba(38,115,229,.22); stroke-dasharray: 6 4; }
/* 详情面板里的状态点：内联 SVG 圆点 + 文字，颜色由外层 color 给出（原来是字符 ●） */
.st-dot { display: inline-flex; align-items: center; gap: 5px; }
.st-dot svg { display: block; flex: none; }

/* ================= MML 终端 ================= */
.mml-shell {
  background: #1e1e1e; border: 1px solid var(--border); border-radius: 6px;
  display: flex; flex-direction: column; height: 72vh; overflow: hidden;
}
.mml-head {
  padding: 8px 14px; display: flex; gap: 14px; align-items: center;
  background: #2a2a2a; border-bottom: 1px solid #1a1a1a; color: #ccc;
}
.mml-head .dot { width: 10px; height: 10px; border-radius: 50%; }
.mml-head .dot.r { background: #ff5f56; } .mml-head .dot.y { background: #ffbd2e; } .mml-head .dot.g { background: #27c93f; }
.mml-head .title { font-size: 12px; color: #ccc; margin-left: 6px; }
.mml-head .hint { flex: 1; text-align: right; font-size: 12px; color: #888; }
.mml-out {
  flex: 1; overflow-y: auto; padding: 14px 16px; font-family: Consolas, "Courier New", monospace;
  font-size: 13px; line-height: 1.6; white-space: pre-wrap; word-break: break-all;
  color: #d4d4d4; background: #1e1e1e;
}
.mml-out .prompt-line { color: #4ec9b0; }
.mml-out .output { color: #d4d4d4; }
.mml-out .cmd-text { color: #9cdcfe; }
.mml-in { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-top: 1px solid #1a1a1a; background: #2a2a2a; }
.mml-in .prompt { color: #4ec9b0; font-family: Consolas, monospace; font-size: 14px; }
.mml-in input {
  flex: 1; background: transparent; border: none; outline: none; color: #d4d4d4;
  font-family: Consolas, "Courier New", monospace; font-size: 14px;
}

/* ================= 图表 ================= */
.chart-box { background: #fff; border: 1px solid var(--border); border-radius: 6px; padding: 12px; margin-bottom: 12px; }
.chart-title { font-size: 13px; color: var(--text-dim); margin-bottom: 8px; display: flex; justify-content: space-between; align-items: center; }
.chart-title .legend span { margin-left: 12px; }
.chart-svg { width: 100%; height: 200px; display: block; }
.kpi-tabs { display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 12px; }
.kpi-tab {
  padding: 5px 14px; border-radius: 4px; cursor: pointer; font-size: 13px;
  background: #fff; border: 1px solid var(--border); color: var(--text-dim);
}
.kpi-tab.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.kpi-tab:hover:not(.active) { color: var(--accent); border-color: var(--accent); }

/* 任务卡片 */
.task-card {
  display: flex; align-items: center; gap: 14px; padding: 12px 14px;
  background: #fff; border: 1px solid var(--border); border-radius: 6px; margin-bottom: 8px;
}
.task-card .tc-info { flex: 1; min-width: 0; }
.task-card .tc-name { font-size: 13px; margin-bottom: 4px; color: var(--text); }
.task-card .tc-meta { font-size: 12px; color: var(--text-faint); }

/* 消息/文档列表 */
.msg-item { padding: 12px 4px; border-bottom: 1px solid var(--border-light); cursor: pointer; }
.msg-item:hover { background: var(--hover); }
.msg-item .msg-title { font-size: 14px; margin-bottom: 4px; color: var(--text); }
.msg-item .msg-meta { font-size: 12px; color: var(--text-faint); }
.msg-item .msg-content { margin-top: 10px; padding: 12px; background: var(--panel-3); border-radius: 4px; font-size: 13px; line-height: 1.8; }

.doc-item { display: flex; align-items: center; gap: 12px; padding: 11px 4px; border-bottom: 1px solid var(--border-light); }
.doc-item .doc-type {
  width: 40px; height: 40px; flex: none; border-radius: 4px; display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; color: #fff;
}
.doc-type.PDF { background: linear-gradient(135deg, #f5222d, #a8071a); }
.doc-type.DOC { background: linear-gradient(135deg, #2673e5, #1855a5); }
.doc-item .doc-info { flex: 1; min-width: 0; }
.doc-item .doc-name { font-size: 13px; color: var(--text); }
.doc-item .doc-meta { font-size: 12px; color: var(--text-faint); margin-top: 3px; }

/* ================= 网元树（深度复刻：蓝色方块图标） ================= */
.ne-tree { font-size: 13px; user-select: none; }
.ne-tree .nt-row {
  display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: 4px;
  cursor: pointer; color: var(--text-dim); white-space: nowrap;
}
.ne-tree .nt-row:hover { background: var(--hover); color: var(--accent); }
.ne-tree .nt-row.branch { color: var(--text); font-weight: 500; }
.ne-tree .nt-row .nt-toggle {
  flex: none; width: 14px; height: 14px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-strong); border-radius: 2px;
  color: var(--text-dim); background: #fff;
  cursor: pointer; user-select: none;
}
.ne-tree .nt-row .nt-toggle:hover { border-color: var(--accent); color: var(--accent); }
.ne-tree .nt-row .nt-toggle.nt-toggle-leaf { cursor: default; color: var(--text-faint); border-color: var(--border); background: #fafafa; }
.ne-tree .nt-row .nt-toggle.nt-toggle-leaf:hover { border-color: var(--border); color: var(--text-faint); }
.ne-tree .nt-row.collapsed + .nt-children { display: none; }
.ne-tree .nt-row .nt-count { font-size: 11px; color: var(--text-faint); font-weight: 400; margin-left: auto; }
.ne-tree .nt-children { padding-left: 22px; }
.ne-tree .nt-leaf { padding: 5px 8px; cursor: pointer; gap: 8px; }
.ne-tree .nt-leaf .nt-ne-icon {
  width: 14px; height: 14px; flex: none; background: var(--accent); border-radius: 2px;
  display: inline-block;
}
.ne-tree .nt-check { flex: none; width: 14px; height: 14px; accent-color: var(--accent); cursor: pointer; }
.ne-tree .nt-status { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.ne-tree .nt-status.ok { background: var(--success); }
.ne-tree .nt-status.bad { background: var(--critical); }
/* 网元状态三态（网元入库后）：正常=绿 / 预部署=橙 / 脱管=灰（真实 MAE 里脱管显示灰色） */
.ne-tree .nt-status.pre { background: var(--major); }
.ne-tree .nt-status.offline { background: var(--text-faint); }
.ne-tree .nt-leaf.selected { background: var(--accent-soft); color: var(--accent); }
.ne-tree .nt-leaf .nt-name { overflow: hidden; text-overflow: ellipsis; min-width: 0; }

/* ================= MML 向导页 ================= */
.mml-wizard { display: flex; gap: 14px; align-items: flex-start; }
.mml-ne-pane {
  width: 260px; flex: none; background: #fff; border: 1px solid var(--border);
  border-radius: 6px; padding: 12px; max-height: 74vh; overflow-y: auto;
}
.mml-ne-pane .pane-title { font-size: 13px; font-weight: 600; margin-bottom: 10px; display: flex; align-items: center; gap: 8px; }
.mml-ne-pane .pane-title::before { content: ''; width: 3px; height: 13px; background: var(--accent); border-radius: 2px; }
.mml-ne-pane .sel-count { margin-top: 10px; padding: 7px 10px; font-size: 12px; color: var(--text-dim); background: var(--panel-3); border-radius: 4px; }
.mml-editor-pane { flex: 1; min-width: 0; }

/* 步骤条（蓝色弧线圆点） */
.wizard-steps {
  display: flex; align-items: center; gap: 8px; padding: 18px 14px; margin-bottom: 14px;
  background: #fff; border: 1px solid var(--border); border-radius: 6px; font-size: 13px;
}
.wizard-steps .step { display: flex; flex-direction: column; align-items: center; gap: 4px; color: var(--text-faint); min-width: 80px; }
.wizard-steps .step .lbl-top { font-size: 11px; }
.wizard-steps .step .lbl-bot { font-size: 13px; font-weight: 500; color: var(--text); }
.wizard-steps .step .dot {
  width: 18px; height: 18px; border-radius: 50%; flex: none;
  background: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft);
}
.wizard-steps .step.active .lbl-bot { color: var(--accent); }
.wizard-steps .step.active .dot { background: var(--accent); }
.wizard-steps .step.done .dot { background: var(--success); box-shadow: 0 0 0 4px var(--success-bg); }
.wizard-steps .arr {
  flex: 1; height: 2px; min-width: 60px; background: linear-gradient(90deg, var(--accent), #9bc2f5);
  border-radius: 1px;
}

/* MML 向导主面板布局（左侧模式 + 中间面板） */
.mml-layout { display: flex; gap: 0; background: #fff; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
.mml-mode-bar {
  width: 24px; flex: none; background: var(--panel-3); border-right: 1px solid var(--border);
  display: flex; flex-direction: column; align-items: center; padding: 12px 0; gap: 16px;
}
.mml-mode-bar .mode-item {
  writing-mode: vertical-rl; padding: 10px 4px; font-size: 12px; color: var(--text-faint);
  background: transparent; border: none; cursor: pointer; border-radius: 4px;
}
.mml-mode-bar .mode-item.active { background: var(--accent); color: #fff; }
.mml-ne-area { width: 280px; flex: none; padding: 12px; border-right: 1px solid var(--border); overflow-y: auto; }
.mml-ne-area .ne-toolbar { display: flex; gap: 6px; margin-bottom: 8px; align-items: center; }
.mml-ne-area .ne-toolbar .ic { width: 22px; height: 22px; display: flex; align-items: center; justify-content: center; border: 1px solid var(--border); border-radius: 4px; cursor: pointer; color: var(--text-faint); font-size: 12px; }
.mml-ne-area .ne-toolbar .ic:hover { color: var(--accent); border-color: var(--accent); }
.mml-ne-area .ne-search { width: 100%; height: 28px; padding: 0 10px; border: 1px solid var(--border-strong); border-radius: 4px; font-size: 13px; outline: none; margin-bottom: 10px; }
.mml-ne-area .ne-search:focus { border-color: var(--accent); }
.mml-ne-area .ne-filter-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; font-size: 12px; color: var(--text-dim); }
.mml-ne-area .ne-filter-row select { flex: 1; height: 26px; padding: 0 6px; border: 1px solid var(--border-strong); border-radius: 4px; font-size: 12px; }
.mml-ne-area .ne-tabs { display: flex; border-bottom: 1px solid var(--border); margin-bottom: 8px; }
.mml-ne-area .ne-tab { padding: 6px 12px; font-size: 13px; cursor: pointer; color: var(--text-dim); border-bottom: 2px solid transparent; }
.mml-ne-area .ne-tab.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 500; }
.mml-ne-area .ne-toggle { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-dim); margin: 6px 0; }
.mml-ne-area .ne-toggle .switch { width: 32px; height: 16px; border-radius: 10px; background: var(--border-strong); position: relative; cursor: pointer; }
.mml-ne-area .ne-toggle .switch::after { content: ''; position: absolute; left: 2px; top: 2px; width: 12px; height: 12px; border-radius: 50%; background: #fff; transition: left .15s; }
.mml-ne-area .ne-toggle .switch.on { background: var(--accent); }
.mml-ne-area .ne-toggle .switch.on::after { left: 18px; }

/* MML 主内容面板（步骤图 + 提示） */
.mml-main-area { flex: 1; padding: 28px 24px; min-height: 480px; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; }
.mml-illustration {
  width: 220px; height: 220px; border-radius: 50%;
  background: radial-gradient(circle at 40% 40%, #c2dcfa, #6ea6e7 60%, #2c6dc7);
  display: flex; align-items: center; justify-content: center; color: #fff; font-size: 13px;
  position: relative; overflow: hidden;
}
.mml-illustration::before {
  content: 'MML'; font-size: 42px; font-weight: 800; letter-spacing: 4px; opacity: .95;
}
.mml-main-area h3 { font-size: 18px; font-weight: 500; color: var(--text); margin: 18px 0 22px; }
.mml-main-area .tip { font-size: 13px; color: var(--text-faint); margin-top: 24px; }
.mml-main-area .tip .link { color: var(--accent); padding: 0 4px; }

/* MML 编辑面板（第二步） */
.mml-editor-card { background: #fff; border: 1px solid var(--border); border-radius: 6px; padding: 14px; }
.mml-editor-card .head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.mml-editor-card .head .title { font-size: 13px; font-weight: 500; }
.mml-cmd-input {
  width: 100%; min-height: 100px; padding: 12px 14px; border-radius: 4px; resize: vertical;
  background: #fafbfc; border: 1px solid var(--border-strong); color: var(--text); outline: none;
  font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.7;
}
.mml-cmd-input:focus { border-color: var(--accent); }
.mml-quick { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 10px 0 14px; }
.mml-quick .chip { padding: 3px 10px; border-radius: 12px; background: var(--accent-soft); color: var(--accent); font-size: 12px; cursor: pointer; border: 1px solid var(--accent-border); }
.mml-quick .chip:hover { background: var(--accent); color: #fff; }

/* 注：这里原先还有一份 .res-block 系列定义，与「结果块（报文 tab 内容）」那份完全重复
   （同名选择器，后者生效 = 死代码）。2026-09-24 已删除：留着会变成"属性复活"的地雷
   —— 后一份一旦不声明某属性，前一份的声明就接管（踩过 max-height / overflow-y）。
   报文相关的样式统一写在「结果块」那一节，且一律带 .mr-body 前缀。 */

/* ================= 表单 / 链接按钮 ================= */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 18px; }
.form-grid .field.full { grid-column: 1 / -1; }
.form-grid .field label { display: block; font-size: 12px; color: var(--text-dim); margin-bottom: 6px; }
.form-grid .field input, .form-grid .field select, .form-grid .field textarea {
  width: 100%; padding: 6px 10px; border-radius: 4px; outline: none;
  background: #fff; border: 1px solid var(--border-strong); color: var(--text); font-size: 13px;
  height: 30px;
}
.form-grid .field textarea { height: auto; padding: 8px 10px; }
.form-grid .field input:focus, .form-grid .field select:focus, .form-grid .field textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(38,115,229,.12); }

/* 胶囊式多选（告警过滤弹窗） */
.chips { display: flex; flex-wrap: wrap; gap: 6px; padding-top: 4px; }
.chip-toggle {
  padding: 3px 12px; border-radius: 14px; cursor: pointer; font-size: 12px;
  border: 1px solid var(--accent-border); background: #fff; color: var(--accent);
}
.chip-toggle.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.chip-toggle:hover:not(.active) { background: var(--accent-soft); }

.checks { display: flex; flex-wrap: wrap; gap: 12px; padding-top: 4px; }
.checks label { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-dim); cursor: pointer; }
.checks input { accent-color: var(--accent); }

.btn-group { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.btn-group .spacer { flex: 1; }

.link-btn { background: none; border: none; color: var(--accent); cursor: pointer; font-size: 12px; padding: 2px 6px; border-radius: 3px; }
.link-btn:hover { background: var(--accent-soft); }
.link-btn.danger { color: var(--critical); }
.link-btn.danger:hover { background: var(--critical-bg); }

/* 两栏布局 */
.two-col { display: flex; gap: 14px; align-items: flex-start; }
.two-col .left-pane { width: 240px; flex: none; }
.two-col .right-pane { flex: 1; min-width: 0; }
.pane-card {
  background: #fff; border: 1px solid var(--border); border-radius: 6px; padding: 12px;
  max-height: 72vh; overflow-y: auto;
}
.pane-card .pane-title { font-size: 13px; font-weight: 600; margin-bottom: 10px; display: flex; align-items: center; gap: 8px; color: var(--text); }
.pane-card .pane-title::before { content: ''; width: 3px; height: 13px; background: var(--accent); border-radius: 2px; }

.task-type-item {
  padding: 7px 12px; border-radius: 4px; cursor: pointer; font-size: 13px; color: var(--text-dim);
  display: flex; align-items: center; gap: 8px; margin-bottom: 2px;
}
.task-type-item:hover { background: var(--hover); color: var(--accent); }
.task-type-item.active { background: var(--accent-soft); color: var(--accent); font-weight: 500; }
.task-type-item .cnt { margin-left: auto; font-size: 11px; color: var(--text-faint); background: var(--panel-3); padding: 0 6px; border-radius: 8px; }

.backup-bar {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 12px;
  padding: 10px 12px; background: var(--panel-3); border: 1px solid var(--border); border-radius: 6px;
}

.status-text { font-size: 12px; }
.status-text.running   { color: var(--status-running); }
.status-text.waiting   { color: var(--status-waiting); }
.status-text.completed { color: var(--status-completed); }
.status-text.failed    { color: var(--status-failed); }
.status-text.paused    { color: var(--status-paused); }

/* ================= 主页（新版 MIE + NEM 双区） ================= */
.home-page { padding: 0; }

/* ---- MIE 区（柔和抽象渐变背景 + Optimization 卡 + 最近使用） ---- */
.home-mie { position: relative; overflow: hidden; border-radius: 10px; margin: 0 0 18px; min-height: 320px; }
.mie-bg { position: absolute; inset: 0; z-index: 0; }
.mie-bg svg { width: 100%; height: 100%; display: block; }
.mie-inner { position: relative; z-index: 1; display: grid; grid-template-columns: 1fr 280px; gap: 24px; padding: 32px 36px 28px; }
.mie-left { min-width: 0; }
.mie-title { margin: 0 0 18px; font-size: 22px; font-weight: 700; color: #1a2a3a; letter-spacing: .5px; }
.mie-title .mie-sub { font-size: 14px; font-weight: 400; color: #4e5969; margin-left: 4px; }
.mie-card { background: rgba(255,255,255,.92); border: 1px solid rgba(255,255,255,.8); border-radius: 10px; padding: 14px 18px; box-shadow: 0 4px 14px rgba(80,120,180,.1); max-width: 420px; }
.mc-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.mc-icon { width: 18px; height: 18px; display: inline-block; }
.mc-icon svg { display: block; width: 100%; height: 100%; }
.mc-title { font-size: 14px; font-weight: 600; color: #1a2a3a; cursor: pointer; }
.mc-title:hover { color: #1890ff; }
.mc-more { margin-left: auto; font-size: 12px; color: #8c9bab; cursor: pointer; }
.mc-items { display: flex; flex-wrap: wrap; align-items: center; }
.mc-item { font-size: 13px; color: #4e5969; cursor: pointer; padding: 4px 12px; border-right: 1px solid #e4e7ed; transition: color .15s; }
.mc-item.last { border-right: none; }
.mc-item:hover { color: #1890ff; }

/* 最近使用（右侧浮动，无白框） */
.mie-recent { position: relative; height: fit-content; }
.mr-head { display: flex; align-items: center; justify-content: flex-end; margin-bottom: 10px; padding-right: 4px; }
.mr-title { font-size: 13px; font-weight: 600; color: #1a2a3a; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: #1890ff; }
.mr-list { list-style: none; margin: 0; padding: 0; min-width: 0; }
.mr-empty { font-size: 12px; color: #8c9bab; padding: 10px 4px; text-align: center; }
.mr-item { display: flex; justify-content: flex-end; align-items: center; padding: 6px 4px; font-size: 12px; color: #4e5969; cursor: pointer; border-radius: 3px; }
.mr-item:hover { color: #1890ff; }
.mr-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.mr-fav { display: flex; justify-content: flex-end; align-items: center; margin-top: 10px; padding-right: 4px; font-size: 12px; color: #4e5969; }

/* ---- NEM 区（4 卡片 2×2） ---- */
.home-nem { margin-top: 6px; }
.nem-title { margin: 0 0 14px; font-size: 18px; font-weight: 600; color: #1a2a3a; }
.nem-title .nem-sub { font-size: 13px; font-weight: 400; color: #4e5969; margin-left: 4px; }
.nem-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.nem-card { position: relative; background: #fff; border: 1px solid rgba(0,0,0,.04); border-radius: 10px; padding: 18px 22px 16px; min-height: 160px; overflow: hidden; transition: box-shadow .2s, transform .15s; box-shadow: 0 2px 10px rgba(80,120,180,.06); }
.nem-card:hover { box-shadow: 0 6px 20px rgba(80,120,180,.1); }
.nc-head { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.nc-icon { width: 16px; height: 16px; display: inline-block; }
.nc-icon svg { display: block; width: 100%; height: 100%; }
.nc-title { font-size: 15px; font-weight: 600; color: #1a2a3a; cursor: pointer; }
.nc-title:hover { color: #1890ff; }
.nc-more { margin-left: auto; font-size: 12px; color: #8c9bab; cursor: pointer; }
.nc-more:hover { color: #1890ff; }
.nc-items { display: flex; flex-wrap: wrap; align-items: center; }
.nc-item { font-size: 13px; color: #4e5969; padding: 3px 10px; border-right: 1px solid #e4e7ed; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: color .15s; }
.nc-item.last { border-right: none; }
.nc-item:hover { color: #1890ff; }
.nc-item.nc-stub { color: #8c9bab; }
.nc-item.nc-stub:hover { color: #4e5969; }
.nc-illu { position: absolute; right: 18px; bottom: 14px; width: 90px; height: 90px; pointer-events: none; opacity: .9; }
.nc-illu svg { width: 100%; height: 100%; }

/* ---- 老 home 样式保留兼容（如果别处还在用） ---- */
.home-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); gap: 14px; }
.home-card { background: #fff; border: 1px solid var(--border); border-radius: 8px; padding: 18px 20px; position: relative; min-height: 130px; }
.home-card .hc-title { font-size: 15px; font-weight: 600; color: var(--text); margin-bottom: 14px; display: flex; align-items: center; gap: 8px; }
.home-card .hc-title::before { content: ''; width: 3px; height: 13px; background: var(--accent); border-radius: 2px; }
.home-card .hc-more { position: absolute; top: 14px; right: 16px; font-size: 12px; color: var(--text-faint); cursor: pointer; }
.home-card .hc-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.home-card .hc-grid .item { padding: 8px 10px; border-radius: 4px; color: var(--text-dim); font-size: 13px; cursor: pointer; }
.home-card .hc-grid .item:hover { background: var(--hover); color: var(--accent); }

/* ================= 主页沉浸模式（1:1 复刻：顶栏无文字、无侧栏、无页签） ================= */
.app.mode-home .top-nav { display: none; }                 /* header 无导航菜单文字 */
.app.mode-home .topbar-left { min-width: auto; }
.app.mode-home .body .sidebar { display: none; }           /* 整页无侧栏 */
.app.mode-home .main { padding: 0; }                       /* 主页内容通栏 */
.app.mode-home .home-mie { border-radius: 0; margin-bottom: 14px; }  /* 顶部渐变顶满两边 */
.app.mode-home .home-nem { padding: 0 20px 26px; margin-top: 0; }

/* ================= 卡片主页沉浸模式（保留顶部导航、无侧栏、显示 workspace-wrap） ================= */
.app.mode-card-home .body .sidebar { display: none; }      /* 卡片主页无侧栏 */
.app.mode-section-sub .body .sidebar { display: none; }    /* 板块子页面无侧栏 */
.app.mode-card-home .main { padding: 20px; }                  /* 内容通栏 */

/* ================= 卡片主页 ================= */
.card-home-page { display: grid; grid-template-columns: 1fr 280px; gap: 24px; padding: 0; }
/* 第一行：ch-hero（左，弹性） + ch-recent（右，280px）合起来占满一屏宽 */
.ch-hero   { grid-row: 1; grid-column: 1; }
.ch-recent { grid-row: 1; grid-column: 2; }
/* 第二行：ch-grid 独占一屏宽（跨两列，延伸到右侧面板下方） */
.ch-grid   { grid-row: 2; grid-column: 1 / -1; }
.ch-hero {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 32px 36px;
  background: linear-gradient(135deg, #ffffff 0%, #f7f8fa 60%, #f2f4f7 100%);
  border-bottom: 1px solid rgba(0,0,0,.04);
  min-height: 200px;
  overflow: hidden;
}
.ch-text { flex: 1; min-width: 0; position: relative; z-index: 2; }
.ch-title { margin: 0 0 12px; font-size: 26px; font-weight: 500; color: #1a2a3a; letter-spacing: .5px; }
.ch-desc { margin: 0; font-size: 13px; color: #4e5969; line-height: 1.7; white-space: nowrap; }
.ch-illu { width: 220px; height: 176px; flex: none; opacity: .95; z-index: 1; }
.ch-illu svg { width: 100%; height: 100%; }

.ch-grid {
  display: grid;
  /* 固定三列：每列宽度 = 容器 1/3；minmax(0,1fr) 防止内容把列撑宽 */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;                    /* 卡片之间留空隙 */
  padding: 22px 0 32px;         /* 左右由 .main 的 20px padding 提供外间距 */
  align-items: stretch;         /* 同一行卡片等高：以最高者为准，其余拉伸对齐 */
}
.ch-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ch-item-card {
  background: #fff;
  border: 1px solid rgba(0,0,0,.04);
  border-radius: 8px;
  padding: 0;
  min-height: 130px;
  min-width: 0;                 /* 配合 minmax(0,1fr)，保证列宽恒为容器 1/3 */
  width: 100%;                  /* 填满所在列 */
  cursor: pointer;
  transition: box-shadow .2s, transform .15s, border-color .15s;
  box-shadow: 0 2px 8px rgba(80,120,180,.05);
  display: flex; flex-direction: column;
}
.ch-item-card:hover { box-shadow: 0 6px 18px rgba(80,120,180,.1); border-color: rgba(24,144,255,.25); }
.ch-item-card.ch-stub { cursor: default; }
.ch-item-card.ch-stub:hover { border-color: rgba(0,0,0,.04); box-shadow: 0 2px 8px rgba(80,120,180,.05); }
.ch-item-top { display: flex; gap: 12px; padding: 18px 20px 14px; }
.ch-item-icon { width: 32px; height: 32px; flex: none; display: flex; align-items: center; justify-content: center; }
.ch-item-icon svg { width: 28px; height: 28px; }
.ch-item-info { flex: 1; min-width: 0; }
.ch-item-title { font-size: 15px; font-weight: 600; color: #1a2a3a; margin-bottom: 8px; }
.ch-item-card:hover .ch-item-title { color: #1890ff; }
.ch-item-card.ch-stub .ch-item-title { color: #4e5969; }
.ch-item-desc { margin: 0; font-size: 12px; color: #8c9bab; line-height: 1.6; }
.ch-item-sub {
  /* 高度由 JS equalizeCardParts() 统一为所有卡片中的最大值，使分割线对齐 */
  padding: 11px 20px;
  border-top: 1px solid rgba(0,0,0,.04);
  font-size: 12px;
  color: #1a1a1a;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ch-sub-link { cursor: pointer; display: block; color: #1a1a1a; line-height: 1.5; padding: 2px 0; }
.ch-sub-link:hover { color: #1890ff; }   /* 子项文字 hover 变蓝（stub 占位同样生效） */

/* 卡片主页右侧最近使用/我的收藏 */
.ch-recent {
  padding: 24px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0,0,0,.08);
  /* 关键：不随网格 stretch 把整行撑高，改为由 JS 将其高度锁成与左侧 .ch-hero 一致，
     超出部分在 .chr-body 内滚动（否则最近使用列表会变高、整页变长、永不出现滚动条） */
  align-self: start;
}
/* 列表区：填满 ch-recent 剩余高度，超出即滚动（ch-recent 与 ch-hero 同高，由网格 stretch 保证） */
.chr-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* 细滚动条：Firefox */
  scrollbar-width: thin;
  scrollbar-color: #cdd2da transparent;
}
/* 细滚动条：WebKit（4px，hover 微变深，静止时低调不抢视觉） */
.chr-body::-webkit-scrollbar { width: 4px; }
.chr-body::-webkit-scrollbar-track { background: transparent; }
.chr-body::-webkit-scrollbar-thumb { background: #cdd2da; border-radius: 2px; }
.chr-body::-webkit-scrollbar-thumb:hover { background: #a8b0bd; }
.chr-tabs { display: flex; align-items: center; gap: 18px; margin-bottom: 12px; }
.chr-tab { font-size: 13px; color: #4e5969; cursor: pointer; padding-bottom: 4px; position: relative; }
.chr-tab.active { color: #1890ff; font-weight: 600; }
.chr-tab.active::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: #1890ff; border-radius: 1px; }
.chr-list { list-style: none; margin: 0; padding: 0; }
.chr-empty { font-size: 12px; color: #8c9bab; padding: 8px 0; }
.chr-item { display: flex; justify-content: flex-start; align-items: center; padding: 6px 0; font-size: 12px; color: #4e5969; cursor: pointer; }
.chr-item:hover { color: #1890ff; }
/* 列表项名称：撑满剩余宽度并省略，把删除按钮推到最右侧 */
.chr-name, .chr-fav-name { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chr-fav { padding: 0; }
.chr-fav-item { display: flex; justify-content: flex-start; align-items: center; padding: 6px 0; font-size: 12px; color: #4e5969; cursor: pointer; }
.chr-fav-item:hover { color: #1890ff; }
.chr-fav-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* hover 删除按钮（×），默认隐藏，行 hover 时显现 */
.chr-del { margin-left: auto; padding-left: 8px; display: none; align-items: center; color: #bbb; cursor: pointer; flex: none; }
.chr-item:hover .chr-del, .chr-fav-item:hover .chr-del { display: inline-flex; }
.chr-del:hover { color: #ff4d4f; }

/* ================= 告警过滤弹窗（胶囊） ================= */
.filter-grid { display: grid; grid-template-columns: 110px 1fr; gap: 12px 16px; align-items: start; }
.filter-grid .lbl { color: var(--text-dim); font-size: 13px; padding-top: 6px; }
.filter-grid .val { font-size: 13px; }
.filter-grid .val .chips { gap: 6px; }
.filter-grid .val input[type=text], .filter-grid .val select {
  height: 28px; padding: 0 10px; border: 1px solid var(--border-strong); border-radius: 4px;
  background: #fff; color: var(--text); font-size: 13px; outline: none;
}
.filter-grid .val .date-row { display: flex; align-items: center; gap: 8px; }
.filter-grid .val .chk { margin-right: 4px; accent-color: var(--accent); }

/* 行内状态条（告警页顶部） */
.alarm-bar { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.alarm-bar .refresh-switch { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-dim); }
.alarm-bar .refresh-switch .switch { width: 32px; height: 16px; border-radius: 10px; background: var(--border-strong); position: relative; cursor: pointer; transition: background .15s; }
.alarm-bar .refresh-switch .switch::after { content: ''; position: absolute; left: 2px; top: 2px; width: 12px; height: 12px; border-radius: 50%; background: #fff; transition: left .15s; }
.alarm-bar .refresh-switch .switch.on { background: var(--accent); }
.alarm-bar .refresh-switch .switch.on::after { left: 18px; }

/* 占位页 */
.page-placeholder { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 50vh; gap: 10px; text-align: center; }
.page-placeholder .ph-icon { font-size: 52px; opacity: .6; }
.page-placeholder .ph-title { font-size: 18px; font-weight: 600; color: var(--text); }
.page-placeholder .ph-sub { font-size: 13px; color: var(--text-faint); max-width: 520px; line-height: 1.8; }

@media (max-width: 1100px) {
  .sidebar { width: 150px; }
  .topo-wrap { flex-direction: column; }
  .topo-detail { width: 100%; }
  .two-col { flex-direction: column; }
  .two-col .left-pane { width: 100%; }
  .mml-wizard { flex-direction: column; }
  .mml-ne-pane { width: 100%; max-height: 300px; }
  .form-grid { grid-template-columns: 1fr; }
  .home-cards { grid-template-columns: 1fr; }
  .nem-grid   { grid-template-columns: 1fr; }
  .mie-inner  { grid-template-columns: 1fr; }
  .nc-items   { grid-template-columns: repeat(2, 1fr); }
}

/* ================= MML 命令页（严格复刻真实 MAE） ================= */
.mml-page {
  display: grid;
  position: relative;
  grid-template-columns: var(--mml-left-w) 8px 1fr;
  grid-template-rows: 1fr;
  grid-template-areas:
    "left grip main";
  gap: 0;
  height: 100%;   /* 填满 .main 内容区，不按视口硬算，避免整体滚动 */
  background: var(--bg);
}
/* 左右分隔条落位（2026-09-27 用户要求：同 bk/tt，居中于两栏之间的 8px 间隔列，不再 absolute 贴左列边线） */
.mml-page > .mml-grip.grip-left {
  position: relative;   /* 不能 static：::before 2px 线是 absolute，需要本元素当定位祖先 */
  grid-area: grip;
  left: auto; top: auto; bottom: auto;
  transform: none;
  margin: 0;
}

/* ================= MML 分隔条（可拖动改变长宽） ================= */
.mml-grip {
  position: relative;
  background: transparent;          /* 默认完全隐形 */
  flex: none;
  pointer-events: auto;
  user-select: none;
  touch-action: none;
}
.mml-grip::before {
  content: '';
  position: absolute;
  background: transparent;          /* 默认线也隐形 */
  transition: background .15s;
}
/* hover / focus / dragging 才显淡蓝 */
.mml-grip:hover,
.mml-grip:focus-visible,
body.dragging-mml .mml-grip.dragging {
  background: rgba(38, 115, 229, 0.12);
}
.mml-grip:hover::before,
.mml-grip:focus-visible::before,
body.dragging-mml .mml-grip.dragging::before {
  background: var(--accent);
}

/* 垂直分隔条（拖动改变左右宽度） */
.mml-grip.v-grip {
  cursor: e-resize;
  width: 8px;
  margin-left: -4px;
}
.mml-grip.v-grip::before {
  top: 0; bottom: 0; left: 50%;
  width: 2px;
  transform: translateX(-1px);
}
.mml-grip.v-grip::after {
  content: '';
  position: absolute;
  inset: 0;
}

/* 水平分隔条（拖动改变上下高度） */
.mml-grip.h-grip {
  cursor: n-resize;
  height: 8px;
  margin-top: -4px;
}
.mml-grip.h-grip::before {
  left: 0; right: 0; top: 50%;
  height: 2px;
  transform: translateY(-1px);
}
.mml-grip.h-grip::after {
  content: '';
  position: absolute;
  inset: 0;
}

/* 跟随 CSS 变量的 grip（absolute 跟随 mml-page 边） */
.mml-grip.grip-left {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--mml-left-w);
  width: 8px;
  margin-left: 0;
  transform: translateX(-50%);
  cursor: e-resize;
}

/* 主区域底部分隔条：absolute 跟随 --mml-bottom-h 上沿，保证拖动方向跟鼠标一致 */
.mml-grip#mml-grip-main-bot {
  position: absolute;
  bottom: var(--mml-bottom-h);
  left: 0; right: 0;
  height: 8px;
  margin-top: 0;          /* 覆盖 .h-grip 的 -4px */
  width: auto;
  cursor: n-resize;
}

body.dragging-mml { cursor: e-resize; user-select: none; }
body.dragging-mml.v { cursor: e-resize; }
body.dragging-mml.h { cursor: n-resize; }
body.dragging-mml * { pointer-events: none !important; }
body.dragging-mml .mml-grip,
body.dragging-mml .mml-grip * { pointer-events: auto !important; }


/* 网元区（左侧栏） */
.mml-left {
  grid-area: left;
  background: #fff; border-right: 1px solid var(--border);
  display: flex; flex-direction: column; overflow: hidden;
}
.mml-left-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
}
.ml-tools {
  display: flex; align-items: center; gap: 4px;
  padding: 8px 10px; border-bottom: 1px solid var(--border);
}
.ml-tools .ml-ic {
  width: 22px; height: 22px; display: flex; align-items: center; justify-content: center;
  border: 1px solid transparent; border-radius: 3px; cursor: pointer; color: var(--text-dim); font-size: 13px;
}
.ml-tools .ml-ic:hover { color: var(--accent); border-color: var(--accent); }
.ml-tools .ml-ic svg { width: 14px; height: 14px; display: block; }
.ml-tools .ml-ic.on { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.ml-tools .ml-eye .ml-eye-open { display: none; }
.ml-tools .ml-eye.on .ml-eye-open { display: block; }
.ml-tools .ml-eye .ml-eye-closed { display: block; }
.ml-tools .ml-eye.on .ml-eye-closed { display: none; }
.ml-search-wrap { position: relative; margin: 8px 10px; }
.ml-search-wrap .ml-search {
  width: 100%; box-sizing: border-box; height: 28px; padding: 0 48px 0 10px;
  border: 1px solid var(--border-strong); border-radius: 4px; font-size: 12px; outline: none;
}
.ml-search-wrap .ml-search:focus { border-color: var(--accent); }
.ml-search-wrap .ml-search-x,
.ml-search-wrap .ml-search-go {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;
  border-radius: 3px; cursor: pointer; color: var(--text-faint); user-select: none;
}
.ml-search-wrap .ml-search-x { right: 25px; }
.ml-search-wrap .ml-search-x svg { display: block; }
.ml-search-wrap .ml-search-x:hover { color: var(--text); background: var(--border-light); }
.ml-search-wrap .ml-search-go { right: 3px; color: var(--text-dim); }
.ml-search-wrap .ml-search-go:hover { color: var(--accent); }
.ml-search-wrap .ml-search-go svg { width: 13px; height: 13px; display: block; }
.ml-filters { padding: 0 10px 8px; border-bottom: 1px solid var(--border); }
.ml-filters .f-row {
  display: flex; align-items: center; gap: 8px; margin-bottom: 6px;
  font-size: 12px;
}
.ml-filters .f-row .f-lbl { width: 60px; color: var(--text-dim); flex: none; }
.ml-filters .f-row .f-sel {
  flex: 1; height: 24px; padding: 0 6px;
  border: 1px solid var(--border-strong); border-radius: 3px;
  background: #fff; color: var(--text); font-size: 12px; outline: none;
}
.ml-filters .f-dual { display: flex; gap: 4px; flex: 1; }
.ml-filters .f-dual .f-sel { min-width: 0; }
.ml-tabs {
  display: flex; border-bottom: 1px solid var(--border);
  padding: 0 10px;
}
.ml-tabs .ml-tab {
  padding: 7px 14px; font-size: 12px; cursor: pointer; color: var(--text-dim);
  border-bottom: 2px solid transparent; transition: all .15s;
}
.ml-tabs .ml-tab.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 500; }
.ml-tab:hover { color: var(--accent); }
.ml-sel-info {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 12px; font-size: 12px; color: var(--text-dim);
  background: #fafbfc; border-bottom: 1px solid var(--border-light);
}
.ml-sel-info b { color: var(--accent); font-weight: 600; padding: 0 1px; }
.ml-selonly { display: flex; align-items: center; gap: 8px; min-width: 0; }
.ml-selonly .sw {
  width: 28px; height: 14px; border-radius: 8px; background: var(--border-strong);
  position: relative; cursor: pointer; transition: background .15s; flex: none;
}
.ml-selonly .sw::after {
  content: ''; position: absolute; left: 2px; top: 2px;
  width: 10px; height: 10px; border-radius: 50%; background: #fff;
  transition: left .15s;
}
.ml-selonly .sw.on { background: var(--accent); }
.ml-selonly .sw.on::after { left: 16px; }
.ml-add-cust { color: var(--accent); cursor: pointer; }
.ml-add-cust:hover { text-decoration: underline; }
.ml-tree-box { flex: 0 0 var(--mml-tree-h); overflow-y: auto; border-bottom: 1px solid var(--border-light); min-height: 0; }
.ml-tree-box .ml-tree { padding: 6px 6px; font-size: 12px; }

/* 命令导航（高度由 mml-tree-h 变量决定剩余空间） */
.ml-cmd-nav {
  border-top: 1px solid var(--border); background: #fafbfc;
  flex: 1 1 0;
  display: flex; flex-direction: column; overflow: hidden;
  min-height: 0;
}
.ml-cn-head {
  display: flex; align-items: center; gap: 6px;
  padding: 8px 12px; font-size: 12px; color: var(--text-dim); cursor: pointer;
  user-select: none; flex: none;
}
.ml-cn-head:hover { background: #f0f3f8; }
.ml-cn-head .cn-text { flex: 1; font-weight: 500; }
/* 标题行右侧放大镜搜索按钮 */
.cn-search-btn {
  flex: none; width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 3px; color: var(--text-faint); cursor: pointer;
}
.cn-search-btn svg { width: 13px; height: 13px; display: block; }
.cn-search-btn:hover { color: var(--accent); background: #e8f0fb; }
/* 命令导航树节点前的 +/− 方框 */
.cn-toggle-box {
  flex: none; width: 14px; height: 14px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-strong); border-radius: 2px;
  color: var(--text-dim); background: #fff;
  cursor: pointer; user-select: none;
}
.cn-toggle-box:hover { border-color: var(--accent); color: var(--accent); }
.ml-cn-head .cn-toggle-box { background: #fff; }
.cn-toggle-box.cn-toggle-leaf { cursor: default; color: var(--text-faint); border-color: var(--border); background: #fafafa; }
.cn-toggle-box.cn-toggle-leaf:hover { border-color: var(--border); color: var(--text-faint); }

/* 展开/收起方框的图标：内联 SVG 画「+」（横线 + 竖线），
   展开态加 .open → 隐藏竖线即成「−」。不再用文字 +/-，避免不同字体下字形/基线漂移。 */
.cn-toggle-box svg.tg-ic,
.nt-toggle svg.tg-ic { display: block; pointer-events: none; }
.cn-toggle-box.open svg.tg-ic .tg-v,
.nt-toggle.open svg.tg-ic .tg-v { display: none; }
.ml-cn-body { padding: 4px 0 8px; flex: 1; display: flex; flex-direction: column; min-height: 0; }
.cn-search {
  display: block; margin: 2px 10px 6px; width: calc(100% - 20px);
  height: 24px; padding: 0 8px;
  border: 1px solid var(--border-strong); border-radius: 3px; font-size: 12px; outline: none;
  flex: none;
}
.cn-search:focus { border-color: var(--accent); }
.cn-tree { padding: 0 4px 0 24px; flex: 1; overflow-y: auto; min-height: 0; }
.cn-row {
  display: flex; align-items: center; gap: 4px;
  padding: 4px 8px; font-size: 12px; color: var(--text-dim);
  cursor: pointer; border-radius: 3px; white-space: nowrap;
}
.cn-row:hover { background: var(--hover); color: var(--accent); }
.cn-row.active { background: var(--accent-soft); color: var(--accent); font-weight: 500; }
.cn-children { padding-left: 14px; }
.cn-row .cn-name { overflow: hidden; text-overflow: ellipsis; min-width: 0; }

/* 主区域（空状态 + 编辑命令界面） */
.mml-main {
  grid-area: main; overflow: hidden; padding: 0;
  background: var(--bg); min-width: 0;
  display: flex; flex-direction: column;
}
.mml-empty {
  flex: 1; min-height: 0; display: flex; flex-direction: column; align-items: center;
  justify-content: flex-start; padding: 36px 24px 24px; gap: 0;
}
.mml-illu { width: 200px; height: 170px; margin-bottom: 24px; }
.mml-illu svg { width: 100%; height: 100%; display: block; }
.mml-steps-title {
  font-size: 16px; color: var(--text); font-weight: 500;
  margin-bottom: 24px; letter-spacing: 1px;
}
.mml-steps {
  display: flex; align-items: center; gap: 0; padding: 0 20px;
  width: 540px; max-width: 100%;
}
.ms-step {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  min-width: 100px; text-align: center;
}
.ms-num { font-size: 12px; color: var(--text-faint); }
.ms-dot {
  width: 14px; height: 14px; border-radius: 50%;
  background: #c2dcfb; box-shadow: 0 0 0 4px #e8f2fc;
}
.ms-dot.active { background: #3b9eff; box-shadow: 0 0 0 4px #d6e8fb; }
.ms-name { font-size: 13px; color: var(--text-faint); font-weight: 500; }
.ms-name.active { color: var(--accent); }
.ms-arc { flex: 1; height: 24px; min-width: 30px; }
.mml-tip { margin-top: 28px; font-size: 13px; color: var(--text-faint); }

/* 执行结果区 */
.mml-result { height: 100%; display: flex; flex-direction: column; min-height: 0; }
.mr-tabs {
  display: flex; align-items: center; gap: 0;
  background: #fff; border-bottom: 1px solid var(--border);
  padding: 0 12px;
}
.mr-tab {
  padding: 10px 18px; font-size: 13px; color: var(--text-dim); cursor: pointer;
  border-bottom: 2px solid transparent; transition: all .15s;
}
.mr-tab.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 500; }
.mr-tab:hover { color: var(--accent); }
/* 报文区：**唯一的滚动容器**（X + Y 两条滑动条都在这里）。
   内部（.res-body / .res-tbl-wrap）不再各自滚动 —— 由 js 渲染的表格超出宽度时
   直接在 mr-body 上横向滚动（见下方 .res-block 的 overflow: visible）。 */
.mr-body {
  flex: 1; overflow: auto; padding: 0;
  background: #fff;
}
.mr-empty { padding: 60px 0; text-align: center; font-size: 13px; color: var(--text-faint); }
/* 上半框「报文」空状态：纯空白占位（截图中的圆徽是其他软件小组件，不还原） */
.mr-body .me-view { min-height: 100%; height: auto; display: flex; flex-direction: column; }
.mresult-empty { flex: 1; }

/* 结果块（报文 tab 内容）
   作用域：**一律带 .mr-body 前缀** —— 只作用于报文框内部，页面别处不受影响
   （这几个类只有 js/mml.js 在报文框里用；加前缀后，即使别处出现同名类也不会被波及）。
   报文里不要边框、不要分隔线、不要背景色（2026-09-24 用户要求）：
   .res-block 无边框无底色；.res-head / .res-cmd 无底色、无下边线；
   成功/失败只保留文字颜色（绿/红），不再铺底色。
   **不能再给 .res-block 加 overflow: hidden** —— 会把宽表格裁在块内，横向溢出传不到 .mr-body。 */
.mr-body .res-block { margin-bottom: 12px; border: none; background: none; overflow: visible; }
.mr-body .res-block .res-head {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 14px; font-size: 12px; color: var(--text-dim);
  background: none; border: none;
}
.mr-body .res-block .res-head b { color: var(--text); font-weight: 600; }
.mr-body .res-block .res-head .ne-ip { color: var(--text-faint); font-family: Consolas, monospace; font-size: 11px; }
.mr-body .res-block .res-head .res-time { margin-left: auto; color: var(--text-faint); font-size: 11px; }
.mr-body .res-block .res-cmd {
  padding: 6px 14px; font-family: Consolas, "Courier New", monospace; font-size: 12px;
  background: none; color: var(--text); border: none;
}
.mr-body .res-block .res-cmd .cmd-key { color: var(--accent); font-weight: 600; }
.mr-body .res-block .res-cmd .cmd-ne { color: var(--text-dim); }
/* 报文正文：**不再自滚动**（原先 max-height:320px + overflow-y 会多出一条滑动条）
   —— 纵向滚动统一交给 .mr-body。 */
.mr-body .res-block .res-body {
  padding: 12px 14px; font-family: var(--mono-align); font-size: 12px;
  line-height: 1.7; white-space: pre-wrap; word-break: break-all; color: var(--text);
}
.mr-body .res-block.ok .res-head { color: var(--success); background: none; }
.mr-body .res-block.err .res-head { color: var(--critical); background: none; }
/* 查询结果表格（一行一条记录）
   样式口径（2026-09-24 用户要求）：无边框、无背景色，表头与内容同字号同颜色；
   唯一的表头分隔是「表头下空出一个单元格」（见 thead th 的 padding-bottom）。
   超宽不压缩列宽（white-space: nowrap）→ 横向滚动条落在 .mr-body 上，本容器不滚动。 */
.res-tbl-wrap { padding: 10px 12px; }
.res-tbl {
  border-collapse: collapse; font-family: Consolas, "Courier New", monospace;
  font-size: 12px; line-height: 20px; color: var(--text); white-space: nowrap;
}
/* 单元格统一：20px 行距 + 上下 4px 内边距 → 一行高 = 28px（表头留白按它算） */
.res-tbl th, .res-tbl td {
  border: none; background: none; padding: 0 10px; text-align: left;
  font-size: 12px; font-weight: normal; color: var(--text);
}
/* 组开关这类「多行值」（成员名:值 逐行）在单元格里必须按行显示：
   外层 .res-tbl 是 nowrap，HTML 会把 \n 折成空格 → 16 个成员挤成一整行。
   用 pre 而不是 pre-line：pre-line 允许折行，窄列会把一条成员折成三四行、版面错乱
   （2026-10-08 真浏览器截图踩过）；本表格的既有口径就是「不压缩列宽、横向滚动」，
   所以这里只保留换行、不允许折行，列宽由最长的那一行成员决定。 */
.res-tbl td { white-space: pre; vertical-align: top; }
/* 表头与第一行之间空出一个单元格：表头下内边距 24px + 数据行上内边距 4px = 28px = 一行高 */
.res-tbl thead th { padding-bottom: 24px; }

/* 历史 / 命令帮助列表 */
.hist-item {
  display: flex; align-items: center; gap: 14px;
  padding: 8px 14px; font-size: 12px; background: #fff;
  border: 1px solid var(--border); border-radius: 4px; margin-bottom: 6px;
  cursor: pointer;
}
.hist-item:hover { background: var(--hover); }
.hist-time { color: var(--text-faint); min-width: 150px; font-family: Consolas, monospace; }
.hist-cmd { color: var(--accent); font-family: Consolas, monospace; flex: 1; }
.hist-ne { color: var(--text-dim); }
/* 命令详情（复刻离线工具帮助页：所属网元 / 命令功能 / 注意事项） */
.hp-ne { margin: 8px 0 4px; font-size: 12px; color: var(--text); line-height: 1.6; }
.hp-ne b { color: var(--text-dim); font-weight: 600; }
.hp-sec {
  margin: 10px 0 4px; color: var(--text-dim); font-weight: 600; font-size: 12px;
  border-left: 3px solid var(--accent); padding-left: 6px;
}
.hp-func { color: var(--text); line-height: 1.7; margin: 4px 0 0; font-size: 12px; }
.hp-warn {
  margin: 6px 0; color: var(--critical, #e5484d); line-height: 1.7;
  background: #fff5f5; border: 1px solid #ffd6d6; border-radius: 4px; padding: 8px 10px;
}
.hp-notes { margin: 6px 0 0; padding-left: 20px; }
.hp-notes li { color: var(--text); line-height: 1.7; margin-bottom: 6px; }
/* 空内容占位（无。），对齐截图 */
.hp-empty { color: var(--text-dim); line-height: 1.7; margin: 4px 0 0; font-size: 12px; }
/* 参数说明表 */
.hp-params-wrap { overflow: auto; }
.hp-params {
  border-collapse: collapse; width: 100%; margin: 6px 0 0;
  font-size: 12px; table-layout: fixed;
}
.hp-params th, .hp-params td {
  border: 1px solid var(--border); padding: 5px 8px; text-align: left;
  vertical-align: top; line-height: 1.6; word-break: break-word;
}
.hp-params th {
  background: var(--bg, #f0f4fa); color: var(--text-dim); font-weight: 600;
  position: sticky; top: 0; z-index: 1;
}
.hp-params tr:nth-child(even) td { background: rgba(0,0,0,.015); }
.hp-params .hp-pid { font-family: Consolas, monospace; color: var(--accent); }
.hp-params .hp-pname { color: var(--text); }
.hp-params .hp-pdesc { color: var(--text-dim); white-space: pre-line; max-height: 360px; overflow-y: auto; }
/* 使用实例 */
.hp-example {
  margin: 6px 0 0; padding: 10px 12px; background: #f7f9fc;
  border: 1px solid var(--border); border-radius: 4px;
  /* 帮助里的「使用实例」就是真实报文示例，同样靠空格对齐 → 用 --mono-align（见其注释） */
  font-family: var(--mono-align); font-size: 12px; color: var(--text);
  white-space: pre-wrap; word-break: break-all; line-height: 1.7;
}
/* 命令帮助：大标题卡片（复刻离线工具：蓝色大标题 + 下属信息） */
.help-detail { padding: 4px 2px 8px; }
.hp-title {
  font-size: 16px; font-weight: 600; color: var(--accent);
  line-height: 1.5; margin: 0 0 6px; padding: 2px 0 10px;
  border-bottom: 1px solid var(--border); word-break: break-all;
}
.hp-title .hp-cmd-t {
  font-size: 13px; font-weight: 400; color: var(--text-dim);
  font-family: Consolas, monospace; white-space: nowrap;
}
/* 未选择命令时的占位提示（不显示全部帮助，避免大 DOM） */
.help-placeholder {
  display: flex; align-items: center; justify-content: center;
  min-height: 140px; color: var(--text-faint, #9aa5b5);
  font-size: 12px; text-align: center; line-height: 1.9; padding: 24px;
}


/* 编辑命令界面（选中网元后主区域显示，absolute 布局使 grip 跟随 mcmd 顶部移动，方向正确） */
.mml-editor {
  position: relative;
  flex: 1; min-height: 0; min-width: 0;
  display: block;
  background: var(--bg);
  overflow: hidden;
}
/* 上半：报文 / 历史 / 命令帮助（结果展示区，absolute + contain 隔离内部 reflow） */
.mresult {
  position: absolute;
  top: 0; left: 0; right: 0;
  bottom: calc(8px + var(--mml-bottom-h));
  min-width: 0;
  display: flex; flex-direction: column;
  background: #fff;
  border-bottom: 1px solid var(--border);
  contain: layout paint;            /* 隔离 mresult 内部 layout 对外部的影响 */
  overflow: hidden;
}
/* 下半：编辑命令（编辑命令 + 参数配置区，高度由 --mml-bottom-h 控制） */
.mcmd {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  height: var(--mml-bottom-h);
  min-width: 0;
  display: flex; flex-direction: column;
  background: #fff;
  contain: layout;
}
.meb-panel {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column;
  padding: 14px 20px 18px;
  background: #fff;
}
.meb-header {
  display: flex; align-items: center; gap: 14px; margin-bottom: 10px;
}
.meb-title { font-size: 14px; font-weight: 600; color: var(--text); }
.meb-title::before {
  content: ''; display: inline-block; width: 3px; height: 13px;
  background: var(--accent); border-radius: 2px; margin-right: 6px; vertical-align: -2px;
}
.meb-tools { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-dim); margin-left: auto; }
.meb-tools .sw {
  width: 28px; height: 14px; border-radius: 8px; background: var(--border-strong);
  position: relative; cursor: pointer; transition: background .15s;
}
.meb-tools .sw::after {
  content: ''; position: absolute; left: 2px; top: 2px;
  width: 10px; height: 10px; border-radius: 50%; background: #fff;
  transition: left .15s;
}
.meb-tools .sw.on { background: var(--accent); }
.meb-tools .sw.on::after { left: 16px; }
.meb-tools-lbl { color: var(--text-dim); }
/* meb 输入行：左侧工具组（参数面板开关 + 历史 ←/→），收藏内嵌输入框右侧 */
.meb-input-row .meb-tools { margin-left: 0; gap: 6px; flex: none; }
.meb-nav {
  width: 22px; height: 22px; display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-strong); border-radius: 3px; cursor: pointer;
  background: #fff; color: var(--text-dim); font-size: 13px; line-height: 1;
}
.meb-nav:hover { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.meb-input-box { position: relative; flex: 1; min-width: 0; display: flex; }
.meb-input-box .meb-input { width: 100%; padding-left: 34px; padding-right: 10px; }
.meb-fav-in {
  position: absolute; left: 6px; top: 50%; transform: translateY(-50%);
  padding: 2px 10px 2px 2px; border-right: 1px solid var(--border-strong);
  color: var(--text-faint); cursor: pointer; user-select: none;
  display: inline-flex; align-items: center;
}
.meb-fav-in svg { display: block; }
.meb-fav-in:hover { color: var(--major); }
.meb-fav-in.on { color: var(--major); }
/* 已收藏：把空心星填实（内联给的是 fill="none"，CSS 优先级更高，可直接覆盖） */
.meb-fav-in.on svg path { fill: currentColor; }
.meb-tools .meb-ic {
  width: 22px; height: 22px; display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: 3px; cursor: pointer; color: var(--text-dim); font-size: 13px;
}
.meb-tools .meb-ic:hover { color: var(--accent); border-color: var(--accent); }
.meb-input-wrap { position: relative; }
.meb-input-row { display: flex; align-items: center; gap: 8px; }
.meb-fav-btn {
  width: 32px; height: 32px; flex: none;
  background: #e8f2fc; border: 1px solid #b9d2f5; border-radius: 4px;
  color: var(--accent); font-size: 16px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.meb-fav-btn:hover { background: var(--accent); color: #fff; }
.meb-input {
  flex: 1; height: 32px; padding: 0 12px;
  border: 1px solid var(--accent); border-radius: 4px;
  font-size: 13px; color: var(--text); outline: none;
  font-family: Consolas, "Courier New", monospace;
  box-shadow: 0 0 0 2px rgba(38,115,229,.08);
}
.meb-input:focus { box-shadow: 0 0 0 2px rgba(38,115,229,.2); }
.meb-run {
  height: 32px; padding: 0 18px;
  background: var(--accent); color: #fff; border: 1px solid var(--accent);
  border-radius: 4px; font-size: 13px; cursor: pointer; font-weight: 500;
}
.meb-run:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.meb-run:disabled { background: var(--border-strong); border-color: var(--border-strong); cursor: not-allowed; }
/* 命令联想下拉（悬浮在输入框下方） */
.meb-list {
  position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 30;
  max-height: 200px; overflow-y: auto;
  background: #fff; border: 1px solid var(--border); border-radius: 4px;
  box-shadow: 0 6px 18px rgba(0,0,0,.12);
}
.meb-list-body { padding: 4px 6px; }
.cmd-item {
  padding: 4px 8px; font-size: 12px; color: var(--text-dim);
  border-radius: 3px; cursor: pointer; line-height: 1.6;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cmd-item:hover,
.cmd-item.selected { background: #fff; color: var(--accent); }
.cmd-item.selected { background: var(--accent-soft); color: var(--accent); font-weight: 500; }
.cmd-item .ci-name { color: var(--accent); font-family: Consolas, monospace; margin-right: 4px; }
.cmd-item .ci-desc { color: var(--text-faint); }
/* 命令编辑工作区：未执行=「不需要参数配置」占位；已执行=结果块 */
.meb-workspace {
  flex: 1; min-height: 0; margin-top: 12px;
  position: relative; overflow-y: auto;
  border: 1px dashed var(--border-light); border-radius: 6px;
  background: #fafbfc;
}
.me-view { height: 100%; }
.meb-empty-zone {
  min-height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; padding: 20px;
}
.meb-empty-illu { width: 150px; height: 104px; }
.meb-empty-illu svg { width: 100%; height: 100%; display: block; }
.meb-empty-text { font-size: 13px; color: var(--text-dim); }
/* 命令参数面板（华为离线工具风格）：参数行自动换行排布，枚举=下拉、数值=数字框 */
.mp-form { padding: 10px 12px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 18px; }
.mp-row { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; }
.mp-row.req label::after { content: '*'; color: var(--critical); margin-left: 2px; }
.mp-row label { font-size: 12px; color: var(--text-dim); white-space: nowrap; cursor: default; }
.mp-row label:hover { color: var(--text); }
.mp-ctl select,
.mp-ctl input[type=number],
.mp-ctl input[type=text],
.mp-ctl input[type=password] {
  height: 24px; min-width: 88px; padding: 0 6px;
  border: 1px solid var(--border-strong); border-radius: 3px;
  font-size: 12px; color: var(--text); background: #fff; outline: none;
  font-family: Consolas, "Courier New", monospace;
}
.mp-ctl select { min-width: 130px; padding-right: 4px; cursor: pointer; }
.mp-ctl input:focus, .mp-ctl select:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(38,115,229,.12); }
.mp-row.invalid input, .mp-row.invalid select { border-color: var(--critical); background: var(--critical-bg); }
/* fieldarray 三态多选下拉（2026-09-26）：按钮摘要 + fixed 候选菜单 + 三态选框（灰化/选中/不选） */
.mp-fa { position: relative; display: inline-block; max-width: 100%; }
.mp-fa-btn {
  display: inline-block; position: relative; width: 176px; min-height: 24px;
  padding: 2px 26px 2px 8px; text-align: left; font: 12px Consolas, "Courier New", monospace;
  color: var(--text); background: #fff; border: 1px solid var(--border-strong); border-radius: 3px;
  cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; outline: none;
}
.mp-fa-btn:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(38,115,229,.12); }
.mp-fa-caret { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); color: var(--text-faint); pointer-events: none; }
.mp-fa-menu {
  position: fixed; z-index: 90; max-height: 260px; overflow: auto;
  background: #fff; border: 1px solid var(--border-strong); border-radius: 6px;
  box-shadow: 0 8px 24px rgba(15,35,70,.16); padding: 4px 0;
}
.mp-fa-acts { border-bottom: 1px solid var(--border); margin-bottom: 3px; padding-bottom: 2px; }
/* 批量操作行复用 .mp-fa-opt 外观（两态复选框），仅去掉 hover 底色差异并加粗名称 */
.mp-fa-act .mp-fa-nm { font-weight: 600; }
/* 条目行宽随内容（width:max-content），至少填满菜单 → 文字超出菜单宽度时由 .mp-fa-menu 出横向滚动条 */
.mp-fa-opt { display: flex; align-items: center; gap: 8px; padding: 5px 12px; cursor: pointer; font-size: 12px;
  width: max-content; min-width: 100%; box-sizing: border-box; white-space: nowrap; }
.mp-fa-opt:hover { background: #f2f6fc; }
.mp-fa-box { flex: 0 0 14px; width: 14px; height: 14px; border-radius: 3px; border: 1.5px solid #b8c0cc; box-sizing: border-box; position: relative; background: #fff; }
.mp-fa-opt.st-on .mp-fa-box { background: var(--accent); border-color: var(--accent); }
.mp-fa-opt.st-on .mp-fa-box::after { content: ''; position: absolute; left: 3.5px; top: 1px; width: 4px; height: 8px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.mp-fa-opt.st-off .mp-fa-box { background: #fff; border-color: #b8c0cc; }
.mp-fa-opt.st-na .mp-fa-box { background: #e3e7ee; border-color: #cdd4de; }
.mp-fa-opt.st-na .mp-fa-box::after { content: ''; position: absolute; left: 2.5px; top: 4.5px; width: 7px; border-top: 2px solid #a8b1bf; }
.mp-fa-opt.st-na .mp-fa-nm, .mp-fa-opt.st-na .mp-fa-dc { color: var(--text-faint); }
/* 条目文案 = 参数名(中文解释) 连成一串，如 EPS_FB_SWITCH(EPS FB开关)（2026-10-20 用户口径）；
   不换行也不省略 —— 超宽交给菜单横向滚动条 */
.mp-fa-txt { display: inline-flex; align-items: baseline; white-space: nowrap; flex: none; }
.mp-fa-nm { font-weight: 600; color: var(--text); font-family: Consolas, "Courier New", monospace; flex: none; }
.mp-fa-dc { color: var(--text-dim); white-space: nowrap; flex: none; }
.mr-results { padding: 12px 16px; }
/* 参数配置区 ↔ 详细命令框 的可拖动分隔条（2026-10-14 用户要求）：
   复用 .mml-grip 隐形条（hover/拖动才显形），按 flex 子项占位，去掉 h-grip 的 -4px 负边距 */
#meb-grip-detail { flex: none; height: 8px; margin: 2px 0; }
/* 详细命令信息行：图标**直接落在输入框内部**（右侧，无外框），所以输入框要给它留出位置；
   框高由 --meb-detail-h 决定（上方分隔条拖动改变），参数区 .meb-workspace（flex:1）吃剩余高度 */
.meb-detail-box { position: relative; flex: 0 1 var(--meb-detail-h); min-height: 0; margin-top: 0; display: flex; }
/* 参数工作区隐藏时（开关关闭，#meb-workspace display:none，空态一并消失）：
   详细命令框底边不动、上边上浮「长高」，吃满释放的空间（flex-grow，面板底 padding 锚定底边）；
   恢复显示后回到 --meb-detail-h 定高 */
.meb-panel.ws-hidden .meb-detail-box { flex: 1 1 var(--meb-detail-h); }
/* 参数工作区隐藏时拖动条一并隐藏：详细命令框已长高吃满空间，没有可交换的高度，留着用不到（2026-10-14 用户要求） */
.meb-panel.ws-hidden #meb-grip-detail { display: none; }
.meb-detail {
  flex: 1; min-width: 0; height: 100%; padding: 4px 36px 4px 12px;
  border: 1px solid var(--border-strong); border-radius: 4px;
  font-size: 13px; line-height: 1.6; color: var(--text); outline: none;
  white-space: pre-wrap; overflow-wrap: break-word;   /* 多行自动换行（超长参数串也能断行） */
  overflow-y: auto; resize: none;                     /* 高度归分隔条管，禁掉浏览器原生拖角 */
}
.meb-detail:focus { border-color: var(--accent); }
.meb-detail-go {
  position: absolute; right: 5px; top: 50%; transform: translateY(-50%);
  width: 25px; height: 25px;                     /* 25×25（用户指定） */
  display: flex; align-items: center; justify-content: center;
  color: var(--text-dim); cursor: pointer; user-select: none;
}
.meb-detail-go svg { display: block; }
.meb-detail-go:hover { color: var(--accent); }

/* ================= 区域管理（左：优化区域列表 / 右：小区地图分布） ================= */
.main.region-mode { padding: 0; overflow: hidden; }   /* 页面通栏满高，与截图一致（仅当 region 页可见时由 JS 加类） */
.region-page { display: flex; height: calc(100vh - 84px); background: #a9c9ee; }

/* 左侧面板 */
.region-panel { width: 275px; flex: none; background: #fff; display: flex; flex-direction: column; position: relative; z-index: 2; }
.region-panel.collapsed { display: none; }
.rp-tab { flex: none; width: 120px; padding: 10px 0; text-align: center; font-size: 13px; color: #1a2a3a;
  background: #fff; border-bottom: 2px solid #1890ff; box-shadow: 0 1px 3px rgba(0,0,0,.06); }
.rp-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 14px 12px; }
.rp-num { font-size: 30px; font-weight: 600; color: #1a2a3a; line-height: 1.1; text-align: center; }
.rp-num-label { font-size: 12px; color: #8c9bab; text-align: center; margin-top: 2px; }
.rp-actions { display: flex; flex-direction: column; gap: 8px; }
.rp-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 5px 16px;
  background: #1890ff; color: #fff; border: none; border-radius: 3px; font-size: 13px; cursor: pointer; }
.rp-btn:hover { background: #40a9ff; }
.rp-btn svg { width: 13px; height: 13px; }
.rp-techs { display: flex; gap: 14px; padding: 8px 14px; background: #f2f4f7; font-size: 12px; color: #4e5969;
  border-top: 1px solid var(--border-light); border-bottom: 1px solid var(--border-light); }
.rp-tech { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; }
.rp-thead { display: flex; padding: 8px 14px; font-size: 12px; color: #8c9bab; border-bottom: 1px solid var(--border-light); }
.rp-thead span:first-child { flex: 1.4; }
.rp-thead span:last-child { flex: 1; }
.rp-rows { flex: 1; overflow-y: auto; }
.rp-row { display: flex; align-items: center; padding: 7px 14px; font-size: 13px; border-bottom: 1px solid #f0f2f5; }
.rp-row:hover { background: #f5f8ff; }
.rp-name { flex: 1.4; color: #1890ff; cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rp-name:hover { text-decoration: underline; }
.rp-cell { flex: .55; display: inline-flex; align-items: center; gap: 4px; color: #4e5969; }
.rp-ck { width: 13px; height: 13px; color: #1890ff; }
.rp-go { flex: .45; color: #1890ff; cursor: pointer; display: flex; align-items: center; justify-content: flex-end; }
.rp-collapse { flex: none; width: 14px; height: 44px; margin-top: 160px; padding: 0;
  border: none; background: #fff; color: #8c9bab; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  border-radius: 0 4px 4px 0; box-shadow: 2px 0 6px rgba(0,0,0,.08); z-index: 2; }
/* 折叠箭头：图标是内联 SVG，收起态整体翻转 180°（原来是 ◀/▶ 换字符） */
.rp-collapse svg { display: block; transition: transform .15s; }
.rp-collapse.collapsed svg { transform: rotate(180deg); }

/* 右侧地图 */
.region-map { position: relative; flex: 1; min-width: 0; overflow: hidden; cursor: grab; }
.region-map.dragging { cursor: grabbing; }
.region-map.dragging .rm-svg polygon[data-cell] { cursor: grabbing; }
.rm-svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.rm-svg polygon[data-cell] { cursor: pointer; transition: fill .1s; }
.rm-svg polygon[data-cell]:hover { fill: #4aa3f5; }        /* 悬停扇区变蓝（同截图） */
.rm-tip { position: absolute; z-index: 5; pointer-events: none; white-space: nowrap;
  background: rgba(255,255,255,.95); color: #1a3a66; font-size: 12px;
  padding: 3px 8px; border-radius: 2px; box-shadow: 0 2px 6px rgba(0,0,0,.25); }
.rm-toolbar { position: absolute; top: 12px; right: 16px; display: flex; gap: 2px; }
.rm-tb { width: 28px; height: 28px; padding: 4px; border: none; background: transparent; cursor: pointer; border-radius: 4px; }
.rm-tb:hover { background: rgba(255,255,255,.25); }
.rm-tb svg { width: 100%; height: 100%; display: block; }
.rm-scale { position: absolute; right: 60px; bottom: 66px; text-align: center; color: #1a3a66; font-size: 11px; }
.rm-scale i { display: block; width: 64px; height: 0; border-bottom: 2px solid #1a3a66; margin-top: 2px; }
.rm-zoom { position: absolute; right: 24px; bottom: 26px; display: flex; flex-direction: column; }
.rm-zoom button { width: 30px; height: 30px; border: 1px solid #9db8d8; background: #fff; color: #4e5969;
  font-size: 14px; cursor: pointer; }
.rm-zoom button:first-child { border-radius: 3px 3px 0 0; }
.rm-zoom button:last-child { border-radius: 0 0 3px 3px; border-top: none; }
.rm-zoom button:hover { color: #1890ff; }
.rm-coord { position: absolute; right: 12px; bottom: 2px; font-size: 11px; color: #23406e; }
.rm-ch { position: absolute; left: 10px; bottom: 6px; background: rgba(255,255,255,.85); color: #4e5969;
  font-size: 11px; padding: 1px 6px; border-radius: 2px; }
/* ===== 登录用户名历史下拉 ===== */
.login-user-wrap, .login-pass-wrap { position: relative; }
/* 输入框右侧图标按钮：用户名下拉 / 密码眼睛 */
#login-user-dd, #login-pass-eye {
  position: absolute;
  right: 2px; top: 50%;
  transform: translateY(-50%);
  width: 28px; height: 28px;
  align-items: center; justify-content: center;
  background: transparent;
  border: 0; cursor: pointer;
  color: #9bb1c9;
  border-radius: 4px;
  transition: color .15s, background .15s;
  z-index: 2;
}
/* 用户名下拉：默认隐藏，有历史账号时才显示（由 JS 置 flex） */
#login-user-dd { display: none; }
/* 密码眼睛：始终显示 */
#login-pass-eye { display: flex; }
#login-user-dd:hover, #login-pass-eye:hover { color: #2673e5; background: rgba(38,115,229,.08); }
#login-user-dd svg, #login-pass-eye svg { display: block; }
#login-user-dd svg { transition: transform .2s; }
#login-user-dd.open svg { transform: rotate(180deg); }
/* 明文显示时的激活态 */
#login-pass-eye.on { color: #2673e5; }
#login-user-list {
  position: absolute;
  left: 0; right: 0; top: calc(100% + 4px);
  margin: 0; padding: 4px 0;
  list-style: none;
  background: #fff;
  border: 1px solid #d6e2f0;
  border-radius: 6px;
  box-shadow: 0 6px 20px rgba(20,40,80,.18);
  max-height: 220px;
  overflow-y: auto;
  z-index: 10;
}
#login-user-list.hidden { display: none; }
#login-user-list:empty { display: none; }
.login-user-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  font-size: 13px;
  color: #2a3a55;
  cursor: pointer;
  transition: background .12s;
}
.login-user-item:hover { background: #f0f6ff; }
.login-user-item.current { color: #2673e5; font-weight: 600; }
.login-user-rm {
  flex: 0 0 auto;
  width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  color: #b8c5d6;
  cursor: pointer;
  transition: color .15s, background .15s;
}
.login-user-rm:hover { color: #fff; background: #ff5b5b; }
.login-user-rm svg { display: block; }

/* ================= 全屏 404（页面不存在） =================
   触发条件：地址不带板块前缀（#mml / #MML命令）、板块名写错（#WrongAccess/MML）、
             板块名对但页面不属于它（#Evaluation/MML）。
   走 mode-404：保留顶部导航与工作台下拉条，只隐藏侧栏，内容区居中显示。 */
.app.mode-404 .sidebar { display: none; }
.app.mode-404 .workspace-bar { display: flex; }   /* 工作台下拉条保留 */
.app.mode-404 .main { display: flex; padding: 0; }
/* #page-host-live 是普通块级元素（高度自动），.nf-page 的 flex:1 撑不开 → 内容原先贴在顶部。
   改成纵向 flex 容器并撑满，404 才能整体铺满内容区。 */
.app.mode-404 #page-host-live { flex: 1; min-height: 100%; display: flex; flex-direction: column; }
.nf-page {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; text-align: center;
  /* 视觉中心在几何中心上方 100px：(padding-bottom - padding-top) / 2 = (224 - 24) / 2 = 100 */
  padding: 24px 24px 224px;
}
.nf-code { font-size: 76px; font-weight: 700; line-height: 1; letter-spacing: 2px; color: var(--border); }
.nf-title { font-size: 18px; font-weight: 600; color: var(--text); }
.nf-sub { font-size: 13px; line-height: 1.8; color: var(--text-dim); max-width: 470px; }
.nf-page .btn { margin-top: 6px; }

/* 地址栏输入了不存在的路径（/Access2、/index2.php…）：由 PHP 直出 views/404.php，
   没有 .app 外壳，靠 body 撑满一屏让 .nf-page 的 flex:1 生效；
   padding-bottom 是对齐 SPA 版（那里要避开顶栏 + 工作台条），这里无顶栏，改成对称留白。 */
.nf-standalone { display: flex; flex-direction: column; min-height: 100vh; }
.nf-standalone .nf-page { padding: 24px; }

/* ==================== MML 命令库加载模态框 ==================== */
.mml-load-overlay {
  position: fixed; inset: 0; z-index: 2000;
  display: flex; align-items: center; justify-content: center;
  background: rgba(8, 16, 32, .55);
  backdrop-filter: blur(2px);
}
.mml-load-card {
  width: 320px; padding: 26px 26px 20px;
  border-radius: 12px; background: var(--panel, #fff);
  box-shadow: 0 12px 40px rgba(0, 0, 0, .25);
  text-align: center;
}
.mml-load-spinner {
  width: 26px; height: 26px; margin: 0 auto 12px;
  border: 3px solid var(--border, #dde3ec);
  border-top-color: var(--primary, #2673e5);
  border-radius: 50%;
  animation: mml-load-spin .8s linear infinite;
}
@keyframes mml-load-spin { to { transform: rotate(360deg); } }
.mml-load-title { font-size: 14px; font-weight: 600; color: var(--text, #1c2430); margin-bottom: 14px; }
.mml-load-bar {
  height: 6px; border-radius: 3px; overflow: hidden;
  background: var(--border, #dde3ec);
}
.mml-load-bar i {
  display: block; height: 100%; width: 0;
  border-radius: 3px;
  background: linear-gradient(90deg, #5fb6ff, #2673e5);
  transition: width .15s ease-out;
}
.mml-load-pct { margin-top: 8px; font-size: 12px; color: var(--text-dim, #7a8699); }
.mml-load-err { margin-top: 12px; font-size: 13px; color: #d4380d; line-height: 1.6; }
.mml-load-err.hidden { display: none; }
.mml-load-retry {
  margin-left: 8px; padding: 3px 14px;
  border: 1px solid var(--primary, #2673e5); border-radius: 6px;
  background: transparent; color: var(--primary, #2673e5);
  font-size: 12px; cursor: pointer;
}
.mml-load-retry:hover { background: var(--primary, #2673e5); color: #fff; }

/* 登录输入框空值红边框提醒（doLogin 前置校验） */
.field-float input.input-empty { border-bottom-color: #d9534f; }
.field-float input.input-empty + label { color: #d9534f; }

/* ================= 网元管理（网元入库第一期）================= */
/* 网元状态徽标：正常=绿 / 预部署=橙 / 脱管=灰 */
.ne-state { display: inline-block; padding: 1px 8px; border-radius: 10px; font-size: 12px; line-height: 18px; white-space: nowrap; }
.ne-state-normal  { background: rgba(82,193,26,.12);  color: var(--success); }
.ne-state-pre     { background: rgba(250,140,22,.14); color: var(--major); }
.ne-state-offline { background: rgba(140,149,158,.16); color: var(--text-dim); }
.ne-state-unknown { background: rgba(140,149,158,.12); color: var(--text-dim); }
/* 网元管理页表格：名称过长省略 */
#ne-table td { vertical-align: middle; }
#ne-table td:nth-child(2) { max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 拓扑右键菜单 */
.topo-menu {
  position: fixed; z-index: 3000; min-width: 150px; padding: 4px 0;
  background: #fff; border: 1px solid var(--border-strong); border-radius: 6px;
  box-shadow: 0 6px 20px rgba(0,0,0,.14); font-size: 13px;
}
.topo-menu .tm-item { padding: 7px 14px; cursor: pointer; color: var(--text); }
.topo-menu .tm-item:hover { background: var(--hover); color: var(--accent); }

/* ================= 个人设置（左导航树 + 右内容区，对齐真实网管） ================= */
/* 页面级形态：左树右内容，无页面标题/面包屑 —— 与 /views 里的「系统 > 用户管理 > 个人设置」一致 */
.set-page { display: flex; align-items: flex-start; gap: 14px; }
.set-nav {
  width: 200px; flex: none; padding: 8px 0 10px;
  background: #fff; border: 1px solid var(--border); border-radius: 6px;
}
.set-nav-group { padding: 6px 16px 4px; font-size: 12px; color: var(--text-faint); }
.set-nav-item {
  padding: 8px 16px; font-size: 13px; color: var(--text-dim); cursor: pointer;
  border-left: 3px solid transparent;
}
.set-nav-item:hover { color: var(--accent); background: var(--hover); }
.set-body { flex: 1; min-width: 0; }
.set-pane { display: none; }

/* ★ 选中态与面板显隐都由 data-active 派生（同一份状态，二者不可能不同步），不靠 JS 逐个 toggle */
.set-page[data-active="fmt"] .set-nav-item[data-pane="fmt"],
.set-page[data-active="me"]  .set-nav-item[data-pane="me"],
.set-page[data-active="pw"]  .set-nav-item[data-pane="pw"] {
  color: var(--accent); background: var(--accent-soft);
  border-left-color: var(--accent); font-weight: 500;
}
.set-page[data-active="fmt"] .set-pane[data-pane="fmt"],
.set-page[data-active="me"]  .set-pane[data-pane="me"],
.set-page[data-active="pw"]  .set-pane[data-pane="pw"] { display: block; }

.set-sub { font-size: 12px; color: var(--text-faint); margin: -4px 0 14px; }
.set-label { font-size: 12px; color: var(--text-dim); margin-bottom: 8px; }
/* 单选项做成「一行一块」：命中区更大，右侧显示格式示例（真实页面的 HH:mm:ss / hh:mm:ss tt） */
.set-radio {
  display: flex; align-items: center; gap: 8px; padding: 9px 12px; margin-bottom: 8px;
  font-size: 13px; color: var(--text); background: #fff;
  border: 1px solid var(--border); border-radius: 4px; cursor: pointer;
}
.set-radio:hover { border-color: var(--accent-border); background: var(--hover); }
.set-radio:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.set-radio input { accent-color: var(--accent); }
.set-radio-hint { margin-left: auto; font-size: 12px; color: var(--text-faint); font-family: Consolas, monospace; }
.set-preview { padding: 9px 12px; margin-bottom: 12px; font-size: 13px; color: var(--text-dim); background: var(--panel-3); border-radius: 4px; }
.set-preview b { color: var(--text); font-weight: 500; font-family: Consolas, monospace; }
.set-note { font-size: 12px; color: var(--text-faint); margin-bottom: 14px; }
.set-actions { display: flex; gap: 8px; }
/* 修改密码：复用 .form-grid 的输入框样式，只是收成单列（右内容区不必铺满整宽） */
.set-pane .form-grid.set-form { grid-template-columns: 1fr; max-width: 420px; }
/* 个人信息：.kv 原先只在 .modal-body 下定义，搬进本页要自带一份 */
.set-page .kv { display: flex; padding: 7px 0; border-bottom: 1px dashed var(--border-light); font-size: 13px; }
.set-page .kv .k { width: 96px; flex: none; color: var(--text-dim); }
.set-page .kv .v { flex: 1; min-width: 0; color: var(--text); }

/* ---------- 个人信息：姓名就地编辑 ---------- */
/* 编辑态由 .me-name-row 上的 data-editing 派生（和右侧面板用 data-active 同一手法）：
   文本 / 输入框 / 铅笔 / 「保存修改 / 取消」的显隐全在这一段 CSS 里，JS 只改那一个属性。
   「保存修改 / 取消」与输入框同一行（都挂在 .me-name-cell 这个 flex 里，跟在 input 后面）。 */
.set-page .me-name-cell { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* 输入框长在 .kv 里，够不到 .form-grid .field input 那套基础样式 → 这里按同一口径自带一份 */
.set-page .me-name-input {
  display: none; width: 180px; height: 30px; padding: 6px 10px; border-radius: 4px; outline: none;
  background: #fff; border: 1px solid var(--border-strong); color: var(--text); font-size: 13px;
}
.set-page .me-name-input:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(38,115,229,.12); }
.set-page .me-name-actions { display: none; align-items: center; gap: 8px; }
.me-name-row[data-editing="1"] .me-name-text { display: none; }
.me-name-row[data-editing="1"] .me-name-input { display: inline-block; }
.me-name-row[data-editing="1"] .me-name-actions { display: inline-flex; }
.me-name-row[data-editing="1"] .me-icon-btn { display: none; }    /* 编辑中藏掉铅笔：此刻的动作是保存 / 取消 */
/* 铅笔按钮：内联 SVG 里的 fill=currentColor，颜色由这里的 color 决定 */
.set-page .me-icon-btn {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; padding: 0; margin-left: 2px;
  border: 0; border-radius: 4px; background: transparent;
  color: var(--text-faint); cursor: pointer; line-height: 1;
}
.set-page .me-icon-btn:hover { color: var(--accent); background: var(--hover); }
.set-page .me-icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.set-page .me-name-msg { font-size: 12px; }
.set-page .me-name-msg:empty { display: none; }   /* 空提示不占位，免得两个按钮后面多一段空隙 */
.set-page .me-name-msg.err { color: var(--critical); }
.set-page .me-name-msg.ok  { color: var(--success); }

/* ==================== 当前告警（1:1 复刻 U2000/MAE 截图，2026-09-16） ==================== */
/* ---------- 顶部工具区：浮动条 + 白底工具栏 ---------- */
.alm-page { position: relative; }
/* 浮动条（四个级别计数徽章那一行）：2026-09-16 用户要求脱出 .alm-bar —— 不与「自动刷新」同框。
   做法：负外边距抵消 #main-content 的 padding(16px 20px)，让这条横贴内容区顶边与左右两边；
   自带浅灰底 + 下边线自成一档，像 workspace-bar 一样浮在内容之上而非嵌在内容框里。
   ⚠️ top 必须与 margin-top 同为 -16px（= #main-content 的 padding-top）：
      sticky 的参照是滚动容器的【padding box】（即 16px 那条线），top:0 会把本元素从静态位置
      往下推 16px（实测：浮条落在 100 而不是 84，还压住下面白底条 6px）。两值相等时吸顶不产生位移。 */
.alm-row.alm-floatbar {
  position: sticky; top: -16px; z-index: 6;
  margin: -16px -20px 10px; padding: 0 20px;
  min-height: 40px;
  background: #eef1f5; border-bottom: 1px solid var(--border-strong);
}
.alm-bar { background: #fff; padding: 6px 12px 8px; border-bottom: 1px solid var(--border-light); position: relative; }
.alm-row { display: flex; align-items: center; gap: 10px; min-height: 34px; }
.alm-glide { flex: 1; }
.alm-menu-item {
  display: inline-flex; align-items: center; gap: 5px; font-size: 13px; color: var(--text);
  cursor: pointer; padding: 4px 8px; border-radius: 4px; white-space: nowrap; user-select: none;
}
/* 导出下拉菜单（#alm-export 下方，锚 .alm-bar）：display 切换零过渡（铁律） */
.alm-export-menu {
  position: absolute; z-index: 46; min-width: 110px; padding: 4px 0;
  background: #fff; border: 1px solid var(--border); border-radius: 4px;
  box-shadow: 0 6px 16px rgba(0,0,0,.12);
}
.alm-export-menu .alm-menu-item { display: block; padding: 6px 16px; border-radius: 0; font-size: 12px; }
/* 未勾选任何行 → 「导出已选」不可选（灰字 + 禁止图标）；要压过 .alm-menu-item:hover 的蓝色 */
.alm-export-menu .alm-menu-item.is-disabled,
.alm-export-menu .alm-menu-item.is-disabled:hover { color: #b9bec7; background: transparent; cursor: not-allowed; }
/* 导出设置弹窗（居中 modal 复用 .modal 外壳）：两行单选 */
.exp-row { display: flex; align-items: center; gap: 18px; padding: 9px 2px; font-size: 13px; color: #000; }
.exp-lbl { width: 64px; flex: none; color: #000; }
.exp-opt { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; white-space: nowrap; }
.exp-opt input { margin: 0; accent-color: var(--accent); cursor: pointer; }
/* 未勾选行时的「导出已选」：与下拉菜单同口径（灰字 + 禁止图标，点不动） */
.exp-opt.is-disabled { color: #b9bec7; cursor: not-allowed; }
.exp-opt.is-disabled input { cursor: not-allowed; accent-color: #b9bec7; }

/* ============ 选择告警源弹窗（过滤面板「网元」触发器，2026-09-21） ============ */
/* 触发器已选了网元 → 文字转主题蓝，提示过滤条件生效中 */
.alm-filter-body .ff-combo.has-sel { color: var(--accent); }
.np-wrap { display: flex; gap: 14px; height: 520px; font-size: 12px; }
.np-pane { display: flex; flex-direction: column; min-width: 0; }
.np-left { flex: 1.5; }
.np-right { flex: 1; border-left: 1px solid var(--border-light); padding-left: 14px; }
.np-pane-hd { font-size: 13px; color: #000; padding-bottom: 8px; }
.np-left-main { display: flex; flex: 1; min-height: 0; gap: 10px; }
/* 左侧树 */
.np-tree { width: 128px; flex: none; border-right: 1px solid var(--border-light); overflow-y: auto; padding-right: 6px; }
.np-tree-item { display: flex; align-items: center; gap: 5px; padding: 5px 6px; color: #000; cursor: pointer; white-space: nowrap; }
.np-tree-item span { overflow: hidden; text-overflow: ellipsis; }
.np-tree-item:hover { background: var(--hover); }
.np-tree-item.active { color: var(--accent); background: #eaf1fd; }
.np-tree-item.sub { padding-left: 26px; }
.np-twist { display: inline-flex; color: #6b7280; transition: none; }
.np-twist.open { transform: rotate(90deg); }
/* 搜索行（左右两栏同构：搜索框 + 右侧动作图标） */
.np-search-row { display: flex; align-items: center; gap: 8px; padding-bottom: 8px; }
.np-search-box { flex: 1; display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--border-strong); border-radius: 2px; height: 28px; padding: 0 8px; color: #6b7280; background: #fff; }
.np-search-box input { flex: 1; min-width: 0; border: none; outline: none; background: transparent; font-size: 12px; color: #000; }
/* 搜索框内「清除 ×」：仅在有输入内容时出现（[hidden] 必须显式压掉 display:inline-flex，否则类规则胜出） */
.np-search-clear { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 15px; height: 15px; cursor: pointer; color: #9aa1ab; }
.np-search-clear[hidden] { display: none; }
.np-search-clear:hover { color: #5a6270; }
.np-add-all, .np-ico { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; cursor: pointer; color: #6b7280; flex: none; }
.np-add-all:hover, .np-ico:hover { color: var(--accent); }
/* 表格（左右两栏同构） */
.np-tbl { flex: 1; min-height: 0; overflow-y: auto; border: 1px solid var(--border-light); }
.np-tbl table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.np-tbl th, .np-tbl td { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--border-light); color: #000; font-weight: normal; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.np-tbl th { background: #f5f6f8; color: #000; position: sticky; top: 0; }
.np-tbl tbody tr:hover { background: #f7f9fd; }
.np-tbl .np-chk { width: 34px; text-align: center; }
.np-tbl .np-chk input { vertical-align: middle; accent-color: var(--accent); }
.np-tbl .np-name { display: flex; align-items: center; gap: 5px; color: #000; }
.np-tbl .np-name svg { flex: none; color: #2b8a3e; }
.np-tbl .np-op { width: 56px; text-align: center; }
/* 已选择行「操作」列：2026-09-21 由 ✕ 图标改为文字「删除」（用户要求） */
.np-del { display: inline-block; cursor: pointer; color: var(--accent); }
.np-del:hover { text-decoration: underline; }
.np-empty { text-align: center; color: #9aa1ab; padding: 28px 0 !important; }
/* 分页 */
.np-pager { display: flex; align-items: center; justify-content: space-between; padding-top: 8px; color: #000; }
.np-pages { display: inline-flex; align-items: center; gap: 4px; }
.np-pg { display: inline-flex; align-items: center; justify-content: center; min-width: 22px; height: 22px; padding: 0 4px; cursor: pointer; color: var(--accent); border: 1px solid transparent; }
.np-pg:hover { text-decoration: underline; }
.np-pg.cur { background: var(--accent); color: #fff; cursor: default; }
.np-pg.dis { color: #b9bec7; cursor: default; }
.alm-menu-item:hover { background: var(--hover); color: var(--accent); }
.alm-ico-btn {
  display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px;
  border-radius: 4px; cursor: pointer; color: #9aa1ab;
}
.alm-ico-btn:hover { background: var(--hover); color: var(--accent); }
.alm-ico-btn.alm-muted { color: #c62f31; }         /* 静音：铃铛变红提示已关声 */
/* 右上角四个级别徽章：红=紧急 橙=重要 黄=次要 蓝=提示，数字=总数（纯展示，无点击） */
/* 2026-09-16 按截图重做：直角；本色块外 3px 白边，白边外再包 3px 本色边（border=白 + outline=本色） */
.alm-chips { display: inline-flex; gap: 10px; align-items: center; }
.alm-chip {
  min-width: 46px; text-align: center; color: #000; font-size: 12px; line-height: 16px;
  padding: 1px 10px; border-radius: 0; user-select: none;
  border: 3px solid #fff;            /* 本色块外的 3px 白边 */
  outline: 3px solid transparent;    /* 白边外再包 3px 本色边（各色类里给 outline-color） */
}
.chip-critical { background: #e84749; outline-color: #e84749; }
.chip-major    { background: #f2803c; outline-color: #f2803c; }
.chip-minor    { background: #f5a623; outline-color: #f5a623; }
.chip-warning  { background: #4d9bfc; outline-color: #4d9bfc; }
/* ============ 模板管理贴边面板（2026-09-18，复刻真实网管） ============
   位置硬规格由 JS（almTplShow）打开时实测（二修）：top 贴 alm-floatbar 视觉底 / right 到「告警ID」列右边界，
   left=0、bottom=0 顶到【屏幕】边 → position:fixed 相对视口。
   面板 z-index 45、遮罩 44：盖过表格与 sticky 表头(1)、floatbar(6)，低于 toast(90)/modal(2000)。 */
.alm-tpl-panel {
  position: fixed; z-index: 45; display: flex; flex-direction: column;
  background: #fff;
  border-right: 1px solid var(--border-strong);
  box-shadow: 4px 4px 12px rgba(0,0,0,.07);
  overflow: hidden;   /* 滑动条下沉到 .alm-tpl-list（用户 2026-09-18）：tab/搜索框固定不滚 */
}
/* ===== 开关逻辑：与「居中弹窗」完全同口径（2026-09-18 四修，用户反馈连续点击仍卡）=====
   实测 tools/_probe_alm_jank.js（量「点下 → 完全成形」的视觉响应延迟；页面确已布局：468 行 / 2 万节点）：
     居中弹窗      1.1ms   ← 用户认可的「丝滑」基准
     模板管理面板  105.3ms
     过滤面板      102.5ms
   差 100 倍，根因就是下面那条 0.1s 过渡：人手连点约 125ms/次，面板要 103ms 才成形 →
   每次点击都停在「半透明中途」，永远看不到它成形 = 体感的「卡」。
   （同时段掉帧率为 0、连点 8 次最长帧仅 20.8ms → 「卡」不是掉帧，是**响应延迟**。）
   弹窗为什么丝滑：#modal-root 关闭时是空的（不渲染），打开瞬现，**零过渡**。故此处回到同一口径：
     ① 关闭 = display:none（不渲染、不留层、不进合成器，等同弹窗清空 DOM）；
     ② 打开 = 瞬现，零过渡。
   注：箭头翻转一直是即时的（.alm-menu-item.active svg，用户明确要求不要延迟），本次不受影响。
   中间试过的 visibility 常驻层 + 合成器动画（三修）已撤：那条 0.1s 过渡才是"卡"的真凶。 */
.alm-tpl-panel[hidden] { display: none; }
.alm-filter-panel[hidden] { display: none; }
.alm-tpl-mask[hidden], .alm-filter-mask[hidden] { display: none; }
/* 透明遮罩：盖住 alm-tbl-box 区域直到屏幕底（top 由 JS 实测），点击即关闭面板；
   [hidden] 规则见上方「开关性能」段（visibility 常驻层，不用 display:none） */
.alm-tpl-mask { position: fixed; left: 0; right: 0; bottom: 0; z-index: 44; background: rgba(0,0,0,.25); }
/* 菜单选中态：面板打开时「模板管理」蓝底白字 + 尾部箭头翻转 180°（用户 2026-09-18 定） */
.alm-menu-item.active, .alm-menu-item.active:hover { background: var(--accent); color: #fff; }
.alm-menu-item.active svg { transform: rotate(180deg); }   /* 箭头即时翻转（用户 2026-09-18：不要过渡延迟） */
.alm-tpl-tabs { display: flex; border-bottom: 1px solid var(--border-light); flex: none; background: #fff; }
.alm-tpl-tab {
  position: relative; padding: 0 14px; height: 38px; line-height: 38px;
  font-size: 13px; color: var(--text); cursor: pointer; user-select: none;
}
.alm-tpl-tab:hover { color: var(--accent); }
.alm-tpl-tab.on { color: var(--accent); }
.alm-tpl-tab.on::after { content: ''; position: absolute; left: 10px; right: 10px; bottom: 0; height: 2px; background: var(--accent); }
.alm-tpl-search { position: relative; margin: 12px; flex: none; }
.alm-tpl-search input {
  width: 100%; height: 30px; box-sizing: border-box;
  border: 1px solid var(--border-strong); border-radius: 4px;
  padding: 0 30px 0 10px; font-size: 12px; outline: none; color: var(--text);
}
.alm-tpl-search input::placeholder { color: #aab0ba; }
.alm-tpl-search input:focus { border-color: var(--accent); }
.alm-tpl-search svg { position: absolute; right: 9px; top: 50%; transform: translateY(-50%); color: #9aa1ab; pointer-events: none; }
/* 列表区 = 唯一滚动容器（用户 2026-09-18）：面板定高，tab + 搜索框 flex:none 固定，
   列表 flex:1 + min-height:0 撑满剩余高度并自己出纵向滑动条 */
.alm-tpl-list { flex: 1 1 auto; min-height: 0; overflow: hidden auto; }
.alm-tpl-item {
  display: flex; align-items: center; gap: 8px; height: 40px; padding: 0 12px;
  font-size: 13px; color: var(--text); cursor: pointer;
}
.alm-tpl-item:hover { background: var(--hover); }
.alm-tpl-cnt { background: var(--accent); color: #fff; font-size: 11px; line-height: 16px; padding: 0 7px; border-radius: 8px; }
.alm-tpl-arrow { margin-left: auto; color: #b9bec7; display: inline-flex; }
/* 分组行展开子列表（2026-09-18 假数据，照真实网管截图）：分享图标 + 粗体模板名 + 灰色人名；
   hover：字体加粗 + 背景加深一点（用户定）；行头箭头 > 展开时旋转成 ∨（即时，无过渡）。
   2026-09-18 二修：所有分组行统一可展开（.open），数量为 0 的分组展开即空（不再 toast 提示） */
.alm-tpl-item.open .alm-tpl-arrow { transform: rotate(90deg); }
.alm-tpl-subitem {
  display: flex; align-items: center; gap: 7px; min-height: 32px; padding: 0 12px 0 14px;
  font-size: 13px; cursor: pointer; background: #fff;
}
.alm-tpl-subitem:hover { background: #eef1f5; }
.alm-tpl-share-ico { color: var(--accent); display: inline-flex; flex: none; }
.alm-tpl-name { font-weight: 600; color: var(--text); white-space: nowrap; }
.alm-tpl-user { color: #8a9099; font-weight: 400; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.alm-tpl-subitem:hover .alm-tpl-name { font-weight: 800; }
.alm-tpl-subitem:hover .alm-tpl-user { font-weight: 600; }
/* ============ 过滤贴边面板（2026-09-18，照真实网管截图；外壳与模板管理面板同规格） ============
   宽=屏幕宽（left/right=0）、top 由 JS 实测贴 alm-floatbar 底、maxHeight 到屏幕底（超高内部滚）；
   遮罩盖 alm-tbl-box 到屏幕底；#alm-filter-btn 选中态复用 .alm-menu-item.active（蓝底白字+箭头翻转）。
   表单 1:1 样式见下方「过滤表单 1:1」段（.ff-*，照截图逐行核对）。 */
.alm-filter-panel {
  position: fixed; left: 0; right: 0; z-index: 45;
  display: flex; flex-direction: column;
  background: #fff;
  border-bottom: 1px solid var(--border-strong);
  box-shadow: 0 6px 16px rgba(0,0,0,.10);
  overflow: hidden;   /* 内部滚动在 .alm-filter-body（滑动条不在面板上，与模板管理面板同理） */
}
/* [hidden] 规则见模板管理段「开关逻辑」：display:none，与弹窗关闭即清空同口径 */
.alm-filter-mask { position: fixed; left: 0; right: 0; bottom: 0; z-index: 44; background: rgba(0,0,0,.25); }
.alm-filter-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 14px 22px 6px; }
.alm-filter-foot { flex: none; display: flex; justify-content: flex-end; gap: 8px; padding: 10px 18px; border-top: 1px solid var(--border-light); background: #fafbfc; }

/* ---------- 过滤表单 1:1（2026-09-18 四修照截图，五修补回告警状态/清除时间两行） ----------
   标签列灰字右对齐带冒号（约 66px）；下拉触发器=灰字+小箭头（纯外观，点击无动作）；
   级别/告警状态胶囊白底直角边框、未选中文字黑 / 选中文字蓝（都不加粗）、选中右下角三角形（色=边框色）；
   告警状态共 4 个组合（已确认/未确认 × 已清除/未清除，见 js/alarms.js 的 STATUS_OPTS）；
   发生时间=☐从[灰]到[灰]+☑最近[− 3 +]+单选天/小时/分钟；清除时间=☐从[灰]到[灰]；
   告警源行尾深灰开关（白点在左=开）「同时满足多个条件」；备注默认灰禁用；
   footer=重置/保存/另存为(灰禁用)/确定(蓝)（截图无「取消」）。截图右侧圆形悬浮小部件不复刻（用户要求）。
   零 transition（本页既定规则）。 */
/* 文字色口径（用户 2026-09-18 定）：除左侧标题(.ff-lbl 灰)、选中态(.active 蓝)、不可选(disabled 灰)、
   占位符(浅灰，空态提示)外，面板内其余文字一律 #000 纯黑（含触发器、箭头、开关标签、步进器符号）。 */
.alm-filter-body .ff-row { display: flex; align-items: center; min-height: 34px; gap: 10px; }
.alm-filter-body .ff-lbl { flex: none; width: 66px; text-align: right; color: #7d8590; font-size: 12px; white-space: nowrap; }
.alm-filter-body .ff-ctl { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 18px; font-size: 12px; color: #000; min-width: 0; }
.alm-filter-body .ff-dim { color: #000; }
/* 下拉触发器（告警名称 / 告警源 / 定位信息各行）：灰字 + 小箭头，hover 变蓝（纯外观） */
.alm-filter-body .ff-combo { display: inline-flex; align-items: center; gap: 5px; color: #000; white-space: nowrap; cursor: default; }
.alm-filter-body .ff-combo svg { color: #000; flex: none; }
.alm-filter-body .ff-combo:hover, .alm-filter-body .ff-combo:hover svg { color: var(--accent); }
/* 「告警名称/告警名称组」2026-09-18 起也是纯外观触发器 → 所有 ff-combo 都无 input，
   原 .ff-combo input / ::placeholder 两条规则随之删除（勿按旧版加回）。 */
/* 级别 / 告警状态胶囊：白底直角边框，未选中文字黑、选中文字蓝（**都不加粗**，用户 2026-09-18 定）；
   选中态右下角三角形，颜色 = 边框色（var(--accent)），两者永远同色。
   2026-09-18 曾把角标改成 content:url(svg 对勾)、文字加粗 → 均被用户打回，别再改。 */
.alm-filter-body .chip-toggle.ff-chip {
  background: #fff; border: 1px solid #b9c2cc; color: #000; border-radius: 0;
  padding: 0 16px; height: 26px; line-height: 24px; font-size: 12px; position: relative;
}
.alm-filter-body .chip-toggle.ff-chip.active { border-color: var(--accent); color: var(--accent); }
.alm-filter-body .chip-toggle.ff-chip.active::after {
  content: ''; position: absolute; right: 0px; bottom: 0px;
  border: 5px solid transparent; border-right-color: var(--accent); border-bottom-color: var(--accent);
}
/* 发生时间日期框：灰禁用（勾「从」后启用变白）；右侧日历小图标 */
.alm-filter-body .ff-date-wrap { position: relative; display: inline-flex; }
.alm-filter-body .ff-date { width: 168px; height: 26px; border: 1px solid var(--border-light); background: #f2f3f5; border-radius: 2px; font-size: 12px; color: #000; padding: 0 24px 0 8px; outline: none; }
.alm-filter-body .ff-date:disabled { color: #b9bec7; }
.alm-filter-body .ff-date:not(:disabled) { background: #fff; border-color: var(--border-strong); }
.alm-filter-body .ff-date-wrap svg { position: absolute; right: 7px; top: 50%; transform: translateY(-50%); color: #c1c6cd; pointer-events: none; }
/* 时间区间框（用户 2026-10-09：两个时间框「外部样式改成同一个框里」，即 [开始时间 ~ 结束时间 📅]）：
   外壳一个框 = .ff-date-range（挂 .ff-date-wrap 借它的 position:relative 给日历图标定位），
   内部两个 .ff-date 去边框去底色、只留文字，中间「~」，右缘一个日历图标。
   灰/白两态由 JS 切 .is-on（**不用 :has()**：老浏览器不认时框体会一直灰着，跟输入框解禁不同步）。 */
.alm-filter-body .ff-date-range {
  display: inline-flex; align-items: center; gap: 4px;
  height: 26px; box-sizing: border-box; padding: 0 24px 0 8px;
  background: #f2f3f5; border: 1px solid var(--border-light); border-radius: 2px;
}
.alm-filter-body .ff-date-range.is-on { background: #fff; border-color: var(--border-strong); }
.alm-filter-body .ff-date-range .ff-date,
.alm-filter-body .ff-date-range .ff-date:not(:disabled) {
  width: 140px; height: 24px; padding: 0; border: 0; background: transparent; border-radius: 0;
}
.alm-filter-body .ff-date-range .ff-date:disabled { background: transparent; }
/* 最近 [− 3 +] 步进器 */
.alm-filter-body .ff-step { display: inline-flex; align-items: stretch; height: 26px; border: 1px solid var(--border-strong); border-radius: 2px; overflow: hidden; }
.alm-filter-body .ff-step button { width: 26px; border: none; background: #fff; color: #000; font-size: 14px; cursor: pointer; padding: 0; }
.alm-filter-body .ff-step button:hover { color: var(--accent); }
.alm-filter-body .ff-step input { width: 46px; border: none; border-left: 1px solid var(--border-light); border-right: 1px solid var(--border-light); text-align: center; font-size: 12px; outline: none; color: #000; }
/* 勾选 / 单选 / 开关 */
.alm-filter-body .ff-chk { display: inline-flex; align-items: center; gap: 5px; color: #000; cursor: pointer; white-space: nowrap; }
.alm-filter-body .ff-chk input { accent-color: var(--accent); margin: 0; }
.alm-filter-body .ff-switch { width: 34px; height: 18px; border-radius: 9px; background: #676c73; position: relative; cursor: pointer; flex: none; }
.alm-filter-body .ff-switch .ff-knob { position: absolute; left: 2px; top: 2px; width: 14px; height: 14px; border-radius: 50%; background: #fff; }
.alm-filter-body .ff-switch:not(.on) { background: #c9ced6; }
.alm-filter-body .ff-switch:not(.on) .ff-knob { left: auto; right: 2px; }
.alm-filter-body .ff-switch-lbl { color: #000; }
/* 高级设置 / 备注的下拉与输入 */
.alm-filter-body .ff-sel, .alm-filter-body .ff-txt { height: 26px; border: 1px solid var(--border-strong); border-radius: 2px; font-size: 12px; color: #000; padding: 0 6px; background: #fff; outline: none; }
.alm-filter-body .ff-txt { width: 220px; padding: 0 8px; }
.alm-filter-body .ff-sel:disabled, .alm-filter-body .ff-txt:disabled { background: #f2f3f5; border-color: var(--border-light); color: #b9bec7; }
.alm-filter-body .ff-more { color: #000; cursor: pointer; white-space: nowrap; }
.alm-filter-body .ff-more:hover { color: var(--accent); }
/* footer：另存为=灰禁用（照截图，无「取消」按钮） */
.alm-filter-foot .btn.is-disabled { background: #ccd1d8; border-color: #ccd1d8; color: #fff; cursor: not-allowed; }
/* ============ 日期时间选择器（2026-09-18，配合 .ff-date；DOM 挂在 body 上，见 js/alarms.js 的 cal* 段） ============
   为什么 fixed + 挂 body：过滤面板是 overflow:hidden、内部 .alm-filter-body 是 overflow-y:auto，
   挂在 .ff-date-wrap 里会被裁掉。位置由 calPosition() 实测输入框 rect 决定（右侧放不下贴右、下方放不下上翻）。
   零 transition（本页既定规则，用户已两次打回过渡动画）：显隐只切 [hidden]。
   选中日=蓝底白字；今天=蓝字；上/下月=灰字。z-index 60 高于过滤面板(45)/遮罩(44)、低于模态弹窗。 */
.alm-cal {
  position: fixed; z-index: 60; width: 268px;
  background: #fff; border: 1px solid var(--border-strong);
  box-shadow: 0 6px 18px rgba(0,0,0,.14);
  font-size: 12px; color: var(--text); user-select: none;
}
.alm-cal[hidden] { display: none; }
.alm-cal-head { display: flex; align-items: center; gap: 4px; padding: 8px 8px 6px; }
.alm-cal-nav { width: 20px; height: 22px; flex: none; border: none; background: transparent; color: #6b7280; font-size: 14px; line-height: 1; cursor: pointer; padding: 0; }
.alm-cal-nav:hover { color: var(--accent); }
.alm-cal-head select { height: 22px; border: 1px solid var(--border-light); border-radius: 2px; background: #fff; color: var(--text); font-size: 12px; outline: none; padding: 0 2px; }
.alm-cal-head #alm-cal-year { flex: 1 1 auto; min-width: 0; }
.alm-cal-head #alm-cal-month { flex: none; width: 64px; }
.alm-cal-week { display: grid; grid-template-columns: repeat(7, 1fr); padding: 0 8px; color: #8a9099; text-align: center; }
.alm-cal-week span { height: 20px; line-height: 20px; }
.alm-cal-days { display: grid; grid-template-columns: repeat(7, 1fr); padding: 0 8px 6px; }
.alm-cal-day { height: 24px; line-height: 24px; text-align: center; cursor: pointer; border-radius: 2px; }
.alm-cal-day.other { color: #b9bec7; }
.alm-cal-day.today { color: var(--accent); }
.alm-cal-day.on { background: var(--accent); color: #fff; }
.alm-cal-day:not(.on):not(.dis):hover { background: var(--accent-soft); }
/* 界外日子（今天之后 / 起止互限挡住的）：置灰 + 点不动（2026-10-15 报表创建页第 3 步） */
.alm-cal-day.dis { color: #c9cdd4; cursor: not-allowed; background: transparent; }
/* 区间模式（2026-10-09，见 js/alarms.js 的 calOpenRange）：只选日期，像订酒店那样点两下选一个区间。
   两端蓝底白字、中间浅蓝底；hover 不能把两端冲淡（同特异性、后写覆盖） */
.alm-cal-day.rg-start, .alm-cal-day.rg-end { background: var(--accent); color: #fff; }
.alm-cal-day.rg-mid { background: var(--accent-soft); }
.alm-cal-day.rg-start:hover, .alm-cal-day.rg-end:hover { background: var(--accent); color: #fff; }
.alm-cal-time { display: flex; align-items: center; gap: 4px; padding: 6px 8px; border-top: 1px solid var(--border-light); }
.alm-cal-tlbl, .alm-cal-colon { flex: none; color: #7d8590; }
.alm-cal-spin { display: inline-flex; align-items: stretch; height: 22px; border: 1px solid var(--border-strong); border-radius: 2px; overflow: hidden; }
.alm-cal-spin button { width: 18px; flex: none; border: none; background: #fff; color: #6b7280; font-size: 12px; cursor: pointer; padding: 0; }
.alm-cal-spin button:hover { color: var(--accent); }
.alm-cal-spin input {
  width: 28px; flex: none; border: none; outline: none; padding: 0; text-align: center;
  border-left: 1px solid var(--border-light); border-right: 1px solid var(--border-light);
  font-size: 12px; color: var(--text); user-select: text;
}
.alm-cal-foot { display: flex; align-items: center; gap: 6px; padding: 6px 8px 8px; border-top: 1px solid var(--border-light); background: #fafbfc; }
.alm-cal-link { border: none; background: transparent; color: var(--accent); font-size: 12px; cursor: pointer; padding: 0 2px; }
.alm-cal-link:hover { text-decoration: underline; }
.alm-cal-sp { flex: 1 1 auto; }
.alm-cal-foot .btn { padding: 3px 12px; font-size: 12px; border-radius: 2px; }
/* 区间模式：隐藏时间行与「此刻」「今天」（区间只到日期粒度，也没有「今天一天」的快捷需求），
   footer 左侧换成一行动的提示 —— 腾出的宽度刚好放下完整提示，不会把 取消/确定 挤到第二行 */
.alm-cal.alm-cal-range .alm-cal-time, .alm-cal.alm-cal-range #alm-cal-now, .alm-cal.alm-cal-range #alm-cal-today { display: none; }
/* 只到日期的单选（报表创建页第 3 步）：收起时间行与「此刻」，「今天」保留 */
.alm-cal.alm-cal-dayonly .alm-cal-time, .alm-cal.alm-cal-dayonly #alm-cal-now { display: none; }
.alm-cal-hint { display: none; color: #7d8590; }
/* 提示不换行（footer 只有 268px 宽，换行会把 取消/确定 挤到第二行，见 2026-10-09 首版截图） */
.alm-cal.alm-cal-range .alm-cal-hint { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
/* 区间模式「一天都没选」时「确定」置灰（单选模式永远不置灰，视觉零变化） */
.alm-cal-foot .btn:disabled, .alm-cal-foot .btn.is-disabled { background: #f5f6f8; border-color: #e0e3e8; color: #b9bec7; cursor: not-allowed; }
/* ---------- 第二行按钮 ---------- */
.alm-switch { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; user-select: none; }
.alm-switch-track { width: 34px; height: 16px; border-radius: 8px; background: #c9ced6; position: relative; transition: background .15s; flex: none; }
.alm-switch-track::after { content: ''; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 50%; background: #fff; transition: left .15s; }
.alm-switch-track.on { background: #2fbf6b; }
.alm-switch-track.on::after { left: 20px; }
.alm-btn {
  height: 28px; padding: 0 14px; background: #fff; border: 1px solid var(--border-strong);
  border-radius: 4px; font-size: 13px; cursor: pointer; color: var(--text); white-space: nowrap;
}
.alm-btn:hover { border-color: var(--accent); color: var(--accent); }
.alm-btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.alm-btn-primary:hover { background: var(--accent-hover); color: #fff; }
/* ---------- 列表：横竖滚动条 + 左侧吸附列 ---------- */
.alm-tbl-wrap { overflow: auto; max-height: calc(100vh - 250px); background: #fff; border-bottom: 1px solid var(--border-light); }
/* table-layout:fixed：列宽完全由 colgroup 驱动 → 拖表头手柄改 col 宽度即时生效、不被长内容撑开 */
.alm-tbl { border-collapse: separate; border-spacing: 0; font-size: 12.5px; table-layout: fixed; }
.alm-tbl th {
  position: sticky; top: 0; z-index: 3; background: #f7f8fa; text-align: left; font-weight: normal;
  padding: 7px 10px; white-space: nowrap; border-bottom: 1px solid #e3e6ea; border-right: 1px solid #f0f1f3;
  color: var(--text); user-select: none;
}
.alm-th-chk { cursor: default; }
.alm-th:hover { color: var(--accent); }
/* 排序只认图标：指针样式跟到图标上（th 本体不再触发排序） */
.alm-sort-ico { margin-left: 4px; vertical-align: -1px; cursor: pointer; }
.alm-sort-ico path { fill: #b9bfc7; }
.alm-sort-ico .up { opacity: .9; }
th[data-dir="asc"]  .alm-sort-ico .up   { fill: var(--accent); }
th[data-dir="desc"] .alm-sort-ico .down { fill: var(--accent); }
/* 数据格之间 1px 黑色实线隔开；上下 padding 去掉，只留左右 10px（2026-09-16 用户要求） */
.alm-tbl td {
  padding: 0 10px; border-bottom: 1px solid #000; border-right: 1px solid #000;
  white-space: nowrap; color: var(--text); overflow: hidden; text-overflow: ellipsis;
}
/* 空态/错误提示浮层：表格显式总宽（约 2900px）远超视口，colspan 行的 text-align:center
   会把提示居中到「整表中点」（视口外，看起来一片空白）→ 改锚在 .alm-tbl-box 上相对可视区居中 */
.alm-tbl-box { position: relative; }
.alm-tbl-box.is-empty .alm-tbl-wrap { min-height: 180px; }   /* 空态时列表区保持一块可视高度，提示才有「居中在列表里」的观感 */
.alm-tbl-box .alm-empty {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--text-faint); font-size: 12.5px; pointer-events: none;
}
.alm-tbl-box .alm-empty[hidden] { display: none; }
.alm-tbl tbody tr:hover td { background: var(--hover); }
/* 表头右缘的列宽拖拽手柄（th 是 sticky=定位元素，absolute 就锚在 th 上）。
   类名必须与 js/alarms.js 一致：.alm-col-resizer
   （曾误写成 .alm-e-resizer，手柄没了手型和定位，拖拽直接失效，_test_alarms_ui 会红）
   cursor：2026-09-22 按用户要求由 col-resize 改为 e-resize（纯左右箭头，
   不再是带竖线的列表分隔光标），与拖拽中的 body.alm-col-dragging 手型保持一致 */
.alm-col-resizer {
  position: absolute; top: 0; right: -4px; width: 9px; height: 100%;
  cursor: e-resize; z-index: 6;
}
body.alm-col-dragging { cursor: e-resize; user-select: none; }
/* 复选框/操作两列吸附（th 的 z-index 要盖过 td 与普通 th）；操作列的 left 跟随第 0 列宽度 */
.alm-tbl th.alm-sticky-1, .alm-tbl td.alm-sticky-1 { position: sticky; left: 0; z-index: 4; background: #fff; }
.alm-tbl th.alm-sticky-2, .alm-tbl td.alm-sticky-2 { position: sticky; left: var(--alm-sticky2-left, 34px); z-index: 4; background: #fff; box-shadow: 3px 0 5px rgba(0,0,0,.06); }
.alm-tbl th.alm-sticky-1, .alm-tbl th.alm-sticky-2 { z-index: 5; background: #f7f8fa; }
.alm-tbl td.alm-sticky-1, .alm-tbl td.alm-sticky-2 { background: #fff; }
.alm-tbl tbody tr:hover td.alm-sticky-1, .alm-tbl tbody tr:hover td.alm-sticky-2 { background: var(--hover); }
.alm-dim { color: var(--text-dim, var(--text-faint)); }
/* 表格下方左侧的「共 XXX 行」计数（2026-09-16 用户要求） */
.alm-total { padding: 6px 12px; font-size: 12px; color: #000; background: #fff; }
/* 行内操作小图标 */
.alm-tbl .col-op { display: flex; gap: 2px; align-items: center; }
.alm-op {
  display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px;
  border-radius: 3px; cursor: pointer; color: #9aa1ab;
}
.alm-op:hover { color: var(--accent); background: var(--hover); }
.alm-tbl .alarm-link { color: var(--accent); text-decoration: none; display: inline-flex; align-items: center; gap: 4px; }
.alm-tbl .alarm-link:hover { text-decoration: underline; }
/* 级别徽章（scoped 到本表，不影响拓扑/详情里的 sevCell） */
/* 级别列：色块撑满父级 td，仅上下留 1px、左右留 3px 白边（2026-09-16 按截图改） */
/* 用 td 相对定位 + 子块 absolute inset 拉伸：无论行高多少，色块都撑满父级框 */
.alm-tbl td.alm-sev { padding: 1px 3px; position: relative; }
/* ⚠️ 这里不能写 background 兜底：本条特异性 (0,3,1) 高于配色规则的 (0,3,0)，
   一旦写了 background（哪怕 transparent）会把四色全盖掉（2026-09-16 踩过） */
.alm-tbl td.alm-sev .sev-cell {
  position: absolute; inset: 1px 3px; display: flex; align-items: center; justify-content: center;
  color: #000; font-size: 12px; line-height: 1; border-radius: 0;
}
.alm-tbl .sev-cell.critical { background: #e84749; }
.alm-tbl .sev-cell.major    { background: #f2803c; }
.alm-tbl .sev-cell.minor    { background: #f5a623; }
.alm-tbl .sev-cell.warning  { background: #4d9bfc; }
/* ---------- 全屏加载遮罩（刚打开时） ---------- */
.alm-loading {
  position: fixed; inset: 0; z-index: 999; background: rgba(255, 255, 255, .55);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
}
.alm-loading.alm-done { display: none; }
.alm-spinner { width: 72px; height: 72px; }
.alm-spinner svg { display: block; animation: alm-rotate .9s linear infinite; }
@keyframes alm-rotate { to { transform: rotate(360deg); } }
.alm-loading-text { font-size: 13px; color: var(--text); }

/* ================= 集中任务管理（taskmgr.js） ================= */
/* 任务树图：组（可折叠）+ 叶子（任务类型） */
.tm-group { margin-bottom: 2px; }
.tm-group-head {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 8px; font-size: 13px; font-weight: 500;
  color: var(--text-dim); cursor: pointer; user-select: none;
}
.tm-group-head:hover { color: var(--accent); }
.tm-caret { font-size: 10px; color: var(--text-faint); width: 12px; }
.tm-leaf {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 8px 4px 26px; font-size: 12.5px;
  color: var(--text-dim); cursor: pointer; user-select: none; white-space: nowrap;
}
.tm-leaf svg { flex: none; color: var(--accent); opacity: .75; }
.tm-leaf span { overflow: hidden; text-overflow: ellipsis; }
.tm-leaf:hover { background: var(--hover); color: var(--accent); }
.tm-leaf.active { background: var(--accent-soft); color: var(--accent); font-weight: 500; }

/* 过滤下拉（挂在工具条上，显隐只切 hidden） */
.tm-filter-panel {
  position: absolute; top: 100%; left: 0; z-index: 20;
  min-width: 130px; margin-top: 4px; padding: 4px 0;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 4px; box-shadow: 0 4px 14px rgba(31,35,41,.12);
}
.tm-filter-item { padding: 6px 14px; font-size: 12.5px; color: var(--text-dim); cursor: pointer; }
.tm-filter-item:hover { background: var(--hover); color: var(--accent); }
.tm-filter-item.active { color: var(--accent); font-weight: 500; background: var(--accent-soft); }

/* 底部脚条：总计 + 分页（每页条数为自定义上拉面板，bottom:100% 向上弹出） */
.tm-foot { display: flex; align-items: center; gap: 8px; padding: 10px; }
/* 分页「上一页/下一页」的 SVG 箭头：只做基线对齐，不用 display:block
   —— 保留 .btn 自身的 line-height，按钮高度/宽度与原来用 ‹ › 字符时一致 */
.tm-page-ico { vertical-align: middle; }
.tm-ps-wrap { position: relative; }
.tm-ps-panel {
  position: absolute; bottom: 100%; left: 0; z-index: 30;
  min-width: 104px; margin-bottom: 4px; padding: 4px 0;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 4px; box-shadow: 0 4px 14px rgba(31,35,41,.12);
}
.tm-ps-panel[hidden] { display: none; }

/* 创建/详情弹窗行 */
.tm-form-row { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.tm-form-row label { flex: none; width: 64px; font-size: 12.5px; color: var(--text-dim); text-align: right; }
.tm-form-row select, .tm-form-row input[type=text] {
  height: 30px; padding: 0 8px; border: 1px solid var(--border); border-radius: 4px; font-size: 12.5px;
}
.tm-form-row select:focus, .tm-form-row input[type=text]:focus { border-color: var(--accent); outline: none; }

/* 任务状态徽标（完成/失败复用既有 badge-status-cleared / badge-status-unconfirmed） */
.badge-status-running   { background: var(--warning-bg); color: var(--status-running); }
.badge-status-suspended { background: var(--gray-soft); color: var(--text-faint); }

/* ============ 集中任务管理：表格滚动框 + 排序图标 + 行内操作图标（2026-09-21 二轮） ============ */
/* 横竖都要滑动条：wrap 双向 overflow；表格给定最小宽（否则窄屏下会被压扁、出不来横向条） */
.tm-tbl-wrap { overflow: auto; max-height: calc(100vh - 290px); background: #fff; }
/* 集中任务管理列表视图：左右两栏高度撑满 main-content 内容区（main 的 padding 不计入）。
   靠 .two-col 交叉轴 stretch + 各栏 flex column 传递，表格/树各自在自己框内滚动，
   不再用 72vh / calc(100vh-290px) 这类写死高度（2026-09-22 用户要求） */
.tm-list-view { height: 100%; min-height: 0; }
.tm-list-view > .two-col { height: 100%; min-height: 0; align-items: stretch; }
.tm-list-view .left-pane, .tm-list-view .right-pane { display: flex; flex-direction: column; min-height: 0; }
.tm-list-view .pane-card { flex: 1; max-height: none; min-height: 0; }
.tm-list-view .right-pane > .panel { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.tm-list-view .tm-tbl-wrap { flex: 1; max-height: none; min-height: 0; }
/* 2026-10-16：刷新遮罩（.tbl-loading-mask）的定位父级 —— 挂面板（不是 .tm-tbl-wrap，
   它自己是滚动容器，遮罩会跟着内容滚走） */
.tm-tbl-panel { position: relative; }
/* ---- 2026-10-16：操作日志「滚动条在 .log-tbl-panel 自己身上」——不再把 main 撑高滚动 ----
   口径同信令跟踪 .tt-view 占满 .main：page-host(#ph-logs) 已是 height:100%，这里把它变纵向 flex，
   副标题/工具条定高、剩下的全给 .log-tbl-box → 里面的滚动区才有确定高度（overflow:auto 才成立）。
   ★ **不要**把 #log-foot 塞进滚动区再指望 sticky 吸底：实测 sticky bottom:0 在这里不吸附
     （会跟着内容滚到 3486px 外），所以照列表页既有口径做成**兄弟**——
     滚动区 .log-tbl-panel + 底条 .rp-list-foot，底条天然不滚，不必依赖 sticky。
   ★ 遮罩(.tbl-loading-mask)的定位父级是外层 .log-tbl-box：挂滚动容器上会跟着内容一起滚。 */
#ph-logs { display: flex; flex-direction: column; min-height: 0; }
#ph-logs > .page-sub, #ph-logs > .toolbar { flex: none; }
/* ★ .log-tbl-box 带 .panel 类只为复用「白底+边框+圆角」卡片外观，其自带 padding:14px 16px / margin-bottom:14px
     要 override 掉，否则滚动区和底条整体缩进一圈；左右留白改由滚动区自己的 padding:8px 10px 提供 */
/* ★ 顶部留白放在**外层 box** 而不是滚动区：滚动区必须 padding-top:0，
     否则 sticky 表头停在 content box 顶部（比 scrollport 顶低 8px），那 8px 缝隙里会漏出滚动的日志行。
     既有滚动区（.tm-tbl-wrap / .bk-file-wrap / .tt-wrap / .rp-list-wrap）同理都是零 padding-top。 */
#ph-logs > .log-tbl-box { flex: 1; min-height: 0; position: relative; display: flex; flex-direction: column; overflow: hidden; padding: 8px 0 0; margin: 0; }
.log-tbl-panel { flex: 1; min-height: 0; overflow: auto; padding: 0 10px 8px; }
/* 2026-10-16：日志滚动时**表头吸顶不跟着滑**（用户口径「表头不要动」= 不要跟着滚动动）。
   写法照既有 sticky 表头口径（.tm-tbl / .bk-file-wrap / .tt-wrap / .rp-res-tbl …）：
   ★ top:0 + z-index 必须有；background 必须显式（.tbl th 自带 #fafbfc 会漏出下方内容）；
   ★ 别再给 log-tbl-panel thead th 写 position: relative —— 会把 sticky 覆盖掉（见 .tm-tbl 处的同款警告）。 */
.log-tbl-panel thead th { position: sticky; top: 0; z-index: 3; background: #fafbfc; }
.log-tbl-box .rp-list-foot { flex: none; margin: 0; padding: 6px 11px; }
.tm-tbl { min-width: 1120px; }
.tm-tbl thead th { position: sticky; top: 0; z-index: 3; background: #f7f8fa; }
.tm-tbl tbody td { padding: 7px 10px; text-overflow: ellipsis; overflow: hidden;}

/* 表头排序图标（同「当前告警」alm-sort-ico 观感） */
.tm-sort-ico { margin-left: 4px; vertical-align: -1px; cursor: pointer; }
.tm-sort-ico path { fill: #b9bfc7; }
.tm-sort-ico .up { opacity: .9; }
th[data-dir="asc"]  .tm-sort-ico .up   { fill: var(--accent); }
th[data-dir="desc"] .tm-sort-ico .down { fill: var(--accent); }

/* 行内操作：播放 / 停止 / 暂停 / 更多 */
.tm-ops { display: inline-flex; align-items: center; gap: 10px; }
.tm-ico { display: inline-flex; align-items: center; color: var(--accent); cursor: pointer; }
.tm-ico:hover { color: var(--accent-hover); }
.tm-ico-disabled { color: #c8ccd2; cursor: default; pointer-events: none; }

/* 更多菜单（挂起/恢复、删除、复制） */
.tm-more-menu {
  position: fixed; z-index: 30; min-width: 104px; padding: 4px 0;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 4px; box-shadow: 0 4px 14px rgba(31,35,41,.14);
}
.tm-more-menu[hidden] { display: none; }
.tm-more-item { padding: 6px 14px; font-size: 12.5px; color: var(--text-dim); cursor: pointer; white-space: nowrap; }
.tm-more-item:hover { background: var(--hover); color: var(--accent); }
.tm-more-item.disabled { color: var(--text-faint); cursor: default; pointer-events: none; }

/* 任务状态徽标：未执行 / 已停止 */
.badge-status-idle    { background: var(--panel-3); color: var(--text-dim); }
.badge-status-stopped { background: var(--gray-soft); color: var(--text-dim); }

/* ============ 集中任务管理：批量操作按钮禁用态（2026-09-21 五轮） ============ */
/* 一条都没勾选时：挂起/恢复、删除、复制 三个按钮置灰。
   注意 cursor 必须是 not-allowed，且**不能**用 pointer-events:none（那样鼠标退回默认箭头，
   禁止图标就出不来）；点击拦截靠 button[disabled] 原生行为，所以这里只管样式。 */
.btn.tm-batch.is-disabled,
.btn.tm-batch.is-disabled:hover {
  background: #f5f6f8; border-color: var(--border-light); color: #b9bec7;
  cursor: not-allowed;
}

/* ============ 集中任务管理：表头列分隔线 + 执行结果圆标（2026-09-22） ============ */
/* 表头每列之间的 | 分隔（SVG 竖线，贴 th 右边缘；th 是 sticky = 已定位，可直接做包含块）。
   注意：这里**不能**再给 .tm-tbl thead th 写 position: relative —— 会把 sticky 覆盖掉。 */
.tm-th-sep {
  position: absolute; right: 0; top: 50%;
  margin-top: -7px; width: 1px; height: 14px;
  color: var(--border-strong); pointer-events: none;
}

/* 执行结果：圆底 + 白 √/×，圆色 & 文字色按成功/失败 */
.tm-res { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; }
.tm-res-ico { flex: none; }
.tm-res-ico.ok  { color: var(--status-completed); }
.tm-res-ico.bad { color: var(--status-failed); }
.tm-res.completed .tm-res-txt { color: var(--status-completed); }
.tm-res.partial   .tm-res-txt { color: var(--status-waiting); }
.tm-res.failed    .tm-res-txt { color: var(--status-failed); }
/* 部分成功：图标仍是 √，只换颜色区分三态（绿=成功 / 琥珀=部分成功 / 红=失败）。
   放在基础规则之后且特异性更高（0,3,0 > 0,2,0），压过 .tm-res-ico.ok 的绿 */
.tm-res.partial .tm-res-ico.ok { color: var(--status-waiting); }

/* ============ 集中任务管理：按钮下拉三角 + 导出子菜单（2026-09-22 二轮） ============ */
/* 过滤/导出/每页条数 按钮里的下拉三角（SVG 包在 span 里便于对齐，svg 走 display:block 消基线缝） */
/* 注意：类名用 tm-btn-caret，不能叫 tm-caret —— 后者是左侧任务类型树折叠箭头的类 */
.tm-btn-caret { display: inline-flex; align-items: center; margin-left: 4px; vertical-align: middle; }
.tm-btn-caret svg { display: block; }

/* 导出按钮 + 其下子菜单：wrap 相对定位，面板贴按钮下方（复用 tm-filter-panel 观感） */
.tm-exp-wrap { position: relative; display: inline-flex; }
.tm-exp-panel { min-width: 104px; }

/* 面板项禁用态（「导出已选」无勾选时）：与更多菜单 disabled 项同款 */
.tm-filter-item.disabled { color: var(--text-faint); cursor: default; pointer-events: none; }

/* ============ 新建任务向导（2026-09-22 三轮）：点「创建」→ 全页三步 ============ */
/* 向导撑满 main-content 内容区（page-host height:100%，main 的 padding 保留不算进页面） */
.tm-wizard { height: 100%; display: flex; flex-direction: column; background: #fff; border: 1px solid var(--border); border-radius: 4px; }
/* 步骤条：水平直线连接，完成=绿√、当前=绿实心、未来=灰空心；名字在圆点下方。
   line 用 align-self: flex-start + margin-top 与 16px 圆点垂直居中对齐 */
.tmw-steps { display: flex; align-items: flex-start; justify-content: center; padding: 22px 0 6px; }
.tmw-step { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 90px; }
.tmw-step[data-back] { cursor: pointer; }
.tmw-dot { width: 16px; height: 16px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; }
.tmw-step.todo .tmw-dot { background: #fff; border: 1.5px solid #c9ced6; }
.tmw-step.cur  .tmw-dot { background: var(--status-completed); box-shadow: 0 0 0 3px #eaf7e6; }
.tmw-step.done .tmw-dot { background: var(--status-completed); }
.tmw-name { font-size: 13px; color: var(--text-faint); }
.tmw-step.cur .tmw-name { color: var(--status-completed); font-weight: 500; }
.tmw-line { width: 96px; height: 2px; background: #e3e6ea; margin: 7px 8px 0; align-self: flex-start; }
.tmw-line.on { background: var(--status-completed); }
/* 主体与底部按钮条。第 1 步 no-scroll：树自己撑满剩余高度，整页不出纵向滚动条；
   注意用 overflow:visible 而不是 hidden —— hidden 会把浮到输入框上方的校验提示裁掉（曾把提示挡住） */
.tmw-body { flex: 1; overflow: auto; padding: 8px 28px 10px; min-height: 0; }
.tmw-body.no-scroll { overflow: visible; }   /* 第 1 步：树自己撑满，且校验提示要浮到容器外 */
.tmw-body.fixed { overflow: hidden; }        /* 第 3 步：body 不滚，滚动条交给左右两列各自持有 */
.tmw-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 10px 28px 16px; }
/* 第 1 步没有上一步可退 → 「上一步」置灰（disabled 拦点击 + is-disabled 只管样式，鼠标禁止图标） */
.tmw-foot .btn.is-disabled,
.tmw-foot .btn.is-disabled:hover { background: #f5f6f8; border-color: #e0e3e8; color: #b9bec7; cursor: not-allowed; }
/* 表单行（label 定宽 + 内容列）；label 文字左对齐（2026-09-23 用户要求，原来右对齐） */
.tmw-field { display: flex; align-items: flex-start; margin-bottom: 8px; }
.tmw-field > label { width: 96px; text-align: left; font-size: 13px; color: var(--text); padding-top: 5px; flex: none; }
/* 必填星号：绝对定位到文字左侧外侧（2026-09-23 用户要求）—— 星号不占位，
   带星与不带星的行（任务名称 / 执行类型、起始时间 / 超期时间）文字左缘完全对齐。
   top 取 label 的 padding-top 值，星号才跟文字同一水平线（口径同「保存结果」弹窗的 .exp-req） */
.tmw-field > label.tmw-req { position: relative; }
.tmw-field > label.tmw-req i { position: absolute; left: -9px; top: 5px; color: #f5222d; font-style: normal; }
.tmw-fc { flex: 1; min-width: 0; position: relative; }
.tmw-fc input[type=text] { height: 28px; padding: 0 8px; border: 1px solid var(--border-strong); border-radius: 2px; font-size: 13px; color: var(--text); }
.tmw-fc input[type=text]:focus { outline: none; border-color: var(--accent); }
.tmw-note { font-size: 12px; color: var(--text-faint); line-height: 1.6; }
/* 「任务类型」小节标题（原「任务别名」位置，无冒号无输入框） */
.tmw-sec-title { margin: 0 0 6px 100px; font-size: 13px; color: var(--text); }
/* 名称校验提示：绝对浮动在输入框上方（白底红边），出现/消失不改变页面布局。
   宽度与任务名称输入框一致（215px）；两行结构：① 图标 +「必填项」+ 右上角关闭 ×  ② 完整校验说明
   文案长会自动折行、浮层变高，父级用 overflow:visible 保证不被裁 */
.tmw-tip-err { position: absolute; left: 0; bottom: 100%; margin-bottom: 4px; z-index: 60; width: 300px; padding: 6px 8px 7px; border: 1px solid #ffa39e; background: #fff; color: #f5222d; font-size: 12px; line-height: 1.5; border-radius: 2px; box-shadow: 0 2px 8px rgba(31,35,41,.08); }
.tmw-tip-head { display: flex; align-items: center; gap: 5px; padding-right: 16px; }
.tmw-tip-head svg { flex: none; }
.tmw-tip-close { position: absolute; top: 4px; right: 4px; display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; cursor: pointer; color: #f5222d; }
.tmw-tip-close:hover { color: #820014; }
.tmw-tip-body { margin-top: 3px; word-break: break-all; }
/* 第 1 步：竖向 flex，树占满剩余高度（配合 .tmw-body.no-scroll 不出滚动条）。
   padding-top 为浮在输入框上方的校验提示预留位置（提示 215px 宽时约 84px 高），
   这样提示落在向导内部、不会盖住顶部步骤条；该留白恒定，提示显隐不影响布局 */
.tmw-s1 { height: 100%; display: flex; flex-direction: column; min-height: 0;}
.tmw-type-tree { flex: 1; min-height: 150px; margin: 0 0 0 100px; width: 560px; max-width: calc(100% - 100px); overflow: auto; border: 1px solid var(--border); background: #fff; padding: 4px 0; }
.tmw-tgroup-head { display: flex; align-items: center; gap: 4px; padding: 4px 10px; font-size: 13px; cursor: pointer; }
.tmw-tgroup-head:hover { background: var(--hover); }
.tmw-tleaf { display: flex; align-items: center; gap: 5px; padding: 4px 10px 4px 30px; font-size: 13px; cursor: pointer; color: var(--text); }
.tmw-tleaf:hover { background: var(--hover); }
.tmw-tleaf.sel, .tmw-tleaf.sel svg { background: var(--accent); color: #fff; }
/* 第 2 步：两列 grid 按**行**排（左字段 / 右勾选框），align-items:center 让勾选框落在同行时间控件的垂直中线上。
   说明文字各占一整行，右列那格是空 span 占位 —— 说明换行也不会把「自动删除」顶偏 */
.tmw-s2-grid { display: grid; grid-template-columns: minmax(0, 1fr) 190px; gap: 8px 30px; align-items: center; max-width: 880px; }
/* 行内对齐的坑：.tmw-field 自带 margin-bottom:8px，会让 grid 行高 = 36（内容 28 + margin 8），
   align-items:center 把勾选框按 36 居中 → 比时间控件低 4px。行间距交给 grid 的 row-gap，这里把 margin 清掉 */
.tmw-s2-grid .tmw-field { margin-bottom: 0; }
.tmw-check { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; cursor: pointer; }
.tmw-req-tip { color: #f5222d; font-size: 12px; margin-left: 8px; }
/* 时间控件：文本框 + 右侧日历图标 + 下弹月历面板。
   禁用态 = wrapper cursor:not-allowed + input disabled 灰底（不用 pointer-events:none，禁图标要显示） */
.tmw-dt { position: relative; display: inline-flex; align-items: center; width: 260px; }
.tmw-dt-input { flex: 1; width: 100%; height: 28px; padding: 0 30px 0 8px; border: 1px solid var(--border-strong); border-radius: 2px; font-size: 13px; color: var(--text); background: #fff; cursor: pointer; }
.tmw-dt-input:focus { outline: none; border-color: var(--accent); }
.tmw-dt-ico { position: absolute; right: 8px; display: inline-flex; color: var(--text-dim); pointer-events: none; }
.tmw-dt.disabled { cursor: not-allowed; }
.tmw-dt.disabled .tmw-dt-input { background: #f5f6f7; color: #b9bec7; border-color: var(--border); cursor: not-allowed; }
.tmw-dt.disabled .tmw-dt-ico { color: #c9ced6; }
.tmw-dt-panel { position: absolute; top: 32px; left: 0; z-index: 40; background: #fff; border: 1px solid var(--border); border-radius: 4px; box-shadow: 0 4px 14px rgba(31,35,41,.14); padding: 8px; width: 234px; box-sizing: border-box; }
/* 2026-09-27 集中任务管理时间选择器统一为网元备份页那种：.ff-date + cal* 日历（300px 同任务名称框宽） */
.tmw-fc .ff-date-wrap { position: relative; display: inline-flex; width: 300px; max-width: 100%; }
.tmw-fc .ff-date { flex: 1; min-width: 0; width: 100%; height: 28px; box-sizing: border-box; padding: 0 28px 0 8px; font-size: 13px; color: var(--text); border: 1px solid var(--border-strong); border-radius: 2px; background: #fff; outline: none; }
.tmw-fc .ff-date:focus { border-color: var(--accent); }
.tmw-fc .ff-date:disabled { color: #b9bec7; background: #f5f6f7; border-color: var(--border); cursor: not-allowed; }
.tmw-fc .ff-date-wrap svg { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); color: var(--text-dim); pointer-events: none; }
.tmw-cal-head { display: flex; align-items: center; justify-content: space-between; padding: 2px 4px 6px; }
.tmw-cal-title { font-size: 13px; font-weight: 500; }
.tmw-cal-nav { cursor: pointer; color: var(--text-dim); padding: 0 8px; font-size: 15px; line-height: 1; }
.tmw-cal-nav:hover { color: var(--accent); }
.tmw-cal-week { display: grid; grid-template-columns: repeat(7, 1fr); font-size: 12px; color: var(--text-faint); text-align: center; padding-bottom: 2px; }
.tmw-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.tmw-cal-grid i { visibility: hidden; }
.tmw-cal-grid b { font-weight: 400; font-size: 12px; text-align: center; padding: 4px 0; cursor: pointer; border-radius: 2px; }
.tmw-cal-grid b:hover { background: var(--hover); }
.tmw-cal-grid b.on { background: var(--accent); color: #fff; }
/* 今天之前的日期：置灰 + 鼠标禁止图标（点击在 JS 里直接 return，选不中） */
.tmw-cal-grid b.off { color: #b9bec7; cursor: not-allowed; }
.tmw-cal-grid b.off:hover { background: transparent; }
.tmw-cal-time { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-dim); padding: 8px 2px; border-top: 1px solid var(--border); margin-top: 6px; }
.tmw-cal-time input { width: 48px; height: 24px; border: 1px solid var(--border-strong); text-align: center; font-size: 12px; }
.tmw-cal-foot { display: flex; justify-content: flex-end; gap: 6px; padding-top: 4px; }
/* 第 3 步：左右两列参数卡片；网元树数据来自 /api/ne/list */
/* 第 3 步：两列各自独立滚动 —— 滑动条在 .tmw-s3-right（左列不动），body 不再整体滚 */
.tmw-s3 { height: 100%; min-height: 0; display: flex; flex-direction: column; }
.tmw-s3-grid { height: 100%; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 20px; align-items: stretch; }
.tmw-s3-left, .tmw-s3-right { min-height: 0; overflow-y: auto; overflow-x: hidden; }
.tmw-s3-right { padding-right: 4px; }   /* 给滚动条留位，避免压住卡片右缘 */
.tmw-card { border: 1px solid var(--border); border-radius: 4px; padding: 10px 12px; margin-bottom: 12px; background: #fff; }
.tmw-card-title { font-size: 13px; font-weight: 600; margin-bottom: 8px; }
/* 卡片标题与它的选项同行（「选择文件：」+ 两个 radio、「选择网元：」+ 三个 tab） */
.tmw-card-head { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.tmw-card-head .tmw-card-title { margin-bottom: 0; flex: none; }
.tmw-radios { display: flex; gap: 18px; flex-wrap: wrap; }
.tmw-radio { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; cursor: pointer; }
.tmw-file-row { display: flex; gap: 8px; margin-top: 8px; }
/* 文件框（伪输入框）：整条可点＝选 .txt；文件名 → 紧跟 × （删除）→ 最右侧文件夹图标（打开） */
.tmw-file-input { flex: 1; min-width: 0; display: flex; align-items: center; height: 28px; box-sizing: border-box; padding: 0 6px 0 8px; border: 1px solid var(--border-strong); border-radius: 2px; background: #fff; font-size: 13px; cursor: pointer; }
.tmw-file-input:hover { border-color: var(--accent); }
.tmw-file-txt { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); }
.tmw-file-txt.empty { color: var(--text-faint); }
.tmw-file-x { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; margin-left: 5px; color: var(--text-dim); cursor: pointer; }
.tmw-file-x:hover { color: var(--critical); }
.tmw-file-x.hidden { display: none; }
.tmw-file-folder { flex: none; margin-left: auto; padding-left: 8px; display: inline-flex; align-items: center; color: var(--text-dim); }
.tmw-file-folder svg { width: 15px; height: 15px; display: block; }
.tmw-file-input:hover .tmw-file-folder { color: var(--accent); }
/* 未选脚本文件：网元 tab 与网元树勾选框一律置灰不可选（禁用态用 disabled，不用 pointer-events:none） */
.tmw-radio.locked { color: var(--text-faint); cursor: not-allowed; }
.tmw-radio.locked input { cursor: not-allowed; }
.tmw-ne-tree.locked .nt-row { cursor: not-allowed; }
.tmw-ne-tree.locked input.nt-check { cursor: not-allowed; }
.tmw-ne-tree.locked .nt-name { color: var(--text-faint); }
/* 网元树容器：树本身由 js/neTree.js 渲染（与 MML 命令页同一棵，样式 .ne-tree/.nt-*） */
.tmw-ne-tree { margin-top: 8px; height: 320px; overflow: auto; border: 1px solid var(--border); }
/* 脚本自己用 {网元名称} 指定了作用网元 → 说明为什么这棵树是灰的（与「未选文件」区分开） */
.tmw-ne-scripttip { margin-top: 8px; padding: 4px 8px; border: 1px solid #ffe58f; background: #fffbe6; color: #ad6800; font-size: 12px; line-height: 1.6; border-radius: 2px; }
.tmw-ne-scripttip.hidden { display: none; }
/* 「选择网元」工具条：第一行三个 tab（.tmw-radios），第二行刷新/展开/收起/导入/导出/筛选（复用 .ml-tools 的图标样式，
   只把容器自身的内边距/底边线/底色去掉以贴合卡片）+ 点「筛选」后出现的搜索框 */
.tmw-netools { display: flex; align-items: center; gap: 10px; margin-top: 6px; }
.tmw-netools .ml-tools { padding: 4px 0; border-bottom: 0; background: none; }
.tmw-netools .ml-search { width: 170px; height: 26px; box-sizing: border-box; padding: 0 8px; border: 1px solid var(--border-strong); border-radius: 3px; font-size: 12px; outline: none; }
.tmw-netools .ml-search:focus { border-color: var(--accent); }
.tmw-netools .ml-search.hidden { display: none; }
.tmw-prow { display: flex; align-items: center; gap: 8px; font-size: 13px; margin-bottom: 8px; flex-wrap: wrap; }
.tmw-prow input[type=number] { width: 84px; height: 26px; border: 1px solid var(--border-strong); padding: 0 6px; }
/* 运行结果「保存为」：240px 文件名输入框 + 紧跟的 .txt；下方「仅错误结果 / 全部结果」；
   未勾选「保存为」时输入框与两个单选项一并置灰（disabled + 禁图标，不用 pointer-events:none） */
.tmw-savename { display: flex; align-items: center; gap: 4px; margin: 8px 0; }
.tmw-savename input[type=text] { width: 240px; height: 26px; box-sizing: border-box; padding: 0 8px; border: 1px solid var(--border-strong); border-radius: 2px; font-size: 12.5px; color: var(--text); }
.tmw-savename input[type=text]:focus { outline: none; border-color: var(--accent); }
.tmw-savename input[type=text]:disabled { background: #f5f6f7; color: #b9bec7; border-color: var(--border); cursor: not-allowed; }
.tmw-save-ext { font-size: 12.5px; color: var(--text-dim); }

/* ============ 「保存结果」弹窗（2026-09-23）：复用告警页的 exp-row/exp-lbl/exp-opt ============ */
/* 只把标签列加宽到放得下「完整性校验：」，并补上输入框/下拉/开关三个控件。
   零 transition（复刻口径）；开关本身可点切换，所以不用 pointer-events:none */
.tm-exp .exp-row { gap: 10px; padding: 8px 2px; }
/* label 文字左对齐（2026-09-23 用户要求）；宽度放到 96px 才装得下最长的「完整性校验：」。
   必填星号用绝对定位放到文字左侧外侧 —— 它不占位，带星与不带星的行文字左缘完全对齐 */
.tm-exp .exp-lbl { width: 96px; text-align: left; position: relative; }
.tm-exp .exp-req { position: absolute; left: -9px; top: 0; color: #f5222d; font-style: normal; }
.tm-exp .exp-input,
.tm-exp .exp-select { width: 240px; height: 28px; box-sizing: border-box; padding: 0 8px; border: 1px solid var(--border-strong); border-radius: 2px; font-size: 13px; color: var(--text); background: #fff; }
.tm-exp .exp-input:focus,
.tm-exp .exp-select:focus { outline: none; border-color: var(--accent); }
.tm-exp .exp-switch { position: relative; width: 34px; height: 18px; border-radius: 9px; background: #676c73; cursor: pointer; flex: none; }
.tm-exp .exp-switch::after { content: ''; position: absolute; left: 2px; top: 2px; width: 14px; height: 14px; border-radius: 50%; background: #fff; }
.tm-exp .exp-switch.on { background: var(--accent); }
.tm-exp .exp-switch.on::after { left: 18px; }

/* ============ 「下载历史结果」弹窗（2026-09-23）============ */
/* 表头「全选框 | 文件 | 文件大小（KB）」与数据行共用同一套 grid，列才对得齐；
   分隔线是行内 SVG（列表页表头那个 .tm-th-sep 是绝对定位的，这里不能用）。
   行数多时只有 .tm-dlh-list 出 Y 滑动条，表头与底部合计行固定不动 */
.tm-dlh-row { display: grid; grid-template-columns: 26px 9px minmax(0, 1fr) 9px 104px; align-items: center; }
.tm-dlh-head { padding: 0 0 6px; font-size: 13px; font-weight: 500; color: var(--text); border-bottom: 1px solid var(--border); }
.tm-dlh-bar { display: block; color: var(--border-strong); }
.tm-dlh-ck { display: inline-flex; align-items: center; }
.tm-dlh-ck input { margin: 0; accent-color: var(--accent); cursor: pointer; }
.tm-dlh-list { max-height: 260px; overflow-y: auto; overflow-x: hidden; }
.tm-dlh-list .tm-dlh-row { padding: 6px 0; border-bottom: 1px dashed var(--border-light); }
.tm-dlh-list .tm-dlh-row:last-child { border-bottom: 0; }
/* 文件名超长不换行，用 … 截断（title 里带全名，悬停可见） */
.tm-dlh-file { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tm-dlh-size { text-align: right; font-size: 12.5px; color: var(--text-dim); }
.tm-dlh-head .tm-dlh-size { font-size: 13px; color: var(--text); }
/* 底部：左「合并文件」、右「选择文件总大小」（0.000 三位小数由 JS 算） */
.tm-dlh .tm-dlh-sum { justify-content: space-between; border-top: 1px solid var(--border); margin-top: 4px; padding: 10px 2px 2px; }
.tm-dlh-total { font-size: 13px; color: var(--text-dim); }
.tm-dlh-total b { font-weight: 500; color: var(--text); }
/* 置灰的「下载」：原生 disabled 在 Chrome 下光标是 default，这里显式给禁图标 */
.tm-dlh-dl.is-disabled { cursor: not-allowed; }

/* ============ ws-home「菜单」抽屉（2026-09-24）============ */
/* 点工作台条最左的九宫格图标 → 从左边滑出；上/左/下与 .main-wrap 重合（绝对定位），
   宽度随内容自适应：内容窄就窄，最宽不超过 main-wrap（明细列排不下时换行，见 .md-cols）。
   ★ 这是用户点名的「滑动出现」，所以开/合各有一次 keyframes 动画；
     抽屉只在开合时动，hover/悬停一律零 transition（与全站口径一致）。 */
.menu-drawer {
  position: absolute; left: 0; top: 0; bottom: 0; z-index: 30;
  width: max-content; max-width: 100%;
  display: flex; flex-direction: column;
  background: #fff; border-right: 1px solid var(--border-strong);
  box-shadow: 2px 0 12px rgba(0,0,0,.10);
  animation: md-in .22s ease-out;
}
.menu-drawer.hidden { display: none; }
.menu-drawer.closing { animation: md-out .18s ease-in; }
@keyframes md-in  { from { transform: translateX(-100%); } to { transform: translateX(0); } }
@keyframes md-out { from { transform: translateX(0); }     to { transform: translateX(-100%); } }

/* 顶部：长搜索框（图标在最左）+ 右上角关闭 */
.md-top { flex: none; display: flex; align-items: center; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--border-light); }
.md-search {
  position: relative; flex: 1 1 auto; min-width: 300px; height: 34px;
  display: flex; align-items: center; padding: 0 12px 0 34px;
  background: #fff; border: 1px solid var(--border-strong); border-radius: 17px;
}
.md-search:focus-within { border-color: var(--accent); }
.md-search .md-search-ico {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; color: var(--text-faint);
}
.md-search .md-search-ico svg { display: block; }
.md-search input {
  flex: 1 1 auto; min-width: 0; border: 0; outline: none; background: transparent;
  font-size: 13px; color: var(--text);
}
.md-search input::placeholder { color: var(--text-faint); }
.md-close {
  flex: none; width: 26px; height: 26px; display: flex; align-items: center; justify-content: center;
  border-radius: 4px; color: var(--text-dim); cursor: pointer;
}
.md-close:hover { background: var(--hover); color: var(--accent); }
.md-close svg { display: block; }

.md-body { flex: 1 1 auto; min-height: 0; display: flex; }

/* 左：大字「菜单」+ 五大板块各一行（行右侧是进该板块主页的图标） */
.md-side { flex: none; padding: 12px 16px 16px; border-right: 1px solid var(--border-light); }
.md-side-title { font-size: 17px; font-weight: 600; color: var(--text); padding: 2px 8px 12px; }
.md-board {
  display: flex; align-items: center; gap: 10px; white-space: nowrap;
  padding: 8px 8px 8px 10px; border-radius: 4px;
  font-size: 13px; color: var(--text-dim); cursor: pointer;
}
.md-board:hover { background: var(--hover); color: var(--accent); }
.md-board.active { background: var(--accent-soft); color: var(--accent); font-weight: 500; }
.md-board .md-board-name { flex: 1 1 auto; }
.md-board .md-board-home {
  flex: none; width: 20px; height: 20px; display: inline-flex;
  align-items: center; justify-content: center; border-radius: 3px;
  color: var(--text-faint); cursor: pointer;
}
.md-board:hover .md-board-home { color: var(--accent); }
.md-board .md-board-home:hover { background: rgba(38,115,229,.12); }

/* 右：菜单明细。一个大菜单一块，块与块由 JS 贪心装箱到列里；
   列横向排布、一行放不下就换行，纵向滚动统一收在 .md-cols 上
   → ★ 整个明细区有且只有【一条】滑动条（用户口径）。
     列自己一律不滚（一列一条滚动条看着乱，且高度参差更明显）。 */
.md-detail { flex: 1 1 auto; min-width: 0; display: flex; padding: 14px 16px 10px; }
.md-cols {
  flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap;
  align-items: flex-start; align-content: flex-start; gap: 22px;
  overflow-y: auto; overflow-x: hidden;
}
.md-cols::-webkit-scrollbar { width: 6px; }
.md-cols::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
.md-cols::-webkit-scrollbar-track { background: transparent; }
/* 列不再滚动 → 不需要给滚动条留白，列宽就是内容宽 */
.md-col { flex: none; width: max-content; min-width: 132px; }
/* 块高含自己的 padding-bottom（JS 按 offsetHeight/scrollHeight 装箱，量到多少就占多少）。
   width:100% → 同一列里各块的宽度对齐到该列最宽的那块：标题下划线一样长、条目 hover 底
   与收藏星也在同一条竖线上（不然每块宽度各随内容，看着参差）。 */
.md-group { width: 100%; padding-bottom: 18px; }
.md-group-title {
  font-size: 14px; font-weight: 600; color: var(--text);
  padding: 0 8px 8px; margin-bottom: 4px; border-bottom: 1px solid var(--border-light);
}
/* 搜索结果里的「所在大菜单」小标签（跨板块搜索时用来区分同名条目） */
.md-tag { flex: none; font-size: 11px; color: var(--text-faint); background: var(--bg); border-radius: 2px; padding: 0 5px; }
.md-empty { font-size: 13px; color: var(--text-faint); padding: 24px 8px; }

/* ================= 网元备份（2026-09-24 按真机截图重排） =================
   布局：左「网元选择」一列到底（工具条/搜索/过滤/模型分组树/共·选中/上传备份刷新），
   右上「备份文件列表」+ 右下任务区（即时任务/批量即时任务/文件传输任务 三页签）。
   排序图标 / 分页 / 过滤下拉 / 行内操作图标复用 tm- 系列全局样式。
   左右宽度 / 右侧上下高度可拖（--bk-left-w / --bk-file-h，mml-grip 手柄，双击重置）。 */
:root { --bk-left-w: 252px; --bk-file-h: 300px; }
.bk-view { height: 100%; min-height: 0; }
.bk-view > .two-col { height: 100%; min-height: 0; align-items: stretch; gap: 8px; }
/* ---- 左列 ---- */
.bk-view .bk-left-pane { width: var(--bk-left-w); display: flex; flex-direction: column; min-height: 0; background:white;}
.bk-left-card { flex: 1; min-height: 0; max-height: none; display: flex; flex-direction: column; padding: 10px; background: transparent; border-radius: 0;border:none }
.bk-tools { margin-bottom: 8px; }
.bk-search { position: relative; margin-bottom: 8px; }
.bk-search input {
  width: 100%; box-sizing: border-box; padding: 5px 26px 5px 8px;
  border: 1px solid var(--border); border-radius: 4px; font-size: 12.5px; color: var(--text);
}
.bk-search input:focus { border-color: var(--accent); outline: none; }
.bk-search svg { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); color: var(--text-faint); pointer-events: none; }
.bk-filters { margin-bottom: 8px; }
.bk-f-row { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.bk-f-row > label { flex: none; width: 56px; font-size: 12px; color: var(--text-dim); }
.bk-f-row select {
  flex: 1; min-width: 0; font-size: 12px; padding: 3px 4px;
  border: 1px solid var(--border); border-radius: 3px; background: #fff; color: var(--text);
}
.bk-f-row select.bk-f-op { flex: none; width: 56px; }
.bk-tree { flex: 1; min-height: 0; overflow: auto; border-top: 1px solid var(--border-light); padding-top: 6px; }
/* 横向滚动：flex 行默认被压到容器宽内，内容超宽时直接裁掉不出滚动条；
   min-width:max-content 让行按内容撑开 → 容器出现横向滚动条（组计数会贴到名字后） */
.bk-tree .nt-row { min-width: max-content; }
.bk-left-foot { padding: 8px 10px 6px; font-size: 12px; color: var(--text-dim); white-space: nowrap; }
.bk-left-btns { display: flex; gap: 8px; }
/* 批量按钮置灰（与 taskmgr 的 is-disabled 同口径：原生 disabled + 禁用样式） */
.bk-view .btn:disabled, .bk-view .btn.is-disabled {
  background: #ccd1d8 !important; border-color: #ccd1d8 !important; color: #fff !important;
  cursor: not-allowed !important; box-shadow: none;
}
.bk-view .btn.btn-primary:disabled { background: #ccd1d8 !important; }
/* ---- 右列 ---- */
/* overflow:hidden 兜底：即便极端情况内容仍略超高，也只裁在右列内，不把主页面撑出滚动条
   （tm-ps-panel / 过滤弹层均向上或列内展开，不受影响） */
.bk-view .bk-right { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
.bk-toolbar, .bk-task-bar { padding: 10px;margin:0; }
.bk-file-panel { flex: none; height: var(--bk-file-h); min-height: 140px; padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.bk-file-wrap { flex: 1; min-height: 0; }
/* 列宽拖拽：fixed 布局 + JS 显式总宽（同 alm-tbl 口径），拖表头即时生效、不被长内容撑开。
   border-collapse 必须用 separate（本表单元格只有 border-bottom，视觉无差）：
   collapse 下 th 右缘外 4px 的手柄命中区会被相邻单元格盖住，拖拽点不进（实测踩坑）。 */
.bk-file-wrap .tm-tbl, .bk-task-wrap .tm-tbl { min-width: 0; table-layout: fixed; border-collapse: separate; border-spacing: 0; }
.bk-file-wrap thead th, .bk-task-wrap thead th { position: sticky; top: 0; z-index: 3; background: #f7f8fa; }
/* 空态：图标 + 暂无数据（截图同款居中灰态） */
.bk-empty { text-align: center; padding: 0; color: var(--text-faint); font-size: 13px; }
.bk-empty svg { display: block; margin: 0 auto 10px; }
.bk-foot { font-size: 12px; color: var(--text-dim); }
/* ---- 任务区（高度 = 右列剩余空间，由上方 h-grip 拖 --bk-file-h 决定） ---- */
.bk-task-sec { margin-top: 0; flex: 1; min-height: 0; display: flex; flex-direction: column; background:white}
/* mml-grip 手柄在 bk 内的落位：v-grip 占 two-col 的 8px gap（覆盖 mml 的 -4px 外边距） */
.bk-view .mml-grip { flex: none; }
.bk-view .mml-grip.v-grip { margin: 0; }
.bk-view .mml-grip.h-grip { height: 10px; margin: 3px 0; }
.bk-tabs { display: flex; gap: 26px; border-bottom: 1px solid var(--border); padding: 0 10px; }
.bk-tab {
  padding: 7px 2px; font-size: 13px; color: var(--text-dim); cursor: pointer;
  border-bottom: 2px solid transparent; user-select: none; white-space: nowrap;
}
.bk-tab:hover { color: var(--accent); }
.bk-tab.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 500; }
/* 2026-10-16：刷新遮罩（.tbl-loading-mask）的定位父级 —— 两个区各挂一个，
   遮罩只盖本区（文件区刷新不挡住任务区，反之亦然） */
.bk-task-sec { position: relative; }
.bk-task-panel { flex: 1; min-height: 0; padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.bk-task-wrap { flex: 1; min-height: 120px; overflow: auto; }
.bk-filter-wrap { position: relative; }
.bk-prog { display: inline-flex; align-items: center; gap: 6px; width: 130px; }
.bk-prog .progress { flex: 1; min-width: 0; }
.bk-prog > b { font-size: 11px; font-weight: 400; color: var(--text-faint); width: 32px; text-align: right; flex: none; }
.bk-tip { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--text-faint); margin-left: 12px; white-space: nowrap; }
.bk-tip svg { color: var(--warning); flex: none; }

/* ---- 2026-09-25 备份页二轮：按钮方形化 / 底条两行 / 上下分区包装 ---- */
/* 左下三按钮：无圆角；未选中置灰=灰底白字（.bk-view .btn:disabled 既有规则）；
   选中后=灰框黑字 */
.bk-left-btns { display: flex; gap: 8px; padding: 10px;}
.bk-left-btns .btn {
  border-radius: 0; background: #fff; border: 1px solid #c9cdd4; color: var(--text);
}
.bk-left-btns .btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.bk-left-btns .btn.btn-primary { background: #fff; color: var(--text); }
/* 上半区包装（工具条 + 文件表 + 底条），与 .bk-task-sec 结构对称 */
/* 2026-10-16：刷新遮罩的定位父级（同上，理由同 .bk-task-sec） */
.bk-file-sec { flex: none; background:white; position: relative; }
/* 底条两行：第一行=分页（右对齐，空数据整行隐藏）；第二行=共/选中（+任务区提示靠右） */
.bk-foot { flex-direction: column; align-items: stretch; gap: 4px; }
.bk-pager { display: flex; align-items: center; justify-content: flex-end; gap: 6px; }
.bk-pager[hidden] { display: none; }
.bk-foot-row { display: flex; align-items: center; }
.bk-foot-row .spacer { flex: 1; }
.bk-foot-row .bk-tip { margin-left: 0; }
.bk-upd { margin-left: 12px; font-size: 12px; color: var(--text-dim); }
/* 警告确认弹窗：黄色圆圈+！ */
.bk-warn { display: flex; align-items: center; gap: 10px; font-size: 13px; padding: 8px 2px; }
.bk-warn-ico { width: 22px; height: 22px; border-radius: 50%; background: #f5a623; color: #fff;
  font-weight: 700; font-size: 14px; line-height: 1; display: inline-flex; align-items: center; justify-content: center; flex: none; }

/* ---- 2026-09-25「查询」过滤条件弹窗（居中，openModal 标准壳） ---- */
.bkq-grid { display: grid; grid-template-columns: 72px 1fr; row-gap: 12px; column-gap: 10px; align-items: start; }
.bkq-lab { font-size: 13px; color: var(--text); padding-top: 5px; }
.bkq-in {
  width: 100%; box-sizing: border-box; padding: 5px 8px;
  border: 1px solid var(--border); border-radius: 4px; font-size: 12.5px; color: var(--text);
}
.bkq-in:focus { border-color: var(--accent); outline: none; }
select.bkq-in { height: 29px; background: #fff; }
/* 时间选择器：同告警页 ff-occur-from 口径（.ff-date + 日历图标；置灰只改字色，图标不受影响）。
   告警页样式作用域在 .alm-filter-body 下，弹窗内这里补一份同款 */
.bkq-grid .ff-date-wrap { position: relative; display: inline-flex; width: 100%; }
.bkq-grid .ff-date {
  flex: 1; width: 100%; height: 26px; border: 1px solid var(--border-light);
  background: #f2f3f5; border-radius: 2px; font-size: 12px; color: #000;
  padding: 0 24px 0 8px; outline: none;
}
.bkq-grid .ff-date:disabled { color: #b9bec7; }
.bkq-grid .ff-date:not(:disabled) { background: #fff; border-color: var(--border-strong); }
.bkq-grid .ff-date-wrap svg { position: absolute; right: 7px; top: 50%; transform: translateY(-50%); color: #c1c6cd; pointer-events: none; }
/* 勾选框+文字落在标签列（与其他 bkq-lab 左对齐） */
.bkq-lab-ck { display: flex; align-items: center; gap: 4px; padding-top: 0; cursor: pointer; white-space: nowrap; }
.bkq-lab-ck input { margin: 0; }
.bkq-sec { grid-column: 1 / -1; font-size: 12px; color: var(--text-dim); padding-top: 0; }
.bkq-time-row input[type="datetime-local"] {
  flex: 1; min-width: 0; padding: 4px 6px;
  border: 1px solid var(--border); border-radius: 4px; font-size: 12.5px; color: var(--text);
}
.bkq-time-row input[type="datetime-local"]:disabled { background: #f2f3f5; color: var(--text-faint); }
.bkq-opts { display: flex; flex-wrap: wrap; gap: 6px 16px; padding-top: 5px; font-size: 12.5px; color: var(--text); }
.bkq-opts label { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; cursor: pointer; }

/* ---- 2026-09-25 备份文件区「下载/删除」下拉选项菜单 ---- */
.bk-act-menu { position: fixed; z-index: 1300; min-width: 110px; background: var(--panel);
  border: 1px solid var(--border-strong); box-shadow: 0 4px 14px rgba(0, 0, 0, .13); }
.bk-act-item { padding: 7px 16px; font-size: 12.5px; color: var(--text); cursor: pointer; white-space: nowrap; }
.bk-act-item:hover { background: var(--hover); }
.bk-act-item.disabled { color: var(--text-faint); cursor: not-allowed; background: none; }

/* ---- 2026-09-25 备份三连确认 + 进度弹窗 ---- */
/* 确认/提示文案行：蓝!图标 + 文字 */
.bk-confirm-row { display: flex; gap: 10px; align-items: flex-start; font-size: 13px; line-height: 1.7; }
.bk-confirm-row svg { flex: none; margin-top: 3px; }
/* 加密选项弹窗 */
.bk-enc-row { display: flex; align-items: center; gap: 16px; margin-bottom: 12px; }
.bk-enc-row label { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; cursor: pointer; }
.bk-enc-row input[type="radio"] { margin: 0; }
.bk-enc-lbl { width: 76px; flex: none; font-size: 13px; color: var(--text-dim); }
.bk-enc-inp {
  flex: 1; min-width: 0; box-sizing: border-box; padding: 6px 8px;
  border: 1px solid var(--border); border-radius: 4px; font-size: 13px; color: var(--text);
}
.bk-enc-inp:focus { border-color: var(--accent); outline: none; }
.bk-enc-inp:disabled { background: #f2f3f5; color: var(--text-faint); cursor: not-allowed; }
.bk-enc-hint { font-size: 12px; color: var(--text-faint); }
/* 口令校验：必填/复杂度不满足 → 提示行本身变红（不另起一行）；两次不一致 → 白框浮于确认口令框下（不改变弹窗大小） */
.bk-enc-row-rel { position: relative; }
.bk-enc-hint-err { color: #e5484d; }
.bk-enc-pop { position: absolute; left: 96px; top: 100%; margin-top: 3px; background: #fff;
  border: 1px solid var(--border-strong); box-shadow: 0 3px 10px rgba(0, 0, 0, .14);
  padding: 5px 12px; font-size: 12px; color: #e5484d; white-space: nowrap; z-index: 10; }

/* ---- 2026-09-25 打包备份文件弹窗 ---- */
.bk-pack-tip { font-size: 13px; color: var(--text); margin-bottom: 14px; }
/* 进度弹窗：24px 灰底条 + 填充 #61cab2 + 百分比 */
.bk-prog-row { display: flex; align-items: center; gap: 10px; padding: 6px 0; }
.bk-bigprog {
  display: block; flex: 1; min-width: 0; height: 24px;
  background: #e5e7eb; border-radius: 3px; overflow: hidden;
}
.bk-bigprog i { display: block; height: 100%; width: 0; background: #61cab2; transition: width .25s linear; }
.bk-prog-row > b { width: 42px; flex: none; text-align: right; font-size: 13px; font-weight: 400; color: var(--text); }

/* ---- 网元树「导出格式」弹层（ntt-，neTreeTools.js；MML/备份/任务向导三处共用） ---- */
/* 不居中：fixed 定位贴在 .ml-tools 工具条左下方（位置由 JS 按锚点算）；无关闭按钮，点外部即收 */
.ntt-pop {
  position: fixed; z-index: 95; width: 200px; background: #fff;
  border: 1px solid var(--border); border-radius: 4px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, .14); padding: 10px 12px 8px; user-select: none;
}
.ntt-pop-title { font-size: 13px; font-weight: 500; color: var(--text); margin-bottom: 8px; }
.ntt-pop-opt { display: flex; flex-direction: row; align-items: center; gap: 12px; margin-bottom: 10px; }
.ntt-pop-opt label { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--text); cursor: pointer; }
.ntt-pop-opt label:hover { color: var(--accent); }
/* 确定按钮：无底色、黑框黑字、无圆角（用户 2026-09-25 定） */
.ntt-pop-ok {
  padding: 4px 18px; font-size: 12.5px; cursor: pointer;
  background: #fff; border: 1px solid #333; color: #000; border-radius: 0;
}
.ntt-pop-ok:hover { border-color: #000; background: #f5f6f7; }
.ntt-pop-foot { text-align: right; }
/* 向导第三步锁定图标：颜色稍浅（透明度），仅作用于第三步工具条，不影响任务列表行内同款置灰 */
.tmw-netools .tm-ico-disabled { opacity: .5; }
/* 第三步四行筛选复用网元备份页 .bk-filters/.bk-f-row（全局样式），这里只收窄宽度适配右栏 */
.tmw-ne-filters-wrap .bk-f-row > label,
#tmw-ne-filters .bk-f-row > label { width: 56px; }

/* ================= 信令跟踪管理（tt-，trace.js；2026-09-26 二轮：布局对齐网元备份） =================
   左「跟踪类型」树 + 右上跟踪任务表 + 右下任务状态，双手柄可拖：
   左右宽度 --tt-left-w / 右侧上下高度 --tt-file-h（mml-grip，双击重置，做法同 bk-）。
   整页不出滚动条：.tt-view 占满 .main，三个分区各自 overflow:auto（x/y 都有）。 */
:root { --tt-left-w: 252px; --tt-file-h: 300px; }
.tt-view { height: 100%; min-height: 0; display: flex; flex-direction: column; }
/* 顶部页签条（2026-09-27）：上下 padding 5px、宽 100%；最左「信令跟踪管理」+ 查看结果多开页签。
   2026-09-27 二改：负外边距抵消 #main-content 的 padding(16px 20px)，页签条直接顶到 main-wrap 顶部
   （口径同当前告警 .alm-floatbar），自带内容区底色，左右随 20px 内边距对齐。 */
.tt-tabs { flex: none; width: calc(100% + 40px); box-sizing: border-box; margin: -16px -20px 10px; padding: 5px 20px 6px; background: var(--bg); display: flex; align-items: flex-end; gap: 2px; overflow-x: auto; scrollbar-width: none; }
.tt-tabs::-webkit-scrollbar { display: none; }
.tt-tab { display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 10px; background: #f0f1f3; color: #7a828e; font-size: 12.5px; border-radius: 4px 4px 0 0; cursor: pointer; max-width: 260px; white-space: nowrap; flex: none; user-select: none; }
.tt-tab .tt-tab-name { overflow: hidden; text-overflow: ellipsis; }
.tt-tab.on { background: #e2e5ea; color: var(--accent, #1a66ff); }
.tt-tab-x { font-style: normal; margin-left: 4px; width: 15px; height: 15px; line-height: 14px; text-align: center; border-radius: 2px; flex: none; font-size: 13px; }
.tt-tab-x:hover { background: rgba(0,0,0,.12); color: #333; }
#tt-mainwrap { flex: 1; min-height: 0; }
#tt-mainwrap[hidden] { display: none; }
#tt-result { flex: 1; min-height: 0; }
#tt-result[hidden] { display: none; }
#tt-mainwrap > .two-col { height: 100%; min-height: 0; align-items: stretch; gap: 8px; }
/* 查看结果页 */
.rst-view { height: 100%; min-height: 0; display: flex; flex-direction: column; }
.rst-toolbar { margin-bottom: 8px; position: relative; flex-wrap: nowrap; }
/* 工具条控件等高：按钮与搜索框都 26px（2026-09-27 用户要求搜索框高度和按钮一致） */
.rst-toolbar .btn { height: 26px; box-sizing: border-box; }
.rst-toolbar .bk-search { margin: 0; width: 200px; flex: none; }
.rst-toolbar .bk-search input { height: 26px; padding: 0 26px 0 8px; }
/* 保存/更多下拉（贴按钮弹出）与按列过滤面板（贴工具条左侧弹出，宽同截图） */
.rst-menu-wrap { position: relative; display: inline-flex; }
.rst-dd { right: 0; left: auto; min-width: 110px; z-index: 30; }
.rst-toolbar .btn.has-flt, .rst-toolbar .btn.on { background: #1a6fbd; border-color: #1a6fbd; color: #fff; }
.rst-flt-panel {
  position: absolute; top: calc(100% + 4px); left: 0; z-index: 30;
  width: 880px; max-width: calc(100vw - 60px); box-sizing: border-box;
  background: var(--panel); border: 1px solid var(--border); border-radius: 4px;
  box-shadow: 0 8px 24px rgba(31,35,41,.16); padding: 14px 18px 12px;
}
.rstf-title { font-size: 12.5px; font-weight: 600; color: var(--text); margin: 2px 0 8px; }
.rstf-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 24px; margin-bottom: 10px; }
.rstf-item { display: flex; align-items: center; gap: 10px; }
.rstf-item label { flex: none; width: 130px; font-size: 12.5px; color: var(--text-dim); }
.rstf-item select { flex: 1; min-width: 170px; }   /* min-width 保「全部」完整显示（2026-09-27 用户反馈被截断） */
.rstf-time { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.rstf-time .ttv-chk { width: 76px; flex: none; }
/* 时间选择器（cal* 全套，同弹窗 .ttv-row .ff-date 口径）：勾选启用、未勾选置灰 */
.rstf-time .ff-date-wrap { position: relative; flex: 1; min-width: 170px; display: inline-flex; }
.rstf-time .ff-date { flex: 1; min-width: 0; width: 100%; height: 26px; box-sizing: border-box; padding: 0 26px 0 8px; font-size: 12.5px; color: var(--text); border: 1px solid var(--border-strong); border-radius: 2px; background: #fff; outline: none; }
.rstf-time .ff-date:disabled { color: #b9bec7; background: #f5f6f7; border-color: var(--border); cursor: not-allowed; }
.rstf-time .ff-date-wrap > svg { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); color: var(--text-dim); pointer-events: none; }
.rstf-rev { display: inline-flex; margin-bottom: 4px; }
.rstf-foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 6px; }
.rst-panel { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.rst-wrap { flex: 1; min-height: 0; position: relative; overflow: auto; }
/* 列宽可拖拽：table-layout:fixed + th 显式宽（拖拽时由 JS 改写）；td 超宽省略号。
   border-box + separate(间距0)：th style.width 与 rect 宽严格相等 —— 沿用 .tbl 的 collapse 时
   Chrome 会对指定宽做内部再分配（实测 style 172px 渲染 181px），拖一格其他列跟着漂。 */
.rst-tbl { width: 100%; min-width: 1512px; table-layout: fixed; border-collapse: separate; border-spacing: 0; }
/* table.tbl(0,1,1) 的 collapse 优先级压过 .rst-tbl —— 提一档才盖得住 */
table.tbl.rst-tbl { border-collapse: separate; border-spacing: 0; }
.rst-tbl th, .rst-tbl td { box-sizing: border-box; }
.rst-tbl th { position: relative; }
.rst-tbl th, .rst-tbl td { white-space: nowrap; }
.rst-tbl td { overflow: hidden; text-overflow: ellipsis; }
.rst-tbl .alm-col-resizer { position: absolute; top: 0; right: -4px; width: 9px; height: 100%; cursor: e-resize; z-index: 6; }
body.alm-col-dragging { cursor: e-resize; user-select: none; }
/* 空态：图标+文字在父级内 xy 居中 */
.rst-empty { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; color: var(--text-faint); font-size: 13px; pointer-events: none; }
.rst-empty[hidden] { display: none; }   /* 修 bug：display:flex 压过 hidden 属性 → 有数据时「没有数据」叠在表格上不消失（2026-09-27） */
/* 行内「更多操作」下拉：fixed 挂 .rst-view（td overflow:hidden 裁 absolute），复用 tm-filter-panel 观感 */
.rst-row-menu { position: fixed; z-index: 300; min-width: 110px; }
.tt-view > .two-col { height: 100%; min-height: 0; align-items: stretch; gap: 8px; }
/* ---- 左列 ---- */
.tt-view .tt-left-pane { width: var(--tt-left-w); flex: none; display: flex; flex-direction: column; min-height: 0; background: white;}
.tt-left-card { flex: 1; min-height: 0; display: flex; flex-direction: column; padding: 10px 0 6px; background: transparent; border: none; border-radius: 0; max-height: 100vh;}
/* -/+ 两个按钮与搜索框同一行 */
.tt-tools-row { display: flex; align-items: center; gap: 6px; padding: 0 10px 6px; }
.tt-tools-row .ml-ic {
  flex: none; width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center;
  color: var(--text-dim); cursor: pointer; border-radius: 3px;
}
.tt-tools-row .ml-ic:hover { color: var(--accent); background: var(--hover); }
.tt-tools-row .ml-ic svg { width: 14px; height: 14px; display: block; }
.tt-tools-row .tt-search { flex: 1; min-width: 0; margin-bottom: 0; }
/* 树：容器自己出 x/y 滚动条；行 min-width:max-content 撑开横向滚动 */
.tt-tree { flex: 1; min-height: 0; overflow: auto; border-top: 1px solid var(--border-light); padding: 4px 0 6px; user-select: none; }
.tt-row { display: flex; align-items: center; gap: 5px; min-height: 24px; padding-right: 6px; font-size: 12.5px; color: var(--text); white-space: nowrap; min-width: max-content; }
.tt-row:hover { background: var(--hover); }
.tt-row.branch { font-weight: 500; cursor: pointer; }
.tt-row.leaf { cursor: pointer; }
/* 单选高亮（同集中任务管理 .tm-leaf.active） */
.tt-row.active { background: var(--accent-soft); color: var(--accent); }
.tt-row .tt-tg {
  flex: none; width: 14px; height: 14px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: 2px; color: var(--text-dim); background: #fff; cursor: pointer;
}
.tt-row .tt-tg svg.tg-ic { display: block; pointer-events: none; }
/* 展开后 + 变 -：展开行（非 collapsed）隐藏竖线只剩横线；收起是 + */
.tt-row:not(.collapsed) .tt-tg svg.tg-ic .tg-v { display: none; }
/* 叶子行无 +/- 框，补同宽隐形占位（14 + 行 gap 5 = 19），让叶子图标与父级文字左对齐 */
.tt-tg-spacer { flex: none; width: 14px; }
.tt-row.collapsed + .tt-children { display: none; }
.tt-children.collapsed { display: none; }
.tt-row .tt-nico { flex: none; display: inline-flex; align-items: center; }
.tt-row .tt-name { overflow: hidden; text-overflow: ellipsis; }
/* ---- 右列 ---- */
.tt-view .tt-right { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
.tt-top-sec { flex: none; height: var(--tt-file-h); min-height: 140px; display: flex; flex-direction: column; background: white;}
.tt-toolbar { padding: 8px 10px; flex: none; }
.tt-kw { position: relative; width: 200px; margin-bottom: 0; }
.tt-kw input {
  width: 100%; height: 28px; padding: 0 26px 0 8px; font-size: 12.5px;
  border: 1px solid var(--border); border-radius: 3px; background: #fff; color: var(--text);
}
.tt-kw input:focus { border-color: var(--accent); outline: none; }
.tt-kw svg { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); color: var(--text-faint); pointer-events: none; }
.tt-funnel {
  flex: none; width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid transparent; border-radius: 3px; color: var(--text-dim); cursor: pointer;
}
.tt-funnel svg { width: 14px; height: 14px; display: block; }
.tt-funnel:hover { color: var(--accent); border-color: var(--accent); }
/* 表格面板：面板不滚，滚动全在 .tt-wrap（x/y 都有）；表头 sticky */
.tt-panel { padding: 0; overflow: hidden; flex: 1; min-height: 0; display: flex; flex-direction: column; }
.tt-wrap { flex: 1; min-height: 0; overflow: auto; }
.tt-wrap thead th { position: sticky; top: 0; z-index: 3; background: #f7f8fa; }
#tt-table tbody tr.tt-susp td { color: #e0331f; }
#tt-table tbody tr.tt-susp td .status-text.paused { color: #e0331f; }
.tt-ico { color: var(--accent); }
/* 底条：总计/选中 + 分页（页码用蓝色圆徽标，对齐截图） */
.tt-foot { flex: none; flex-direction: column; align-items: stretch; gap: 4px; }
.tt-foot-row { font-size: 12px; color: var(--text-dim); }
.tt-page-badge {
  min-width: 20px; height: 20px; padding: 0 5px; border-radius: 10px;
  background: var(--accent); color: #fff; font-size: 11.5px; font-weight: 500;
  display: inline-flex; align-items: center; justify-content: center;
}
/* ---- 右下「任务状态」（高度 = 右列剩余空间，由 h-grip 拖 --tt-file-h 决定） ---- */
.tt-task-sec { margin-top: 0; flex: 1; min-height: 0; display: flex; flex-direction: column; background: white;}
.tt-task-head { flex: none; display: flex; align-items: center; gap: 8px; padding: 6px 10px 8px; }
.tt-task-title { font-size: 13.5px; font-weight: 600; color: var(--text); }
.tt-task-kw { width: 200px; }
/* mml-grip 手柄落位（同 bk-：v-grip 吃掉 two-col 的 gap，h-grip 固定 10px） */
.tt-view .mml-grip { flex: none; }
.tt-view .mml-grip.v-grip { margin: 0; }
.tt-view .mml-grip.h-grip { height: 10px; margin: 3px 0; }
/* 弹窗内输入框（创建/批量创建/编辑） */
.tt-in { width: 100%; height: 28px; padding: 0 8px; font-size: 12.5px; border: 1px solid var(--border); border-radius: 3px; background: #fff; color: var(--text); }
.tt-in:focus { border-color: var(--accent); outline: none; }
.tt-view .btn:disabled, .tt-view .btn.is-disabled {
  background: #ccd1d8; border-color: #ccd1d8; color: #fff; cursor: not-allowed;
}

/* ---- 2026-09-26 信令跟踪四轮：列宽拖拽 + 更多下拉 ---- */
/* 列宽拖拽：fixed 布局 + JS 显式总宽（同 alm-tbl / bk- 口径，类名与 alarms 一致只换前缀） */
#tt-table { table-layout: fixed; border-collapse: separate; border-spacing: 0; }
/* 手柄必须整体落在自己的 th 内（th 同为 sticky z-index:3，后一个 th 会盖住前一个伸出去的部分） */
.tt-col-resizer { position: absolute; top: 0; right: 0; width: 8px; height: 100%; cursor: e-resize; z-index: 6; }
body.tt-col-dragging { cursor: e-resize; user-select: none; }
/* 「定位到跟踪类型」短暂高亮 */
.tt-row.flash { background: var(--accent-soft); }

/* ---- 2026-09-26 信令跟踪五轮：右上面板加载遮罩 ---- */
.tt-top-sec .tt-panel { position: relative; }
.tt-loading-mask {
  position: absolute; inset: 0; z-index: 20; display: none;
  align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.35);
}
.tt-loading-mask.show { display: flex; }
.tt-loading-box {
  display: flex; align-items: center; gap: 9px;
  background: #fff; border: 1px solid var(--border); border-radius: 4px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.14);
  padding: 11px 20px; font-size: 12.5px; color: var(--text);
}
.tt-loading-spin {
  flex: none; width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid #d8dce3; border-top-color: var(--accent);
  animation: tt-spin 0.8s linear infinite;
}
@keyframes tt-spin { to { transform: rotate(360deg); } }
/* ---- 2026-10-16 公共：点「刷新」时盖在列表区上的遮罩（口径同信令跟踪管理 / ANR）----
   ★ 只登记遮罩自己这一类：白底加载框（.tt-loading-box）与转圈（.tt-loading-spin）直接复用上面那套，
     和 .tt-loading-mask / .anr-loading-mask 是同一个外观、同一套显隐（只切 .show，零过渡）。
   ★ 定位父级（position:relative）由**各页自己**保证，且必须是非滚动容器
     （滚动容器里绝对定位的子元素会跟着内容滚走 —— 见 .anr-loading-mask 那条注释）：
     .alm-tbl-box（告警三页）/ .bk-file-sec · .bk-task-sec（备份）/ .tm-tbl-panel（集中任务）
     / .log-tbl-panel（操作日志）/ .rp-pane.rp-has-list（对象组）。
   z-index 20：盖住表头 sticky(1)、工具条浮层，低于筛选贴边面板(45)/弹窗(2000)。 */
.tbl-loading-mask {
  position: absolute; inset: 0; z-index: 20; display: none;
  align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.35);
}
.tbl-loading-mask.show { display: flex; }
.tbl-loading-mask[hidden] { display: none; }

/* ---- 2026-09-26 信令跟踪八轮：创建按钮主色 #1870be + 重新执行图标恒置灰 ---- */
#tt-create:not(:disabled):not(.is-disabled) { background: #1870be; border-color: #1870be; color: #fff; }
#tt-create:not(:disabled):not(.is-disabled):hover { background: #1466ac; border-color: #1466ac; color: #fff; }
.tt-ico-off { color: #c3c7cf !important; cursor: not-allowed; }
.tt-ico-off:hover { color: #c3c7cf !important; }

/* ---- 2026-09-27 信令跟踪创建弹窗（虚用户跟踪 / 信令跟踪网元选择） ---- */
.ttv-grid2 { display: grid; grid-template-columns: 130px 1fr; row-gap: 10px; column-gap: 12px; align-items: center; }
.ttv-lbl { font-size: 13px; color: #333; white-space: nowrap; position: relative; }
.ttv-lbl i { color: #e34d4d; font-style: normal; position: absolute; left: -9px; top: 0; }   /* '*' 悬挂，不参与对齐 */
/* PLMN 行（2026-09-27 用户要求）：PLMN 与 MCC 同一行，MNC 行留空对齐；
   两个输入框 flex:1 铺满同一列 → 同宽、与上方输入框左对齐；MCC/MNC 身份靠 hover 提示辨识 */
.ttv-ctl > .tt-in { flex: 1; min-width: 0; }
/* PLMN 子栏标签（2026-09-27 补回 *MCC / *MNC）：固定同宽保证两个输入框等宽；'*' 绝对定位悬挂不参与对齐
   （★ 别把「星号紧跟斜杠」连写：本文件注释里踩过一次，会让「注释开始符」多出一个，扫注释的守卫容易误报） */
.ttv-slbl { flex: none; width: 44px; position: relative; font-size: 13px; color: #333; white-space: nowrap; }
.ttv-slbl i { color: #e34d4d; font-style: normal; position: absolute; left: -9px; top: 0; }
/* 时间选择行（2026-09-27 统一为网元备份页 .ff-date + cal* 日历）：输入框随行撑满，右缘与其他输入框对齐 */
.ttv-row .ff-date-wrap { position: relative; display: inline-flex; flex: 1; min-width: 0; }
.ttv-row .ff-date { flex: 1; min-width: 0; width: 100%; height: 28px; box-sizing: border-box; padding: 0 28px 0 8px; font-size: 13px; color: var(--text); border: 1px solid var(--border-strong); border-radius: 2px; background: #fff; outline: none; }
.ttv-row .ff-date:focus { border-color: var(--accent); }
.ttv-row .ff-date:disabled { color: #b9bec7; background: #f5f6f7; border-color: var(--border); cursor: not-allowed; }
.ttv-row .ff-date-wrap svg { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); color: var(--text-dim); pointer-events: none; }
/* MCC/MNC hover 提示：白框浮于输入框正下方，不占布局 */
.tr-hover-tip { position: fixed; z-index: 300; background: #fff; border: 1px solid var(--border-strong, #c9ced6); border-radius: 3px; box-shadow: 0 4px 14px rgba(31,35,41,.14); padding: 5px 10px; font-size: 12px; color: #333; white-space: nowrap; pointer-events: none; }
/* 信令跟踪弹窗高度锁死（JS 设 inline height），筛选面板显隐只压缩网元树高度 */
#tts-p1 { display: flex; flex-direction: column; height: 100%; box-sizing: border-box; overflow-y: auto; }
#tts-p1[hidden] { display: none; }   /* ID 的 display:flex 会压过 hidden 属性，必须显式关掉 */
/* 网元区不压缩：树上限内 flex:1、下限 150px 不让位；底部各行 flex-shrink:0 不被挤矮，
   筛选面板(128px)展开后内容超出 → #tts-p1 自身出 y 滚动条（2026-09-27 用户拍板：允许这一步纵向滑动） */
#tts-p1 > *:not(.ttv-ne-box) { flex-shrink: 0; }
#tts-p1 .ttv-ne-box { flex: 1; min-height: 150px; height: auto; }
.ttv-lbl2 { width: 130px; flex: none; text-align: left; font-size: 13px; color: #333; }
.ttv-ctl { flex: 1; display: flex; align-items: center; gap: 8px; min-width: 0; }
.ttv-row { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.ttv-chk { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; color: #333; cursor: pointer; }
.ttv-radio { display: inline-flex; align-items: center; gap: 4px; margin-right: 18px; font-size: 13px; color: #333; cursor: pointer; }
.ttv-section { font-weight: 600; font-size: 13px; color: #333; margin: 16px 0 2px; }
.ttv-dt { flex: 1; min-width: 0; }
.ttv-dt:disabled { background: #eceef1; color: #9aa2ad; cursor: not-allowed; }
.ttv-num { width: 90px; flex: none; }
/* 网元选择区工具条 + 版本树开关 */
.ttv-ne-tools { display: flex; align-items: center; gap: 6px; margin: 14px 0 8px; }
.ttv-ne-tools .ml-ic { width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--border, #dfe3e8); border-radius: 3px; cursor: pointer; color: #5a6572; background: #fff; }
.ttv-ne-tools .ml-ic svg { width: 14px; height: 14px; display: block; }
.ttv-ne-tools .ml-ic:hover { color: var(--accent); border-color: var(--accent); }
.ttv-ne-tools .ml-ic.on { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.ttv-ver-lbl { font-size: 13px; color: #333; margin-left: auto; }
.tt-switch { width: 34px; height: 16px; border-radius: 8px; background: #c9ced6; position: relative; cursor: pointer; transition: background .15s; flex: none; }
.tt-switch::after { content: ''; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 50%; background: #fff; transition: left .15s; }
.tt-switch.on { background: var(--accent); }
.tt-switch.on::after { left: 20px; }
/* 筛选行 */
.ttv-search { margin-bottom: 8px; }
.ttv-frow { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.ttv-flbl { width: 72px; flex: none; font-size: 13px; color: #333; }
.ttv-frow .tt-in { width: 220px; }
.ttv-seg { display: flex; }
.ttv-seg button { border: 1px solid var(--border-strong, #c9ced6); background: #fff; padding: 3px 14px; font-size: 12.5px; cursor: pointer; color: #333; }
.ttv-seg button + button { border-left: none; }
.ttv-seg button.on { background: var(--accent); border-color: var(--accent); color: #fff; }
/* 网元树容器与计数 */
.ttv-ne-box { border: 1px solid var(--border, #dfe3e8); height: 250px; overflow: auto; padding: 6px 4px; margin-bottom: 6px; }
.ttv-count { font-size: 12.5px; color: #333; margin: 2px 0 4px; }
.ttv-count b { font-weight: 600; }

/* ---- 2026-09-27「请选择一个用户跟踪ID」选择弹窗（独立浮层，叠在创建弹窗之上） ---- */
.uidp-mask { position: fixed; inset: 0; z-index: 120; background: rgba(0,0,0,.28); }
/* 2026-09-27 收窄并上移：不完全盖住下方的创建弹窗 */
/* 2026-09-27 用户要求：选择弹窗居中显示（此前为避让外层弹窗偏左上） */
.uidp-float { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 540px; max-width: 60vw; background: #fff; border-radius: 6px; box-shadow: 0 12px 48px rgba(0,0,0,.28); }
.uidp-head { display: flex; align-items: center; justify-content: space-between; padding: 11px 16px; font-size: 14px; font-weight: 600; color: #333; }
.uidp-close { cursor: pointer; color: #8a929e; display: inline-flex; padding: 2px; }
.uidp-close:hover { color: var(--accent); }
.uidp-body { padding: 0 14px 4px; overflow: auto; max-height: 330px; }
.uidp-body table { width: 720px; border-collapse: collapse; font-size: 12.5px; color: #333; }
.uidp-body th { text-align: left; font-weight: 600; padding: 7px 9px; border-bottom: 1px solid var(--border, #dfe3e8); white-space: nowrap; background: #f7f8fa; }
.uidp-body td { padding: 6px 9px; border-bottom: 1px solid #f0f2f5; white-space: nowrap; }
.uidp-body tbody tr { cursor: pointer; }
.uidp-body tbody tr:hover td { background: #f5f8fd; }
.uidp-body tbody tr.sel td { background: var(--accent-soft); }
.uidp-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 10px 16px 12px; }

/* ---- 2026-09-27 信令跟踪创建第 2 步（上报参数/消息类型） ---- */
.tts2-grid { display: grid; grid-template-columns: 200px 1fr; row-gap: 13px; column-gap: 12px; align-items: center; }
.tts2-grid .ttv-lbl { line-height: 1.35; }
/* 上报周期(分)步进器 / 对端基站标识置灰输入框：鼠标禁止图标（2026-09-27 用户要求） */
.tts2-grid .tt-in:disabled { cursor: not-allowed; }
/* 弹窗壳挂在 body 上（不在 .tt-view/.tmw 作用域内），footer 置灰按钮需要自己的样式：
   原生 disabled + is-disabled 双保险（2026-09-27 用户反馈「置灰没加成功」的根因） */
.modal-float .btn:disabled, .modal-float .btn.is-disabled,
.modal-float .btn:disabled:hover, .modal-float .btn.is-disabled:hover {
  background: #f5f6f8; border-color: #e0e3e8; color: #b9bec7; cursor: not-allowed; box-shadow: none;
}
.modal-float .btn.btn-primary:disabled, .modal-float .btn.btn-primary.is-disabled,
.modal-float .btn.btn-primary:disabled:hover, .modal-float .btn.btn-primary.is-disabled:hover {
  background: #ccd1d8; border-color: #ccd1d8; color: #fff; cursor: not-allowed; box-shadow: none;
}
.tts2-step { flex: 1; display: flex; align-items: center; height: 28px; border: 1px solid var(--border); border-radius: 2px; background: #f5f6f7; overflow: hidden; cursor: not-allowed; }
.tts2-step button { width: 36px; height: 100%; border: none; background: transparent; color: #b9bec7; cursor: not-allowed; font-size: 15px; line-height: 1; }
.tts2-step b { flex: 1; text-align: center; color: #b9bec7; font-weight: 400; font-size: 13px; }
.tts2-msgs { border: 1px solid var(--border); border-radius: 2px; height: 180px; overflow: auto; padding: 4px 2px; margin-top: 8px; }
.tts2-mi { display: flex; align-items: center; gap: 7px; padding: 4px 8px; font-size: 13px; color: #333; cursor: pointer; }
.tts2-mi:hover { background: #f5f8fd; }

/* ================= 报表页（网元报表/网元统计报表/RAN报表/MBTS关系报表/RBTS报表 共用） =================
   布局同 MML：左菜单 + 右上/右下，左右宽/右上下高可拖（mml-grip 体系），CSS 变量 rp-left-w / rp-bottom-h */
:root { --rp-left-w: 220px; --rp-bottom-h: 280px; }
.rp-view { height: 100%; min-height: 0; position: relative; }  /* relative：#rp-grip-left 的定位祖先，缺了它手柄会逃逸到 .main-wrap 错位 20px（MML 的 .mml-page 同理靠 relative） */
.rp-body { height: 100%; position: relative; display: grid; grid-template-columns: var(--rp-left-w) 8px 1fr; grid-template-areas: "left grip main"; background: var(--bg); }
.rp-left { grid-area: left; background: #fff; border-right: 1px solid var(--border); display: flex; flex-direction: column; overflow: hidden; }
.rp-left-head { flex: none; display: flex; align-items: center; gap: 8px; padding: 12px 14px; border-bottom: 1px solid var(--border); color: var(--text); font-size: 14px; font-weight: 600; }
.rp-left-head .rp-menu-ic { width: 20px; height: 20px; flex: none; color: var(--text-dim); }
.rp-menu { flex: 1; min-height: 0; overflow: auto; padding: 6px 0; }
.rp-item { display: flex; align-items: center; gap: 6px; height: 34px; padding: 0 16px; font-size: 13px; color: var(--text); cursor: pointer; user-select: none; white-space: nowrap; }
.rp-item:hover { background: #f2f6fb; }
.rp-item.on { color: var(--accent); background: #eaf2fd; }
.rp-item .rp-arrow { margin-left: auto; display: inline-flex; color: var(--text-faint); transition: transform .15s; }
.rp-item .rp-arrow.open { transform: rotate(180deg); }
.rp-item.subitem { padding-left: 38px; color: var(--text-dim); }
.rp-item.subitem.on { color: var(--accent); }
.rp-main { grid-area: main; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.rp-toolbar { flex: none; display: flex; align-items: center; gap: 8px; padding: 8px 12px; }
.rp-toolbar .spacer { flex: 1; }
/* 「查询」按钮**不要颜色**（2026-10-09 用户要求）：原先这里是蓝底白字（#1870be），与工具条里
   其余按钮不同色显得突兀。现在 .rp-btn-query 只是一个语义标记（标明「这是查询按钮」），
   不再有任何自己的配色 —— 外观完全走 .btn 默认白底描边。
   报表页 #rp-query / ANR #anr-query 靠这条。
   ⚠ 报表管理的「创建」已改用 .btn-primary 保留主操作色；且 2026-10-12 用户又单独要求
     「报表管理的『搜索』与『创建』都要 #1870be」→ 见下面 .rpm-view 那两条**只作用报表管理页**的覆盖
     （报表页 / ANR 的查询按钮仍是白底描边，别把覆盖范围扩大）。 */
/* 左内边距为 0：右上/右下两栏贴着分隔条，否则分隔条看起来偏左（2026-10-05 用户要求）
   下内边距 0（2026-10-09 用户要求，报表页 / 报表管理 / ANR 三页统一）：留 12px 时右侧内容区
   比左侧菜单区短一截，上下分界线在视觉上左右对不齐。 */
.rp-content { flex: 1; min-height: 0; display: flex; flex-direction: column; position: relative; padding: 0; box-sizing: border-box; }
.rp-pane { background: #fff; border: 1px solid var(--border); border-radius: 4px; min-height: 0; overflow: auto; }
.rp-top-pane { flex: 1; }
.rp-bottom-pane { flex: none; height: var(--rp-bottom-h); }
.rp-view .mml-grip.h-grip { height: 10px; margin: 3px 0; flex: none; }
/* 左右分隔条：占 .rp-body 的 8px 间隔列，居中于两栏之间（同 MML/bk/tt 口径，2026-09-27） */
.rp-view .mml-grip.grip-left { position: relative; grid-area: grip; left: auto; top: auto; bottom: auto; transform: none; margin: 0; }
.rp-empty { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; color: var(--text-faint); font-size: 14px; background: var(--bg); }
.rp-empty[hidden] { display: none; }
.rp-empty .rp-doc-ic { width: 72px; height: 72px; }

/* ---- 网元统计报表：右侧单块结果表（网元类型 / 版本 / 网元数目，2026-10-05）----
   口径（用户要求）：表头【彻底没有背景色、没有边框】——白底也不能给（表上整体刷白会把表头那行刷白）；
   白底/边框只出现在「内容单元格」上：td 各自带 1px 边框 + 白底，表格外与表头行露出页面底色 */
.rp-view .rp-pane.rp-pane-plain { background: transparent; border: 0; border-radius: 0; }
.rp-stat-tbl { width: 100%; table-layout: fixed; border-collapse: collapse; font-size: 13px; }   /* fixed + colgroup：列宽由列定义决定，收起/展开不会重算列宽（2026-10-05 用户要求） */
.rp-stat-tbl .rp-stat-c1 { width: 30%; }
.rp-stat-tbl .rp-stat-c3 { width: 140px; }
.rp-stat-tbl thead th { background: transparent; border: 0; padding: 8px 12px; text-align: left; font-weight: 600; color: var(--text); white-space: nowrap; cursor: pointer; }
.rp-stat-tbl tbody td { background: #fff; border: 1px solid var(--border); padding: 6px 12px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rp-stat-tbl tbody tr:hover td { background: #f7fafd; }
.rp-stat-type { white-space: nowrap; cursor: pointer; }
/* 折叠图标：方框里的 + / −（展开= −，收起= +） */
.rp-stat-tg { position: relative; display: inline-block; width: 13px; height: 13px; margin-right: 7px; border: 1px solid var(--border-strong); border-radius: 2px; background: #fff; vertical-align: -2px; }
.rp-stat-tg::before { content: ''; position: absolute; left: 2px; right: 2px; top: 5px; height: 1.5px; background: var(--text-dim); }
.rp-stat-tg::after { content: ''; position: absolute; top: 2px; bottom: 2px; left: 5px; width: 1.5px; background: var(--text-dim); display: none; }
.rp-stat-grp.collapsed .rp-stat-tg::after { display: block; }

/* ---- 网元报表查询结果（2026-10-05）：右上=结果表，右下=统计信息 ---- */
/* 工具条：搜索框在行最左，放大镜按钮在框内右缘；导出基站维护区按钮在保存后面（仅网元报表显示） */
.rp-search { display: flex; align-items: center; width: 220px; height: 28px; border: 1px solid var(--border); border-radius: 3px; background: #fff; overflow: hidden; }
.rp-search[hidden] { display: none; }
.rp-search input { flex: 1; min-width: 0; border: 0; outline: none; padding: 0 4px 0 10px; font-size: 12px; color: var(--text); background: transparent; }
.rp-search input::placeholder { color: #9aa7b5; }
.rp-search-btn { flex: none; width: 28px; height: 100%; border: 0; background: transparent; cursor: pointer; color: #7b8794; display: flex; align-items: center; justify-content: center; padding: 0; }
.rp-search-btn:hover { color: #1870be; }
.rp-search-btn svg { width: 14px; height: 14px; }
/* 结果表：面板改成纵向 flex（表格区滚动、总计/分页行钉底）；列设置齿轮绝对浮动在列表右上角 */
.rp-pane.rp-has-list { position: relative; display: flex; flex-direction: column; overflow: hidden; }
/* RAN报表：表格上方的白底横条（2026-10-05）——像页签但没有 × 关闭，蓝字 = 当前报表类型 */
.rp-tab-bar { flex: none; background: #fff; padding: 8px 14px; font-size: 13px; color: var(--accent); }
.rp-gear { position: absolute; top: 7px; right: 14px; z-index: 3; display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; color: #5b6b7c; }
.rp-gear-underbar { top: 41px; }   /* RAN结果表：齿轮下移，让开上方约 34px 高的白底横条（2026-10-05 用户要求 RAN 也放齿轮） */
.rp-list-wrap { flex: 1; min-height: 0; overflow: auto; }
.rp-list-tbl { table-layout: fixed; border-collapse: collapse; font-size: 13px; }
/* 表头：无底色、无边框（与网元统计报表完全一致，2026-10-05 用户第三次要求）；列多 → 表宽=Σ列宽，横向滚动在 .rp-list-wrap 里
   吸顶（2026-10-05 用户要求「滑动的时候表头不要动」）：sticky 吸附在 .rp-list-wrap 滚动区顶部；
   sticky 表头必须不透明才能挡住滑过的内容行 → 铺页面底色 var(--bg)（静止时与「无底色」视觉一致，因为面板已是 rp-pane-plain）；sticky 同样为绝对定位后代的包含块，拖宽手柄照旧贴在本列右缘 */
/* 表头文字不加粗（2026-10-09 用户要求，含报表页与 Evaluation 的报表管理）：默认 600 太抢眼，
   与内容行同字重；「标题突出」靠底色/分割线，不靠字重 */
.rp-list-tbl thead th { position: sticky; top: 0; z-index: 2; background: var(--bg); border: 0; padding: 8px 18px 8px 12px; text-align: left; font-weight: normal; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; }
.rp-list-tbl thead th .alm-col-resizer { right: 0; }
/* 内容单元格：白底 + 1px 分割线（与网元统计报表 tbody td 同口径，2026-10-05 用户要求） */
.rp-list-tbl tbody td { background: #fff; border: 1px solid var(--border); padding: 6px 12px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 结果表整行提示（加载中）：跨列居中、不显示 hover 底色与单元格边框（2026-10-08，NR小区报表改真数据后加） */
.rp-list-tbl tbody td.rp-list-msg { text-align: center; color: var(--text-faint); padding: 24px 0; border-left: 0; border-right: 0; }
.rp-list-tbl tbody tr:hover td { background: #f2f6fb; }

/* ===== 表格空态「视觉居中」，不做结构上居中（2026-10-09 用户要求）=====
   背景：列多 / 表头长时表格总宽 > 滚动口（ANR 16 列 1644px vs 可视 1398px），
   colspan 单元格里的 text-align:center 会把「暂无数据」居中到「整表中点」——
   真中点落在屏幕外，看起来就是一片空白（告警页当年同一个坑，那页改用绝对浮层，
   见 .alm-tbl-box 上方注释）。这里统一口径：
     · 滚动口当查询容器（container-type: inline-size）→ 100cqw = 滚动口「可见宽」；
     · 空态块 position:sticky + left:0 → 粘在滚动口左缘，用户横向拖 x 条时一动不动；
       宽 = min(100%, 100cqw) → 表比滚动口宽时取可见宽（在可见区里居中），表窄时退回单元格宽；
     · 表比滚动口窄时（备份/跟踪：表 1126、可视 1362，表左对齐）再补一段位移
       max(0px, (100cqw - 100%) / 2) = 「可视中线 - 表中线」，把块推到面板中线；
       表比滚动口宽时这个值为负被 max 钳成 0 → 退化成上面的 sticky 定位（不影响主场景）；
     · 空表撑满滚动口高度（:has 只在真出现空态时才生效）→ 纵向也居中。
   ⚠ 空态所在单元格必须 overflow:visible：td 自带 overflow:hidden 时它自己就成了滚动口，
     里面的 sticky 会改成粘在 td 上 → 又变回结构性居中，白改。
   ⚠ 位移只在「表 ≤ 可视宽」时非零，此时块右缘 =（可视+表宽）/2 ≤ 可视 → 不会撑出横向滚动条；
     表更宽时位移为 0（块右缘 = 表宽，本来就有滚动条）→ 也不会多出滚动条。
   ⚠ 已知偏差：Chrome 的 cqw 把竖向滚动条算进容器宽（实测 cqw=1394 而 clientWidth=1378），
     所以「有竖向滚动条」的空态会向右偏 scrollbar/2 ≈ 8px —— 1400px 宽里 8px，肉眼不可见。
   ⚠ 依赖 Chrome 105+ 的 cqw / :has()：不认就整条声明失效 → 自动退回旧行为，不会坏版。
   覆盖范围：报表页 / 报表管理 / ANR（.rp-list-wrap）+ 备份 / 跟踪 / 集中任务管理（.tm-tbl-wrap）。 */
.rp-list-wrap, .tm-tbl-wrap { container-type: inline-size; }
.rp-list-tbl tbody td:has(> .bk-empty), .rp-list-tbl tbody td.rp-list-msg,
.tm-tbl-wrap tbody td:has(> .bk-empty) { overflow: visible; }
.rp-list-wrap .bk-empty, .tm-tbl-wrap .bk-empty {
  position: sticky; left: 0; width: min(100%, 100cqw); box-sizing: border-box;
  transform: translateX(max(0px, (100cqw - 100%) / 2));   /* 表比滚动口窄时补到面板中线；表更宽时为 0 */
  height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.rp-list-wrap:has(.bk-empty) .rp-list-tbl,
.tm-tbl-wrap:has(.bk-empty) .tm-tbl { height: 100%; }
/* 「加载中…」整行提示同一个坑（列多时也跑到屏幕外）：内容包一层块，同样粘滚动口左缘。
   ⚠ 只认 .rp-list-msg-in，别放宽成「该单元格的任意子元素」——那样会命中空态的 .bk-empty
     并把它的 display:flex 顶掉（后者特异性更低），空态纵向就不居中了（2026-10-09 实测踩坑）。 */
.rp-list-wrap td.rp-list-msg > .rp-list-msg-in { position: sticky; left: 0; display: block; width: min(100%, 100cqw); box-sizing: border-box; }
/* 表底：总计 + 「100条/页」+ 数字页码（最多 5 个，中间「…」省略）+ 跳转（2026-10-05 用户要求） */
.rp-list-foot { flex: none; display: flex; align-items: center; justify-content: space-between; padding: 6px 12px; border-top: 1px solid var(--border); font-size: 12px; color: var(--text); }
.rp-list-pg { display: flex; align-items: center; gap: 6px; }
.rp-list-pg select { height: 24px; border: 1px solid var(--border); border-radius: 3px; font-size: 12px; color: var(--text); background: #fff; padding: 0 4px; }
.rp-pg-nums { display: flex; align-items: center; gap: 5px; }
.rp-pg-num { min-width: 22px; height: 22px; padding: 0 6px; border: 1px solid var(--border); border-radius: 11px; background: #fff; color: var(--text); font-size: 12px; line-height: 20px; cursor: pointer; }
.rp-pg-num:hover { border-color: #1870be; color: #1870be; }
.rp-pg-num.is-cur { background: #1870be; border-color: #1870be; color: #fff; cursor: default; }
.rp-pg-gap { min-width: 14px; text-align: center; color: #9aa4b0; font-size: 12px; user-select: none; }
.rp-pg-jump { display: flex; align-items: center; gap: 4px; margin-left: 4px; color: var(--text); }
.rp-pg-ipt { width: 38px; height: 22px; border: 1px solid var(--border); border-radius: 3px; background: #fff; color: var(--text); font-size: 12px; text-align: center; padding: 0 2px; }
.rp-pg-ipt:focus { outline: none; border-color: #1870be; }
.rp-pg-go { height: 22px; padding: 0 8px; border: 1px solid var(--border); border-radius: 3px; background: #fff; color: var(--text); font-size: 12px; cursor: pointer; }
.rp-pg-go:hover { border-color: #1870be; color: #1870be; }
/* 统计信息（右下）：标题行 + 逐类型「型号: 在线/总数」 */
.rp-statinfo { font-size: 13px; color: var(--text); }
.rp-si-head { padding: 8px 12px; border-bottom: 1px solid var(--border); }
.rp-si-body { padding: 6px 12px; }
.rp-si-line { padding: 3px 0; }

/* ================= 报表管理（Evaluation > 报表 > 报表管理，2026-10-08 新增；同日二次改版）=================
   复用报表页的 .rp-view/.rp-body/.rp-left/.rp-item/.rp-search/.rp-list-* 一整套（同款观感），
   只补本页独有的：左栏搜索行、我关注的/我创建的/全部报表、−＋ 两个方框、
   可滑动文件夹树（展开收起 = 方框 + 「− / ＋」）、右栏标题行、
   高级搜索 + 导入/删除/创建/更多 工具条、带勾选框与**文字操作列**的结果表
   （报表名称/目录蓝字可点、只有横向分割线 + 表头竖向分隔线不顶格、默认不出横向滚动条）。
   左右宽度用**独立变量** --rpm-left-w：与报表页的 --rp-left-w 互不干扰（两个页面各自记住自己的宽度）。 */
:root { --rpm-left-w: 240px; }
.rpm-body { grid-template-columns: var(--rpm-left-w) 8px 1fr; }
/* 左栏最上方：整行宽的搜索框（与报表页 .rp-search 同款，只是占满一行） */
.rpm-search-row { flex: none; padding: 8px 12px; border-bottom: 1px solid var(--border); }
.rpm-search-row .rp-search { width: 100%; height: 28px; }
/* 2026-10-14 用户要求：rpm-all-box 高度高一点，底边直接到 rpm-menu 的最低——
   菜单改纵向 flex、底部内边距清零（否则盒子距底边差 10px），全部报表盒子 flex:1 吃掉剩余高度，
   树在盒子里自行滚动 */
.rpm-menu { padding: 6px 0 0; display: flex; flex-direction: column; }
/* 我关注的报表 / 我创建的报表 之间的分割线（用户要求「换行（分割线）」） */
.rpm-div { height: 1px; margin: 4px 0; background: var(--border); }
/* 「全部报表」行：与普通条目同高，右侧挂 rp-arrow（点击展开/收起 rpm-all-box） */
.rpm-all-row { justify-content: flex-start; }
.rpm-all-row .rp-arrow.open { transform: rotate(180deg); }
/* − 全部收起 / ＋ 全部展开 两个方框 */
.rpm-tree-tools { display: flex; gap: 6px; padding: 2px 16px 6px; }
/* 全部报表盒子：吃掉菜单剩余高度（底边贴到菜单最低）；收起时 hidden 必须显式压掉 display:flex（项目铁律） */
.rpm-all-box { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.rpm-all-box[hidden] { display: none; }
.rpm-sq { width: 20px; height: 20px; padding: 0; border: 1px solid var(--border); border-radius: 3px; background: #fff; color: var(--text-dim); font-size: 13px; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.rpm-sq:hover { border-color: #1870be; color: #1870be; }
/* 文件夹树：在盒子里吃满剩余高度、xy 都可滑动（不再限 max-height:340） */
.rpm-tree { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 0 6px; }
.rpm-node { display: flex; align-items: center; gap: 5px; height: 28px; padding-right: 12px; font-size: 13px; color: var(--text); cursor: pointer; user-select: none; white-space: nowrap; }
.rpm-node:hover { background: #f2f6fb; }
.rpm-node.on { color: var(--accent); background: #eaf2fd; }
/* 树的展开/收起图标 = **方框 + 「− / ＋」**（2026-10-08 用户要求，不再是三角箭头）；
   叶子节点没有方框，但占位宽度一样，文件夹图标才对得齐 */
.rpm-twist { flex: none; width: 15px; display: inline-flex; align-items: center; justify-content: center; }
.rpm-box { display: inline-flex; align-items: center; justify-content: center; width: 13px; height: 13px; border: 1px solid #9aa4b0; border-radius: 2px; background: #fff; color: #5b6b7c; font-size: 11px; line-height: 1; }
.rpm-node.on .rpm-box, .rpm-node:hover .rpm-box { border-color: #9aa4b0; }
.rpm-node .rpm-fold { flex: none; }
.rpm-node .rpm-name { overflow: hidden; text-overflow: ellipsis; }
/* 右栏：左上角标题（当前选中的文件夹 / 我的报表） */
.rpm-head { flex: none; padding: 12px 14px 0; }
.rpm-title { font-size: 14px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rpm-toolbar { padding: 8px 12px; }
/* 高级搜索：**蓝字** + rp-arrow（2026-10-08 用户要求「搜索框后面跟一个高级搜索+rp-arrow（蓝色字）」） */
.rpm-adv-wrap { position: relative; flex: none; }
.rpm-adv { display: inline-flex; align-items: center; gap: 3px; height: 28px; padding: 0 2px; border: 0; background: transparent; color: #1870be; font-size: 13px; cursor: pointer; white-space: nowrap; }
.rpm-adv:hover { color: #14619f; }
.rpm-adv.is-on { font-weight: 600; }   /* 有条件在生效 → 加粗提示 */
.rpm-adv .rp-arrow { display: inline-flex; }
.rpm-adv .rp-arrow svg { transition: transform .15s; }
.rpm-adv.open .rp-arrow svg { transform: rotate(180deg); }
.rpm-adv-box { position: absolute; left: 0; top: calc(100% + 4px); z-index: 22; width: 360px; padding: 10px 12px; background: #fff; border: 1px solid var(--border); border-radius: 4px; box-shadow: 0 4px 14px rgba(0, 0, 0, .14); }
/* 面板标题「搜索条件」（2026-10-12 用户要求） */
.rpm-adv-title { font-size: 13px; font-weight: 600; color: var(--text); padding-bottom: 8px; }
.rpm-adv-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.rpm-adv-lbl { flex: none; width: 56px; text-align: right; font-size: 12.5px; color: var(--text); }
/* 关系下拉（包含 / 等于 / 不包含），三项高度与输入框齐平 */
.rpm-adv-sel { flex: none; width: 76px; height: 28px; box-sizing: border-box; border: 1px solid var(--border-strong); border-radius: 2px; padding: 0 4px; font-size: 12.5px; color: var(--text); background: #fff; outline: none; }
.rpm-adv-sel:focus { border-color: var(--accent); }
/* 输入框 + 右缘「×」清空（输入框右侧留出 24px 给它；有内容才出现，见 .rpm-adv-clr[hidden]） */
.rpm-adv-ipt { position: relative; flex: 1; min-width: 0; display: inline-flex; }
.rpm-adv-row input { flex: 1; min-width: 0; width: 100%; height: 28px; box-sizing: border-box; border: 1px solid var(--border-strong); border-radius: 2px; padding: 0 24px 0 8px; font-size: 12.5px; color: var(--text); background: #fff; outline: none; }
.rpm-adv-row input:focus { border-color: var(--accent); }
.rpm-adv-clr { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; color: #9aa1ab; cursor: pointer; }
.rpm-adv-clr[hidden] { display: none; }   /* inline-flex 会盖掉浏览器给 [hidden] 的默认 display:none */
.rpm-adv-clr:hover { color: #5a6270; }
.rpm-adv-foot { display: flex; justify-content: flex-end; gap: 8px; padding-top: 2px; }
/* 「搜索」与「创建」= 主操作色 #1870be（2026-10-12 用户要求）。
   只按 id 作用于报表管理页这两枚按钮：报表页 #rp-query / ANR #anr-query 仍是白底描边（2026-10-09 口径）。
   id 选择器权重高于 .btn-primary，无需 !important。 */
.rpm-view #rpm-adv-ok, .rpm-view #rpm-create { background: #1870be; border-color: #1870be; color: #fff; }
.rpm-view #rpm-adv-ok:hover, .rpm-view #rpm-create:hover { background: #14619f; border-color: #14619f; color: #fff; }
.rpm-view #rpm-create:disabled, .rpm-view #rpm-create.is-disabled { background: #ccd1d8; border-color: #ccd1d8; color: #fff; }
/* 「更多」下拉（工具条） */
.rpm-more-wrap { position: relative; }
.rpm-more .rp-arrow { margin-left: 4px; display: inline-flex; }
.rpm-more .rp-arrow svg { transition: transform .15s; }
.rpm-more.open .rp-arrow svg { transform: rotate(180deg); }
.rpm-more-box { position: absolute; right: 0; top: calc(100% + 4px); z-index: 20; min-width: 112px; padding: 4px 0; background: #fff; border: 1px solid var(--border); border-radius: 4px; box-shadow: 0 4px 14px rgba(0, 0, 0, .14); }
.rpm-more-item { padding: 7px 14px; font-size: 13px; color: var(--text); cursor: pointer; white-space: nowrap; }
.rpm-more-item:hover { background: #f2f6fb; color: var(--accent); }
/* 行「更多」下拉：fixed 定位（挂 .rp-main；td 的 overflow:hidden 会把 absolute 面板裁掉），
   复用集中任务管理的 .tm-more-menu 皮肤，只把层级抬高；这里用的是 span → 补成块级竖排 */
.rpm-row-menu { z-index: 320; }
.rpm-row-menu .tm-more-item { display: block; }
.rpm-row-more-arrow { margin-left: 3px; display: inline-flex; }
/* 结果表（2026-10-08 二次改版）：12px 字号 + 收窄内边距 + 描述列留空 → 默认视口不出横向滚动条；
   分隔线只留**横向**（td 只有 border-bottom）；表头竖向分隔线用 ::after 画，上下不顶格、给拖拽留手感。
   ★ width:100% 是关键：table-layout:fixed 只有表宽**确定**时才是"按列宽分配"，
     否则浏览器先按内容算固有宽度（nowrap 的长文本会把表顶宽 → 出横向滚动条）。 */
.rpm-list-tbl { width: 100%; font-size: 12px; }
.rpm-list-tbl thead th { padding: 8px 14px 8px 8px; border: 0; }
.rpm-list-tbl thead th::after { content: ''; position: absolute; right: 0; top: 22%; height: 56%; width: 1px; background: var(--border-strong); }
.rpm-list-tbl thead th.checkbox-cell::after, .rpm-list-tbl thead th.rpm-ops-h::after { content: none; }
.rpm-list-tbl tbody td { border: 0; border-bottom: 1px solid var(--border); padding: 6px 8px; }
.rpm-list-tbl th.checkbox-cell, .rpm-list-tbl td.checkbox-cell { width: 26px; padding: 6px 0 6px 6px; text-align: left; }
.rpm-list-tbl .rpm-no { width: 46px; text-align: left; }
.rpm-list-tbl thead th.rpm-ops-h, .rpm-list-tbl tbody td.rpm-ops { text-align: left; }
.rpm-list-tbl thead th.rpm-ops-h { cursor: default; }
.rpm-list-tbl th:not([data-sortable]) { cursor: default; }
/* 报表名称 / 报表目录：蓝字可点（用户要求）；名称前一个黑色「数据」图标 */
.rpm-link { color: #1870be; cursor: pointer; }
.rpm-link:hover { color: #14619f; text-decoration: underline; }
.rpm-name-td .rpm-link { display: inline-flex; align-items: center; max-width: 100%; }
.rpm-name-td .rpm-link-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rpm-data-ic { flex: none; margin-right: 4px; }
/* 操作列 = 纯文字（用户要求「操作栏里改成文字不要图标」）：
   修改（**仅自己创建的**报表才有这一项，不是自己创建的直接不渲染）/ 关注·取消关注 / 按条件查询 / 更多 + rp-arrow */
.rpm-op { display: inline-block; color: #1870be; font-size: 12px; cursor: pointer; white-space: nowrap; }
.rpm-op + .rpm-op { margin-left: 8px; }
.rpm-op:hover { color: #14619f; text-decoration: underline; }
.rpm-row-more { display: inline-flex; align-items: center; }
.rpm-list-tbl tbody tr.on td { background: #eaf2fd; }
.rpm-empty-td { text-align: center; color: var(--text-faint); padding: 30px 0; }
.rpm-tip { font-size: 13px; color: var(--text); line-height: 1.7; }
/* 保存 / 导出基站维护区弹窗（2026-10-05）：文件名称（必填）+ 文件类型 + 编码 */
.rp-save-row { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.rp-save-row:last-child { margin-bottom: 2px; }
.rp-save-lbl { flex: none; width: 118px; text-align: right; font-size: 13px; color: var(--text); }
.rp-save-ipt, .rp-save-sel { flex: 1; min-width: 0; height: 30px; box-sizing: border-box; border: 1px solid var(--border-strong); border-radius: 2px; padding: 0 8px; font-size: 13px; color: var(--text); background: #fff; outline: none; }
.rp-save-ipt:focus, .rp-save-sel:focus { border-color: var(--accent); }
/* 必填星号（红）+ 必填未填的红框（比 :focus 高一级特异性，聚焦时仍是红框） */
.rp-save-req { font-style: normal; color: var(--critical); margin-right: 2px; }
.rp-save-ipt.is-err, .rp-save-ipt.is-err:focus { border-color: var(--critical); }
.rp-save-sel:disabled { background: #f5f6f8; color: #9aa7b5; }

/* ---- 报表类型选择弹窗（网元树弹窗复用 ttv-ne-box/ttv-count；RAN 向导表格） ---- */
.rpw-row { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text); margin: 2px 0 10px; }
.rpw-row select { height: 28px; min-width: 140px; border: 1px solid var(--border-strong); border-radius: 2px; padding: 0 6px; font-size: 13px; color: var(--text); background: #fff; outline: none; }
.rpw-row select:focus { border-color: var(--accent); }
/* 向导两步面板：弹窗高度固定（560px），面板各自撑满 modal-body，内部区块 flex 压缩/撑开 */
#rpw-p1, #rpw-p2 { display: flex; flex-direction: column; height: 100%; min-height: 0; }
#rpw-p1[hidden], #rpw-p2[hidden] { display: none; }
#rpw-p1 > *:not(.rpw-tbl-wrap), #rpw-p2 > *:not(.ttv-ne-box) { flex: none; }
#rpw-p2 .ttv-ne-box { flex: 1; min-height: 0; height: auto; }
/* 网元报表/网元统计报表弹窗（rpNeDlg）：工具条+筛选+树+计数 一列撑满，开关筛选只压缩树、弹窗高度不变 */
.rp-ne-pick { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.rp-ne-pick > *:not(.ttv-ne-box) { flex: none; }
.rp-ne-pick .ttv-ne-box { flex: 1; min-height: 150px; height: auto; }
/* ---- 报表查询进度弹窗（复用备份页 .bk-prog-row/.bk-bigprog，进度条上方左对齐文字）---- */
.rp-prog-txt { font-size: 12px; color: var(--text); margin-bottom: 6px; }
/* ---- 报表执行结果弹窗 ----
   表头可拖列宽：table-layout:fixed + th 显式宽（拖拽时由 JS 改写）+ separate(间距0)
   → th style.width 与渲染宽严格相等（collapse 会被 Chrome 内部再分配，拖一列其他列跟着漂）
   口径（2026-10-05 用户要求）：表格整体宽高都不变，拖动 = 相邻两列一增一减；
   内容不换行、超出部分「...」截断（口径同信令跟踪 .rst-tbl），拖列宽时行高/表高恒定；
   容器自身无边框，改为列间分隔线（首列左缘/末列右缘不要） */
.rp-res-wrap { max-height: 260px; overflow-y: auto; overflow-x: hidden; }   /* 只纵向滚动、无外框：表宽钉死=容器内容宽，不出横向滚动条（2026-10-05） */
.rp-res-tbl { width: 100%; table-layout: fixed; border-collapse: separate; border-spacing: 0; font-size: 13px; }
/* 列间分隔线：separate 不合并边框 → 每格右缘画 1px，末列去掉即得「列之间才有线、两边没有」 */
.rp-res-tbl th, .rp-res-tbl td { box-sizing: border-box; border-bottom: 1px solid var(--border); border-right: 1px solid var(--border); padding: 6px 10px; text-align: left; color: var(--text); white-space: nowrap; }
.rp-res-tbl th:last-child, .rp-res-tbl td:last-child { border-right: 0; }
.rp-res-tbl th { position: relative; }
.rp-res-tbl td { overflow: hidden; text-overflow: ellipsis; }
.rp-res-tbl thead th { position: sticky; top: 0; z-index: 1; background: #f7f8fa; font-weight: 600; border-bottom: 1px solid var(--border-strong); }
.rp-res-tbl tbody tr:hover { background: #f2f6fb; }
/* 拖宽手柄收进列内（默认 right:-4px 会伸出表格右缘 4px → 撑出 wrap 横向滚动条，2026-10-05） */
.rp-res-tbl .alm-col-resizer { right: 0; }
/* 执行结果表：成功/失败不着色，与其它单元格同为正文色；表头排序图标复用信令跟踪的 .tm-sort-ico */
.rp-res-lbl { margin: 14px 0 6px; font-size: 13px; color: var(--text); }
.rp-res-ta { width: 100%; height: 56px; box-sizing: border-box; resize: none; border: 1px solid var(--border-strong); border-radius: 3px; padding: 6px 8px; font-size: 12px; line-height: 1.5; color: var(--text); background: #fff; outline: none; }
.rpw-tbl-wrap { flex: 1; min-height: 0; overflow: auto; border: 1px solid var(--border); }
.rpw-tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.rpw-tbl th, .rpw-tbl td { border-bottom: 1px solid var(--border); padding: 6px 10px; text-align: left; color: var(--text); }
.rpw-tbl thead th { position: sticky; top: 0; z-index: 1; background: #f7f8fa; font-weight: 600; border-bottom: 1px solid var(--border-strong); }
.rpw-tbl thead th:first-child, .rpw-tbl tbody td:first-child { width: 36px; text-align: center; }
.rpw-tbl tbody tr:hover { background: #f2f6fb; }
.modal-foot .btn:disabled { opacity: .55; cursor: not-allowed; }

/* ============ 用户管理（公共 > 系统 > 用户管理，2026-10-06）============
   单块页面：一块 .panel 里放「工具条 + 列表 + 总计」。工具条左侧搜索、右侧操作按钮
   （.toolbar .spacer 把两侧撑开，与集中任务管理同套路）。 */
.um-toolbar { margin-bottom: 10px; }
.um-toolbar input[type=text] { width: 220px; }
.um-tbl-wrap { border: 1px solid var(--border); border-radius: 4px; overflow: auto; }
/* 状态徽标：启用（绿）/ 禁用（灰） */
.um-st-on  { background: var(--success-bg); color: var(--success); }
.um-st-off { background: var(--gray-soft); color: var(--text-faint); }
/* 操作列：三个内联 SVG 图标按钮（禁用·启用 / 删除 / 修改密码） */
.um-op-th, .um-op-cell { width: 92px; }
.um-op-cell { white-space: nowrap; }
.um-op-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; margin-right: 4px; border-radius: 3px;
  color: var(--text-dim); cursor: pointer; vertical-align: middle;
}
.um-op-btn:hover { background: var(--hover); color: var(--accent); }
.um-op-btn.danger:hover { background: var(--critical-bg); color: var(--critical); }
.um-empty { text-align: center !important; color: var(--text-faint) !important; padding: 22px 0 !important; }
.um-foot { margin-top: 10px; font-size: 12px; color: var(--text-dim); }
/* 弹窗表单：必填星号 + 校验错误行 */
.um-form { grid-template-columns: 1fr 1fr; }
.um-req { color: var(--critical); font-style: normal; margin-left: 2px; }
.um-err { color: var(--critical); font-size: 12px; min-height: 16px; }
.um-pwd-who { font-size: 13px; color: var(--text); }

/* ================= SON > LTE ANR / NR ANR（js/anr.js，2026-10-09） =================
   骨架复用「报表管理」的 rp-* / rpm-* 体系：左菜单（无搜索框）+ 左右拖动 + 右上/右下（上下可拖）。
   左右宽度与右下高度用**独立变量** --anr-left-w / --anr-bot-h（与报表页、报表管理互不干扰）。
   ⚠ 注释里绝不能出现「星号紧跟斜杠」的连写（例如把 rp-* 与 /rpm-* 写在一起）—— 那个符号对
     会**提前闭合注释**，让紧随其后的 :root 被并进一条非法选择器而整条被浏览器丢弃
     （2026-10-09 线上踩坑：--anr-left-w 读不到 → 左栏/右下退化成 auto，刷新后偏窄，
     双击分割条写了内联值才「恢复」）。守卫见 tools/_test_anr.js【8】与 tools/_probe_anr.js【2】。 */
:root { --anr-left-w: 220px; --anr-bot-h: 200px; }
.anr-body { grid-template-columns: var(--anr-left-w) 8px 1fr; }
/* 下内边距 0 已提到全局 .rp-content（2026-10-09，报表页/报表管理/ANR 三页统一），此处不再单独覆盖 */
/* 上区：白底表格块内部再分「列表（可滚）+ rp-list-foot」，所以自己接管 flex（覆盖 .rp-pane 的 overflow:auto） */
/* 上区：白底表格块内部再分「列表（可滚）+ rp-list-foot」，所以自己接管 flex（覆盖 .rp-pane 的 overflow:auto）；
   position:relative = 刷新时那块「遮罩 + 转圈」的定位父级（口径同 .rp-pane.rp-has-list，见下面 .anr-loading-mask） */
.anr-view .anr-top-pane { flex: 1; display: flex; flex-direction: column; overflow: hidden; position: relative; }
/* 下区：白底「操作信息」；内嵌一块灰边框日志区（绿色文字 #548657） */
.anr-view .anr-bot-pane { flex: none; height: var(--anr-bot-h); display: flex; flex-direction: column; overflow: hidden; }
.anr-view .mml-grip.h-grip { flex: none; }
.anr-bot-head { flex: none; display: flex; align-items: center; justify-content: space-between; padding: 8px 12px; }
.anr-bot-title { font-size: 13px; font-weight: 600; color: var(--text); }
.anr-log-box { flex: 1; min-height: 0; overflow: auto; margin: 0 12px 12px; padding: 6px 10px; background: #fff; border: 1px solid var(--border-strong, #dfe3e8); border-radius: 2px; }
.anr-log-line { font-size: 12.5px; line-height: 1.9; color: #548657; white-space: pre-wrap; word-break: break-all; }
.anr-log-empty { font-size: 12.5px; color: var(--text-faint); }
/* 左菜单：分组行（父项）名称 + 右缘箭头（.rp-item .rp-arrow 自带 margin-left:auto 与翻转） */
.anr-group-name { overflow: hidden; text-overflow: ellipsis; }
/* 列表：与「Evaluation 的报表管理」同一口径（2026-10-09 用户要求「跟已有样式来」）——
   table-layout:fixed + 表头右缘 1px 竖分割线（.alm-col-resizer 手柄压在这条线上，可拖动改列宽）；
   列宽默认值写在 js/anr.js 的 ANR_COLS（每列 w），拖过的宽度记进 st.colW/st.tblW 并在重画后保留。
   16 列默认合计 > 右栏宽 → 横向滚动条出在 .rp-list-wrap 里（fixed 布局下「表宽=Σ列宽」自动生效）。 */
.anr-list-tbl { width: 100%; font-size: 12px; }
.anr-list-tbl thead th::after { content: ''; position: absolute; right: 0; top: 22%; height: 56%; width: 1px; background: var(--border-strong); }
/* 过滤贴边面板（复用当前告警的 .alm-filter-panel / .ff-* 全套）：选择网元的红星必填标记 */
.anr-req { color: var(--critical); margin-right: 2px; }
.anr-ne-ipt { cursor: pointer; }
/* 层级：本页过滤面板**不配自己的遮罩**（用户 2026-10-09：面板出来不压暗），
   但面板里弹的「选择网元」等弹窗，其遮罩必须盖住面板 —— 默认分层是
   .modal-mask 44 < .alm-filter-panel 45，遮罩盖不住（用户报障「目前没遮住」）。
   办法：弹窗开着时把本页面板压到 43（弹窗本体 .modal-float 是 46，仍在最上）。
   用 body:has(.modal-float) 判定「此刻有弹窗」，无弹窗时面板仍是 45，一切照旧。
   ⚠ 只认 #anr-filter-panel：告警 / 告警历史 / 操作日志三页的面板各自配 44 的遮罩
     （它们的遮罩要**在面板之下**接住点击关闭），分层绝不能一起动。 */
body:has(.modal-float) #anr-filter-panel { z-index: 43; }
/* 空态（未选菜单 / 该菜单还没数据）：插画 + 「暂无数据」，表格内与空白区各一种居中方式 */
.anr-empty { padding: 6px 0 10px; }
.anr-empty-wrap { height: 100%; display: flex; align-items: center; justify-content: center; }

/* ---------- 查询进度条（2026-10-10 用户要求）----------
   位置：「查询」按钮右边紧挨着；只在**点过滤面板「确定」发起查询**时出现（翻页/排序是静默重查，不闪它）。
   外观：底 #e4e4e4、进度色 #62c8b0、高 8px、两头圆；右边百分比数字；再右边一枚
   #1870be 的「停止」按钮——空心圆环里套一个同色实心正方形（环与方块都由 svg 画，
   stroke/fill 都用 currentColor → 只改这里的 color 就能整枚换色）。
   ★ 进度是**假加载**（js/anr.js：0.3s 冲到 98%，再用 1.7s 缓缓到 100%，最短停留约 2.3s），
     口径与 RAN 的 NR小区报表一致。
   零过渡（本页既定规则：显隐只切 [hidden]）。 */
.anr-prog { display: inline-flex; align-items: center; gap: 8px; margin-left: 4px; }
.anr-prog[hidden] { display: none; }
.anr-prog-bar { width: 160px; height: 8px; border-radius: 4px; background: #e4e4e4; overflow: hidden; }
.anr-prog-fill { display: block; height: 100%; width: 0; border-radius: 4px; background: #62c8b0; }
.anr-prog-txt { min-width: 36px; text-align: right; font-size: 12px; color: var(--text); font-variant-numeric: tabular-nums; }
.anr-prog-stop {
  width: 18px; height: 18px; flex: none; padding: 0; border: none; border-radius: 50%;
  background: transparent; color: #1870be; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.anr-prog-stop:hover { color: #1259a0; }
.anr-prog-stop svg { display: block; }
/* ---------- 刷新的「遮罩 + 转圈」（2026-10-10 用户要求）----------
   点「刷新」**不出进度条**，走「信令跟踪管理」点刷新那条路：列表区（#anr-top-pane = .rp-list-wrap
   表格 + rp-list-foot）盖半透明遮罩 + 居中白底加载框（转圈 + 正在加载）。
   白框/转圈直接复用跟踪页的 .tt-loading-box / .tt-loading-spin（不另造一套外观），
   本页只登记遮罩自己这一类 + 定位父级（.anr-view .anr-top-pane 已 position:relative）。
   ★ 遮罩挂在**上区**（不是挂在 .rp-list-wrap 里）：.rp-list-wrap 自己是滚动容器，
     绝对定位的子元素会跟着内容滚走（滚到下面时遮罩就跑出视口了）。
   显隐同样零过渡：只切 .show。 */
.anr-loading-mask {
  position: absolute; inset: 0; z-index: 20; display: none;
  align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.35);
}
.anr-loading-mask.show { display: flex; }
/* ---------- 「接受 / 拒绝」按钮组（2026-10-10 用户要求，只出现在「优化建议」菜单）----------
   两枚按钮做成一组（.anr-opt-btns 包着），组内横向排 8px 间隔（与工具条其余按钮间隔一致）；
   组本身是**整组显隐**（切到非优化建议菜单 → [hidden]，零过渡）——所以必须显式写 [hidden]:display:none，
   否则 .anr-opt-btns 的 inline-flex 会盖掉浏览器对 [hidden] 的默认 display:none。
   两枚按钮带 rp-arrow rpm-more-arrow（箭头外壳，靠 .rpm-more .rp-arrow 那条规则撑开）；
   ★ 2026-10-12 用户口径：按钮**放开**（不再 disabled/.is-disabled）——各自套一个 .rpm-more-wrap
     ＋ .rpm-more-box 下拉（「…已选」「…全部」），下拉外观直接复用工具条「导出」那套（无需本页新样式）。 */
.anr-opt-btns { display: inline-flex; align-items: center; gap: 8px; }
.anr-opt-btns[hidden] { display: none; }
/* ---------- 「越区核查」开关（2026-10-10 用户要求，只在 NR ANR 的「优化建议」，排在「刷新」右边）----------
   底色 = **进度条同色 #62c8b0**（与 .anr-prog-fill 同一个色值，改色两边一起改）；
   白点常驻右侧 = 默认打开；轨道 34×16 圆角 8px，与全站开关（.tt-switch / .alm-switch-track）同一规格。
   ★ 置灰不让关：常驻 .is-locked → cursor:not-allowed + 整体略降不透明度（读作「不可操作」），
     但**底色仍是 #62c8b0**（不给 grayscale，否则就不是「和进度条一样」了）；点了不翻转状态。
   显隐零过渡：只切 [hidden]，所以要显式写 [hidden]{display:none}（同 .anr-opt-btns）。 */
.anr-ovs { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-dim); user-select: none; }
.anr-ovs[hidden] { display: none; }
.anr-ovs-track { width: 34px; height: 16px; border-radius: 8px; background: #c9ced6; position: relative; flex: none; }
.anr-ovs-track::after { content: ''; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 50%; background: #fff; }
.anr-ovs-track.on { background: #62c8b0; }
.anr-ovs-track.on::after { left: 20px; }
.anr-ovs.is-locked { cursor: not-allowed; opacity: .85; }
.anr-ovs.is-locked .anr-ovs-lbl { color: var(--text-faint); }
/* 查询进行中：查询 / 导出 / 刷新 三枚按钮置灰（口径同本项目其它页：灰底灰字 + not-allowed） */
.anr-view .rp-toolbar .btn:disabled, .anr-view .rp-toolbar .btn.is-disabled {
  background: #f5f6f8; border-color: #e0e3e8; color: #b9bec7; cursor: not-allowed;
}
/* 表体首列 = 勾选列（「导出已选」的依据）：窄、居中、不画右缘竖分割线、不参与排序/列宽拖动 */
.anr-list-tbl thead th.anr-ck-th, .anr-list-tbl tbody td.anr-ck-td { width: 38px; text-align: center; padding-left: 0; padding-right: 0; }
.anr-list-tbl thead th.anr-ck-th { cursor: default; }
.anr-list-tbl thead th.anr-ck-th::after { display: none; }
.anr-list-tbl .anr-ck-th input, .anr-list-tbl .anr-ck-td input { accent-color: var(--accent); margin: 0; vertical-align: middle; cursor: pointer; }
/* 下拉里的「…已选」项（导出已选 / 接受已选 / 拒绝已选）在**没勾选任何行**时置灰
   （2026-10-10 用户要求导出那项；2026-10-12 扩到接受 / 拒绝） */
.rpm-more-item.is-disabled, .rpm-more-item.is-disabled:hover { color: #b9bec7; background: transparent; cursor: not-allowed; }

/* ================= 报表管理：创建页（点「创建」盖住整个 ph-rpMgr，2026-10-12） ================= */
/* .rpm-view 本身 relative（3436 行），绝对定位覆盖件挂它里面就正好盖满整个页面区域 */
.rpm-create { position: absolute; inset: 0; z-index: 40; background: var(--bg); display: flex; flex-direction: column; min-height: 0; }
.rpmc-top { flex: none; height: 46px; display: flex; align-items: center; gap: 10px; padding: 0 16px; background: #fff; border-bottom: 1px solid var(--border); }
.rpmc-back { border: 0; background: none; padding: 4px; margin-left: -6px; cursor: pointer; color: var(--text); display: inline-flex; align-items: center; }
.rpmc-back:hover { color: #1870be; }
.rpmc-title { font-size: 14px; font-weight: 600; color: var(--text); }
.rpmc-top-sp { flex: 1; }
.rpmc-top .btn { min-width: 64px; }
.rpmc-top .rpmc-save { background: #1870be; border-color: #1870be; color: #fff; }
.rpmc-top .rpmc-save:hover { background: #1668ae; border-color: #1668ae; color: #fff; }
/* 外层（页签 + 三张卡片）**不出滑动条**：body 锁 overflow:hidden，多余高度全给最后一张（图形）卡片，
   高度不够时由「表格区」「图形占位区」各自内部滚（用户 2026-10-12 口径） */
.rpmc-body { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; padding: 0 16px 16px; }
.rpmc-tabs { display: flex; align-items: flex-end; background: #fff; border-bottom: 1px solid var(--border); padding: 0 10px; margin: 0 -16px; }
.rpmc-tab { padding: 9px 14px 7px; font-size: 13px; color: var(--text-dim); cursor: pointer; border-bottom: 2px solid transparent; user-select: none; }
.rpmc-tab.on { color: #1870be; border-bottom-color: #1870be; }
.rpmc-tabplus { border: 0; background: none; color: var(--text-dim); font-size: 14px; cursor: pointer; padding: 6px 10px; }
.rpmc-tabplus:hover { color: #1870be; }
.rpmc-card { flex: none; background: #fff; border: 1px solid var(--border); border-radius: 4px; margin-top: 12px; padding: 12px 16px 14px; }
/* 表格卡片：正常按内容高；空间紧时先压缩这里，表格自己内部滚（不推 body） */
.rpmc-card-tbl { flex: 0 1 auto; min-height: 108px; display: flex; flex-direction: column; }
.rpmc-tbl-wrap { flex: 1; min-height: 0; overflow: auto; }
/* 图形卡片：吃掉剩余高度；占位区再不够就自己内部滚 */
.rpmc-grow { flex: 1 1 auto; min-height: 96px; display: flex; flex-direction: column; }
.rpmc-sec-h { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--text); cursor: pointer; user-select: none; }
.rpmc-chev { color: var(--text-dim); transition: transform .15s; }
.rpmc-card.fold .rpmc-chev { transform: rotate(-90deg); }
.rpmc-card.fold .rpmc-foldable { display: none; }
.rpmc-fields { display: flex; flex-wrap: wrap; gap: 12px 30px; padding: 14px 0 4px; }
.rpmc-f { display: inline-flex; align-items: center; gap: 8px; }
.rpmc-fl { font-size: 12px; color: var(--text-dim); white-space: nowrap; }
.rpmc-f select { height: 28px; min-width: 150px; border: 1px solid var(--border-strong); border-radius: 3px; background: #fff; font-size: 12px; color: var(--text); padding: 0 6px; }
.rpmc-f select.rpmc-ph { color: var(--text-faint); }
/* 置灰不可操作的两个固定值字段（2026-10-12）：Benchmark规则=下拉锁定「无」，报表样式=与对象类型同款框体但不可点 */
.rpmc-f select:disabled { background: #f5f6f8; color: var(--text-dim); cursor: default; }
.rpmc-ot-wrap.is-dis, .rpmc-ot-wrap.is-dis:hover { border-color: var(--border-strong); background: #f5f6f8; cursor: default; }
.rpmc-ot-wrap.is-dis .rpmc-ot-ipt, .rpmc-ot-wrap.is-dis .rpmc-ot-ipt:disabled { color: var(--text-dim); cursor: default; }
.rpmc-ot-wrap.is-dis .rpmc-ot-more, .rpmc-ot-wrap.is-dis:hover .rpmc-ot-more { color: var(--text-dim); }   /* 置灰框里的 ··· 也不变蓝 */
/* 网元类型：自绘下拉（触发框 + 华为分组，组行 = 方框 −/＋ 展开收起） */
.rpmc-dd { position: relative; display: inline-flex; }
.rpmc-dd-btn { display: inline-flex; align-items: center; gap: 8px; min-width: 150px; height: 28px; padding: 0 8px; border: 1px solid var(--border-strong); border-radius: 3px; background: #fff; font-size: 12px; color: var(--text); cursor: pointer; }
.rpmc-dd-btn:hover { border-color: #1870be; }
.rpmc-dd-car { margin-left: auto; color: var(--text-dim); transition: transform .15s; }
.rpmc-dd-btn.open .rpmc-dd-car { transform: rotate(180deg); }
.rpmc-dd-box { position: absolute; top: 30px; left: 0; z-index: 6; min-width: 150px; padding: 4px 0 6px; background: #fff; border: 1px solid var(--border); border-radius: 3px; box-shadow: 0 4px 14px rgba(0,0,0,.12); }
.rpmc-dd-box[hidden], .rpmc-dd-list[hidden] { display: none; }
.rpmc-dd-grp { display: flex; align-items: center; gap: 6px; padding: 3px 8px 6px; font-size: 12px; color: var(--text-dim); }
.rpmc-dd-item { display: block; padding: 5px 12px 5px 34px; font-size: 12px; color: var(--text); cursor: pointer; white-space: nowrap; }
.rpmc-dd-item:hover { background: #f2f7fd; color: #1870be; }
.rpmc-dd-item.on { background: #eaf3fc; color: #1870be; font-weight: 600; }
/* 对象类型：只读输入框 + ··· 合成一个框（融为一体，无间隙；点整框弹窗） */
.rpmc-ot-wrap { display: inline-flex; align-items: center; min-width: 150px; height: 28px; border: 1px solid var(--border-strong); border-radius: 3px; background: #fff; cursor: pointer; }
.rpmc-ot-wrap:hover { border-color: #1870be; }
.rpmc-ot-ipt { flex: 1; min-width: 0; width: 116px; height: 26px; border: 0; background: none; padding: 0 4px 0 8px; font-size: 12px; color: var(--text); cursor: pointer; }
.rpmc-ot-ipt:focus { outline: none; }
.rpmc-ot-more { flex: none; padding: 0 8px 0 2px; font-size: 12px; color: var(--text-dim); letter-spacing: 1px; }
.rpmc-ot-wrap:hover .rpmc-ot-more { color: #1870be; }
.rpmc-cfg { display: flex; align-items: center; gap: 10px; padding: 12px 0 2px; }
.rpmc-cfg-btn { display: inline-flex; align-items: center; gap: 16px; height: 30px; padding: 0 12px; border: 1px solid var(--border-strong); border-radius: 3px; background: #fff; font-size: 12px; color: var(--text); cursor: pointer; }
.rpmc-cfg-btn:hover { border-color: #1870be; color: #1870be; }
.rpmc-cfg-ar { color: var(--text-faint); display: inline-flex; }
.rpmc-cfg-btn:hover .rpmc-cfg-ar { color: #1870be; }
/* 该步「有已选内容」的完成态（2026-10-15 用户口径）：右侧箭头换成 √、外边框变 #1870be；
   文字仍是正文色（与 hover 的整枚变蓝区分开）；hover 不受影响（本来就同色） */
.rpmc-cfg-btn.is-done { border-color: #1870be; }
.rpmc-cfg-btn.is-done .rpmc-cfg-ar { color: #1870be; }
.rpmc-cfg-link { border: 0; background: none; color: #1870be; font-size: 12px; cursor: pointer; padding: 0 4px; }
.rpmc-cfg-link:hover { text-decoration: underline; }
/* 置灰（2026-10-19 用户口径：「选择对象属性」先灰着 —— 功能未接入，点了不响应、也不弹「待接入」窗） */
.rpmc-cfg-link.is-off, .rpmc-cfg-link.is-off:hover { color: var(--text-faint); cursor: not-allowed; text-decoration: none; }
.rpmc-panel-h { display: flex; align-items: center; margin-bottom: 10px; }
.rpmc-panel-t { font-size: 13px; font-weight: 600; color: var(--text); }
.rpmc-panel-ops { margin-left: auto; display: flex; align-items: center; gap: 14px; }
.rpmc-op { display: inline-flex; align-items: center; gap: 5px; border: 0; background: none; color: var(--text-dim); font-size: 12px; cursor: pointer; padding: 0; }
.rpmc-op:hover { color: #1870be; }
/* 2026-10-19：过滤设置功能未接入 → 去掉图标 + 整枚置灰（点了不响应） */
.rpmc-op.is-off, .rpmc-op.is-off:hover { color: var(--text-faint); cursor: not-allowed; }
/* 开关类按钮（过滤规则设置 / TopN分析）：整枚按钮含图标+文字都是开关本体 */
.rpmc-op-ic { display: inline-flex; align-items: center; cursor: pointer; }
.rpmc-op-ic:hover { color: #1870be; }
.rpmc-sw { width: 32px; height: 16px; border-radius: 8px; background: #c9ced6; position: relative; cursor: pointer; flex: none; }
.rpmc-sw::after { content: ''; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 50%; background: #fff; transition: left .15s; }
.rpmc-sw.on { background: #1870be; }
.rpmc-sw.on::after { left: 18px; }
.rpmc-sw-row { display: inline-flex; align-items: center; }
/* 创建页空表：只有横向分割线、表头不加粗（项目口径） */
.rpmc-tbl { width: 100%; border-collapse: collapse; table-layout: fixed; font-size: 12px; }
.rpmc-tbl th, .rpmc-tbl td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--border); color: var(--text); font-weight: normal; }
.rpmc-tbl thead th { color: var(--text-dim); }
.rpmc-tbl tbody tr:last-child td { border-bottom: 0; }
.rpmc-lay-lbl { font-size: 12px; color: var(--text-dim); }
.rpmc-lays { display: inline-flex; gap: 5px; }
.rpmc-lay { width: 24px; height: 21px; border: 1px solid var(--border-strong); border-radius: 3px; background: #fff; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; color: var(--text-dim); padding: 0; }
.rpmc-lay.on { border-color: #1870be; color: #1870be; background: #eaf3fc; }
.rpmc-chart-bar { display: flex; align-items: center; gap: 8px; padding: 4px 0 10px; }
.rpmc-chart-bar select { height: 26px; border: 1px solid var(--border-strong); border-radius: 3px; background: #fff; font-size: 12px; color: var(--text); padding: 0 6px; }
.rpmc-chart-empty { flex: 1; min-height: 0; overflow: auto; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 24px 0 28px; }
.rpmc-chart-tip { margin-top: 8px; font-size: 12px; color: var(--text-faint); }

/* 对象类型弹窗（居中）：排序按钮组（无圆角、彼此不隔开、选中的 #1870be）+ 关键字框 + 4 列可选列表（y 可滚） */
.rpmc-ot-bar { display: flex; margin-bottom: 10px; }
.rpmc-ot-sort { height: 28px; padding: 0 12px; border: 1px solid var(--border-strong); border-radius: 0; background: transparent; color: var(--text); font-size: 12px; cursor: pointer; display: inline-flex; align-items: center; gap: 4px; }
.rpmc-ot-sort + .rpmc-ot-sort { border-left: 0; }
.rpmc-ot-sort:hover { color: #1870be; }
.rpmc-ot-sort.on, .rpmc-ot-sort.on:hover { background: #1870be; border-color: #1870be; color: #fff; }
.rpmc-ot-ar { display: inline-flex; width: 9px; height: 9px; flex: none; align-items: center; }
.rpmc-ot-ar:empty { display: none; }   /* 箭头只挂在选中的按钮上，未选中按钮不留空位 */
.rpmc-ot-search { position: relative; margin-bottom: 10px; }
.rpmc-ot-search input { width: 100%; height: 30px; border: 1px solid var(--border-strong); border-radius: 3px; padding: 0 32px 0 8px; font-size: 12px; color: var(--text); }
.rpmc-ot-search input:focus { outline: none; border-color: #1870be; }
.rpmc-ot-lens { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); display: inline-flex; width: 16px; height: 16px; color: var(--text-dim); pointer-events: none; }
.rpmc-ot-lens svg { width: 16px; height: 16px; }
/* 高度写死 300px（不是 max-height）：关键字过滤后无论剩几项，弹窗高度都保持不变（2026-10-12 用户口径）。
   grid-auto-rows:max-content 必须有——item 自带 overflow:hidden（最小高度归 0），
   否则 Chrome 会把 auto 行压缩到 ~16px 硬塞进固定 300px（行高被挤、文字竖向裁掉）。 */
.rpmc-ot-grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: max-content; height: 300px; overflow-y: auto; align-content: start; padding: 4px; border: 1px solid var(--border); border-radius: 3px; }
.rpmc-ot-item { padding: 8px 10px; font-size: 12px; color: var(--text); cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border-radius: 2px; }
.rpmc-ot-item:hover:not(.on) { background: #f2f7fd; }
.rpmc-ot-item.on { background: #1870be; color: #fff; }
.rpmc-ot-none { grid-column: 1 / -1; padding: 8px 10px; font-size: 12px; color: var(--muted, #8a8a8a); }
.modal-float .rpmc-ot-ok { background: #1870be; border-color: #1870be; color: #fff; }
.modal-float .rpmc-ot-ok:hover { background: #1668ae; border-color: #1668ae; color: #fff; }

/* ================= 配置项弹窗（选择对象/指标/时间 三步向导，2026-10-12；2026-10-13 二改） =================
   尺寸恒定 + 整窗不出滑动条（用户口径：「配置项弹窗整体不要出现滑动条」「三步切换的时候，弹窗大小不要改变」）：
     · .modal.rpmcf-modal 写死高度 → 三步切换弹窗大小一模一样（86vh 兜小屏）；
     · .modal-body.rpmcf-host 改成 flex 纵向 + overflow:hidden → 整个弹窗没有滑动条；
     · 该滚的只有 .rpmcf-tree / .rpmcf-seltbl（xy 都允许，内容超了在内部滚）。 */
.modal.rpmcf-modal { height: 600px; max-height: 86vh; }
/* body 必须 flex:1 撑满剩余高度：否则 .modal 的纵向 flex 把 body 按内容高（0 1 auto）排版，
   footer 就紧贴内容底部 → 三步内容高矮不同，footer 跟着忽上忽下（2026-10-13 用户报）。
   撑满后内容不足也只是 body 内留白，footer 恒定贴弹窗底。 */
.rpmcf-modal .modal-body.rpmcf-host { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.rpmcf { flex: 1; min-height: 0; display: flex; flex-direction: column; font-size: 12px; color: var(--text); position: relative; }
/* 步条：箭头绶带（当前步蓝底；第 1 步左端无豁口） */
/* 步条：箭头绶带。★外框不能靠 border 画：绶带是 clip-path 斜切的，矩形 border 会被斜切掉
   （只剩上下两条+右边一点点，2026-10-13 用户报的问题）。改两层叠出「贴着形状的一圈等宽描边」：
     · 父层 .rpmcf-step 背景 = 描边色（var(--border) / 选中态 #1870be），整体按绶带裁剪；
     · ::after 内缩 1px 再按绶带裁剪、填白色 → 露出的 1px 父层就是描边。
   ::after 是定位元素（盖在文字上），所以文字 .rpmcf-st 和图标 svg 都要抬到 z-index:1。 */
.rpmcf-steps { flex: none; display: flex; padding: 2px 0 12px; }
.rpmcf-step { position: relative; flex: none; width: 214px; height: 30px; display: inline-flex; align-items: center; gap: 8px; padding: 0 26px 0 30px; background: var(--border); color: var(--text-dim); cursor: pointer; user-select: none; clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 50%, calc(100% - 12px) 100%, 0 100%, 12px 50%); }
.rpmcf-step::after { content: ''; position: absolute; inset: 1px; background: #fff; clip-path: polygon(0 0, calc(100% - 11px) 0, 100% 50%, calc(100% - 11px) 100%, 0 100%, 11px 50%); }
.rpmcf-step.first { clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 50%, calc(100% - 12px) 100%, 0 100%); padding-left: 16px; }
.rpmcf-step.first::after { clip-path: polygon(0 0, calc(100% - 11px) 0, 100% 50%, calc(100% - 11px) 100%, 0 100%); }
.rpmcf-step .rpmcf-st { position: relative; z-index: 1; }
.rpmcf-step > svg { position: relative; z-index: 1; margin-left: auto; }
.rpmcf-step:hover { color: #1870be; }
.rpmcf-step.on { background: #1870be; color: #fff; }
.rpmcf-step.on::after { display: none; }              /* 当前步整块蓝底，不需要填充层 */
/* 有已选内容 = 贴着绶带形状的蓝色外框（父层蓝底 + 白色填充层 = 1px 蓝环） */
.rpmcf-steps .rpmcf-step.has-sel { background: #1870be; color: #1870be; }
.rpmcf-steps .rpmcf-step.has-sel.on { background: #1870be; color: #fff; }
/* 第 1 步页签 */
.rpmcf-tabs { flex: none; display: flex; gap: 20px; border-bottom: 1px solid var(--border); }
.rpmcf-tab { padding: 4px 2px 7px; cursor: pointer; color: var(--text-dim); border-bottom: 2px solid transparent; }
.rpmcf-tab:hover { color: #1870be; }
.rpmcf-tab.on { color: #1870be; border-bottom-color: #1870be; }
/* 置灰页签（2026-10-15：「按自定义视图」全程置灰，点了不响应）—— 与项目其它置灰同口径（#b9bec7 + not-allowed） */
.rpmcf-tab.is-dis, .rpmcf-tab.is-dis:hover { color: #b9bec7; cursor: not-allowed; }
/* 双栏 + 中间搬移钮 */
.rpmcf-main { flex: 1; min-height: 0; display: flex; gap: 10px; padding: 10px 0 0; }
.rpmcf-pane { flex: 1; min-width: 0; border: 1px solid var(--border); border-radius: 3px; background: #fff; display: flex; flex-direction: column; }
.rpmcf-pane-h { flex: none; display: flex; align-items: center; gap: 8px; padding: 7px 10px; font-size: 12px; color: var(--text); border-bottom: 1px solid var(--border); }
/* 左栏标题右侧的「保存为对象组」图标钮（2026-10-13）：贴右缘、无边框，hover 才显底色 */
.rpmcf-savegrp { margin-left: auto; flex: none; width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 3px; background: transparent; color: #6b7d92; cursor: pointer; }
.rpmcf-savegrp:not(:disabled):hover { color: #1870be; background: #eef3fa; }
/* 「已选」为空 → 置灰（保存的是已选内容，没得存） */
.rpmcf-savegrp:disabled { color: #c4ccd6; cursor: not-allowed; }
/* 保存为对象组弹窗：描述多行框（复用 .rp-save-* 那套表单控件，只补多行形态） */
.rp-save-row.rpm-sg-descrow { align-items: flex-start; }
.rp-save-area { flex: 1; min-width: 0; box-sizing: border-box; border: 1px solid var(--border-strong); border-radius: 2px; padding: 6px 8px; font-size: 13px; line-height: 1.5; color: var(--text); background: #fff; outline: none; resize: vertical; }
.rp-save-area:focus { border-color: var(--accent); }
.rpmcf-tools { flex: none; display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-bottom: 1px solid var(--border); }
.rpmcf-tbtn { min-width: 20px; height: 20px; padding: 0 3px; border: 1px solid var(--border); border-radius: 3px; background: #fff; color: var(--text-dim); font-size: 12px; line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.rpmcf-tbtn:hover { border-color: #1870be; color: #1870be; }
.rpmcf-sp { flex: 1; }
.rpmcf-cklb { display: inline-flex; align-items: center; gap: 5px; color: var(--text-dim); cursor: pointer; }
.rpmcf-typebar { flex: none; display: flex; gap: 6px; padding: 6px 8px; border-bottom: 1px solid var(--border); align-items: center; }
.rpmcf-typebar1 { justify-content: flex-end; }
.rpmcf-sel { height: 26px; border: 1px solid var(--border-strong); border-radius: 3px; background: #fff; font-size: 12px; color: var(--text); padding: 0 4px; }
/* 宽度 230 只管宽；颜色分开：真下拉（相对时间的日期范围）正文色，
   占位框（绝对时间的「日期范围」假下拉）才灰 —— 灰给到 .rpmcf-phsel，
   之前颜色挂在 .rpmcf-sel-wide 上把相对时间下拉里「今天/昨天/…」全染灰了（2026-10-13 用户报）。 */
.rpmcf-sel-wide { width: 230px; }
.rpmcf-phsel { color: var(--text-faint); }
/* 「自定义」disabled 的灰：收起态浏览器自动灰，展开列表里显式兜一层 */
.rpmcf-sel option:disabled { color: var(--text-faint); }
.rpmcf-kwwrap { flex: 1; min-width: 0; position: relative; display: flex; }
.rpmcf-kw { flex: 1; min-width: 0; width: 100%; height: 26px; border: 1px solid var(--border-strong); border-radius: 3px; padding: 0 26px 0 8px; font-size: 12px; color: var(--text); }
.rpmcf-kw:focus { outline: none; border-color: #1870be; }
.rpmcf-lens { position: absolute; right: 7px; top: 50%; transform: translateY(-50%); display: inline-flex; color: var(--text-dim); pointer-events: none; }
.rpmcf-tree { flex: 1; min-height: 0; overflow: auto; padding: 4px 0 6px; }
/* 树种行：**不省略号收尾**（2026-10-13 七改，用户口径）—— 行宽按内容撑开（max-content），
   超宽交给 .rpmcf-tree 的横向滚动条（xy 双向都可滚，回读用户早先的「xy 都要滑动条」）。 */
.rpmcf-node { display: flex; align-items: center; gap: 5px; height: 27px; padding-right: 10px; font-size: 12px; cursor: pointer; user-select: none; white-space: nowrap; width: max-content; min-width: 100%; box-sizing: border-box; }
.rpmcf-node:hover { background: #f2f6fb; }
.rpmcf-node[data-key] { cursor: pointer; }
/* 树里没有选框（2026-10-13）：点行 = 选中高亮；已在已选里的小区图标是绿实心圆 + √（ICON_CF_OKC） */
.rpmcf-node.on { background: #e6f0fb; }
.rpmcf-node.on:hover { background: #dbeaf9; }
.rpmcf-grp { cursor: default; }
.rpmcf-grp:hover { background: transparent; }
/* 叶/入口行的缩进占位：没有方框也要跟分组行的方框对齐 */
.rpmcf-nosq { width: 18px; height: 18px; flex: none; }
.rpmcf-node .rpm-sq { width: 18px; height: 18px; font-size: 12px; flex: none; }
.rpmcf-node input[type="checkbox"] { flex: none; margin: 0; }
.rpmcf-ico { display: inline-flex; color: #8fa3bc; flex: none; }
/* 行尾名字不参与压缩（flex:none）→ 名字多长行就多宽，整行横向滚动 */
.rpmcf-node > span:last-child { flex: none; }
.rpmcf-tip { padding: 30px 0; text-align: center; color: var(--text-faint); }
/* 中间搬移按钮列 */
.rpmcf-mid { flex: none; width: 46px; display: flex; flex-direction: column; justify-content: center; gap: 10px; }
.rpmcf-mv { height: 30px; border: 1px solid #b9c6d6; border-radius: 3px; background: #fff; color: var(--text); font-size: 13px; cursor: pointer; }
.rpmcf-mv:hover { border-color: #1870be; color: #1870be; }
/* 已选栏 */
.rpmcf-selbar { flex: none; display: flex; align-items: center; gap: 10px; padding: 6px 8px; border-bottom: 1px solid var(--border); }
.rpmcf-lnk { color: #1870be; cursor: pointer; white-space: nowrap; }
.rpmcf-lnk:hover { text-decoration: underline; }
/* 置灰态（已选为空时的「导出」）：不变色、不下划线、点了没反应 */
.rpmcf-lnk.is-off, .rpmcf-lnk.is-off:hover { color: var(--text-faint); cursor: not-allowed; text-decoration: none; }
.rpmcf-seltbl { flex: 1; min-height: 0; overflow: auto; }
.rpmcf-thead { display: flex; align-items: center; gap: 8px; padding: 6px 10px; color: var(--text-dim); border-bottom: 1px solid var(--border); position: sticky; top: 0; background: #fff; }
.rpmcf-thead span:first-of-type { flex: 1; }
/* 三列表（第 2 步「已选指标」：勾选占位 / KPI名称 / 别名）—— 表头与数据行同宽口径 */
.rpmcf-thead3 span:first-of-type { flex: none; width: 13px; }
.rpmcf-thead3 span:nth-of-type(2) { flex: 1.6; }
.rpmcf-thead3 span:nth-of-type(3) { flex: 1; }
.rpmcf-ckph { width: 13px; flex: none; }
.rpmcf-thead .rpmcf-pall { flex: none; }
.rpmcf-trow { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-bottom: 1px solid var(--border); }
/* 已选表单元格：一律单行 + 省略号收尾（2026-10-13 七改）——
   超长对象名不再折行把行撑高，完整值放 title 里悬浮看 */
.rpmcf-trow span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.rpmcf-trow span:first-of-type { flex: 1; }
.rpmcf-trow .rpmcf-pk { flex: none; }
.rpmcf-trow3 span:first-of-type { flex: 1.6; }
.rpmcf-trow3 span:nth-of-type(2) { flex: 1; }
.rpmcf-empty { flex: 1; min-height: 220px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; color: var(--text-faint); }
/* 第 2 步：上移/下移列（2026-10-13 用户要求：按钮挪到「已选」框**外面**，框因此右侧收窄） */
.rpmcf-order { flex: none; display: flex; flex-direction: column; justify-content: center; gap: 8px; }
.rpmcf-ud { width: 26px; height: 28px; border: 1px solid var(--border-strong); border-radius: 3px; background: #fff; color: var(--text-dim); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.rpmcf-ud:hover:not(:disabled) { border-color: #1870be; color: #1870be; }
.rpmcf-ud:disabled { background: #f5f6f8; color: var(--text-faint); cursor: default; }
/* 第 3 步表单 */
.rpmcf-form { flex: 1; min-height: 0; overflow: auto; padding: 14px 4px 0; }
.rpmcf-frow { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 12px; }
.rpmcf-flbl { flex: none; width: 70px; text-align: left; padding-top: 5px; color: var(--text); }
.rpmcf-seg { display: inline-flex; }
.rpmcf-seg button { height: 28px; padding: 0 14px; border: 1px solid var(--border-strong); background: #fff; color: var(--text); font-size: 12px; cursor: pointer; }
.rpmcf-seg button + button { border-left: 0; }
.rpmcf-seg button.on { background: #1870be; border-color: #1870be; color: #fff; }
/* 日期范围 = 告警页那套 .ff-date + cal* 日历的样式（2026-10-13 用户要求「复用之前的，样式以及功能」） */
.rpmcf-daterange { display: inline-flex; align-items: center; gap: 8px; }
.rpmcf-daterange .ff-date-wrap { position: relative; display: inline-flex; }
.rpmcf-daterange .ff-date { width: 174px; height: 28px; box-sizing: border-box; padding: 0 26px 0 8px; font-size: 12px; color: var(--text); border: 1px solid var(--border-strong); border-radius: 3px; background: #fff; outline: none; }
.rpmcf-daterange .ff-date:focus { border-color: #1870be; }
.rpmcf-daterange .ff-date-wrap svg { position: absolute; right: 7px; top: 50%; transform: translateY(-50%); color: #c1c6cd; pointer-events: none; }
.rpmcf-to { color: var(--text-dim); }
/* 相对时间：两个日期是纯文字（年-月-日，随所选相对项变化），不是输入框 */
.rpmcf-reldates { display: inline-flex; align-items: center; gap: 10px; height: 28px; color: var(--text); }
/* 指定小时：24 个方块（0~23 多选，选中变蓝）；两行 12 个，超出弹窗宽会自动换行 */
.rpmcf-hgrid { display: flex; flex-wrap: wrap; gap: 6px; max-width: 420px; }
.rpmcf-hcell { width: 28px; height: 28px; border: 1px solid var(--border-strong); border-radius: 3px; background: #fff; color: var(--text); font-size: 12px; line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; padding: 0; }
.rpmcf-hcell:hover { border-color: #1870be; color: #1870be; }
.rpmcf-hcell.on { background: #1870be; border-color: #1870be; color: #fff; }
.rpmcf-styles { display: inline-flex; gap: 26px; }
.rpmcf-stywrap { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.rpmcf-stycard { display: inline-flex; flex: none; flex-direction: column; }
.rpmcf-styh { display: flex; border: 1px solid var(--border); border-bottom: 0; background: #f7f9fc; }
/* 列宽自适应内容（min-width 兜住短值对齐），加 nowrap：「时间」风格那格的值 'YYYY-MM-DD HH:mm'
   比 96px 宽，写死宽度会折成两行（2026-10-13 用户报）。 */
.rpmcf-styh i, .rpmcf-styv i { flex: none; min-width: 96px; padding: 3px 8px; text-align: center; white-space: nowrap; font-style: normal; color: var(--text-dim); }
.rpmcf-styh i + i, .rpmcf-styv i + i { border-left: 1px solid var(--border); }
.rpmcf-styv { display: flex; border: 1px solid var(--border); color: var(--text); white-space: nowrap; }
.rpmcf-styv i { color: var(--text); }
.rpmcf-stywrap input { margin: 0; }
/* 配置项弹窗的确定键 = 蓝主键 */
.modal .rpmcf-ok { background: #1870be; border-color: #1870be; color: #fff; }
.modal .rpmcf-ok:hover { background: #1668ae; border-color: #1668ae; color: #fff; }

/* ==================== Evaluation > 报表 > KPI管理（2026-10-13 新增）====================
   左树 + 右列表；复用 .rp-view/.rp-body/.rp-left/.rp-main/.rp-toolbar/.rp-list-tbl/.rp-list-foot
   （含 tm-sort-ico 排序、alm-col-resizer 列宽拖动、bk-empty 空态、rp-pg-* 分页）。 */
:root { --kpi-left-w: 232px; }
.kpi-body { grid-template-columns: var(--kpi-left-w) 8px 1fr; }
/* 右列表栏高度恒定（2026-10-13 用户要求）：.rp-pane 自身没有 flex，高度会被表格内容撑开，
   于是「全部KPI」20 行时 741px、搜到 1 条时只有 133px，切左树/搜索时整页跳动。
   这里 flex:1 让 pane 恒等于 .rp-content 的可用高度，数据多少都不变
   （行少时表格下方留白，行多时由内层 .rp-list-wrap 自己滚，底部页码条 + 提示行始终贴底）。
   ⚠ 只作用于 KPI 管理页的 pane，不动通用 .rp-pane（其它列表页各有各的口径）。 */
.kpi-pane { flex: 1; }
/* 左栏：显示未激活KPI + 树搜索 + 树 */
.kpi-inact { flex: none; display: flex; align-items: center; gap: 6px; padding: 10px 12px 4px; font-size: 12px; color: var(--text); cursor: pointer; }
.kpi-inact input { margin: 0; }
.kpi-tree-search { flex: none; position: relative; margin: 4px 12px 6px; }
.kpi-tree-search input { width: 100%; height: 26px; border: 1px solid var(--border); border-radius: 3px; padding: 0 26px 0 8px; font-size: 12px; box-sizing: border-box; }
.kpi-tree-search input:focus { border-color: var(--accent); outline: none; }
.kpi-tree-lens { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); color: var(--text-faint); display: inline-flex; }
.kpi-tree { flex: 1; min-height: 0; overflow: auto; padding: 2px 0 10px; user-select: none; }
/* 根「全部KPI」= 可选蓝条（对齐截图） */
.kpi-root { display: flex; align-items: center; gap: 7px; height: 28px; margin: 2px 0 3px; padding: 0 10px; font-size: 13px; cursor: pointer; background: var(--accent); color: #fff; }
.kpi-root:not(.on) { background: transparent; color: var(--text); font-weight: 600; }
.kpi-root .kpi-root-svg { width: 16px; height: 16px; flex: none; }
.kpi-node { display: flex; align-items: center; gap: 5px; height: 26px; font-size: 12px; cursor: pointer; white-space: nowrap; }
.kpi-node:hover { background: #f2f6fb; }
.kpi-node.on { background: #e6f0fb; }
.kpi-twist { width: 16px; height: 16px; flex: none; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
.kpi-twist.leaf { cursor: default; }
.kpi-box { width: 14px; height: 14px; border: 1px solid #9aa7b8; border-radius: 2px; font-size: 11px; line-height: 12px; text-align: center; color: var(--text-dim); background: #fff; }
/* 右栏工具条 */
.kpi-type-sel { height: 28px; border: 1px solid var(--border); border-radius: 3px; font-size: 12px; padding: 0 4px; background: #fff; color: var(--text); }
.kpi-tbtn { display: inline-flex; align-items: center; gap: 4px; }
.kpi-tbtn svg { flex: none; }
.kpi-tbtn:disabled, .kpi-tbtn.is-disabled { opacity: 0.45; cursor: not-allowed; }
/* 工具条分割线（2026-10-14：查找引用关系 与 激活/去激活 之间那根「|」） */
.kpi-tbar-sep { flex: none; width: 1px; align-self: stretch; margin: 6px 2px; background: var(--border); }
/* 新建KPI弹窗：网元类型复选行（2026-10-14 起改成「下拉多选」：6 项全放进来，至少选一个） */
.kpi-nw-ck { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
.kpi-nw-ck input { margin: 0; }
/* 网元类型下拉（2026-10-14 二改，用户口径）：① 与其它输入框同宽同高（flex:1 + 30px，观感同 .rp-save-ipt）
   ② 箭头用项目 ARROW_SVG（不再是 ▾ 字符），展开时旋转 180°
   ③ 浮层 position:fixed、坐标由 JS 按按钮现算——展开不撑高弹窗、不出滚动条
     （.modal-body 的 overflow 裁不住 fixed，fixed 也不参与滚动尺寸计算；弹窗链上无 transform，fixed 锚定视口） */
.kpi-nw-dd { display: block; flex: 1; min-width: 0; }
.kpi-nw-dd-btn { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; height: 30px; box-sizing: border-box; padding: 0 8px; border: 1px solid var(--border-strong); border-radius: 2px; background: #fff; font-size: 13px; color: var(--text); cursor: pointer; outline: none; }
.kpi-nw-dd-btn:hover, .kpi-nw-dd-btn.open, .kpi-nw-dd-btn:focus { border-color: var(--accent); }
.kpi-nw-dd-val { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.kpi-nw-dd-ar { flex: none; display: inline-flex; color: var(--text-dim); transition: transform 0.15s; }
.kpi-nw-dd-btn.open .kpi-nw-dd-ar { transform: rotate(180deg); }
.kpi-nw-dd-box { position: fixed; z-index: 60; padding: 8px 12px; border: 1px solid var(--border); border-radius: 3px; background: #fff; box-shadow: 0 4px 12px rgba(0,0,0,.12); display: flex; flex-direction: column; gap: 7px; font-size: 12px; }
/* [hidden] 必须显式压掉上面的 display:flex，否则类规则胜出、下拉永远关不掉（项目既有口径，见 .np-search-clear） */
.kpi-nw-dd-box[hidden] { display: none; }
.kpi-nw-dd.is-err .kpi-nw-dd-btn, .kpi-nw-dd.is-err .kpi-nw-dd-btn:focus { border-color: var(--critical); }
.kpi-search { width: 210px; }
.kpi-adv { display: inline-flex; align-items: center; gap: 4px; border: 0; background: transparent; color: var(--accent); font-size: 12px; cursor: pointer; padding: 0; }
.kpi-adv:hover { text-decoration: underline; }
.kpi-adv .rp-arrow { display: inline-flex; }
/* 表格：13 列 fixed 布局；单元格单行省略；未激活行整行淡化 */
/* 2026-10-14 用户口径：默认列宽下不出横向滚动条（列宽总和 ≤ 可视宽时富余按比例摊回各列，
   表更宽时才在 .rp-list-wrap 里横向滚）；表头文字不被截断出 '...'（默认列宽即按
   「表头文字 + 内边距 30 + 图标位 14」定的，见 KPI_COLS 注释） */
.kpi-tbl { width: 100%; }
.kpi-tbl th { white-space: nowrap; }
.kpi-tbl th .kpi-th-txt { display: inline-block; max-width: calc(100% - 14px); overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; }
.kpi-tbl td { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 12px; }
/* 勾选列：右侧内边距清零——td 自带的 text-overflow:ellipsis 会把溢出的勾选框渲染成 '...'
   （2026-10-14 用户抓到：每个勾选框后面拖着省略号），留足 32-左12-边框 后不再溢出 */
.kpi-tbl th.checkbox-cell, .kpi-tbl td.checkbox-cell { padding-right: 0; text-align: left; }
.kpi-name { display: inline-flex; align-items: center; gap: 5px; min-width: 0; }
.kpi-name-txt { overflow: hidden; text-overflow: ellipsis; }
.kpi-doc-ic { color: #6b7686; flex: none; }
.kpi-inact-tag { font-style: normal; color: var(--critical, #f5222d); font-size: 11px; border: 1px solid currentColor; border-radius: 2px; padding: 0 3px; margin-left: 6px; flex: none; }
.kpi-tbl tr[data-inact] td { color: var(--text-faint); }
.kpi-tbl tr[data-inact] .kpi-doc-ic { color: var(--text-faint); }
/* 操作列两枚图标 */
.kpi-ops, .kpi-ops-h { text-align: center; }
.kpi-op { display: inline-flex; color: var(--text-dim); cursor: pointer; padding: 2px; }
.kpi-op:hover { color: var(--accent); }
.kpi-op-del:hover { color: var(--critical, #f5222d); }
/* 表格下方提示行 */
.kpi-note { display: flex; align-items: center; gap: 5px; padding: 6px 10px; font-size: 12px; color: var(--text-dim); }
.kpi-note svg { flex: none; }
/* 空态 */
.kpi-empty-td { padding: 26px 0; }

/* ============ 对象组管理（2026-10-15 新增）============
   左树 + 右列表复用 .rp-view/.kpi-view/.kpi-left/.kpi-tree/.kpi-tbl/.rp-list-* 全套既有样式，只补缺口 */
/* 左树每个网元类型右侧的计数 */
.og-cnt { margin-left: auto; padding-right: 10px; font-style: normal; font-size: 11px; color: var(--text-dim); }
/* 导出下拉菜单：结构与 .alm-export-menu 同款，但工具条没有 positioned 祖先 → fixed 按按钮现算 */
.og-export-menu {
  position: fixed; z-index: 46; min-width: 110px; padding: 4px 0;
  background: #fff; border: 1px solid var(--border); border-radius: 4px;
  box-shadow: 0 6px 16px rgba(0,0,0,.12);
}
.og-export-menu .alm-menu-item { display: block; width: 100%; text-align: left; padding: 6px 16px; border-radius: 0; font-size: 12px; background: none; border: 0; cursor: pointer; color: var(--text); }
.og-export-menu .alm-menu-item:hover { background: #f0f5fb; }
.og-export-menu .alm-menu-item.is-disabled,
.og-export-menu .alm-menu-item.is-disabled:hover { color: #b9bec7; background: transparent; cursor: not-allowed; }
/* 新建弹窗「组内成员」textarea（.rp-save-ipt 的 30px 高度是给 input 的） */
textarea.rp-save-ipt { height: auto; min-height: 96px; line-height: 20px; padding: 5px 8px; resize: vertical; font-family: inherit; }
.og-mem-row { align-items: flex-start; }
.og-mem-row .rp-save-lbl { padding-top: 6px; }
/* 查看弹窗：字段值 + 成员清单滚动盒 */
.og-view-val { flex: 1; min-width: 0; min-height: 30px; display: flex; align-items: center; box-sizing: border-box; border: 1px solid var(--border); border-radius: 2px; padding: 0 8px; font-size: 13px; color: var(--text); background: #f7f9fc; word-break: break-all; }
.og-mem-box { margin: 0 0 4px 84px; max-height: 180px; overflow: auto; border: 1px solid var(--border); border-radius: 2px; background: #fff; }
.og-mem-item { padding: 3px 10px; font-size: 12px; color: var(--text); word-break: break-all; border-bottom: 1px solid #f0f2f5; }
.og-mem-item:last-child { border-bottom: 0; }
.og-mem-empty { padding: 14px 0; text-align: center; color: var(--text-dim); font-size: 12px; }
