/* ══════════════════════════════════════════════════════════════════
   电竞馆经营看板 · 双主题
   ──────────────────────────────────────────────────────────────────
   约定（改样式前先读这段）：
   · 组件样式只允许引用变量，不写死颜色。否则切主题必漏。
   · 深色不是"反色"，而是另一套配色，只覆盖变量值，组件规则一行不动。
   · `html[data-theme]` 由 <head> 里的内联脚本在首屏前写好，避免闪白。
   · 图表不吃 CSS 变量（Chart.js 把颜色写在 canvas 上），所以 app.js 里
     那些颜色是「渲染时读变量」+ 切主题后重建图表，见 app.js 的主题模块。
   ══════════════════════════════════════════════════════════════════ */

/* ── 浅色（默认）──────────────────────────────────────────────── */
:root {
  /* 骨架色 */
  --bg:      #f3f4f9;
  --card:    #ffffff;
  --line:    #e6e8f0;
  --line2:   #f0f1f6;
  --tx:      #14161f;
  --tx2:     #6b7280;
  --tx3:     #9aa1ae;
  --pri:     #5b5bd6;
  --pri-soft:#eef0fd;
  --pri-hover:#4a4ac4;
  --up:      #e5484d;   /* 涨 · 红（中国习惯，别改成绿） */
  --down:    #16a34a;   /* 跌 · 绿 */
  --warn:    #f59e0b;
  --radius:  14px;

  /* 表面层次：elev=浮起面(原 #fff) · field=输入框静息底 · hover=行悬停
     soft=弱底(引用块/键值格) · head-bg=顶栏半透明 · overlay=遮罩 */
  --elev:    #ffffff;
  --field:   #fafbfd;
  --hover:   #fafbfd;
  --soft:    #f7f8fc;
  --head-bg: rgba(255,255,255,.88);
  --overlay: rgba(20,22,31,.42);
  --mono-bg: rgba(20,22,31,.06);
  --on-pri:  #ffffff;                     /* 主色按钮上的字 */

  /* 图表（app.js 渲染时读取） */
  --grid:    #f0f1f6;
  --tip-bg:  rgba(20,22,31,.92);
  --code-bg: #1e2130;                    /* SQL 代码块：两套主题都用深底，语法感更稳 */
  --code-tx: #c8d0e8;

  /* 语义底色 */
  --warn-bg:   #fff8ec;
  --warn-line: #fde3b8;
  --warn-tx:   #8a5a04;
  --warn-tx2:  #7a4d02;
  --err-bg:    #fdf0f0;
  --err-line:  #f6d5d5;
  --err-tx:    #a12328;
  --bad-bg:    #fdecec;
  --ok-fg:     #1d8a56;                       /* 正常值守标注（如「吧台有人」） */
  --ok-bg:     rgba(34, 160, 94, 0.14);
  --ok-line:   rgba(34, 160, 94, 0.35);

  /* 排行榜前三：金银铜 */
  --rank1:   #b8860b;
  --rank2:   #7b8794;
  --rank3:   #a9714b;
  --bar-grad: linear-gradient(90deg, #6366f1, #8b5cf6);

  /* 呼吸点动画要拆成 rgb 分量，rgba() 里塞不进 hex 变量 */
  --up-rgb: 229,72,77;

  --shadow:    0 1px 2px rgba(20,22,31,.04), 0 4px 14px rgba(20,22,31,.05);
  --shadow-lg: 0 12px 40px rgba(20,22,31,.09);
  --shadow-xl: 0 20px 60px rgba(0,0,0,.22);
  color-scheme: light;
}

/* ── 深色 ────────────────────────────────────────────────────────
   保留靛蓝主色作为品牌识别（提亮一档以适配深底），底色走冷调深灰，
   不用纯黑 —— 纯黑上放卡片会失去层次，且红绿涨跌色会显得刺眼。 */
html[data-theme="dark"] {
  --bg:      #0e1015;
  --card:    #171a22;
  --line:    #272b37;
  --line2:   #21242e;
  --tx:      #e7e9f0;
  --tx2:     #a3aab9;
  --tx3:     #7d8596;
  --pri:     #8b8bf5;
  --pri-soft:#262a45;
  --pri-hover:#a3a3fb;
  --up:      #ff5b60;
  --down:    #34d17e;
  --warn:    #f2a93b;

  --elev:    #21252f;
  --field:   #1c1f28;
  --hover:   #1d212b;
  --soft:    #1b1e27;
  --head-bg: rgba(14,16,21,.86);
  --overlay: rgba(0,0,0,.62);
  --mono-bg: rgba(255,255,255,.09);
  --on-pri:  #0e1015;                     /* 亮底按钮上用深字，对比更足 */

  --grid:    #2a2f3d;
  --tip-bg:  rgba(4,5,8,.96);
  --code-bg: #0a0c11;
  --code-tx: #c8d0e8;

  --warn-bg:   rgba(242,169,59,.12);
  --warn-line: rgba(242,169,59,.32);
  --warn-tx:   #f0b860;
  --warn-tx2:  #f6cd8f;
  --err-bg:    rgba(255,91,96,.12);
  --err-line:  rgba(255,91,96,.32);
  --err-tx:    #ff9298;
  --bad-bg:    rgba(255,91,96,.16);
  --ok-fg:     #34d17e;                       /* 正常值守标注（深色下提亮一档） */
  --ok-bg:     rgba(52, 209, 126, 0.14);
  --ok-line:   rgba(52, 209, 126, 0.35);

  --rank1:   #e0b341;
  --rank2:   #a8b4c4;
  --rank3:   #cf9469;
  --bar-grad: linear-gradient(90deg, #7c7cf0, #a97cf5);

  --up-rgb: 255,91,96;

  --shadow:    0 1px 2px rgba(0,0,0,.4), 0 4px 14px rgba(0,0,0,.3);
  --shadow-lg: 0 12px 40px rgba(0,0,0,.45);
  --shadow-xl: 0 20px 60px rgba(0,0,0,.55);
  color-scheme: dark;                     /* 滚动条/表单原生控件跟着变深 */
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0; padding: 0;
  background: var(--bg);
  color: var(--tx);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
               "Microsoft YaHei", "Hiragino Sans GB", sans-serif;
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* ── 颜色工具类 ────────────────────────────────────────────────
   给 JS 拼 HTML 时用，替代 `style="color:#9aa1ae"` 这类写死的内联色。
   好处：切主题时这些内容**不用重绘**，CSS 自己就跟着变了。
   （图表不一样 —— 颜色画在 canvas 上，必须重建，见 app.js。） */
.c-tx2  { color: var(--tx2); }
.c-tx3  { color: var(--tx3); }
.c-warn { color: var(--warn); }
.c-up   { color: var(--up); }
.c-down { color: var(--down); }

/* ── 主题切换按钮 ──────────────────────────────────────────────── */
.btn-theme {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); background: var(--elev); color: var(--tx2);
  padding: 6px 11px 6px 9px; border-radius: 9px; font-size: 13px;
  font-family: inherit; cursor: pointer; transition: .15s; line-height: 1.2;
}
.btn-theme:hover { border-color: var(--pri); color: var(--pri); background: var(--pri-soft); }
.btn-theme:active { transform: scale(.97); }
.btn-theme svg { width: 15px; height: 15px; display: block; }
/* 图标与文案由主题属性决定，JS 只负责改 html[data-theme] 那一个值。
   做成声明式的好处：不会有「按钮说深色、页面已经是浅色」这种不同步。 */
html[data-theme="light"] .ic-moon,
html[data-theme="dark"]  .ic-sun,
html[data-theme="light"] [data-for="dark"],
html[data-theme="dark"]  [data-for="light"] { display: none; }
/* 窄屏只留图标，省出顶栏空间 */
@media (max-width: 560px) {
  html[data-theme] .btn-theme .t-label { display: none; }
  .btn-theme { padding: 6px 9px; }
}

/* ── 顶栏 ─────────────────────────────────────────────────── */
header {
  position: sticky; top: 0; z-index: 50;
  background: var(--head-bg);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
}
.head-in {
  max-width: 1180px; margin: 0 auto; padding: 12px 18px 0;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.brand { font-size: 17px; font-weight: 700; letter-spacing: .3px; display: flex; align-items: center; }
/* 左上角品牌标：直接吃 brand.png，不另外画 —— 换 LOGO 只换那张图 */
.brand-logo { width: 24px; height: 24px; display: block; margin-right: 8px; border-radius: 6px; }
.brand em {
  font-style: normal; color: var(--pri);
  background: var(--pri-soft); padding: 2px 7px; border-radius: 6px; margin-right: 7px;
  font-size: 13px;
}
.head-right { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.stamp { font-size: 12.5px; color: var(--tx3); }
/* 当前登录账号。总密码登录时没有账号，这个标签整体不显示（admin.js 控制）。 */
.who {
  font-size: 12.5px; color: var(--tx2); max-width: 110px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.who::before {
  content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--pri); margin-right: 5px; vertical-align: 1px;
}
/* 数据过期 / 正在更新：让「刷新到底有没有在动」一眼可见 */
.stamp.stale { color: var(--warn); }
.stamp.busy  { color: var(--pri); }
.stamp.busy::before {
  content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--pri); margin-right: 5px; vertical-align: 1px;
  animation: blink 1s infinite;
}
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
.dot-live {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: var(--up); margin-right: 5px; vertical-align: 1px;
  box-shadow: 0 0 0 0 rgba(var(--up-rgb),.6);
  animation: pulse 2s infinite;
}
@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 rgba(var(--up-rgb),.55); }
  70%  { box-shadow: 0 0 0 7px rgba(var(--up-rgb),0); }
  100% { box-shadow: 0 0 0 0 rgba(var(--up-rgb),0); }
}
.btn {
  border: 1px solid var(--line); background: var(--elev); color: var(--tx2);
  padding: 6px 12px; border-radius: 9px; font-size: 13px; cursor: pointer;
  transition: .15s; font-family: inherit;
}
.btn:hover { border-color: var(--pri); color: var(--pri); background: var(--pri-soft); }
.btn:active { transform: scale(.97); }

/* ── Tab ──────────────────────────────────────────────────── */
nav.tabs {
  max-width: 1180px; margin: 8px auto 0; padding: 0 18px;
  display: flex; gap: 4px; align-items: stretch;
}
/* 横向滚动只在这一层：nav 自己不能再有 overflow，
   否则 absolute 定位的分组下拉面板会被裁掉一半。 */
.tabs-scroll {
  display: flex; gap: 4px; flex: 0 1 auto; min-width: 0;
  overflow-x: auto; scrollbar-width: none;
}
.tabs-scroll::-webkit-scrollbar { display: none; }
.tab {
  border: 0; background: none; font-family: inherit; font-size: 14px; color: var(--tx2);
  padding: 9px 14px 11px; cursor: pointer; white-space: nowrap;
  border-bottom: 2px solid transparent; transition: .15s;
}
.tab:hover { color: var(--tx); }
.tab.on { color: var(--pri); border-bottom-color: var(--pri); font-weight: 600; }
/* 页签角标：待办条数。0 条时由 JS 隐藏。 */
.tab-n {
  display: inline-block; min-width: 16px; margin-left: 4px; padding: 0 5px;
  font-size: 11px; font-style: normal; line-height: 16px; text-align: center;
  color: #fff; background: var(--up); border-radius: 999px; vertical-align: 1px;
}
.tab-n[hidden] { display: none; }

/* ── 分组下拉菜单 ────────────────────────────────────────────
   常用页签平铺主栏，其余按业务分组：组名即按钮，点开平铺展示组内页签。
   .tab-g 不能塞进 .tabs-scroll（overflow 会裁掉绝对定位的面板），
   所以它是 nav 下与 .tabs-scroll 并列的 flex 项。 */
.tab-g { position: relative; display: flex; flex: none; align-items: stretch; }
/* hidden 坑：.tab-g 自带 display:flex，不显式关掉 [hidden] 关不掉整组 */
.tab-g[hidden] { display: none; }
.tab-grp {
  display: inline-flex; align-items: center; gap: 4px;
  border: 0; background: none; font-family: inherit; font-size: 14px; color: var(--tx2);
  padding: 9px 12px 11px; cursor: pointer; white-space: nowrap;
  border-bottom: 2px solid transparent; transition: .15s;
}
.tab-grp:hover { color: var(--tx); }
/* 当前页落在本组 → 组按钮高亮，用着用着就知道自己在哪 */
.tab-grp.on { color: var(--pri); border-bottom-color: var(--pri); font-weight: 600; }
.tab-grp .caret { width: 12px; height: 12px; flex: none; opacity: .6; transition: transform .18s; }
.tab-g.open .tab-grp .caret { transform: rotate(180deg); }
.g-short { display: none; }               /* 窄屏才露出的缩写组名 */

.tab-grp-panel {
  position: absolute; top: 100%; left: 0; z-index: 45;
  display: none; min-width: 100%;
  flex-direction: column; gap: 1px;
  padding: 8px; background: var(--card); border: 1px solid var(--line);
  border-radius: 12px; box-shadow: var(--shadow-lg);
  animation: fade .16s ease;
}
.tab-g.open .tab-grp-panel { display: flex; }
.tab-g.flip .tab-grp-panel { left: auto; right: 0; }
/* 面板里的页签平铺成竖排菜单条；.tab.on 的下边框在这里去掉 */
.tab-grp-panel .tab {
  display: block; text-align: left; font-size: 13.5px;
  padding: 7px 12px; border-bottom: 0; border-radius: 7px;
}
.tab-grp-panel .tab:hover { background: var(--soft); color: var(--tx); }
.tab-grp-panel .tab.on {
  background: var(--pri-soft); color: var(--pri); font-weight: 600;
  border-bottom-color: transparent;
}

/* ── 布局 ─────────────────────────────────────────────────── */
main { max-width: 1180px; margin: 0 auto; padding: 18px; }
.view { display: none; }
.view.on { display: block; animation: fade .22s ease; }
@keyframes fade { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }

.grid { display: grid; gap: 14px; }
.g4 { grid-template-columns: repeat(4, 1fr); }
.g3 { grid-template-columns: repeat(3, 1fr); }
.g2 { grid-template-columns: repeat(2, 1fr); }

.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px 18px; box-shadow: var(--shadow);
}
.card h3 {
  margin: 0 0 12px; font-size: 14px; font-weight: 600; color: var(--tx2);
  display: flex; align-items: center; gap: 8px;
}
.card h3 .hint { font-weight: 400; font-size: 12px; color: var(--tx3); margin-left: auto; }
/* 同一行有多个提示时，只有第一个负责把整组推到右侧；
   否则每个都 auto 会把它们拆开、中间裂出一大块空白 */
.card h3 .hint + .hint { margin-left: 0; }
/* 日报落后于「应该有」的日期（T+1 还没结算完 / 采集没跑成）时提示出来 */
.card h3 .hint.stale { color: var(--warn); }

/* ── 大数字 ───────────────────────────────────────────────── */
.kpi { display: flex; flex-direction: column; gap: 3px; }
.kpi .lab { font-size: 12.5px; color: var(--tx2); }
.kpi .val { font-size: 26px; font-weight: 700; letter-spacing: -.6px; font-variant-numeric: tabular-nums; }
.kpi .val small { font-size: 14px; font-weight: 500; color: var(--tx3); margin-left: 2px; }
.kpi .sub { font-size: 12px; color: var(--tx3); }
.kpi .sub .up   { color: var(--up);   font-weight: 600; }
.kpi .sub .down { color: var(--down); font-weight: 600; }
/* 可点的 KPI 卡（异常/注意类目 → 钻取明细） */
.card.kpi.click { cursor: pointer; transition: border-color .15s, transform .15s; }
.card.kpi.click:hover { border-color: var(--pri); transform: translateY(-1px); }
/* 钻取明细行 */
.kpi-list { display: flex; flex-direction: column; gap: 9px; max-height: 52vh; overflow-y: auto; }
.kpi-it {
  display: flex; align-items: center; gap: 12px;
  background: var(--soft); border: 1px solid var(--line); border-radius: 10px;
  padding: 10px 13px;
}
.kpi-it.acked { opacity: .62; }
.kpi-it-main { flex: 1; min-width: 0; font-size: 13px; }
.kpi-it-main .hint { margin-left: 8px; }
.kpi-it-detail { margin-top: 3px; color: var(--tx2); }
.kpi-it .mini { flex-shrink: 0; }
.todo { color: var(--warn); font-weight: 600; font-size: 15px; }

/* ── 进度条 ───────────────────────────────────────────────── */
.bar { height: 6px; border-radius: 4px; background: var(--line2); overflow: hidden; margin-top: 9px; }
.bar > i { display: block; height: 100%; border-radius: 4px; background: var(--pri); transition: width .5s; }
.bar.warn > i { background: var(--warn); }
.bar.bad  > i { background: var(--up); }
/* 门店卡：去年同期同时点上座率 —— 蓝条下方那条灰色细线（小字） */
.ly-line { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
.ly-line .bar { flex: 1; height: 3px; margin-top: 0; border-radius: 2px; }
.ly-line .bar > i { background: var(--tx3); border-radius: 2px; opacity: .7; }

.ly-line > span { font-size: 10px; color: var(--tx3); white-space: nowrap; }

/* ── 门店卡 ───────────────────────────────────────────────── */
.shop {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px 16px; box-shadow: var(--shadow); cursor: pointer; transition: .16s;
  position: relative; overflow: hidden;
}
.shop:hover { border-color: var(--pri); transform: translateY(-2px); }
.shop::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 3px; background: var(--c, var(--pri)); }
.shop-top { display: flex; align-items: baseline; gap: 8px; margin-bottom: 10px; }
.shop-name { font-weight: 650; font-size: 15px; }
.shop-flag {
  font-size: 11px; padding: 1px 6px; border-radius: 5px; background: var(--pri-soft);
  color: var(--pri); font-weight: 600;
}
.shop-flag.bad { background: var(--bad-bg); color: var(--up); }
.shop-rev { font-size: 23px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -.5px; }
.shop-rev small { font-size: 13px; color: var(--tx3); font-weight: 500; margin-left: 3px; }
/* 上机人数胶囊：与营收并列的第二视觉焦点（用户要求一眼入眼） */
.shop-main { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
/* 今日累计机时：夹在「今日营收」和「上机胶囊」中间，比两边都轻，不抢焦点 */
.shop-mh {
  display: flex; align-items: baseline; gap: 3px; flex-shrink: 0;
  padding: 0 10px; border-left: 1px solid var(--line); border-right: 1px solid var(--line);
  font-variant-numeric: tabular-nums; color: var(--tx2);
}
.shop-mh b { font-size: 19px; font-weight: 700; color: var(--tx); letter-spacing: -.4px; }
.shop-mh small { font-size: 11px; color: var(--tx3); font-weight: 500; }
.shop-pc {
  display: flex; align-items: baseline; gap: 3px; flex-shrink: 0;
  background: var(--pri-soft); color: var(--pri);
  border-radius: 10px; padding: 4px 11px 5px; line-height: 1.05;
}
.shop-pc i { font-style: normal; font-size: 14px; align-self: center; }
.shop-pc b { font-size: 25px; font-weight: 750; font-variant-numeric: tabular-nums; letter-spacing: -.5px; }
.shop-pc small { font-size: 11.5px; font-weight: 650; opacity: .72; }
/* 满座：上座率 ≥90% 时胶囊变金色 + 🔥 */
.shop-pc.full { background: var(--warn-bg); color: var(--warn-tx); }
.shop-pc.full small { opacity: .85; }
.shop-row { display: flex; gap: 16px; margin-top: 9px; font-size: 12.5px; color: var(--tx2); flex-wrap: wrap; }
.shop-row b { color: var(--tx); font-weight: 600; font-variant-numeric: tabular-nums; }
/* 门店卡「已消费网费」：比灰字营收构成高半档，但不去抢主金额的风头 */
.shop-consume { margin-top: 6px; }
.shop-consume b { color: var(--tx); font-weight: 700; }

/* ── 图表 ─────────────────────────────────────────────────── */
.chart-wrap { position: relative; height: 300px; }
.chart-wrap.short { height: 230px; }

/* 图表空态 / 单点时点占位 */
.ph {
  height: 100%; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 3px;
  color: var(--tx3); font-size: 13px; text-align: center;
}
.ph .big {
  font-size: 30px; font-weight: 700; color: var(--tx);
  font-variant-numeric: tabular-nums; letter-spacing: -.6px;
}
.ph code { background: var(--line2); padding: 1px 5px; border-radius: 4px; font-size: 11.5px; }
canvas { max-width: 100%; }
.legend { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 10px; font-size: 12.5px; color: var(--tx2); }
.legend span { display: flex; align-items: center; gap: 5px; }
.legend i { width: 9px; height: 9px; border-radius: 3px; display: inline-block; }

.seg { margin-left: auto; display: flex; gap: 3px; background: var(--line2); padding: 2px; border-radius: 8px; }
.seg button {
  border: 0; background: none; font-family: inherit; font-size: 12px; color: var(--tx2);
  padding: 3px 10px; border-radius: 6px; cursor: pointer;
}
.seg button.on { background: var(--elev); color: var(--tx); font-weight: 600; box-shadow: var(--shadow); }

/* ── 筛选条（历史页：门店多选 + 月份区间）────────────────────
   和 .seg 的区别：.seg 是「互斥单选」，这里是可以同时选好几个的门店。
   选中态用主色实心，熄灭态是普通描边 —— 一眼能看出选了哪几家。 */
.filters { display: flex; flex-direction: column; gap: 9px; margin: 0 0 14px; }
.f-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.f-lab { font-size: 12px; color: var(--tx3); width: 30px; flex: none; }
.f-tilde { color: var(--tx3); font-size: 12px; }
.segs { display: flex; gap: 6px; flex-wrap: wrap; }
.segs button {
  border: 1px solid var(--line); background: var(--elev); color: var(--tx2);
  font-family: inherit; font-size: 12.5px; padding: 4px 11px; border-radius: 999px;
  cursor: pointer; transition: .15s; line-height: 1.4;
}
.segs button:hover { border-color: var(--pri); color: var(--pri); }
.segs button.on {
  background: var(--pri); border-color: var(--pri);
  color: var(--on-pri); font-weight: 600;
}
.sel {
  border: 1px solid var(--line); background: var(--elev); color: var(--tx);
  font-family: inherit; font-size: 12.5px; padding: 5px 8px; border-radius: 9px;
  cursor: pointer; outline: none; transition: .15s;
}
.sel:focus { border-color: var(--pri); box-shadow: 0 0 0 3px var(--pri-soft); }
.in {
  border: 1px solid var(--line); background: var(--elev); color: var(--tx);
  font-family: inherit; font-size: 12.5px; padding: 5px 8px; border-radius: 9px;
  outline: none; transition: .15s;
}
.in:focus { border-color: var(--pri); box-shadow: 0 0 0 3px var(--pri-soft); }

/* ── 表格 ─────────────────────────────────────────────────── */
.tw { overflow-x: auto; margin: 0 -18px -16px; padding: 0 18px 4px; }
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
th, td { padding: 9px 10px; text-align: right; white-space: nowrap; }
th:first-child, td:first-child { text-align: left; position: sticky; left: 0; background: var(--card); }
th {
  font-size: 12px; font-weight: 600; color: var(--tx2); border-bottom: 1px solid var(--line);
  background: var(--card);
}
td { border-bottom: 1px solid var(--line2); font-variant-numeric: tabular-nums; }
tbody tr:hover td { background: var(--hover); }
tbody tr:hover td:first-child { background: var(--hover); }
.up { color: var(--up); } .down { color: var(--down); }
.empty { color: var(--tx3); text-align: center; padding: 28px 0; font-size: 13.5px; }

/* ── 营销页 · 备注/事由文本列 ──────────────────────────────
   表格默认 td 是 nowrap + 右对齐（给数字用）。备注是长文本，
   「赠送事由」和「赠送明细」两张表改左对齐并允许换行。 */
#t-mkt-remark th, #t-mkt-remark td,
#t-mkt-gift-rows th, #t-mkt-gift-rows td { text-align: left; }
#t-mkt-remark td, #t-mkt-gift-rows td {
  white-space: normal; word-break: break-word; line-height: 1.5;
}
#t-mkt-gift-rows td:nth-child(6) { text-align: right; }
.mkt-rm { color: var(--tx); }
.mkt-rm-empty { color: var(--tx3); }

/* ── AI 问答 ──────────────────────────────────────────────── */
.ai-wrap { display: grid; grid-template-columns: 1fr 250px; gap: 14px; align-items: start; }
.chat { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
        box-shadow: var(--shadow); display: flex; flex-direction: column; height: 640px; }
.chat-head { padding: 14px 18px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 9px; }
.chat-head b { font-size: 14.5px; }
.chat-head span { font-size: 12px; color: var(--tx3); margin-left: auto; }
.chat-body { flex: 1; overflow-y: auto; padding: 16px 18px; display: flex; flex-direction: column; gap: 14px; }
.msg { max-width: 92%; font-size: 14px; }
.msg.me { align-self: flex-end; background: var(--pri); color: var(--on-pri); padding: 9px 14px;
          border-radius: 13px 13px 4px 13px; }
.msg.ai { align-self: flex-start; width: 100%; }
.msg.ai .txt { background: var(--soft); border: 1px solid var(--line); border-radius: 4px 13px 13px 13px;
               padding: 11px 14px; white-space: pre-wrap; word-break: break-word; }
.msg.err .txt { background: var(--err-bg); border-color: var(--err-line); color: var(--err-tx); }
.msg .row { font-size: 12px; color: var(--tx3); margin-top: 6px; display: flex; gap: 10px; align-items: center; }
/* AI 回答的数据时点提示：问「现在」却只能拿到旧快照时，必须说清楚 */
.msg .fresh-warn {
  margin-top: 8px; padding: 7px 10px; border-radius: 9px; font-size: 12.5px;
  background: var(--warn-bg); border: 1px solid var(--warn-line); color: var(--warn-tx);
}
.msg .fresh-ok { margin-top: 8px; font-size: 12px; color: var(--tx3); }
.msg .row a { color: var(--pri); cursor: pointer; text-decoration: none; }
.msg .row a:hover { text-decoration: underline; }
details.sql { margin-top: 8px; font-size: 12px; }
details.sql summary { cursor: pointer; color: var(--tx3); list-style: none; }
details.sql summary::-webkit-details-marker { display: none; }
details.sql summary::before { content: "▸ "; }
details.sql[open] summary::before { content: "▾ "; }
details.sql pre {
  margin: 7px 0 0; padding: 11px; background: var(--code-bg); color: var(--code-tx);
  border-radius: 9px; overflow-x: auto; font-size: 11.5px; line-height: 1.6;
  font-family: ui-monospace, Consolas, monospace;
}
.mini-tbl { margin-top: 8px; overflow-x: auto; border: 1px solid var(--line); border-radius: 9px; }
.mini-tbl table { font-size: 12px; }
.mini-tbl th, .mini-tbl td { padding: 6px 9px; }
.chat-foot { padding: 12px 18px; border-top: 1px solid var(--line); display: flex; gap: 9px; }
.chat-foot input {
  flex: 1; border: 1px solid var(--line); border-radius: 11px; padding: 10px 14px;
  font-size: 14px; font-family: inherit; outline: none; transition: .15s; background: var(--field);
}
.chat-foot input:focus { border-color: var(--pri); background: var(--elev); box-shadow: 0 0 0 3px var(--pri-soft); }
.chat-foot button {
  border: 0; background: var(--pri); color: var(--on-pri); padding: 0 20px; border-radius: 11px;
  font-size: 14px; font-family: inherit; cursor: pointer; font-weight: 600; transition: .15s;
}
.chat-foot button:hover { background: var(--pri-hover); }
.chat-foot button:disabled { opacity: .45; cursor: not-allowed; }
.chat-foot button.mic {
  background: var(--elev); color: var(--tx2); border: 1px solid var(--line);
  padding: 0 13px; font-size: 16px; font-weight: 400;
}
.chat-foot button.mic:hover { background: var(--pri-soft); color: var(--pri); }
.chat-foot button.mic.rec {
  background: var(--up); color: var(--on-pri); border-color: var(--up);
  animation: mic-pulse 1.2s infinite;
}
.chat-foot button.mic.busy { opacity: .6; cursor: wait; }
@keyframes mic-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(229, 72, 77, .45); }
  50%      { box-shadow: 0 0 0 7px rgba(229, 72, 77, 0); }
}

.side .card { margin-bottom: 14px; }
.chips { display: flex; flex-direction: column; gap: 7px; }
.chip {
  text-align: left; border: 1px solid var(--line); background: var(--elev); font-family: inherit;
  font-size: 12.5px; color: var(--tx2); padding: 8px 11px; border-radius: 9px; cursor: pointer;
  transition: .15s; line-height: 1.4;
}
.chip:hover { border-color: var(--pri); color: var(--pri); background: var(--pri-soft); }
.note { font-size: 12px; color: var(--tx3); line-height: 1.65; }
.note b { color: var(--tx2); }
.typing i {
  display: inline-block; width: 5px; height: 5px; border-radius: 50%; background: var(--tx3);
  margin-right: 3px; animation: blink 1.3s infinite;
}
.typing i:nth-child(2) { animation-delay: .18s; }
.typing i:nth-child(3) { animation-delay: .36s; }
@keyframes blink { 0%,60%,100% { opacity: .25; } 30% { opacity: 1; } }

/* ── 登录页 ───────────────────────────────────────────────── */
.login-page { display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 20px; }
.login-box {
  background: var(--card); border: 1px solid var(--line); border-radius: 18px;
  padding: 34px 30px; width: 100%; max-width: 350px; box-shadow: var(--shadow-lg);
  text-align: center;
}
.login-box h1 { font-size: 19px; margin: 0 0 6px; }
.login-box p { color: var(--tx3); font-size: 13px; margin: 0 0 22px; }
.login-box input {
  width: 100%; border: 1px solid var(--line); border-radius: 12px; padding: 12px 15px;
  font-size: 15px; font-family: inherit; outline: none; background: var(--field); margin-bottom: 12px;
}
.login-box input:focus { border-color: var(--pri); background: var(--elev); box-shadow: 0 0 0 3px var(--pri-soft); }
.login-box button {
  width: 100%; border: 0; background: var(--pri); color: var(--on-pri); padding: 12px;
  border-radius: 12px; font-size: 15px; font-family: inherit; font-weight: 600; cursor: pointer;
}
.login-box button:hover { background: var(--pri-hover); }
.login-err { color: var(--up); font-size: 13px; min-height: 19px; margin-top: 10px; }

/* ── 弹层 ─────────────────────────────────────────────────── */
.modal-bg {
  position: fixed; inset: 0; background: var(--overlay); z-index: 100;
  display: flex; align-items: center; justify-content: center; padding: 18px;
  backdrop-filter: blur(2px);
}
.modal {
  background: var(--elev); border-radius: 16px; width: 100%; max-width: 640px;
  max-height: 86vh; overflow-y: auto; padding: 22px 24px; box-shadow: var(--shadow-xl);
}
.modal h2 { margin: 0 0 4px; font-size: 18px; display: flex; align-items: center; gap: 9px; }
.modal .close { margin-left: auto; border: 0; background: none; font-size: 22px; color: var(--tx3);
                cursor: pointer; line-height: 1; padding: 0 4px; }
.modal .kvs { display: grid; grid-template-columns: repeat(3,1fr); gap: 12px; margin: 16px 0; }
.modal .kv { background: var(--soft); border-radius: 10px; padding: 10px 12px; }
.modal .kv .l { font-size: 12px; color: var(--tx2); }
.modal .kv .v { font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* ── 弹层里的表单（改密码 / 建账号 / 门店勾选）────────────────── */
.modal .field { margin-bottom: 13px; }
.modal .field label {
  display: block; font-size: 12.5px; color: var(--tx2); margin-bottom: 5px;
}
.modal .field input, .modal .field select {
  width: 100%; border: 1px solid var(--line); border-radius: 10px; padding: 9px 12px;
  font-size: 14px; font-family: inherit; outline: none;
  background: var(--field); color: var(--tx);
}
.modal .field input:focus, .modal .field select:focus {
  border-color: var(--pri); background: var(--elev); box-shadow: 0 0 0 3px var(--pri-soft);
}
.modal .field input:disabled { color: var(--tx3); cursor: not-allowed; }
.modal .acts { display: flex; gap: 9px; justify-content: flex-end; margin-top: 18px; }
.modal .acts .btn { padding: 8px 16px; font-size: 13.5px; }
.modal .err { color: var(--up); font-size: 12.5px; min-height: 17px; margin-top: 6px; text-align: right; }
.modal .note { margin-bottom: 14px; }

.btn.pri { border-color: var(--pri); background: var(--pri); color: var(--on-pri); font-weight: 600; }
.btn.pri:hover { background: var(--pri-hover); border-color: var(--pri-hover); color: var(--on-pri); }
.btn.pri:disabled { opacity: .5; cursor: not-allowed; }
.btn.bad { color: var(--up); }
.btn.bad:hover { border-color: var(--up); color: var(--up); background: var(--bad-bg); }
.btn.bad:disabled { opacity: .5; cursor: not-allowed; }

/* 门店勾选：两列卡片，点整块都能勾 */
.picks { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.pick {
  display: flex; align-items: center; gap: 9px; border: 1px solid var(--line);
  border-radius: 10px; padding: 9px 12px; cursor: pointer; transition: .15s;
}
.pick:hover { border-color: var(--pri); background: var(--pri-soft); }
.pick input { margin: 0; flex: none; accent-color: var(--pri); }
.pick input:disabled { cursor: not-allowed; }
.pick span { font-size: 13.5px; }
.pick em { font-style: normal; display: block; font-size: 11.5px; color: var(--tx3); }

/* ── 账号后台 ─────────────────────────────────────────────── */
td.ops { white-space: nowrap; text-align: left; }
.mini {
  border: 1px solid var(--line); background: var(--elev); color: var(--tx2);
  font-family: inherit; font-size: 12px; padding: 3px 9px; border-radius: 7px;
  cursor: pointer; margin: 0 4px 3px 0; transition: .15s;
}
.mini:hover { border-color: var(--pri); color: var(--pri); background: var(--pri-soft); }
.mini.bad:hover { border-color: var(--up); color: var(--up); background: var(--bad-bg); }
.mini:disabled { opacity: .4; cursor: not-allowed; }
.dot.on  { background: var(--down); }     /* 状态点：绿=启用，灰=停用 */
.dot.off { background: var(--tx3); }

/* 操作结果提示条 */
.toast {
  position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%);
  background: var(--elev); color: var(--tx); border: 1px solid var(--line);
  font-size: 13px; padding: 10px 18px; border-radius: 10px; z-index: 200;
  box-shadow: var(--shadow-lg); max-width: 80vw; text-align: center;
  transition: opacity .45s, transform .45s;
}
.toast.bad { background: var(--err-bg); border-color: var(--err-line); color: var(--err-tx); }
.toast.go { opacity: 0; transform: translate(-50%, 10px); }

/* 页内确认/输入弹层（替代原生 prompt/confirm，微信里原生框点不动） */
.ui-mask {
  position: fixed; inset: 0; background: rgba(0,0,0,.42); z-index: 300;
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.ui-modal {
  background: var(--elev); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: var(--shadow-lg); padding: 18px; width: 340px; max-width: 92vw;
}
.ui-m-title { font-size: 14px; font-weight: 600; margin-bottom: 12px; line-height: 1.5; }
.ui-m-in { width: 100%; box-sizing: border-box; margin-bottom: 14px; }
.ui-m-btns { display: flex; justify-content: flex-end; gap: 8px; }

/* ── 作业统计 ─────────────────────────────────────────────── */
/* 配置类提醒（有条数但没分值）：用告警色，但区别于报错红 */
.notice {
  background: var(--warn-bg); border-color: var(--warn-line); color: var(--warn-tx);
  font-size: 13px; line-height: 1.7;
}
.notice b { color: var(--warn-tx2); }
.mono {
  font-family: ui-monospace, Consolas, monospace; font-size: 12.5px;
  background: var(--mono-bg); padding: 1px 5px; border-radius: 4px;
}
.dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 3px;
  margin-right: 6px; vertical-align: 0;
}
/* 完成率：数字前面跟一条细进度条，扫一眼就知道哪家掉队 */
.mini-bar {
  display: inline-block; width: 46px; height: 5px; border-radius: 3px;
  background: var(--line2); overflow: hidden; margin-right: 7px; vertical-align: 1px;
}
.mini-bar > i { display: block; height: 100%; border-radius: 3px; background: var(--up); }

/* 得分榜前三名用金银铜，其余灰 */
td.rank { color: var(--tx3); font-weight: 600; width: 44px; }
td.rank-1 { color: var(--rank1); }
td.rank-2 { color: var(--rank2); }
td.rank-3 { color: var(--rank3); }

/* 员工榜人多时内部滚动，别把整个页面撑长 */
.tw.scroll { max-height: 372px; overflow-y: auto; }
.tw.scroll thead th { position: sticky; top: 0; z-index: 2; }

/* 分类列表比员工榜矮时，别让卡片被拉伸出一大片空白 */
#v-work .grid.g2 { align-items: start; }

/* 分类得分 */
.cat-list { display: flex; flex-direction: column; gap: 13px; }

/* ── 门店巡检 ─────────────────────────────── */
.p-row { display: flex; gap: 14px; padding: 11px 2px; border-bottom: 1px solid var(--line); }
.p-row:last-child { border-bottom: none; }
.p-row.test { opacity: .55; }                /* 门店端自测数据：灰显，不污染统计观感 */
.p-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.p-head { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.p-verdict { font-size: 13px; font-weight: 650; color: var(--warn, #d97706); }
.p-detail { font-size: 12.5px; color: var(--tx2); }
.p-thumb { width: 108px; height: 72px; object-fit: cover; border-radius: 8px;
           border: 1px solid var(--line); flex: none; cursor: zoom-in; }
.p-tag { display: inline-block; padding: 1px 8px; border-radius: 999px;
         font-size: 11.5px; font-weight: 650; }
.p-tag.ok   { background: rgba(16,185,129,.14); color: #0d9e73; }
.p-tag.bad  { background: rgba(239,68,68,.14);  color: #dc2626; }
.p-tag.warn { background: rgba(245,158,11,.16); color: #b45309; }
.p-tag.gray { background: rgba(128,128,128,.14); color: var(--tx3); }

/* ── 游戏统计排行 ─────────────────────────────── */
.g-row { display: flex; align-items: center; gap: 10px; padding: 7.5px 0;
         border-bottom: 1px solid var(--line); font-size: 13px; }
.g-row:last-child { border-bottom: none; }
.g-i { width: 22px; height: 22px; border-radius: 7px; flex: none;
       background: rgba(127,127,127,.12); color: var(--tx3);
       font-size: 11.5px; font-weight: 700;
       display: flex; align-items: center; justify-content: center; }
.g-i.top { background: var(--pri-soft); color: var(--pri); }
.g-name { width: 132px; flex: none; font-weight: 600;
          overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.g-bar { flex: 1; height: 10px; border-radius: 5px;
         background: rgba(127,127,127,.12); overflow: hidden; }
.g-bar i { display: block; height: 100%; border-radius: 5px; background: var(--pri); }
.g-num { min-width: 56px; text-align: right; font-variant-numeric: tabular-nums; }
.g-pct { min-width: 46px; text-align: right; font-size: 11.5px; }
.cat-row { display: flex; flex-direction: column; gap: 5px; }
.cat-head { display: flex; align-items: baseline; gap: 8px; }
.cat-name { font-size: 13.5px; font-weight: 600; }
.cat-total { margin-left: auto; font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; }
.cat-total small { font-size: 11px; font-weight: 500; color: var(--tx3); margin-left: 2px; }
.cat-bar { height: 6px; border-radius: 4px; background: var(--line2); overflow: hidden; }
.cat-bar > i {
  display: block; height: 100%; border-radius: 4px; transition: width .5s;
  background: var(--bar-grad);
}
.cat-tops { display: flex; gap: 12px; flex-wrap: wrap; font-size: 12px; color: var(--tx3); }
.cat-top { display: flex; align-items: baseline; gap: 4px; }
.cat-top b { color: var(--tx2); font-weight: 600; }
.cat-top em { font-style: normal; color: var(--tx3); }

/* ── 响应式 ───────────────────────────────────────────────── */
@media (max-width: 1000px) {
  .ai-wrap { grid-template-columns: 1fr; }
  .side { order: -1; }
  .side .card { margin-bottom: 12px; }
  .chips { flex-direction: row; flex-wrap: wrap; }
  .chip { flex: 1 1 46%; }
}
@media (max-width: 720px) {
  body { font-size: 14.5px; }
  main { padding: 13px; }
  .g4, .g3, .g2 { grid-template-columns: 1fr; }
  .g4.keep2 { grid-template-columns: repeat(2, 1fr); }
  .head-in { padding: 10px 14px 0; }
  nav.tabs { padding: 0 14px; }
  /* 页签窄屏压紧一档：不压的话主栏最后两个会被挤进横向滚动区，
     而滚动条是隐藏的，用户根本不知道还能往右滑。 */
  .tabs-scroll { gap: 2px; }
  .tabs-scroll .tab { padding: 9px 8px 11px; font-size: 13.5px; }
  /* 分组按钮同步压紧，并换成缩写组名（现场运营→运营 等）——
     8 个控件（4 页签 + 4 组）才挤得下窄屏。 */
  .tab-grp { padding: 9px 8px 11px; font-size: 13.5px; gap: 3px; }
  .tab-grp .caret { width: 11px; height: 11px; }
  .tab-grp .g-full { display: none; }
  .tab-grp .g-short { display: inline; }
  .tab-grp-panel .tab { font-size: 13px; padding: 7px 10px; }
  /* 分组下拉面板仍锚在各自按钮上，靠右时 JS 翻侧（flip），无需改挂 nav */
  .kpi .val { font-size: 23px; }
  .chart-wrap { height: 250px; }
  .chat { height: 74vh; }
  .msg { max-width: 100%; }
  .modal .kvs { grid-template-columns: 1fr 1fr; }
  .picks { grid-template-columns: 1fr; }
  .who { display: none; }              /* 窄屏顶栏挤，账号名让位给按钮 */
  .card { padding: 14px; }
  .tw { margin: 0 -14px -14px; padding: 0 14px 4px; }
}

/* 手机档（≤430px）：再压一档，4 页签 + 4 个分组按钮（缩写组名）才全露出来。 */
@media (max-width: 430px) {
  .tabs-scroll { gap: 1px; }
  .tabs-scroll .tab { padding: 9px 4px 11px; font-size: 12.5px; }
  .tab-grp { padding: 9px 4px 11px 5px; font-size: 12.5px; }
}

/* ── 成本填报 ─────────────────────────────────────────────────── */
/* 保存栏：按钮在 h3 里，提示文字另起一行跟着表格，别挤成一团 */
.fill-bar {
  display: flex; align-items: center; gap: 10px;
  margin-top: 12px; min-height: 20px;
}
.fill-bar .hint { font-size: 12px; color: var(--tx3); }
.fill-bar .hint.bad { color: var(--up); font-weight: 600; }

/* 录入框：数字右对齐 + 等宽数字，竖着排能一眼看出哪一行位数不对 */
input.fi {
  width: 94px; padding: 6px 9px; text-align: right;
  font: inherit; font-variant-numeric: tabular-nums;
  color: var(--tx); background: var(--field);
  border: 1px solid var(--line); border-radius: 8px;
  transition: border-color .15s, box-shadow .15s;
}
input.fi:focus {
  outline: none; border-color: var(--pri); background: var(--elev);
  box-shadow: 0 0 0 3px var(--pri-soft);
}
input.fi::placeholder { color: var(--tx3); }
/* 数字框自带的上下箭头太丑，且在这个宽度里会占掉半格 */
input.fi::-webkit-outer-spin-button,
input.fi::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input.fi { -moz-appearance: textfield; appearance: textfield; }

/* 快到期 / 已过期：借用「涨」的红，但语义是催办，不是亏损 —— 所以单独一个类名 */
.due { color: var(--up); font-weight: 600; }
/* 已停用的特权：压暗，保留可读（历史要看，但别抢眼） */
.off { opacity: .55; }

/* 到期日补填（填报页）：日期框与「保存」并排，换行会把这一列撑成两行 */
.fp-cell { white-space: nowrap; }
#t-fill-priv input.fp-date {
  width: 136px; padding: 5px 8px; font: inherit; font-size: 12.5px;
  color: var(--tx); background: var(--field);
  border: 1px solid var(--line); border-radius: 7px;
}
#t-fill-priv input.fp-date:focus {
  outline: none; border-color: var(--pri); background: var(--elev);
  box-shadow: 0 0 0 3px var(--pri-soft);
}

/* 添加特权弹窗的多门店勾选：小方块一排，勾重了去重由服务端兜底 */
.p-shops { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; }
.p-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border: 1px solid var(--line); border-radius: 7px;
  background: var(--field); font-size: 12.5px; cursor: pointer;
  user-select: none;
}
.p-chip:has(input:checked) { border-color: var(--pri); background: var(--pri-soft); }
.p-chip input { accent-color: var(--pri); margin: 0; }

/* 来客提示设置 · AI 特效包缩略图（点开看大图） */
#pt-effects { flex-wrap: wrap; gap: 8px; }
.pt-fx {
  width: 132px; height: 74px; object-fit: cover; border-radius: 6px;
  border: 1px solid var(--line); background: #000; cursor: zoom-in;
}
.pt-fx:hover { border-color: var(--pri); }

/* ── 到期提醒后台 ─────────────────────────────────────────────── */
/* 推送成功用绿（与「涨红跌绿」里的绿同色，这里语义是「已办妥」）。
   失败/待推沿用上面的 .c-warn 橙色 —— 提醒要显眼，但不该跟报错红抢。 */
.c-ok { color: var(--down); }

/* 表格里的内联输入框：地址长、天数短，各给各的宽度 */
#t-notify input.wh,
#t-notify input.rd {
  padding: 5px 8px; font: inherit; font-size: 12.5px;
  color: var(--tx); background: var(--field);
  border: 1px solid var(--line); border-radius: 7px;
}
#t-notify input.wh { width: 100%; min-width: 210px; }
#t-notify input.rd { width: 66px; text-align: right; font-variant-numeric: tabular-nums; }
#t-notify input.wh:focus,
#t-notify input.rd:focus {
  outline: none; border-color: var(--pri); background: var(--elev);
  box-shadow: 0 0 0 3px var(--pri-soft);
}
#t-notify input.en { accent-color: var(--pri); width: 16px; height: 16px; }

/* ── 月目标看板 ───────────────────────────────────────────────── */
/* 结构：合计一条细横幅（看方向）→ 每店一张卡（真正的主角）。
   全部走主题变量 —— 店卡要在浅色/深色下都融进页面，
   「第一眼」交给每张卡自己的顶边颜色与进度条，而不是一张大色块。 */
.mb-strip {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 6px 20px;
  margin-top: 14px; padding: 12px 18px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
  font-size: 13px; color: var(--tx2);
}
.mb-strip .ms-who { font-weight: 600; color: var(--tx); }
.mb-strip .ms-rev {
  font-size: 22px; font-weight: 700; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; color: var(--tx);
}
.mb-strip .ms-pg b { color: var(--pri); }
.mb-strip .ms-d { display: inline-flex; gap: 5px; align-items: baseline; }
.mb-strip .ms-d b { font-variant-numeric: tabular-nums; }

/* 每店一卡：一眼看出「谁快谁慢」—— 顶边颜色定调，进度条上刻时间线 */
.mb-cards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(248px, 1fr));
  gap: 12px; margin-top: 14px;
}
.shop-card {
  background: var(--card); border: 1px solid var(--line);
  border-top: 3px solid var(--pri);
  border-radius: var(--radius); padding: 14px 16px 13px;
  box-shadow: var(--shadow); min-width: 0;
}
.shop-card.lag  { border-top-color: var(--up); }
.shop-card.done { border-top-color: var(--down); }
.sc-hd { display: flex; align-items: center; gap: 8px; }
.sc-hd > b { font-size: 15px; }
.sc-badge {
  font-size: 11.5px; font-weight: 600; padding: 1.5px 8px;
  border-radius: 99px; white-space: nowrap;
}
.sc-badge.lag { color: var(--err-tx); background: var(--bad-bg); }
.sc-badge.ok  { color: var(--down); background: var(--soft); }
.sc-badge.na  { color: var(--tx3); background: var(--soft); }
.sc-share { margin-left: auto; font-size: 12px; color: var(--tx3); }
.sc-rev {
  font-size: 25px; font-weight: 700; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; color: var(--tx);
  margin-top: 7px; line-height: 1.2;
}
.sc-tgt { font-size: 12.5px; color: var(--tx2); margin-top: 3px; }
.sc-tgt b { color: var(--warn); font-variant-numeric: tabular-nums; }
.sc-bar {
  position: relative; height: 10px; margin: 11px 0 5px;
  background: var(--soft); border: 1px solid var(--line2);
  border-radius: 99px;
}
.sc-fill {
  display: block; height: 100%; width: 0; border-radius: 99px;
  background: var(--pri); transition: width .55s cubic-bezier(.3,.9,.4,1);
}
.shop-card.lag  .sc-fill { background: var(--up); }
.shop-card.done .sc-fill { background: var(--down); }
/* 时间刻度线：进度条是快是慢，得跟「时间走到哪」比才有意义 */
.sc-tick {
  position: absolute; top: -4px; bottom: -4px; width: 2px;
  background: var(--tx3); border-radius: 2px;
}
.sc-pg { font-size: 12px; color: var(--tx3); margin-bottom: 8px; }
.sc-pg b { color: var(--tx); }
/* 去年同期：蓝条下面那条细灰线（同一个目标，去年同段日子的完成度）。
   刻意用 <i> 而不是 .sc-fill —— 否则会被 .shop-card.lag/.done 的
   红绿覆盖规则串色。 */
.sc-ly { display: flex; align-items: center; gap: 8px; margin: 0 0 7px; }
.sc-bar.ly { flex: 1; height: 4px; margin: 0; background: var(--soft); }
.sc-bar.ly > i {
  display: block; height: 100%; border-radius: 99px;
  background: var(--tx3); opacity: .8; transition: width .55s cubic-bezier(.3,.9,.4,1);
}
.sc-ly > span { font-size: 11px; color: var(--tx3); white-space: nowrap; }
.sc-ly > span b { color: var(--tx2); font-variant-numeric: tabular-nums; }
.sc-row {
  display: flex; align-items: baseline; gap: 5px;
  font-size: 12px; line-height: 1.9; color: var(--tx3);
}
.sc-row span { flex: 0 0 76px; }
.sc-row b { font-variant-numeric: tabular-nums; }
.sc-mini {
  margin-top: 9px; padding-top: 8px;
  border-top: 1px dashed var(--line);
  font-size: 12px; color: var(--tx3);
}

/* 经营摘要 */
.mb-sum {
  margin-top: 14px; padding: 16px 18px;
  background: var(--soft); border: 1px solid var(--line2);
  border-radius: var(--radius);
}
.mb-sum h4 { margin: 0 0 9px; font-size: 13.5px; color: var(--tx); }
.mb-sum .ln {
  font-size: 13px; line-height: 2; color: var(--tx2);
  font-variant-numeric: tabular-nums;
}
.mb-sum .ln + .ln { border-top: 1px solid var(--line2); }
.mb-sum .ln b { color: var(--tx); font-weight: 600; }
.mb-sum .ln em { font-style: normal; color: var(--tx3); }
.mb-sum .ln .tag {
  display: inline-block; min-width: 66px; font-size: 12px; color: var(--tx3);
}
.mb-sum .warn { color: var(--up); font-weight: 600; }
.mb-sum .good { color: var(--down); font-weight: 600; }

@media (max-width: 900px) {
  .mb-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
  .mb-cards { grid-template-columns: 1fr; }
  .mb-strip .ms-rev { font-size: 19px; }
}

/* 月目标设定表里的金额框：要够宽，不然 200000 只露半截 */
#t-tg-edit input.num2 {
  width: 134px; padding: 6px 9px; text-align: right;
  font: inherit; font-size: 13px; font-variant-numeric: tabular-nums;
  color: var(--tx); background: var(--field);
  border: 1px solid var(--line); border-radius: 7px;
}
#t-tg-edit input.num2:focus {
  outline: none; border-color: var(--pri); background: var(--elev);
  box-shadow: 0 0 0 3px var(--pri-soft);
}
/* 历史月：整个输入框灰掉。后端也会拒，这里只是别让人白填一遍 */
#t-tg-edit input.num2:disabled { opacity: .55; cursor: not-allowed; }



/* ── 巡检异常 · 图片灯箱（页内看大图，‹/› 切换，Esc/点图关闭）── */
.p-thumb { cursor: zoom-in; }
#patrol-lb {
  position: fixed; inset: 0; z-index: 200; background: var(--overlay);
  display: none; align-items: center; justify-content: center;
  padding: 24px;
}
#patrol-lb.on { display: flex; }
#patrol-lb .lb-img {
  max-width: min(1100px, 92vw); max-height: 80vh;
  border-radius: 12px; box-shadow: 0 12px 48px var(--overlay);
  display: block; background: var(--code-bg); cursor: zoom-out;
}
#patrol-lb .lb-cap {
  position: absolute; top: 18px; left: 22px;
  color: var(--on-pri); font-size: 13.5px; opacity: .9;
}
#patrol-lb .lb-x, #patrol-lb .lb-nav {
  position: absolute; border: 1px solid var(--tip-bg);
  background: var(--tip-bg); color: var(--on-pri);
  border-radius: 50%; cursor: pointer; line-height: 1;
}
#patrol-lb .lb-x { top: 14px; right: 18px; width: 40px; height: 40px; font-size: 17px; }
#patrol-lb .lb-nav {
  top: 50%; transform: translateY(-50%);
  width: 46px; height: 46px; font-size: 26px;
}
#patrol-lb .lb-x:hover, #patrol-lb .lb-nav:hover { filter: brightness(1.25); }
#patrol-lb .lb-prev { left: 18px; }
#patrol-lb .lb-next { right: 18px; }
#patrol-lb .lb-foot {
  position: absolute; bottom: 16px; left: 22px; right: 22px;
  display: flex; justify-content: space-between;
  color: var(--on-pri); font-size: 12.5px; opacity: .75;
}
@media (max-width: 720px) {
  #patrol-lb { padding: 10px; }
  #patrol-lb .lb-img { max-width: 94vw; max-height: 70vh; }
  #patrol-lb .lb-nav { width: 38px; height: 38px; }
  #patrol-lb .lb-prev { left: 8px; }
  #patrol-lb .lb-next { right: 8px; }
}

/* ── 考勤页 ──────────────────────────────────────────────── */
.att-card h3 { margin-bottom: 10px; }
.att-tag {
  display: inline-block; padding: 1px 8px; border-radius: 999px;
  font-size: 11.5px; line-height: 1.6; margin-left: 4px; white-space: nowrap;
}
.att-tag.ok   { background: var(--ok-bg); color: var(--ok-fg); }
.att-tag.warn { background: var(--warn-bg); color: var(--warn-tx); }
.att-tag.info { background: var(--line2); color: var(--tx3); }
.att-bad { color: var(--warn-tx); }
.att-ev-hint { margin: 12px 0 6px; font-size: 12.5px; color: var(--tx3); }
/* 月度表异常数字：点击展开该人明细（原地展开，不跳页） */
.att-num {
  cursor: pointer; color: var(--warn-tx); font-weight: 600;
  border-bottom: 1px dashed var(--warn-tx); padding-bottom: 1px;
}
.att-num:hover { color: var(--pri); border-bottom-color: var(--pri); }

/* ── 会员等级：可点的会员名 + 「手动」小标 ─────────────────────── */
.mem-name {
  cursor: pointer; font-weight: 600;
  border-bottom: 1px dashed var(--tx3);
}
.mem-name:hover { color: var(--pri); border-bottom-color: var(--pri); }
.mem-manual-tag {
  display: inline-block; margin-left: 2px; padding: 0 5px;
  font-size: 11px; border-radius: 4px;
  background: var(--warn-bg, rgba(230, 162, 60, .15));
  color: var(--warn-tx, #b8860b);
}
/* 营销页赠送数字：点击就地展开该分组明细（同考勤，不跳页） */
.mkt-num {
  cursor: pointer; font-weight: 600;
  border-bottom: 1px dashed var(--tx3); padding-bottom: 1px;
}
.mkt-num:hover { color: var(--pri); border-bottom-color: var(--pri); }
tr.att-dt-row > td {
  background: var(--hover); padding: 10px 14px !important;
  border-top: 1px dashed var(--line);
}
.att-dt-title { font-size: 12.5px; font-weight: 600; color: var(--tx2); margin-bottom: 6px; }
.att-dt-load { font-size: 12.5px; color: var(--tx3); padding: 2px 0; }
.att-dt-row table { margin: 0; }
.att-dt-row th, .att-dt-row td { font-size: 12px; padding: 4px 8px; }

/* ── 碰一碰打卡（卫生间 NFC/二维码）────────────────────────── */
.wc-ok   { color: var(--ok-tx, #2e9e63); }
.wc-bad  { color: var(--warn-tx); }
.wc-ops  { white-space: nowrap; }
.wc-act  { color: var(--pri); cursor: pointer; margin-right: 8px; font-size: 12.5px; }
.wc-act:hover { text-decoration: underline; }
.wc-act.danger { color: var(--warn-tx); }
.wc-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.wc-form label { display: inline-flex; gap: 5px; align-items: center; font-size: 13px; color: var(--tx2); }
.wc-form input, .wc-form select {
  border: 1px solid var(--line); background: var(--elev); color: var(--tx);
  border-radius: 8px; padding: 6px 9px; font-size: 13px; font-family: inherit;
}
.wc-form input:focus, .wc-form select:focus { outline: none; border-color: var(--pri); }
.wc-dt-row td { background: var(--bg-soft, transparent); }
.wc-slots { display: flex; flex-wrap: wrap; gap: 5px; }
.wc-slot {
  min-width: 52px; text-align: center; font-size: 12px; font-weight: 600;
  padding: 4px 7px; border-radius: 7px;
}
.wc-s-ok   { background: var(--ok-bg); color: var(--ok-tx, #2e9e63); }
.wc-s-miss { background: var(--warn-bg); color: var(--warn-tx); }
.wc-s-wait { background: var(--line2); color: var(--tx3); }

/* 贴码卡：打印件永远白底黑字，不跟主题走 */
#wc-labels .lbl-wrap { display: flex; flex-wrap: wrap; gap: 12px; margin: 12px 0 20px; }
.lbl {
  width: 210px; padding: 14px 12px; border: 1px dashed #b9c0cc; border-radius: 10px;
  background: #fff; color: #111; text-align: center; page-break-inside: avoid;
}
.lbl .lb-top { font-size: 12px; color: #666; letter-spacing: .5px; }
.lbl .lb-name { font-size: 19px; font-weight: 700; margin: 2px 0 8px; }
.lbl .lb-qr { display: flex; align-items: center; justify-content: center; min-height: 168px; }
.lbl .lb-qr svg { width: 160px; height: 160px; display: block; }
.lbl .lb-noqr { font-size: 12px; color: #a33; line-height: 1.6; padding: 24px 0; }
.lbl .lb-code { font-size: 22px; font-weight: 700; letter-spacing: 4px; margin: 6px 0 2px; }
.lbl .lb-tip { font-size: 13px; line-height: 1.5; }
.lbl .lb-sub { font-size: 11px; color: #777; margin-top: 2px; }
.lbl .lb-url {
  font-size: 9px; color: #999; word-break: break-all; margin-top: 8px; padding-top: 6px;
  border-top: 1px solid #eee; font-family: Consolas, Menlo, monospace;
}
.lbl.noqr .lb-url { color: #a33; font-size: 11px; }

@media print {
  body * { visibility: hidden !important; }
  #wc-labels, #wc-labels * { visibility: visible !important; }
  #wc-labels { position: absolute; left: 0; top: 0; width: 100%; }
  #wc-labels .card { display: none !important; }
  #wc-labels .lbl-wrap { position: absolute; left: 0; top: 0; width: 100%; gap: 6mm; padding: 8mm; }
  .lbl { border: 1px solid #000; border-radius: 0; width: 62mm; }
  .lbl .lb-url { display: none; }
}

/* ── 开店测算 ─────────────────────────────────────────────── */
.calc-form { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 10px 14px; margin-top: 12px; }
.ci { display: flex; flex-direction: column; gap: 4px; }
.ci > span { font-size: 12px; color: var(--tx2); display: flex; justify-content: space-between; align-items: baseline; }
.ci > span em { font-style: normal; color: var(--tx3); font-size: 11px; }
.ci input {
  border: 1px solid var(--line); background: var(--elev); color: var(--tx);
  font-family: inherit; font-size: 13px; padding: 6px 9px; border-radius: 9px;
  outline: none; transition: .15s; width: 100%; box-sizing: border-box;
  font-variant-numeric: tabular-nums;
}
.ci input:focus { border-color: var(--pri); box-shadow: 0 0 0 3px var(--pri-soft); }
.calc-t input {
  width: 100%; min-width: 70px; box-sizing: border-box;
  border: 1px solid transparent; background: transparent; color: var(--tx);
  font-family: inherit; font-size: 13.5px; padding: 4px 6px; border-radius: 7px;
  outline: none; text-align: right; font-variant-numeric: tabular-nums; transition: .15s;
}
.calc-t input:hover, .calc-t input:focus { border-color: var(--line); background: var(--elev); }
.calc-t .row-del {
  border: none; background: transparent; color: var(--tx3); cursor: pointer;
  font-size: 13px; padding: 4px 8px; border-radius: 7px; transition: .15s;
}
.calc-t .row-del:hover { color: var(--up); background: var(--hover); }
.calc-actions { display: flex; gap: 10px; margin: 2px 0 20px; }
.cmp td:last-child { font-weight: 600; }
.cmp .cmp-good { color: var(--up); }
.cmp .cmp-bad { color: var(--down); }
.ai-tips p { margin: 6px 0; font-size: 13px; color: var(--tx2); line-height: 1.65; }

/* ── AI 智能排班（v-sch）────────────────────────────── */
.sch-tbl th, .sch-tbl td { text-align: center; padding: 7px 8px; font-size: 12.5px; }
.sch-tbl td:first-child, .sch-tbl th:first-child { text-align: left; white-space: nowrap; }
.sch-shift {
  display: inline-block; padding: 3px 8px; border-radius: 6px;
  font-size: 12px; line-height: 1.4; white-space: nowrap;
}
.sch-d { background: var(--pri-soft, rgba(59,130,246,.14)); color: var(--pri, #3b82f6); }
.sch-m { background: rgba(234,179,8,.14); color: #b98a00; }
.sch-n { background: rgba(124,58,237,.14); color: #8b5cf6; }
.sch-off { color: var(--tx3); font-size: 12px; }
.sch-cov { max-width: 96px; font-size: 11px !important; line-height: 1.4; word-break: break-all; }
.sch-cov-list { margin-top: 8px; font-size: 12.5px; line-height: 1.8; color: var(--tx2); }
.sch-cov-list b { margin-right: 8px; color: var(--tx); font-weight: 600; }
.sch-cov-list > div { margin-top: 2px; }
.sch-tbl.sch-month th, .sch-tbl.sch-month td { padding: 4px 6px; font-size: 12px; }
.sch-tbl.sch-month td:first-child, .sch-tbl.sch-month th:first-child {
  position: sticky; left: 0; background: var(--bg1, #fff); z-index: 1; }
.sch-day { white-space: nowrap; }
.g5 { grid-template-columns: repeat(5, 1fr); }
@media (max-width: 1100px) { .g5 { grid-template-columns: repeat(2, 1fr); } }


/* ════ 机器监控（云更新·云维护平台）════════ */
.ygx-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 900px) { .ygx-grid { grid-template-columns: 1fr; } }
.ygx-hours { display: flex; align-items: flex-end; gap: 3px; height: 72px; }
.ygx-hbar { flex: 1; height: 100%; display: flex; align-items: flex-end;
  background: var(--bg2, rgba(127,127,127,.08)); border-radius: 3px; overflow: hidden; }
.ygx-hbar > i { display: block; width: 100%; background: var(--pri); border-radius: 3px; }
.ygx-drow { display: flex; align-items: center; gap: 8px; font-size: 12px; padding: 2px 0; }
.ygx-drow > span:first-child { width: 40px; flex: none; }
.ygx-drow b { width: 34px; text-align: right; flex: none; }
.ygx-drow .mini-bar { flex: 1; }
.ygx-wrow { display: flex; gap: 8px; font-size: 12px; padding: 3px 0;
  border-bottom: 1px dashed rgba(127,127,127,.15); align-items: baseline; }
.ygx-wrow.ok { opacity: .55; }
.ygx-wrow > span:first-child { flex: none; width: 74px; }
.ygx-wrow > b { flex: none; }
.ygx-wrow > span:last-child { flex: 1; min-width: 0; }
.ygx-games { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; font-size: 12px; }
.ygx-games > div > .ygx-drow > span:first-child { width: auto; flex: 1; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.tag { display: inline-block; padding: 2px 8px; border-radius: 10px; font-size: 12px;
  background: rgba(127,127,127,.14); }
.tag.warn { background: var(--warn, #c80); color: #fff; }
.tag.ok { background: var(--up, #2a2); color: #fff; }
.ell { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── 机器监控·四块布局（客户机/温度/游戏下载/服务器）── */
.ygx-grid4 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 900px) { .ygx-grid4 { grid-template-columns: 1fr; } }
.ygx-cell { border: 1px solid rgba(127,127,127,.18); border-radius: 10px; padding: 10px 12px;
  max-height: 300px; overflow-y: auto; }
.ygx-ct { font-weight: 600; margin-bottom: 6px; font-size: 13px; }
.ygx-day { padding: 4px 14px !important; font-size: 12px; background: transparent; }
.ygx-day.on { background: var(--pri, #3a7afe); color: #fff; }
.ygx-cell .ygx-wrow > b { max-width: 90px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── 机器监控 v2.1：字号加大 + 游戏名不截断 ── */
.ygx-cell { font-size: 13px; }
.ygx-cell .ygx-drow, .ygx-cell .ygx-wrow { font-size: 13px; }
.ygx-cell .ygx-drow > span.ell { flex: 1; min-width: 0; }
.ygx-cell .ygx-drow > span.mut { flex: none; white-space: nowrap; }
.ygx-cell .ygx-games { grid-template-columns: 1fr; font-size: 13px; }
.ygx-cell .ygx-ct { font-size: 13.5px; }
.ygx-cell .ygx-wrow > b { max-width: 110px; }

/* ── 机器监控 v2.4：未接入云更新的门店占位卡 ── */
.ygx-unbound { opacity: .8; }
.ygx-unbound h3 .hint { color: var(--tx3); font-weight: 400; }
.ygx-ub-tip { padding: 26px 12px; text-align: center; font-size: 13px;
  color: var(--tx3); line-height: 1.9; }

.msg.ai .txt .mini-tbl { margin: 8px 0; }

/* ── 客户机硬件台账（机器监控页，硬件来自大吧掌「资产/客户机硬件」）── */
.hw-card { margin-bottom: 14px; }
.hw-card h3 { margin: 0; }
/* 门店页签：店长 scope 只有 1 家时前端不渲染，看到的就是自己那家 */
.hw-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 2px; }
.hw-tab { display: inline-flex; align-items: center; gap: 5px; padding: 4px 11px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--soft);
  color: var(--tx2); font-size: 12.5px; font-family: inherit; cursor: pointer; }
.hw-tab:hover { border-color: var(--pri); color: var(--pri); }
.hw-tab i { font-style: normal; font-size: 11px; color: var(--tx3); font-weight: 700; }
.hw-tab.on { background: var(--pri); border-color: var(--pri); color: #fff; }
.hw-tab.on i { color: rgba(255, 255, 255, .8); }
.hw-srow { cursor: pointer; }
.hw-dists { margin: 10px 0 4px; }
.hw-dl { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 5px 0; font-size: 12px; }
.hw-dl > b { flex: 0 0 34px; color: var(--tx3); font-weight: 600; }
.hw-pill { display: inline-flex; align-items: center; gap: 5px; max-width: 300px;
  padding: 2px 8px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--soft); color: var(--tx2); white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
.hw-pill i { font-style: normal; color: var(--pri); font-weight: 700; }
.hw-alert { margin: 10px 0 0; padding: 8px 12px; border-radius: 9px; font-size: 12.5px;
  background: var(--warn-bg); border: 1px solid var(--warn-line); color: var(--warn-tx); }
.hw-alert:not(.ok) { cursor: pointer; user-select: none; }
.hw-alert.ok { background: var(--soft); border-color: var(--line); color: var(--tx2); }
.hw-more { margin-left: 6px; color: var(--pri); font-weight: 600; }
.hw-arlist { margin: 8px 0 2px; border: 1px solid var(--line); border-radius: 10px;
  max-height: 320px; overflow: auto; background: var(--field); }
.hw-ard { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
  padding: 6px 11px; border-bottom: 1px solid var(--line2); font-size: 12.5px; }
.hw-ard:last-child { border-bottom: none; }
.hw-m { font-weight: 700; min-width: 52px; }
.hw-diff { color: var(--tx2); }
.hw-diff b { color: var(--up); }
.hw-table { width: 100%; border-collapse: collapse; margin-top: 12px; font-size: 12.5px; }
.hw-table th { text-align: left; color: var(--tx3); font-weight: 600; padding: 6px 8px;
  border-bottom: 1px solid var(--line); white-space: nowrap; }
.hw-table td { padding: 7px 8px; border-bottom: 1px solid var(--line2); max-width: 240px; }
.hw-table tr:hover td { background: var(--hover); }
.hw-table .num { text-align: right; }
.hw-bad { color: var(--up); font-weight: 700; }
.hw-warn { color: var(--warn); font-weight: 700; }

/* ── CEO 专属：服务器更新时间 ─────────────────────────────── */
.sv-shop h3 { font-size: 15px; }
.sv-tbl { width: 100%; border-collapse: collapse; margin-top: 4px; font-size: 13px; }
.sv-tbl th { text-align: left; color: var(--tx3); font-weight: 600; font-size: 12.5px;
  padding: 7px 9px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.sv-tbl td { padding: 7px 9px; border-bottom: 1px solid var(--line2); }
.sv-tbl tr:hover td { background: var(--hover); }
.sv-edit-wrap { max-height: 56vh; overflow-y: auto; margin: 4px 0 10px; }
.sv-tbl input {
  width: 100%; border: 1px solid var(--line); border-radius: 8px; padding: 7px 9px;
  font-size: 13px; font-family: inherit; outline: none;
  background: var(--field); color: var(--tx);
}
.sv-tbl input:focus { border-color: var(--pri); box-shadow: 0 0 0 3px var(--pri-soft); }

/* CEO 服务器更新时间：本期有更新 / 超期未更新 标红 + 状态徽标 */
.sv-tbl tr.sv-warn > td { background: rgba(var(--up-rgb), .10); }
.sv-tbl tr.sv-warn:hover > td { background: rgba(var(--up-rgb), .16); }
.sv-badge { display: inline-block; padding: 1px 9px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600; line-height: 1.7; white-space: nowrap; }
.sv-badge.up   { color: var(--up); border: 1px solid var(--up); }
.sv-badge.old  { color: var(--up); border: 1px solid var(--up);
  background: rgba(var(--up-rgb), .12); font-weight: 700; }
.sv-badge.ok   { color: var(--ok-fg); border: 1px solid var(--ok-line); }
.sv-badge.gray { color: var(--tx3); border: 1px solid var(--line); }

/* ══════════════════════════════════════════════════════════════════
   主板 BIOS 官网更新信息（bios_vendor.py）
   ──────────────────────────────────────────────────────────────────
   全部走变量，不写死颜色（切主题必漏的坑见文件头约定）。
   ══════════════════════════════════════════════════════════════════ */
.bios-rows { margin-top: 10px; display: flex; flex-direction: column; gap: 10px; }
.bios-row { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px;
  background: var(--field); }
.bios-row[data-status="no_vendor"] { border-style: dashed; }
.bios-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.bios-board { font-weight: 700; font-size: 13.5px; }
.bios-n { font-size: 12px; color: var(--tx3); }
.bios-vendor { font-size: 12px; font-weight: 600; color: var(--pri);
  border: 1px solid var(--pri); border-radius: 999px; padding: 1px 9px; }
.bios-vsel { font-size: 12px; padding: 2px 6px; border: 1px solid var(--line);
  border-radius: 7px; background: var(--soft); color: var(--tx2); }
.bios-new { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin-top: 8px; font-size: 12.5px; }
.bios-ver { font-size: 14px; color: var(--up); }
.bios-dl { font-size: 12px; font-weight: 600; color: var(--pri); }
.bios-desc { margin-top: 5px; font-size: 12px; color: var(--tx2);
  max-width: 760px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bios-more { margin-top: 6px; font-size: 12px; color: var(--pri);
  font-weight: 600; cursor: pointer; user-select: none; }
.bios-hist { margin-top: 8px; }
.bios-hist td { max-width: 320px; }

/* ══════════════════════════════════════════════════════════════════
   BIOS 版本审计（云更新当前版本 vs 官网最新；落后=红、最新=绿）
   ══════════════════════════════════════════════════════════════════ */
.ba-stats { display: flex; gap: 10px; flex-wrap: wrap; margin: 12px 0 4px; }
.ba-stat { flex: 1; min-width: 110px; border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 12px; background: var(--field);
  display: flex; flex-direction: column; gap: 2px; }
.ba-stat b { font-size: 22px; font-weight: 800; line-height: 1.1; }
.ba-stat span { font-size: 12px; color: var(--tx3); }
.ba-ok { color: var(--down); }            /* 已是最新 = 绿 */
.ba-bad { color: var(--up); }             /* 落后 = 红 */
.ba-warn { color: var(--warn); }
.ba-shop { margin: 12px 0 6px; font-size: 13px; font-weight: 700;
  color: var(--tx2); }
.ba-tbl { margin-bottom: 6px; }
.ba-tbl td, .ba-tbl th { padding: 5px 8px; font-size: 12.5px; }
.ba-tbl .ctr { text-align: center; }
.ba-mach td { white-space: nowrap; }
.ba-more { margin-top: 8px; font-size: 12px; color: var(--pri);
  font-weight: 600; cursor: pointer; user-select: none; }

.btn.ghost { background: transparent; border: 1px solid var(--bdr, #d6dbe3); color: var(--mut, #888); }


/* ── 防逃费 ─────────────────────────────────────────────── */
.esc-kpis { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 12px; }
.esc-kpis .ba-stat {
  flex: 1 1 150px; background: var(--card, #fff); border: 1px solid var(--line, #e5e7eb);
  border-radius: 10px; padding: 12px 14px; text-align: center;
}
.esc-kpis .ba-stat b { display: block; font-size: 22px; line-height: 1.2; }
.esc-kpis .ba-stat span { font-size: 12px; color: var(--tx3); }
.esc-shop { margin-bottom: 12px; }
.esc-badge {
  display: inline-block; font-size: 11.5px; font-weight: 600; line-height: 1;
  padding: 4px 8px; border-radius: 999px; margin-left: 8px; vertical-align: middle;
}
.esc-badge-bad { color: #fff; background: var(--up); }
.esc-badge-warn { color: var(--warn); background: var(--warn-soft, rgba(245,158,11,.12)); }
.esc-badge-ok { color: var(--down); background: var(--down-soft, rgba(34,197,94,.12)); }
.esc-badge-off { color: var(--tx3); background: var(--tx3-soft, rgba(120,120,120,.12)); }
.esc-tbl td { font-size: 12.5px; }
/* AI 监控通知群配置行（CEO 可改 / 店长只读） */
.esc-ch-row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 9px 4px; border-bottom: 1px dashed var(--line, #e5e7eb);
}
.esc-ch-row:last-child { border-bottom: 0; }
.esc-ch-name { flex: 0 0 64px; font-weight: 600; font-size: 13px; }
.esc-ch-val { flex: 1 1 220px; font-size: 12px; min-width: 0; word-break: break-all; }
.esc-ch-ops { display: flex; gap: 6px; flex: 2 1 380px; min-width: 260px; }
.esc-ch-in {
  flex: 1; min-width: 0; font-size: 12px; padding: 6px 9px;
  border: 1px solid var(--bdr, #d6dbe3); border-radius: 8px; background: var(--card, #fff);
  color: var(--tx);
}
/* 空调系统账号行：地址/账号/密码三个输入框，窄屏自动换行 */
.ac-src-row .esc-ch-val { display: flex; gap: 6px; flex-wrap: wrap; }
.ac-src-in { flex: 1 1 150px; min-width: 110px; font-size: 12px; padding: 6px 9px;
  border: 1px solid var(--bdr, #d6dbe3); border-radius: 8px; background: var(--card, #fff);
  color: var(--tx); }
.btn.sm { padding: 5px 12px; font-size: 12px; border-radius: 7px; }
.btn.sm.ghost { background: transparent; border: 1px solid var(--bdr, #d6dbe3); color: var(--mut, #888); }

/* ── 运营 SOP 制度库（v-opsop）────────────────────────────────── */
.os-wrap { display: grid; grid-template-columns: 250px 1fr; gap: 14px; align-items: start; }
@media (max-width: 960px) { .os-wrap { grid-template-columns: 1fr; } }
.os-side { position: sticky; top: 12px; max-height: calc(100vh - 120px); overflow: auto; padding: 10px; }
.os-side-t { font-size: 12px; font-weight: 700; color: var(--tx3); padding: 2px 4px 8px; }
.os-nav {
  display: flex; align-items: flex-start; gap: 8px; width: 100%;
  text-align: left; background: none; border: 0; cursor: pointer;
  padding: 7px 8px; border-radius: 8px; color: var(--tx); font: inherit; line-height: 1.4;
}
.os-nav:hover { background: var(--soft); }
.os-nav.on { background: var(--pri); color: #fff; }
.os-nav.on .os-who { color: rgba(255, 255, 255, .75); }
.os-ico { font-size: 16px; flex: 0 0 20px; }
.os-nav-t { font-size: 13px; }
.os-who { display: block; font-style: normal; font-size: 11px; color: var(--tx3); }
.os-mod .os-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.os-goal { font-size: 13px; color: var(--tx2); margin: 2px 0 10px; line-height: 1.6; }
.os-b { margin: 14px 0; }
.os-bt { font-size: 14px; font-weight: 700; margin-bottom: 8px; }
.os-list { margin: 0; padding-left: 18px; font-size: 13.5px; line-height: 1.85; color: var(--tx); }
.os-flow { list-style: none; margin: 0; padding: 0; }
.os-flow li {
  position: relative; padding: 0 0 12px 26px;
  border-left: 2px solid var(--line); margin-left: 8px;
}
.os-flow li:last-child { border-left-color: transparent; padding-bottom: 2px; }
.os-flow li::before {
  content: ""; position: absolute; left: -6px; top: 2px; width: 10px; height: 10px;
  border-radius: 50%; background: var(--pri);
}
.os-fs { font-weight: 700; font-size: 13.5px; }
.os-fd { font-size: 13px; color: var(--tx2); margin-top: 2px; line-height: 1.6; }
.os-say {
  display: inline-block; margin-top: 5px; font-size: 12.5px; color: var(--pri);
  background: var(--soft); border-radius: 8px; padding: 4px 10px; line-height: 1.6;
}
.os-tbl { min-width: 560px; font-size: 13px; }
.os-tbl td { line-height: 1.6; }
.os-cks { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 14px; }
@media (max-width: 720px) { .os-cks { grid-template-columns: 1fr; } }
.os-ck {
  display: flex; gap: 8px; align-items: flex-start; cursor: pointer;
  font-size: 13.5px; line-height: 1.6; padding: 6px 9px; border-radius: 8px;
  border: 1px dashed var(--line);
}
.os-ck:hover { background: var(--soft); }
.os-ck.on { border-style: solid; color: var(--tx3); text-decoration: line-through; }
.os-ck input { margin-top: 3px; accent-color: var(--pri); }
.os-ckn {
  float: right; font-size: 11.5px; font-weight: 600; color: var(--pri);
  background: var(--soft); border-radius: 10px; padding: 1px 9px;
}
.os-rules { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 720px) { .os-rules { grid-template-columns: 1fr; } }
.os-rgt { font-weight: 700; font-size: 13px; margin-bottom: 6px; }
.os-rg .up { color: #e11d48; }  .os-rg .dn { color: #16a34a; }
.os-red {
  background: color-mix(in srgb, #e11d48 7%, transparent);
  border: 1px solid color-mix(in srgb, #e11d48 30%, transparent);
  border-radius: 10px; padding: 10px 14px;
}
.os-red .os-bt { color: #e11d48; }
.os-note {
  background: var(--soft); border-radius: 10px; padding: 9px 14px;
  font-size: 12.5px; color: var(--tx2); line-height: 1.7;
}

/* ── 运营 SOP · 制度依据（挂门店知识库 sop_doc）────────────────── */
.os-kb { margin-bottom: 14px; }
.os-kb-h { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.os-kb-h b { font-size: 14px; }
.os-kb-list { max-height: 220px; overflow: auto; }
.os-kb-i {
  display: flex; align-items: baseline; gap: 9px; width: 100%; text-align: left;
  background: none; border: 0; border-bottom: 1px dashed var(--line);
  padding: 7px 6px; cursor: pointer; font: inherit; color: var(--tx);
}
.os-kb-i:hover { background: var(--soft); }
.os-kb-c {
  flex: 0 0 auto; font-size: 11px; color: var(--pri); background: var(--soft);
  border-radius: 6px; padding: 1px 7px;
}
.os-kb-t { font-size: 13px; }
.os-src { border-top: 1px dashed var(--line); padding-top: 12px; }
.os-ref {
  background: var(--soft); border-radius: 10px; padding: 9px 13px; margin-bottom: 8px;
}
.os-ref-h { font-size: 13px; font-weight: 700; margin-bottom: 5px; }
.os-ref-id { float: right; font-size: 11px; font-weight: 400; color: var(--tx3); }
.os-ref-b p { margin: 0 0 3px; font-size: 12.5px; line-height: 1.75; color: var(--tx2); }
.os-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.os-chip {
  font: inherit; font-size: 12px; cursor: pointer; color: var(--pri);
  background: var(--soft); border: 1px solid var(--line);
  border-radius: 20px; padding: 3px 11px;
}
.os-chip:hover { background: var(--pri); color: #fff; border-color: var(--pri); }
.os-gap {
  background: color-mix(in srgb, #f59e0b 9%, transparent);
  border-radius: 10px; padding: 8px 13px; font-size: 12.5px;
  line-height: 1.7; color: var(--tx2);
}
.os-doc-body { max-height: 62vh; overflow: auto; margin-top: 10px; }
.os-doc-body p { margin: 0 0 6px; font-size: 13.5px; line-height: 1.85; color: var(--tx); }

/* ══════════ 经营洞察（#1~#7）═════════════════════════════════════
   说明条、诊断三段式、状态标签。颜色一律走变量，自动跟随浅/深主题。 */
.ins-note {
  font-size: 12px;
  line-height: 1.65;
  color: var(--tx2);
  background: var(--bg2, rgba(127,127,127,.08));
  border: 1px solid var(--line);
  border-left: 3px solid var(--pri);
  border-radius: 6px;
  padding: 8px 11px;
  margin: 8px 0;
}
.ins-diag {
  white-space: pre-wrap;
  word-break: break-word;
  font-family: inherit;
  font-size: 13.5px;
  line-height: 1.85;
  color: var(--tx1, var(--tx));
  background: var(--bg2, rgba(127,127,127,.06));
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 12px 14px;
  margin: 0;
  max-height: 46vh;
  overflow-y: auto;
}
.ins-tag {
  display: inline-block;
  margin-left: 6px;
  font-size: 10.5px;
  line-height: 1.5;
  padding: 0 5px;
  border-radius: 4px;
  border: 1px solid var(--line);
  color: var(--tx3);
  vertical-align: 1px;
}
.ins-tag.ins-low  { color: var(--down); border-color: var(--down); }
.ins-tag.ins-hi   { color: var(--up);   border-color: var(--up); }
.ins-tag.warn     { color: #d89100;     border-color: #d89100; }

/* 表格里的数值着色：低效绿（跌）、高产出红（涨）—— 沿用站内涨红跌绿 */
.ch-tbl td.ins-low { color: var(--down); font-weight: 600; }
.ch-tbl td.ins-hi  { color: var(--up);   font-weight: 600; }

/* ══════════════════════════════════════════════════════════════
   质检中心（v-qc）：多卡打分 / 一岗一表 / 日清 / 节奏 / 人员 / 模板
   涨红跌绿沿用 --up/--down；hidden 一律走样式表，不写 style=""   ══════ */

/* —— 通用兜底（质检页复用，避免依赖别处定义）—— */
#v-qc .inp, .qc-modal .inp {
  border: 1px solid var(--line); background: var(--elev); color: var(--tx);
  border-radius: 8px; padding: 5px 9px; font-size: 13px; font-family: inherit;
}
#v-qc .btn-s, .qc-modal .btn-s {
  padding: 3px 9px; font-size: 12px; border-radius: 7px;
}
#v-qc .btn-primary, .qc-modal .btn-primary {
  border-color: var(--pri); color: var(--pri); font-weight: 600;
}
#v-qc .tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
#v-qc .tbl th, #v-qc .tbl td {
  padding: 7px 9px; border-bottom: 1px solid var(--line); text-align: left;
}
#v-qc .tbl th { color: var(--tx3); font-weight: 600; font-size: 12px; }
#v-qc .tbl .num { text-align: right; font-variant-numeric: tabular-nums; }
#v-qc .tbl-wrap { overflow-x: auto; }

/* —— 顶栏：门店/日期/子页签 —— */
.qc-bar { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: end; margin-top: 10px; }
.qc-fld { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--tx3); }
.qc-fld .inp { min-width: 130px; }

/* —— 角色选择 —— */
.qc-roles { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.qc-role {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--line); background: var(--elev); color: var(--tx2);
  border-radius: 10px; padding: 8px 14px; font-size: 13.5px; cursor: pointer;
  font-family: inherit; transition: .15s;
}
.qc-role:hover { border-color: var(--pri); color: var(--pri); }
.qc-role.on { border-color: var(--pri); color: var(--pri); background: var(--pri-soft); font-weight: 600; }

/* —— 星级 / 标签 —— */
.qc-star { font-weight: 700; }
.qc-star.sA { color: var(--up); }
.qc-star.sB { color: #d89100; }
.qc-star.sC { color: var(--tx2); }
.qc-star.sD { color: var(--down); }
.qc-tag {
  display: inline-block; padding: 1px 7px; border-radius: 5px;
  font-size: 11px; border: 1px solid var(--line); color: var(--tx3);
  vertical-align: 1px; white-space: nowrap;
}
.qc-tag.ok   { color: var(--up);   border-color: var(--up); }
.qc-tag.warn { color: #d89100;     border-color: #d89100; }
.qc-tag.mut  { color: var(--tx3); }

/* —— 卡列表 —— */
.qc-card { margin-bottom: 10px; cursor: pointer; transition: .15s; }
.qc-card:hover { border-color: var(--pri); }
.qc-card-h { display: flex; align-items: center; gap: 9px; font-size: 14.5px; }
.qc-card-m { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 7px;
  font-size: 12.5px; color: var(--tx2); }
.qc-red { margin-top: 7px; font-size: 12.5px; color: var(--down); }

/* —— 自动判分面板 —— */
.qc-auto h3 { margin: 0 0 10px; font-size: 14px; }
.qc-auto-g { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 9px; }
.qc-auto-i { border: 1px solid var(--line); border-radius: 9px; padding: 8px 11px;
  font-size: 12.5px; display: flex; flex-direction: column; gap: 3px; }
.qc-auto-i b { font-size: 12px; color: var(--tx2); }
.qc-auto-i span { color: var(--tx3); }
.qc-auto-i.hit { border-color: #d89100; }
.qc-auto-i.hit span { color: #d89100; }

/* —— 打分弹窗 —— */
.qc-modal { max-width: 860px; width: 94vw; }
.qc-items { max-height: 52vh; overflow-y: auto; margin: 10px 0; }
.qc-item { border: 1px solid var(--line); border-radius: 10px;
  padding: 9px 11px; margin-bottom: 8px; }
.qc-item-t { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.qc-no { flex: 0 0 auto; min-width: 22px; height: 22px; border-radius: 6px;
  background: var(--soft); color: var(--tx3); font-size: 11.5px;
  display: inline-flex; align-items: center; justify-content: center; }
.qc-g { flex: 0 0 auto; font-size: 11px; color: var(--pri);
  border: 1px solid var(--pri); border-radius: 4px; padding: 0 5px; }
.qc-tt { flex: 1 1 auto; }
.qc-item-c { display: flex; flex-wrap: wrap; align-items: center; gap: 9px;
  margin-top: 7px; padding-left: 30px; font-size: 12.5px; color: var(--tx2); }
.qc-got { width: 64px; }
.qc-ded { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
.qc-desc { flex: 1 1 220px; min-width: 180px; }
.qc-photo-l { cursor: pointer; color: var(--pri); white-space: nowrap; }
.qc-photo { display: none; }
.qc-photos { display: inline-flex; gap: 5px; }
.qc-thumb { width: 34px; height: 34px; object-fit: cover; border-radius: 6px;
  border: 1px solid var(--line); }
.qc-foot { border-top: 1px solid var(--line); padding-top: 10px; }
.qc-rl { font-size: 12.5px; }
.qc-rl-i { display: inline-flex; align-items: center; gap: 5px; margin: 5px 12px 0 0;
  cursor: pointer; color: var(--tx2); }
.qc-cmp { margin-top: 9px; font-size: 12.5px; color: var(--tx2); }
.qc-btns { display: flex; gap: 9px; justify-content: flex-end; margin-top: 11px; }

/* —— 日清 —— */
.qc-daily-h { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; font-size: 13px; color: var(--tx2); flex-wrap: wrap; }
.qc-shifts { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 12px; }
.qc-shift h3 { display: flex; align-items: center; gap: 8px; font-size: 14px; margin: 0 0 9px; }
.qc-tasks { display: flex; flex-direction: column; gap: 5px; }
.qc-task { display: flex; align-items: center; gap: 8px; font-size: 12.5px;
  padding: 5px 8px; border-radius: 8px; cursor: pointer; }
.qc-task:hover { background: var(--soft); }
.qc-task.done { opacity: .55; }
.qc-task.done .qc-task-t { text-decoration: line-through; }
.qc-task-t { flex: 1 1 auto; }

/* —— 节奏时间轴 —— */
.qc-nodes { display: flex; flex-direction: column; gap: 9px; }
.qc-node { border: 1px solid var(--line); border-radius: 11px; padding: 10px 13px; }
.qc-node.done { border-color: var(--up); }
.qc-node-t { display: flex; align-items: center; gap: 11px; }
.qc-node-t b { font-size: 13px; color: var(--pri); font-variant-numeric: tabular-nums; }
.qc-node-n { font-size: 14px; font-weight: 600; flex: 1 1 auto; }
.qc-node ul { margin: 7px 0 0; padding-left: 42px; font-size: 12.5px;
  color: var(--tx2); line-height: 1.75; }
.qc-patrol { margin: 6px 0 0; padding-left: 20px; font-size: 12.5px;
  color: var(--tx2); line-height: 1.8; }

/* —— 人员：职级/承诺/技能/晋升 —— */
.qc-lv { display: inline-block; padding: 1px 8px; border-radius: 5px;
  font-size: 11.5px; border: 1px solid var(--line); color: var(--tx2); }
.qc-lv.lv-manager { color: var(--up); border-color: var(--up); font-weight: 600; }
.qc-lv.lv-vice    { color: var(--up); border-color: var(--up); }
.qc-lv.lv-mentor  { color: #d89100; border-color: #d89100; }
.qc-lv.lv-trainer { color: #d89100; border-color: #d89100; }
.qc-lv.lv-star3   { color: var(--pri); border-color: var(--pri); }
.qc-promise-f { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 11px; }
.qc-promise-f .inp { flex: 1 1 120px; min-width: 0; }
.qc-conds { margin: 6px 0 0; padding-left: 20px; font-size: 13px; line-height: 2; }
.qc-conds li.ok  { color: var(--up); }
.qc-conds li.no  { color: var(--down); }
.qc-conds li.mut { color: var(--tx3); }
.qc-skills { display: flex; flex-direction: column; gap: 8px; margin: 10px 0; }
.qc-skill { display: flex; align-items: center; gap: 11px; font-size: 13px; }
.qc-skill > span:first-child { flex: 0 0 130px; }
.qc-sk-r { flex: 1 1 auto; accent-color: var(--pri); }
.qc-sk-v { flex: 0 0 46px; text-align: right; font-variant-numeric: tabular-nums; }
.qc-skill-add { display: flex; gap: 7px; flex-wrap: wrap; }
.qc-skill-add .inp { flex: 1 1 120px; min-width: 0; }
.qc-weak { margin: 6px 0 0; padding-left: 20px; font-size: 12.5px;
  color: var(--tx2); line-height: 1.9; }

/* —— 模板编辑 —— */
.qc-tpl-f { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12.5px;
  color: var(--tx2); margin-bottom: 8px; }
.qc-tpl-f label { display: inline-flex; align-items: center; gap: 6px; }

/* ══════════ 监控智能（v-nvr，逗鱼店试点）══════════ */
.nvr-stats { display: grid; grid-template-columns: repeat(6, 1fr); gap: 10px; margin-top: 12px; }
.nvr-stat { background: var(--soft); border-radius: 10px; padding: 10px 12px;
  display: flex; flex-direction: column; gap: 2px; }
.nvr-stat .lab { font-size: 12px; color: var(--tx3); }
.nvr-stat .val { font-size: 20px; font-weight: 700; color: var(--tx1); }
.nvr-stat .val.warn { color: var(--down); }
.nvr-bar { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; margin-top: 12px; }
.nvr-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.nvr-cam { border: 1px solid var(--line); border-radius: 12px; overflow: hidden; background: var(--card); }
.nvr-cam.off { opacity: .55; }
.nvr-shot { position: relative; aspect-ratio: 16/10; background: #0c0e13; cursor: zoom-in; }
.nvr-shot img.nvr-live { width: 100%; height: 100%; object-fit: cover; display: block; }
.nvr-offline { position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; color: var(--tx3); font-size: 13px; }
.nvr-ch { position: absolute; left: 8px; bottom: 6px; font-size: 11.5px; color: #fff;
  background: rgba(0,0,0,.55); padding: 2px 7px; border-radius: 6px; }
.nvr-kind { position: absolute; right: 8px; top: 6px; font-size: 11px; color: #fff;
  background: rgba(0,0,0,.55); padding: 2px 7px; border-radius: 6px; }
.nvr-kind.k-private { background: rgba(220,60,60,.75); }
.nvr-kind.k-outdoor { background: rgba(40,120,220,.75); }
.nvr-cam-foot { display: flex; align-items: center; justify-content: space-between;
  gap: 8px; padding: 8px 10px; }
.nvr-badge { font-size: 11.5px; padding: 2px 8px; border-radius: 999px; white-space: nowrap; }
.nvr-badge.k-motion  { background: rgba(40,120,220,.14); color: #2878dc; }
.nvr-badge.k-residue { background: rgba(230,150,0,.16);  color: #b87400; }
.nvr-badge.k-scene   { background: rgba(220,60,60,.14);  color: #dc3c3c; }
.nvr-badge.k-offline { background: var(--soft); color: var(--tx3); }
.nvr-badge.k-mach    { background: rgba(30,160,120,.14); color: #1ea078; }
.nvr-badge.k-fp       { background: rgba(150,150,160,.18); color: #6b7280; }
.nvr-fp-reasons { display: flex; flex-wrap: wrap; gap: 6px 14px; margin: 8px 0 4px; }
.nvr-fp-reasons .qc-fld { margin: 0; font-size: 13px; }
.nvr-fp-stat { margin: 6px 0 2px; font-size: 12.5px; }
.nvr-fp-stat .nvr-badge { margin-right: 4px; }
.btn-s.nvr-fp { margin-left: 6px; background: var(--soft); color: var(--tx2); }
.nvr-thumb { width: 92px; height: 58px; object-fit: cover; border-radius: 6px;
  border: 1px solid var(--line); cursor: zoom-in; display: block; }
.nvr-big { max-width: 860px; }
.nvr-bigimg { width: 100%; border-radius: 10px; border: 1px solid var(--line); background: #0c0e13; }
.nvr-foot { display: flex; gap: 10px; justify-content: flex-end; margin-top: 14px; }
.nvr-modal { max-width: 420px; }
#v-nvr .btn-s { padding: 5px 12px; font-size: 12.5px; }
#v-nvr .btn-s.off { color: var(--tx3); border-style: dashed; }
@media (max-width: 720px) {
  .nvr-stats { grid-template-columns: repeat(3, 1fr); }
}

/* ── 一键巡店报告（patrol_report.js）────────────────────────── */
#pr-shop { display: inline-block; width: auto; min-width: 130px; margin-right: 8px; }
.pr-head { display: flex; gap: 16px; align-items: center; margin-bottom: 10px; }
.pr-score { display: flex; align-items: baseline; gap: 6px; padding: 8px 18px;
  border-radius: 12px; background: var(--soft); }
.pr-score .pr-num { font-size: 34px; font-weight: 700; line-height: 1; }
.pr-score .pr-star { font-size: 15px; font-weight: 700; opacity: .75; }
.pr-score.s-A { color: #16a34a; }
.pr-score.s-B { color: #2563eb; }
.pr-score.s-C { color: #d97706; }
.pr-score.s-D { color: #dc2626; }
.pr-meta { font-size: 13px; color: var(--tx2); line-height: 1.7; }
.pr-meta .up { color: #dc2626; }
.pr-meta .down { color: #16a34a; }
.pr-hist { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: 12px; }
.pr-hitem { font-size: 12px; padding: 3px 10px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--line); background: var(--bg2); color: var(--tx2); }
.pr-hitem:hover { border-color: var(--ac); color: var(--ac); }
.pr-dims { display: grid; gap: 8px; margin-bottom: 14px; }
.pr-dim { display: grid; grid-template-columns: 150px 1fr 48px; gap: 10px;
  align-items: center; font-size: 13px; }
.pr-dim .pr-dname i { font-style: normal; margin-left: 6px; }
.pr-bar { height: 8px; border-radius: 999px; background: var(--soft); overflow: hidden; }
.pr-bar i { display: block; height: 100%; border-radius: 999px; }
.pr-bar i.ok { background: #16a34a; }
.pr-bar i.mid { background: #d97706; }
.pr-bar i.bad { background: #dc2626; }
.pr-dscore { text-align: right; font-weight: 600; }
.pr-thumb { width: 92px; height: 58px; object-fit: cover; border-radius: 6px;
  cursor: zoom-in; border: 1px solid var(--line); }
.nvr-badge.k-hw { background: #fef3c7; color: #92400e; }
.nvr-badge.k-ygx { background: #ede9fe; color: #5b21b6; }
.nvr-badge.k-cam { background: var(--soft); color: var(--tx3); }
.nvr-badge.k-patrol { background: #dcfce7; color: #166534; }
.nvr-badge.k-nvr { background: #dbeafe; color: #1e40af; }

/* ── 摄像头画面框选机位（nvr.js nvrEditCam）─────────────────── */
.nvr-zone-modal { width: 860px; max-width: 94vw; }
.nvr-ce-row { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; }
.nvr-ce-row .qc-fld { flex: 1 1 160px; margin: 0; }
.nvr-ce-on { flex: 0 0 auto; }
.nvr-zone-tip { font-size: 12.5px; color: var(--tx3); margin: 10px 0 8px;
  line-height: 1.6; }
.nvr-zone-wrap { position: relative; width: 100%; aspect-ratio: 16/9;
  background: #000; border-radius: 8px; overflow: hidden;
  user-select: none; cursor: crosshair; }
.nvr-zone-wrap img { width: 100%; height: 100%; object-fit: fill; display: block; }
.nvr-zbox { position: absolute; border: 2px solid #ef4444; border-radius: 3px;
  box-sizing: border-box; cursor: pointer; background: rgba(239,68,68,.08); }
.nvr-zbox span { position: absolute; left: 0; top: -19px; font-size: 11px;
  background: #ef4444; color: #fff; padding: 1px 6px; border-radius: 3px;
  white-space: nowrap; }
.nvr-zbox:hover { background: rgba(239,68,68,.22); }
#nvr-zdrag { position: absolute; border: 2px dashed #fbbf24;
  background: rgba(251,191,36,.15); pointer-events: none; }
.nvr-zone-foot { display: flex; justify-content: space-between;
  align-items: center; margin: 8px 0 4px; font-size: 12.5px; }
.nvr-ask { position: fixed; left: 50%; top: 18%; transform: translateX(-50%);
  z-index: 999; display: flex; gap: 8px; padding: 12px 14px;
  background: var(--bg2); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 8px 30px rgba(0,0,0,.35); }
.nvr-ask .inp { width: 150px; }


/* ── 固定资产台账 ─────────────────────────────────────────────
   版式：左边一条窄导航（模块入口 + 全局动作），右边一块内容区。
   模块多了以后横排页签会挤成一行看不出重点，竖排靠左反而一眼扫完。
   表格默认 td 是右对齐（给数字用的），资产页大多是文字，统一改左；
   只有金额/件数这几列保留右对齐。 */

.as-shell { display: grid; grid-template-columns: 198px minmax(0, 1fr); gap: 16px; align-items: start; }

.as-side {
  position: sticky; top: 88px;              /* 让开上面那条吸顶导航 */
  max-height: calc(100vh - 102px); overflow: auto;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 10px;
  display: flex; flex-direction: column; gap: 6px;
  box-shadow: var(--shadow);
}
.as-side-shop { padding: 2px 4px 9px; border-bottom: 1px solid var(--line2); }
.as-side-shop label {
  display: block; font-size: 11px; color: var(--tx3);
  letter-spacing: .4px; margin-bottom: 5px;
}
.as-side-shop select { width: 100%; }

#as-nav { display: flex; flex-direction: column; gap: 2px; }
#as-nav button {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 8px 10px; border: 0; border-radius: 9px; cursor: pointer;
  background: transparent; color: var(--tx2);
  font-size: 13.5px; font-family: inherit; text-align: left;
  transition: background .12s, color .12s;
}
#as-nav button i {
  width: 15px; flex: 0 0 15px; text-align: center;
  font-style: normal; font-size: 13px; color: var(--tx3); opacity: .85;
}
#as-nav button span { flex: 1; min-width: 0; }
#as-nav button b.as-n {
  font-size: 11px; font-weight: 600; color: var(--tx3);
  font-variant-numeric: tabular-nums;
}
#as-nav button:hover { background: var(--soft); color: var(--tx); }
#as-nav button.on { background: var(--pri-soft); color: var(--pri); font-weight: 600; }
#as-nav button.on i { color: var(--pri); opacity: 1; }
#as-nav button.on b.as-n { color: var(--pri); }

.as-side-foot {
  border-top: 1px solid var(--line2); padding-top: 7px;
  display: flex; flex-direction: column; gap: 1px;
}
.as-side-foot button {
  border: 0; background: transparent; cursor: pointer;
  padding: 7px 10px; border-radius: 8px; text-align: left;
  font-size: 12.5px; color: var(--tx3); font-family: inherit;
}
.as-side-foot button:hover { background: var(--soft); color: var(--pri); }

/* 页面头：标题 + 一句话说明 + 本页才用得上的动作 */
.as-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 12px;
}
.as-head h2 { margin: 0; font-size: 19px; letter-spacing: -.3px; font-weight: 650; }
.as-head .as-sub { margin: 4px 0 0; font-size: 12.5px; color: var(--tx3); }
.as-acts { display: flex; gap: 8px; flex-wrap: wrap; }

/* 筛选条：搜索占一头，其余控件收成紧凑一组 */
.as-tools { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 10px; }
.as-search { position: relative; flex: 1 1 200px; max-width: 330px; }
.as-search input { width: 100%; padding-left: 30px; }
.as-search::before {
  content: "⌕"; position: absolute; left: 10px; top: 50%;
  transform: translateY(-52%); font-size: 15px; color: var(--tx3); pointer-events: none;
}
.as-tools .sel { width: auto; min-width: 104px; }
.as-link {
  border: 0; background: transparent; cursor: pointer; padding: 6px 4px;
  font-size: 12.5px; color: var(--tx3); font-family: inherit;
}
.as-link:hover { color: var(--pri); }

/* 分类快捷筛选 */
.as-chips {
  display: flex; gap: 6px; overflow-x: auto; padding-bottom: 4px;
  margin-bottom: 11px; scrollbar-width: thin;
}
.as-chips::-webkit-scrollbar { height: 4px; }
.as-chips button {
  flex: 0 0 auto; cursor: pointer; white-space: nowrap;
  border: 1px solid var(--line); background: var(--card); color: var(--tx2);
  border-radius: 999px; padding: 5px 12px; font-size: 12.5px; font-family: inherit;
  transition: border-color .12s, color .12s, background .12s;
}
.as-chips button b { font-weight: 600; color: var(--tx3); margin-left: 5px; font-size: 11.5px; }
.as-chips button:hover { border-color: var(--pri); color: var(--pri); }
.as-chips button.on { border-color: var(--pri); background: var(--pri-soft); color: var(--pri); }
.as-chips button.on b { color: var(--pri); }

#v-assets .as-t { width: 100%; border-collapse: collapse; font-size: 13px; }
#v-assets .as-t th:first-child, #v-assets .as-t td:first-child { width: 34px; }
#v-assets .as-t input[type=checkbox] {
  width: 14px; height: 14px; cursor: pointer; accent-color: var(--pri); vertical-align: middle;
}
#v-assets .as-t th, #v-assets .as-t td { text-align: left; white-space: nowrap; }
#v-assets .as-t thead th {
  font-size: 12px; font-weight: 600; color: var(--tx3);
  padding: 8px 10px; border-bottom: 1px solid var(--line);
}
#v-assets .as-t tbody td { padding: 9px 10px; border-bottom: 1px solid var(--line2); vertical-align: middle; }
#v-assets .as-t td.num, #v-assets .as-t th.num {
  text-align: right; font-variant-numeric: tabular-nums;
}
#v-assets .as-t tbody tr { cursor: pointer; }
#v-assets .as-t tbody tr:hover td { background: var(--soft); }
#v-assets .as-t tbody tr:hover td:first-child { background: var(--soft); }
#v-assets .as-t tbody tr:last-child td { border-bottom: 0; }

/* 名称列：主行名称，次行型号 / 序列号 */
.as-cell-main { font-weight: 500; }
.as-cell-sub { font-size: 11.5px; color: var(--tx3); margin-top: 2px; }

/* 状态用一个小圆点 + 文字，比整块色标安静，一列扫下来也更齐 */
.as-dot { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--tx2); }
.as-dot::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--tx3); flex: 0 0 6px; }
.as-dot.ok::before   { background: var(--ok-fg); }
.as-dot.info::before { background: var(--pri); }
.as-dot.warn::before { background: var(--warn); }
.as-dot.bad::before  { background: var(--up); }

.as-chip {
  display: inline-block; padding: 1px 8px; border-radius: 999px;
  font-size: 11.5px; line-height: 1.65; white-space: nowrap;
  border: 1px solid transparent;
}
.as-chip.ok   { background: var(--ok-bg); color: var(--ok-fg); }
.as-chip.warn { background: var(--warn-bg); color: var(--warn-tx); }
.as-chip.info { background: var(--line2); color: var(--tx3); }
.as-chip.bad  { color: var(--up); border-color: var(--up); }

/* 详情弹层的动作条：主操作在左，工具类收成文字链接在右 */
.as-detail-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 14px 0 4px; }
.as-detail-acts .sp { flex: 1 1 12px; }
.as-detail-acts .as-link { font-size: 12.5px; }

/* 总览：左边分类构成、右边待办 */
.as-grid2 { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 14px; }
.as-bar { height: 6px; border-radius: 3px; background: var(--line2); overflow: hidden; min-width: 60px; }
.as-bar i { display: block; height: 100%; border-radius: 3px; background: var(--bar-grad); }
.as-todo { display: flex; flex-direction: column; }
.as-todo button {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 4px; border: 0; border-bottom: 1px solid var(--line2);
  background: transparent; cursor: pointer; font-family: inherit;
  font-size: 13px; color: var(--tx); text-align: left;
}
.as-todo button:last-child { border-bottom: 0; }
.as-todo button:hover { color: var(--pri); }
.as-todo button b { font-variant-numeric: tabular-nums; font-size: 15px; }
.as-todo-t { display: block; }
.as-todo .as-todo-hint { display: block; font-size: 11.5px; color: var(--tx3); margin-top: 2px; }

/* 盘点进度 */
.as-prog { display: flex; align-items: center; gap: 8px; min-width: 130px; }
.as-prog .as-bar { flex: 1; }
.as-prog span { font-size: 11.5px; color: var(--tx3); font-variant-numeric: tabular-nums; }

#v-assets .mono { font-variant-numeric: tabular-nums; letter-spacing: .2px; }
#v-assets .kvs { grid-template-columns: repeat(3, 1fr); }

@media (max-width: 980px) {
  .as-grid2 { grid-template-columns: 1fr; }
}
@media (max-width: 860px) {
  .as-shell { grid-template-columns: 1fr; }
  .as-side {
    position: static; flex-direction: row; align-items: center;
    overflow-x: auto; padding: 7px 8px; gap: 8px;
  }
  .as-side-shop { border: 0; padding: 0 6px 0 0; flex: 0 0 auto; }
  .as-side-shop label { display: none; }
  .as-side-shop select { width: 108px; }
  #as-nav { flex-direction: row; gap: 3px; flex: 0 0 auto; }
  #as-nav button { width: auto; padding: 7px 10px; white-space: nowrap; }
  #as-nav button i, #as-nav button b.as-n { display: none; }
  .as-side-foot { border: 0; padding: 0; flex-direction: row; gap: 2px; flex: 0 0 auto; }
  .as-side-foot button { white-space: nowrap; }
  #v-assets .kvs { grid-template-columns: 1fr 1fr; }
}

/* ══════════════════════════════════════════════════════════════
   2026-10-31 照精灵那套补齐的模块：待办 / 备件 / 流转 / 帮助
   ──────────────────────────────────────────────────────────────
   共用一个小胶囊按钮 .as-pill（筛选和分段都用它），
   四个新页面都靠它，所以样式集中写在这里一次。
   ══════════════════════════════════════════════════════════════ */

/* 胶囊筛选：选中态用主色描边 + 淡底，不抢页头标题的注意力 */
.as-pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 11px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--line); background: var(--card); color: var(--tx2);
  font-size: 12.5px; line-height: 1.6; white-space: nowrap;
  transition: all .12s;
}
.as-pill:hover { border-color: var(--pri); color: var(--pri); }
.as-pill.on {
  background: var(--pri-soft); border-color: var(--pri); color: var(--pri);
  font-weight: 600;
}
.as-pill b { font-variant-numeric: tabular-nums; opacity: .75; font-weight: 600; }
.as-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }

/* 一行筛选：搜索框 + 下拉 + 右侧胶囊 */
.as-flt {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 10px;
}
.as-flt .sel { width: 150px; }

/* ── 待办卡片 ─────────────────────────────────────────────── */
.as-tds { display: flex; flex-direction: column; gap: 8px; }
.as-td {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 13px 16px; border-radius: 11px; cursor: pointer; text-align: left;
  border: 1px solid var(--line); background: var(--card); color: var(--tx);
  transition: all .12s;
}
.as-td:hover { border-color: var(--pri); background: var(--soft); }
.as-td-t { flex: 1; display: block; font-size: 13.5px; font-weight: 500; }
.as-td-t em {
  display: block; font-style: normal; font-size: 11.5px;
  color: var(--tx3); margin-top: 2px; font-weight: 400;
}
.as-td b {
  font-size: 19px; font-variant-numeric: tabular-nums;
  color: var(--pri); min-width: 34px; text-align: right;
}
.as-td i { font-style: normal; color: var(--tx3); font-size: 16px; }

/* ── 备件缺口 ─────────────────────────────────────────────── */
.as-gaps { display: flex; flex-direction: column; }
.as-gap-row {
  display: grid; grid-template-columns: minmax(0, 1.4fr) 90px minmax(0, 1fr);
  gap: 12px; align-items: center; padding: 9px 0;
  border-top: 1px solid var(--line2); font-size: 13px;
}
.as-gap-row:first-child { border-top: 0; }
.as-gap-row span { display: block; font-size: 11.5px; margin-top: 1px; }
.as-gap-need {
  font-weight: 700; color: var(--up); font-variant-numeric: tabular-nums;
  text-align: right;
}
@media (max-width: 720px) {
  .as-gap-row { grid-template-columns: 1fr auto; }
  .as-gap-row > :nth-child(3) { grid-column: 1 / -1; }
}

/* 各店分布的小徽标 */
.as-shopn {
  display: inline-block; padding: 1px 7px; margin-right: 4px;
  border-radius: 6px; background: var(--line2); color: var(--tx2);
  font-size: 11.5px; white-space: nowrap;
}
.as-shopn b { color: var(--tx); font-variant-numeric: tabular-nums; }

/* ── 选择设备的长列表（流转 / 纠正数量） ─────────────────── */
.as-pick {
  max-height: 230px; overflow: auto; border: 1px solid var(--line);
  border-radius: 9px; background: var(--field);
}
.as-pick-row {
  display: flex; align-items: center; gap: 9px; padding: 7px 11px;
  border-bottom: 1px solid var(--line2); cursor: pointer; font-size: 12.5px;
}
.as-pick-row:last-child { border-bottom: 0; }
.as-pick-row:hover { background: var(--hover); }
.as-pick-row input { width: 14px; height: 14px; accent-color: var(--pri); }
.as-pick-row span:nth-child(2) { color: var(--tx3); font-size: 12px; }
.as-pick-row span:nth-child(3) { flex: 1; }

/* 表里可点的数字：一眼看出「这里能钻进去」 */
.as-num {
  border: 0; background: none; padding: 0; cursor: pointer;
  color: var(--pri); font: inherit; font-variant-numeric: tabular-nums;
  border-bottom: 1px dashed currentColor;
}
.as-num:hover { color: var(--pri-hover); }

/* ── 使用帮助 ─────────────────────────────────────────────── */
.as-help-g + .as-help-g { margin-top: 18px; }
.as-help-g h4 {
  margin: 0 0 8px; font-size: 12.5px; font-weight: 600; color: var(--tx3);
  letter-spacing: .04em; display: flex; align-items: center; gap: 8px;
}
.as-help-g h4 span {
  font-weight: 400; font-size: 11.5px; color: var(--tx3); opacity: .8;
}
.as-help {
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--card); margin-bottom: 7px; overflow: hidden;
}
.as-help[open] { border-color: var(--pri); }
.as-help summary {
  padding: 11px 14px; cursor: pointer; list-style: none;
  display: flex; flex-direction: column; gap: 2px;
}
.as-help summary::-webkit-details-marker { display: none; }
.as-help summary:hover { background: var(--soft); }
.as-help-t { font-size: 13.5px; font-weight: 600; color: var(--tx); }
.as-help-t::before {
  content: '›'; display: inline-block; width: 13px; color: var(--pri);
  transition: transform .15s; transform-origin: center;
}
.as-help[open] .as-help-t::before { transform: rotate(90deg); }
.as-help summary em {
  font-style: normal; font-size: 12px; color: var(--tx3);
  padding-left: 13px; line-height: 1.6;
}
.as-help-b { padding: 2px 16px 14px 30px; }
.as-help-b ol { margin: 6px 0 0; padding-left: 18px; }
.as-help-b ol li {
  font-size: 13px; line-height: 1.85; color: var(--tx); margin-bottom: 3px;
}
.as-help-n {
  margin: 10px 0 0; padding: 9px 12px 9px 26px; border-radius: 8px;
  background: var(--warn-bg); border: 1px solid var(--warn-line);
}
.as-help-n li { font-size: 12.5px; line-height: 1.75; color: var(--warn-tx); }
.as-help-l { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 12px; }

/* 台账的「按件 / 按型号」视图切换：单独一行贴右，不跟筛选控件抢位置 */
.as-modes {
  display: flex; align-items: center; gap: 6px; justify-content: flex-end;
  margin: -2px 0 8px;
}
.as-modes .c-tx3 { font-size: 12px; }

/* 机器监控同步来的 CPU/显卡串很长，名称列限宽截断，别把表格撑坏 */
#v-assets .as-cell-main {
  max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (max-width: 980px) {
  #v-assets .as-cell-main { max-width: 190px; }
}

/* 机位表：CPU / 主板 / 显卡是长串，压窄省略，右侧「已绑 / 编辑」才露得出来 */
#v-assets .as-t td.mach-hw {
  max-width: 175px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ══════════════════════════════════════════════════════════════════
   开关（后台「门店管理」的启用/停用）
   结构：<label class="sw"><input type="checkbox"><i></i></label>
   原生 checkbox 藏起来但仍在 DOM 里 —— 键盘 Tab 和读屏照常可用，
   所以不要换成 <div onclick>。
   ══════════════════════════════════════════════════════════════════ */
.sw {
  position: relative; display: inline-block; width: 36px; height: 20px;
  vertical-align: middle; cursor: pointer;
}
.sw input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer;
}
.sw i {
  position: absolute; inset: 0; display: block;
  background: var(--line); border-radius: 999px;
  transition: background .16s;
}
.sw i::after {
  content: ""; position: absolute; left: 2px; top: 2px;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--elev); box-shadow: 0 1px 2px rgba(20, 22, 31, .22);
  transition: transform .16s;
}
.sw input:checked + i { background: var(--pri); }
.sw input:checked + i::after { transform: translateX(16px); }
.sw input:focus-visible + i { outline: 2px solid var(--pri); outline-offset: 2px; }
.sw input:disabled { cursor: progress; }
.sw input:disabled + i { opacity: .55; }

/* 停用门店整行压暗，扫一眼能分出「在跑的」和「关了的」 */
#t-shops tr.off td { color: var(--tx3); }
#t-shops tr.off td b { color: var(--tx3); font-weight: 500; }
