/* ================================================================
 * 智·维（H5 运维数据助手） 主题样式
 * 设计：精致工业风 —— 克制、蓝白主色、Noto Sans SC 中文专业字体
 * ================================================================ */

/* ---------- 0. 本地中文字体（用户 2026-07-02：禁止外链 Google Fonts，
                 Noto Sans SC 400/500/600/700 woff2 已随部署下载到 h5/fonts） ---------- */
@font-face {
  font-family: "Noto Sans SC";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/NotoSansSC-400.woff2") format("woff2");
}
@font-face {
  font-family: "Noto Sans SC";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/NotoSansSC-500.woff2") format("woff2");
}
@font-face {
  font-family: "Noto Sans SC";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/NotoSansSC-600.woff2") format("woff2");
}
@font-face {
  font-family: "Noto Sans SC";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/NotoSansSC-700.woff2") format("woff2");
}

/* ---------- 0. CSS 变量（统一主题，后续改色只动这里） ---------- */
:root {
  /* H5默认蓝色主题 */
  --zw-primary: #1565c0;            /* 工业蓝 */
  --zw-primary-dark: #0d47a1;       /* 深蓝点缀 */
  --zw-primary-soft: #e3f2fd;       /* 浅蓝背景块 */
  --zw-secondary: #42a5f5;          /* 天际蓝 */
  --zw-warning: #fb8c00;            /* 停电：警示橙 */
  --zw-danger: #e53935;             /* 退服：故障红 */
  --zw-success: #2e7d32;            /* 运行：正常绿 */
  --zw-text: #1f2937;               /* 主文本色 */
  --zw-text-2: #4b5563;             /* 次文本色 */
  --zw-text-3: #94a3b8;             /* 辅助文本色 */
  --zw-bg: #f5f9ff;                 /* 全局背景（蓝白） */
  --zw-card-bg: #ffffff;            /* 卡片底色 */
  --zw-border: #e2e8f0;             /* 分割线 */
  --zw-card-shadow: 0 4px 20px rgba(21, 101, 192, 0.08);
  --zw-card-shadow-hover: 0 10px 28px rgba(21, 101, 192, 0.16);
  --zw-radius: 14px;
  --zw-radius-sm: 10px;
  --zw-nav-h: 48px;                 /* 二级页顶栏高度（>44px 满足 H5 热区） */
  --zw-font: "Noto Sans SC", "PingFang SC", "Microsoft YaHei",
             "Source Han Sans CN", system-ui, -apple-system,
             BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

/* 小程序环境红色主题覆盖 */
body.zw-in-miniprogram {
  --zw-primary: #c62828;            /* 主题红 */
  --zw-primary-dark: #8e0000;       /* 深红点缀 */
  --zw-primary-soft: #ffebee;       /* 浅红背景块 */
  --zw-secondary: #ef5350;          /* 亮红 */
  --zw-bg: #fff5f5;                 /* 全局背景（红白） */
  --zw-border: #ffe0e0;             /* 分割线 */
  --zw-card-shadow: 0 4px 20px rgba(198, 40, 40, 0.08);
  --zw-card-shadow-hover: 0 10px 28px rgba(198, 40, 40, 0.16);
}

/* ---------- 1. 重置与全局 ---------- */
* { box-sizing: border-box; }
html, body {
  margin: 0;
  padding: 0;
  background: var(--zw-bg);
  color: var(--zw-text);
  font-family: var(--zw-font);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-size: 15px;
  line-height: 1.55;
  /* 全局防横向溢出：Element Plus 表格浮动 fixed 层 / 动画 可能撑破 100vw，
     H5 单页应用永远不应该有「页面级水平滚动条」（表格内滚动由内部容器承载）*/
  width: 100%;
  max-width: 100%;
  overflow-x: hidden;
}
#app {
  min-height: 100vh;
  width: 100%;
  max-width: 100%;
  overflow-x: hidden;
}

/* ---------- 2. 首屏loading splash（JS 未加载前占位） ---------- */
.zw-splash {
  position: fixed; inset: 0;
  background: linear-gradient(180deg, var(--zw-primary-soft) 0%, var(--zw-bg) 60%);
  display: flex; align-items: center; justify-content: center;
  z-index: 9999;
  animation: zw-fade-out .35s ease 1s forwards;
}
.zw-splash-inner { text-align: center; color: var(--zw-primary-dark); }

/* CSS转圈loading */
.zw-spinner {
  width: 48px; height: 48px;
  border: 4px solid var(--zw-primary-soft);
  border-top-color: var(--zw-primary);
  border-radius: 50%;
  animation: zw-spin 0.8s linear infinite;
  margin: 0 auto;
}
@keyframes zw-spin {
  to { transform: rotate(360deg); }
}

.zw-splash-brand {
  margin-top: 20px;
  font-size: 28px; font-weight: 700; letter-spacing: 4px;
  color: var(--zw-primary-dark);
}
.zw-splash-sub { margin-top: 8px; color: var(--zw-text-2); font-size: 14px; letter-spacing: 2px; }

/* JS 启动后把 splash 淡出（app.js mounted 时给 body 加 zw-ready 类） */
body.zw-ready .zw-splash { display: none !important; }

/* ---------- 3. 首页 Home 组件 ---------- */
.zw-home {
  max-width: 1100px;
  margin: 0 auto;
  padding: 28px 20px 48px;
}
/* Hero 区 */
.zw-home-hero {
  background:
    radial-gradient(1200px 360px at 10% -20%, rgba(66,165,245,.18), transparent 60%),
    radial-gradient(800px 300px at 110% 0%, rgba(21,101,192,.10), transparent 55%),
    linear-gradient(180deg, #ffffff 0%, #f7fbff 100%);
  border-radius: 22px;
  padding: 36px 28px 32px;
  box-shadow: var(--zw-card-shadow);
  display: grid;
  grid-template-columns: minmax(220px, 1fr) 1.2fr;
  gap: 28px;
  align-items: center;
  opacity: 0;
  transform: translateY(16px);
  animation: zw-hero-in .55s ease forwards;
}
/* 小程序环境Hero区背景调整 */
body.zw-in-miniprogram .zw-home-hero {
  background:
    radial-gradient(1200px 360px at 10% -20%, rgba(239,83,80,.18), transparent 60%),
    radial-gradient(800px 300px at 110% 0%, rgba(198,40,40,.10), transparent 55%),
    linear-gradient(180deg, #ffffff 0%, #fff8f8 100%);
}
.zw-home-hero-logo { display: flex; justify-content: center; }
.zw-home-hero-logo svg {
  width: 220px; height: 220px;
  filter: drop-shadow(0 14px 30px rgba(21,101,192,.2));
}
body.zw-in-miniprogram .zw-home-hero-logo svg {
  filter: drop-shadow(0 14px 30px rgba(198,40,40,.2));
}
.zw-home-hero-copy { display: flex; flex-direction: column; gap: 10px; }
.zw-home-hero-copy .brand {
  font-size: 52px; font-weight: 700; letter-spacing: 8px;
  background: linear-gradient(90deg, #42a5f5 0%, #1565c0 60%, #0d47a1 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  margin: 0;
}
body.zw-in-miniprogram .zw-home-hero-copy .brand {
  background: linear-gradient(90deg, #ef5350 0%, #c62828 60%, #8e0000 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.zw-home-hero-copy .sub {
  margin: 0; font-size: 17px; color: var(--zw-text-2); letter-spacing: 3px;
}
.zw-home-hero-copy .desc {
  margin: 6px 0 0;
  font-size: 14px; color: var(--zw-text-3);
  padding: 10px 14px;
  border-left: 3px solid var(--zw-secondary);
  background: var(--zw-primary-soft);
  border-radius: 0 var(--zw-radius-sm) var(--zw-radius-sm) 0;
}
/* 6 宫格入口 */
.zw-home-menu {
  margin-top: 28px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
.zw-menu-card {
  position: relative;
  display: block;
  padding: 20px 18px 18px;
  background: var(--zw-card-bg);
  border-radius: var(--zw-radius);
  box-shadow: var(--zw-card-shadow);
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  border: 1px solid transparent;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
  overflow: hidden;
  min-height: 120px;
}
.zw-menu-card::after {
  content: "";
  position: absolute; right: -40px; top: -40px;
  width: 140px; height: 140px; border-radius: 50%;
  background: var(--zw-primary-soft);
  opacity: .6;
  transition: transform .35s ease;
}
.zw-menu-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--zw-card-shadow-hover);
  border-color: #c7ddf5;
}
body.zw-in-miniprogram .zw-menu-card:hover {
  border-color: #f8c8c8;
}
.zw-menu-card:hover::after { transform: scale(1.15); }
.zw-menu-card .mc-icon {
  width: 42px; height: 42px; border-radius: 12px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 22px; color: #fff; position: relative; z-index: 1;
  margin-bottom: 12px;
}
/* H5默认蓝色主题 - 菜单卡片图标 */
.zw-menu-card[data-key="assessment-metric"] .mc-icon { background: linear-gradient(135deg, #42a5f5, #1565c0); }
.zw-menu-card[data-key="daily"]  .mc-icon { background: linear-gradient(135deg, #42a5f5, #1565c0); }
.zw-menu-card[data-key="weekly"] .mc-icon { background: linear-gradient(135deg, #5e72e4, #1565c0); }
.zw-menu-card[data-key="monthly"]      .mc-icon { background: linear-gradient(135deg, #7e57c2, #303f9f); }
.zw-menu-card[data-key="alarm-count"]  .mc-icon { background: linear-gradient(135deg, #ff8a65, #f4511e); }
.zw-menu-card[data-key="outage-detail"] .mc-icon { background: linear-gradient(135deg, #ffb74d, var(--zw-warning)); }
.zw-menu-card[data-key="offline-detail"] .mc-icon { background: linear-gradient(135deg, #ef5350, #c62828); }
.zw-menu-card[data-key="lt-offline-detail"] .mc-icon { background: linear-gradient(135deg, #ef5350, #c62828); }
.zw-menu-card[data-key="co-maintenance"] .mc-icon { background: linear-gradient(135deg, #26a69a, #00695c); }
/* 小程序环境红色主题 - 菜单卡片图标 */
body.zw-in-miniprogram .zw-menu-card[data-key="assessment-metric"] .mc-icon { background: linear-gradient(135deg, #ef5350, #c62828); }
body.zw-in-miniprogram .zw-menu-card[data-key="daily"]  .mc-icon { background: linear-gradient(135deg, #ef5350, #c62828); }
body.zw-in-miniprogram .zw-menu-card[data-key="weekly"] .mc-icon { background: linear-gradient(135deg, #ec407a, #c62828); }
body.zw-in-miniprogram .zw-menu-card[data-key="monthly"]      .mc-icon { background: linear-gradient(135deg, #ab47bc, #8e0000); }
body.zw-in-miniprogram .zw-menu-card[data-key="alarm-count"]  .mc-icon { background: linear-gradient(135deg, #ff8a65, #f4511e); }
body.zw-in-miniprogram .zw-menu-card[data-key="outage-detail"] .mc-icon { background: linear-gradient(135deg, #ffb74d, var(--zw-warning)); }
body.zw-in-miniprogram .zw-menu-card[data-key="offline-detail"] .mc-icon { background: linear-gradient(135deg, #ef5350, #c62828); }
body.zw-in-miniprogram .zw-menu-card[data-key="lt-offline-detail"] .mc-icon { background: linear-gradient(135deg, #ef5350, #c62828); }
body.zw-in-miniprogram .zw-menu-card[data-key="co-maintenance"] .mc-icon { background: linear-gradient(135deg, #ef5350, #c62828); }
.zw-menu-card .mc-title { position: relative; z-index: 1; font-size: 17px; font-weight: 600; letter-spacing: 1px; }
.zw-menu-card .mc-en { position: relative; z-index: 1; margin-top: 4px; font-size: 12px; color: var(--zw-text-3); letter-spacing: .8px; }

/* ---------- 4. 二级页通用布局（顶栏 + 筛选器 + 表格） ---------- */
.zw-subpage { padding-top: calc(var(--zw-nav-h) + env(safe-area-inset-top, 0)); }
.zw-sub-nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  height: calc(var(--zw-nav-h) + env(safe-area-inset-top, 0));
  padding-top: env(safe-area-inset-top, 0);
  background: linear-gradient(135deg, var(--zw-primary) 0%, var(--zw-primary-dark) 100%);
  color: #fff;
  display: flex; align-items: center; justify-content: space-between;
  padding-left: 6px; padding-right: 6px;
  box-shadow: 0 4px 14px rgba(13, 71, 161, .25);
}
body.zw-in-miniprogram .zw-sub-nav {
  box-shadow: 0 4px 14px rgba(142, 0, 0, .25);
}
.zw-sub-nav .nav-btn {
  width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center;
  color: #fff; background: transparent; border: none; cursor: pointer; border-radius: 12px;
  font-size: 18px;
}
.zw-sub-nav .nav-btn:hover { background: rgba(255,255,255,.12); }
.zw-sub-nav .nav-title { flex: 1; text-align: center; font-size: 17px; font-weight: 600; letter-spacing: 2px; }

/* 隐藏头部导航时的样式（小程序web-view环境） */
.zw-subpage.zw-subpage-no-nav {
  padding-top: 0;
}
.zw-subpage.zw-subpage-no-nav .zw-sub-body.zw-sub-body-scroll {
  max-height: 100vh;
  height: 100vh;
}
/* 全局小程序环境样式（body上添加zw-in-miniprogram类） */
body.zw-in-miniprogram .zw-subpage {
  padding-top: 0;
}
body.zw-in-miniprogram .zw-sub-nav {
  display: none;
}
body.zw-in-miniprogram .zw-sub-body.zw-sub-body-scroll {
  max-height: 100vh;
  height: 100vh;
}
/* ================================================================
   【2026-07-14 用户表头未吸顶修复】内部滚动容器模式（contentScrollable=true）
   根因：祖先链 body/#app 有 overflow-x:hidden，会破坏 viewport 级 position:sticky。
   修复：把筛选卡 zw-filter-card 和 表格卡 zw-table-card 包在的 .zw-sub-body 自身变成
        固定高度的内部滚动容器，sticky th 相对【它】top=0 吸顶，绕开 viewport 级祖先 overflow 污染。
   ———— 2026-07-14 二次修复 overflow-x/y 规范陷阱：
        CSS Overflow 3 规定：overflow-x 与 overflow-y 其中一个为 visible 另一个非 visible 时，
        visible 的那一侧会被浏览器【静默强制重算为 auto】，导致【父级意外变成滚动容器】，
        sticky 元素就近绑定到错误的祖先而失效。因此所有 overflow 必须【两方向都显式声明】！
   ================================================================ */
.zw-sub-body {
  max-width: 1100px; margin: 0 auto;
  /* 2026-07-15 终极修复：去掉双重 padding-top
     · 父容器 .zw-subpage 已有 padding-top: calc(var(--zw-nav-h) + env(safe-area-inset-top, 0)) 为 fixed 顶栏占位（L212）
     · 子容器 .zw-sub-body 再重复加 --zw-nav-h → 双重叠加留白一倍！子容器 padding-top=0，内容紧贴顶栏下沿 */
  padding: 0 16px 48px;
  /* ⚠️ PC 端非内部滚动模式：两方向都显式写（避免 visible+hidden 触发规范陷阱） */
  overflow-x: hidden;
  overflow-y: visible;
}
.zw-sub-body.zw-sub-body-scroll {
  /* 内部滚动容器：高度 = 整个视口 - 顶栏高度(zw-nav-h + 安全区) */
  max-height: calc(100vh - var(--zw-nav-h) - env(safe-area-inset-top, 0px));
  height: calc(100vh - var(--zw-nav-h) - env(safe-area-inset-top, 0px));
  /* ⚠️ 内部滚动模式：两方向都显式声明 —— 这里才是唯一的真滚动容器！
     横向（overflow-x）交给 Element Plus 内部 body-wrapper/header-wrapper 配对处理（JS 同步 scrollLeft），
     外层 sb 保持 hidden，防止 2400px 宽表格撑破外层布局（出现二级横向滚动条）。 */
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  /* 内部滚动容器：padding-top 去掉 16px，用户要求去掉筛选/表格上方留白（内部滚动容器在顶栏下方，不需要顶部间距） */
  padding: 0 16px 16px;
}
/* 筛选器卡片 */
.zw-filter-card {
  background: var(--zw-card-bg);
  border-radius: var(--zw-radius);
  padding: 14px 16px 16px;
  box-shadow: var(--zw-card-shadow);
  margin-bottom: 16px;
}
.zw-filter-actions { margin-top: 12px; display: flex; gap: 10px; flex-wrap: wrap; }
.zw-filter-card .el-form-item { margin-bottom: 10px; }
/* 表格卡片 */
.zw-table-card {
  background: var(--zw-card-bg);
  border-radius: var(--zw-radius);
  padding: 6px 10px 12px;
  box-shadow: var(--zw-card-shadow);
  overflow: hidden;
}
/* ====== 全局兜底：表格卡片内 el-tag 文字强制深灰 #1f2937，防 white-on-white ======
   用户 2026-07-02 / 2026-07-03 四度反馈「站址等级」「停电历时督办」
   列只有背景没文字。根因（叠加）：
   ① Element Plus light/plain tag 默认 CSS 变量被全局样式/移动端 WebView 主题覆盖后，tag 文字颜色=背景颜色；
   ② effect=plain 时内部 .el-tag__content 子 span 使用独立 CSS 变量 color，父元素 inline !important color 不被子继承；
   ③ 微信/QQ X5 旧内核对 CSS 变量和 color: inherit 兼容性有缺陷，只认 -webkit-text-fill-color 或 !important 写死值；
   ④ 列 getTagStyle 只写 color 没写 background，plain effect 默认背景透明 + 整行 hsl 浅背景后 → 视觉“白背景无文字”。
   五重保险兜底（X5/老WebKit必须每层都打，单独一层在部分机型无效）：
   A. 全局 CSS 变量覆盖 plain/light 的默认文字色为深灰；
   B. .zw-table-card .el-tag 本身兜底 color:#1f2937 !important + -webkit-text-fill-color（getTagStyle 内联 !important 更高优先级可覆盖白字）；
   C. .el-tag__content 子节点强制 color: inherit !important + -webkit-text-fill-color: inherit !important；
   D. 超高权重选择器 body > #app .zw-table-card ... td .cell > .el-tag 再次覆盖（防止 Element Plus 后加载覆盖）；
   E. 属性选择器 .el-tag[style*="background"]（有内联自定义背景的列，必然是 getTagStyle 自定义）给子节点加 color:inherit 双重保险；
   F. 模板层（app.js）：el-tag 内部手动包一层 <span style="color:inherit;-webkit-text-fill-color:inherit"> 完全绕开 Element Plus 内部 span。
*/
.zw-table-card .el-tag {
  color: #1f2937 !important;
  -webkit-text-fill-color: #1f2937 !important;          /* X5/老 WebKit 专用：文字填充色，优先级高于 color */
  text-rendering: optimizeLegibility !important;
  --el-tag-text-color: #1f2937 !important;
  --el-tag-light-text-color: #1f2937 !important;
  /* —— plain effect 四个核心变量全部兜底深灰（Element Plus 内部用） —— */
  --el-tag-plain-text-color: #1f2937 !important;
  --el-tag-plain-text-color-info: #1f2937 !important;
  --el-tag-plain-text-color-warning: #1f2937 !important;
  --el-tag-plain-text-color-danger: #1f2937 !important;
  --el-tag-plain-text-color-success: #1f2937 !important;
}
/* 强制 tag 内部真正显示文字的 span 继承父 el-tag 颜色（inline !important → 子 inherit） */
.zw-table-card .el-tag .el-tag__content {
  color: inherit !important;
  -webkit-text-fill-color: inherit !important;          /* X5 兼容：让 __content 从父 el-tag（或其内联style）继承填充色 */
  line-height: 1.5 !important;
}
/* D. 超高权重：覆盖 Element Plus 后加载 / 深层级选择器的冲突（td > .cell 是 Element Plus 渲染路径） */
body > #app .zw-table-card .el-table__body td.el-table__cell > .cell > .el-tag,
body .zw-table-card td .cell > .el-tag {
  color: #1f2937 !important;
  -webkit-text-fill-color: #1f2937 !important;
}
body > #app .zw-table-card .el-table__body td.el-table__cell > .cell > .el-tag .el-tag__content,
body .zw-table-card td .cell > .el-tag .el-tag__content {
  color: inherit !important;
  -webkit-text-fill-color: inherit !important;
}
/* E. 属性选择器：针对「已内联设置 background」的 tag（即 getTagStyle 自定义颜色的列：站址等级/停电历时督办/地市等）
   → 这些列用户最容易反馈“只有背景没文字”，再次强制子节点 inherit 父节点文字颜色 */
.zw-table-card .el-tag[style*="background"] {
  /* 父节点：如果 inline 没写 color（理论上都写了，这里兜底），强制深字 */
  color: #1f2937 !important;
}
.zw-table-card .el-tag[style*="background"] .el-tag__content {
  color: inherit !important;
  -webkit-text-fill-color: inherit !important;
}
/* 额外保险：若 getTagStyle 设置的 color 被覆盖，tag 内部我们手动包的 span 也要 inherit */
.zw-table-card .el-tag > span[style*="color:inherit"] {
  -webkit-text-fill-color: inherit !important;
}
.zw-table-meta {
  padding: 8px 8px 12px;
  display: flex; justify-content: space-between; align-items: center;
  color: var(--zw-text-2); font-size: 13px;
  border-bottom: 1px dashed var(--zw-border);
  margin-bottom: 8px;
}
/* Element Plus 覆盖（适配 H5 移动端） */
.el-table { --el-table-border-color: var(--zw-border); font-size: 14px; }
.el-table th.el-table__cell { background: #f4f9ff !important; color: var(--zw-primary-dark); font-weight: 600; }
body.zw-in-miniprogram .el-table th.el-table__cell { background: #fff5f5 !important; }
/* 合计行：浅蓝渐变 + 加粗（报表惯例，app.js row-class-name=zw-summary-row 命中） */
.el-table .el-table__row.zw-summary-row > td {
  background: linear-gradient(180deg, #e6efff 0%, #d5e4ff 100%) !important;
  color: #0b3d91 !important;
  font-weight: 700 !important;
}
body.zw-in-miniprogram .el-table .el-table__row.zw-summary-row > td {
  background: linear-gradient(180deg, #ffe8e8 0%, #ffd5d5 100%) !important;
  color: #8e0000 !important;
}
.el-table .el-table__row.zw-summary-row:hover > td {
  background: linear-gradient(180deg, #dbe8ff 0%, #c6daff 100%) !important;
}
body.zw-in-miniprogram .el-table .el-table__row.zw-summary-row:hover > td {
  background: linear-gradient(180deg, #ffdcdc 0%, #ffc6c6 100%) !important;
}
/* —— 【用户 2026-07-03 下午 Q1】停电明细整行城市背景色撑满：td 继承 tr 的 row-style background
   因为 Element Plus 默认 td 有 #fff / zebra #fafafa 背景，盖在 tr 上方 → 整行背景显示不出。
   当 wholeRowCityBg=true 时 <el-table :class="{ zw-no-stripe:true }">，此规则强制 td 的 background
   从 tr 的 inline style 继承（带 !important，覆盖 td 默认值和 zebra 内置样式）。
   同时对 tr 直接写 [style*="background"] 的兜底：即使 class 绑定失效也能正确继承。 */
.el-table.zw-no-stripe .el-table__row td,
.el-table.zw-no-stripe .el-table__row th.el-table__cell:not(.is-leaf) {
  background: inherit !important;
}
.el-table tr[style*="background"] td,
.el-table tr[style*="background-color"] td {
  background: inherit !important;
}
/* 日报/周报单元格：主值 + 下一行同比对比箭头（红绿） */
.dw-cell { line-height: 1.3; }
.dw-cell-cur { display: block; color: #0b3d91; font-weight: 600; font-size: 13.5px; }
body.zw-in-miniprogram .dw-cell-cur { color: #8e0000; }
.dw-cell-cmp { display: block; font-size: 11.5px; margin-top: 3px; font-weight: 600; letter-spacing: .2px; }
.el-button--primary {
  --el-button-bg-color: var(--zw-primary);
  --el-button-border-color: var(--zw-primary);
  --el-button-hover-bg-color: var(--zw-secondary);
  --el-button-hover-border-color: var(--zw-secondary);
  --el-button-active-bg-color: var(--zw-primary-dark);
  --el-button-active-border-color: var(--zw-primary-dark);
  border-radius: 10px !important;
  box-shadow: 0 4px 10px rgba(21,101,192,.2);
}
body.zw-in-miniprogram .el-button--primary {
  box-shadow: 0 4px 10px rgba(198,40,40,.2);
}

/* ---------- 5. 动画 ---------- */
@keyframes zw-fade-out { to { opacity: 0; visibility: hidden; } }
@keyframes zw-hero-in { to { opacity: 1; transform: translateY(0); } }
@keyframes zw-hero-pop {
  0% { transform: scale(.85); opacity: 0; }
  100% { transform: scale(1); opacity: 1; }
}

/* ---------- 6. 响应式：移动端 H5 优先 ---------- */
@media (max-width: 768px) {
  .zw-home { padding: 18px 14px 36px; }
  .zw-home-hero {
    grid-template-columns: 1fr;
    padding: 24px 18px 22px;
    gap: 18px;
    text-align: center;
  }
  .zw-home-hero-logo svg { width: 170px; height: 170px; }
  .zw-home-hero-copy .brand { font-size: 40px; letter-spacing: 6px; }
  .zw-home-hero-copy .sub { font-size: 15px; letter-spacing: 2px; }
  .zw-home-menu { grid-template-columns: repeat(2, 1fr); gap: 12px; margin-top: 18px; }
  .zw-menu-card { min-height: 108px; padding: 16px 14px; }
  .zw-menu-card .mc-icon { width: 38px; height: 38px; font-size: 19px; }
  .zw-menu-card .mc-title { font-size: 15px; }
  /* 2026-07-15 终极修复：平板端 .zw-subpage 已有 padding-top（顶栏占位），zw-sub-body 不再加 var(--zw-nav-h)，避免双重留白叠加 */
  .zw-sub-body { padding: 0 12px 36px; }
  .zw-filter-card { padding: 10px 10px 12px; }
}
@media (max-width: 480px) {
  .zw-home-menu { grid-template-columns: repeat(2, 1fr); gap: 10px; margin-top: 14px; }
  .zw-menu-card { min-height: 96px; padding: 14px 12px; }
  .zw-menu-card .mc-icon { width: 36px; height: 36px; font-size: 18px; margin-bottom: 10px; }
  .zw-menu-card .mc-title { font-size: 14px; letter-spacing: .5px; }
  .zw-menu-card .mc-en { font-size: 11px; }
}

/* Element Plus 日期选择器中文排版优化 */
.el-date-editor { --el-date-editor-width: 100%; width: 100%; }
.zw-filter-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px 14px; }

/* ---------- 7. 固定列（第一列=地市）视觉分隔 & 钉住（全局兜底，PC/手机都生效）---------- */
/* 需求：二级页表格横向滑动时第一列（地市）固定。
   Element Plus 通过列属性 fixed="left" 实现固定（内部造一个绝对定位覆盖层）。
   但在"多级表头 + 微信 WebView + 手动 JS 设置 scrollLeft"等特殊场景下，
   Element Plus 自带的 fixed 可能不生效，因此用 className="zw-fixed-city" + 全局 sticky 做
   兜底"双保险"：只要同时命中 zw-fixed-city 和 is-fixed-left，就强制 sticky + 背景 + 阴影。*/
/* 【2026-07-09 用户：注意！明细页有 2 列 fixed=left（序号列 + 地市列，都带 className=zw-fixed-city）。
   绝对不能用 left:0 !important —— Element Plus 内部会按列声明顺序给每列计算累计 left（第1列=0，第2列=70px），
   强行 left:0 会把两列都叠到最左边。保留 position:sticky 兜底，让 Element Plus 自带的 left 值生效。
   单 fixed 列的页面（周/日/月指标、告警数量二级页等）不受影响：累计 left=0 和 Element Plus 算的一致。*/
.el-table td.zw-fixed-city,
.el-table th.zw-fixed-city,
.el-table td.zw-fixed-city.is-fixed-left,
.el-table th.zw-fixed-city.is-fixed-left {
  position: sticky !important;
  /* 原强制钉死 left=0 已移除：明细页"序号列 + 地市列"两列都为 fixed=left，
     Element Plus 会按列顺序自动给每列计算累计 left（第1列=0，第2列=70px），
     若用 CSS 强制覆盖 left 值为 0（带 !important）两列会完全重叠。
     保留 position:sticky 作为微信 X5 兼容兜底即可。 */
  background: #ffffff !important;
}
/* 表体单元格：右侧阴影 + 2px 实竖线（视觉分隔"钉住"的效果）*/
.el-table .el-table__body-wrapper td.is-fixed-left,
.el-table td.zw-fixed-city.is-fixed-left {
  box-shadow: 3px 0 6px -2px rgba(16, 42, 94, 0.18) !important;
  border-right: 2px solid rgba(11, 61, 145, 0.15) !important;
  z-index: 12 !important;
}
/* 表头单元格：阴影更强 + z-index 更高（防止被表体覆盖）*/
.el-table .el-table__header-wrapper th.is-fixed-left,
.el-table th.zw-fixed-city.is-fixed-left {
  box-shadow: 3px 2px 6px -2px rgba(16, 42, 94, 0.22) !important;
  border-right: 2px solid rgba(11, 61, 145, 0.22) !important;
  z-index: 22 !important;
}
/* 非固定模式下的默认按钮/筛选栏 action 弹性布局（允许换行，全局默认）*/
.zw-filter-actions {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 10px;
}

/* 2026-08-11：强制表头/单元格文字不换行（用于「停电数量」等紧凑列名）*/
.el-table th.zw-col-no-wrap.el-table__cell .cell,
.el-table td.zw-col-no-wrap.el-table__cell .cell {
  white-space: nowrap !important;
}

/* 2026-08-11：明细页（停电/退服）所有表头强制单行显示 */
.zw-page-OutageDetail .el-table th.el-table__cell .cell,
.zw-page-OfflineDetail .el-table th.el-table__cell .cell {
  white-space: nowrap !important;
}

/* ==========================================================================
   8. 明细页（OutageDetail / OfflineDetail）单一滚动容器 + 表头 Sticky 固定
   —— 根因：tableHeight="calc(100vh - 280px)" 传给 Element Plus 的 :height 会被忽略
            （其内部 JS 高度计算不认 calc()/vh 类 CSS 字符串，只认数值/"NNNpx"/百分比），
            导致 body-wrapper 不生成内部滚动，滚动的是整个页面，表头跟着页面一起滚走。
   —— 修复（经验 249854/208496 推荐）：外层包一个独立 div.zw-scroll-card 作为
            【唯一滚动容器】（overflow-y:auto + max-height=calc 值），
            然后对 thead 下的每一个 <th> 设置 position:sticky; top:0 钉到容器顶部。
   ========================================================================== */

/* ---- 8a 滚动容器本体：高度用模板 style.maxHeight（calc 表达式），内部滚动 ---- */
.zw-scroll-card {
  width: 100%;
  overflow-y: auto;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;  /* iOS 惯性滚动 */
  overscroll-behavior: contain;      /* 防止底部/顶部拉动触发浏览器下拉刷新手势 */
  box-sizing: border-box;
  min-height: 0;                     /* flex 布局子项必备，允许收缩产生内部滚动 */
}

/* ---- 8b 普通表头单元格 sticky top=0 钉住 ----
          必须给 background + box-shadow，否则滚动时下面的行文字穿透"透明表头"，
          视觉上看起来像表头没固定（经验 208496 失败教训） */
.zw-scroll-card .el-table .el-table__header th.el-table__cell,
.zw-scroll-card .el-table th.el-table__cell,
.zw-scroll-card table.el-table__header thead th.el-table__cell {
  position: sticky;
  top: 0;
  z-index: 35;
  background: #f4f9ff !important;
  background-color: #f4f9ff !important;
  -webkit-text-fill-color: #1f2937;
  color: #1f2937;
  box-shadow: inset 0 -1px 0 rgba(11, 61, 145, 0.35),
              0 1px 3px rgba(16, 42, 94, 0.12);
}

/* ---- 8b-2 表头换行支持：AlarmCount 累计退服数 "累计退服数\n时间区间" 两行展示 ----
   Element 2.x 默认把 label 的 \n 折叠成空格；设置 pre-line 让 \n 真正变成换行。
   不带 \n 的普通表头（如"停电数量"）不受影响：pre-line 会合并空格、仅 \n 处换行。*/
.zw-scroll-card .el-table .el-table__header th.el-table__cell .cell,
.zw-scroll-card .el-table th.el-table__cell .cell,
.zw-scroll-card table.el-table__header thead th.el-table__cell .cell,
.el-table .el-table__header th.el-table__cell .cell {
  white-space: pre-line !important;
  line-height: 1.35;
}

/* ---- 8c 多级表头子表头（Daily/Weekly 的第二行表头），钉到第一行表头下方 ---- */
.zw-scroll-card .el-table .el-table__header tr:nth-child(2) th.el-table__cell {
  top: var(--zw-subheader-top, 38px);
  z-index: 34;
}

/* ---- 8d 双轴钉：既是固定列（序号/地市 fixed=left）又是表头 → 左上交叉点，更高 z-index ---- */
/* 【2026-07-09 明细页双列 fixed 拆分！】
   注意：明细页「序号列 + 地市列」两列都带 zw-fixed-city，都在 is-fixed-left 状态。
   下面第一组选择器：带 zw-fixed-city —— 绝对不能写 left:0 !important，否则两列完全重叠！
   只保留 sticky + 背景 + z-index：Element Plus 会按列顺序自计算 left。
   第二组选择器：不带 zw-fixed-city（单 fixed 列的二级页/其他页面，或通用 header 钉子） —— 保留 left:0!important 正常钉死。*/
.zw-scroll-card .el-table th.zw-fixed-city.is-fixed-left.el-table__cell {
  position: sticky !important;
  /* 故意不写"左=0 强制覆盖"：明细页双列 fixed 由 Element Plus 自计算 left（第1列=0 第2列=70px） */
  top: 0;
  z-index: 40 !important;  /* 40 > 普通表头 35 / 子表头 34 */
  background: #eaf2ff !important;
  background-color: #eaf2ff !important;
}
.zw-scroll-card .el-table th.el-table__cell.is-fixed-left,
.zw-scroll-card .el-table .el-table__header th.is-fixed-left.el-table__cell {
  position: sticky !important;
  left: 0 !important;
  top: 0;
  z-index: 40 !important;
  background: #eaf2ff !important;
  background-color: #eaf2ff !important;
}
/* 多级表头下第二行固定列子表头的双钉位置 */
.zw-scroll-card .el-table .el-table__header tr:nth-child(2) th.is-fixed-left.el-table__cell {
  top: var(--zw-subheader-top, 38px) !important;
  z-index: 39 !important;
}

/* ---- 8e 表体固定列 z-index 必须低于表头 35，否则滚上去会盖住表头 ---- */
.zw-scroll-card .el-table td.is-fixed-left.el-table__cell {
  z-index: 10 !important;
}

/* ---- 8f 防止 Element Plus 的多级 wrapper overflow:hidden 把 sticky <th> 裁掉 ----
   ⚠️ 关键修复（用户 2026-07-08 "表头还是没固定"的根因）：
   - .el-table 根容器默认 overflow:hidden → 即使滚动条在外层 zw-scroll-card，
     .el-table 仍然是 sticky<th> 的【裁剪祖先】，会把要钉到 zw-scroll-card 顶部的
     <th> 直接在 .el-table 框边界处裁掉 → sticky 直接失效，看起来像"没钉住"。
   - .el-table__body-wrapper / inner-wrapper 同样必须取消 overflow 裁剪。
   - header-wrapper 之前已经设过，保留。
*/
.zw-scroll-card .el-table                      { overflow: visible !important; }
.zw-scroll-card .el-table__header-wrapper      { overflow: visible !important; }
.zw-scroll-card .el-table__body-wrapper        { overflow: visible !important; }
.zw-scroll-card .el-table__inner-wrapper       { overflow: visible !important; }
.zw-scroll-card .el-table .hidden-columns,
.zw-scroll-card .el-table .el-table__header,
.zw-scroll-card .el-table thead                { background: transparent !important; }

/* ================================================================
   【2026-07-14 用户】整页滚动表头吸顶模式（停电/退服/告警明细二级页）
   ———— 2026-07-14 表头没吸顶的根因修复：祖先链 body/#app 有 overflow-x:hidden 破坏 viewport 粘性。
   现在改为【内部滚动容器】方案：contentScrollable=true 时 .zw-sub-body 自己是固定高度滚动容器，
   sticky th 相对【内部容器】top=0 吸顶，完全绕开祖先 overflow 污染。
   目标：上方筛选栏/meta信息/导出按钮 先随页面一起滚上去，表头触及容器顶部时才吸顶固定。
   实现要点：
   1. 不使用 Element Plus 内部 :height（tbody 内部滚动），不使用 zw-scroll-card 子滚动容器。
   2. 主方案（兼容微信X5旧内核）：通过 ZwPageLayout 模板动态给 zw-table-card 加 zw-table-card--no-clip class，
      直接取消 overflow:hidden 裁剪，完全不依赖 CSS :has()（旧X5不支持）。
   3. 兜底方案（现代浏览器）：:has() 选择器：如果 zw-table-card 内包含 .zw-wholepage-sticky，也取消 overflow:hidden。
   4. <th> sticky top = 0（相对内部容器 .zw-sub-body.zw-sub-body-scroll 的顶部）。
   5. 多级表头第二行 top 在第一行下方（38px）；fixed 列 + 表头交叉点 z-index 最高。
================================================================ */
/* 主方案：模板层显式加 class（X5兼容，不依赖:has()） */
.zw-table-card.zw-table-card--no-clip { overflow: visible !important; }
/* 兜底方案：现代浏览器 :has() 自动识别（不用模板加class也能生效） */
.zw-table-card:has(> .zw-wholepage-sticky),
.zw-table-card:has(.zw-wholepage-sticky)    { overflow: visible !important; }

.zw-wholepage-sticky .el-table                { overflow: visible !important; width: 100% !important; }
/* 【2026-07-15 终极修复 sticky vs 横向滚动冲突】
   - overflow-y:visible → 纵向不抢 sticky scrollport（保证 sticky top 相对外层 .zw-sub-body-scroll 生效）
   - overflow-x 不再强制覆盖 → 交回 Element Plus 默认样式/内联样式决定（只在列总宽真的超出时出现横向滚动条，避免在表头下方出现多余的滚动条占位） */
.zw-wholepage-sticky .el-table__body-wrapper   {
  overflow-y: visible !important;
  /* overflow-x: auto → 移除强制，回归 Element Plus 默认，避免多余滚动条出现在表头正下方 */
}
.zw-wholepage-sticky .el-table__inner-wrapper  { overflow: visible !important; }
/* ================================================================
   【2026-07-14 三次修复 sticky 生效保险】
   Element Plus 运行时可能通过 JS 给这些 wrapper 注入 transform / will-change / contain
   等属性以触发 GPU 加速，但这些属性都会【创建新的 containing block】，让 sticky 元素
   的定位对象从我们想要的 .zw-sub-body-scroll 变成中间某个 wrapper，从而 sticky 失效。
   显式覆盖为默认值阻断这种风险。
   —— 2026-07-15 终极修复：【从列表中移除 el-table__header-wrapper】
      因为终极兼容方案改为【JS 监听 scroll + transform:translateY 手动吸顶】，
      header-wrapper 需要允许 transform 属性（通过内联 style 注入）！
      其余 wrapper 仍保持 transform:none 阻断 containing block 创建。
================================================================ */
.zw-wholepage-sticky .el-table,
.zw-wholepage-sticky .el-table__body-wrapper,
.zw-wholepage-sticky .el-table__inner-wrapper,
.zw-wholepage-sticky .el-table__header-wrapper,
.zw-wholepage-sticky .el-table__fixed-header-wrapper,
.zw-wholepage-sticky .el-table__fixed-right-header-wrapper,
.zw-wholepage-sticky .el-table__fixed-body-wrapper,
.zw-wholepage-sticky .el-table__fixed,
.zw-wholepage-sticky .el-table__fixed-right,
.zw-wholepage-sticky .el-table .hidden-columns,
.zw-wholepage-sticky .el-table .el-table__header,
.zw-wholepage-sticky .el-table thead,
.zw-wholepage-sticky .el-table tbody,
.zw-wholepage-sticky .el-table tr,
.zw-wholepage-sticky .el-table th.el-table__cell,
.zw-wholepage-sticky .el-table td.el-table__cell {
  transform: none !important;
  -webkit-transform: none !important;
  will-change: auto !important;
  perspective: none !important;
  -webkit-perspective: none !important;
  filter: none !important;
  -webkit-filter: none !important;
  contain: layout style !important;
}

/* ================================================================
   【2026-07-15 终极兼容方案】JS 手动吸顶模式样式（微信X5旧内核 CSS sticky on table-cell 硬件级 bug 兜底）
   —— 原理：CSS sticky 作用在 th(table-cell) 在部分微信X5内核不生效，
      改为【JS 监听 .zw-sub-body-scroll 的 scroll 事件，实时计算 translateY
      通过内联 style.transform 直接把 .el-table__header-wrapper
      「钉」在滚动容器可视区顶部】。
   —— 为什么需要这些样式：
      1. header-wrapper 需要 position:relative（默认已满足），transform 才会生效；
      2. z-index 要高于表体内容，防止滚动时表体穿透；
      3. 不透明背景色 + 阴影保证视觉吸顶效果；
      4. transition 让滚动时无跳帧（手机GPU加速）。
================================================================ */
/* 2026-07-15 用户反馈「滚动过程中还是被遮挡」：去掉 transition！
   因为 JS 每帧 scroll 事件都在动态调整 translateY，transition: transform 0.08s 会让
   实际生效的 transform 延迟 80ms。快速滚动时，JS 已经算好 translateY(100px) 拉回安全区，
   但 CSS 动画要 80ms 才到位，这 80ms 内表头视觉上还停留在原位置，会短暂冲进顶栏下沿
   被 z-index:50 的蓝色标题栏盖住。transition 为 0 才能即时同步不延迟。 */
.zw-wholepage-sticky .el-table__header-wrapper {
  overflow: visible !important;
  z-index: 45 !important;
  background: #f4f9ff !important;
  background-color: #f4f9ff !important;
}
.zw-wholepage-sticky .el-table__fixed-header-wrapper,
.zw-wholepage-sticky .el-table__fixed-right-header-wrapper {
  z-index: 46 !important;
  background: transparent !important;
}
.zw-wholepage-sticky .el-table .hidden-columns,
.zw-wholepage-sticky .el-table .el-table__header,
.zw-wholepage-sticky .el-table thead          { background: transparent !important; }

/* 表头吸顶本体（两层机制保证稳定生效）：
   ① 优先层：.el-table__header-wrapper 整层 sticky（DIV display:block，不依赖 table 格式化上下文，100% 生效）
   ② 兜底层：<th> 自身 sticky（与旧版保持兼容，防止 wrapper sticky 被 Element Plus 内联样式覆盖时仍能吸顶） */
.zw-wholepage-sticky .el-table__header-wrapper {
  position: sticky !important;
  top: var(--zw-sticky-top, 4px) !important;
  z-index: 45 !important;       /* z-index 45：高于 td sticky(z-index 10+)，吸顶不被穿透；40+ 满足断言 */
  background: #f4f9ff !important;
  background-color: #f4f9ff !important;
  /* 【纵向 sticky scrollport 传递】
     y=visible：纵向不抢 scrollport，sticky top 正确相对外层 .zw-sub-body-scroll 生效
     x=hidden：Element Plus 默认 header-wrapper overflow-x:hidden（不参与横向滚动，靠 JS 同步 body-wrapper 的 scrollLeft） */
  overflow-y: visible !important;
  overflow-x: hidden !important;
  overflow: visible hidden !important;
}
/* 【关键：Element Plus 固定列 header sticky】
   地市列（唯一固定列）存在于独立的 .el-table__fixed (position:absolute) 容器中，
   但只要：
   1. .el-table__fixed / .el-table / .zw-wholepage-sticky 三层均无 transform / overflow!=visible 属性
      （transform:none + overflow:visible 已在前面规则保证）；
   2. .el-table__fixed 不设 overflow，则 sticky scrollport 仍统一为外层 .zw-sub-body-scroll；
   那么对 .el-table__fixed-header-wrapper 设置 sticky top 就直接与普通 header-wrapper 同步生效，
   不需要 JS 同步 position:fixed / transform，纯 CSS 性能最好。 */
.zw-wholepage-sticky .el-table__fixed-header-wrapper,
.zw-wholepage-sticky .el-table__fixed-right-header-wrapper {
  position: sticky !important;
  top: var(--zw-sticky-top, 4px) !important;
  z-index: 46 !important;
  background: #eaf2ff !important;
  background-color: #eaf2ff !important;
}
.zw-wholepage-sticky .el-table__fixed,
.zw-wholepage-sticky .el-table__fixed-right {
  overflow: visible !important;
  overflow-x: visible !important;
  overflow-y: visible !important;
}
.zw-wholepage-sticky .el-table .el-table__header th.el-table__cell,
.zw-wholepage-sticky .el-table th.el-table__cell,
.zw-wholepage-sticky table.el-table__header thead th.el-table__cell {
  position: sticky !important;
  top: var(--zw-sticky-top, 4px) !important;
  z-index: 35;
  background: #f4f9ff !important;
  background-color: #f4f9ff !important;
  -webkit-text-fill-color: #1f2937;
  color: #1f2937;
  box-shadow: inset 0 -1px 0 rgba(11, 61, 145, 0.35),
              0 1px 3px rgba(16, 42, 94, 0.12);
}
/* 多级表头第二行：top = 主表头 sticky top + 第一行高度（与普通列 th 规则一致） */
.zw-wholepage-sticky .el-table .el-table__header tr:nth-child(2) th.el-table__cell {
  top: calc(var(--zw-sticky-top, 4px) + var(--zw-subheader-top, 38px)) !important;
  z-index: 34;
}
/* 双轴交叉点：既是 fixed=left 固定列 又是表头 → 最高 z-index，保留 Element Plus 算的 left 值 */
.zw-wholepage-sticky .el-table th.zw-fixed-city.is-fixed-left.el-table__cell {
  position: sticky !important;
  top: var(--zw-sticky-top, 4px) !important;
  z-index: 40 !important;
  background: #eaf2ff !important;
  background-color: #eaf2ff !important;
}
.zw-wholepage-sticky .el-table th.el-table__cell.is-fixed-left,
.zw-wholepage-sticky .el-table .el-table__header th.is-fixed-left.el-table__cell {
  position: sticky !important;
  top: var(--zw-sticky-top, 4px) !important;
  z-index: 39 !important;
  background: #eaf2ff !important;
  background-color: #eaf2ff !important;
}
/* Fixed 列（左/右）的 header-wrapper 用独立 sticky，因为它在 .el-table__fixed 容器内（position:absolute）
   这个 wrapper 本身是 DIV，sticky 对它 100% 生效；z-index 比普通 header-wrapper 高一层，保证滚过去不被覆盖。 */
.zw-wholepage-sticky .el-table__fixed-header-wrapper,
.zw-wholepage-sticky .el-table__fixed-right-header-wrapper {
  position: sticky !important;
  top: var(--zw-sticky-top, 4px) !important;
  z-index: 46 !important;
  background: #eaf2ff !important;
  background-color: #eaf2ff !important;
}
/* 多级表头 + fixed 列：top = 主表头吸顶 + 子表头高度 */
.zw-wholepage-sticky .el-table .el-table__header tr:nth-child(2) th.is-fixed-left.el-table__cell {
  top: calc(var(--zw-sticky-top, 4px) + var(--zw-subheader-top, 38px)) !important;
  z-index: 39;
}
/* 表体 fixed 列：z-index 低于表头，滚上去不会盖住吸顶表头 */
.zw-wholepage-sticky .el-table td.is-fixed-left.el-table__cell {
  position: sticky !important;
  z-index: 10 !important;
}

/* ================================================================
   【2026-07-15 终极方案：纯 CSS sticky left 实现「地市列单独固定」】
   —— 放弃 Element Plus 原生 fixed=left（会把列抽出来打乱列顺序）。
   —— 原理：给带 className="zw-fixed-city" 的地市列（th + td）加 position:sticky; left:0;，
            滚动时当该列滚到左边缘（left=0）就粘住，实现左右滑动的固定效果。
   —— 优点：序号列 columns[0] 永远在地市列 columns[1] 前面（正常 DOM 顺序），
            初始视觉序号第 1 列、地市第 2 列；向左滑动时序号列滚出视口，地市列粘在最左边。
   —— 注意：sticky 元素必须显式有背景色，否则后面滚过来的列内容会透出来！
================================================================ */
/* ================================================================
   【2026-07-15 终极方案：纯 CSS sticky left 实现「地市列单独固定」—— 全局版（所有页面都生效）】
   —— 去掉 .zw-wholepage-sticky 前缀（之前只有明细页有 wholePageSticky=true 才带这个类），
      现在所有二级页（日指标/周指标/告警统计/告警明细/停电/退服数量页 / 明细页）统一使用全局规则，
      只要 th/td 带 className="zw-fixed-city"（就是地市列）就自动居中+吸左固定。
================================================================ */
/* 地市列表头：双 sticky（top 吸顶 + left 吸左）同时生效 —— 仅明细页 wholePageSticky=true 时 header sticky top 生效，其他页面只生效 left 吸左 */
.el-table th.zw-fixed-city.el-table__cell,
.el-table thead th.zw-fixed-city.is-leaf.el-table__cell,
.el-table .el-table__header th.zw-fixed-city.el-table__cell,
.zw-wholepage-sticky .el-table th.zw-fixed-city.el-table__cell {
  position: sticky !important;
  /* 非明细页（日指标/周指标/告警统计等）没有 --zw-sticky-top 变量 → sticky top: auto 即不生效；明细页 wholePageSticky=true 时 JS 会注入变量，此时双 sticky 生效 */
  top: var(--zw-sticky-top, auto) !important;
  left: 0 !important;
  z-index: 47 !important;              /* z-index 最高：既高于普通表头 th(z=35)，又高于表体 td(z=10) */
  background: #eaf2ff !important;     /* 显式浅蓝背景：盖住后面滚出来的普通列，不透光 */
  background-color: #eaf2ff !important;
  /* 【问题 1 修复：地市列文字显式居中（覆盖 Element Plus 默认左对齐） */
  text-align: center !important;
  -webkit-text-fill-color: #1f2937;
  color: #1f2937;
  /* 右侧 1px 阴影：视觉上和 Element Plus 原生 fixed 列一致（分割线效果） */
  box-shadow: inset 0 -1px 0 rgba(11, 61, 145, 0.35),
              0 1px 3px rgba(16, 42, 94, 0.12),
              1px 0 0 rgba(11, 61, 145, 0.18) !important;
}
/* 内部 .cell 也强制居中（Element Plus 会把内容塞到 .cell 里，需二次覆盖默认对齐） */
.el-table th.zw-fixed-city.el-table__cell .cell,
.el-table thead th.zw-fixed-city.is-leaf.el-table__cell .cell {
  text-align: center !important;
  justify-content: center !important;
  display: block !important;
}
/* 地市列表体：单 sticky left 吸左 */
.el-table td.zw-fixed-city.el-table__cell,
.el-table tbody td.zw-fixed-city.el-table__cell,
.zw-wholepage-sticky .el-table td.zw-fixed-city.el-table__cell {
  position: sticky !important;
  left: 0 !important;
  z-index: 15 !important;              /* z-index 高于普通 td(z=1/auto)，低于表头吸顶 z-index */
  background-color: inherit !important;/* 表体背景：继承整行背景色（wholeRowCityBg 给整行加的哈希色），不破坏整行视觉统一 */
  /* 【问题 1 修复：表体地市列文字同样居中（覆盖 Element Plus 默认左对齐） */
  text-align: center !important;
  /* 右侧 1px 阴影：和表头保持一致的分割线效果 */
  box-shadow: 1px 0 0 rgba(11, 61, 145, 0.12) !important;
}
/* 表体 td 内部 .cell 强制居中 */
.el-table td.zw-fixed-city.el-table__cell .cell {
  text-align: center !important;
  justify-content: center !important;
  display: block !important;
}

/* 六修：JS 手动 translateY 方案已经退役，下面的 header-wrapper / fixed-wrapper transform 设置仅用于极端兜底，
   默认不启用。真正生效的是上一段 th position: sticky CSS。 */

/* ---------- 9. 手机端（≤ 560px）：二级日报/周报表格整体紧凑化 ---------- */
@media (max-width: 560px) {
  /* ⚠️ 2026-07-14 三次修复 overflow-x/y 规范陷阱（关键！）
     CSS Overflow 3 规定：x 或 y 一侧非 visible 时，另一侧若是默认 visible 会被浏览器【静默强转 auto】。
     原写法只写 overflow-x:hidden 没写 y，会让 html / body / #app / .zw-page-layout / .zw-sub-body
     全部意外变成 overflow-y:auto → 全部变成滚动容器，sticky th 就近绑定到错误的祖先而失效。
     现对每个元素两方向都【显式声明】：非内部滚动的外层（html/body/#app/.zw-page-layout/.zw-sub-body:not(.zw-sub-body-scroll)）
     的 y 方向强制 visible，只有真正的内部滚动容器 .zw-sub-body-scroll 才允许 y=auto！ */
  html, body, #app, .zw-page-layout {
    width: 100%; max-width: 100%;
    box-sizing: border-box;
    overflow-x: hidden;  /* 禁止页面外层被 el-table 内部 2400px 宽的滚动内容撑破 */
    overflow-y: visible; /* ⬅️ 显式声明！防止被浏览器静默转成 auto 抢夺滚动容器 */
    -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
    font-size: 14px;
  }
  /* 非内部滚动模式的 .zw-sub-body（整页滚动模式）：y 方向 visible */
  .zw-sub-body:not(.zw-sub-body-scroll) {
    width: 100%; max-width: 100%;
    box-sizing: border-box;
    overflow-x: hidden;
    overflow-y: visible; /* ⬅️ 显式声明！防止规范陷阱 */
    -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
    font-size: 14px;
  }
  /* 内部滚动容器模式的 .zw-sub-body.zw-sub-body-scroll：y=auto 才是真滚动，x=hidden 防止撑破
     横向交给 Element Plus 内部 body-wrapper/header-wrapper 配对处理（JS 同步 scrollLeft）。 */
  .zw-sub-body.zw-sub-body-scroll {
    width: 100%; max-width: 100%;
    box-sizing: border-box;
    overflow-x: hidden;   /* 禁止外层横向滚动；Element Plus 内部横向滚动配对处理 */
    overflow-y: auto;   /* ⬅️ 唯一允许 y 滚动的外层 */
    -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
    font-size: 14px;
  }
  body { margin: 0; padding: 0; }
  /* 2026-07-15 终极修复：.zw-subpage 已有 padding-top（顶栏占位），zw-sub-body 不再加 var(--zw-nav-h)，避免双重留白叠加 */
  .zw-sub-body:not(.zw-sub-body-scroll) { padding: 0 6px 40px; }
  .zw-sub-body.zw-sub-body-scroll {
    max-height: calc(100svh - var(--zw-nav-h) - env(safe-area-inset-top, 0px));
    height: calc(100svh - var(--zw-nav-h) - env(safe-area-inset-top, 0px));
    padding: 0 6px 6px;
  }
  .zw-page-layout { min-height: 100svh; }
  /* 筛选卡片更紧凑 */
  .zw-filter-card { padding: 10px 8px 10px; margin-bottom: 10px; }
  /* 强制筛选行单列 + inline form 子项 width:100%（覆盖 Element Plus 默认 inline flex） */
  .zw-filter-row {
    grid-template-columns: 1fr !important;
    gap: 8px;
  }
  .zw-filter-row .el-form-item,
  .el-form--inline .zw-filter-row .el-form-item,
  .el-form--inline .el-form-item {
    width: 100% !important;
    margin-right: 0 !important;
  }
  .el-form--inline { display: block; } /* 解除 inline form 的 nowrap 弹性盒 */
  .zw-filter-actions { gap: 8px; flex-wrap: nowrap; align-items: stretch; }
  .zw-filter-actions .el-button {
    padding: 8px 10px; font-size: 13px; min-height: 36px; border-radius: 8px;
  }
  .zw-btn-search { flex-grow: 3; }
  .zw-btn-reset  { flex-grow: 2; }
  .el-form-item { margin-bottom: 4px !important; }
  /* 表格元信息栏更小 */
  .zw-table-meta { padding: 6px 4px 8px; font-size: 11.5px; flex-wrap: wrap; gap: 4px; }
  /* Element Plus 表格字号 / 行高调小（手机端一屏能看到更多数据） */
  .el-table { font-size: 12px; --el-table-font-size: 12px; width: 100% !important; max-width: 100%; }
  /* 2026-08-12：停电明细/退服明细允许表格宽度自适应，不强制100% */
  .zw-page-OutageDetail .el-table,
  .zw-page-OfflineDetail .el-table { width: auto !important; max-width: none !important; }
  .zw-page-OutageDetail .el-table__inner-wrapper,
  .zw-page-OfflineDetail .el-table__inner-wrapper { max-width: none !important; }
  .el-table th.el-table__cell { font-size: 11.5px; padding: 8px 4px; }
  .el-table td.el-table__cell { padding: 6px 4px; }
  /* 日报/周报单元格（当前值 + 同比对比）字号调小 */
  .dw-cell-cur { font-size: 12.5px; }
  .dw-cell-cmp { font-size: 10.5px; margin-top: 2px; letter-spacing: .1px; }
  /* 合计行字号小一点避免被放大 */
  .el-table .zw-summary-row > td { font-size: 12.5px; }
  /* 表格外卡片：去横向 padding 让表格占满宽度（手机屏本来就窄） */
  .zw-table-card { padding: 2px 0 6px; border-radius: 8px; max-width: 100%; }
  /* 固定列宽度更窄（手机屏原来太宽，尽量缩短） */
  .el-table td.zw-fixed-city.is-fixed-left,
  .el-table th.zw-fixed-city.is-fixed-left { min-width: 65px !important; width: 65px !important; }
  /* 2026-08-12：序号列在手机端也缩短 */
  .zw-page-OutageDetail .el-table td.is-fixed-left:not(.zw-fixed-city),
  .zw-page-OutageDetail .el-table th.is-fixed-left:not(.zw-fixed-city),
  .zw-page-OfflineDetail .el-table td.is-fixed-left:not(.zw-fixed-city),
  .zw-page-OfflineDetail .el-table th.is-fixed-left:not(.zw-fixed-city) { min-width: 50px !important; width: 50px !important; }
  /* 2026-08-12：停电明细/退服明细表格卡片允许横向滚动 */
  .zw-page-OutageDetail .zw-table-card,
  .zw-page-OfflineDetail .zw-table-card { overflow-x: auto !important; }
}

/* ============================================================
   2026-08-12：生成图片时清除固定列边框的全局类
   ============================================================ */
.zw-no-border,
.zw-no-border * {
  border: none !important;
  border-top: none !important;
  border-bottom: none !important;
  border-left: none !important;
  border-right: none !important;
  box-shadow: none !important;
}
.zw-no-border-sep {
  display: none !important;
}

/* ============================================================
   2026-07-15：单页专属样式 —— 通过 .zw-page-{Name} 独立类精准命中，
   避免改动全局规则影响其他页面
   ============================================================ */

/* --------------- 告警统计页 AlarmCount：自适应宽度 --------------- */
/* 2026-08-12：改用 table-layout: auto + minWidth，让表格自动撑满容器宽度 */
.zw-page-AlarmCount .el-table {
  table-layout: auto !important;
  width: 100% !important;
}
.zw-page-AlarmCount .zw-table-card,
.zw-page-AlarmCount .zw-sub-body { overflow-x: auto !important; }
.zw-page-AlarmCount .el-table__inner-wrapper { width: 100% !important; max-width: 100% !important; }
/* ========== 2026-07-15 修复 ==========
   (A) 所有列（地市/三个数字列）统一强制居中 + 统一表头高度 44px 垂直居中
       —— 第三列表头是两行（累计退服数+时间区间），其他三列是一行，若高度不同，
          Element Plus 内部列宽计算会出现偏差，导致截图时列宽不一致。
       —— 所有 th 统一高度 44px，行高 44px，一行文字的列自动垂直居中，
          两行文字的列（第三列）内部用 zw-two-line-header 自行撑开。
   (B) 两行表头（累计退服数）差异化渲染：主标题加粗+主色，副标题小字号+灰字，更直观。*/
.zw-page-AlarmCount .el-table th.el-table__cell,
.zw-page-AlarmCount .el-table td.el-table__cell {
  text-align: center !important;
}
.zw-page-AlarmCount .el-table th.el-table__cell {
  height: 44px !important;       /* 所有列表头统一高度 44px */
  padding: 0 !important;         /* 取消默认 padding，避免撑大 th.offsetWidth */
  line-height: 44px !important;  /* 一行文字自动垂直居中 */
  vertical-align: middle !important;
}
.zw-page-AlarmCount .el-table th.el-table__cell .cell,
.zw-page-AlarmCount .el-table td.el-table__cell .cell {
  text-align: center !important;
  justify-content: center !important;
  display: block !important;
  white-space: pre-wrap !important;
  word-break: break-all !important;
  line-height: 1.4;
  padding: 0 2px !important;  /* 2026-07-15：减少左右内边距，防止 colgroup sync 读取 offsetWidth 过大 */
}
/* (B) 两行表头差异化样式：通过 #header 插槽渲染的 zw-two-line-header
   —— 去掉左右 padding（2px → 0）防止 th offsetWidth 被撑大；
   —— 整体高度 ≤ 44px（main line-height 20 + sub line-height 16 + 2 间距 = 38 ≤ 44） */
.zw-page-AlarmCount .el-table th.el-table__cell .zw-two-line-header {
  line-height: 1 !important;
  padding: 4px 0 !important;  /* 仅上下内边距，左右为 0，不撑宽度 */
}
.zw-page-AlarmCount .el-table th.el-table__cell .zw-two-line-header__main {
  line-height: 20px !important;
  margin-bottom: 2px !important;
}
.zw-page-AlarmCount .el-table th.el-table__cell .zw-two-line-header__sub {
  line-height: 16px !important;
  letter-spacing: 0;
}
/* 普通一行表头的 th（第一/二/四列）：cell 里的文字垂直居中 */
.zw-page-AlarmCount .el-table th.el-table__cell:not(:has(.zw-two-line-header)) .cell {
  padding-top: 12px !important;
  padding-bottom: 12px !important;
  line-height: 20px !important;
}

/* ============================================================
   zw-empty-state：二级页接口空返回时的"无数据"样式卡片
   用户 2026-07-02 硬性要求：
    ① 不展示 el-table（表头+空态文字也不能展示）；
    ② 展示独立的空态卡片（图标 + 提示 + 刷新按钮）；
    ③ 任何接口空/失败时禁止用 mock 默认数据顶替。
   ============================================================ */
.zw-empty-state {
  min-height: 360px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 36px 24px;
  margin: 18px 14px 24px;
  background: linear-gradient(180deg, #ffffff 0%, #f4f8ff 100%);
  border: 1px dashed rgba(21, 101, 192, 0.28);
  border-radius: 14px;
  box-shadow: 0 2px 12px rgba(21, 101, 192, 0.06);
  text-align: center;
}
body.zw-in-miniprogram .zw-empty-state {
  background: linear-gradient(180deg, #ffffff 0%, #fff8f8 100%);
  border: 1px dashed rgba(198, 40, 40, 0.28);
  box-shadow: 0 2px 12px rgba(198, 40, 40, 0.06);
}
.zw-empty-state .zw-empty-icon {
  width: 72px; height: 72px;
  border-radius: 50%;
  background: #e0ecff;
  color: var(--zw-primary, #1565c0);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 34px;
  box-shadow: inset 0 0 0 4px rgba(21, 101, 192, 0.08);
}
body.zw-in-miniprogram .zw-empty-state .zw-empty-icon {
  background: #ffe8e8;
  color: var(--zw-primary, #c62828);
  box-shadow: inset 0 0 0 4px rgba(198, 40, 40, 0.08);
}
.zw-empty-state .zw-empty-icon .el-icon,
.zw-empty-state .zw-empty-icon svg { width: 34px !important; height: 34px !important; }
.zw-empty-state .zw-empty-title {
  font-size: 15.5px;
  font-weight: 600;
  color: #1f2a44;
  line-height: 1.5;
  max-width: 420px;
}
.zw-empty-state .zw-empty-desc {
  font-size: 12.5px;
  color: #6b7280;
  line-height: 1.55;
  max-width: 420px;
}
.zw-empty-state .zw-empty-btn {
  margin-top: 4px;
  border-radius: 999px;
  padding: 8px 20px;
  font-size: 13px;
}
/* 移动端空态卡调整：高度降低、字号缩小、圆角柔和 */
@media (max-width: 480px) {
  .zw-empty-state { min-height: 280px; padding: 28px 16px; margin: 12px 10px 18px; border-radius: 12px; gap: 10px; }
  .zw-empty-state .zw-empty-icon { width: 60px; height: 60px; font-size: 28px; }
  .zw-empty-state .zw-empty-icon .el-icon,
  .zw-empty-state .zw-empty-icon svg { width: 28px !important; height: 28px !important; }
  .zw-empty-state .zw-empty-title { font-size: 14px; }
  .zw-empty-state .zw-empty-desc { font-size: 11.5px; }
  .zw-empty-state .zw-empty-btn { padding: 6px 16px; font-size: 12.5px; }
}

/* ============================================================
 * 10. 「生成图片 → 长按保存到相册」按钮 / 预览层 / 提示条
 *     配合 _makePage 模板的「生成图片」按钮与 zw-capture-mask 预览层。
 *     用户 2026-07-02：H5 无跨端直写相册能力，统一走预览层 + 长按保存。
 * ============================================================ */

/* 10.1 按钮：放在 zw-table-meta 右侧（和「返回首页」一行）*/
.zw-btn-capture-image {
  margin-right: 8px;
  box-shadow: 0 1px 2px rgba(198,40,40,.1);
}
.zw-btn-capture-image .el-icon { vertical-align: -1px; }

/* 10.2 预览层全屏遮罩：黑底 + 顶部提示条 + 可滚动图片区
   ⚠️ 交互层（zw-capture-click-layer）是独立的全屏 div，z-index: 2，放在"装饰层 bg"之上、
   "交互节点 hint + scroll"之下。非交互区的任何点击 → 100% 命中 click-layer → 冒泡给 mask → 关闭；
   交互节点（.zw-capture-interact 与 .zw-capture-scroll）的 z-index: 3，覆盖在 click-layer 之上，
   pointer-events:auto 正常响应，但各自用 @click.stop 阻止冒泡（关闭按钮除外），确保点击不穿透到 mask。
   这种「分层 + z 轴叠放」方案彻底避开 flex 子项撑满高度后「没有 mask 本体可点击」的历史坑。 */
.zw-capture-mask {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: transparent;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
/* 背景装饰层：黑色 + 毛玻璃；pointer-events:none 让点击穿透它，继续命中 click-layer / 交互节点。 */
.zw-capture-bg {
  position: absolute;
  inset: 0;
  background: rgba(0,0,0,.92);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  z-index: 0;
  pointer-events: none;
}
/* 关闭点击承接层：独立全屏一层，负责"点击空白关闭遮罩"。
   z-index: 2 位于装饰层之上 / 交互节点之下。 */
.zw-capture-click-layer {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: auto;
  background: transparent;
  /* 调试期：临时打开可看见这一层，正式代码必须 transparent
   background: rgba(255,0,0,.1); */
}
/* 两个 flex 子项本体不响应事件（它们内部的交互节点会覆盖） */
.zw-capture-hint,
.zw-capture-scroll { position: relative; z-index: 3; pointer-events: none; }
/* 交互节点：开启 pointer-events，承接点击；z-index: 3 > click-layer 的 2，所以在上层 */
.zw-capture-interact {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  z-index: 3;
}
/* 滚动容器：开启 pointer-events（拖/滚/点图片都需要走这里）
   空白区点击：scroll → 冒泡到 mask → 关闭 ✓
   点 <img>：img 上 @click.stop 拦截 → 不关闭 ✓ */
.zw-capture-scroll { pointer-events: auto; }

/* 10.3 顶部黑条提示：「长按保存图片」+ 右侧关闭按钮 */
.zw-capture-hint {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 10px 14px;
  background: linear-gradient(180deg, #000 0%, #111 100%);
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .5px;
  border-bottom: 1px solid #222;
  /* iOS 安全区适配（刘海屏/灵动岛） */
  padding-top: calc(10px + env(safe-area-inset-top, 0px));
}
.zw-capture-hint-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  width: 22px;
  color: #ffd54f; /* 琥珀色，提示醒目 */
}

/* ===========================================================
 *  2026-07-09 新增：告警数量 地市→区县 下钻面包屑 / 可点行视觉样式
 * =========================================================== */
.zw-drill-breadcrumb {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px 4px;
  font-size: 13px;
  color: #1f2937;
}
.zw-drill-breadcrumb .el-button {
  font-size: 13px;
  padding: 2px 0;
}
.zw-drill-sep {
  color: #94a3b8;
  margin: 0 2px;
}
.zw-drill-current {
  color: #0b3d91;
  font-weight: 600;
}
/* drillLevel=0：表格行可点击（hover 高亮 + hand pointer） */
.el-table.zw-drillable .el-table__body tr:not(.zw-summary-row) > td {
  cursor: pointer;
}
.el-table.zw-drillable .el-table__body tr:hover:not(.zw-summary-row) > td {
  background-color: #e6efff !important;  /* 与品牌蓝统一的 hover 色 */
  -webkit-transition: background-color .15s ease;
  transition: background-color .15s ease;
}
.zw-capture-close {
  margin-left: auto;
  padding: 4px 12px !important;
  font-size: 13px !important;
}

/* 10.4 图片滚动区：允许表格大图横向/纵向完整滚动查看；
   ⚠️ 不放 padding：因为 stop 冒泡绑在 <img> 上而不是容器上，
   这样点击 scroll 内部「图片周围空白区」会正常冒泡到 mask → 触发关闭（点击空白关闭）。 */
.zw-capture-scroll {
  flex: 1 1 auto;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  padding: 0;
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
  /* 2026-08-06 修复：flex 容器滚动问题的关键
     min-height: 0 解决 flex 子项默认 min-height:auto 导致内容无法滚动的问题 */
  min-height: 0;
  /* 关键：允许横向滚动 */
  overflow-x: auto;
}
.zw-capture-img {
  display: block;
  /* 视觉外边距从 scroll 的 padding 迁到 img 的 margin，
     这样图片周围的黑边不属于 img，点击它不会被 img 的 stop 拦截 → 冒泡到 mask 关闭。 */
  margin: 12px;
  /* 图片撑满容器宽度，保持原始比例 */
  max-width: 100%;    /* 撑满容器宽度，但不超过实际像素 */
  min-width: 0;       /* 允许图片在窄容器中缩小 */
  width: auto;
  height: auto;
  background: #fff;
  border-radius: 4px;
  box-shadow: 0 6px 18px rgba(0,0,0,.5);
  -webkit-user-drag: none;
  user-select: none;
  -webkit-touch-callout: default;  /* iOS 关键：允许长按菜单（否则禁用用户操作会调不出「保存图片」） */
}
@media (hover: none) and (pointer: coarse) {
  /* 移动端：允许图片「长按 → 保存图片」，不阻止系统手势 */
  .zw-capture-img {
    -webkit-touch-callout: default;
    user-select: text;  /* 配合 callout 才会弹保存菜单 */
  }
}

/* 10.5 预览层超窄屏额外适配 */
@media (max-width: 480px) {
  .zw-capture-hint { font-size: 14px; padding: 8px 12px; gap: 6px; }
  .zw-capture-hint-icon { font-size: 16px; width: 18px; }
  .zw-capture-close { padding: 3px 10px !important; font-size: 12px !important; }
  .zw-capture-scroll { padding: 8px; }
}
@media (max-width: 380px) {
  .zw-btn-capture-image { padding: 4px 10px !important; font-size: 11.5px !important; margin-right: 4px; }
}

/* ---------- 9. 超窄屏（≤ 380px，小屏安卓/SE）额外再紧凑 ---------- */
@media (max-width: 380px) {
  .el-table { font-size: 11.5px; }
  .el-table th.el-table__cell { font-size: 11px; padding: 7px 3px; }
  .el-table td.el-table__cell { padding: 5px 3px; }
  .dw-cell-cur { font-size: 12px; }
  .dw-cell-cmp { font-size: 10px; }
  .zw-home-hero-copy .brand { font-size: 32px; letter-spacing: 4px; }
}

/* ============================================================
 *  11. 小程序环境 - 全面红色主题覆盖
 *      解决内联样式硬编码蓝色(#0b3d91, #1565c0)在小程序环境中仍显示蓝色的问题
 * ============================================================ */

/* 11.1 两行表头主标题（累计退服数/实时退服数的主标题） */
body.zw-in-miniprogram .zw-two-line-header__main {
  color: #8e0000 !important;
}

/* 11.2 下钻面包屑当前项 */
body.zw-in-miniprogram .zw-drill-current {
  color: #8e0000 !important;
}

/* 11.3 表格行可点击hover高亮 */
body.zw-in-miniprogram .el-table.zw-drillable .el-table__body tr:not(.zw-summary-row):hover > td {
  background-color: #ffe8e8 !important;
}

/* 11.4 表格表头背景色 */
body.zw-in-miniprogram .el-table th.el-table__cell {
  background: #fff5f5 !important;
  color: #8e0000 !important;
}

/* 11.5 下钻提示文字（覆盖内联 style="color:#1565c0"） */
body.zw-in-miniprogram [style*="color:#1565c0"] {
  color: #c62828 !important;
}

/* 11.6 退服类型标签（覆盖内联样式 color:#0b3d91） */
body.zw-in-miniprogram [style*="color:#0b3d91"] {
  color: #8e0000 !important;
  -webkit-text-fill-color: #8e0000 !important;
}

/* 11.7 退服类型标签背景（覆盖内联样式 background:rgba(227,242,253,.7)） */
body.zw-in-miniprogram [style*="background:rgba(227,242,253"] {
  background: #ffebee !important;
}

/* 11.8 全省汇总行内联样式覆盖 */
body.zw-in-miniprogram [style*="background:linear-gradient(135deg,#e6efff"] {
  background: linear-gradient(135deg, #ffe8e8, #ffd5d5) !important;
}

/* 11.9 生成图片按钮和返回首页按钮 - 小程序环境改为红色实心背景+白色文字 */
body.zw-in-miniprogram .zw-btn-capture-image,
body.zw-in-miniprogram .zw-btn-back-home {
  --el-button-bg-color: #c62828 !important;
  --el-button-border-color: #c62828 !important;
  --el-button-hover-bg-color: #ef5350 !important;
  --el-button-hover-border-color: #ef5350 !important;
  --el-button-active-bg-color: #8e0000 !important;
  --el-button-active-border-color: #8e0000 !important;
  --el-button-text-color: #ffffff !important;
  --el-button-hover-text-color: #ffffff !important;
  --el-button-active-text-color: #ffffff !important;
  color: #ffffff !important;
  box-shadow: 0 4px 10px rgba(198, 40, 40, .3) !important;
}

/* 11.10 菜单卡片图标渐变（首页） */
body.zw-in-miniprogram .zw-menu-card[data-key="daily"] .mc-icon {
  background: linear-gradient(135deg, #ef5350, #c62828) !important;
}
body.zw-in-miniprogram .zw-menu-card[data-key="weekly"] .mc-icon {
  background: linear-gradient(135deg, #ff7043, #c62828) !important;
}

/* 11.11 首页Hero区品牌渐变文字 */
body.zw-in-miniprogram .zw-home-hero-copy .brand-gradient {
  background: linear-gradient(90deg, #ef5350 0%, #c62828 60%, #8e0000 100%) !important;
  -webkit-background-clip: text !important;
  background-clip: text !important;
}

/* 11.12 告警统计页面特殊表头颜色 */
body.zw-in-miniprogram .zw-page-AlarmCount .el-table th.el-table__cell .cell {
  color: #8e0000 !important;
}
