/* 提成结算系统 —— 简洁、克制、就事论事 */
:root{
  --bg:#f5f6f8; --card:#ffffff; --line:#e3e6ea; --text:#1d2329;
  --muted:#6b7785; --brand:#2f7cf6; --ok:#1a9d63; --warn:#c47f17;
  --danger:#d94a3d; --shadow:0 1px 3px rgba(16,24,40,.06),0 1px 2px rgba(16,24,40,.04);
  /* 中国股市习惯：涨红跌绿；提成系统里「增加」用红、「减少」用绿 */
  --up:#d94a3d; --down:#1a9d63;
}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--text);
  font:14px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI","Microsoft YaHei",sans-serif}
a{color:var(--brand);text-decoration:none}
a:hover{text-decoration:underline}

.topbar{display:flex;align-items:center;gap:24px;padding:0 20px;height:52px;
  background:var(--card);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:10}
.brand{font-weight:600;font-size:15px}
.topbar nav{display:flex;gap:4px;flex:1}
.topbar nav a{padding:6px 12px;border-radius:6px;color:var(--text);font-size:13.5px}
.topbar nav a:hover{background:#eef2f7;text-decoration:none}
.me{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--muted)}
.tag{font-size:11px;padding:1px 6px;border-radius:4px;background:#e8f0fe;color:#1a56c4}
.tag.admin{background:#fdeee8;color:#b2441f}

/* 内容区全宽：不限 max-width，也不要 margin auto 居中（老板嫌两侧空太多） */
.page{margin:0;padding:20px 26px 60px}
h1{font-size:19px;margin:0 0 4px}
h2{font-size:15px;margin:26px 0 10px;color:#2c3540}
.sub{color:var(--muted);font-size:13px;margin:0 0 18px}

.flash{padding:10px 14px;border-radius:8px;margin-bottom:14px;font-size:13.5px}
.flash.ok{background:#e8f7f0;color:#0f6b45;border:1px solid #bfe6d4}
.flash.error{background:#fdeceb;color:#a33327;border:1px solid #f5c9c4}

.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px}
.card{background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:14px 16px;box-shadow:var(--shadow)}
.card .label{font-size:12.5px;color:var(--muted)}
.card .value{font-size:22px;font-weight:600;margin-top:4px;font-variant-numeric:tabular-nums}
.card .unit{font-size:12px;color:var(--muted);font-weight:400;margin-left:3px}
.card.accent{background:#f0f6ff;border-color:#cfe0fb}
.card.accent .value{color:#1a56c4}
.card.muted{background:#fbfbfc}

table{width:100%;border-collapse:separate;border-spacing:0;background:var(--card);
  border:1px solid var(--line);border-radius:10px;overflow:hidden;font-size:13.5px}
th,td{padding:9px 12px;text-align:left;border-bottom:1px solid #eceff3;
  border-right:1px solid #f0f2f5}
th:last-child,td:last-child{border-right:none}
/* 表头：底色深一些、字加粗、列之间有隔断，滚动时固定在顶部
   （老板要求：像他那套系统的表格那样，看着清爽） */
th{background:#e9eef5;font-weight:600;color:#26313d;font-size:12.5px;
  position:sticky;top:0;z-index:6;box-shadow:inset 0 -1px 0 #d8e0ea}
tbody tr:last-child td{border-bottom:none}
tbody tr:hover{background:#fafcff}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}
.mono{font-family:ui-monospace,Consolas,"Courier New",monospace;font-size:12.5px}

.btn{display:inline-block;padding:7px 14px;border-radius:7px;border:1px solid var(--line);
  background:var(--card);color:var(--text);cursor:pointer;font-size:13px}
.btn:hover{background:#f7f9fb;text-decoration:none}
.btn.primary{background:var(--brand);border-color:var(--brand);color:#fff}
.btn.primary:hover{background:#2569d8}
/* ⛔ 2026-10-26 老板：「这个点开登录记录的时候为什么感觉有点乱？数字和名字没有在一行里面」
   根因：按钮里那个数字用的是通用的 `.hint`，而 `.hint` 带着 **`margin-top:6px`**
   （那是给段落间距用的）—— 在 flex 按钮里它把数字往下推了 6px，看着就不在一行。
   ⇒ 按钮里的 `.hint` 一律去掉外边距、跟文字同一条基线；
      选中（蓝底）那档数字要半透明白，不然灰字压在蓝底上看不清。 */
.btn .hint{margin:0 0 0 4px;font-size:11.5px;line-height:1;color:var(--muted);
  display:inline-flex;align-items:center;align-self:center;vertical-align:middle}
.btn.primary .hint{color:rgba(255,255,255,.82)}
.btn.warn{background:#fff7e8;border-color:#f0d9a8;color:#8a5b0a}
.btn.danger{background:#fdeceb;border-color:#f5c9c4;color:#a33327}
.btn:disabled{opacity:.55;cursor:not-allowed}

.pill{display:inline-block;font-size:11.5px;padding:2px 8px;border-radius:20px}
.pill.ok{background:#e8f7f0;color:#0f6b45}
.pill.pending{background:#eef2f7;color:#4a5560}
.pill.locked{background:#fff7e8;color:#8a5b0a}
.pill.settled{background:#e8f0fe;color:#1a56c4}
.pill.returned{background:#fdeceb;color:#a33327}
.pill.completed{background:#e8f7f0;color:#0f6b45}

.toolbar{display:flex;gap:8px;align-items:center;margin-bottom:14px;flex-wrap:wrap}
.toolbar .spacer{flex:1}
input[type=text],input[type=password],select{
  padding:7px 10px;border:1px solid var(--line);border-radius:7px;font-size:13.5px;background:#fff}
.empty{color:var(--muted);text-align:center;padding:40px 0;font-size:13.5px}
.hint{font-size:12.5px;color:var(--muted);margin-top:6px}
.amount-up{color:var(--up)}
.amount-down{color:var(--down)}

/* 登录页 */
.login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;background:#eef1f6}
.login{width:340px;background:var(--card);border:1px solid var(--line);border-radius:12px;
  padding:28px 26px;box-shadow:0 4px 16px rgba(16,24,40,.08)}
.login h1{font-size:17px;margin-bottom:18px;text-align:center}
.login label{display:block;font-size:12.5px;color:var(--muted);margin:12px 0 4px}
.login input,.login select{width:100%}
.login .btn{width:100%;margin-top:18px;padding:9px}
.tabs{display:flex;background:#f2f4f7;border-radius:8px;padding:3px;margin-bottom:6px}
.tabs label{flex:1;text-align:center;padding:6px;margin:0;border-radius:6px;cursor:pointer;
  font-size:13px;color:var(--muted)}
.tabs input{display:none}
.tabs input:checked + span{font-weight:600;color:var(--text)}
.tabs label:has(input:checked){background:#fff;box-shadow:var(--shadow)}

/* 宽表格：订单页要放淘宝原表的全部列，靠横向滚动而不是砍列 */
/* 表格容器：内容多时自己滚动，这样表头 sticky 才有意义 */
.table-wrap{overflow:auto;max-height:calc(100vh - 235px);
  border:1px solid var(--line);border-radius:10px;background:var(--card)}
.table-wrap table{border:none;border-radius:0}
table.wide th,table.wide td{white-space:nowrap;font-size:12.5px;padding:8px 10px}
td.clip{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
td.nowrap,th.nowrap{white-space:nowrap}

/* 分页条：支持直接跳页，不用一页页点 */
.pager{margin-top:14px}
.pager-form{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  background:var(--card);border:1px solid var(--line);border-radius:10px;padding:10px 14px}
.pager-form .spacer{flex:1}
.pager-form label{font-size:13px;color:var(--muted);display:flex;align-items:center;gap:5px}
.page-input{width:72px;padding:5px 8px;border:1px solid var(--line);border-radius:6px;
  text-align:center;font-size:13px}

/* 上传框 */
.upload-box{display:flex;gap:12px;align-items:center;background:var(--card);
  border:1px dashed #c8d0da;border-radius:10px;padding:18px 20px;margin-bottom:8px}
.upload-box input[type=file]{flex:1;font-size:13px}

/* ── 导入块（2026-10-01 老板：两份数据的说明 + 上传框各自成块、**竖着排**）──
   背景：老板说「一开始的时候 我以为 才导入一个呢」—— 因为两份数据的标题、
   说明、上传框、按钮是散在页面上的，看不出是两件独立的事。
   现在每份数据包成一个带框的块：左框=①推广报表、右框=②生意参谋，各自
   标题 + 说明 + 选择文件 + 按钮，一眼看清是「两份、各导各的」。 */
.import-block{background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:16px 20px 18px;margin-bottom:16px;box-shadow:var(--shadow)}
.import-block h2{margin:0 0 6px;font-size:15px}
.import-block .hint{margin:0 0 12px}
/* 同一块里两列并排；窄屏自动收成一列 */
.import-cards{display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:stretch}
@media (max-width:1000px){.import-cards{grid-template-columns:1fr}}
.import-cards .import-block{margin-bottom:0}
.import-block .upload-box{margin-bottom:0}

/* 两栏布局（提成组页：左边组员 / 右边待分配） */
.two-col{display:grid;grid-template-columns:1fr 1fr;gap:22px;align-items:start}
@media (max-width:960px){.two-col{grid-template-columns:1fr}}
.two-col h2{margin-top:0}

/* 进度条（导入用） */
.progress{height:10px;background:#eef1f5;border-radius:6px;overflow:hidden;margin:10px 0}
.progress > i{display:block;height:100%;width:0;background:var(--brand);
  border-radius:6px;transition:width .3s}
.progress-text{font-size:13px;color:var(--muted)}

/* 订单列表里的内联编辑（不点进去就能改） */
.inline-fix{display:flex;gap:4px;align-items:center}
.inline-fix input{padding:4px 6px;font-size:12.5px;border:1px solid var(--line);
  border-radius:5px;background:#fff}
.inline-fix input:focus{border-color:var(--brand);outline:none}
.inline-fix .btn{padding:4px 10px;font-size:12.5px;white-space:nowrap}

/* 列表里「点一下就能改」的单元格：平时看着像普通文本，鼠标移上去才提示可编辑 */
.cell-form{display:inline-block;width:100%}
.cell-input{width:100%;max-width:110px;padding:3px 6px;text-align:right;
  font-size:13.5px;font-variant-numeric:tabular-nums;color:inherit;
  background:transparent;border:1px solid transparent;border-radius:5px;cursor:pointer}
.cell-input:hover{background:#f2f6fd;border-color:#d6e2f7}
.cell-input:focus{background:#fff;border-color:var(--brand);outline:none;cursor:text}
/* 去掉数字输入框的上下箭头，免得看着乱 */
.cell-input::-webkit-outer-spin-button,
.cell-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.cell-input{-moz-appearance:textfield;appearance:textfield}

/* 页脚：显示版本号，方便老板确认自己用的是哪一版 */
.app-foot{margin:8px 0 26px;padding:0 26px;font-size:12.5px;
  color:var(--muted);display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.app-foot .ver{background:#eef2f7;border-radius:4px;padding:1px 7px;font-size:12px;
  color:#42536a;font-family:ui-monospace,Consolas,monospace}
.app-foot .hint{font-size:12px}

/* ── 页面标题栏（左标题 + 右操作）── */
.page-head{display:flex;align-items:flex-start;justify-content:space-between;
  gap:16px;flex-wrap:wrap;margin:0 0 12px}
.page-head h1{margin:0 0 4px}
.page-head .sub{margin:0}
.page-head-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap}

/* ── 全屏表格：撑满窗口可用宽度，不写死尺寸 ── */
.table-full{width:100%}
.table-full table.wide{width:100%}

/* ── 列显示配置菜单 ── */
.col-picker{position:relative}
.col-menu{position:absolute;right:0;top:calc(100% + 6px);z-index:50;background:#fff;
  border:1px solid var(--line);border-radius:8px;padding:10px 12px;min-width:200px;
  max-height:440px;overflow:auto;box-shadow:0 10px 28px rgba(20,40,70,.14)}
.col-menu-head{font-size:12.5px;color:var(--muted);margin-bottom:8px;
  padding-bottom:6px;border-bottom:1px solid var(--line)}
.col-item{display:block;padding:3px 0;font-size:13.5px;cursor:pointer;white-space:nowrap}
.col-item input{margin-right:6px;vertical-align:middle}
.col-menu-foot{margin-top:8px;padding-top:8px;border-top:1px solid var(--line)}

/* ── 人工改动标记：红色小三角，鼠标移上去看谁改的、什么时候 ── */
td{position:relative}
.fix-flag{color:#e03e2d;font-size:11px;margin-left:4px;cursor:help;
  vertical-align:super;line-height:1}
.fix-detail{display:none;position:absolute;left:0;top:100%;z-index:60;
  background:#2b3440;color:#fff;font-size:12px;padding:6px 10px;border-radius:6px;
  white-space:nowrap;max-width:560px;box-shadow:0 6px 18px rgba(0,0,0,.22)}
.fix-flag:hover + .fix-detail{display:block}

/* ── 统计卡片行（奖惩页顶部） ── */
.stat-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
  gap:12px;margin-bottom:20px}
.card.stat{padding:14px 16px;margin:0}
.card.stat .label{font-size:12.5px;color:var(--muted);margin-bottom:6px}
.card.stat .value{font-size:20px;font-weight:600;
  font-variant-numeric:tabular-nums;line-height:1.2}
.card.stat .hint{font-size:12px;margin-top:4px}

/* 金额方向（记账场景，不是股票行情）：
   绿色 = 给员工加钱（奖励），红色 = 从员工那里扣（扣款/退款扣回） */
.amount-up{color:#2f9e5e}
.amount-down{color:#d94a3d}

/* 员工列表里的「每个身份一行」分组选择 */
.role-groups{display:flex;flex-direction:column;gap:4px}
.role-group-row{display:flex;gap:6px;align-items:center;margin:0}
.role-tag{display:inline-block;min-width:104px;font-size:13px;font-weight:500;
  color:#26313d;white-space:nowrap}
.role-group-row select{padding:3px 6px;font-size:12.5px;border:1px solid var(--line);
  border-radius:5px;max-width:150px}
.role-group-row .btn{padding:3px 9px;font-size:12.5px}

/* ══════════════════════════════════════════════════════════════
   左侧菜单布局（2026-09-17 参考老板给的截图改的）
   —— 菜单固定在左边、内容区自适应，表格能撑满整个宽度
   ══════════════════════════════════════════════════════════════ */
body.with-side{display:flex;min-height:100vh;background:#f5f7fa;margin:0}

.side{width:214px;flex:0 0 214px;background:#1f2b3a;color:#c7d2de;
  display:flex;flex-direction:column;position:sticky;top:0;height:100vh;
  font-size:13.5px}
.side-brand{display:flex;align-items:center;gap:10px;padding:18px 16px 14px}
.side-brand .logo{width:32px;height:32px;border-radius:8px;background:#2f7cf6;
  color:#fff;display:grid;place-items:center;font-weight:700;font-size:16px;flex:none}
.side-brand .txt{display:flex;flex-direction:column;line-height:1.3;min-width:0}
.side-brand b{color:#fff;font-size:14.5px;font-weight:600;white-space:nowrap}
.side-brand i{font-style:normal;font-size:11.5px;color:#7b8ea3}

.side-nav{flex:1;padding:6px 8px;overflow-y:auto}
.side-nav a{display:flex;align-items:center;gap:9px;padding:9px 12px;border-radius:7px;
  color:#c7d2de;text-decoration:none;margin-bottom:2px;transition:background .12s}
.side-nav a:hover{background:#2a3849;color:#fff}
.side-nav a.active{background:#2f7cf6;color:#fff}
.side-nav .ico{width:16px;text-align:center;font-size:13px;opacity:.85;flex:none}

.side-user{border-top:1px solid #2e3b4d;padding:12px 16px 14px;font-size:13px}
.side-user .row{display:flex;align-items:center;gap:6px;margin-bottom:9px;flex-wrap:wrap}
.side-user .who{color:#fff;font-weight:500}
.side-user .tag{font-size:11px;padding:1px 6px;border-radius:4px;
  background:#3a4759;color:#a9b8c9}
.side-user .tag.admin{background:#33507a;color:#bcd4f5}
.side-user .logout{color:#8fa3b8;text-decoration:none;font-size:12.5px}
.side-user .logout:hover{color:#fff}

.main{flex:1;min-width:0;display:flex;flex-direction:column}
.main .page{flex:1}

/* ── 登录页：占满整个视口并居中 ──
   注意：登录页不能用带 padding 的 .page（会让 100vh 溢出、把卡片挤歪），
   所以这里把 .main / .page 的约束全部放开，由 .login-wrap 自己居中。 */
body:not(.with-side){background:#eef1f6}
body:not(.with-side) .main{min-height:100vh}
body:not(.with-side) .page{max-width:none;padding:0;margin:0;display:flex;
  align-items:center;justify-content:center;flex:1}
body:not(.with-side) .login-wrap{width:100%;min-height:100vh;display:flex;
  align-items:center;justify-content:center;padding:24px;box-sizing:border-box}
body:not(.with-side) .app-foot{display:none}

/* ── 提成组管理：大类别分区（2026-09-17） ───────────────────────── */
.cat-block{border:1px solid var(--line);border-radius:12px;background:var(--card);
  margin-bottom:16px;overflow:hidden}
.cat-block.pending{border-color:#f0c9a0;background:#fffcf8}
.cat-head{display:flex;align-items:center;gap:10px;padding:11px 16px;
  background:#eaeff6;border-bottom:1px solid var(--line);font-size:13.5px}
.cat-block.pending .cat-head{background:#fbeed9}
.cat-head strong{font-size:14px;font-weight:500}
.cat-head .hint{font-size:12.5px;color:var(--muted)}
.cat-head .spacer{flex:1}
.cat-head .cnt{font-size:12.5px;color:var(--muted)}
.cat-empty{padding:16px;color:var(--muted);font-size:13px}
.cat-block table{width:100%;border-collapse:collapse}
.cat-block th,.cat-block td{padding:9px 14px;text-align:left;
  border-bottom:1px solid #f0f2f5;vertical-align:middle}
.cat-block th{background:#f7f9fc;font-weight:500;font-size:12.5px;color:#4a5560;
  border-bottom:1px solid var(--line)}
.cat-block tbody tr:last-child td{border-bottom:none}
.cat-block tbody tr:hover{background:#fafcff}
.cat-block .ops{white-space:nowrap;display:flex;gap:6px}
.cat-block .ops .btn{padding:3px 9px;font-size:12.5px}

/* 大类别的颜色标识：左边缘一道色条 */
.cat-block.k-designer{border-left:3px solid #378add}
.cat-block.k-service{border-left:3px solid #1d9e75}
.cat-block.k-admin{border-left:3px solid #888780}

/* 弹窗（原生 dialog） */
dialog{border:none;border-radius:12px;padding:0;width:430px;max-width:92vw;
  box-shadow:0 14px 44px rgba(16,24,40,.2);background:var(--card);color:var(--text)}
dialog::backdrop{background:rgba(18,24,34,.34)}
.dlg-head{padding:16px 20px 0;font-size:15px;font-weight:500}
.dlg-sub{padding:6px 20px 0;font-size:12.5px;color:var(--muted);line-height:1.55}
.dlg-body{padding:12px 20px 4px;display:flex;flex-direction:column;gap:4px}
.dlg-body label{font-size:12.5px;color:var(--muted);margin-top:8px}
.dlg-body input,.dlg-body select{width:100%;padding:8px 10px;border:1px solid var(--line);
  border-radius:6px;font-size:13.5px;font-family:inherit;background:#fff;color:var(--text)}
.dlg-body input:focus,.dlg-body select:focus{border-color:var(--brand);outline:none}
.dlg-foot{padding:16px 20px 18px;display:flex;justify-content:flex-end;gap:8px}






/* ── 分成管理页（照老板那套系统做的）2026-09-17 ───────────────── */
.tag{display:inline-block;padding:1px 8px;border-radius:4px;font-size:12px;
  background:#eef2f7;color:#42536a;white-space:nowrap}
.tag.blue{background:#e3effd;color:#1f6fd0}
.tag.warn{background:#fdf0dc;color:#a56b12}
.pager{display:flex;align-items:center;gap:8px;padding:12px 4px;flex-wrap:wrap}
.pager .pager-cur{font-size:13px;color:var(--muted);min-width:64px;text-align:center}
.pager select{width:auto;padding:5px 8px}
.pager .btn{padding:4px 10px;font-size:13px}
.pager .btn[disabled]{opacity:.4;cursor:not-allowed}

dialog.wide{width:960px;max-width:96vw}
.mem-bar{display:flex;align-items:center;gap:8px;padding:12px 20px 6px;flex-wrap:wrap}
.mem-bar select{width:150px;padding:7px 10px;border:1px solid var(--line);
  border-radius:6px;font-size:13.5px;background:#fff}
.mem-bar input{width:220px;padding:7px 10px;border:1px solid var(--line);
  border-radius:6px;font-size:13.5px}
.mem-bar .spacer{flex:1}
.mem-body{padding:6px 20px 0;max-height:52vh;overflow:auto}
.mem-body table{width:100%;border-collapse:collapse}
.mem-body th,.mem-body td{padding:8px 10px;text-align:left;
  border-bottom:1px solid #f0f2f5;font-size:13px}
.mem-body th{background:#f7f9fc;font-weight:500;font-size:12.5px;color:#4a5560;
  position:sticky;top:0;z-index:1}
.mem-body .empty{text-align:center;color:var(--muted);padding:22px 0}

.radio-row{display:flex;gap:18px;padding:6px 0}
.radio-row .radio{display:flex;align-items:center;gap:5px;font-size:13.5px;
  color:var(--text);cursor:pointer}
.radio-row input[type=radio]{width:auto;margin:0}
.input-suffix{display:flex;align-items:center;gap:8px}
.input-suffix input{flex:1}
.input-suffix span{font-size:13px;color:var(--muted)}
.req{color:var(--danger)}

/* 表格操作列的小按钮 */
td.ops{white-space:nowrap}
td.ops .btn{padding:3px 9px;font-size:12.5px;margin:0 4px 0 0}


/* ===========================================================================
   视觉精修 v3（2026-09-17 老板说"太丑了，优化下"）
   —— 用覆盖写法放在最后，前面的规则不动，要回退只需删掉这一段
   =========================================================================== */

/* 1. 配色：整体更清爽，主色更沉稳 */
:root{
  --bg:#f5f7fb;
  --card:#ffffff;
  --line:#e6eaf2;
  --text:#101828;
  --muted:#667085;
  --brand:#2563eb;
  --ok:#059669;
  --warn:#d97706;
  --danger:#dc2626;
  --shadow:0 1px 2px rgba(16,24,40,.04), 0 1px 3px rgba(16,24,40,.06);
  --up:#dc2626;
  --down:#059669;
}
body{font-size:13.5px;-webkit-font-smoothing:antialiased}

/* 2. 标题区 */
.page{padding:22px 28px 60px}
h1{font-size:20px;font-weight:600;letter-spacing:-.2px;color:#101828;margin:0 0 6px}
h2{font-size:15px;font-weight:600;color:#1d2939;margin:28px 0 12px}
.sub{color:var(--muted);font-size:12.5px;line-height:1.75;margin:0 0 18px}
.page-head{display:flex;align-items:flex-start;gap:20px;flex-wrap:wrap;margin-bottom:16px}
.page-head > div:first-child{flex:1;min-width:260px}
/* 面包屑：子页面回主页面用。存在感要低，但不能像普通链接那样被忽略。 */
.crumb{font-size:12.5px;margin:0 0 10px}
.crumb a{color:var(--muted);text-decoration:none}
.crumb a:hover{color:var(--blue,#2f7cf6)}

/* 3. 卡片：极轻的立体感 */
.card{border-radius:12px;border:1px solid var(--line);padding:16px 18px;
  box-shadow:0 1px 2px rgba(16,24,40,.04)}
.card .value{font-size:24px;font-weight:600;letter-spacing:-.3px}
.card .label{font-size:12px;color:var(--muted)}

/* 4. 表格：行更高、表头更淡、加斑马纹和极轻阴影 */
table{border-radius:12px;font-size:13px;box-shadow:0 1px 2px rgba(16,24,40,.04)}
th,td{padding:11px 14px;border-bottom:1px solid #f1f4f9;
  border-right:1px solid #f6f8fc}
th{background:#f8fafc;color:#475467;font-size:12px;font-weight:600;
  letter-spacing:.3px;white-space:nowrap;box-shadow:inset 0 -1px 0 #e9eef6}
tbody tr:nth-child(even){background:#fbfcfe}
tbody tr:hover{background:#f3f7fe}
.table-wrap{border-radius:12px}

/* 5. 按钮：统一高度 + 主次分明 */
.btn{display:inline-flex;align-items:center;justify-content:center;height:34px;
  padding:0 14px;border-radius:8px;border:1px solid #dbe2ec;background:#fff;
  color:#344054;font-size:13px;font-family:inherit;cursor:pointer;line-height:1;
  white-space:nowrap;transition:background .15s,border-color .15s,box-shadow .15s}
.btn:hover{background:#f8fafc;border-color:#c7d2e0;text-decoration:none}
.btn.primary{background:var(--brand);border-color:var(--brand);color:#fff;
  box-shadow:0 1px 2px rgba(37,99,235,.22)}
.btn.primary:hover{background:#1d4ed8;border-color:#1d4ed8}
.btn.danger{background:#fff;border-color:#fbd3d3;color:var(--danger)}
.btn.danger:hover{background:#fef3f2;border-color:#f6b4b4}
.btn.warn{background:#fff;border-color:#f3ddb4;color:#a3610a}
/* ⚠️ 2026-10-07：`.btn` 是 inline-flex → **会压过 HTML 的 `hidden` 属性**
   （UA 样式 `[hidden]{display:none}` 优先级最低，被这里覆盖了）。
   症状：JS 里 `btn.hidden = true` 看着赋值成功了，按钮却还杵在那儿
   （只在 disabled 变淡）。凡是靠 hidden 控显隐的按钮都得兜这一条。 */
.btn[hidden]{display:none !important}
.btn[disabled]{opacity:.45;cursor:not-allowed;box-shadow:none}
td.ops .btn{height:30px;padding:0 11px;font-size:12.5px;margin-right:6px}

/* 6. 输入控件：统一高度 + 柔和聚焦环 */
/* ⚠️ 必须带 `input:not([type])`（2026-10-01 老板报的 bug）：
   属性选择器 `input[type=text]` **只匹配"有 type 且=text"**，
   而 `<input name="x">` 这种**不写 type** 的，浏览器虽按 text 渲染、
   却匹配不到这条规则 → 退回浏览器默认的深色 inset 边框
   （老板原话：「分类和标题这两个输入框为什么和下面的完全不一样？黑色的怪怪的」）。
   `:not([type])` 是**纯增量**：只补上漏掉的那类，不影响任何已有选择器。 */
input[type=text],input[type=password],input[type=number],input:not([type]),select,textarea{
  height:36px;padding:0 12px;border:1px solid #dbe2ec;border-radius:8px;
  font-size:13px;font-family:inherit;background:#fff;color:var(--text);
  transition:border-color .15s,box-shadow .15s}
textarea{height:auto;padding:9px 12px;line-height:1.6}
input:focus,select:focus,textarea:focus{
  outline:none;border-color:var(--brand);box-shadow:0 0 0 3px rgba(37,99,235,.12)}
select{appearance:none;padding-right:30px;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path d='M2 4.5L6 8.5L10 4.5' fill='none' stroke='%23667085' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat:no-repeat;background-position:right 10px center}
.input-suffix input{width:100%}
.toolbar{gap:10px;margin-bottom:16px}

/* 7. 弹窗：更多留白 */
dialog{border-radius:14px;box-shadow:0 24px 60px rgba(16,24,40,.18);width:460px}
dialog::backdrop{background:rgba(16,24,40,.42)}
.dlg-head{padding:22px 26px 0;font-size:16px;font-weight:600;color:#101828}
.dlg-sub{padding:8px 26px 0;font-size:12.5px;color:var(--muted);line-height:1.7}
.dlg-body{padding:12px 26px 2px}
.dlg-body label{display:block;font-size:12.5px;color:#475467;font-weight:500;
  margin-top:14px}
.dlg-body input,.dlg-body select{width:100%;margin-top:6px}
.dlg-foot{padding:18px 26px;gap:10px;margin-top:18px;border-top:1px solid #f1f4f9;
  background:#fcfdfe;border-radius:0 0 14px 14px}

/* 8. 横排表单行（奖惩页那种） */
.form-row{display:flex;gap:14px;align-items:flex-end;flex-wrap:wrap}
.form-row .field{display:flex;flex-direction:column;gap:6px}
.form-row .field > label{font-size:12.5px;color:#475467;font-weight:500}
.form-row .field.grow{flex:1;min-width:200px}
.form-row .field .input-suffix{display:flex;align-items:center;gap:6px}
.form-row .field .input-suffix span{font-size:12.5px;color:var(--muted)}

/* 9. 管理组提示 & 分段隐藏 */
.only-income{display:contents}
.mgmt-tip{margin-top:16px;padding:11px 14px;border-radius:8px;background:#f4f8ff;
  border:1px solid #d6e4fb;color:#1e50a0;font-size:12.5px;line-height:1.7}

/* 10. 标签 */
.tag{border-radius:6px;padding:2px 8px;font-size:11.5px;font-weight:500}
.tag.blue{background:#eaf1fe;color:#1d4ed8}
.tag.warn{background:#fef4e6;color:#a3610a}
.pill{border-radius:999px;font-size:11.5px;padding:2px 9px}

/* 11. 分页 */
.pager{padding:14px 2px}
.pager .btn{height:30px;padding:0 10px;font-size:12.5px}
.pager .pager-cur{font-size:12.5px;color:var(--muted)}

/* 12. 侧边栏 —— 保持原来的深色底。
   ⚠️ 2026-09-17 踩过的坑：曾经把 .side 改成白底，但忘了
   .side-brand b / .side-user .who 本来就是白字、.side-nav a:hover 也是白字，
   于是变成「浅底白字」，菜单和标题全都看不见了。
   **改背景色时必须把所有相关的前景色一起改，不能只改一半。** */
.side-nav a{border-radius:8px;font-size:13px;padding:9px 12px;color:#c7d2de;
  transition:background .15s,color .15s}
.side-nav a:hover{background:#2b3a50;color:#fff;text-decoration:none}
.side-nav a.active{background:#2563eb;color:#fff}
/* 次级菜单项（挂在主菜单下面的子页，比如「参数设置」）：
   缩进 + 弱化图标，让层级看得出来，但别做成折叠——老板要的是点得到。 */
.side-nav a.sub-nav{padding-left:28px;font-size:12.5px;color:#9fb0c4}
.side-nav a.sub-nav .ico{font-size:13px;opacity:.85}

/* 2026-09-30：员工被授了后台栏目时，「管理后台」这一组里再按
   「系统管理 / 订单管理 / 人员绩效 / 宝贝运营」分开显示 ——
   以前是一长串**拍平**的，十几项堆一起、没有栏目名，老板说「看着好乱」。
   ⚠️ 用**不可折叠的小标题**（两层折叠太深、点起来烦），
      下面的链接走现成的 `.sub-nav`（缩进 + 弱化图标）。 */
.side-nav .nav-sub{margin:9px 0 2px;padding:0 12px;font-size:11px;
  letter-spacing:.5px;color:#6b7f96;font-weight:600}

/* ⭐ 2026-10-06：「客服辅助」这类**分组栏目**的三种形状
   （定义见 web/nav.py 顶部 + base.html 的 nav_links 宏）。
   老板原话：「先是一个概览，然后下面就是一个客服的功能界面，
   然后对应的一个管理员的配置界面，对应的出现」。
     · `.nav-grp`  = **功能界面**（客服用）—— 跟普通项一样，点一下就去；
     · `.nav-sub2` = 组内**小标题**（只剩配置项时的兜底，or 再分层）；
     · `.nav-kid`  = **配置界面**（管理员用）—— 缩进挂在功能界面下面。
   ⚠️ 少一个都会让「话术管理」跟「快捷短语」看起来平级，层级看不出来。 */
.side-nav a.nav-grp{padding-left:12px}
.side-nav .nav-sub2{margin:7px 0 2px;padding:0 12px 0 22px;font-size:11px;
  letter-spacing:.5px;color:#7d8fa6;font-weight:600}
.side-nav a.nav-kid{padding-left:30px;font-size:12.5px;color:#9fb0c4}
.side-nav a.nav-kid .ico{font-size:13px;opacity:.85}

/* 13. 登录卡片 */
.login{border-radius:14px;box-shadow:0 12px 36px rgba(16,24,40,.1);width:360px}
.login h1{font-size:18px;text-align:center}


/* ===========================================================================
   视觉精修 v4（2026-09-17 老板给了参考图："严格完全按照这个样式"）
   参考图特征：
     · 表格白底、表头是浅灰小字（不是灰底）、无竖线、无斑马纹
     · 行高紧凑、信息密度高、横向滚动条是细灰圆角
     · 筛选区是一块白底卡片
   =========================================================================== */

/* 1. 表格：白底 + 浅灰表头文字 + 只有淡横线 */
.table-wrap{border:none;background:#fff;border-radius:8px;
  box-shadow:0 1px 2px rgba(16,24,40,.05);
  max-height:calc(100vh - 240px)}
table{border:none;border-radius:0;box-shadow:none;background:#fff;font-size:12.5px}
th,td{padding:10px 12px;border-bottom:1px solid #f0f3f7;border-right:none;
  white-space:nowrap;vertical-align:middle}
th{background:#fff;color:#8a94a6;font-size:12px;font-weight:400;letter-spacing:0;
  border-bottom:1px solid #e8ecf2;box-shadow:none;
  position:sticky;top:0;z-index:6;white-space:nowrap !important}
tbody tr{background:#fff}
tbody tr:nth-child(even){background:#fff}
tbody tr:hover{background:#f8fafc}
tbody tr:last-child td{border-bottom:none}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}

/* 2. 细一点的滚动条 */
.table-wrap::-webkit-scrollbar{width:10px;height:10px}
.table-wrap::-webkit-scrollbar-track{background:#f7f9fb;border-radius:5px}
.table-wrap::-webkit-scrollbar-thumb{background:#d5dbe4;border-radius:5px;
  border:2px solid #f7f9fb}
.table-wrap::-webkit-scrollbar-thumb:hover{background:#bfc7d4}

/* 3. 筛选区：白底卡片 */
.filter-bar{background:#fff;border:1px solid var(--line);border-radius:8px;
  padding:14px 16px;margin-bottom:14px;gap:10px}
.filter-bar input[type=text],.filter-bar select{background:#fff}

/* 4. 开关样式的按钮（参考图顶部那种圆形开关） */
.switch{display:inline-flex;align-items:center;gap:8px;font-size:12.5px;
  color:#475467;cursor:pointer;user-select:none}
.switch input{display:none}
.switch .track{width:34px;height:18px;border-radius:9px;background:#d0d5dd;
  position:relative;transition:background .18s;flex:none}
.switch .track::after{content:"";position:absolute;top:2px;left:2px;
  width:14px;height:14px;border-radius:50%;background:#fff;
  transition:transform .18s;box-shadow:0 1px 2px rgba(16,24,40,.2)}
.switch input:checked + .track{background:var(--brand)}
.switch input:checked + .track::after{transform:translateX(16px)}


/* ===========================================================================
   视觉精修 v5（2026-09-17 老板纠正）
   ⚠️ v4 我看错了参考图：以为要去掉竖线、表头改白底。
      实际上参考图是**经典网格表格** —— 表头浅灰底（深色字）、
      每列之间有竖线、每行之间有横线，四边带外框。
   =========================================================================== */

/* 表格：经典网格 */
.table-wrap{border:1px solid #e7eaf0;background:#fff;border-radius:6px;
  box-shadow:none;max-height:calc(100vh - 240px)}
table{border:none;border-radius:0;box-shadow:none;background:#fff;font-size:12.5px}
th,td{padding:9px 12px;border-bottom:1px solid #e7eaf0;
  border-right:1px solid #e7eaf0;white-space:nowrap;vertical-align:middle;
  text-align:left}
th:last-child,td:last-child{border-right:none}
th{background:#f2f4f7;color:#344054;font-size:12.5px;font-weight:600;
  letter-spacing:0;box-shadow:none;position:sticky;top:0;z-index:6;
  border-bottom:1px solid #e0e4ec}
tbody tr{background:#fff}
tbody tr:nth-child(even){background:#fff}
tbody tr:hover{background:#f7f9fc}
tbody tr:last-child td{border-bottom:none}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}

/* 序号列：蓝色 + 方括号（参考图里的【1】【2】） */
tbody td.seq{color:#2563eb;font-weight:500;text-align:left;width:64px}
tbody td.seq::before{content:"【"}
tbody td.seq::after{content:"】"}

/* 第一列如果是链接（订单号 / 用户名），用蓝色 */
tbody td a{color:#2563eb}


/* ===========================================================================
   视觉精修 v6（2026-09-17 老板："你做的表格比我给你的那个高了很多"）
   —— 用无头浏览器实测改前：
        分成管理行高 49px、订单管理 53px、表头 39px，明显比参考图高。
        原因：① 单元格上下各 9px 内边距；
              ② 操作列按钮 30px 高；
              ③ 订单页格子里的输入框被全局 height:36px 撑到 36px。
      目标：控件行 ≈ 34px、纯文本行 ≈ 30px、表头 ≈ 32px。
   =========================================================================== */

/* 1. 单元格内边距收紧，字号降到 12px */
th,td{padding:6px 10px;line-height:1.45}
table{font-size:12px}
th{padding:7px 10px;font-size:12px}
table thead th{line-height:1.3}

/* 2. 表格里的输入框：压到 24px，别再被全局 36px 撑高 */
td input[type=text],td input[type=number],td input[type=password],td select{
  height:24px;padding:0 6px;font-size:12px;border-radius:5px}
.cell-input{height:24px;padding:0 6px;font-size:12px;max-width:92px;
  line-height:22px;vertical-align:middle}

/* 3. 表格里的按钮：统一 24px（原来 30 / 34px 把行撑开了） */
td .btn,td button,td.ops .btn{height:24px;min-height:24px;padding:0 9px;
  font-size:12px;border-radius:5px;margin:0 4px 0 0;line-height:22px;
  vertical-align:middle}
td.ops{line-height:1}
table .pill{font-size:11px;padding:1px 7px;line-height:1.5}

/* 4. 弹窗里的成员表格也一起压 */
.mem-body th,.mem-body td{padding:6px 10px;font-size:12px}
.mem-body th{font-size:11.5px}
.mem-body .btn{padding:0 8px;height:22px;font-size:11.5px}

/* 5. 分页条紧凑一点 */
.pager{padding:9px 4px}

/* 6. 可编辑格子（里面有输入框）：去掉行盒基线留白，行高才能压到 34px */
td.cell-edit{line-height:1;padding-top:5px;padding-bottom:5px}
td.cell-edit .cell-input{display:block;margin-left:auto}

/* 7. ⚠️ 关键：老规则 `table.wide th,table.wide td`（第 105 行）优先级更高，
      一直在把订单管理页的单元格撑成 padding:8px / 12.5px 字号。
      这里必须用同样具体的选择器压回去，否则上面所有收紧都不生效。 */
table.wide th,table.wide td{padding:6px 10px;font-size:12px;line-height:1.45}
table.wide thead th{padding:7px 10px;font-size:12px;line-height:1.3}

/* 8. 表格里成对出现的 inline-block（标签 / 链接）不要撑高行盒 */
table td a,table td .pill,table td span{vertical-align:middle}


/* ===========================================================================
   视觉精修 v7（2026-09-17 老板三条反馈）
   ① 数字格子平时别显示输入框边框，点进去改的时候才显示
      —— 被 v3 的 `input[type=number]{border:1px solid #dbe2ec}` 盖住了，
         原来的 `.cell-input` 本来就是"透明边框、看着像文本"的设计。
   ② 人工改过的红三角标记不要撑大格子
      —— 三角是脚本动态插进格子的 inline 元素，参与行盒布局 → 把格子顶高。
         改成绝对定位，不占位置。
   ③ 表头字号要比数据行稍大、加粗
      —— 原来表头和数据行都是 12px，表头又用了偏浅的灰，显得比正文还小。
   =========================================================================== */

/* ① 可编辑格子：平时就是普通数字，鼠标移上去才暗示可点 */
td .cell-input,
td.cell-edit .cell-input{
  border:1px solid transparent;background:transparent;box-shadow:none;
  padding:0 6px;color:inherit}
td .cell-input:hover{background:#f2f6fd;border-color:#d6e2f7}
td .cell-input:focus{background:#fff;border-color:var(--brand);
  box-shadow:0 0 0 2px rgba(37,99,235,.12);outline:none}

/* ② 人工改动的红三角：不撑高行 */
td .fix-flag{vertical-align:baseline;font-size:9px;line-height:1;margin-left:3px}
td.cell-edit{position:relative}
td.cell-edit .fix-flag{position:absolute;left:3px;top:50%;
  transform:translateY(-50%);margin:0;padding:0;cursor:help}

/* ③ 表头：比数据行稍大一号 + 加粗 + 颜色加深 */
table thead th,table.wide thead th{
  font-size:13px;font-weight:700;color:#1d2939;padding:8px 10px}


/* ===========================================================================
   视觉精修 v8（2026-09-17 老板三条反馈）
   ① 表头没钉住 —— 往下翻的时候表头跟着滚走了
   ② 数据偏了，要居中
   ③ 表头也要居中，颜色淡一点
   =========================================================================== */

/* ① 表头钉不住的真凶：第 46 行 `table{...overflow:hidden}`。
      它是早先给表格做圆角用的（圆角要靠 overflow 裁），但圆角早就改由
      外层 `.table-wrap` 负责了，这条留着只会坏事 ——
      它让 table 成为 sticky 的裁剪边界，表头只能在 table 内部活动，
      而 table 本身不滚动 → 等于钉不住。
      改成 visible 后，sticky 才会相对 `.table-wrap`（真正的滚动容器）生效。 */
table{overflow:visible}

/* 容器高度要"卡"得刚好，页面本身别产生滚动，否则表头还是会跟着整页走。
   这一版把高度按「页头 + 筛选栏 + 分页条 + 底部留白」重新算过。 */
.table-wrap{max-height:calc(100vh - 285px)}
body.with-side .page{padding-bottom:28px}

/* ② 表格数据居中（老板要求） */
table th,table td{text-align:center}
table.wide th,table.wide td{text-align:center}
td.num,th.num{text-align:center;font-variant-numeric:tabular-nums}
td.mono,th.mono{text-align:center}
td.seq{text-align:center}
td .cell-input,td.cell-edit .cell-input{text-align:center}
td.clip{text-align:center}
/* 备注这种长文本居中会很难看，保持左对齐 */
td[data-col="note"],td[data-col="item_title"]{text-align:left}

/* ③ 表头：居中 + 颜色淡一点（原来 #1d2939 太深） */
table thead th,table.wide thead th{
  text-align:center;color:#5b6b7f;font-weight:700;font-size:13px}


/* ===========================================================================
   视觉精修 v9（2026-09-17）让表头真正钉住
   —— v8 把 table 的 overflow 去掉后，表头位置仍然不对（跑到视口顶部、
      被容器裁掉）。根子是：多个滚动容器套在一起时，sticky 的参照很不可靠。

   换成最稳的经典布局：
     整个窗口不滚 → 只剩「内容区」一个滚动容器 → 表头相对它 sticky。
   这样无论怎么滚，表头都钉在内容区顶部。
   =========================================================================== */

body.with-side{height:100vh;overflow:hidden}
body.with-side .main{height:100vh;min-height:0;overflow:hidden}
/* 内容区：唯一滚动容器（纵向 + 横向都交给它） */
body.with-side .page{flex:1;min-height:0;overflow:auto;padding-bottom:24px}
/* 表格容器不再裁剪，让滚动统一由 .page 负责 */
body.with-side .table-wrap{max-height:none;overflow:visible}

/* 2026-09-30 老板实拍：「后面这边错乱了」——
   用户管理是 **15 列**的宽表（列宽合计约 1886px）。桌面端上面那条把
   `.table-wrap` 设成 `overflow:visible`（为了表头 sticky），于是**中等宽度的
   屏幕（约 1000~1900px）** 上，表格被硬压进容器：`white-space:nowrap` 的格子
   互相压住、列看着对不上。
   ⭐ 给它一个最小宽度：宁可让 `.page`（唯一滚动容器）横向滚动，也不把列压扁。
   ⚠️ 只有 `.staff-table` 用得上这条，别的表不受影响。
   ⭐ 2026-10-06：1886 → 1924（「组织归属」列 158 → 196，留着带队名单的宽度）*/
body.with-side table.staff-table{min-width:1924px}
/* ⛔ 2026-10-26 老板连报三次「还是透出来」——
   根因是**表格没锁列宽**：`table-layout:auto` 下 `<th width=40>` 只是个建议值，
   浏览器按内容算出 41 或 39，而冻结区的 `left` 是按 th 宽度累加的 ⇒ **累计误差**，
   最后那几 px 就露出后面的列。
   ⇒ 锁成 `fixed`，列宽严格按 th 分配，JS 累加才和实际一致。 */
.staff-table{table-layout:fixed}
/* 表头必须有不透明底色，否则下面的数据会透上来 */
body.with-side thead th{background:#f2f4f7;position:sticky;top:0;z-index:6}
body.with-side .app-foot{padding:8px 26px 14px;margin:0}


/* ===========================================================================
   视觉精修 v10（2026-09-17 老板两条反馈）
   ① 表格上方冒出一截滚过去的数据行
      —— 内容区 `.page` 原来有 22px 的「上内边距」，表头钉住的位置
         （top:0）在某些浏览器内核下按「内容区」算而不是「内边距框」算，
         于是这 22px 里会露出滚过去的数据行。
         改成：上内边距归零，改用内容流里的占位块做留白 —— 无论哪种算法都不会露。
   ② 表头再加高一些
   =========================================================================== */

body.with-side .page{padding-top:0}
body.with-side .page::before{content:"";display:block;height:18px}

/* 表头再高一点（老板要求）—— 但字号保持 13px，
   老板 2026-09-17 补充："这个标题文字不要变大"（要的是行高，不是字大） */
table thead th,table.wide thead th{padding:12px 10px;font-size:13px}

/* 用户状态开关：在表格里窄一点、文字小一号 */
.mem-body .switch{font-size:12px;gap:6px}
.mem-body .switch .track{width:32px;height:17px;border-radius:9px}
.mem-body .switch .track::after{width:13px;height:13px;top:2px;left:2px}
.mem-body .switch input:checked + .track::after{transform:translateX(15px)}
.mem-body .switch .txt{color:#475467;min-width:40px;text-align:left}

/* 表头钉住时要挡住下面的数据（不透明底 + 一道分隔线） */
body.with-side thead th{background:#f2f4f7;
  border-bottom:1px solid #d7dee8;box-shadow:0 2px 4px rgba(16,24,40,.04)}


/* ===========================================================================
   视觉精修 v11（2026-09-20）设计师排行页
   老板要「统计设计师接单情况，帮客服找优秀的设计师」。
   =========================================================================== */

/* 名次：前三名金银铜，其他是普通灰色数字 */
.medal{display:inline-flex;align-items:center;justify-content:center;
  width:22px;height:22px;border-radius:50%;font-size:12px;font-weight:700;
  color:#fff}
.medal.m1{background:linear-gradient(160deg,#f7c948,#e0a400);
  box-shadow:0 1px 3px rgba(224,164,0,.45)}
.medal.m2{background:linear-gradient(160deg,#c9d2dc,#98a5b3);
  box-shadow:0 1px 3px rgba(152,165,179,.45)}
.medal.m3{background:linear-gradient(160deg,#e0a878,#bf8447);
  box-shadow:0 1px 3px rgba(191,132,71,.45)}
.rank-no{color:#98a2b3;font-variant-numeric:tabular-nums}

/* 综合分：分档上色，一眼看出高低 */
.score{display:inline-block;min-width:44px;padding:1px 8px;border-radius:6px;
  font-weight:700;font-variant-numeric:tabular-nums;font-size:13px}
.score.s4{background:#e6f4ea;color:#137a45}
.score.s3{background:#e8f0fe;color:#1a56c4}
.score.s2{background:#f4f6f9;color:#667085}
.score.s1{background:#f7f8fa;color:#98a2b3}

/* 表头里可点排序的链接 */
thead th a{color:inherit;text-decoration:none;border-bottom:1px dashed #cbd5e1}
thead th a:hover{color:var(--brand);border-bottom-color:var(--brand);
  text-decoration:none}
.caret{font-size:9px;color:var(--brand);margin-left:2px}

/* 折叠的算法说明 */
.explain{background:#fff;border:1px solid #e7eaf0;border-radius:8px;
  padding:12px 18px;font-size:13px;color:#475467}
.explain summary{cursor:pointer;font-weight:600;color:#344054;font-size:13.5px}
.explain summary::marker{color:var(--brand)}
.explain-body{margin-top:12px;line-height:1.9}
.explain-body table{margin:10px 0}
.explain-body td{padding:6px 12px 6px 0;text-align:left;border:none;
  vertical-align:top;white-space:normal}
.explain-body td:first-child{width:110px;color:#667085;white-space:nowrap}
.explain-body p{margin:8px 0}

/* 概览卡片里的单位字 */
.card.stat .value .unit{font-size:12.5px;font-weight:400;color:var(--muted);
  margin-left:3px}

/* 提示条（浅蓝底） */
.notice{background:#f0f6ff;border:1px solid #d3e2fb;border-left:3px solid var(--brand);
  border-radius:6px;padding:10px 14px;margin-bottom:14px;font-size:13px;
  color:#24405f;line-height:1.9}
.notice strong{color:#123a6b}

/* ===========================================================================
   视觉精修 v12（2026-09-20）设计师排行：单量趋势 / 活跃 / 常合作客服
   老板问「还有什么其他方式统计设计师数据」，从候选里选了三项。
   =========================================================================== */

/* 单量趋势：近 30 天 vs 前 30 天。差 3 单以内算持平，免得噪声看起来像涨跌 */
.trend{font-size:12.5px;font-weight:600;font-variant-numeric:tabular-nums}
.trend.up{color:#15803d}
.trend.down{color:#c2410c}
.trend.flat{color:#98a2b3;font-weight:400}

/* 封顶角标：到手价超出上限被截断的单数，挂在设计师名字后面 */
.cap-flag{display:inline-block;margin-left:5px;padding:0 5px;border-radius:4px;
  background:#fef3c7;color:#92400e;font-size:11px;font-weight:600;
  border:1px solid #fde68a;cursor:help;vertical-align:1px;white-space:nowrap}
/* ⭐ 2026-11-02 老板定的两个标签：
   「超本金」= 备注/显示的到手金额 超过客户付款金额（更严重，红）
   「超比例」= 到手金额 超过这个岗位正常的提成比例（黄） */
.cap-flag.over-paid{background:#fee2e2;color:#b42318;border-color:#fecaca}

/* 常合作客服 */
.cs-partner{font-size:12.5px;color:#475467;white-space:nowrap}
.cs-partner b{color:#344054;font-weight:600}

/* ===========================================================================
   视觉精修 v13（2026-09-20）派单：接单大厅 / 建派单 / 派单详情
   客服端将来要挂在企业微信侧边栏里（窄，约 400px），所以这些卡片
   一律**窄屏优先**：不写死宽度、该换行就换行，电脑上摆宽了也不会散。
   =========================================================================== */

.dispatch-bar{display:flex;align-items:center;gap:10px;margin-bottom:14px;flex-wrap:wrap}

.d-card{background:#fff;border:1px solid #e7eaf0;border-radius:10px;
  padding:14px 16px;margin-bottom:12px;max-width:760px}
.d-card-top{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.d-amount{font-size:19px;font-weight:700;color:#c2410c;font-variant-numeric:tabular-nums}
.d-amount i{font-size:12px;font-weight:400;color:var(--muted);font-style:normal;margin-left:2px}
.d-st{margin-left:auto;font-size:12px;padding:1px 8px;border-radius:10px;white-space:nowrap}
.d-st-open{background:#e8f0fe;color:#1a56c4}
.d-st-chosen{background:#fef3c7;color:#92400e}
.d-st-grouped{background:#e6f4ea;color:#137a45}
.d-st-deal{background:#d1fae5;color:#065f46}
.d-st-closed{background:#f4f6f9;color:#667085}

.d-content{margin:9px 0;font-size:13.5px;color:#344054;line-height:1.75;
  white-space:pre-wrap;word-break:break-word}
.d-meta{font-size:12.5px;color:#667085}
.d-mine{color:#1a56c4}
.d-actions{display:flex;gap:8px;align-items:center;margin-top:11px;flex-wrap:wrap}
.d-actions form{margin:0}

.d-panel{background:#fff;border:1px solid #e7eaf0;border-radius:10px;
  padding:14px 16px;margin-bottom:12px;max-width:760px}
.d-label{font-size:12px;color:#98a2b3;margin-bottom:6px}
.d-label b{color:#344054;font-size:14px}

.d-signup{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:9px 0;border-bottom:1px solid #f2f4f7;flex-wrap:wrap}
.d-signup:last-child{border-bottom:none}
.d-signup-l{min-width:0}
.d-picked{display:inline-block;margin-left:6px;padding:0 7px;border-radius:4px;
  background:#d1fae5;color:#065f46;font-size:11px;font-weight:600;vertical-align:1px}

.d-copy{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.d-copy code{background:#f7f8fa;border:1px solid #e7eaf0;border-radius:6px;
  padding:7px 10px;font-size:13px;color:#344054;word-break:break-all;flex:1;min-width:0}
.d-secret{background:#fff9f0;border:1px dashed #f0c98a;border-radius:8px;
  padding:10px 12px;margin-top:10px}
.d-note{background:#f7f8fa;border-radius:6px;padding:9px 12px;font-size:12.5px;
  color:#667085;margin-bottom:14px}
.d-empty{text-align:center;color:#98a2b3;padding:26px 0;font-size:13px}

.d-form{background:#fff;border:1px solid #e7eaf0;border-radius:10px;
  padding:16px;max-width:560px}
.d-form label{display:block;font-size:13px;color:#344054;margin-bottom:14px}
.d-form label i{color:#e24b4a;font-style:normal}
.d-form input,.d-form select,.d-form textarea{width:100%;margin-top:6px;
  padding:9px 11px;border:1px solid #d0d5dd;border-radius:7px;font-size:13.5px;
  font-family:inherit;color:#101828;background:#fff}
.d-form input:focus,.d-form select:focus,.d-form textarea:focus{
  outline:none;border-color:var(--brand);box-shadow:0 0 0 3px rgba(37,99,235,.1)}
.d-form textarea{resize:vertical;line-height:1.6}
.d-form .hint{display:block;margin-top:5px;font-size:12px}
.d-form-foot{display:flex;gap:10px;justify-content:flex-end;padding-top:4px}

@media (max-width:520px){
  .d-card,.d-panel,.d-form{max-width:100%}
  .d-amount{font-size:17px}
  .d-actions .btn{flex:1;text-align:center}
}

/* ===========================================================================
   视觉精修 v14（2026-09-20）窄屏：把左侧菜单收起来
   派单要挂在企业微信侧边栏里（约 400px 宽），那儿**没有空间摆菜单** ——
   内容占满宽度，手机端打开也顺带受益。
   ⚠️ 2026-09-23 改过：原来这里是 `.side{display:none !important}` ——
      手机上**把菜单整个藏掉，等于没有导航**（老板在手机上打开后没法点别的栏目）。
      现在菜单改成"抽屉"，见文件末尾「手机端适配 v1.17.9」段。⛔ 别再写回 display:none。
   =========================================================================== */
@media (max-width:560px){
  html,body{overflow-x:hidden}
  .main{margin-left:0 !important;width:100% !important;max-width:100vw}
  .page{padding-left:12px;padding-right:12px;box-sizing:border-box;overflow-x:hidden}
  .page-head{display:block}
  .page-head > div:first-child{flex:none;min-width:0}
  .page-head h1{font-size:18px}
  .stat-row{grid-template-columns:1fr 1fr}
  .d-st{margin-left:0}
  .app-foot{flex-wrap:wrap}
  .app-foot .hint{display:none}
}


/* ===========================================================================
   宝贝推广评估 v1（2026-09-21）
   和绩效系统其它页共用 .toolbar/.cards/.card/.pill/.flash/.hint 等基础件，
   这里只补推广页专属的几块。
   =========================================================================== */

/* 主表：列多，给个横向滚动容器，别把单元格挤成两行 */
.table-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;
  border:1px solid var(--line);border-radius:10px;background:var(--card)}
.promo-table{min-width:1500px;margin:0;border:none}
.promo-table th,.promo-table td{white-space:nowrap;vertical-align:top;
  padding:6px 10px;font-size:13px}
/* ⚠️ min-width 必须有：主图/ID/店铺/团队 都是 nowrap，会把可换行的名称列压成竖排 */
.promo-table td.promo-name{white-space:normal;min-width:170px;max-width:220px}
/* ⚠️ 这列是整张表"最高"的元凶（2026-09-30 实测）：窄格子会把解释文字挤成 5~6 行，
   一个格子就把整行 17 个格子一起顶起来。放宽到 620px 让文字横向铺开 → 全表矮 15%。
   再想矮就得改交互（默认折一行、点开看全），那属于功能改动，不在这里做。 */
.promo-table td.promo-why-cell{white-space:normal;min-width:430px;max-width:620px}
.promo-table tbody tr:hover{background:#fafbfc}
/* 第 1 列主图（2026-09-30）：44 → 34px，这页表本来就高，图片别抢行高 */
.promo-table td.promo-thumb{padding-left:10px;padding-right:6px}
.promo-table .item-thumb{width:34px;height:34px;border-radius:4px}

/* 「为什么给这个建议」 */
.promo-why-cell .reason{font-size:12.5px;color:#344054;line-height:1.45}
.promo-why-cell .why{margin:3px 0 0;padding-left:15px;font-size:12px;
  color:#667085;line-height:1.5}
.promo-why-cell .why li{margin-bottom:0}
.promo-reason{margin-top:8px;padding:8px 10px;background:#f8fafc;
  border-left:3px solid var(--brand);border-radius:0 6px 6px 0}

/* 独立使用的理由列表（单品详情页用） */
ul.why{margin:8px 0 0;padding-left:20px;font-size:13px;color:#475467;line-height:1.8}
ul.why li{margin-bottom:2px}

/* 设置页 / 导入页的表单 */
.settings-form{background:var(--card);border:1px solid var(--line);
  border-radius:10px;padding:18px 20px;max-width:640px;box-shadow:var(--shadow)}
.settings-form label{display:block;font-size:13px;color:#344054;margin-bottom:16px}
.settings-form label span{display:block;margin-bottom:6px;font-weight:600}
.settings-form input,.settings-form select{width:100%;margin-top:2px;padding:9px 11px;
  border:1px solid #d0d5dd;border-radius:7px;font-size:13.5px;font-family:inherit;
  color:#101828;background:#fff;box-sizing:border-box}
.settings-form input:focus,.settings-form select:focus{outline:none;
  border-color:var(--brand);box-shadow:0 0 0 3px rgba(47,124,246,.1)}
.settings-form .hint{display:block;margin-top:5px;font-size:12px;color:var(--muted)}
.settings-form .form-foot{display:flex;gap:10px;justify-content:flex-end;padding-top:4px}

/* 单价/进度条之类的轻量盒子 */
.progress-box{background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:14px 16px;margin-bottom:14px}
.progress-box .bar{height:6px;background:#eef1f5;border-radius:999px;overflow:hidden;margin-top:8px}
.progress-box .bar > i{display:block;height:100%;background:var(--brand);border-radius:999px;
  transition:width .3s ease}

/* 行内代码（算账口径里用了 <code>） */
code{background:#f2f4f7;border:1px solid #e4e7ec;border-radius:4px;
  padding:1px 5px;font-size:12.5px;font-family:ui-monospace,Consolas,monospace;color:#344054}

/* 窄屏：表格靠 .table-scroll 横向滚动，内容一律不隐藏 */
@media (max-width:900px){
  .promo-table th,.promo-table td{padding:9px 10px;font-size:12.5px}
}


/* ══════════════════════════════════════════════════════════════════
   视觉精修 v1.17.2 · 表格列宽可拖（老板：有些列空的很多，想拉长缩小）
   回退办法：删掉本段即可（table_resize.js 也要一起去掉）
   ══════════════════════════════════════════════════════════════════ */

/* 拖过列宽的表改成固定布局 —— 不这样，浏览器会把宽度又"平均分配"回去 */
table.col-resize{table-layout:fixed}
/* 拖窄了别让字压到隔壁格子上（默认宽度就是原来的宽度，所以不拖不会截断） */
table.col-resize th,table.col-resize td{overflow:hidden;text-overflow:ellipsis}

/* 表头右边缘那根拖拽条。
   ⚠️ th 是 position:sticky，它本身就是"定位祖先"，所以拖拽条用 absolute 就好，
      ⛔ 千万别给 th 加 position:relative —— 会把 sticky 表头干掉。 */
.col-h{position:absolute;top:0;right:0;width:6px;height:100%;
  cursor:col-resize;z-index:4;touch-action:none}
.col-h::after{content:"";position:absolute;left:2px;top:5px;bottom:5px;width:2px;
  border-radius:2px;background:transparent;transition:background .12s ease}
.col-h:hover::after{background:#c3cddd}
.col-h.dragging::after{background:var(--brand,#2563eb)}
/* 正在拖的时候，整页都是左右拉伸指针，且不许选中文字 */
body.col-dragging{cursor:col-resize!important;user-select:none!important}
body.col-dragging *{user-select:none!important}


/* ===========================================================================
   视觉精修 v1.17.7 —— 设计师排行改卡片式
   老板 2026-09-23：「改成一块一块的形式，不要一行的那种，我要适配到企微侧边栏」
   ⚠️ 卡片必须能在 ~360px 宽的企微侧边栏里正常显示，所以：
      · 网格用 auto-fill + minmax —— 宽屏自动多列、窄屏自动一列，不用媒体查询硬切
      · 卡片内部一律 flex/grid 分配，不写死宽度
   =========================================================================== */
.dc-grid{
  display:grid;gap:12px;
  /* ⚠️ 必须用 min(330px,100%)：窗口比 330px 还窄时（企微侧边栏 360~400px）
     minmax(330px,1fr) 会直接撑破容器，右边内容被切掉 —— 踩过。 */
  grid-template-columns:repeat(auto-fill,minmax(min(330px,100%),1fr));
}
.dc-card{
  /* ⚠️ min-width:0 是必须的：栅格子项默认 min-width:auto，
     会被内部 nowrap 的内容（比如「近30天 · 近7天 0」）撑宽 → 整页横向溢出。 */
  min-width:0;
  container-type:inline-size;   /* 让下面的 @container 能按「卡片自己有多宽」判断 */
  background:#fff;border:1px solid var(--line);border-radius:10px;
  padding:12px 14px;display:flex;flex-direction:column;gap:10px;
  transition:box-shadow .15s,border-color .15s;
}
/* ⭐ 按容器宽度（不是视口宽度）判断：卡片自己被挤窄了就变 2 列。
   这样挂进企微侧边栏（~360px）时不用管视口，卡片自己会适配。 */
@container (max-width:350px){
  .dc-nums{grid-template-columns:repeat(2,1fr);row-gap:10px}
}
.dc-card:hover{border-color:#c9d4e4;box-shadow:0 2px 10px rgba(16,24,40,.06)}
.dc-card.dc-top{border-left:3px solid var(--brand)}

/* 头：名次 + 名字 + 综合分 */
.dc-head{display:flex;align-items:flex-start;gap:10px}
.dc-rank{
  flex:none;width:26px;height:26px;border-radius:7px;background:#eef2f7;color:#5a6572;
  font-size:13px;font-weight:700;display:flex;align-items:center;justify-content:center;
  font-variant-numeric:tabular-nums;
}
.dc-rank.m1{background:#fff2cc;color:#a06a00}
.dc-rank.m2{background:#eef1f5;color:#5c6570}
.dc-rank.m3{background:#f7e9dd;color:#9a5f2a}
.dc-who{flex:1;min-width:0}
.dc-name{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.dc-name strong{font-size:14.5px;color:#1d2836}
.dc-sub{font-size:12px;color:#7a8698;margin-top:3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dc-sub b{color:#4a5560;font-weight:600}
.dc-score{flex:none;text-align:center;line-height:1.15}
.dc-score b{display:block;font-size:19px;font-weight:700}
.dc-score span{font-size:11px;color:#98a2b3}

/* 中间四个数字 */
.dc-nums{
  display:grid;grid-template-columns:repeat(4,1fr);gap:6px;
  background:#f8fafc;border-radius:8px;padding:8px 4px;
}
.dc-n{text-align:center;min-width:0}
.dc-n b{display:block;font-size:16px;font-weight:700;color:#1d2836;
  font-variant-numeric:tabular-nums;line-height:1.25}
.dc-n span{font-size:11px;color:#8a94a6;display:block;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dc-n.dc-warn b,.dc-n.dc-warn span{color:#c9372c}

/* 底部：金额 + 趋势 + 按钮 */
.dc-foot{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.dc-amt{font-size:14px;font-weight:700;color:#1d2836;font-variant-numeric:tabular-nums}
.dc-avg{font-size:11.5px;color:#98a2b3}
.dc-foot .spacer{flex:1}
.dc-foot .btn{height:30px;padding:0 12px;font-size:12.5px}

/* 空状态 */
.empty-box{
  background:#fff;border:1px solid var(--line);border-radius:10px;
  padding:40px 20px;text-align:center;color:#8a94a6;font-size:13.5px;
}

/* 窄屏（企微侧边栏）：一列铺满 + 数字略小 */
@media (max-width:560px){
  .dc-grid{grid-template-columns:minmax(0,1fr);gap:10px}
  .dc-card{padding:11px 12px}
  .dc-n b{font-size:15px}
  .dc-score b{font-size:17px}
}
/* 很窄（<380px）：四个数字挤成两行 */
@media (max-width:380px){
  .dc-nums{grid-template-columns:repeat(2,1fr);row-gap:10px}
}

/* ==========================================================================
   设计师卡片改版 —— 名字下挂状态 + 近1个月/近3个月 两套接单情况（2026-10-02）
   老板：「把 最近接单 和 会做的单子 什么的 放到名字下面；
           两块接单情况 近1个月的放上面、近3个月的放下面」

   ⚠️ 新样式一律用 `dw-` 前缀，**绝不改 `dc-nums` / `dc-foot` / `dc-sub`** ——
      那几个类「客服数据」页（service_stat.html）也在用，改了会把那一页一起改掉。
   ⚠️ 卡片在企微侧边栏里只有 ~380px 宽，所有数字必须留得住：
      过长的（154,152 / 1,939.50）靠容器查询降字号，⛔ 不能撑破。
   ========================================================================== */
/* ── 名字下面那行：最近接单 + 在做中 ── */
.dw-sub{
  display:flex;align-items:center;gap:4px;flex-wrap:nowrap;
  font-size:12px;color:#5a6572;margin-top:3px;min-width:0;
}
.dw-sub b{color:#1d2836;font-weight:600;font-variant-numeric:tabular-nums}
.dw-sub .k{color:#8a94a6;font-size:11px;white-space:nowrap}
.dw-sub em{font-style:normal;font-size:10.5px;color:#98a2b3;white-space:nowrap}
.dw-sub .sp{flex:1;min-width:6px}
.dw-dot{flex:none;width:7px;height:7px;border-radius:50%;background:#cbd3dd}
.dw-dot.ok{background:#1a9d63}
.dw-dot.info{background:var(--brand)}
.dw-dot.warn{background:#c47f17}
.dw-dot.mut{background:#cbd3dd}

/* ── 「会做的单子」那个小名头（标签行前面） ── */
.dw-k{
  flex:none;font-size:11px;color:#8a94a6;background:#f2f4f7;
  border-radius:4px;padding:0 6px;line-height:1.7;white-space:nowrap;
}

/* ── 接单情况：2 行小表格（行=窗口，列名共用） ── */
.dw-tbl{border:1px solid #eaecf0;border-radius:8px;overflow:hidden}
.dw-tr{
  display:grid;align-items:center;
  /* ⚠️ 第一列要放得下「近1个月」+ 下面那行日期（08-21 ~ 09-20）。
     64px 时日期会差几像素露出来（实测 60 > 56），所以给到 72px。 */
  grid-template-columns:72px repeat(4,minmax(0,1fr));
}
.dw-tr + .dw-tr{border-top:1px solid #f0f2f5}
.dw-tr .rl{
  display:flex;flex-direction:column;justify-content:center;
  padding:4px 0 4px 8px;font-size:11.5px;font-weight:600;color:#5a6572;
  line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.dw-tr .rl i{font-style:normal;font-size:8.5px;font-weight:400;color:#aab4c0}
.dw-tr .cv{
  text-align:center;font-size:13.5px;font-weight:700;color:#1d2836;
  font-variant-numeric:tabular-nums;letter-spacing:-.2px;
  padding:6px 1px;border-left:1px solid #f0f2f5;
  white-space:nowrap;overflow:hidden;
}
.dw-th{background:#fafbfc}
.dw-th .rl{padding:0}
.dw-th span{font-size:10.5px;font-weight:400;color:#98a2b3;padding:4px 1px}
/* 主角：近 1 个月 */
.dw-now{background:#eef4ff}
.dw-now .rl{color:#1d4ed8}
.dw-now .cv{color:#1b4f9c;border-left-color:#dbe7fb}
/* 退款率按高低上色。⚠️ 必须带 `.dw-tr .cv` 前缀（0,3,0），
   否则会输给上面的 `.dw-now .cv`（0,2,0），红黄会被盖成蓝的 —— 踩过。 */
.dw-tr .cv.rt.ok{color:#15803d}
.dw-tr .cv.rt.warn{color:#b45309}
.dw-tr .cv.rt.bad{color:#c9372c}
.dw-tr .cv.rt.mut{color:#cbd3dd}

/* ── 底下：案例库那行 + 看他的单 ── */
.dw-foot{
  display:flex;align-items:center;gap:6px;flex-wrap:nowrap;
  border-top:1px dashed #eaecf0;padding-top:7px;
  font-size:11.5px;color:#5a6572;min-width:0;
}
.dw-foot .sp{flex:1;min-width:4px}
.dw-case{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dw-case i{font-style:normal;margin-right:3px}
.dw-case.dim{color:#98a2b3}
/* ⭐ 2026-10-02：这一格从 `em` 改成了**可点的链接**（点开看他的案例），
   所以要显式去掉下划线；hover 才出现，提示「这里能点」。 */
.dw-cn{font-style:normal;color:var(--brand);font-size:11px;flex:none;white-space:nowrap;
  text-decoration:none;cursor:pointer}
.dw-cn:hover{text-decoration:underline}
.dw-foot .btn{height:26px;padding:0 9px;font-size:11.5px;flex:none}
.dw-eval{
  font-size:11px;color:#98a2b3;margin-top:-6px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* 卡片被挤窄（企微侧边栏 / 手机）时，把表格里的字降一档，别撑破 */
@container (max-width:355px){
  .dw-tr .cv{font-size:12.5px}
  .dw-tr{grid-template-columns:58px repeat(4,minmax(0,1fr))}
  .dw-tr .rl{font-size:11px;padding-left:6px}
  .dw-tr .rl i{font-size:8.5px}
}
@container (max-width:310px){
  .dw-tr .cv{font-size:11.5px}
  .dw-sub em{display:none}
}


/* ===========================================================================
   视觉精修 v1.17.7（续）—— 订单预警页
   ⚠️ 四个类别卡片也用 auto-fill + min(240px,100%)：
      窄到企微侧边栏那样也不会撑破（跟设计师排行卡片同一个坑，见上面的注释）。
   =========================================================================== */
.alert-kinds{
  display:grid;gap:12px;margin-bottom:16px;
  grid-template-columns:repeat(auto-fill,minmax(min(240px,100%),1fr));
}
/* ⭐ 2026-10-02 第 5 类加进来后是 **5 张卡** —— 240px 一列只放得下 4 张，
   第 5 张会掉到第二行、右边空一大块（很难看）。这里只在**真的有 5 张**时
   把列宽收窄，让 5 张排成一行。
   ⚠️ 用 `:has()` 而不是直接改上面的规则 —— 4 张卡时（老样子）**一个像素都不动**。
   ⚠️ 万一浏览器不认 `:has()`（Edge 105 以下），就回落到原来的 4+1 排版，不会坏。 */
.alert-kinds:has(> :nth-child(5)){
  grid-template-columns:repeat(auto-fit,minmax(min(170px,100%),1fr));
}
.alert-kind{
  display:block;min-width:0;
  background:#fff;border:1px solid var(--line);border-radius:10px;
  padding:12px 14px;text-decoration:none;color:inherit;
  transition:border-color .15s,box-shadow .15s;
}
.alert-kind:hover{border-color:#c9d4e4;box-shadow:0 2px 10px rgba(16,24,40,.06)}
.alert-kind.on{border-color:var(--brand);background:#f5f8ff;
  box-shadow:inset 0 0 0 1px var(--brand)}
.ak-num{font-size:22px;font-weight:700;color:#1d2836;
  font-variant-numeric:tabular-nums;line-height:1.2}
.alert-kind.on .ak-num{color:var(--brand)}
.ak-name{font-size:13.5px;font-weight:600;color:#344054;margin-top:2px}
.ak-desc{font-size:11.5px;color:#98a2b3;margin-top:4px;line-height:1.5}
.alert-title{font-size:15px;font-weight:600;color:#1d2836;margin:18px 0 10px}
.alert-title .hint{font-weight:400;margin-left:8px}

/* 占比徽标：60% 以上标红、50% 以上标橙 */
.ratio-badge{
  display:inline-block;padding:1px 7px;border-radius:6px;font-size:12px;
  font-weight:600;font-variant-numeric:tabular-nums;
  background:#f2f4f7;color:#475467;
}
.ratio-badge.warm{background:#fff4e5;color:#b25e09}
.ratio-badge.hot{background:#fdecea;color:#c9372c}

/* ==========================================================================
   视觉精修 v1.17.8 —— 能力标签（2026-09-23）
   老板：「根据设计师接单的宝贝名称识别他能做哪些，标签写上去，派单时参考」

   ⚠️ 用 .skill-tag 而不是 .tag —— 项目里 .tag 是「岗位/身份」的徽标，
      全局覆盖那个类会把别处（提成组、员工页）的徽标一起改掉（踩过）。
   ⚠️ 标签都很短（2~6 个字），所以 nowrap + 小字号，窄屏才排得下。
   ========================================================================== */

/* ── 标签本体 ── */
.skill-tag{
  display:inline-flex;align-items:center;gap:3px;
  padding:1px 8px;border-radius:999px;font-size:12px;line-height:1.8;
  background:#eef4ff;color:#1d4ed8;border:1px solid #c7dbfe;
  white-space:nowrap;
}
.skill-tag b{
  font-weight:600;color:#1e40af;font-size:11.5px;
  font-variant-numeric:tabular-nums;
}
/* 手工标的：换个颜色，一眼能跟"系统推的"区分开 */
.skill-tag.sk-manual{background:#f0fdf4;color:#15803d;border-color:#bbf7d0}
.skill-tag.sk-manual b{color:#166534}
/* 被去掉的（弹窗里） */
.skill-tag.sk-off{background:#f6f7f9;color:#98a2b3;border-color:#e4e7ec;text-decoration:line-through}
.skill-tag.sk-off button{
  background:none;border:none;color:#1d4ed8;cursor:pointer;
  font-size:11.5px;padding:0 0 0 4px;text-decoration:none;
}
.skill-tag > button{
  background:none;border:none;color:#1d4ed8;cursor:pointer;
  font-size:13px;line-height:1;padding:0 0 1px 2px;opacity:.55;
}
.skill-tag > button:hover{opacity:1}

/* ── 设计师排行卡片里那一行 ── */
.dc-tags{
  display:flex;flex-wrap:wrap;gap:5px;align-items:center;
  margin:8px 0 2px;padding-top:8px;border-top:1px dashed #eaecf0;
}
.dc-tags-none{opacity:.85}
.skill-edit{
  margin-left:auto;background:none;border:1px dashed #d0d5dd;border-radius:6px;
  color:#667085;font-size:11.5px;padding:1px 7px;cursor:pointer;white-space:nowrap;
}
.skill-edit:hover{color:var(--brand);border-color:var(--brand);border-style:solid}

/* ── 派单详情：报名的人下面那行 ── */
.d-tags{display:flex;flex-wrap:wrap;gap:5px;margin-top:6px;align-items:center}
.d-signup .skill-tag{font-size:11.5px;padding:0 7px}

/* ── 员工列表那列（⚠️ 只放纯文字，这一页 3800 多人，别加重）── */
.st-tags{font-size:12.5px;color:#475467;line-height:1.7}
.st-tags-cell{max-width:180px}

/* ── 「能力标签」页的卡片 ── */
.sk-card{
  background:#fff;border:1px solid var(--line,#e7eaf0);border-radius:10px;
  padding:16px 18px;
}
.sk-card h2{font-size:15px;margin:0 0 12px;padding-left:9px;border-left:3px solid var(--brand,#2563eb)}
.sk-card table{margin:0}
.sk-form label{display:block;font-size:13px;color:#475467;margin:10px 0 5px;font-weight:600}
.sk-form label:first-child{margin-top:0}
.sk-form .input-suffix{max-width:340px}

/* ── 编辑弹窗 ── */
.sk-mask{
  position:fixed;inset:0;background:rgba(16,24,40,.45);z-index:9000;
  display:none;align-items:center;justify-content:center;padding:16px;
}
.sk-dlg{
  background:#fff;border-radius:12px;width:100%;max-width:520px;
  max-height:86vh;display:flex;flex-direction:column;overflow:hidden;
  box-shadow:0 18px 48px rgba(16,24,40,.22);
}
.sk-head{
  display:flex;align-items:center;justify-content:space-between;
  padding:13px 16px;border-bottom:1px solid #eaecf0;font-size:15px;
}
.sk-x{background:none;border:none;font-size:20px;line-height:1;color:#98a2b3;cursor:pointer;padding:0 2px}
.sk-x:hover{color:#475467}
.sk-body{padding:14px 16px 18px;overflow:auto}
.sk-sec{margin-bottom:16px}
.sk-sec:last-child{margin-bottom:0}
.sk-lab{font-size:12.5px;color:#667085;font-weight:600;margin-bottom:8px}
.sk-chips{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.sk-add{display:flex;gap:8px;flex-wrap:wrap}
.sk-add select{flex:0 0 auto;min-width:150px}
.sk-add input{flex:1;min-width:130px}
/* 窄屏（企微侧边栏 ~400px）：按钮整行，别挤成一条缝 */
@media (max-width:460px){
  .sk-add{flex-direction:column}
  .sk-add select,.sk-add input,.sk-add button{width:100%}
  .dc-tags .skill-edit{margin-left:0}
}

/* ===========================================================================
   视觉精修 v1.17.9 · 手机端适配（2026-09-23）
   老板在手机上打开线上系统：「这个页面乱码了，能不能手机端、电脑端通用？」

   诊断：**不是乱码，是布局没适配** —— 左边 214px 的菜单没收起来，
   正文被挤成一条缝。而原来的窄屏规则是 `@media (max-width:560px)`，
   老板那台手机的 CSS 宽度约 650px，**根本没触发**；
   而且那条规则是"把菜单藏掉"，手机上就没导航了。

   这一段的做法：
     ① 断点提到 1000px（214px 菜单 + 正文，不到 1000 都在受罪）
     ② 菜单从"占一列"改成"抽屉"：平时滑出屏幕外，点 ☰ 滑进来、点黑幕关掉
     ③ 顶栏显示当前是谁 + 退出（手机上没地方看这些）
     ④ 多列表格改成可以横着滑，别把 15 列挤成两行
   ⚠️ 桌面端（>1000px）**这一整段都不生效**，电脑上的样子一点不变。
   =========================================================================== */

/* 顶栏和黑幕：桌面端完全不显示 */
.mbar{display:none}
.nav-backdrop{display:none}

@media (max-width:1000px){
  /* ── ① 菜单改成抽屉 ── */
  html,body{overflow-x:hidden}
  /* ⚠️ 桌面端是「body 固定 100vh、正文在里面自己滚」（为了钉住表头）。
     手机上必须改回「整页正常滚」，否则 body 的 overflow:hidden 会把
     一屏以下的内容**剪掉且滚不动**。
     ⛔ 这里 height/overflow 一定要显式写，只写 display:block 是不够的
     （那样 100vh+hidden 还在生效）。 */
  body.with-side{display:block;height:auto;min-height:100%;overflow:visible}
  body.with-side .main{height:auto;min-height:100vh;overflow:visible}
  body.with-side .page{overflow:visible;flex:none;min-height:0}
  .side{
    position:fixed;left:0;top:0;bottom:0;z-index:60;
    width:min(76vw,250px);flex:none;height:100vh;
    transform:translateX(-105%);transition:transform .18s ease;
    box-shadow:0 0 30px rgba(0,0,0,.35);
  }
  body.nav-open .side{transform:none}
  .nav-backdrop{position:fixed;inset:0;background:rgba(16,24,40,.45);z-index:55}
  body.nav-open .nav-backdrop{display:block}

  /* ── ② 窄屏顶栏 ── */
  .mbar{display:flex;align-items:center;gap:10px;
    background:#1f2b3a;color:#fff;padding:8px 12px;
    position:sticky;top:0;z-index:40}
  .mbar-btn{background:none;border:1px solid #3a4759;color:#fff;border-radius:8px;
    font-size:16px;line-height:1;padding:6px 11px;cursor:pointer;flex:none}
  .mbar-btn:active{background:#2a3849}
  .mbar-title{font-weight:600;font-size:15px;white-space:nowrap}
  .mbar-user{font-size:12.5px;color:#a9b8c9;margin-left:auto;
    max-width:32vw;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .mbar-out{color:#8fa3b8;font-size:12.5px;text-decoration:none;flex:none}

  /* ── ③ 正文占满宽度 ── */
  body.with-side .page{padding-left:12px;padding-right:12px;box-sizing:border-box}
  .page-head{display:block}
  .page-head h1{font-size:18px}
  .app-foot{flex-wrap:wrap;padding-left:12px;padding-right:12px}
  .app-foot .hint{display:none}

  /* ── ④ 表格：能横着滑 ──
     ⚠️ 桌面端 `.table-wrap` 被设成 overflow:visible（为了表头 sticky），
        手机上必须改回 auto，否则 15 列的表格会被挤成一堆断行。 */
  body.with-side .table-wrap{
    overflow-x:auto;-webkit-overflow-scrolling:touch;
    max-height:none;overscroll-behavior-x:contain;
  }
  /* 多列表格给个最小宽度 —— 让它横向滑，而不是把每格压成竖排 */
  table.wide{min-width:680px}

  /* ── ⑤ 各种格子窄屏堆一列 ── */
  .filter-bar,.toolbar{flex-wrap:wrap;gap:8px}
  .stat-row{grid-template-columns:repeat(2,minmax(0,1fr))}
  .two-col,.grid2{grid-template-columns:1fr}
}

/* 更窄（企微侧边栏 ~400px、小屏手机）：再收一点 */
@media (max-width:460px){
  .mbar-title{font-size:14px}
  .mbar-user{max-width:26vw}
  .side{width:min(82vw,240px)}
  table.wide{min-width:600px}
  body.with-side .page{padding-left:9px;padding-right:9px}
}

/* ==========================================================================
   视觉精修 v1.18.2 · 窄屏下的「显示列」菜单（2026-09-23）
   老板在手机上点「显示列」，面板只露出左边一小条 ——
   因为它 `position:absolute; right:0` 是往**左**展开 min-width:200px 的浮层，
   而窄屏上这个按钮靠屏幕左边 → 菜单整个跑到屏幕左侧外，
   再被 `html,body{overflow-x:hidden}`（窄屏那段的）裁掉，只剩几十像素。

   修法：窄屏下**不做浮层**，改成文档流里的整行（按钮下面直接展开）——
   手机上这样反而更好点：不遮挡内容、不用管溢出、也不用担心被裁。
   ⚠️ 桌面端（>1000px）这一段完全不生效，电脑上的浮层样子一点不变。
   ========================================================================== */
@media (max-width:1000px){
  .col-picker{position:static;flex:1 1 100%;min-width:0}
  .col-menu{
    position:static;right:auto;top:auto;
    min-width:0;width:auto;max-height:none;margin-top:8px;
    box-shadow:none;
  }
  /* 浮动层里可以 nowrap 让列名一行一个，进了文档流就别硬撑宽度了 */
  .col-item{white-space:normal}
}

/* ==========================================================================
   视觉精修 v1.18.4 · 表格对齐 + 金额格居中（2026-09-23）
   老板：「金额数字这边没有居中，你居中下，其他列也看下，优化下」

   ① 关键问题：金额格里的 <input> 要**在格子里居中**，而不只是"字在框里居中"。
      它是 `width:100%; max-width:110px` —— 列一宽，输入框就贴左边，
      框里的字再怎么居中，整体看着也是偏的。
   ② 顺带把对齐规则理一遍并写死优先级：默认全居中；只有长文本列（备注、商品标题）
      左对齐 —— 而且**表头也跟着左对齐**，不然头居中、内容靠左，看着是歪的。
   ========================================================================== */

td.cell-edit,td.cell-edit .cell-input,td.num,th.num{text-align:center}

td .cell-input{
  display:block;
  margin:0 auto;          /* ← 输入框本身在格子里居中（这才是老板说的"没居中"） */
}

td[data-col="note"],th[data-col="note"],
td[data-col="item_title"],th[data-col="item_title"]{text-align:left}

/* 序号列窄，居中更整齐 */
td[data-col="no"],th[data-col="no"]{text-align:center}

/* ==========================================================================
   视觉精修 v1.18.6 · 成员弹窗里的「名字」列要能截断（2026-09-23）
   老板：「有些名字特别长，他就显示的特别长，整个页面都没了，导致其他的列看不到了」

   根因其实在数据：`staff` 表里有 47 个"名字"长度 > 20（最长的 101 字）——
   那是**整条备注被当成了一个人名**（解析器遇到"一条备注写了好几个人"的格式时切错了）。
   数据要单独治，但**界面必须扛得住**：再长的名字也只能占一格。

   做法：名字单独包 `<span class="mem-name">`，超出就省略号，鼠标移上去看全文。
   ⚠️ 「未授权」标签放在 span **外面**，否则会被一起截掉（那就看不出授权状态了）。
   ========================================================================== */
.mem-name{
  display:inline-block;
  max-width:230px;              /* 正常名字 5~8 个字，230px 足够；再长就是脏数据了 */
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
  vertical-align:bottom;
}
/* 窄屏（企微侧边栏 / 手机）再收一点 */
@media (max-width:560px){
  .mem-name{max-width:130px}
}

/* ==========================================================================
   视觉精修 v1.18.11 · 订单预警：把「操作」列固定在右侧（2026-09-24）
   老板要在这页加「处理结果 / 处理备注」，可表格本来就有 11 列，
   加上去 13 列 ≈ 1450px —— 他那台机器内容区只有 ~880px，
   结果「保存」按钮被推到屏幕外，要横滑才能点到（截图里看出来了）。

   修法：**操作列 sticky 固定在右边**，横滑时它一直跟着 —— 点「处理」永远不用找。
   顺手把「处理结果 / 处理备注」也改成弹窗里的输入项，表格只多一列窄按钮。

   ⚠️ sticky 的三个前提（这页都满足）：表格不能 overflow:hidden、
      滚动容器只能一层（.table-wrap）、th 不能有 padding-top。
   ⚠️ 背景必须不透明，否则下面的字会透出来。
   ⚠️ 表头那格 z-index 要更高，不然会被表体的固定列盖住。
   ========================================================================== */
.alert-table th[data-col="ops"],
.alert-table td[data-col="ops"]{
  position:sticky;right:0;
  background:var(--card);
  border-left:1px solid #d8dee8;
}
.alert-table th[data-col="ops"]{z-index:7}
.alert-table td[data-col="ops"]{z-index:2}
/* 鼠标划过整行时，固定那格也要跟着变色，否则看着像"断了一截" */
.alert-table tbody tr:hover td[data-col="ops"]{background:#f7f9fc}

/* ==========================================================================
   视觉精修 v1.18.12 · 侧边栏「一级栏目 / 二级栏目」（2026-09-24）
   老板：「总览放在第一页，然后我们配置下一级栏目和二级栏目…」

   做法：一级栏目 = 可折叠的标题（.nav-group-head），二级 = 缩进在下面。
   ⚠️ 默认**全部展开**（他怕点两下才到）—— 想收的可以自己点，状态记在 localStorage。
   ⚠️ 当前页所在的那一组**强制展开**，否则"自己在哪一栏"都看不出来。
   ⚠️ 一级标题是 <button>，不是 <a> —— 别让它吃到 .side-nav a 的链接样式和
      "最长前缀匹配高亮"（那套逻辑只认 a）。
   ========================================================================== */
.nav-group{margin:7px 0 3px}
.nav-group-head{
  display:flex;align-items:center;gap:9px;width:100%;
  padding:8px 12px;border:0;background:transparent;border-radius:7px;
  color:#7f93a8;font:inherit;font-size:12px;letter-spacing:.3px;
  text-align:left;cursor:pointer}
.nav-group-head:hover{background:#2a3849;color:#c7d2de}
.nav-group-head .ico{width:16px;text-align:center;font-size:12px;opacity:.75;flex:none}
.nav-group-head i{margin-left:auto;font-style:normal;font-size:10px;
  opacity:.7;transition:transform .15s}
.nav-group.open .nav-group-head i{transform:rotate(180deg)}
/* 当前页在这一组里 → 标题亮一点，一眼知道"我在哪一栏" */
.nav-group.has-active > .nav-group-head{color:#c7d2de;font-weight:600}
.nav-group-body{display:none;padding-left:6px}
.nav-group.open > .nav-group-body{display:block}
/* 二级项缩进一点，跟一级标题区分开 */
.nav-group-body > a{padding-left:20px;font-size:13px}
.nav-group-body > a .ico{font-size:13px;opacity:.7}

/* ⭐ 2026-10-11 老板：「为什么这些分类没办法点击的。。。。不能折叠么？」
   —— 侧栏（含员工端「管理后台」里那一层）现在会出现**嵌套的** `.nav-group`：
     外层是栏目分组，内层是"栏目名（可折叠）→ 它的子项"。
   ⚠️ 不补这几行的话，内层子项会吃两层缩进（6px + 20px = 26px）显得太深，
      而且内层标题会跟一级标题**一样大**，层次糊在一起。
   ⛔ 全部只作用于**嵌套那一层**（`.nav-group .nav-group`），
      顶部那层和独立用的 `.nav-group` 一个像素都不动 —— 别影响管理员端现有长相。 */
.nav-group .nav-group{margin:2px 0}
.nav-group .nav-group > .nav-group-body{padding-left:0}
.nav-group .nav-group > .nav-group-head{padding-left:12px;font-size:13px;color:#9fb0c2}
.nav-group .nav-group > .nav-group-head .ico{opacity:.8}
/* 内层再往右缩一档，但仍比"一级标题"浅，保证看得出层级 */
.nav-group .nav-group > .nav-group-body > a{padding-left:26px}

/* ==========================================================================
   视觉精修 v1.18.12 · 运营宝贝库「主图」缩略图（2026-09-24）
   老板：「智能表格那边是有图片的，为啥同步到这边来没有主图了？」
   —— 数据一直在（存在 raw 里），只是没往上捞；现在补上 image_url 并显示。
   ⚠️ 图走本系统的缩略图接口（/admin/items/thumb/<id>），**不是**直接嵌企微原图 ——
      原图平均 532KB、CDN 还不吃缩放参数，一页 30 行能到 15MB。
   ========================================================================== */
.item-thumb{
  width:52px;height:52px;object-fit:cover;display:block;
  border:1px solid var(--line);border-radius:6px;background:#f2f4f7}
a:hover > .item-thumb{border-color:var(--brand)}

/* ==========================================================================
   视觉精修 v1.18.18 · 「组权限管理」的栏目权限弹窗（2026-09-24）
   老板：「放到提成组里面去…比如财务组，我可以配置他能登录哪些后台栏目」

   弹窗分两区：员工端栏目 / 后台栏目。勾选项做成**大一点的胶囊**，
   手机上也好点（他经常在手机上看）。后台栏目按栏目组（订单管理/系统管理…）分行。
   ⛔ 后台栏目默认全不勾 —— 那是能进管理后台改钱的东西。
   ========================================================================== */
.pm-sec{
  display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;
  margin:2px 0 9px;padding-bottom:6px;border-bottom:1px solid var(--line)}
.pm-sec > strong{font-size:14px}
.pm-sec .hint{font-size:12px;line-height:1.6;color:var(--muted)}
.pm-grp{font-size:12px;color:var(--muted);margin:12px 0 6px;letter-spacing:.2px}
.pm-grid{display:flex;flex-wrap:wrap;gap:8px}
.pm-ck{
  display:inline-flex;align-items:center;gap:7px;
  padding:7px 12px;border:1px solid var(--line);border-radius:9px;
  background:var(--card);cursor:pointer;font-size:13px;white-space:nowrap;
  transition:border-color .12s,background .12s}
.pm-ck:hover{border-color:var(--brand);background:#f7faff}
.pm-ck input{width:15px;height:15px;margin:0;cursor:pointer;flex:none}
.pm-ck i{font-style:normal;opacity:.5;margin-right:5px;font-size:12px}
/* 勾上的用边框加粗一点，一眼能数出勾了几个 */
.pm-ck:has(input:checked){border-color:var(--brand);background:#f2f7ff}
.pm-ck:has(input:checked) > span{font-weight:600}
/* 带说明小字的项（2026-09-26）——勾之前就知道"勾了会怎样"，别勾完才发现在放权。
   ⚠️ 有说明的项要允许换行、自己撑高；用 align-items:flex-start 让复选框跟第一行对齐，
      不要居中（居中会跟着小字往下沉）。 */
.pm-ck:has(.pm-desc){align-items:flex-start;white-space:normal}
.pm-ck:has(.pm-desc) input{margin-top:2px}
.pm-ck em.pm-desc{
  display:block;font-size:11.5px;font-style:normal;color:var(--muted);
  margin-top:2px;line-height:1.45;white-space:normal;max-width:30em}
.pm-ck:has(input:checked) em.pm-desc{color:#0d6b39}

/* ── ⭐ 2026-10-16 按人配「栏目权限」：勾选框卡片（跟「组权限管理」同款外观）──
   状态类挂在卡片 class 上：g-on/g-no（组）/ p-on/p-off（个人）/ skip（批量·不动）。 */
.pm-ck.tri{cursor:pointer;user-select:none;gap:7px;white-space:normal;align-items:flex-start}
/* 勾选框外观（16×16 小方块，跟组权限管理的 checkbox 一致） */
.pm-ck.tri .tri-ic{font-style:normal;flex:none;width:16px;height:16px;
  display:inline-flex;align-items:center;justify-content:center;
  border:1px solid #cfd6de;border-radius:3px;background:#fff;
  font-size:11px;line-height:1;color:transparent;transition:all .12s}
.pm-ck.tri:has(.pm-desc) .tri-ic{margin-top:1px}
.pm-ck.tri .tri-tag{display:block;font-size:11px;font-style:normal;line-height:1.4;
  margin-top:2px;white-space:normal;max-width:30em;color:var(--muted)}
/* 组给的（g-on）：浅蓝勾 */
.pm-ck.tri.g-on{border-color:#b9d0f5;background:#f6f9fe}
.pm-ck.tri.g-on .tri-ic{border-color:#b9d0f5;background:#eaf2ff;color:#5a8ed6}
.pm-ck.tri.g-on .tri-tag{color:#5a8ed6}
/* 个人开的（p-on）：品牌蓝勾 */
.pm-ck.tri.p-on{border-color:var(--brand);background:#f2f7ff}
.pm-ck.tri.p-on .tri-ic{border-color:var(--brand);background:var(--brand);color:#fff}
.pm-ck.tri.p-on .tri-tag{color:var(--brand)}
/* 个人关的（p-off）：红叉 */
.pm-ck.tri.p-off{border-color:#d92d20;background:#fdf3f2}
.pm-ck.tri.p-off .tri-ic{border-color:#d92d20;background:#fdf3f2;color:#d92d20}
.pm-ck.tri.p-off .tri-tag{color:#d92d20}
/* 批量·不动（虚线空框） */
.pm-ck.tri.skip{opacity:.75}
.pm-ck.tri.skip .tri-ic{border-style:dashed}
/* 「① 组权限」只读块：不可点、不 hover 高亮 */
.pm-ck.tri.ro{pointer-events:none;cursor:default}

/* ══════════════════════════════════════════════════════════════════════
   ⭐⭐⭐ 2026-10-16（第二轮）· 老板点了样稿 **B 套** —— 权限弹窗分块
   ──────────────────────────────────────────────────────────────────────
   老板原话（配一张弹窗截图）：「这个权限管理这边我不知道哪一个是员工端的权限，
     哪一个是管理端的权限。你能不能弄的清楚一些。。。。然后做个网页我大概看下
     么问题的话 再发布~」

   ⛔ 根因：单人弹窗里 `grid(data.staff)` 和 `adminBlocks()` 是**直接连着排的**，
      中间**一条分界线都没有**（批量那个弹窗反而有分界）⇒ 员工端的「发派单」
      和后台「派单记录」挨在一起，差一个字、位置又近，**老板就勾错过一次**。

   ⭐ 做法：包成两个色块（员工端浅蓝 / 管理后台灰）+ 一条防呆提示。
   ⛔ 只加"包一层"的视觉 —— 卡片本身（`.pm-ck.tri`）一个像素都不动；
      权限数据、勾选逻辑、保存逻辑也一个字节不动。
   ⚠️ 后台那块**没内容就不画**（空色块比不画难看）；防呆提示同理
      （见 `staff.html` 的 `zone()` / `zoneGuard()`）。
   ========================================================================== */
.pm-zone{border-radius:11px;padding:11px 12px;margin-top:13px}
.pm-zone.emp{background:#f4f8ff;border:1px solid #d6e4fb}
.pm-zone.adm{background:#fafbfc;border:1px solid var(--line)}
.pm-zone-hd{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;margin-bottom:9px}
.pm-zone-hd > b{font-size:14.5px}
.pm-zone.emp .pm-zone-hd > b{color:#1a56c4}
.pm-zone-hd > span{font-size:12px;color:var(--muted)}
/* 防呆提示：「想让他派单 → 勾上面蓝块的『发派单』，不是下面灰块的『派单记录』」 */
.pm-guard{background:#fff8ec;border:1px solid #f0dcb4;border-radius:9px;
  padding:9px 12px;font-size:12.5px;color:#a3611f;line-height:1.7;margin-top:11px}
.pm-guard b{color:#7a4512}
.pm-guard code{background:#fff;border:1px solid #f0dcb4;padding:0 4px;
  border-radius:3px;font-size:12px}

/* ==========================================================================
   视觉精修 v1.18.19 · 老板 2026-09-24 提的四件事
   ========================================================================== */

/* ── ① 设计师卡片：能力标签**只占一行**，装不下给「…」，「改」始终同行 ──
   老板：「能力标签这边 只显示一行吧，其他的话就省略号就好了~~不然的话，
          有些框空着有些框很满」+「这个『改』能不能放在技能那同一行，不要单独下来」
   ⚠️ 原来 .dc-tags 是 flex-wrap:wrap，标签一多就换行；而 .skill-edit 是
      margin-left:auto —— 一旦换行，它就被挤到最后一行自己待着（截图里就是这样）。
   现在：标签那条线 nowrap + overflow:hidden（裁掉），「…」和「改」在裁切线**外面**，
        所以永远在同一行、永远点得到。 */
.dc-tags{
  display:flex;flex-wrap:nowrap;align-items:center;gap:6px;
  margin:8px 0 2px;padding-top:8px;border-top:1px dashed #eaecf0;
}
.dc-tagline{
  display:flex;flex-wrap:nowrap;align-items:center;gap:5px;
  flex:1 1 auto;min-width:0;overflow:hidden;
}
.dc-more{
  flex:none;color:#98a2b3;font-size:13px;line-height:1;padding:0 2px;user-select:none;
}
.dc-tags-none{opacity:.85}
.skill-edit{
  margin-left:0;flex:none;background:none;border:1px dashed #d0d5dd;border-radius:6px;
  color:#667085;font-size:11.5px;padding:1px 7px;cursor:pointer;white-space:nowrap;
}
.skill-edit:hover{color:var(--brand);border-color:var(--brand);border-style:solid}

/* ── ② 客服数据：名字列别一个人把表格撑满，其它列均衡一点 ──
   老板：「这个名字的栏目默认咋这么大。。能不能 均衡一些哦~~~」
   原来「客服」那列没写宽度，而别的列都固定了宽度 → 多出来的宽度全给了它。
   给个上限 + 长名字截断（库里最长的人名有 101 字，是整条备注被当成人名了）。 */
.svc-name{
  display:inline-block;max-width:168px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;vertical-align:bottom;
}

/* ── ③ 项目运营情况：宝贝名称可能很长（库里最长 101 字）→ 截断，hover 看全文 ── */
.ops-name{max-width:420px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* 「栏目权限」按钮：配过后台栏目的组高亮，一眼看出谁能进后台 */
.perm-btn.on{background:#eaf2ff;border-color:#bcd5ff;color:#1d4ed8;font-weight:600}

/* ⚠️ 组权限管理这张表有 10 列、约 1120px，老板那台机器内容区只有 ~880px，
   横滑才能看到「操作」—— 跟订单预警那次是同一个坑（按钮被推出屏幕外）。
   修法一样：**操作列 sticky 固定在右侧**（那 4 个按钮永远点得到）。
   ⚠️ sticky 的前提这页都满足：table 没有 overflow:hidden、th 没有 padding-top。 */
.groups-table th:last-child,
.groups-table td:last-child{
  position:sticky;right:0;background:var(--card);
  border-left:1px solid #d8dee8}
.groups-table th:last-child{z-index:7}
.groups-table td:last-child{z-index:2}
.groups-table tbody tr:hover td:last-child{background:#f7f9fc}
/* 已禁用的行整行变淡（模板在 tr 上写 opacity）—— 固定那格也跟着淡，别突出来 */
/* ⚠️ 只给**普通按钮**刷白底 —— 用 :not(.on) 排除掉「栏目权限」的高亮态。
   不加这个排除的话，下面这条的权重比 `.perm-btn.on` 高（多一个 td:last-child），
   配过后台栏目的组**再也高亮不起来**（白底盖住了蓝底）。v1.18.22 修。 */
.groups-table td:last-child .btn:not(.on){background:#fff}

/* ⚠️ 这个弹窗比别的弹窗长得多（13 个后台栏目，分了 5 个区，约 750px），
   老板那台机器内容区矮、手机上更矮（他经常在手机上看）——
   不加限制的话「保存权限」按钮会被顶到屏幕外，点不着（跟订单预警那次的坑一样）。
   所以：弹窗最高 92vh 可滚，**底部按钮条 sticky 钉在底边**，滚到哪都点得到。 */
/* ⚠️ 这几个弹窗内容长（栏目权限 13 项 / 新增用户 5 个字段），
   老板那台机器内容区矮、手机上更矮（他经常在手机上看）——
   不加限制的话「保存 / 建账号」按钮会被顶到屏幕外，点不着（跟订单预警那次的坑一样）。
   所以：弹窗最高 92vh 可滚，**底部按钮条 sticky 钉在底边**，滚到哪都点得到。
   ⚠️ 2026-09-24 补：`dlg-newstaff` / `dlg-new`（新增用户、新建带队的人）也漏加了，
      截图里当场看到「建账号」被截掉 —— 新做弹窗时记得一起加进来。 */
#dlg-perms,#dlg-newstaff,#dlg-add{max-height:92vh;overflow:auto;overscroll-behavior:contain}
#dlg-perms .dlg-foot,#dlg-newstaff .dlg-foot,#dlg-add .dlg-foot{
  position:sticky;bottom:0;background:var(--card);
  border-top:1px solid var(--line);z-index:2}
@media (max-width:1000px){
  #dlg-perms,#dlg-newstaff,#dlg-add{width:96vw;max-width:96vw;max-height:94vh}
  #dlg-perms .dlg-head,#dlg-newstaff .dlg-head,#dlg-add .dlg-head{
    padding:14px 16px 0;font-size:15px}
  #dlg-perms .dlg-sub,#dlg-perms .dlg-body,
  #dlg-newstaff .dlg-sub,#dlg-newstaff .dlg-body,
  #dlg-add .dlg-sub,#dlg-add .dlg-body{padding-left:16px;padding-right:16px}
  #dlg-perms .dlg-foot,#dlg-newstaff .dlg-foot,#dlg-add .dlg-foot{padding:12px 16px}
  .pm-ck{padding:8px 11px}   /* 手机上手指点得到的尺寸 */
}

/* ── 用户管理的搜索框（2026-09-24）──
   新加的账号没有订单、按账单数排会掉到最后一页，老板在 3802 人里找不到人，
   所以这一页必须有搜索。放筛选按钮后面，窄屏自动换行占满。 */
.staff-search{display:flex;gap:8px;align-items:center;margin-left:6px}
.staff-search input[type=text]{width:210px}
@media (max-width:1000px){
  .staff-search{width:100%;margin:8px 0 0 0}
  .staff-search input[type=text]{flex:1;width:auto;min-width:0}
}

/* ── 团队管理（2026-09-24）──
   跟「组权限管理」同一个套路：操作列 sticky 钉右侧（老板内容区只有 ~880px），
   「他归谁管」是个下拉，宽度给够但别撑爆。 */
.teams-table th:last-child,.teams-table td:last-child{
  position:sticky;right:0;background:var(--card);
  border-left:1px solid #d8dee8}
.teams-table th:last-child{z-index:7}
.teams-table td:last-child{z-index:2}
.teams-table tbody tr:hover td:last-child{background:#f7f9fc}
/* ⚠️ 只给普通按钮刷白底，「队员」是 primary（蓝底白字）—— 一起刷白会变成
   **白底白字，按钮直接看不见**（v1.18.22 截图里当场抓到） */
.teams-table td:last-child .btn:not(.primary){background:#fff}
/* 职务小标签（队长 / 运营）—— 老板 2026-09-24：「带队的人这边最好边上加职务，
   不然感觉有点乱」。名字只显示人名，职务靠这个标签，一眼看得出层级。 */
.rank-tag{background:#eef2ff;color:#4f46e5;border-color:#dfe4ff}
/* ⚠️ 下拉的文字会**压在向下箭头上**（老板：「那个向下的箭头在名字上了。。有点乱」）
   → 右边留出箭头的位置。 */
.teams-table select{padding-right:22px;max-width:100%}
.teams-table select{max-width:190px}

/* ── 团队提成比例那一格（2026-09-24）──
   每个队长/运营单独填一个数，改完立刻存；留空 = 不算钱（placeholder 写「不算」）。 */
.teams-table .rate-cell{display:inline-flex;align-items:center;gap:2px}
.teams-table .rate-cell input{width:62px;text-align:right;padding:3px 5px}
.teams-table .rate-cell .unit{color:var(--muted);font-size:12px}


/* ── 「添加带队的人」弹窗：从「用户管理」挑人（2026-09-24 v1.18.26）──
   老板：「前面不是有用户管理么。。。不然这样的话不是有两个账号重复了么」→
   这里**不建账号**，只搜已有的人、点一下加进带队名单。 */
.add-results{
  margin-top:8px;max-height:212px;overflow:auto;overscroll-behavior:contain;
  border:1px solid var(--line);border-radius:8px;background:#fff;
}
.add-results .hint{display:block;padding:10px 12px}
.add-item{
  display:flex;align-items:center;gap:9px;margin:0;padding:8px 12px;
  border-bottom:1px solid var(--line);cursor:pointer;font-size:13.5px;
}
.add-item:last-child{border-bottom:0}
.add-item:hover{background:#f7f9fc}
.add-item input[type=radio]{width:auto;margin:0;flex:0 0 auto}
.add-item .ai-name{font-weight:500;color:var(--text);margin-right:auto}
/* ⚠️ 组名靠右、`margin-left:10px` 兜底 —— 不用 `margin-left:auto`：
   那样「已在名单」标签会跟组名挤在一起，同一列里三行的右端对不齐（截图里看到过）。 */
.add-item .ai-grp{margin-left:10px;color:var(--muted);font-size:12px}
/* 「已在名单」的灰标 —— 让他知道点下去不会重复加 */
.add-in{background:#f2f4f7;border-color:#e4e7ec;color:#667085;font-size:11px;
  padding:1px 6px}
/* 弹窗底部那行「搜不到人？去用户管理」要贴在左边 */
#dlg-add .dlg-foot .hint{margin-right:auto;text-align:left;line-height:1.5}

/* ══════════════════════════════════════════════════════════════════════
   视觉精修 v1.18.30 ｜ 下拉箭头不许压住文字
   ──────────────────────────────────────────────────────────────────────
   全局 `select` 的箭头是用 background-image 画的（12px 宽 + `right 10px`），
   所以右侧内边距**至少要 28px**。可下面这几处各自又写了 `padding` **简写**，
   把它覆盖成 6~10px → 箭头直接压在数字上
   （老板 2026-09-24 报：「这个箭头也是一样 把数字给挡住了」）。

   ⛔ 以后给 select 写 `padding` 简写，右侧一律留 28px 以上。
   ⚠️ 必须写**同特异性**的选择器才盖得住：`.pager select` 能盖 `.pager select`，
      但裸 `select{...}` 盖不住 `.pager select`（后者特异性更高）。 */
.pager select{padding-right:30px}
.settings-form select{padding-right:30px}
.dlg-body select{padding-right:30px}
.mem-bar select{padding-right:30px}
.role-group-row select{padding-right:26px}
.teams-table select{padding-right:28px}

/* ══ v1.18.31 ｜「添加宝贝」弹窗：字段多，矮屏/手机上必须钉住底部按钮 ══
   ⚠️ 不加这条，小屏上「添加」按钮会被切到屏幕外 = 建不了（老弹窗都踩过）。 */
#dlg-newitem{max-height:92vh;overflow:auto;overscroll-behavior:contain;width:520px}
#dlg-newitem .dlg-foot{
  position:sticky;bottom:0;background:var(--card);
  border-top:1px solid var(--line);z-index:2}
@media (max-width:1000px){
  #dlg-newitem{width:96vw;max-width:96vw;max-height:94vh}
  #dlg-newitem .dlg-foot{padding:12px 16px}
}


/* ══ 用户管理：状态开关 / 行内图标按钮 / 操作列固定右侧（2026-09-24）══
   老板：「操作列那边可以编辑，编辑里面可以改这个用户的密码，换组什么的。。也可以删除账户」
   ⚠️ 这页列变多了（14 列），操作列**必须 sticky 钉在右边**，否则会被挤出屏幕点不到。 */
.state-form{display:inline;margin:0}
.state-sw{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--line);
  background:#f4f6f9;color:var(--muted);border-radius:20px;padding:3px 10px 3px 5px;
  font-size:12px;line-height:1.6;cursor:pointer;white-space:nowrap;font-family:inherit}
.state-sw .dot{width:11px;height:11px;border-radius:50%;background:#c4ccd8;flex:none}
.state-sw.on{background:#eaf2ff;border-color:#bcd5ff;color:#1d4ed8;font-weight:600}
.state-sw.on .dot{background:var(--brand)}
.state-sw:hover{border-color:var(--brand)}
/* ⭐ 2026-10-07（第十三轮）离职：状态从两态扩成三态，颜色必须能一眼分清 ——
   启用=蓝 / 已禁用=黄（临时停用，还打算让他回来） / 已离职=粉+日期（不干了）。
   ⚠️ 原来"非启用"一律是灰底灰字，离职和禁用长得一样，老板认不出谁走了。 */
.state-sw.off{background:#faf0d9;border-color:#f0d59a;color:#8a5a12}
.state-sw.off .dot{background:#e0a33a}
.state-sw.off:hover{border-color:#d9a94a}
.state-sw.resigned{background:#fdeaf2;border-color:#f5bcd4;color:#a53a6b;font-weight:600}
.state-sw.resigned .dot{background:#d4537e}
.state-sw.resigned:hover{border-color:#d4537e}
/* ⭐ 2026-10-30（第 2 条）：第四态「未启用」（= 系统从备注/推送/接待里自动认出来的新号）。
   老板要的是「一眼看出这人还没启用」⇒ 用**灰**（比"已禁用"的黄更冷），
   ⛔ 别跟 `.off`（黄=临时停用）撞色，否则「未启用」和「已禁用」又分不清了。 */
.state-sw.pending{background:#eef1f5;border-color:#cfd6e0;color:#5a6779;font-weight:600}
.state-sw.pending .dot{background:#8b98ab}
.state-sw.pending:hover{border-color:#8b98ab}
/* 点「启用」弹出的「禁用 / 离职」选择框（第十三轮） */
.state-pick{display:flex;gap:10px}
.pick-btn{flex:1;display:flex;flex-direction:column;gap:3px;align-items:flex-start;
  border:1px solid var(--line);background:#fff;border-radius:10px;padding:11px 13px;
  cursor:pointer;font-family:inherit;text-align:left}
.pick-btn strong{font-size:14px;font-weight:500;color:var(--text)}
.pick-btn span{font-size:12px;color:var(--muted)}
.pick-btn:hover{background:#f7f9fc}
.pick-btn.pick-disable:hover{border-color:#e0a33a}
.pick-btn.pick-resign:hover{border-color:#d4537e}
.icon-btn{border:1px solid var(--line);background:#fff;border-radius:6px;padding:2px 8px;
  cursor:pointer;font-size:13px;line-height:1.5;margin-left:4px;font-family:inherit;
  color:var(--text)}
.icon-btn:hover{border-color:var(--brand);color:var(--brand)}
.icon-btn.danger:hover{border-color:var(--danger);color:var(--danger)}
/* ⭐⭐ 2026-10-25 老板：「我往右移动的时候能不能把这个 用户账号的这列给冻结。。
     别移动到我看不到。。不然后面的信息我都不确定~~
   ⇒ 把**左边三列（勾选 / 组别 / 用户账号）冻住**：横向滚动时一直贴在左边。

   ⚠️ 为什么是"三列"不是"一列"：sticky left 是**逐列累加**的，
      只冻「用户账号」的话，它贴到 left:0 会把前面的勾选框和组别盖住。
      要冻就得从最左边连续冻。

   ⚠️ `left` 的值**不写死**：① 每列宽度可以用 table_resize.js 拖
      ② 勾选框/组别还能在「显示列」里关掉 —— 宽度一变，写死的 left 就全错。
      所以 left 由 JS 现算（见 staff.html 里的 `frozenCols`，用 ResizeObserver 兜住变化）。

   ⚠️ 背景必须**不透明**：sticky 只是"浮在上面"，透明的话滚动时下面的内容会透出来。 */
/* ⚠️ 2026-10-26 老板：「左边会有一个背景挡着的，稍微移动过去一点点之后
     那个背景也移动过去了，后面就透出来了」
   ⇒ 冻结区里**每一列都要有不透明底色**（少一列就透一条缝）。
     四列全列上，z-index 抬到 5（普通单元格是 auto，操作列是 1，够压住）。 */
.staff-table th[data-col="no"],
.staff-table td[data-col="no"],
.staff-table th[data-col="pick"],
.staff-table td[data-col="pick"],
.staff-table th[data-col="grp"],
.staff-table td[data-col="grp"],
.staff-table th[data-col="acct"],
.staff-table td[data-col="acct"]{
  position:sticky;left:0;background:#fff;z-index:5}

/* 序号列：居中、灰一点、小一点，不抢戏
   ⛔ 2026-10-26 老板连报两次：「序号能不能居中下，不要偏向右边」+
      「这个还是这样的。。你到底是否理解这个呢」
   ⇒ 两次是**同一个根因**：我给这一格加了 `class="num"`，而 `.num{text-align:right}`
     把数字推到右边 → 左边空出一大片，滚动时看着就像"背景没盖住、后面透出来"。
   ⇒ 改成**居中**，并且这格不要 `.num`（模板那边也一起去掉）。 */
.staff-table td[data-col="no"]{
  color:#98a2b3;font-size:12px;text-align:center !important;
  padding-left:0;padding-right:0;white-space:nowrap}
.staff-table th[data-col="no"]{text-align:center !important}

/* 表头那三列还要**贴顶**（body.with-side thead th 本来就是 sticky top:0），
   z-index 要压过普通表头的 6，否则横向滚动时表头会盖住它们 */
body.with-side .staff-table thead th[data-col="no"],
body.with-side .staff-table thead th[data-col="pick"],
body.with-side .staff-table thead th[data-col="grp"],
body.with-side .staff-table thead th[data-col="acct"]{
  top:0;z-index:8;background:#f2f4f7}

/* ⛔ 2026-10-26 老板：「横向拖动 是 A」（左三列右边出现一条白/空，后面的内容透出来）
   根因就是这行 `box-shadow` —— 它是**半透明**的，滚动时后面的单元格会从阴影里透出来，
   看着像"冻结区后面空了一块"。⇒ 换成**实线边框**（不透明，挡得死）。 */
.staff-table td[data-col="acct"],
.staff-table th[data-col="acct"]{
  border-right:1px solid #d8dee8;
  box-shadow:2px 0 0 #fff}

/* 操作记录里"补齐到满页"的空行：只留网格线，别有内容 */
tr.pad-row td{color:transparent;border-bottom:1px solid #f0f3f7}
tr.pad-row:hover td{background:transparent}

/* ⛔⛔ 2026-10-26 老板两次报「出来两个了」（第一版是员工 运营小宇，第二版是管理员 admin）：
      侧栏底部有**两套**用户信息：
        · `.who + .tag` → 后台皮肤（with-side，214px）
        · `.utxt`        → 员工端皮肤（ms-body，206px 文字侧栏）
      `.utxt` 的显示规则写在 **shell.css** 里，而 `shell.css` **只在员工端加载**
      （base.html 里 `{% if staff_shell %}<link shell.css>{% endif %}`）——
      所以后台页面里它**没有任何 CSS 管**，`<span>` 默认 inline 就跟着露出来了。
      ⇒ 隐藏规则必须写在**全站都加载的 style.css**；员工端那边照旧由 shell.css 放出来。 */
.side-user .utxt{display:none}

/* 停用/离职弹窗里的「理由」快捷标签（2026-10-26）
   老板要 4 个：接私单 / 数据差 / 人失联 / 其他（可自己填），**非必填**。 */
/* 停用弹窗里"选中"的那张卡片（2026-10-26）：原来只有聚焦时的黑边，看不出选中了哪张 */
.pick-btn.on{border-color:#2f7cf6;background:#f5f9ff;box-shadow:0 0 0 2px rgba(47,124,246,.15)}
.pick-btn.on strong{color:#175cd3}

.reason-picks{display:flex;flex-wrap:wrap;gap:8px}
.reason-chip{
  padding:6px 14px;border-radius:999px;border:1px solid var(--line);
  background:#fff;color:#475467;font-size:13px;cursor:pointer;
  transition:background .12s,border-color .12s,color .12s}
.reason-chip:hover{background:#f5f7fa}
.reason-chip.on{background:#eef4ff;border-color:#84adff;color:#175cd3;font-weight:600}

.staff-table td.ops{white-space:nowrap}
/* ⭐ 2026-10-16：用户管理「栏目权限」列（账号名右边）—— 带字的「配权限」按钮，不用横向滚动就能看见 */
.staff-table td[data-col="perm"]{white-space:nowrap}
.staff-table .perm-go{padding:3px 10px;font-size:12px;line-height:1.65}
.staff-table td.ops form{display:inline}
/* ⚠️ 2026-10-26 老板：「操作列不是会自动跟着网页移动的么。。。移动的时候
     他上面的标题也显示出来跟着移动」
   ⇒ 操作列本身是 sticky right 的，但 `th:last-child` 的 z-index 只有 1，
     而 `body.with-side thead th` 是 **z-index:6** —— 横向滚动时旁边那些普通表头
     把「操作」这两个字盖住了，所以看着"表头不跟着走"。
   ⇒ 表头单独抬到 7（比普通表头 6 高），数据单元格保持 1。 */
.staff-table td:last-child{
  position:sticky;right:0;background:var(--card);z-index:1;
  border-left:1px solid #d8dee8}
.staff-table th:last-child{
  position:sticky;right:0;top:0;background:#f2f4f7;z-index:7;
  border-left:1px solid #d8dee8}
/* ⭐ 2026-10-01 v1.23.2：操作列钉右边会**压住**左边的「用户状态」开关（实测压 28px）。
   根因：sticky 的 right:0 是贴**容器**右边，而容器（.page）比表格窄，横向滚动时
   操作列就骑到了状态列头上。
   解法：给表格右边留出一块等宽于操作列的**车位**（padding-right），让最后一个数据列
   的右边缘刚好停在 sticky 列左侧 —— 实测重叠 28px → 0px，且「钉右边」完全保留。
   ⚠️ 别改成「缩窄状态列」或「加宽操作列」，实测都无效（sticky 仍贴容器右缘）。 */
body.with-side table.staff-table{padding-right:126px}
.staff-table tbody tr:hover td:last-child{background:#f7f9fc}
/* 组别那一小格里的「不参与提成」提示别撑高行 */
.staff-table .tag{white-space:nowrap}

/* ⭐ 2026-10-06「组织归属」列（双向看：归谁带 / 带着谁）——
   老板：「客服挂在队长身上之后，看不出这个队长下面有哪些客服」
   → 上行「归 XXX」、下行「👥 带 N 人」（点开看名单）。
   ⭐⭐ 2026-10-24 老板：「这里为什么变成两行了。。。表格 变高了很多。。
      能不能变成一行的 。别弄这么高。。。。看着怪怪的~~~~~」
      ⇒ 不再是两行：`.org-up` / `.org-down` 都改成 **inline-flex**，
        外面再用 `.org-line` 一行排开。整行高度从 ~44px 降到 ~28px
        （100 行省 1600px），跟别的列一样高。
      ⚠️ `flex-wrap:nowrap` 故意不给换行：宁可把这一列撑宽一点，
         也不让它偷偷折成第二行又把整张表顶高。 */
.staff-table td[data-col="org"]{line-height:1.45}
.staff-table td[data-col="org"] .org-line{
  display:flex;align-items:center;gap:6px;flex-wrap:nowrap}
.staff-table td[data-col="org"] .org-down{
  display:inline-flex;align-items:center;gap:4px;flex-wrap:nowrap;margin-top:0}
.staff-table td[data-col="org"] .org-down .icon-btn{margin-left:0;padding:2px 6px;
  font-size:11px;line-height:1.4}
.org-kids{border:0;background:#eef4ff;color:#1a56c4;border-radius:5px;
  padding:1px 7px;font-size:11.5px;line-height:1.6;cursor:pointer;
  font-family:inherit;white-space:nowrap;flex:0 0 auto}
.org-kids:hover{background:#dbe8ff}

/* ⭐ 2026-10-24：马甲候选支持多选 —— 选中的行要**一眼看得出**（原来只是淡蓝底，太弱） */
.alias-cand-row.on{background:#eef4ff;box-shadow:inset 3px 0 0 #1a56c4}

/* ⭐ 2026-10-24：用户账号那一格，名字下面单独一行放「岗位」（老板要的） */
/* ⚠️ 2026-10-24 老板（改口）：「这个为什么两行了？给弄成 一行的哦~~~」
   ⇒ 岗位 + 来源**跟名字并排在同一行**，不另起一行（刚才做成了上下两行，太占高度）。 */
/* ⭐ 2026-10-24：整格**一行**（名字 + 岗位 + 来源），不换行 */
.acct-line{display:flex;align-items:center;justify-content:center;gap:5px;
  white-space:nowrap;line-height:1.25}
.acct-line .mem-name{margin:0;min-width:0}
.acct-post{font-size:10px;color:#667085;background:#f2f4f7;border-radius:4px;
  padding:1px 4px;white-space:nowrap;flex:0 0 auto}

/* 危险操作按钮（删除账号） */
.btn.danger{color:#b42318;border-color:#fecdca;background:#fef3f2}
.btn.danger:hover{background:#fee4e2;border-color:#fda29b}

/* ⭐ 主号星标（多账号的人才有） */
.acct-star{color:#f5a524;font-size:12px;flex:0 0 auto;cursor:default}
.acct-star-btn{background:none;border:0;padding:0 1px;color:#c9cdd4;font-size:12px;
  cursor:pointer;flex:0 0 auto;line-height:1}
.acct-star-btn:hover{color:#f5a524}
.alias-cand-row.on::after{content:'✓';float:right;color:#1a56c4;font-weight:700;
  font-size:13px}
.org-kids b{font-weight:700}
/* 「带 N 人」名单里点名字 → 跳回那一行，跳过去后闪一下，好找 */
.staff-table tbody tr.row-flash td{background:#fff8e1 !important;
  box-shadow:inset 0 0 0 2px #f6c445}
.staff-table tbody tr.row-flash td:last-child{background:#fff8e1 !important}
/* 名单弹窗里的一行 */
#kd-list .kd-row:hover{background:#f4f7fc}
#kd-list .kd-row a{color:#1a56c4}
#kd-list .kd-row a:hover{text-decoration:underline}

/* ⭐ 2026-10-06（第三轮）：归属从"只能看"变"能管理"——
   · 上行「归 XXX」后面加「改」（换上级）
   · 名单每行加「✕ 摘掉」（把人从名下摘出来）
   ⚠️ 两个都是小按钮，别撑高行（跟「带 N 人」一样 `flex:0 0 auto`）。 */
.staff-table td[data-col="org"] .org-up{display:inline-flex;align-items:center;gap:4px;
  flex-wrap:nowrap}
.org-edit{border:0;background:transparent;color:#7a8699;border-radius:5px;
  padding:0 5px;font-size:11px;line-height:1.6;cursor:pointer;font-family:inherit;
  white-space:nowrap;flex:0 0 auto}
.org-edit:hover{background:#eef4ff;color:#1a56c4}
.org-edit.ghost{color:#98a2b3;border:1px dashed #d0d5dd}
.org-edit.ghost:hover{color:#1a56c4;border-color:#a9c2f0;border-style:solid}
/* ⭐ 2026-10-06（第四轮）「✕ 摘掉」—— 老板：「队长所属的这个为什么不能去掉，只能改」。
   跟「改」并排，但用**危险色**（红），一眼区分"换人"和"摘掉"。 */
.org-edit.danger{color:#b42318}
.org-edit.danger:hover{background:#fef3f2;color:#912018}
/* ⭐ 第四轮（问题 6）两级归属之间的「›」分隔符 */
.staff-table td[data-col="org"] .org-sep{color:#b0b7c3;font-size:12px;
  flex:0 0 auto;line-height:1;padding:0 1px}
/* ⭐ 2026-10-06（第五轮）「团队提成」—— 老板：「能不能把这个归属团队的提成
   也在这里设置掉？」「只有管理员才能配置」。
   放在归属格第二行，跟「带 N 人」并排；不是管理员就只显示数字（只读）。 */
.staff-table td[data-col="org"] .org-rate{display:inline-flex;align-items:center;
  gap:4px;font-size:11px;color:#69748b;flex:0 0 auto}
.staff-table td[data-col="org"] .org-rate .org-rate-lb{white-space:nowrap}
.staff-table td[data-col="org"] .org-rate .rate-cell{display:inline-flex;
  align-items:center;gap:2px}
.staff-table td[data-col="org"] .org-rate .rate-cell input{width:48px;
  text-align:right;padding:2px 4px;font-size:11.5px}
.staff-table td[data-col="org"] .org-rate .rate-cell .unit{color:#98a2b3;
  font-size:11.5px}
.staff-table td[data-col="org"] .org-rate .org-rate-ro{color:#3538cd;
  font-weight:500;font-size:11.5px}
.staff-table td[data-col="org"] .org-rate .org-rate-ro.none{color:#b0b7c3;
  font-weight:400}

/* ══ ⭐⭐ 2026-10-06（第七轮）批量操作（勾选 / 批量删除 / 放入分组）═══════
   老板：「有一些账号没用的，我就一次性删除掉，而不是说一个一个删除，好麻烦。」
   ⚠️ 勾选列的宽度必须**钉死**在表头那个 38px（表头里写的是 inline 38px），
      否则列宽拖拽功能（table_resize.js）会把它算成"没设置宽度"再平均分。 */
.staff-table td[data-col="pick"]{text-align:center;vertical-align:middle}
.staff-table td[data-col="pick"] input{width:15px;height:15px;cursor:pointer;
  accent-color:#3538cd;margin:0}
.staff-table th[data-col="pick"] input{width:14px;height:14px;cursor:pointer;
  accent-color:#3538cd;margin:0}

/* 批量操作条：勾了人才冒出来（默认 hidden），不占地方 */
.pl-bar{display:flex;align-items:center;gap:10px;margin:8px 0;
  padding:8px 12px;border-radius:8px;background:#eef4ff;
  border:1px solid #c7d7fe}
.pl-bar[hidden]{display:none}
.pl-bar .pl-count{font-size:13px;color:#3538cd}
.pl-bar .pl-count b{font-size:14px;font-weight:500}
.pl-bar .btn.danger{background:#d92d20;color:#fff;border-color:#d92d20}
.pl-bar .btn.danger:hover{background:#b42318}
/* 勾了「已启用」的行时的说明小字（2026-10-09：那些行只能配权限、不能删） */
.pl-bar .pl-note{font-size:12px;color:#8a5a12;margin-left:4px}

/* ── ⭐ 2026-10-09 配功能权限弹窗（单人 / 批量共用）────────────────── */
.perm-row{display:flex;align-items:center;gap:12px;
  padding:10px 2px;border-bottom:1px solid #eef0f4}
.perm-row:last-child{border-bottom:0}
.perm-meta{flex:1;min-width:0}
.perm-name{font-size:14px;font-weight:500;color:var(--text)}
.perm-desc{font-size:12px;color:var(--muted);margin-top:2px}
.perm-now{font-size:12px;color:#3538cd;margin-top:3px}
.perm-seg{display:flex;flex:0 0 auto;border:1px solid #cfd6de;
  border-radius:7px;overflow:hidden;background:#fff}
.perm-seg .seg-btn{border:0;background:#fff;cursor:pointer;
  padding:6px 14px;font-size:13px;color:#5f5e5a;
  border-right:1px solid #eef0f4;font-family:inherit}
.perm-seg .seg-btn:last-child{border-right:0}
.perm-seg .seg-btn:hover{background:#f4f7fc}
.perm-seg .seg-btn.active{background:#3538cd;color:#fff;font-weight:500}
.perm-seg .seg-btn[data-v="off"].active{background:#d92d20}
.perm-seg .seg-btn[data-v="skip"].active{background:#98a2b3}
/* 「跟组」= 恢复成跟组一样 —— 用一个中性的灰蓝，别跟"开/关"抢视觉 */
.perm-seg .seg-btn[data-v="follow"].active{background:#6b7280;color:#fff}
/* 栏目清单很长（员工端 + 后台 + 找设计师），弹窗里得能滚 */
#perms-body{max-height:62vh;overflow-y:auto;padding-right:4px}

/* 弹窗里的"逐条命运"清单 */
.pl-list{max-height:290px;overflow:auto;border:1px solid #e4e7ec;
  border-radius:8px;padding:4px 8px;background:#fcfcfd}
.pl-row{display:flex;align-items:center;gap:8px;padding:5px 2px;
  border-bottom:1px solid #f2f4f7;font-size:12.5px;line-height:1.5}
.pl-row:last-child{border-bottom:0}
.pl-dot{width:7px;height:7px;border-radius:50%;flex:0 0 auto}
.pl-dot.ok{background:#12b76a}
.pl-dot.warn{background:#f79009}
.pl-row .pl-name{color:#101828;font-weight:500;flex:0 0 auto}
.pl-row .pl-dest{color:#667085;flex:1 1 auto;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ⭐ 第八轮（C 方案·治本）：行内操作改成 fetch 后就地更新，
   不再整页重载 → 也就没有整页 flash 了。这块是统一的结果提示条。 */
.row-toast{margin:8px 0;padding:8px 12px;border-radius:8px;font-size:13px;
  line-height:1.6;border:1px solid #abefc6;background:#ecfdf3;color:#067647}
.row-toast[hidden]{display:none}
/* 行内的 form 已经全去掉，这个选择器留给老缓存页面兜底（别报错） */
.state-form{display:inline}

/* ⭐ 第八轮：企业微信列的内联 style 抽成 class（每行省 ~120 字节 × 100 行） */
/* ⭐⭐ 2026-10-07（第十四轮）：老板「这个企微绑定的这个名字放在后面而不是放在下面，
   否则这个表格有点高了」→ 两行压成**一行**：绿标 + 企微号 + 名字（省略号）。 */
.wx-cell{white-space:nowrap}          /* 三个东西排一行，不换行 */
.wx-on{background:#e7f6ec;color:#059669}
.wx-dot{display:inline-block;width:6px;height:6px;border-radius:50%;margin-right:4px}
.wx-dot.on{background:#059669}
.wx-dot.off{background:#d97706}
.wx-uid{margin-left:5px;font-family:ui-monospace,Consolas,monospace;font-size:12px;
  background:#f2f4f7;padding:1px 5px;border-radius:4px}
/* 企微登记名：跟在企微号后面，太长就省略号（老板「后面省略号即可」） */
.wx-nm-inline{display:inline-block;vertical-align:middle;margin-left:6px;
  max-width:110px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:12px;color:#667085}
.wx-wait{color:#98a2b3;font-size:12px;margin-left:4px}

#kd-list .kd-del{border:0;background:#fef3f2;color:#b42318;border-radius:5px;
  padding:1px 7px;font-size:11px;line-height:1.7;cursor:pointer;font-family:inherit;
  white-space:nowrap}
#kd-list .kd-del:hover{background:#fee4e2;color:#912018}


/* ══ 排行榜的两种模式（2026-09-24 老板：「改成两种：一块一块 / 一行一行，默认一块一块」）══
   两种都渲染，靠外层 data-view 切换 —— 点按钮不用重新请求，秒切。 */
.rank-modes[data-view="cards"] .rank-table{display:none}
.rank-modes[data-view="table"] .rank-cards{display:none}
.rank-tbl td,.rank-tbl th{vertical-align:middle}
.rank-tbl .tag{font-size:11px;padding:1px 6px}
.rank-tbl .cap-flag{font-size:11px;margin-left:4px}
#view-seg .btn{cursor:pointer;user-select:none}


/* ══ 「一块一块 / 一行一行」切换控件（2026-09-24）══
   ⚠️ 特意**不用现有那套按钮类**（.btn / .btn.primary）—— 实测那套组合在这个位置会渲染成
      「白底白字」（量出来的：bg=255,255,255 / color=255,255,255，肉眼看不见）。
      这里自己定义颜色，不依赖任何已有按钮类，避免再被别的规则盖掉。 */
.view-seg{display:inline-flex;border:1px solid #dbe2ec;border-radius:8px;
  overflow:hidden;background:#fff;vertical-align:middle}
.view-seg a{display:inline-flex;align-items:center;height:32px;padding:0 12px;
  font-size:13px;color:#475467;text-decoration:none;cursor:pointer;user-select:none;
  border-left:1px solid #dbe2ec;white-space:nowrap}
.view-seg a:first-child{border-left:0}
.view-seg a:hover{background:#f7f9fc;text-decoration:none}
.view-seg a.on{background:var(--brand);color:#fff;font-weight:600}
.view-seg a.on:hover{background:var(--brand)}


/* ── 接待数据：团队行展开（2026-09-26 老板要「点一下就地看队员」）────────────────
   ⛔ v1.18.57 已废弃：老板第 3 次改说「还是要按客服的节奏，不要变成只有队长一行」，
      所以「队长行可展开」那套（checkbox + label 开合 + 成员子表）整个不用了，
      页面改成「按客服」那张表 + 最前面两列 运营/队长。
      → 下面 `.tm-*` 规则**已无引用**，先留着（万一老板又改回去），
        确认稳定后再删。别再往这里加新样式。 */
.tm-toggle{position:absolute;opacity:0;width:1px;height:1px;margin:0;pointer-events:none}
.tm-label{display:inline-flex;align-items:center;gap:5px;cursor:pointer;
  user-select:none;padding:2px 6px;border-radius:6px;margin-left:-6px}
.tm-label:hover{background:#eef4fd}
.tm-caret{display:inline-block;font-size:10px;color:var(--brand);
  transition:transform .15s ease}
.tm-toggle:checked ~ .tm-label .tm-caret{transform:rotate(90deg)}
.tm-toggle:focus-visible ~ .tm-label{outline:2px solid var(--brand);outline-offset:1px}
/* 折叠态默认隐藏；勾上才显示。⚠️ 用 `+` 相邻兄弟，只影响**本行**那个 tr */
tr.tm-row{display:none}
.tm-toggle:checked ~ .tm-row{display:table-row}
.tm-box{padding:4px 0 10px 26px}
.tm-sub{width:100%;border-collapse:collapse;background:#fafbfd;
  border:1px solid #e3e9f2;border-radius:8px;overflow:hidden}
.tm-sub th{font-size:12px;font-weight:600;color:#5b6b85;text-align:left;
  padding:6px 10px;background:#f2f6fc;border-bottom:1px solid #e3e9f2}
.tm-sub th.num,.tm-sub td.num{text-align:right}
.tm-sub td{padding:5px 10px;border-bottom:1px solid #eef2f8;font-size:13px}
.tm-sub tr:last-child td{border-bottom:0}
.tm-sub tbody tr:hover{background:#eef4fd}
/* ════════════════════════════════════════════════════════════════════════
   视觉精修 v1.18.58 · 接待数据「按团队」：运营层 / 队长层汇总行 + 归属列
   （老板 2026-09-26 拍板 UI 草图 v4 —— 完全照草图样式）
   ⚠️ 一律用末尾覆盖写法，前面的原始规则不动；要回退整段删掉即可。
   ⚠️ 每条改背景色的地方都**成对写了前景色**（开发约定第七节）。
   ════════════════════════════════════════════════════════════════════════ */

/* ── 运营整体行（草图 .op-row）── */
tr.op-row td{background:#eef4ff;font-weight:600;color:#1d2329;
  border-bottom:1px solid #d8e6ff;border-top:2px solid #b8d4f8}
tr.op-row td .sub{font-weight:400;color:#5b7590;font-size:11.5px}
tr.op-row .op-flag{display:inline-block;font-size:10.5px;padding:0 6px;border-radius:8px;
  background:#dbe9ff;color:#1a56c4;margin-left:6px;font-weight:500}

/* ── 队长整体行（草图 .lead-row，整行可点）── */
tr.lead-row td{background:#f7faff;font-weight:600;color:#1d2329;
  border-bottom:1px solid #e3ebf7;border-top:1px solid #cfe0fb;
  cursor:pointer;user-select:none}
tr.lead-row td .sub{font-weight:400;color:#7d8fa3;font-size:11.5px}
tr.lead-row:hover td{background:#eaf3ff}
tr.lead-row .lead-flag{display:inline-block;font-size:10.5px;padding:0 6px;border-radius:8px;
  background:#e6f0ff;color:#3a6ea5;margin-left:6px;font-weight:500}
tr.lead-row .leadname{color:#1a56c4;border-bottom:1px dotted #8fb6ec}
tr.lead-row .chev{display:inline-flex;align-items:center;justify-content:center;
  width:16px;height:16px;margin-right:5px;border-radius:4px;
  background:#dbe9ff;color:#1a56c4;font-size:10px;
  transition:transform .15s;transform:rotate(90deg)}
tr.lead-row.closed .chev{transform:rotate(0deg)}

/* ── 客服行：收起时隐藏 + 左边缩进（草图 .staff-row）── */
tr.staff-row.hidden{display:none}
tr.staff-row td.muted{color:#98a2b3}

/* ── 归属队长 / 归属运营 两列（草图 td.own .pill）── */
th.own{background:#eef2f7}
td.own{background:#fbfcfe}
td.own .pill{display:inline-block;padding:1px 7px;border-radius:9px;font-size:12px;
  background:#f4f6f9;color:#3d4a5c;border:1px solid #e4e8ee}
td.own .pill.lead{background:#eef4ff;color:#1a56c4;border-color:#d8e6ff}
td.own .pill.op{background:#f3f0ff;color:#5b46b8;border-color:#e3ddf8}
td.own .none{color:#b9c0c9;font-size:12px}

/* ── 「全部展开 / 全部收起」工具条（草图 .expandbar）── */
.expandbar{display:flex;align-items:center;gap:9px;margin-top:10px;font-size:12.5px}
.expandbar a{color:var(--brand);cursor:pointer}
.expandbar a:hover{text-decoration:underline}

/* ════════════════════════════════════════════════════════════════════════
   v1.18.59 · 「按团队看数据」可见范围提示（老板 2026-09-26）
   ── 管理员 / 看全部：灰底「全公司」；运营 / 队长：蓝底醒目「你看到的是XX名下的团队」
   ⚠️ 必须显眼 —— 否则老板以为"数据怎么少了"，其实是权限范围。
   ════════════════════════════════════════════════════════════════════════ */
.scope-row{display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  margin-top:10px;padding:9px 13px;border:1px solid var(--line);border-radius:9px;
  background:#f7f9fc;font-size:13px}
.scope-row.locked{background:#eef4ff;border-color:#c8daff}
.scope-row .scope-badge{font-size:11.5px;font-weight:600;padding:2px 9px;border-radius:20px;
  flex:none;white-space:nowrap}
.scope-row .scope-badge.lock{background:#dbe8ff;color:#1f4fc4}
.scope-row .scope-badge.free{background:#eef1f6;color:#5c687e}
.scope-row .scope-val{font-weight:600;color:var(--ink)}
.scope-row.locked .scope-val{color:#1a56c4}
.scope-row .scope-tip{color:var(--muted);font-size:12px}
@media (max-width:760px){
  .scope-row{align-items:flex-start}
  .scope-row .scope-tip{flex-basis:100%}   /* 手机上小字另起一行，别挤在一起 */
}

/* ════════════════════════════════════════════════════════════════════════
   v1.18.61 · 「日志管理 → 网站更新记录」（老板 2026-09-26）
   ── 照 `docs/网站更新记录-样稿-v5.html` 搬过来，只把配色换成系统现有变量。
   ⚠️ 页签类名用 `.audit-tabs`，**不复用 `.tabs`** ——
      style.css 第 93 行已有一个 `.tabs`（分段选择器，配 <label>+<input>），
      同名会用错样式（而且会影响别的页面）。
   ⛔ 卡片间隔（gap:14px + 左边框）是老板三次强调的：不能让版本号分不清归属。
   ════════════════════════════════════════════════════════════════════════ */
.audit-tabs{display:flex;gap:8px;border-bottom:2px solid var(--line);margin:0 0 16px}
.audit-tabs a{padding:8px 15px;font-size:14px;color:var(--muted);
  text-decoration:none;border:1px solid transparent;border-bottom:none;
  border-radius:8px 8px 0 0}
.audit-tabs a:hover{text-decoration:none;background:#f7f9fc}
.audit-tabs a.on{background:#fff;border-color:var(--line);color:var(--brand);
  font-weight:700;margin-bottom:-2px;border-bottom:2px solid #fff}

/* ── 顶部 4 张统计卡 ── */
.up-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:16px}
.up-st{background:#fff;border:1px solid var(--line);border-radius:11px;padding:13px 15px}
.up-st .l{font-size:12px;color:var(--muted);margin-bottom:4px}
.up-st .v{font-size:21px;font-weight:700;letter-spacing:.3px;font-variant-numeric:tabular-nums}
.up-st .v small{font-size:12px;font-weight:400;color:var(--muted);margin-left:4px}
.up-st.hl{background:#eef4ff;border-color:#c8daff}
.up-st.hl .v{color:var(--brand)}
.up-st.warn{background:#fff7e8;border-color:#ffd591}
.up-st.warn .v{color:#8a5a00}
@media (max-width:760px){.up-stats{grid-template-columns:repeat(2,1fr)}}

/* ── 筛选按钮栏 ── */
.up-fbar{display:flex;gap:8px;flex-wrap:wrap;align-items:center;background:#fff;
  border:1px solid var(--line);border-radius:11px;padding:10px 13px;margin-bottom:4px}
.up-fbar .lab{font-size:12.5px;color:var(--muted);margin-right:2px}
.up-fbtn{border:1px solid var(--line);background:#fff;color:#3a4659;border-radius:8px;
  padding:5px 13px;font-size:13px;cursor:pointer;font-family:inherit;
  font-variant-numeric:tabular-nums}
.up-fbtn:hover{border-color:#c8daff;background:#eef4ff}
.up-fbtn.on{background:var(--brand);border-color:var(--brand);color:#fff;font-weight:700}
.up-fbtn b{font-weight:700;opacity:.85}
.up-fbtn.danger.on{background:#8a5a00;border-color:#8a5a00}
.up-empty{display:none;margin:20px 0;padding:26px;text-align:center;background:#fff;
  border:1px dashed var(--line);border-radius:12px;color:var(--muted)}
.up-note{margin:18px 0 0;padding:12px 15px;border-radius:10px;font-size:13px;
  background:#fff7e8;border:1px solid #ffd591;color:#8a5a00;line-height:1.85}
.up-note.ok{background:#eafaf0;border-color:#a8e6c1;color:#0d6b39}
.up-note b{font-weight:700}
.up-note code{background:rgba(255,255,255,.7);border:1px solid rgba(0,0,0,.06);
  border-radius:4px;padding:0 4px;font-size:12px}

/* ── 版本卡片列表 ── */
.up-list{display:flex;flex-direction:column;gap:14px;margin-top:18px}
.up-ver{background:#fff;border:1px solid var(--line);border-left:4px solid #c8daff;
  border-radius:12px;padding:16px 18px}
.up-ver.latest{border-left-color:var(--brand);box-shadow:0 2px 12px rgba(47,124,246,.10)}
.up-ver[data-st="waiting"]{border-left-color:#ffd591}
.up-ver[data-st="unknown"]{border-left-color:var(--line)}
.up-vhead{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.up-seq{font-size:12px;font-weight:700;color:var(--muted);background:#f2f5fa;
  border:1px solid var(--line);border-radius:6px;padding:1px 7px;
  font-variant-numeric:tabular-nums}
.up-vno{font-size:17px;font-weight:700;letter-spacing:.3px;font-variant-numeric:tabular-nums}
.up-badge{font-size:11.5px;font-weight:700;color:#fff;background:var(--brand);
  border-radius:20px;padding:2px 9px}
.up-vdate{font-size:12.5px;color:var(--muted);font-variant-numeric:tabular-nums}
.up-seqday{font-size:12px;font-weight:700;color:#22408a;background:#eef3ff;
  border:1px solid #c8daff;border-radius:20px;padding:2px 10px;
  font-variant-numeric:tabular-nums}
.up-vtimes{margin:9px 0 0;display:flex;gap:8px;flex-wrap:wrap}
.up-t{font-size:12px;background:#f6f8fc;border:1px solid var(--line);border-radius:7px;
  padding:2px 10px;font-variant-numeric:tabular-nums;color:#4a5568}
.up-t b{color:#3a4659;font-weight:700}
.up-t.made{background:#eef3ff;border-color:#c8daff;color:#22408a}
.up-t.made b{color:#22408a}
.up-t.live{background:#eafaf0;border-color:#a8e6c1;color:#0d6b39}
.up-t.live b{color:#0d6b39}
.up-t.dim{color:#a3adbf;background:#fafbfd}
.up-t.wait{background:#fff7e8;border-color:#ffd591;color:#8a5a00}
.up-t.wait b{color:#8a5a00}
.up-stag{font-size:11.5px;font-weight:700;border-radius:20px;padding:2px 9px}
.up-stag.wait{color:#8a5a00;background:#fff7e8;border:1px solid #ffd591}
.up-stag.ok{color:#0d6b39;background:#eafaf0;border:1px solid #a8e6c1}
.up-vsum{font-size:14px;line-height:1.7;margin-top:9px}
.up-vmore{margin-top:8px}
.up-vmore a{font-size:12.5px;color:var(--brand);text-decoration:none;cursor:pointer}
.up-vmore a:hover{text-decoration:underline}
.up-vbody{display:none;margin-top:10px;padding-top:10px;border-top:1px dashed var(--line)}
.up-vbody pre{background:#f7f9fc;border:1px solid var(--line);border-radius:8px;
  padding:11px 13px;font-size:12px;line-height:1.6;white-space:pre-wrap;
  word-break:break-word;max-height:360px;overflow:auto;color:#4a5568;
  font-family:Consolas,Monaco,monospace;margin:0}



/* ═══════════════════════════════════════════════════════════════════
   客服 AI 助手（web/ai_kb.py）
   2026-09-30 精简：只剩两页 ——
     · AI 分析看板（侧边栏形式：左列表 + 右详情 + 客服勾选）
     · 任务日志（最近一次分析的真实日志）
   ⚠️ 只用上面 :root 里已有的变量，不引入第二套设计语言。
   ⚠️ 这里**不要**定义 .page —— 它是 <main class="page"> 的滚动容器语义，
      内层再叫 .page 会被 display:none 命中、整块看不见（踩过一次）。
   ⚠️ 页内 class 一律带 `aib-` 前缀（或 .ac / .as / .tg / .sm 这类短名，
      风险是撞车 —— 加之前先 grep 一下 style.css）。
   ═══════════════════════════════════════════════════════════════════ */

/* ── 看板外壳：固定高度，里面自己滚（不靠整页滚）
   高度 = 100vh − (页脚 ~54 + .page 下内边距 24 + .page::before 18) ── */
.aib{height:calc(100vh - 104px);min-height:520px;display:flex;flex-direction:column;
  background:var(--card);border:1px solid var(--line);border-radius:10px;overflow:hidden}

.aib-top{flex:0 0 auto;border-bottom:1px solid var(--line)}

.aib-hd{display:flex;align-items:center;gap:10px;padding:11px 16px 7px;flex-wrap:wrap}
.aib-hd h1{font-size:17px;margin:0}
.aib-hd .sp{flex:1}
.aib-src{font-size:12px;color:var(--muted)}
.aib-note{font-size:12px;color:var(--muted)}

/* 客服勾选 */
.aib-pick{display:flex;align-items:baseline;gap:9px;padding:0 16px;flex-wrap:wrap}
.pk-t{font-size:13px;font-weight:600}
.pk-s{font-size:12px;color:var(--muted);flex:1}
.pk-o a{margin-left:10px;font-size:12px}
.aib-chips{display:flex;flex-wrap:wrap;gap:7px;padding:8px 16px 9px}

.ac{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--line);
  border-radius:999px;padding:4px 12px 4px 9px;cursor:pointer;background:#fff;
  font-size:13px;color:var(--muted);user-select:none}
.ac:hover{border-color:var(--brand);color:var(--brand)}
.ac .bx{width:14px;height:14px;border:1.5px solid #b8bec7;border-radius:4px;
  display:inline-flex;align-items:center;justify-content:center;font-size:11px;color:#fff}
.ac .n{font-size:11px;color:#a6adb8}
.ac.on{background:#eaf1fe;border-color:var(--brand);color:#1a56c4;font-weight:500}
.ac.on .bx{background:var(--brand);border-color:var(--brand)}
.ac.on .n{color:var(--brand)}
.ac.off{opacity:.62}

/* 统计 + 阶段漏斗（漏斗单独一行 —— 6 个数字 + 8 格塞一行会挤） */
.aib-stats{display:flex;align-items:stretch;padding:0 16px;flex-wrap:wrap}
.as{display:flex;flex-direction:column;justify-content:center;min-width:72px;
  padding:9px 14px 9px 0;margin-right:14px;border-right:1px solid var(--line)}
.as .l{font-size:12px;color:var(--muted)}
.as .n{font-size:18px;font-weight:600;line-height:1.3}
.as.brand .n{color:var(--brand)}
.as.neg .n{color:var(--danger)}
.as.warn .n{color:var(--warn)}
.as.ok .n{color:var(--ok)}
/* ⭐ 超时待回复：0 的时候是灰色的，有超时才变红（别让"0"也是红的，看不出重点） */
.as.ot .l{color:var(--danger)}
.as.ot .n{color:#9aa2ad}
.as.ot.has .n{color:var(--danger)}
.aib-funnel{display:flex;align-items:center;gap:10px;padding:7px 16px 9px;
  border-top:1px solid var(--line)}
.aib-funnel .fr-t{font-size:12px;color:var(--muted);flex:0 0 auto}
.afunnel{display:flex;flex:1;gap:5px;overflow:hidden}
.afn{flex:1 1 0;min-width:0;background:#fafbfd;border:1px solid var(--line);
  border-radius:6px;padding:4px 3px;text-align:center}
.afn .s{font-size:11px;color:var(--muted);white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.afn .v{font-size:15px;font-weight:600;color:var(--brand);line-height:1.25}
.afn.zero .v{color:#c6ccd5;font-weight:400}
.afn.done .v{color:var(--ok)}
.afn.fail .v{color:var(--danger)}

/* 主体：左列表 + 右详情 */
.aib-body{flex:1;min-height:0;display:grid;grid-template-columns:340px 1fr}
.aib-list{overflow-y:auto;padding:9px;border-right:1px solid var(--line);background:#fcfdfe}
.aib-detail{overflow-y:auto;padding:12px 14px 20px}

.aib-item{border:1px solid var(--line);border-radius:8px;padding:8px 10px;margin-bottom:7px;
  cursor:pointer;background:#fff}
.aib-item:hover{border-color:#bcd0f7;background:#fafcff}
.aib-item.on{border-color:var(--brand);background:#eaf1fe;
  box-shadow:0 0 0 1px var(--brand) inset}
/* 超时的会话在列表里也要能一眼扫到（左边一条红边） */
.aib-item.ot{border-left:3px solid var(--danger);padding-left:8px}
.aib-item .r1{display:flex;align-items:center;gap:6px}
.aib-item .nm{font-weight:600;font-size:13px;flex:1;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.aib-item .tm{font-size:11px;color:var(--muted);flex:0 0 auto}
.aib-item .r2{display:flex;align-items:center;gap:5px;margin-top:5px;flex-wrap:wrap}

.tg{font-size:11px;border-radius:4px;padding:1px 6px;white-space:nowrap;
  background:#f2f4f7;color:var(--muted)}
.tg.stage{background:#eaf1fe;color:#1a56c4}
.tg.biz{background:#e8f7f0;color:#0f6b45}
.tg.neg{background:#fdeceb;color:#a33327;font-weight:500}
.tg.bad{background:#fdeceb;color:#a33327;font-weight:500}
.tg.grp{background:#f0eefe;color:#5b46c8}
.tg.pri{background:#eef1f5;color:#4a5560}
.tg.none{background:#f2f4f7;color:#9aa2ad}
.tg.ot{background:var(--danger);color:#fff;font-weight:600}

/* 详情卡片 */
.dcard{background:#fff;border:1px solid var(--line);border-radius:8px;
  margin-bottom:9px;overflow:hidden}
.dcard h3{font-size:13px;font-weight:600;margin:0;padding:8px 13px;background:#fafbfd;
  border-bottom:1px solid var(--line);display:flex;align-items:center;gap:7px}
.dcard h3::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--brand)}
.dcard .cb{padding:11px 13px;font-size:13px;line-height:1.85}
.dcard .cb.pre{white-space:pre-wrap;word-break:break-word}
.dcard.ot{border-color:#f5c9c4;background:#fffafa}
.dcard.ot h3{background:#fdeceb;color:#a33327;border-bottom-color:#f5c9c4}
.dcard.ot h3::before{background:var(--danger)}

.tgrow{display:flex;flex-wrap:wrap;gap:7px}
.btag{font-size:12px;border-radius:5px;padding:3px 10px;background:#eaf1fe;
  color:#1a56c4;font-weight:500}
.btag.biz{background:#e8f7f0;color:#0f6b45}
.btag.gray{background:#f2f4f7;color:#9aa2ad;font-weight:400}
.note{font-size:12px;color:var(--muted);margin-top:8px}
.muted{color:var(--muted)}

.sline{display:block;padding-left:14px;position:relative}
.sline::before{content:"";position:absolute;left:3px;top:9px;width:4px;height:4px;
  border-radius:50%;background:#c6ccd5}

.smrow{display:flex;gap:6px;flex-wrap:wrap}
.sm{font-size:12px;border-radius:4px;padding:2px 8px;background:#f2f4f7;color:var(--muted)}
.sm.ok{background:#e8f7f0;color:#0f6b45}
.sm.bad{background:#fdeceb;color:#a33327}

.sbar{display:flex;height:9px;border-radius:5px;overflow:hidden;background:#eef0f3;
  margin:8px 0 6px}
.sbar i{display:block;height:100%}
.sbar .p{background:#3aa76d}
.sbar .u{background:#cdd2da}
.sbar .g{background:var(--danger)}
.lgd{font-size:12px;color:var(--muted);display:flex;gap:12px;flex-wrap:wrap}
.lgd b{font-weight:600}
.lgd b.bg{color:var(--danger)}

.aib-none{padding:34px 12px;text-align:center;color:var(--muted);font-size:13px}
.aib-none span{font-size:12px;color:#9aa2ad}
.aib-prog{display:block;padding:6px 2px 0;font-size:12px;color:var(--muted)}

/* 空状态 / 任务日志 */
.aib-blank{background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:22px 24px;max-width:760px}
.aib-blank .big{font-size:15px;font-weight:600;margin-bottom:8px}
.aib-blank p{font-size:13px;color:var(--muted);margin:6px 0}
.aib-blank ol{margin:8px 0 8px 20px;font-size:13px;color:var(--muted);line-height:1.9}
.aib-blank .tip{color:var(--text)}
.aib-blank .ops{display:flex;align-items:center;gap:12px;margin-top:14px}
.prog{font-size:12px;color:var(--muted)}

.tl{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:16px 18px}
.tl-head{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.tl-head .sp{flex:1}
.tl-t{font-size:12.5px;color:var(--muted)}
.tl-scope{margin-top:12px;padding:10px 13px;border-radius:8px;background:#f4f8ff;
  border:1px solid #d6e4ff;font-size:13px;line-height:1.8;color:#2b4368}
.tl-scope b{color:#1a56c4}
.tl-log{margin-top:12px;background:#1c1f23;color:#cbd5e1;border-radius:8px;
  padding:11px 13px;font-size:12px;line-height:1.8;max-height:420px;overflow:auto;
  font-family:Consolas,Monaco,monospace;white-space:pre-wrap}

/* 窄屏：并排的收成一列 */
@media (max-width:1000px){
  .aib{height:auto;min-height:0}
  .aib-body{grid-template-columns:1fr}
  .aib-list{max-height:46vh;border-right:none;border-bottom:1px solid var(--line)}
  .afunnel{display:none}
}

/* ── 项目数据明细（2026-10-01）────────────────────────────────────────────
   全部限定在 .rec-* 前缀里，只服务这一页，不碰其他页面。
   一个 .rec-tablewrap 兜住表 —— 72 列时横向滚，表头固定。
   ⚠️ 必须覆盖全局的 `table{width:100%;overflow:hidden}` 和 `th,td{border-right}`，
     否则宽表会被压扁（列挤成一条）。类选择器特异性高于标签选择器，稳。 */
.rec-cards{margin-bottom:16px}
.rec-tabs{display:flex;gap:4px;border-bottom:1px solid var(--line);margin-bottom:12px}
.rec-tabs button{border:0;background:none;padding:9px 16px;font-size:14px;cursor:pointer;
  color:var(--muted);border-bottom:2px solid transparent;font-family:inherit}
.rec-tabs button:hover{color:var(--text)}
.rec-tabs button.on{color:var(--brand);border-bottom-color:var(--brand);font-weight:600}
.rec-toolbar{margin-bottom:8px}
.rec-toolbar .rec-f{font-size:13px;color:var(--muted);display:flex;align-items:center;gap:6px}
.rec-toolbar .rec-chk{cursor:pointer}
.rec-toolbar input[type=date],.rec-toolbar input[type=text]{border:1px solid var(--line);
  border-radius:7px;padding:6px 10px;font-size:13px;font-family:inherit;
  background:var(--card);color:var(--text)}
.rec-toolbar .rec-q{width:200px}
.rec-tip{margin:0 0 10px}
.rec-tablewrap{background:var(--card);border:1px solid var(--line);border-radius:10px;
  overflow:auto;max-height:560px;margin-bottom:10px}
.rec-table{width:auto;min-width:100%;border-collapse:separate;border-spacing:0;
  background:var(--card);border:0;border-radius:0;overflow:visible;margin:0;
  font-size:13px;white-space:nowrap}
.rec-table th,.rec-table td{padding:8px 12px;text-align:left;vertical-align:top;
  border-bottom:1px solid var(--line);border-right:0}
.rec-table th{background:#f7f9fc;position:sticky;top:0;z-index:6;font-weight:600;
  font-size:12.5px;color:#39424e;box-shadow:inset 0 -1px 0 var(--line)}
.rec-table tbody tr:hover{background:#f8fbff}
.rec-table tr.rec-row{cursor:pointer}
.rec-table td.rec-num,.rec-table th.rec-num{text-align:right;
  font-variant-numeric:tabular-nums}
.rec-table .rec-idx{color:#98a2b3;width:46px}
.rec-table th.rec-used::after{content:"";display:inline-block;width:5px;height:5px;
  border-radius:50%;background:var(--brand);margin-left:5px;vertical-align:middle}
.rec-table td.rec-clip{max-width:260px;overflow:hidden;text-overflow:ellipsis}
.rec-table td.rec-empty{text-align:center;color:var(--muted);padding:44px 0;
  font-size:13.5px;white-space:normal}
.rec-legend{display:flex;gap:18px;flex-wrap:wrap;font-size:12.5px;color:var(--muted);
  margin:6px 0 4px}
.rec-legend i{display:inline-block;width:6px;height:6px;border-radius:50%;
  background:var(--brand);margin-right:5px;vertical-align:middle}
.rec-table tr.rec-detail td{background:#fbfcfe;padding:0;white-space:normal}
.rec-table tr.rec-detail:hover td{background:#fbfcfe}
.rec-box{padding:14px 16px;border-left:3px solid var(--brand)}
.rec-box h4{margin:0 0 8px;font-size:13px;color:#2c3540;font-weight:600}
.rec-kv{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));
  gap:4px 20px;font-size:12.5px}
.rec-kv div{display:flex;gap:8px;border-bottom:1px dotted #e8edf4;padding:3px 0}
.rec-kv span:first-child{color:var(--muted);min-width:118px;flex:0 0 auto}
.rec-kv span:last-child{word-break:break-all;white-space:normal}
@media (max-width:760px){
  .rec-toolbar .rec-q{width:100%}
  .rec-kv{grid-template-columns:1fr}
}


/* ===========================================================================
   自绘下拉 · 款1「描边简约」  —— 2026-10-03（老板：这个筛选的框太丑了，给我弄个新的）
   ---------------------------------------------------------------------------
   ⚠️ 为什么必须自绘：原生 <select> 收起态可以调，但**点开后的面板是浏览器
      自己画在页面最上层的，CSS 完全碰不到** —— 所以只调样式永远救不回来。
      这里改成「自己的按钮 + 自己的面板」。
   ⚠️ 命名全部收在 .pksel 下，不碰系统任何已有选择器；
      逻辑在同目录 pksel.js（渐进增强：没跑 JS 时原生 select 照常能用）。
   ⚠️ 改这里记得升 APP_VERSION —— style.css 的 URL 带 ?v=版本号，那是缓存钥匙。
   =========================================================================== */
/* ⚠️ min-width 必须在 CSS 里定（不能在 JS 里写内联 —— 内联会压掉下面按场景的覆盖）。
   112px 是「什么都放不下」的兜底，具体场景（.filters / .filter-bar / td）再放大。 */
.pksel{position:relative;display:inline-block;vertical-align:middle;max-width:100%;
  min-width:112px}
.pksel-hidden{display:none !important}

/* 收起态：白底 + 细边框 + 圆角 —— 跟系统现有输入框同一套（款1 的全部含义就这一条） */
.pksel-trigger{width:100%;height:36px;display:flex;align-items:center;gap:8px;
  padding:0 11px;border-radius:8px;cursor:pointer;font:inherit;font-size:13px;
  text-align:left;color:var(--text);background:#fff;border:1px solid #dbe2ec;
  transition:border-color .15s,box-shadow .15s}
.pksel-trigger:hover{border-color:#c3cdda}
.pksel.pksel-open .pksel-trigger{border-color:var(--brand);
  box-shadow:0 0 0 3px rgba(37,99,235,.12)}
.pksel-val{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pksel-val.pksel-ph{color:#98a2b3}
.pksel-chev{flex:none;color:#667085;transition:transform .18s}
.pksel.pksel-open .pksel-chev{transform:rotate(180deg)}

/* 展开面板：自绘（不顶开下面的内容，浮在上面） */
.pksel-panel{display:none;position:absolute;top:calc(100% + 6px);left:0;right:0;
  z-index:60;min-width:100%;background:#fff;border:1px solid #e6eaf0;
  border-radius:11px;box-shadow:0 14px 34px rgba(16,24,40,.13);padding:6px}
.pksel.pksel-open .pksel-panel{display:block}

.pksel-srch{display:flex;align-items:center;gap:7px;height:32px;padding:0 9px;
  background:#f6f8fb;border:1px solid #e8ecf3;border-radius:8px;margin:1px 1px 6px}
.pksel-srch svg{flex:none}
/* 面板里这个搜索框要"素"：压掉系统全局 input 的边框/内阴影 */
.pksel-srch input{flex:1;min-width:0;border:0 !important;background:transparent !important;
  height:auto !important;padding:0 !important;margin:0 !important;border-radius:0 !important;
  font-size:12.5px !important;color:var(--text) !important;
  box-shadow:none !important;outline:none !important}

.pksel-opts{list-style:none;margin:0;padding:0;max-height:214px;overflow:auto}
.pksel-opt{display:flex;align-items:center;gap:8px;height:34px;padding:0 10px;
  border-radius:7px;font-size:13px;color:var(--text);cursor:pointer;
  transition:background .12s}
.pksel-opt:hover,.pksel-opt.pksel-hl{background:#f4f7fc}
.pksel-opt:focus{outline:none}
.pksel-opt.on{background:#eef4ff;color:#1a56c4;font-weight:600}
.pksel-opt[hidden]{display:none}
.pksel-opt.pksel-off{opacity:.45;cursor:not-allowed}
.pksel-otxt{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pksel-check{margin-left:auto;flex:none;opacity:0;color:#1a56c4}
.pksel-opt.on .pksel-check{opacity:1}
.pksel-empty{padding:14px 10px;text-align:center;font-size:12.5px;color:#98a2b3}

/* 放进「筛选栏」时的尺寸：跟旁边输入框一样高，宽度留够别把长名字截掉 */
.filters .pksel{min-width:132px}
.filter-bar .pksel{min-width:140px}
/* 表格行内（以后要用到的话）：跟系统表格里的 select 同高 */
td .pksel-trigger{height:24px;padding:0 8px;font-size:12.5px;border-radius:6px}
td .pksel-chev{width:10px;height:10px}
@media (max-width:760px){
  .filters .pksel,.filter-bar .pksel{width:100%;min-width:0}
}

/* ===========================================================================
   运行检测（系统体检看板）　2026-10-10 老板
   ---------------------------------------------------------------------------
   老板原话：「能不能给我弄个大概的运行检测。。。。类似这种。。
     稍微有点危险的话就得 弄下。。。否则到时候系统崩溃打不开或者什么的就会很麻烦了」
   → 照他参考的那套「守护脚本」看板做的：总状态条 + 4 张 KPI 卡 + 明细表。

   ⚠️ 类名统一用 `.ops-` 前缀 —— 这页是新加的，别去动系统里已有的通用类
      （`.cards`/`.card`/`.pill` 那些是很多页面共用的，动一个地方可能影响一片）。
   =========================================================================== */

/* ── ① 总状态条 ── */
.ops-banner{display:flex;align-items:center;gap:14px;padding:16px 20px;
  border-radius:12px;border:1px solid var(--line);background:var(--card);
  box-shadow:var(--shadow);margin-bottom:18px}
.ops-banner-ico{font-size:26px;line-height:1;flex:none}
.ops-banner-txt{flex:1;min-width:0}
.ops-banner-txt b{display:block;font-size:17px;margin-bottom:2px}
.ops-banner-txt span{font-size:13px;color:var(--muted)}
.ops-banner-meta{flex:none;text-align:right;font-size:12.5px;color:var(--muted);
  line-height:1.7}
.ops-banner-meta b{color:var(--text)}
/* 三档配色：绿=正常 / 黄=注意 / 红=危险（跟顶部 status 提示一致的观感） */
.ops-banner.ok{background:#eefaf3;border-color:#bfe6d4}
.ops-banner.ok .ops-banner-txt b{color:#0f6b45}
.ops-banner.warn{background:#fffaf0;border-color:#f2dfae}
.ops-banner.warn .ops-banner-txt b{color:#8a5b0a}
.ops-banner.bad{background:#fdeceb;border-color:#f5c9c4}
.ops-banner.bad .ops-banner-txt b{color:#a33327}
.ops-banner.none{background:#f7f8fa;border-style:dashed}

/* ── ② KPI 卡（4 张） ── */
.ops-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:12px;margin-bottom:26px}
.ops-kpi{background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:14px 16px;box-shadow:var(--shadow)}
.ops-kpi-label{font-size:12.5px;color:var(--muted)}
.ops-kpi-value{font-size:26px;font-weight:600;line-height:1.25;
  font-variant-numeric:tabular-nums}
.ops-kpi-hint{font-size:11.5px;color:var(--muted);margin-top:2px}
.ops-kpi.ok .ops-kpi-value{color:var(--ok)}
.ops-kpi.warn .ops-kpi-value{color:var(--warn)}
.ops-kpi.bad .ops-kpi-value{color:var(--danger)}

/* ── ③ 明细表 ── */
/* 「看日志」按钮 —— 只在「服务有没有断过」报警时出现（老板要的"边上加个按钮"） */
.ops-jbtn{margin-left:9px;padding:2px 10px;border-radius:11px;font-size:11.5px;
  border:1px solid var(--brand);background:#fff;color:var(--brand);
  cursor:pointer;font-family:inherit;vertical-align:middle;white-space:nowrap}
.ops-jbtn:hover{background:var(--brand);color:#fff}

/* 日志弹层（点「看日志」后弹出来的那块） */
.ops-modal{position:fixed;inset:0;z-index:9000;display:flex;
  align-items:center;justify-content:center}
.ops-modal[hidden]{display:none}
.ops-modal-mask{position:absolute;inset:0;background:rgba(16,24,40,.45)}
.ops-modal-box{position:relative;width:min(960px,92vw);max-height:84vh;display:flex;
  flex-direction:column;background:#fff;border-radius:12px;overflow:hidden;
  box-shadow:0 12px 40px rgba(16,24,40,.3)}
.ops-modal-head{display:flex;align-items:center;gap:10px;padding:12px 16px;
  border-bottom:1px solid var(--line)}
.ops-modal-head b{font-size:14px}
.ops-modal-sub{font-size:12px;color:var(--muted)}
.ops-modal-x{margin-left:auto;padding:3px 12px;border-radius:14px;font-size:12.5px;
  border:1px solid var(--line);background:#fff;cursor:pointer;font-family:inherit}
.ops-modal-x:hover{border-color:var(--brand);color:var(--brand)}
.ops-modal-log{margin:0;padding:14px 16px;overflow:auto;font-size:11.5px;
  line-height:1.65;font-family:Consolas,Menlo,monospace;color:#334155;
  background:#fbfcfd;white-space:pre;flex:1;min-height:180px}

/* ── 弹层里的「人话版」结论区 ──
   ⭐ 老板 2026-10-15：「大哥 这么多代码。。我哪里看的懂啊。。肯定需要你翻译出来呀」
   ⇒ 这块是给他看的；原始日志收在下面折叠里，给懂技术的人核对。 */
.ops-modal-plain{padding:14px 16px;background:#fffaf0;border-bottom:1px solid #f5e0b8}
.ops-jp-t{font-size:12px;color:var(--muted);margin-bottom:6px}
.ops-jp-what{font-size:16px;font-weight:600;color:#b7791f;margin-bottom:10px;
  line-height:1.5}
.ops-jp-row{display:flex;gap:10px;margin-top:8px;font-size:13px;line-height:1.7}
.ops-jp-row>span{flex:0 0 78px;color:var(--muted);text-align:right}
.ops-jp-row>b{color:var(--text);font-weight:600}
.ops-jp-row>div{flex:1;color:var(--text);min-width:0}

/* 原始日志默认折叠（点「看原始日志」才展开） */
.ops-modal-raw{display:flex;flex-direction:column;flex:1;min-height:0}
.ops-modal-raw>summary{padding:10px 16px;font-size:12.5px;color:var(--muted);
  cursor:pointer;border-bottom:1px solid var(--line);background:#fbfcfd;
  list-style:none;flex:0 0 auto}
.ops-modal-raw>summary::-webkit-details-marker{display:none}
.ops-modal-raw>summary::before{content:'▸ ';color:var(--brand)}
.ops-modal-raw[open]>summary::before{content:'▾ '}
.ops-modal-raw>summary:hover{color:var(--brand)}

.ops-table td,.ops-table th{vertical-align:middle}
/* ⚠️ 状态列要**给够宽度** —— 少了会被截成「❌ 危...」（实测踩过）。
   `th` 上的 width 在 auto 布局里只是"建议"，所以这里显式给 min-width 兜底。 */
.ops-table th:first-child,.ops-table td:first-child{min-width:92px}
.ops-st{white-space:nowrap}
.ops-st-t{margin-left:4px;font-size:12px}
.ops-row.ok .ops-st-t{color:var(--ok)}
.ops-row.warn .ops-st-t{color:var(--warn)}
.ops-row.bad .ops-st-t{color:var(--danger)}
.ops-row.skip{opacity:.72}
.ops-detail{line-height:1.55}
.ops-dim{color:var(--muted);font-size:12.5px}
.ops-ago{font-size:11.5px}
/* 危险行给个淡红底：扫一眼就知道是哪一行要处理（不改表格结构，只加底色） */
.ops-row.bad td{background:#fff7f6}
.ops-row.warn td{background:#fffdf7}
.ops-row.bad:hover td{background:#ffefed}
.ops-row.warn:hover td{background:#fff9ec}

/* ── 空状态 / 说明块 ── */
.ops-empty{background:var(--card);border:1px dashed var(--line);border-radius:10px;
  padding:34px 20px;text-align:center}
.ops-empty p{margin:0 0 6px}
.ops-note{background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:14px 20px;box-shadow:var(--shadow)}
.ops-note ul{margin:0;padding-left:20px}
.ops-note li{margin:7px 0;font-size:13.5px;line-height:1.65;color:#2c3540}

/* ── ⑤ 趋势图（2026-10-11 老板：磁盘空间的上涨情况 / 以前是多少）─────────────
   ⚠️ 全部 `.ops-` 前缀，别碰通用类。
   ⚠️ 折线是**内联 SVG**（不引图表库）→ 这里只需要给描边/填充上色。 */
.ops-trends{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));
  gap:14px;margin-bottom:10px}
.ops-trend{background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:14px 16px 10px;box-shadow:var(--shadow)}
.ops-trend-head{display:flex;align-items:baseline;justify-content:space-between;
  gap:10px;margin-bottom:6px}
.ops-trend-title{font-size:13.5px;font-weight:600;color:var(--text)}
.ops-trend-now{text-align:right;line-height:1.35}
.ops-trend-now b{font-size:19px;font-variant-numeric:tabular-nums}
.ops-trend-delta{display:block;font-size:11.5px}
/* 涨=红（跟"钱/风险"的直觉一致：涨上去是要留意的方向） */
.ops-trend-delta.up{color:var(--danger)}
.ops-trend-delta.down{color:var(--ok)}
.ops-trend-delta.flat{color:var(--muted)}
.ops-spark{width:100%;height:120px;display:block;overflow:visible}
.ops-spark-axis{stroke:var(--line);stroke-width:1}
.ops-spark-area{fill:rgba(59,130,246,.10);stroke:none}
.ops-spark-line{fill:none;stroke:#3b82f6;stroke-width:2.2;
  stroke-linejoin:round;stroke-linecap:round}
.ops-spark-dot{fill:#3b82f6;stroke:#fff;stroke-width:1.4}
.ops-spark-box{position:relative;height:150px;margin-top:4px}
.ops-trend-cmp{display:flex;flex-wrap:wrap;gap:2px 14px;font-size:12px;
  color:var(--muted);margin-top:2px}
.ops-trend-cmp b{font-weight:600;font-variant-numeric:tabular-nums}
.ops-trend-cmp b.up{color:var(--danger)}
.ops-trend-cmp b.down{color:var(--ok)}
.ops-trend-cmp b.flat{color:var(--muted)}
.ops-trend-foot{display:flex;justify-content:space-between;gap:8px;
  font-size:11.5px;color:var(--muted);margin-top:2px}
.ops-trend-note{font-size:12.5px;color:var(--muted);line-height:1.7;margin:8px 0 0}
/* 还攒不够两天时的占位 */
.ops-trend-wait{background:var(--card);border:1px dashed var(--line);border-radius:10px;
  padding:18px 20px;box-shadow:var(--shadow);line-height:1.8;font-size:13.5px}
.ops-trend-wait b{display:block;margin-bottom:3px}
.ops-trend-wait span{color:var(--muted)}

/* ── ⑥ 服务器信息（时间 / 域名 / 运行时长 / 系统）───────────────────────── */
.ops-srv{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  gap:14px;margin-bottom:24px}
.ops-srv-card{background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:14px 16px;box-shadow:var(--shadow)}
.ops-srv-title{font-size:12.5px;color:var(--muted);margin-bottom:5px}
.ops-srv-big{font-size:20px;font-weight:600;line-height:1.3;
  font-variant-numeric:tabular-nums;word-break:break-all}
.ops-srv-big a{color:#2563eb;text-decoration:none}
.ops-srv-big a:hover{text-decoration:underline}
.ops-srv-big-sm{font-size:15px}
.ops-srv-sub{font-size:12px;color:var(--muted);margin-bottom:9px}
.ops-srv-row{display:flex;justify-content:space-between;gap:10px;font-size:12.5px;
  padding:4px 0;border-top:1px dashed var(--line)}
.ops-srv-row span{color:var(--muted);flex:none}
.ops-srv-row b{font-weight:600;text-align:right;word-break:break-all}
.ops-srv-row b.good{color:var(--ok)}
.ops-srv-row b.warn{color:var(--warn)}

/* ── ⑦ 资源占用（CPU / 内存 / 谁在吃）　2026-10-13 老板：
      「加上 那个 内存和 cpu的 情况。。。好知道 什么程序 会耗费比较大的内存或者
        cpu。。到时候 可以 看风险~？」
   ⚠️ 全部 `.ops-` 前缀，别碰通用类。
   ⚠️ 配色沿用上面已有的三档（ok 绿 / warn 黄 / bad 红），保持整页一致。 */
.ops-res-banner{display:flex;align-items:center;gap:14px;padding:14px 20px;
  border:1px solid var(--line);border-radius:10px;background:var(--card);
  box-shadow:var(--shadow);margin-bottom:14px}
.ops-res-ico{font-size:22px;line-height:1;flex:none}
.ops-res-txt{flex:1;min-width:0}
.ops-res-txt b{display:block;font-size:15.5px;margin-bottom:3px}
.ops-res-txt span{display:block;font-size:13px;color:var(--muted);line-height:1.6}
.ops-res-live{flex:none;font-size:11.5px;color:var(--muted);text-align:right}
.ops-res-banner.ok{background:#eefaf3;border-color:#bfe6d4}
.ops-res-banner.ok .ops-res-txt b{color:#0f6b45}
.ops-res-banner.warn{background:#fffaf0;border-color:#f2dfae}
.ops-res-banner.warn .ops-res-txt b{color:#8a5b0a}
.ops-res-banner.bad{background:#fdeceb;border-color:#f5c9c4}
.ops-res-banner.bad .ops-res-txt b{color:#a33327}
.ops-res-banner.none{background:#f7f8fa;border-style:dashed}
.ops-res-banner.none .ops-res-txt b{color:var(--muted)}

.ops-res-bars{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));
  gap:14px;margin-bottom:16px}
.ops-res-card{background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:14px 16px;box-shadow:var(--shadow)}
.ops-res-head{display:flex;align-items:baseline;justify-content:space-between;
  gap:10px;margin-bottom:9px}
.ops-res-name{font-size:13.5px;font-weight:600;color:var(--text)}
.ops-res-val{font-size:19px;font-weight:600;font-variant-numeric:tabular-nums}
.ops-res-val em{font-style:normal;font-size:12px;font-weight:400;color:var(--muted);
  margin-left:3px;font-variant-numeric:normal}
/* 占用条：底槽 + 里面一根按宽度上色的条子 */
.ops-res-bar{height:9px;border-radius:6px;background:#eef1f5;overflow:hidden}
.ops-res-bar i{display:block;height:100%;border-radius:6px;transition:width .3s ease}
.ops-res-bar i.ok{background:var(--ok)}
.ops-res-bar i.warn{background:var(--warn)}
.ops-res-bar i.bad{background:var(--danger)}
.ops-res-foot{display:flex;justify-content:space-between;gap:8px;
  font-size:11.5px;color:var(--muted);margin-top:5px}
.ops-res-row{display:flex;justify-content:space-between;gap:10px;font-size:12.5px;
  padding:4px 0;border-top:1px dashed var(--line);margin-top:8px}
.ops-res-row span{color:var(--muted);flex:none}
.ops-res-row b{font-weight:600;text-align:right;word-break:break-all}
.ops-res-row b.warn{color:var(--warn)}

.ops-res-h3{font-size:14.5px;font-weight:600;margin:18px 0 8px}
.ops-res-procs{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));
  gap:14px;margin-bottom:10px}
.ops-res-ptable{background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:12px 14px;box-shadow:var(--shadow)}
.ops-res-pcap{font-size:12.5px;color:var(--muted);margin-bottom:7px}
/* 排行表比明细表紧凑一些 —— 一屏里要塞两张 */
.ops-ptable{margin:0;font-size:12.5px}
.ops-ptable th,.ops-ptable td{padding:5px 8px}
.ops-ptable td b{font-size:12.5px}
/* CPU 占用很高的行给一点红，扫一眼就知道是谁 */
.ops-ptable tr.ops-hot td{background:#fff7f6}
.ops-ptable tr.ops-hot td b{color:var(--danger)}

@media (max-width:760px){
  .ops-res-banner{flex-wrap:wrap}
  .ops-res-live{text-align:left;width:100%}
}

/* ── ⑧ 资源趋势 + 异常时段　2026-10-13 老板再提：
      「这个占用能不能弄个 趋势线。。。。而不是现在的情况~~~
        而且比如 某一个时间段cpu 占比超过50的时候 是什么程序的 造成的。。
        能显示出来。。。否则一直是显示实时的。。我也不知道前面出了什么情况」

      两块：① 折线图（CPU/内存两条线，超标点标出来）
            ② 异常时段表（一段时间一行，点开看当时谁在吃）
      ⚠️ 图的坐标是**服务端算好的 SVG 用户坐标**，这里只管上色和尺寸。 */

/* 头部：时间窗切换 + 这段的统计 */
.ops-res-trend-head{display:flex;justify-content:space-between;align-items:center;
  flex-wrap:wrap;gap:10px;margin-bottom:10px}
.ops-res-wins{display:flex;gap:4px}
.ops-res-win{padding:4px 12px;border-radius:14px;font-size:12.5px;
  border:1px solid var(--line);color:var(--text);text-decoration:none;
  background:#fff;transition:.15s}
.ops-res-win:hover{border-color:var(--brand);color:var(--brand)}
.ops-res-win.on{background:var(--brand);border-color:var(--brand);color:#fff;font-weight:600}
.ops-res-tstats{font-size:12.5px;color:var(--muted)}
.ops-res-tstats b{color:var(--text)}
/* 这一段负载顶过高线 —— 数儿本身要红，别等老板自己去比 */
.ops-res-tstats b.ops-tstats-hot{color:var(--danger)}

/* ⭐ 2026-10-15 老板：「这个 24小时的这个能不能不要 全屏的。。。。不然看着 不明显。。
   能不能改成半屏的。。。。然后 把其他的 东西移上来一些？」
   ⇒ **左半边放图、右半边放「什么时候出过情况」**。
   · 图变窄 ⇒ 同样的起伏落在更短的横向距离里 ⇒ 坡度更陡、**波动反而更看得清**
     （全宽时线被拉平贴在底部，正是老板说"不明显"的原因）；
   · 原来在图下面的异常记录**提到右边并排** ⇒ 一眼就能对照"图上那段鼓起来的原来是它干的"。 */
/* ⚠️ 右栏高度**写死**跟左边的图一样高（min=max=332px）。
   为什么不用 `align-items:stretch` 自动等高：这栏带 `overflow-y:auto`
   （异常多时要能滚），而带滚动的 grid item 在浏览器里**拉伸行为不统一**，
   实测它就是不跟着长 —— 与其跟浏览器较劲，不如直接钉死高度，效果一样且稳。
   窄屏堆成一列时这栏自然要放开（见下面的媒体查询）。 */
.ops-res-2col{display:grid;grid-template-columns:1fr 1fr;gap:14px;
  align-items:start;margin-bottom:10px}
.ops-res-main{min-width:0}
.ops-res-side{min-width:0;background:#fff;border:1px solid var(--line);
  border-radius:8px;padding:12px 14px;min-height:472px;max-height:472px;
  overflow-y:auto}
.ops-res-side-cap{font-size:12.5px;color:var(--muted);margin:0 0 9px;padding-bottom:7px;
  border-bottom:1px solid #f0f2f4}
/* 右栏里的异常卡 —— 竖着排，比横着一行塞 5 列的表格好读得多 */
.ops-inc-card{border:1px solid var(--line);border-radius:8px;
  padding:9px 11px;margin-bottom:8px;background:#fdfefe}
.ops-inc-card.open{background:#fffdf6;border-color:#f5d9a8}
.ops-inc-top{display:flex;align-items:center;gap:8px;margin-bottom:5px}
.ops-inc-peak{font-size:15px;font-variant-numeric:tabular-nums}
.ops-inc-peak.bad{color:var(--danger)}
.ops-inc-peak.warn{color:#b7791f}
.ops-inc-dur{margin-left:auto;font-size:12px;color:var(--muted)}
.ops-inc-when{font-size:12px;font-variant-numeric:tabular-nums;margin-bottom:3px}
.ops-inc-who{font-size:12.5px;line-height:1.6}
/* 「是哪个脚本」—— 等宽小字，跟程序名区分开（老板要"具体哪个操作"） */
.ops-cmd{font-family:Consolas,Menlo,monospace;font-size:11.5px;
  background:#f1f4f8;color:#4a5568;padding:1px 5px;border-radius:4px;
  border:1px solid #e2e8f0;word-break:break-all}
/* 右栏里的空态：去掉外框（右栏本身已经是白框了，再来一层就成双层框） */
.ops-res-empty-sm{padding:10px 2px;border:0;background:transparent}
/* "确实顶到过线"那种 —— 给个淡橙底，别跟"一切正常"的绿勾混了 */
.ops-res-empty-sm.ops-res-alert{background:#fffaf0;border:1px solid #f5e0b8;
  border-radius:8px;padding:10px 12px}
.ops-res-side-note{margin:6px 0 0;font-size:11.5px;line-height:1.65;color:#9aa0a8}

/* 右栏空态下方的「判定线」说明 —— 老板 2026-10-15 问"前面为什么没提示"，这里当场作答 */
.ops-res-thrbox{margin-top:12px;padding-top:10px;border-top:1px dashed #e6e9ee}
.ops-res-thr-cap{font-size:12px;color:var(--muted);margin-bottom:6px}
.ops-res-thrbox ul{margin:0 0 8px;padding-left:18px;font-size:12.5px;line-height:1.8}
.ops-res-thrbox li b{color:#b7791f}
.ops-res-thr-now{font-size:12.5px;line-height:1.7}
.ops-res-thr-now b{font-variant-numeric:tabular-nums}

/* 折线图画布 */
.ops-res-chartbox{background:#fff;border:1px solid var(--line);border-radius:8px;
  padding:12px 14px}
.ops-res-chart{width:100%;height:260px;display:block;overflow:visible}
/* Chart.js 的画布（2026-10-15 换的）。
   ⛔⛔ **必须有这层固定高度的包裹层**：Chart.js 在 `maintainAspectRatio:false` 时
   按父容器尺寸设 canvas 宽高；canvas 自己没固定高度就会「撑大父容器 → 父容器又撑大 canvas」
   互相撑，图被拉成几千像素高（线上真崩过一次，老板截图就是那个）。
   ⭐ 通用：以后凡是用 Chart.js，都给它包一层 position:relative + 固定 height 的 div。 */
.ops-res-cwrap{position:relative;width:100%;height:200px}
/* 每张图上面的小标题（2026-10-15 拆成两张图后加的）。
   ⭐ 标题里那个 `<b>` 是**最新值**（老板要"已用多少"直接写出来）——
   超过警戒线时变红。 */
.ops-res-chart-t{font-size:12.5px;color:var(--title, #4a5568);font-weight:600;
  margin-bottom:7px}
.ops-res-chart-t b{font-size:15px;font-weight:600;color:var(--text);
  margin-left:8px;font-variant-numeric:tabular-nums}
.ops-res-chart-t b.hot{color:var(--danger)}
.ops-res-chart-t em{font-style:normal;font-weight:400;font-size:11.5px;
  color:#9aa0a8;margin-left:8px}
.ops-res-canvas{display:block}
@media (max-width:900px){.ops-res-cwrap{height:200px}}
@media (max-width:900px){.ops-res-chart{height:200px}}
/* 窄屏：两栏堆成一列（图在上、异常在下），右栏不再限高 */
@media (max-width:1000px){
  .ops-res-2col{grid-template-columns:1fr}
  .ops-res-side{min-height:0;max-height:none}
}

.ops-res-grid{stroke:#eef0f3;stroke-width:1}
.ops-res-grid.base{stroke:#dfe3e8}
.ops-res-ytxt,.ops-res-xtxt{font-size:10.5px;fill:var(--muted);
  font-family:-apple-system,"Segoe UI","Microsoft YaHei",sans-serif}
.ops-res-warnline{stroke:#f0b429;stroke-width:1;stroke-dasharray:5 4;opacity:.85}
.ops-res-warntxt{font-size:10.5px;fill:#b7791f}

.ops-res-ln{fill:none;stroke-width:1.8;stroke-linejoin:round;stroke-linecap:round}
.ops-res-ln.cpu{stroke:#2b6cb0}
/* 2026-10-15：CPU 负载线（替掉原来那条"自开机以来平均"的 CPU 线） */
.ops-res-ln.load{stroke:#2b6cb0}
.ops-res-ln.mem{stroke:#38a169}

.ops-res-dot{stroke:#fff;stroke-width:1.2}
.ops-res-dot.warn{fill:#f0b429}
.ops-res-dot.bad{fill:var(--danger)}

/* 图例 */
.ops-res-legend{display:flex;flex-wrap:wrap;gap:16px;align-items:center;
  margin-top:10px;padding-top:9px;border-top:1px solid #f0f2f4;
  font-size:12.5px;color:var(--muted)}
.ops-res-legend i.sw{display:inline-block;vertical-align:middle;margin-right:5px}
.ops-res-legend i.sw.cpu{width:16px;height:2.5px;background:#2b6cb0;border-radius:2px}
.ops-res-legend i.sw.load{width:16px;height:2.5px;background:#2b6cb0;border-radius:2px}
.ops-res-legend i.sw.mem{width:16px;height:2.5px;background:#38a169;border-radius:2px}
.ops-res-legend i.sw.dot{width:8px;height:8px;border-radius:50%}
.ops-res-legend i.sw.dot.warn{background:#f0b429}
.ops-res-legend i.sw.dot.bad{background:var(--danger)}
.ops-res-legend em{margin-left:auto;font-style:normal;font-size:12px;color:#9aa0a8}

/* 空状态 */
.ops-res-empty{background:#fff;border:1px solid var(--line);border-radius:8px;
  padding:16px 18px;font-size:13.5px;color:var(--text);line-height:1.8}

/* 异常时段表 */
.ops-res-inc{background:#fff;border:1px solid var(--line);border-radius:8px;
  overflow:hidden}
.ops-inctable{margin:0}
.ops-inctable th{font-size:12.5px;color:var(--muted);font-weight:500;
  background:#fcfdfe;padding:9px 12px}
.ops-inctable td{padding:9px 12px;font-size:13px;border-top:1px solid #f4f6f8}
.ops-inctable tr.open td{background:#fffdf6}
.ops-inc-t{white-space:nowrap;font-variant-numeric:tabular-nums}
.ops-live-tag{display:inline-block;margin-left:6px;padding:1px 7px;border-radius:10px;
  font-size:11px;background:#fff4e5;color:#b7791f;border:1px solid #f5d9a8}
.ops-kind{display:inline-block;padding:1px 9px;border-radius:11px;font-size:12px;
  border:1px solid}
.ops-kind.cpu{background:#edf4fc;border-color:#c3d9f2;color:#2b6cb0}
.ops-kind.load{background:#fdf0ef;border-color:#f5cdc8;color:#c53030}
.ops-kind.mem{background:#edf8f1;border-color:#c3e6d0;color:#276749}
.ops-kind.swap{background:#faf1fb;border-color:#e6cdea;color:#805ad5}
.ops-inctable b.ok{color:var(--text)}
.ops-inctable b.warn{color:#b7791f}
.ops-inctable b.bad{color:var(--danger)}

/* 点开看那一刻的排行 */
.ops-inc-det{margin-top:6px}
.ops-inc-det summary{cursor:pointer;font-size:12.5px;color:var(--brand);
  list-style:none}
.ops-inc-det summary::-webkit-details-marker{display:none}
.ops-inc-det summary::before{content:"▸ ";color:var(--muted)}
.ops-inc-det[open] summary::before{content:"▾ "}
.ops-inc-det .ops-ptable{margin-top:7px;border:1px solid var(--line);
  border-radius:6px;overflow:hidden}

@media (max-width:760px){
  .ops-res-trend-head{align-items:flex-start}
  .ops-res-legend em{margin-left:0;width:100%}
  .ops-res-chart{height:170px}
}

@media (max-width:760px){
  .ops-banner{flex-wrap:wrap}
  .ops-banner-meta{text-align:left;width:100%}
}

/* ══════════════════════════════════════════════════════════════════════
   员工端 · 深墨顶部横栏（2026-11-01 老板定）
   「一套系统、一个壳」—— 栏目从左侧竖栏搬到顶部横条，内容满宽。
   ⛔ 接待中心是另一个系统，不在这套壳里，不受影响。
   ⚠️ 只在员工页生效（页面里有 .topbar-staff 时）：
      管理员还是原来的 with-side（左侧 214px），一个字没动。
   ══════════════════════════════════════════════════════════════════════ */
body:has(.topbar-staff) aside.side{display:none !important}
body:has(.topbar-staff) .page{padding-left:26px !important; padding-top:20px !important}

/* ⛔ 必须 fixed —— body 是 flex（老侧栏 + 内容并排），
   横栏作为 flex item 会被拉成一整列铺在左边（实测过，很难看）。 */
.topbar-staff{position:fixed; top:0; left:0; right:0; height:52px; z-index:45;
  background:#1b2430; border-bottom:1px solid rgba(255,255,255,.08); box-sizing:border-box}
/* ⛔⛔ 2026-11-01 老板：「点击接单大厅/我的单之后边上空出这么大一块」
   根因：`body.ms-body` 上写着 `padding-left:184px`（给老左侧图标栏让位），
   栏已经没了，这 184px 就变成一条空白，内容整体往右挤。
   ⇒ 有顶部横栏的页面，body 的左边距一律归零。 */
body:has(.topbar-staff){padding-top:52px; padding-left:0 !important}
.topbar-staff .tb-in{display:flex; align-items:center; gap:10px;
  padding:9px 18px; min-height:52px}
.topbar-staff .tb-brand{display:flex; align-items:center; gap:7px; flex:none}
.topbar-staff .tb-brand i{width:24px; height:24px; border-radius:7px; background:#2f7cf6;
  color:#fff; display:grid; place-items:center; font-size:12px; font-weight:750;
  font-style:normal}
.topbar-staff .tb-brand b{font-size:13px; color:#fff; white-space:nowrap}
.topbar-staff .tb-nav{display:flex; align-items:center; gap:2px; flex:1; min-width:0;
  overflow-x:auto; scrollbar-width:none}
.topbar-staff .tb-nav::-webkit-scrollbar{display:none}
.topbar-staff .tb-nav a{height:30px; padding:0 11px; border-radius:8px; font-size:12.5px;
  color:#c8d2e0; text-decoration:none; display:flex; align-items:center;
  white-space:nowrap; flex:none}
.topbar-staff .tb-nav a:hover{background:rgba(255,255,255,.09); color:#fff}
.topbar-staff .tb-nav a.on{background:rgba(255,255,255,.16); color:#fff; font-weight:700}
.topbar-staff .tb-who{display:flex; align-items:center; gap:7px; flex:none}
.topbar-staff .tb-who .av{width:26px; height:26px; border-radius:50%;
  background:rgba(255,255,255,.16); color:#fff; display:grid; place-items:center;
  font-size:11px; font-weight:750}
.topbar-staff .tb-who .nm{font-size:12px; color:#fff; line-height:1.25}
.topbar-staff .tb-who .nm s{display:block; font-size:10px; color:#8b97a8;
  text-decoration:none}

@media (max-width:640px){
  .topbar-staff .tb-in{padding:8px 10px; gap:6px}
  .topbar-staff .tb-brand b{display:none}
  .topbar-staff .tb-nav a{padding:0 9px; font-size:12px}
  .topbar-staff .tb-who .nm{display:none}
  .topbar-staff{height:48px}
  body:has(.topbar-staff){padding-top:48px}
  body:has(.topbar-staff) .page{padding-left:12px !important; padding-right:12px !important}
}

/* ⭐ 2026-11-02 处理预警弹窗：两个按钮（无异常 / 有异常）
   老板：「弄成两个按钮，一个是无异常忽略按钮，另外一个是有异常，然后下面备注」 */
.hres-btns{display:flex;gap:10px;margin:4px 0 14px}
.hres{flex:1;padding:9px 12px;border-radius:8px;border:1px solid #d8dee8;
  background:#fff;font-size:13.5px;cursor:pointer;color:#475467;text-align:center}
.hres:hover{border-color:#b9c2d0}
.hres.ok.on{background:#ecfdf3;border-color:#12b76a;color:#067647;font-weight:600}
.hres.bad.on{background:#fef3f2;border-color:#f04438;color:#b42318;font-weight:600}
