/* ============================================================
   科睿普 KOREPU · 内部协同 OA  设计系统
   浅色主题 / 本地无依赖 / file:// 可用
   ============================================================ */

:root{
  /* 表面与文字 */
  --bg:#F4F6FA;
  --surface:#FFFFFF;
  --surface-2:#FAFBFD;
  --surface-3:#F1F4F9;
  --border:#E4E8F0;
  --border-strong:#D3DAE6;
  --text:#17202E;
  --text-2:#5A6679;
  --text-3:#8C97A8;

  /* 主色 */
  --primary:#2B5CE6;
  --primary-dark:#1E45B8;
  --primary-soft:#EDF2FE;
  --primary-line:#C7D7FA;

  /* 语义色 */
  --ok:#0E9F6E;
  --ok-soft:#E7F7F0;
  --warn:#C77700;
  --warn-soft:#FFF4E0;
  /* 浅琥珀底上的文字要更深一档：#C77700 压在 #FFF4E0 上只有 3.2:1，
     达不到 4.5:1；#8A5200 在白底 6.4:1、琥珀底 5.9:1，两个底面都够。 */
  --warn-dark:#8A5200;
  --warn-line:#E8B863;
  --danger:#D93B3E;
  --danger-soft:#FDECEC;
  --purple:#7C4DDB;
  --purple-soft:#F2ECFE;
  --cyan:#0E7490;
  --cyan-soft:#E4F5F9;
  --gray-soft:#EFF2F7;

  /* 尺寸 */
  /* ---- 间距标尺（4px 基线）----
     组件级的 padding / margin 只允许 4 / 6 / 8 / 12 / 16 / 20 / 24；
     栅格间隙（.grid/.stack/.toolbar 的 gap 与 mb14）用 14px 半标尺，属于骨架值；
     1~3px 的补偿值只允许出现在边框对位 / 图标微调，禁止用在组件呼吸间距。
     旧值里的奇数（13/15/11/9）已按就近原则收拢，逐处 ±1~2px、不迁移布局。 */
  --side-w:236px;
  --top-h:60px;
  --r-sm:6px;
  --r-md:9px;
  --r-lg:13px;
  --r-xl:18px;

  --shadow-1:0 1px 2px rgba(23,32,46,.05);
  --shadow-2:0 3px 10px rgba(23,32,46,.07);
  --shadow-3:0 14px 40px rgba(23,32,46,.14);

  --ff:"PingFang SC","Hiragino Sans GB","Microsoft YaHei",system-ui,-apple-system,"Segoe UI",sans-serif;
  --ff-num:"SF Mono",ui-monospace,Menlo,Consolas,monospace;
}

*{box-sizing:border-box;margin:0;padding:0}
[hidden]{display:none!important}
html,body{height:100%}
body{
  font-family:var(--ff);
  background:var(--bg);
  color:var(--text);
  font-size:13.5px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
button{font-family:inherit;font-size:inherit;cursor:pointer;border:none;background:none;color:inherit}
input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}
a{color:var(--primary);text-decoration:none}
.ico{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;flex:none}
.ico.sm{width:14px;height:14px}
.ico.lg{width:20px;height:20px}
.mono{font-family:var(--ff-num);font-size:12.5px;letter-spacing:-.2px}
.muted{color:var(--text-3)}
.dim{color:var(--text-2)}
.nowrap{white-space:nowrap}
.right{text-align:right}
.center{text-align:center}
.hidden{display:none!important}

/* ================= 登录门 ================= */
.gate{
  position:fixed;inset:0;z-index:200;
  display:flex;align-items:center;justify-content:center;
  background:
    radial-gradient(900px 480px at 12% -8%,#E4ECFD 0%,transparent 62%),
    radial-gradient(700px 420px at 92% 108%,#E6F6F2 0%,transparent 60%),
    var(--bg);
  padding:24px;
  /* 安全居中（v35.28）：安装向导表单比登录页高得多，.gate-panel 会超过视口高度。
     flex 的 align-items:center 遇到超高内容会「上下对称溢出」——顶部 logo、底部
     说明同时被裁掉且无法滚动（fixed 容器无滚动条）。
     修复：容器允许滚动 + 子项 margin:auto 接管居中——不溢出时效果与 center 一致，
     溢出时 margin 解析为 0、内容从顶部起排，配合容器滚动条可看到全部内容。 */
  overflow-y:auto;
}
/* margin:auto 安全居中：溢出时不裁切，配合 .gate 的 overflow-y:auto 可滚动 */
.gate-card,.gate-panel{margin:auto}
.gate-card{
  width:100%;max-width:660px;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--r-xl);
  box-shadow:var(--shadow-3);padding:30px 30px 22px;
}
.gate-brand{padding-bottom:20px;border-bottom:1px dashed var(--border)}
/* 用 width + max-width + height:auto，窄屏时按比例缩，不会被压扁成异形 */
.gate-logo{display:block;width:253px;max-width:100%;height:auto}
.gate-brand-txt{margin-top:12px}
.gate-brand-txt strong{display:block;font-size:14px;font-weight:600;letter-spacing:.2px}
.gate-brand-txt span{display:block;font-size:12px;color:var(--text-3);margin-top:2px}
/* 公司全称 + 服务热线：取自 db.company，改公司信息后这里跟着变 */
.gate-brand-txt .gate-legal{font-size:11.5px;color:var(--text-3);margin-top:5px;
  padding-top:5px;border-top:1px dashed var(--border)}
.gate-hint{display:flex;align-items:baseline;gap:10px;padding:18px 0 10px}
.gate-hint span:first-child{font-weight:600;font-size:14px}
.gate-hint-sub{font-size:12px;color:var(--text-3)}
.gate-list{display:grid;grid-template-columns:1fr 1fr;gap:9px;max-height:46vh;overflow:auto;padding-right:4px}
.gate-item{
  display:flex;align-items:center;gap:11px;padding:11px 13px;
  border:1px solid var(--border);border-radius:var(--r-md);
  background:var(--surface-2);text-align:left;transition:.16s;
}
.gate-item:hover{border-color:var(--primary-line);background:var(--primary-soft);transform:translateY(-1px);box-shadow:var(--shadow-1)}
.gate-item .avatar{width:34px;height:34px;font-size:13px}
.gate-item-txt{min-width:0}
.gate-item-txt strong{display:block;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gate-item-txt span{display:block;font-size:11.5px;color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gate-foot{margin-top:16px;padding-top:14px;border-top:1px dashed var(--border);font-size:11.5px;color:var(--text-3);line-height:1.7}

/* ================= 布局 ================= */
.app{display:flex;min-height:100vh}
.sidebar{
  width:var(--side-w);flex:none;background:var(--surface);
  border-right:1px solid var(--border);
  display:flex;flex-direction:column;
  position:sticky;top:0;height:100vh;
}
.side-brand{display:flex;align-items:center;padding:0 16px;height:var(--top-h);border-bottom:1px solid var(--border)}
.side-logo{display:block;width:150px;max-width:100%;height:auto}
.side-nav{flex:1;overflow:auto;padding:12px 10px}
.nav-group-title{
  font-size:10.5px;color:var(--text-3);letter-spacing:1.2px;
  padding:14px 8px 6px;text-transform:uppercase;font-weight:600;
}
.nav-group-title:first-child{padding-top:2px}
/* v35.13 导航分组可折叠：标题变可点，右侧给个 caret（默认 ▾ 展开，折起 ▸）。
   默认保持展开 —— e2e / 截图脚本直接按 data-view 找导航项，默认折叠会让它们点不到。 */
.nav-group-fold{display:flex;align-items:center;justify-content:space-between;cursor:pointer;user-select:none}
.nav-group-fold:hover{color:var(--text-2)}
.nav-group-fold .nav-caret{font-size:9px;opacity:.65;letter-spacing:0}
/* v21 站点切换器：导航顶部的站点下拉（加盟商内多站点时出现）。
   视觉上弱于导航项 —— 它是「视野范围」不是「功能入口」。 */
.site-switcher{padding:4px 8px 10px;border-bottom:1px solid var(--border);margin-bottom:6px}
.site-switcher-label{display:block;font-size:10.5px;color:var(--text-3);letter-spacing:1.2px;font-weight:600;margin-bottom:5px;text-transform:uppercase}
.site-select{width:100%;padding:7px 9px;border:1px solid var(--border);border-radius:var(--r-sm);background:var(--surface-3);color:var(--text);font-size:12.5px;font-family:inherit}
.site-select:focus{outline:none;border-color:var(--primary)}
/* .nav-item = 本页的一个视图（button，点了切内容）
   .nav-out  = 另一个站点（a，新标签打开）
   外观共用一套选择器，语义**必须分开** —— 混用同一个 class 会让
   「按 .nav-item 遍历」的逻辑把一个外链点走，整页跳没。 */
.nav-item,
.nav-out{
  display:flex;align-items:center;gap:10px;width:100%;
  padding:9px 14px;border-radius:var(--r-md);
  color:var(--text-2);font-size:13px;text-align:left;
  position:relative;transition:.14s;margin-bottom:1px;
}
.nav-item:hover,.nav-out:hover{background:var(--surface-3);color:var(--text);text-decoration:none}
.nav-out-mark{margin-left:auto;display:flex;align-items:center;opacity:.4}
.nav-out:hover .nav-out-mark{opacity:.85}
.nav-item.active{background:var(--primary-soft);color:var(--primary-dark);font-weight:600}
.nav-item.active::before{
  content:"";position:absolute;left:-14px;top:50%;transform:translateY(-50%);
  width:3px;height:17px;border-radius:0 3px 3px 0;background:var(--primary);
}
.nav-item .nav-count{
  margin-left:auto;font-size:11px;font-weight:600;
  background:var(--danger);color:#fff;border-radius:9px;padding:0 6px;line-height:16px;
}
.nav-item.active .nav-count{background:var(--primary)}
.side-foot{padding:10px 14px 14px;border-top:1px solid var(--border)}
.side-org{display:flex;align-items:center;gap:7px;font-size:11.5px;color:var(--text-3);margin-bottom:8px}
.dot-live{width:6px;height:6px;border-radius:50%;background:var(--ok);box-shadow:0 0 0 3px var(--ok-soft);flex:none}
.side-reset{
  width:100%;padding:6px;border:1px solid var(--border);border-radius:var(--r-sm);
  font-size:11.5px;color:var(--text-3);transition:.14s;
}
.side-reset:hover{border-color:var(--danger);color:var(--danger);background:var(--danger-soft)}

.main{flex:1;min-width:0;display:flex;flex-direction:column}
.topbar{
  height:var(--top-h);flex:none;background:var(--surface);
  border-bottom:1px solid var(--border);
  display:flex;align-items:center;justify-content:space-between;
  padding:0 20px;position:sticky;top:0;z-index:40;
}
.topbar-left{display:flex;align-items:baseline;gap:11px;min-width:0}
.topbar-left h2{font-size:16px;font-weight:650;letter-spacing:.2px}
.crumb{font-size:11.5px;color:var(--text-3)}
.topbar-right{display:flex;align-items:center;gap:12px}
.search-box{
  display:flex;align-items:center;gap:7px;width:250px;
  background:var(--surface-3);border:1px solid transparent;
  border-radius:var(--r-md);padding:6px 10px;transition:.16s;
}
.search-box:focus-within{background:var(--surface);border-color:var(--primary-line);box-shadow:0 0 0 3px var(--primary-soft)}
.search-box .ico{color:var(--text-3)}
.search-box input{flex:1;border:none;background:none;outline:none;font-size:12.5px}
.icon-btn{
  position:relative;width:32px;height:32px;border-radius:var(--r-md);
  display:flex;align-items:center;justify-content:center;
  color:var(--text-2);transition:.14s;
}
.icon-btn:hover{background:var(--surface-3);color:var(--text)}
.badge{
  position:absolute;top:2px;right:1px;min-width:16px;height:16px;
  background:var(--danger);color:#fff;border-radius:8px;
  font-size:10px;font-weight:700;line-height:16px;padding:0 4px;border:2px solid var(--surface);
}
.me{display:flex;align-items:center;gap:9px;padding:4px 9px 4px 4px;border-radius:22px;transition:.14s;cursor:pointer;border:1px solid transparent}
.me:hover{background:var(--surface-3);border-color:var(--border)}
.avatar{
  width:30px;height:30px;border-radius:50%;flex:none;
  display:flex;align-items:center;justify-content:center;
  font-size:12px;font-weight:650;color:#fff;background:var(--primary);
  letter-spacing:.5px;
}
.me-txt strong{display:block;font-size:12.5px;line-height:1.3}
.me-txt span{display:block;font-size:10.5px;color:var(--text-3);line-height:1.3}
.chev{width:13px;height:13px;color:var(--text-3)}
.content{flex:1;padding:24px;min-width:0}

/* ================= 通用件 ================= */
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--shadow-1);min-width:0}
.card-head{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:12px 16px;border-bottom:1px solid var(--border);
}
.card-head h3{font-size:13.5px;font-weight:650}
.card-head .sub{font-size:11.5px;color:var(--text-3);font-weight:400;margin-left:8px}
/* 顶栏同步状态灯（v35.20）：绿=已同步、黄=同步失败、红=会话失效。
   原先同步失败只在内存里留个错误字符串，界面一个字都没有 ——
   于是「以为存上了、服务器一条没收到」这种假成功没人能发现。 */
.sync-chip{display:inline-flex;align-items:center;gap:4px;padding:3px 8px;border-radius:99px;
  font-size:11px;font-weight:600;white-space:nowrap;cursor:pointer;flex:none;border:1px solid transparent}
.sync-chip.ok{color:var(--ok);background:var(--ok-soft)}
.sync-chip.warn{color:var(--warn-dark);background:var(--warn-soft);border-color:var(--warn-line)}
.sync-chip.bad{color:var(--danger);background:var(--danger-soft);border-color:var(--danger)}
.sync-chip:hover{filter:brightness(.97)}

.card-body{padding:16px}
.card-body.tight{padding:0}
/* ---------- 紧凑正文的横向兜底（v35.19 修的对齐 bug）----------
   `.tight` 的语义是「正文不要内边距，让内容自己满幅」：
     表格靠 `.table-wrap` 自带的 `padding:0 16px`，行列表靠每行自带的 16px。
   但只要有行写成 `padding:8px 0`（只给纵向），横向就没有任何内边距 ——
   于是正文从卡片左边缘（0px）起、标题从 16px 起，**整块内容左移 16px**。
   实测全站 68 处、32 个页面都栽在这一个点上（差值一律 -16px，零方差），
   表现就是用户说的「标题与内容不对齐、底部内容整体偏左」。

   这里给直接子元素兜底：横向统一 16px。
     · 已经写了 `padding:X 16px` 的行 → 值不变（不会叠加成 32px）；
     · 只写了 `padding:X 0` 的行   → 补成 `X 16px`；
     · `.table-wrap`（0 16px 6px）→ 左右不变，底部那点留白保留。
   必须用 !important：那些行用的是**行内 style**，普通选择器压不住它。
   这也让「以后新写紧凑列表」不必再记得加横向内边距 —— 默认就是对齐的。
   ------------------------------------------------------------- */
.card-body.tight > *{
  padding-left:16px !important;
  padding-right:16px !important;
}
.card-foot{padding:12px 16px;border-top:1px solid var(--border);background:var(--surface-2);border-radius:0 0 var(--r-lg) var(--r-lg)}

.grid{display:grid;gap:14px;min-width:0}
.grid>*{min-width:0}
.stack{display:grid;grid-template-columns:minmax(0,1fr);gap:14px;min-width:0;align-items:start}
.stack>*{min-width:0}
.g-2{grid-template-columns:repeat(2,minmax(0,1fr))}
.g-3{grid-template-columns:repeat(3,minmax(0,1fr))}
.g-4{grid-template-columns:repeat(4,minmax(0,1fr))}
.g-5{grid-template-columns:repeat(5,minmax(0,1fr))}
.g-main{grid-template-columns:minmax(0,1.62fr) minmax(0,1fr)}
/* PC 管理专用两栏：设置表单的字段是纵向排的，1.62 太宽会把字段拉长；
   1.25:1 让左右更均衡。塌缩跟随 g-main（见媒体查询）。 */
.pc-main{grid-template-columns:minmax(0,1.25fr) minmax(0,1fr)}
.mb14{margin-bottom:14px}
.mb10{margin-bottom:10px}
.row{display:flex;align-items:center;gap:8px}
.row.wrap{flex-wrap:wrap}
.spacer{flex:1}

/* 按钮 */
.btn{
  display:inline-flex;align-items:center;gap:6px;
  padding:6px 12px;border-radius:var(--r-md);font-size:12.5px;font-weight:550;
  border:1px solid var(--border-strong);background:var(--surface);color:var(--text);
  transition:.14s;white-space:nowrap;
}
.btn:hover{border-color:var(--text-3);background:var(--surface-2)}
.btn:disabled{opacity:.42;cursor:not-allowed}
.btn-primary{background:var(--primary);border-color:var(--primary);color:#fff;box-shadow:0 1px 2px rgba(43,92,230,.3)}
.btn-primary:hover{background:var(--primary-dark);border-color:var(--primary-dark)}
.btn-ok{background:var(--ok);border-color:var(--ok);color:#fff}
.btn-ok:hover{filter:brightness(.94)}
.btn-danger{background:var(--surface);border-color:var(--border-strong);color:var(--danger)}
.btn-danger:hover{background:var(--danger-soft);border-color:var(--danger)}
.btn-sm{padding:4px 8px;font-size:11.5px;border-radius:var(--r-sm)}
.btn-ghost{border-color:transparent;background:transparent;color:var(--text-2)}
.btn-ghost:hover{background:var(--surface-3);color:var(--text);border-color:transparent}
.btn-link{padding:2px 4px;border:none;background:none;color:var(--primary);font-size:12.5px;font-weight:500}
.btn-link:hover{text-decoration:underline}

/* 状态药丸 */
.pill{
  display:inline-flex;align-items:center;gap:5px;
  padding:1.5px 8px;border-radius:20px;font-size:11.5px;font-weight:600;
  background:var(--gray-soft);color:var(--text-2);white-space:nowrap;line-height:1.7;
}
.pill .pip{width:5px;height:5px;border-radius:50%;background:currentColor;flex:none}
.pill-blue{background:var(--primary-soft);color:var(--primary-dark)}
.pill-amber{background:var(--warn-soft);color:var(--warn)}
.pill-red{background:var(--danger-soft);color:var(--danger)}
.pill-green{background:var(--ok-soft);color:var(--ok)}
.pill-purple{background:var(--purple-soft);color:var(--purple)}
.pill-cyan{background:var(--cyan-soft);color:var(--cyan)}
.pill-gray{background:var(--gray-soft);color:var(--text-2)}
/* 兼容别名：'danger' 是 CSS 变量名，不是语义色名。数据层已统一用 red，
   这里再留一条，免得外部导入的旧数据带着 danger 时药丸整颗没颜色。 */
.pill-danger{background:var(--danger-soft);color:var(--danger)}
/* 「在保」标识：绿底描边，和状态药丸区分开 ——
   它不是一种状态，是设备此刻仍在质保期内的实时结论（到期自动消失） */
.wbadge{
  display:inline-flex;align-items:center;gap:4px;white-space:nowrap;
  padding:1.5px 8px;border-radius:20px;font-size:11.5px;font-weight:700;
  background:#E8F8F1;color:#0B7A54;border:1px solid #A9E2CB;
}
.wbadge::before{content:"";width:5px;height:5px;border-radius:50%;background:currentColor;flex:none}
/* 「机主凭据已登记」标记：只在有权限的身份下渲染，
   刻意做得比状态药丸轻 —— 它的作用是提醒「这单有密码，别忘清」，不是状态 */
.cred-tag{
  display:inline-flex;align-items:center;gap:3px;white-space:nowrap;
  padding:1.5px 6px;border-radius:var(--r-sm);font-size:11px;
  background:var(--warn-soft);color:var(--warn);border:1px solid #E9CE9A;
}
.cred-tag .ico{stroke:currentColor;stroke-width:2;fill:none}
/* 明文值：加个底纹，让人一眼看出「这是敏感信息，不是普通文本」 */
.cred-val{
  background:var(--warn-soft);padding:1px 6px;border-radius:var(--r-sm);
  letter-spacing:.6px;color:var(--text);
}
/* 80mm 小票底部的提示行（取自「数据与设置 → 单据条款」，与 A4 共用同一段文案） */
.tm-foot-tip{font-size:10px;line-height:1.45;text-align:center;margin-top:6px;color:#000}
.tag{
  display:inline-block;padding:1px 7px;border-radius:var(--r-sm);font-size:11px;
  background:var(--surface-3);color:var(--text-2);border:1px solid var(--border);
}
.tag-src{font-size:10.5px;font-weight:600;letter-spacing:.4px}

/* 表格 */
/* 表格面板的边界（v35.6 全局统一）：表格不再贴死卡片左右边缘，
   左右各留 16px 呼吸 —— 与 .card-body（内容面板）同一套留白，
   于是「表格面板」和「内容面板」的边界视觉一致，不再一边贴边一边留白。
   th 的浅灰底也随之内缩 16px，表头不再顶满卡片宽度（顶满像表格漏出了卡片）。 */
.table-wrap{overflow:auto;border-radius:0 0 var(--r-lg) var(--r-lg);padding:0 16px 6px}
/* 表格首末列与卡片标题对齐（v35.19 修）：
   `.table-wrap` 已经给了 16px 横向内边距，单元格自己还有 14px —— 两者一叠加，
   表头文字就从 30px 起，而卡片标题在 16px，视觉上「表格比标题右移 14px」。
   把首末列的内侧让出去，表格边框仍然贴满、文字与标题同一竖线。
   （右侧同理：末列右内边距归零，数字列右对齐时才不会离卡片边 14px。） */
.table-wrap > table.tb th:first-child,
.table-wrap > table.tb td:first-child{padding-left:0}
.table-wrap > table.tb th:last-child,
.table-wrap > table.tb td:last-child{padding-right:0}
/* `.card-body` 里再套 `.table-wrap` 时，横向内边距**只留一层**（v35.19 修）：
   card-body 已经给了 16px，table-wrap 再来 16px，表头就从 32px 起，
   而卡片标题在 16px —— 整张表右移 16px，正是「标题与内容不对齐」的另一半成因。
   注意：`.card-body.tight` 里反而需要 table-wrap 自带那 16px（tight 自己没有内边距），
   所以那条 `padding-left/right:16px !important` 会盖过这里的 0，两条规则各管一半。 */
.card-body > .table-wrap{padding-left:0;padding-right:0}
/* 内滚表格（带 max-height 的）：底部留渐隐 + 呼吸空隙，滚动中边缘的半行字
   不再紧贴卡外内容（之前看起来像「共 N 笔」压在表格行上）。 */
.table-wrap[style*="max-height"]{
  padding:0 16px 10px;
  -webkit-mask-image:linear-gradient(to bottom,#000 0,#000 calc(100% - 18px),rgba(0,0,0,.25) 100%);
  mask-image:linear-gradient(to bottom,#000 0,#000 calc(100% - 18px),rgba(0,0,0,.25) 100%);
}
table.tb{width:100%;border-collapse:collapse;font-size:12.5px}
table.tb th{
  text-align:left;font-weight:600;color:var(--text-2);font-size:11.5px;
  padding:10px 14px;background:var(--surface-2);border-bottom:1px solid var(--border);
  white-space:nowrap;position:sticky;top:0;z-index:2;
}
table.tb td{padding:10px 14px;border-bottom:1px solid var(--border);vertical-align:middle}
table.tb tbody tr:last-child td{border-bottom:none}
table.tb tbody tr{transition:.1s}
table.tb tbody tr:hover{background:var(--surface-2)}
table.tb tbody tr.clickable{cursor:pointer}
table.tb td.num,table.tb th.num{text-align:right;font-family:var(--ff-num)}
table.tb .strong{font-weight:600}
.empty{padding:44px 20px;text-align:center;color:var(--text-3);font-size:12.5px}
.empty svg{width:34px;height:34px;stroke:var(--border-strong);fill:none;stroke-width:1.4;margin-bottom:8px}

/* 指标卡 */
.stat{padding:16px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--shadow-1);position:relative;overflow:hidden}
.stat-label{font-size:11.5px;color:var(--text-3);display:flex;align-items:center;gap:5px}
.stat-val{font-size:25px;font-weight:680;letter-spacing:-.6px;margin-top:5px;line-height:1.15;font-variant-numeric:tabular-nums}
.stat-val small{font-size:12.5px;font-weight:500;color:var(--text-3);margin-left:3px;letter-spacing:0}
.stat-sub{font-size:11.5px;color:var(--text-3);margin-top:4px;display:flex;align-items:center;gap:5px}
.stat.accent::after{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--primary)}
.stat.accent-ok::after{background:var(--ok)}
.stat.accent-warn::after{background:var(--warn)}
.stat.accent-danger::after{background:var(--danger)}
.trend{font-weight:600}
.trend.up{color:var(--danger)}
.trend.down{color:var(--ok)}

/* 进度条 */
.bar{height:6px;border-radius:4px;background:var(--surface-3);overflow:hidden}
.bar>i{display:block;height:100%;border-radius:4px;background:var(--primary);transition:width .3s}
.bar.ok>i{background:var(--ok)}
.bar.warn>i{background:var(--warn)}
.bar.danger>i{background:var(--danger)}

/* 图表（纯 SVG/CSS） */
.chart-legend{display:flex;flex-wrap:wrap;gap:12px;margin-top:12px}
.chart-legend span{display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--text-2)}
.chart-legend i{width:9px;height:9px;border-radius:3px;flex:none}
.hbars{display:flex;flex-direction:column}
.hbar{display:grid;grid-template-columns:96px 1fr 52px;align-items:center;gap:10px;font-size:12px;padding:7px 0;border-bottom:1px dashed var(--border)}
.hbar:last-child{border-bottom:none}
.hbar .trk{height:18px;background:var(--surface-3);border-radius:5px;overflow:hidden;position:relative}
.hbar .trk>i{display:block;height:100%;border-radius:5px;background:linear-gradient(90deg,#4C7BEE,#2B5CE6)}
.hbar .val{text-align:right;font-family:var(--ff-num);font-size:11.5px;color:var(--text-2)}
/* 空值占位「—」在轨道正中，不再挤到最右 */
.hbar .zero-mark{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--text-3);font-size:11px}

/* 分段控件 */
.seg{display:inline-flex;background:var(--surface-3);border-radius:var(--r-md);padding:2px;gap:2px}
.seg button{padding:4px 12px;border-radius:var(--r-sm);font-size:12px;color:var(--text-2);transition:.14s;white-space:nowrap}
.seg button.on{background:var(--surface);color:var(--text);font-weight:600;box-shadow:var(--shadow-1)}

/* 备件分类树（一级 → 二级） */
.catnode{border-bottom:1px solid var(--border)}
.catnode:last-child{border-bottom:0}
.catnode-head{display:flex;align-items:center;gap:8px;padding:10px 14px;background:var(--surface-2);flex-wrap:wrap}
.catnode-head b{font-size:13px}
.catdot{width:7px;height:7px;border-radius:2px;background:var(--primary);flex:none}
.catsubs{display:flex;flex-direction:column}
.catsub{display:flex;align-items:center;gap:9px;padding:8px 14px 8px 26px;border-top:1px solid var(--border);flex-wrap:wrap}
.catsub:first-child{border-top:0}
.catsub .code{font-size:10.5px;color:var(--text-3);background:var(--surface-3);border-radius:4px;padding:2px 6px;flex:none;letter-spacing:.3px}
.catsub .nm{font-size:12.5px;font-weight:600;min-width:104px}
.catnode-head .spacer,.catsub .spacer{flex:1}

/* 表单 */
/* 键值对照（PC 管理「门店侧会看到什么」等）：dt 定宽、dd 内容对齐同一栅格。
   后台原先没有这个类 —— dt/dd 全靠浏览器默认样式，dd 自带 40px 缩进，
   七行键值挤成一团，是 PC 管理页「乱糟糟」的最大根源。 */
.kv{display:grid;grid-template-columns:84px 1fr;gap:8px 14px;font-size:12.5px;align-items:start}
.kv dt{color:var(--text-3);line-height:1.6}
.kv dd{margin:0;min-width:0;line-height:1.6}

.field{display:flex;flex-direction:column;gap:5px;margin-bottom:12px}
.field>label{font-size:12px;color:var(--text-2);font-weight:550}
.field>label .req{color:var(--danger)}
/* 「选填」标记。原先只定义了 .req（必填）没定义 .opt —— 于是「选填」
   和字段名同一个黑色、同一个字重，看上去和必填一样重。
   全站用了 37 处，属于一直在那种「说不出哪里怪」的状态。 */
.field>label .opt{color:var(--text-3);font-weight:400;font-size:11.5px;margin-left:4px}
/* inp 与 btn 同高：上下 padding 都收 6px，工具栏里「输入框 + 查询按钮」
   不再一高一低（原来 inp 7px / btn 6px，相差 2px，肉眼可见的歪）。 */
.inp,select.inp,textarea.inp{
  width:100%;padding:6px 10px;border:1px solid var(--border-strong);border-radius:var(--r-md);
  background:var(--surface);outline:none;transition:.14s;font-size:12.5px;
}
.inp:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-soft)}
textarea.inp{resize:vertical;min-height:66px;line-height:1.6}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.field-row-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px}
.hint{font-size:11px;color:var(--text-3)}
/* v35.8 面板边界：「表格直贴」的面板里，跟在 table-wrap 后面的提示文字
   是卡片的直接子级 —— 表格有 table-wrap 的 16px 呼吸，它没有就会贴边错位。
   只补左右（card 直接子级的 hint），card-body 里的 hint 不受影响；
   已带 inline padding 的写法（如 padding:0 16px 12px）优先级更高，保持原样。 */
.card>.hint{padding-left:16px;padding-right:16px}
/* 页面底部的口径说明（工资条为什么要有「发放」、真实算例、拆项算法等）。
   这些块落在**整页宽的卡片**里，不像弹窗里的小 hint 那样天然受窄容器约束 ——
   不限宽的话一行能排到 100+ 字，读到行尾就找不着下一行的起点了。
   做法：限住阅读宽度（760px ≈ 55 字/行）+ 浅底 + 一条左色条，
   让它是有归属的「说明块」，而不是漏在卡片角落的注释。
   字号 12px 而不是 hint 的 11px：整段连续文字比零散标签更吃字号。 */
.note-block{
  max-width:760px;margin-top:12px;padding:10px 14px;
  border-left:3px solid var(--primary-line);border-radius:0 var(--r-sm) var(--r-sm) 0;
  background:var(--surface-2);font-size:12px;line-height:1.85;color:var(--text-2);
}
.note-block b{color:var(--text)}

/* 看板 */
.kanban{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(255px,1fr);gap:12px;overflow-x:auto;padding-bottom:6px;align-items:start}
.kcol{background:var(--surface-3);border-radius:var(--r-lg);padding:10px;min-height:190px;border:1px dashed transparent;transition:.16s}
.kcol.drag-over{background:var(--primary-soft);border-color:var(--primary-line)}
.kcol-head{display:flex;align-items:center;justify-content:space-between;padding:0 3px 9px;font-size:12.5px;font-weight:650}
.kcol-head .cnt{font-size:11px;color:var(--text-3);font-weight:600;background:var(--surface);border-radius:9px;padding:0 7px;border:1px solid var(--border)}
.kcard{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);
  padding:10px 11px;margin-bottom:8px;box-shadow:var(--shadow-1);
  cursor:grab;transition:.14s;border-left:3px solid var(--border-strong);
}
.kcard:hover{box-shadow:var(--shadow-2);transform:translateY(-1px);border-color:var(--border-strong)}
.kcard:active{cursor:grabbing}
.kcard.dragging{opacity:.4}
.kcard-top{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:5px}
.kcard-code{font-family:var(--ff-num);font-size:11px;color:var(--text-3)}
.kcard-dev{font-size:13px;font-weight:600;margin-bottom:3px;line-height:1.4}
.kcard-fault{font-size:11.5px;color:var(--text-3);line-height:1.5;margin-bottom:7px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* 客户备注的行内提示（v35.18）：跟着工单走完整条业务流，出现在列表 / 看板 / 作业台。
   与「故障」刻意分开配色 —— 故障是客户说的毛病（灰字），备注是客户提的要求（琥珀底）；
   两者同色同字体的话，扫单的人会把备注当故障的一部分略过去。
   最多两行：备注可以写很长，但它不该把表格行撑成一篇小作文。 */
.rmk-line{display:flex;gap:5px;align-items:flex-start;margin-top:4px;font-size:11px;line-height:1.45;
  color:var(--warn-dark);background:var(--warn-soft);border-radius:4px;padding:2px 6px;text-align:left}
.rmk-line .ico{flex:none;margin-top:2px;opacity:.85}
.rmk-line>span{min-width:0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* 列表里的「内部提醒」行（v35.19）：与 .rmk-line（琥珀 = 客户说的）分开配色，
   这里按提醒类型上色（红=风险、蓝=维修、琥珀=寄送…），色值在 JS 里按类型查表给。
   同样最多两行 —— 一行里塞三条提醒等于没有提醒。 */
.nt-line{display:flex;gap:5px;align-items:flex-start;margin-top:3px;font-size:11px;line-height:1.45;
  border-radius:4px;padding:2px 6px;text-align:left}
.nt-line>span{min-width:0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.nt-line b{font-weight:650}
.kcard-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;padding-top:7px;border-top:1px dashed var(--border)}
.kcard-owner{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--text-2)}
.kcard-owner .avatar{width:19px;height:19px;font-size:9.5px}
.kcard.over{border-left-color:var(--danger)}
.kcard.warn{border-left-color:var(--warn)}
.kcard.ok{border-left-color:var(--ok)}

/* 时间线 */
.timeline{position:relative;padding-left:22px}
.timeline::before{content:"";position:absolute;left:6px;top:6px;bottom:6px;width:1.5px;background:var(--border)}
.tl-item{position:relative;padding-bottom:15px}
.tl-item:last-child{padding-bottom:0}
.tl-item::before{
  content:"";position:absolute;left:-19.5px;top:5px;width:8px;height:8px;border-radius:50%;
  background:var(--surface);border:2px solid var(--border-strong);
}
.tl-item.hot::before{border-color:var(--primary);background:var(--primary-soft)}
.tl-item.ok::before{border-color:var(--ok);background:var(--ok-soft)}
.tl-time{font-size:11px;color:var(--text-3);font-family:var(--ff-num)}
.tl-text{font-size:12.5px;line-height:1.55}
.tl-text b{font-weight:600}

/* 描述列表 */
.dl{display:grid;grid-template-columns:88px 1fr;gap:8px 12px;font-size:12.5px}
.dl dt{color:var(--text-3)}
.dl dd{color:var(--text);word-break:break-all}
.dl dd .mono{font-size:12px}

/* ============================================================
   工单抽屉 · 第一屏组件（v35.19 重排）
   ------------------------------------------------------------
   这三组样式的目标都是同一件事：**把留白收掉、把该抢眼的抢起来**。
   · .kv2  一行两组「标签 值」 —— 原先两个 .dl 各带 88px 标签列并排，
           一行只放得下四个字，剩下全是空的；
   · .rk-* 商家备注 / 内部提醒（通栏、左侧色条、正文 13px 优先可读）；
   · .gate-* 卡点条（缺什么必须比状态更抢眼）。
   ============================================================ */
.kv2{display:grid;grid-template-columns:84px minmax(0,1fr) 84px minmax(0,1fr);
  gap:7px 10px;font-size:12.5px;align-items:baseline}
.kv2 dt{color:var(--text-3);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kv2 dd{color:var(--text);min-width:0;word-break:break-word}
.kv2 dd.strong{font-weight:650}
/* 窄屏（抽屉在 620px 之下）退回单列两组：硬塞四列会把值挤成两个字一行 */
@media (max-width:760px){.kv2{grid-template-columns:76px minmax(0,1fr)}}

/* ---- 两类备注：通栏卡片 ---- */
.rk-card{border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface);
  margin-bottom:12px;overflow:hidden}
.rk-card.rk-merchant{border-left:3px solid var(--warn-line)}
.rk-card.rk-notes{border-left:3px solid var(--primary-line)}
.rk-head{display:flex;align-items:center;gap:6px;padding:8px 12px;background:var(--surface-2);
  border-bottom:1px solid var(--border);font-size:12.5px}
.rk-head .ico{color:var(--text-3);flex:none}
.rk-head b{font-weight:650}
/* 「这是给谁看的」写在标题旁边：备注没有被读取 = 白写，所以必须一眼看到收件人 */
.rk-whom{color:var(--text-3);font-size:11px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rk-head .btn-link{margin-left:auto;flex:none;font-size:11.5px}
.rk-body{padding:9px 12px;font-size:13px;line-height:1.7;white-space:pre-wrap;word-break:break-word}
.rk-body.rk-none{color:var(--text-3);font-size:11.5px;line-height:1.6;white-space:normal}
.rk-foot{padding:5px 12px;border-top:1px dashed var(--border);color:var(--text-3);font-size:10.5px}

/* ---- 内部提醒：按类型分块（不是按时间平铺）---- */
.nt-wrap{padding:9px 12px;display:flex;flex-direction:column;gap:7px}
.nt-block{border-left:3px solid var(--border);border-radius:5px;padding:6px 9px}
.nt-kind{font-size:11px;font-weight:650;display:flex;align-items:baseline;gap:6px;margin-bottom:3px}
.nt-whom{font-weight:400;opacity:.75;font-size:10.5px}
.nt-item{font-size:12.5px;line-height:1.6;padding:3px 0}
.nt-item+.nt-item{border-top:1px dashed rgba(23,32,46,.08)}
.nt-text{word-break:break-word}
.nt-meta{color:var(--text-3);font-size:10.5px;margin-top:1px}

/* ---- 卡点条：缺什么，比状态更抢眼 ---- */
.gate-bar{display:flex;gap:9px;align-items:flex-start;margin-bottom:12px;padding:9px 12px;
  background:var(--danger-soft);border:1px solid var(--danger);border-radius:var(--r-md);color:var(--danger)}
.gate-bar .ico{flex:none;margin-top:1px}
.gb-title{font-weight:650;font-size:12.5px;margin-bottom:4px}
.gb-row{font-size:11.5px;line-height:1.55;display:flex;gap:6px;color:var(--text-2)}
.gb-row b{color:var(--danger);flex:none}
.gb-more{font-size:11px;color:var(--text-3);margin-top:3px}

/* ---------- 组织与人员 · 三个页签 ----------
   这一页是「看组织」的地方，不是填表的地方，所以样式上做三件事：
   ① 用留白和分隔线把「谁在哪个中心」和「这个岗位干什么」分开，不要糊成一片；
   ② 颜色只用来标记中心归属（左侧色条 + 圆点），不用来装饰；
   ③ 可操作的地方（编辑 / 开关）给足点击面积与 hover 反馈。 */
.org-tabs{margin-bottom:14px}
.org-tabs .seg{padding:3px}
.org-tabs .seg button{display:inline-flex;align-items:center;gap:6px;padding:6px 14px;font-size:12.5px}
.org-tabs .seg button svg{width:14px;height:14px}
.org-tabs .seg button.on{color:var(--primary-dark)}

/* 概览条：四个中心 + 人数，一眼看完整个盘子 */
.org-overview{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:14px}
.org-ov{
  display:flex;align-items:center;gap:8px;padding:8px 13px;border:1px solid var(--border);
  border-radius:var(--r-md);background:var(--surface);box-shadow:var(--shadow-1);
}
.org-ov i.dot{width:8px;height:8px;border-radius:3px;background:var(--primary);flex:none}
.org-ov .ov-k{font-size:12.5px;font-weight:600}
.org-ov .ov-v{font-size:12.5px;color:var(--text-3);font-family:var(--ff-num)}
.org-ov[data-center="技术中心"] i.dot{background:var(--ok)}
.org-ov[data-center="运营中心"] i.dot{background:var(--warn)}
.org-ov[data-center="综合管理"] i.dot{background:var(--purple)}
.org-ov[data-center="总经理室"] i.dot{background:var(--danger)}

/* 成员卡 */
.person{
  display:flex;gap:11px;padding:13px;border:1px solid var(--border);border-radius:var(--r-md);
  background:var(--surface);transition:.16s;position:relative;overflow:hidden;
}
.person::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--border-strong);opacity:.5}
.person[data-center="技术中心"]::before{background:var(--ok)}
.person[data-center="运营中心"]::before{background:var(--warn)}
.person[data-center="综合管理"]::before{background:var(--purple)}
.person[data-center="总经理室"]::before{background:var(--danger)}
.person:hover{border-color:var(--primary-line);box-shadow:var(--shadow-2);transform:translateY(-1px)}
.person .avatar{width:38px;height:38px;font-size:14px}
.person-txt{min-width:0;flex:1}
.person-txt strong{font-size:13.5px;display:block;letter-spacing:-.2px}
.person-txt .role{font-size:11.5px;color:var(--primary-dark);font-weight:600;margin:2px 0 4px;display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.person-txt .meta{font-size:11px;color:var(--text-3);line-height:1.65}

/* 组织树 */
.orggrid{display:grid;gap:12px}
.orgcenter{
  border:1px solid var(--border);border-radius:var(--r-lg);padding:0 0 6px;
  background:var(--surface);box-shadow:var(--shadow-1);overflow:hidden;
}
.orgcenter>h4{
  font-size:12.5px;font-weight:650;display:flex;align-items:center;gap:8px;
  padding:11px 13px;margin:0;background:var(--surface-2);border-bottom:1px solid var(--border);
  /* 中心名在上、说明在下（竖排）：允许换行，说明自占一行 */
  flex-wrap:wrap;row-gap:3px;
}
.orgcenter>h4 .cdot{width:8px;height:8px;border-radius:3px;background:var(--primary);flex:none}
/* order 让「N 人在岗」留在第一行右侧，说明排到它后面（即第二行）。
   说明缩进 16px（圆点 8 + 间距 8），与中心名左侧文字对齐。 */
.orgcenter>h4 .cn-desc{
  order:3;flex:1 0 100%;min-width:0;padding-left:16px;box-sizing:border-box;
  font-weight:400;font-size:11.5px;color:var(--text-3);line-height:1.6;
}
.orgcenter>h4 .cn-n{order:2;margin-left:auto;font-size:11px;color:var(--text-2);font-family:var(--ff-num);flex:none}
.orgcenter .org-list{padding:4px 13px 6px}
[data-center="技术中心"] .cdot{background:var(--ok)}
[data-center="运营中心"] .cdot{background:var(--warn)}
[data-center="综合管理"] .cdot{background:var(--purple)}
[data-center="总经理室"] .cdot{background:var(--danger)}
.orgrow{
  display:flex;align-items:center;gap:9px;padding:8px 5px;font-size:12.5px;
  border-bottom:1px dashed var(--border);border-radius:var(--r-sm);transition:.14s;
}
.orgrow:last-child{border-bottom:none}
.orgrow:hover{background:var(--primary-soft)}
.orgrow .avatar{width:26px;height:26px;font-size:10.5px}
.orgrow .t{flex:1;min-width:0}
.orgrow .t b{font-weight:600;display:block;font-size:12.5px;display:flex;align-items:center;gap:5px;flex-wrap:wrap}
.orgrow .t span{font-size:11px;color:var(--text-3)}
.orgrow>svg{opacity:.4}
.orgrow:hover>svg{opacity:.9;color:var(--primary)}

/* 协同说明：横向流程卡，箭头串起来比一串项目符号更像「流程」 */
.flowline{display:flex;flex-wrap:wrap;gap:9px;align-items:stretch}
.flowline .fl{
  flex:1 1 168px;min-width:0;padding:11px 13px;border:1px solid var(--border);
  border-radius:var(--r-md);background:var(--surface-2);position:relative;
}
.flowline .fl::after{
  content:"";position:absolute;right:-9px;top:50%;width:9px;height:1px;background:var(--border-strong);
}
.flowline .fl:last-child::after{display:none}
.flowline .fl b{display:block;font-size:12.5px;margin-bottom:3px}
.flowline .fl span{font-size:11.5px;color:var(--text-2);line-height:1.65}

/* ---------- 岗位职责 ---------- */
/* 人员卡上的职责摘要：只放前两条，多了会把卡片撑成一篇说明书 */
.person-txt .duty-mini{margin-top:7px;font-size:11px;color:var(--text-2);line-height:1.7;
  padding-left:9px;border-left:2px solid var(--border)}
.duty-grid{display:grid;grid-template-columns:1.15fr 1fr;gap:10px 22px;align-items:start}
.duty-label{
  font-size:11.5px;font-weight:650;color:var(--text-2);display:flex;align-items:center;gap:5px;
  margin-bottom:6px;letter-spacing:.2px;
}
.duty-label svg{width:13px;height:13px;color:var(--primary)}
.duty-ol{margin:0 0 0 19px;padding:0;font-size:12px;line-height:1.9;color:var(--text)}
.duty-ol li{margin-bottom:2px;padding-left:2px}
.duty-ol li::marker{color:var(--primary);font-weight:600}
.duty-txt{font-size:11.8px;line-height:1.8;color:var(--text-2);
  padding:8px 11px;background:var(--surface-2);border-radius:var(--r-sm);border-left:2px solid var(--border-strong)}
@media (max-width:1080px){.duty-grid{grid-template-columns:1fr}}

/* 岗位职责卡：两个一行的栅格，一屏能看到更多岗位，不用滚半天 */
.dutycards{display:grid;grid-template-columns:repeat(auto-fill,minmax(430px,1fr));gap:12px}
.dutycard{
  border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);
  box-shadow:var(--shadow-1);overflow:hidden;display:flex;flex-direction:column;
}
/* 新增岗位的卡片位：虚线框 + 居中，跟实体卡片排在一起 —— 让人一眼知道「这里能加」，
   而不是去页签栏右侧找那个离岗位列表很远的按钮 */
.dutycard-add{
  border:2px dashed var(--border);box-shadow:none;background:transparent;
  cursor:pointer;align-items:center;justify-content:center;min-height:96px;text-align:left;
  padding:14px;transition:border-color .15s ease,background .15s ease;
}
.dutycard-add:hover{border-color:var(--primary);background:var(--surface-2)}
.dutycard-add .dc-badge{display:inline-flex;width:28px;height:28px;margin-right:9px;vertical-align:middle}
.dutycard-add .dc-t{display:inline-block;vertical-align:middle}
.dutycard-head{
  display:flex;align-items:center;gap:9px;padding:11px 13px;background:var(--surface-2);
  border-bottom:1px solid var(--border);
}
.dutycard-head .dc-badge{
  width:30px;height:30px;border-radius:var(--r-sm);flex:none;display:flex;align-items:center;
  justify-content:center;font-size:11px;font-weight:700;color:#fff;background:var(--primary);
}
[data-center="技术中心"].dutycard .dc-badge{background:var(--ok)}
[data-center="运营中心"].dutycard .dc-badge{background:var(--warn)}
[data-center="综合管理"].dutycard .dc-badge{background:var(--purple)}
[data-center="总经理室"].dutycard .dc-badge{background:var(--danger)}
.dutycard-head .dc-t{min-width:0;flex:1}
.dutycard-head .dc-t b{display:block;font-size:13px;letter-spacing:-.2px}
.dutycard-head .dc-t span{font-size:11px;color:var(--text-3)}
.dutycard-body{padding:12px 13px;display:flex;flex-direction:column;gap:10px;flex:1}
.duty-staff{display:flex;flex-wrap:wrap;gap:5px}
.duty-actions{margin-top:auto;display:flex;gap:8px;align-items:center}

/* ---------- 岗位权限 ---------- */
/* 岗位列表（左栏）：一眼看出哪个岗位被改过、权限给了多少 */
.rolelist{display:flex;flex-direction:column;gap:6px;max-height:68vh;overflow:auto;padding-right:2px}
.roleitem{
  display:block;width:100%;text-align:left;padding:10px 12px;border:1px solid var(--border);
  border-radius:var(--r-md);background:var(--surface);transition:.14s;position:relative;overflow:hidden;
}
.roleitem::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:transparent;transition:.14s}
.roleitem:hover{border-color:var(--primary-line);box-shadow:var(--shadow-1)}
.roleitem.on{border-color:var(--primary);background:var(--primary-soft);box-shadow:var(--shadow-1)}
.roleitem.on::before{background:var(--primary)}
.roleitem b{font-size:12.5px}
.ri-sub{font-size:11px;color:var(--text-3);margin-top:1px}
.ri-cnt{font-size:10.5px;color:var(--text-3);display:flex;align-items:baseline;gap:3px;margin-top:4px}
.ri-cnt b{font-family:var(--ff-num);font-size:11.5px;color:var(--text-2)}
.ri-cnt .zero{color:var(--danger)}
.permbar{height:5px;border-radius:3px;background:var(--surface-3);margin:7px 0 0;overflow:hidden}
.permbar i{display:block;height:100%;background:linear-gradient(90deg,#4C7BEE,#2B5CE6);border-radius:3px;transition:width .2s}
.roleitem.on .permbar{background:#DCE5FB}

/* 权限分组：标题做成区块头，计数做成胶囊 */
.permgroup{border:1px solid var(--border);border-radius:var(--r-lg);margin-bottom:12px;overflow:hidden;background:var(--surface)}
.permgroup-head{
  display:flex;align-items:center;gap:9px;padding:10px 13px;background:var(--surface-2);
  border-bottom:1px solid var(--border);font-size:12.5px;
}
.permgroup-head svg{width:15px;height:15px;color:var(--primary)}
.permgroup-head b{letter-spacing:-.1px}
.permgroup-head .pg-desc{font-size:11px;color:var(--text-3);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.permgroup-head .pg-n{
  margin-left:auto;flex:none;font-family:var(--ff-num);font-size:11px;color:var(--primary-dark);
  background:var(--primary-soft);border-radius:999px;padding:1px 9px;
}
.permgroup-head .pg-n.zero{background:var(--surface-3);color:var(--text-3)}
/* 组内两列：宽度够就并排，窄屏自动回落到一列。
   一行一个开关铺满整幅会拉出大片空白，读一行要横扫一千多像素。 */
.permgroup-body{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:3px 8px;padding:6px}

/* 权限行：开关样式的复选框（还是 <input type=checkbox>，事件仍走 change，
   只是把原生方框画成了拨杆 —— 一行文字很长，方框太容易被忽略） */
.permrow{
  display:flex;align-items:flex-start;gap:10px;padding:8px 10px;
  border-radius:var(--r-md);cursor:pointer;transition:.12s;
}
.permrow:hover{background:var(--surface-2)}
.permrow.on{background:var(--primary-soft)}
.permrow.on:hover{background:#E4EBFD}
.permrow.locked{cursor:not-allowed;opacity:.66}
.permrow.locked:hover{background:transparent}
.permrow input[type=checkbox]{
  order:2;flex:none;appearance:none;-webkit-appearance:none;width:34px;height:19px;
  border-radius:999px;background:var(--border-strong);position:relative;cursor:pointer;
  transition:background .18s;margin-left:auto;margin-top:1px;
}
.permrow input[type=checkbox]::after{
  content:"";position:absolute;top:2px;left:2px;width:15px;height:15px;border-radius:50%;
  background:#fff;box-shadow:0 1px 2px rgba(23,32,46,.28);transition:transform .18s;
}
.permrow input[type=checkbox]:checked{background:var(--primary)}
.permrow input[type=checkbox]:checked::after{transform:translateX(15px)}
.permrow input[type=checkbox]:disabled{cursor:not-allowed;opacity:.5}
.permrow input[type=checkbox]:focus-visible{outline:2px solid var(--primary-line);outline-offset:2px}
.permrow .pm-txt{order:1;flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.permrow .pm-title{display:flex;align-items:baseline;gap:7px;flex-wrap:wrap}
.permrow .pm-title b{font-size:12.5px;font-weight:600}
/* 权限代码跟在标签后面（原来甩在最右端，中间隔着一整片空白），
   缩小为一枚浅底小签 —— 要跟文档对照时能找到，平时又不抢视线。 */
.permrow .pm-key{
  font-size:10px;line-height:1.7;color:var(--text-3);background:var(--surface-3);
  border-radius:4px;padding:0 5px;flex:none;
}
.permrow.on .pm-key{background:#fff;color:var(--primary-dark)}
.permrow .pm-hint{font-size:11px;color:var(--text-3);line-height:1.55}
.permrow.locked .pm-key{background:transparent}

/* 对照矩阵：只读，勾用实心圆点而不是符号，扫视时不易看串行 */
.perm-matrix th.center,.perm-matrix td.center{text-align:center}
.perm-matrix th{position:sticky;top:0;z-index:2}
.perm-matrix tr.grp td{background:var(--surface-3);font-weight:650;font-size:11.5px;color:var(--text-2);letter-spacing:.3px}
.perm-matrix tbody tr:hover td{background:var(--primary-soft)}
.perm-matrix .mk{display:inline-block;min-width:16px;color:var(--border-strong)}
.perm-matrix .mk.on{color:var(--primary);font-weight:700}

/* 权限页左侧窄栏 + 右侧编辑区的固定栅格（宽屏时右栏更宽，读数不挤） */
.perm-layout{display:grid;grid-template-columns:248px minmax(0,1fr);gap:14px;align-items:start}
@media (max-width:1180px){.perm-layout{grid-template-columns:1fr}}

/* ---------- 工程师分类 · 系数解读 ----------
   系数本身只是个乘数（×1.25 是几倍？），团队看不懂。
   所以每张等级卡里现场把「基准费率 → 实际费率」乘一遍，并给一个工时的钱的例子。 */
.grade-note{
  background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-md);
  padding:9px 11px;margin-bottom:10px;
}
.gn-head{font-size:11px;color:var(--text-3);line-height:1.65}
.gn-head b{
  font-family:var(--ff-num);font-size:11.5px;color:var(--primary-dark);
  background:var(--primary-soft);border-radius:4px;padding:1px 5px;
}
.gn-list{list-style:none;margin:7px 0 0;display:flex;flex-direction:column;gap:3px}
.gn-list li{display:flex;align-items:baseline;gap:8px;font-size:11.5px;color:var(--text-2);min-width:0}
.gn-list li>span:first-child{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gn-list b{font-family:var(--ff-num);font-size:11.5px;color:var(--text);flex:none}
.gn-list b i{font-style:normal;color:var(--text-3);font-weight:400;margin:0 3px}
.gn-list .gn-eff{color:var(--primary-dark)}
.gn-demo{border-top:1px dashed var(--border);margin-top:8px;padding-top:7px;font-size:11.5px;color:var(--text-2);line-height:1.6}
.gn-demo b{font-family:var(--ff-num);color:var(--ok)}
.grade-none{background:transparent;border-style:dashed;color:var(--text-3)}

/* ---------- 结算台账 · 自动汇总 ----------
   汇总块的信息密度比明细高（一行一个期间），所以：
   ① 口径条单独一块底色，先把「这是谁的范围、口径日是哪天」钉住，避免看成两份不同的账；
   ② 图表给一层浅底，和表格分开；
   ③ 合计行走表尾并把上边框加粗 —— 一眼知道哪里是底线。 */
.ledger-toolbar{gap:10px}
.ledger-range{
  display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--text-2);
  background:var(--surface-2);border:1px solid var(--border);border-radius:999px;padding:4px 12px;
}
.ledger-range svg{width:13px;height:13px;color:var(--primary)}
.ledger-scope{
  display:flex;align-items:flex-start;gap:8px;font-size:11.5px;color:var(--text-2);
  line-height:1.6;
  background:var(--primary-soft);border:1px solid var(--primary-line);border-radius:var(--r-md);
  padding:9px 12px;margin-bottom:12px;
}
/* 图标和文字永远同一行：文字在 span 里自然换行，icon 不被 wrap 挤到单独一行 */
.ledger-scope > span{flex:1;min-width:0}
.ledger-scope svg{width:13px;height:13px;color:var(--primary);flex:none;margin-top:3px}
.ledger-scope b{color:var(--text)}
.ledger-scope .muted{color:var(--text-3)}
/* 表头里的小字限定词（如「未回款 · 含未完工」）：
   列名必须一眼可辨，但限定条件又不能省 —— 于是主名正常排、限定词缩一号压在其下。
   一个词在两页指两件事，比漏一个字段严重得多，所以宁可表头多一行小字。 */
th .th-note,.th-note{
  display:block;font-weight:400;font-size:10px;line-height:1.35;
  color:var(--text-3);letter-spacing:0;white-space:nowrap;
}
.ledger-chart{
  background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-md);
  padding:12px 14px;margin-bottom:12px;
}
.ledger-chart .hbar{grid-template-columns:66px 1fr 64px}
/* 灰底轨道限制宽度：不贴满整行，右侧留出呼吸空间 */
.ledger-chart .hbar .trk{max-width:520px}
.ledger-tb tfoot td{
  background:var(--surface-3);border-top:2px solid var(--border-strong);
  font-weight:600;padding-top:10px;padding-bottom:10px;
}
.ledger-tb tr.is-empty td{color:var(--text-3)}
.ledger-tb tr.is-empty td.num{font-weight:400}
.ledger-tb .lbar{
  display:inline-block;width:74px;height:7px;border-radius:4px;overflow:hidden;
  background:var(--surface-3);vertical-align:middle;
}
.ledger-tb .lbar i{display:block;height:100%;border-radius:4px;background:linear-gradient(90deg,#4C7BEE,#2B5CE6)}
.ledger-tb tr.is-empty .lbar i{background:var(--border)}

/* 空数据行：一个期间 / 一个分组里一张单都没有时，整行合并成一格说清楚。
   以前这里排的是「0 ¥0 ¥0 — —」，读者要自己从一串零里推断「哦本期没有单」，
   看着还像表格坏了。 */
.tb td.empty-row,
.ledger-tb td.empty-row{
  color:var(--text-3);font-size:12px;padding-top:9px;padding-bottom:9px;
}
.tb td.empty-row svg,
.ledger-tb td.empty-row svg{
  width:14px;height:14px;stroke:var(--text-3);fill:none;stroke-width:1.5;
  vertical-align:-2px;margin-right:6px;
}

/* 占位：「这里没有值」的两种说法 —— 数值列用弱化短横（会计表格惯例），
   该给人话的地方用浅灰小字（未指派 / 未登记 / 未设库位）。 */
.ph-dash{color:var(--text-3)}
.ph-none{color:var(--text-3);font-size:11.5px}


/* 抽屉 */
.drawer-mask{position:fixed;inset:0;background:rgba(23,32,46,.32);z-index:90;animation:fade .18s ease}
.drawer{
  position:fixed;top:0;right:0;bottom:0;width:min(620px,94vw);background:var(--surface);
  z-index:91;display:flex;flex-direction:column;box-shadow:var(--shadow-3);animation:slide .24s cubic-bezier(.22,1,.36,1);
}
@keyframes slide{from{transform:translateX(30px);opacity:.4}to{transform:none;opacity:1}}
@keyframes fade{from{opacity:0}to{opacity:1}}
@keyframes pop{from{transform:translateY(10px) scale(.985);opacity:0}to{transform:none;opacity:1}}
.drawer-head,.modal-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 16px;border-bottom:1px solid var(--border);flex:none}
.drawer-head h3,.modal-head h3{font-size:14.5px;font-weight:650}
.drawer-body{flex:1;overflow:auto;padding:16px}
.drawer-foot{padding:12px 16px;border-top:1px solid var(--border);background:var(--surface-2);display:flex;gap:8px;flex-wrap:wrap;flex:none}

/* 弹窗 */
.modal-mask{position:fixed;inset:0;background:rgba(23,32,46,.34);z-index:100;display:flex;align-items:center;justify-content:center;padding:20px}
.modal{
  width:100%;max-width:560px;max-height:88vh;background:var(--surface);
  border-radius:var(--r-xl);box-shadow:var(--shadow-3);display:flex;flex-direction:column;animation:pop .2s ease;
}
.modal.wide{max-width:760px}
.modal-body{flex:1;overflow:auto;padding:16px}
.modal-foot{padding:12px 16px;border-top:1px solid var(--border);background:var(--surface-2);display:flex;justify-content:flex-end;gap:8px;border-radius:0 0 var(--r-xl) var(--r-xl);flex:none}

/* 下拉菜单 */
.menu{
  position:fixed;z-index:120;background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-md);box-shadow:var(--shadow-3);padding:5px;min-width:190px;animation:pop .14s ease;
  max-height:70vh;overflow:auto;
}
.menu button{display:flex;align-items:center;gap:9px;width:100%;padding:7px 9px;border-radius:var(--r-sm);font-size:12.5px;text-align:left;transition:.12s}
.menu button:hover{background:var(--surface-3)}
.menu .sep{height:1px;background:var(--border);margin:5px 2px}
.menu .menu-title{font-size:10.5px;color:var(--text-3);padding:6px 9px 4px;letter-spacing:.6px}
.menu .avatar{width:26px;height:26px;font-size:10.5px}
.menu button .mt{min-width:0;text-align:left}
.menu button .mt strong{display:block;font-size:12.5px;font-weight:600}
.menu button .mt span{display:block;font-size:10.5px;color:var(--text-3)}
.menu button.on{background:var(--primary-soft)}
.menu button.on .mt strong{color:var(--primary-dark)}
/* 菜单里的用途说明（目前用于管理员的「快捷切换身份」）：
   比 menu-title 再轻一档，读得到但不抢岗位名 */
.menu .menu-note{padding:0 9px 6px;font-size:10.5px;color:var(--text-3);line-height:1.55}

/* 提示条 */
.notice{display:flex;gap:10px;padding:11px 13px;border-radius:var(--r-md);font-size:12.5px;line-height:1.6;border:1px solid}
.notice-warn{background:var(--warn-soft);border-color:#F5DEB4;color:#7A4A00}
.notice-info{background:var(--primary-soft);border-color:var(--primary-line);color:var(--primary-dark)}
.notice-danger{background:var(--danger-soft);border-color:#F6CFD0;color:#8F1F21}
.notice .ico{margin-top:2px;flex:none}

/* Toast */
.toast-wrap{position:fixed;top:16px;left:50%;transform:translateX(-50%);z-index:300;display:flex;flex-direction:column;gap:8px;align-items:center;pointer-events:none}
.toast{
  display:flex;align-items:center;gap:9px;padding:9px 15px;border-radius:22px;
  background:#1E2735;color:#fff;font-size:12.5px;box-shadow:var(--shadow-3);
  animation:pop .2s ease;max-width:70vw;
}
.toast.ok{background:#0E6E4E}
.toast.err{background:#9E2629}
.toast .ico{stroke-width:2.2}

/* 工具条 */
.toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:14px}
.toolbar .inp{width:auto;min-width:140px}
.toolbar select.inp{min-width:120px}

/* 滚动条 */
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-thumb{background:#D2D9E4;border-radius:5px;border:2px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:#B6C0D0;background-clip:content-box}
::-webkit-scrollbar-track{background:transparent}

@media (max-width:1180px){
  .g-4,.g-5{grid-template-columns:repeat(2,minmax(0,1fr))}
  .g-main,.g-3,.pc-main{grid-template-columns:1fr}
}
@media (max-width:820px){
  .sidebar{position:fixed;left:-100%;z-index:60;transition:.2s}
  .sidebar.open{left:0;box-shadow:var(--shadow-3)}
  .search-box{width:150px}
  .me-txt{display:none}
  .g-2{grid-template-columns:1fr}
}

/* ============================================================
   质保标签 & 质保流转说明
   ============================================================ */
.wtag{display:inline-flex;align-items:baseline;font-size:11px;line-height:1.55;padding:1.5px 7px;
  border-radius:99px;white-space:nowrap;font-weight:500;border:1px solid transparent}
.wtag b{font-weight:600;margin-right:4px}
.wtag-green{background:var(--ok-soft);color:var(--ok);border-color:#BFE8D6}
.wtag-blue{background:var(--primary-soft);color:var(--primary);border-color:var(--primary-line)}
.wtag-purple{background:var(--purple-soft);color:var(--purple);border-color:#DCCCFB}
.wtag-amber{background:var(--warn-soft);color:var(--warn);border-color:#F3D8A6}
.wtag-gray{background:var(--gray-soft);color:var(--text-3);border-color:#DCE2EC}

/* ---------- 维修班组（多工程师协同）----------
   列表里只露主修的脸，协同折成「+N」；详情与打印件才铺开写全 */
.crew-cell{flex-wrap:nowrap;overflow:hidden}
.crew-cell .avatar{width:21px;height:21px;font-size:10px;flex:none}
.crew-role{display:inline-block;margin-left:5px;font-size:10px;color:var(--primary);
  background:var(--primary-soft);border:1px solid var(--primary-line);border-radius:99px;padding:0 5px;line-height:1.5}
.crew-more{display:inline-flex;align-items:center;justify-content:center;flex:none;
  min-width:19px;height:19px;padding:0 5px;border-radius:99px;margin-left:5px;
  background:var(--surface-3);border:1px solid var(--border);color:var(--text-2);
  font-size:10.5px;font-weight:600;cursor:help}
.kcard-owner .crew-more{height:17px;min-width:17px;font-size:10px}

/* 收件 / 交付：列表里的「寄入 › 寄出」两字简写 + 待回填红点 */
.lg-cell{display:inline-flex;align-items:center;gap:1px;font-size:11.5px;color:var(--text-2);
  white-space:nowrap;cursor:help}
.lg-arrow{color:var(--text-3);margin:0 3px;font-size:11px}
.lg-dot{width:6px;height:6px;border-radius:50%;background:var(--danger);flex:none;
  margin-left:3px;vertical-align:middle;box-shadow:0 0 0 2px rgba(217,59,62,.16)}

.warranty-flow{display:flex;flex-direction:column;gap:7px;font-size:12px;color:var(--text-2);
  background:var(--surface-3);border-radius:var(--r-md);padding:10px 12px;line-height:1.55}
.wf-row{display:flex;gap:8px;align-items:flex-start}
.wf-row>b{display:inline-flex;width:17px;height:17px;border-radius:50%;background:var(--primary);
  color:#fff;font-size:10.5px;align-items:center;justify-content:center;flex:none;margin-top:1px}
.wf-row>span{min-width:0}

/* ============================================================
   打印票据：维修服务单（A4）/ 取机小票（80mm）
   预览用同一份 DOM，靠 @media print 切到纸面
   ============================================================ */
.print-area{display:none}

.modal.print-modal{max-width:940px;width:940px}
.print-preview{background:#E9ECF2;border-radius:var(--r-md);padding:14px;max-height:62vh;overflow:auto}
.print-preview .receipt{box-shadow:0 2px 14px rgba(23,32,46,.16)}

.receipt{background:#fff;color:#111;font-size:12px;line-height:1.5}
.receipt .mono{font-family:var(--ff-num)}
.receipt .muted{color:#8A8F98}
.receipt .strong{font-weight:600}

/* ---------- A4 维修服务单 ---------- */
.rc-a4{width:210mm;padding:10mm 9mm;margin:0 auto;box-sizing:border-box}

.rc-head{display:flex;justify-content:space-between;align-items:flex-start;
  border-bottom:2px solid #111;padding-bottom:5px;gap:16px}
/* 打印用黑白版 logo（彩打也是纯黑，黑白机不会把蓝色弧线印成一片灰） */
.rc-brand{display:flex;flex-direction:column;gap:2px}
.rc-logo{display:block;width:46mm;height:auto}
.rc-brand-sub{font-size:9.5px;color:#666}
.rc-title{text-align:right}
.rc-title-cn{font-size:18px;font-weight:700;letter-spacing:5px}
.rc-title-en{font-size:9px;letter-spacing:2px;color:#777}
.rc-copy{display:inline-block;margin-top:4px;font-size:10px;border:1px solid #111;padding:0 6px;border-radius:2px}

.rc-meta{display:flex;flex-wrap:wrap;border-bottom:1px solid #DDD;padding:3px 0 2px}
.rc-meta .rc-kv{margin-right:20px}

.rc-kv{display:flex;gap:5px;padding:1.8px 0;font-size:11.5px;align-items:baseline}
.rc-k{color:#6B7280;flex:none;min-width:58px}
.rc-v{color:#111;min-width:0}

.rc-block{border:1px solid #DDD;border-radius:3px;margin-top:5px;overflow:hidden}
.rc-block-h{background:#F2F3F5;padding:3.5px 8px;font-size:11px;font-weight:700;
  letter-spacing:1.1px;color:#333;border-bottom:1px solid #DDD}
.rc-block>.rc-kv{padding:2.4px 8px}
.rc-cols{display:flex}
.rc-col{flex:1;padding:5px 8px;min-width:0}
.rc-col+.rc-col{border-left:1px solid #DDD}
.rc-col-h{font-size:10px;color:#6B7280;margin-bottom:2px;font-weight:600;letter-spacing:.4px}
.rc-fault-txt{font-size:11.5px;color:#111;line-height:1.5}
.rc-dots{border-bottom:1px dotted #AAA;color:#8A8F98;display:inline-block;min-width:110px}

/* 并排版式：把两个矮块左右拼接，省纵向空间（苹果售后工单同款做法） */
.rc-duo{display:grid;grid-template-columns:1fr 1fr;gap:5px;margin-top:5px;align-items:stretch}
.rc-duo>*{margin-top:0!important;height:100%}

.rc-tb{width:100%;border-collapse:collapse;font-size:11px}
.rc-tb th{background:#F7F8FA;border-bottom:1px solid #DDD;padding:4px 7px;text-align:left;
  font-weight:600;color:#444;font-size:10.5px;white-space:nowrap}
.rc-tb td{border-bottom:1px solid #EEEEEE;padding:4.5px 7px;vertical-align:top}
.rc-tb tr:last-child td{border-bottom:none}
.rc-tb .c{text-align:center}
.rc-tb .n{text-align:right}
/* 票据里的 .mono 只表示「等宽数字」，不是「放大一号」。
   它自带 12.5px 且直接落在单元格上，会把 .rc-lg-detail 的 10px、
   .tight 的 10.5px、.dense 的 9.5px 一起顶回去 —— 行高跟着从 15px 涨到
   19px，A4 一页就少装一半的行，明细表溢出到第二页。字号由所在的那张表
   决定，所以票据里的 .mono 一律跟表走。 */
.receipt .rc-tb .mono{font-size:inherit}
.rc-empty{padding:7px;color:#8A8F98;font-size:11px;text-align:center}
/* 空期间的合并格：比正常内容弱一档，但**不加大内边距** ——
   打印件一行的高度直接决定一页能装多少行，这里绝不能比普通行高。 */
.rc-tb .rc-quiet-cell{color:#8A8F98}

.rc-warranty{border-color:#111;border-width:1.5px}
.rc-warranty>.rc-block-h{background:#111;color:#fff;border-bottom-color:#111}
.rc-warranty-top{display:flex;justify-content:space-between;gap:16px;
  padding:7px 9px;border-bottom:1px dashed #CCC}
.rc-warranty-big{display:flex;flex-direction:column;min-width:0}
.rc-warranty-big .lbl{font-size:10px;color:#6B7280}
.rc-warranty-big .num{font-size:20px;font-weight:700;line-height:1.14;letter-spacing:-.5px}
.rc-warranty-big .sub{font-size:10.5px;color:#555}
.rc-warranty-side{text-align:right;font-size:10.5px;color:#6B7280;flex:none}
.rc-warranty-side b{display:block;color:#111;font-size:11.5px;margin-bottom:3px}
.rc-warranty-list{margin:0;padding:5px 9px 4px 24px;font-size:10.5px;color:#222}
.rc-warranty-list li{margin-bottom:1px}
.rc-note{padding:0 9px 6px;font-size:10.5px;color:#6B7280;line-height:1.5}
.rc-note+.rc-note{padding-top:0}

.rc-fee-box{padding:6px 9px}
.rc-fee{font-size:17px}
.rc-red{color:#C1272D}
.rc-green{color:#0E7A55}

.rc-sign{display:flex;gap:22px;padding:7px 9px 9px}
.rc-sign-cell{flex:1;min-width:0}
/* 左右两列同构：标题行 → 说明行 → 签字行 → 日期行，四行对齐即视觉对称 */
.rc-sign-label{font-size:10.5px;color:#111;font-weight:600;margin-bottom:2px}
.rc-sign-note{font-size:9.5px;color:#6B7280}
.rc-sign-name{font-size:11px;color:#111;margin-top:8px}
.rc-sign-date{font-size:10px;color:#6B7280;margin-top:6px}

.rc-terms ol{margin:0;padding:6px 9px 6px 21px;font-size:10px;color:#555;line-height:1.48;
  columns:2;column-gap:18px;column-fill:balance}
.rc-terms li{margin-bottom:1.5px;break-inside:avoid}

.rc-tail{display:flex;gap:14px;align-items:flex-end;margin-top:5px;
  border-top:1px solid #DDD;padding-top:5px}
.rc-barcode{width:190px;flex:none}
.rc-tail-right{flex:1;font-size:10px;color:#6B7280;text-align:right;line-height:1.5;min-width:0}
.rc-tail-id{font-family:var(--ff-num);color:#111;font-weight:600}
.rc-tail-tip{color:#8A8F98}

/* 部件 ≥5 件时自动切紧凑排版，仍保一张 A4 */
.rc-warranty-inline{padding:5px 9px 6px;font-size:10.5px;color:#222;line-height:1.55}
.rc-warranty-inline b{font-weight:600}
.rc-a4.dense .rc-block{margin-top:4px}
.rc-a4.dense .rc-kv{font-size:10.5px;padding:1.2px 0}
.rc-a4.dense .rc-block>.rc-kv{padding:1.6px 8px}
.rc-a4.dense .rc-col{padding:3.5px 8px}
/* 部件表是 dense 档里最占地方的一块（6 件 + 内部联的 来源/单位成本/毛利好 三列），
   字号收到 9.5px（和这一档其它文字一致）、行内留白再收一点。
   实测这是「6 件 + 内部联」能不能收进一张 A4 的决定性一项。 */
.rc-a4.dense .rc-tb{font-size:9.5px}
.rc-a4.dense .rc-tb th{font-size:9.5px;padding:3px 6px}
.rc-a4.dense .rc-tb td{font-size:9.5px;padding:2px 6px}
.rc-a4.dense .rc-fault-txt{font-size:10.5px;line-height:1.35}
.rc-a4.dense .rc-warranty-top{padding:5px 8px}
.rc-a4.dense .rc-warranty-inline{font-size:9.5px;padding:4px 8px 5px;line-height:1.45}
.rc-a4.dense .rc-note{font-size:9.5px;padding:0 8px 4px;line-height:1.4}
.rc-a4.dense .rc-terms ol{font-size:9.5px;line-height:1.4;padding:5px 8px 5px 19px;column-gap:16px}
.rc-a4.dense .rc-duo{gap:4px;margin-top:4px}
.rc-a4.dense .rc-head{padding-bottom:4px}
.rc-a4.dense .rc-sign{padding:5px 8px 6px}

/* 内部联专用的更紧段间距：**只收留白，不动字号**。
   内部联比客户联多印两行（备件成本 / 本单毛利、机主凭据），实测正好把 A4
   顶到第二页。每处只收 1—3px，单看几乎看不出来，合起来能把那 20 来像素省回来。
   放在 .dense 之后：两档叠加时（部件多 + 内部联）以这里的留白为准，
   字号仍由 .dense 负责。 */
.rc-a4.tight .rc-block{margin-top:2px}
.rc-a4.tight .rc-block-h{padding:2.5px 8px}
.rc-a4.tight .rc-block>.rc-kv{padding:2px 8px}
.rc-a4.tight .rc-col{padding:4px 8px}
.rc-a4.tight .rc-tb td{padding:3.6px 7px}
.rc-a4.tight .rc-warranty-top{padding:5.5px 9px}
.rc-a4.tight .rc-warranty-list{padding:4px 9px 3px 24px}
.rc-a4.tight .rc-fee-box{padding:5px 9px}
.rc-a4.tight .rc-terms ol{padding:5px 9px 5px 21px}
.rc-a4.tight .rc-duo{gap:4px;margin-top:2px}
.rc-a4.tight .rc-sign{padding:6px 9px 7px}
.rc-a4.tight .rc-tail{margin-top:3px;padding-top:3px}

/* ---------- 80mm 热敏取机小票 ---------- */
.rc-tm{width:80mm;padding:6mm 4mm;margin:0 auto;box-sizing:border-box;color:#000;font-size:11.5px;line-height:1.52}
.tm-center{text-align:center}
.tm-logo{display:block;width:48mm;height:auto;margin:0 auto 2px}
.tm-sub{font-size:11px;letter-spacing:2px}
.tm-sub2{font-size:10px}
.tm-hr{border-top:1px dashed #000;margin:5px 0}
.tm-kv{display:flex;justify-content:space-between;gap:8px}
.tm-kv>span{color:#333;flex:none}
.tm-kv>b{font-weight:600;text-align:right;word-break:break-all}
.tm-kv-big>b{font-size:15px}
.tm-sec{font-weight:700;margin:3px 0 2px}
.tm-item{margin-bottom:3px}
.tm-item-n{font-weight:600}
.tm-item-m{font-size:10.5px;color:#333;padding-left:11px}
.tm-warranty{text-align:center;padding:3px 0}
.tm-warranty-big{font-size:16px;font-weight:700}
.tm-warranty-sub{font-size:10.5px}
.tm-warranty-tip{font-size:9.5px;color:#333;line-height:1.5;margin-top:4px;text-align:left}
.tm-sign{font-size:11px;margin-top:6px}
.tm-barcode{margin:8px 0 4px}
.tm-foot{font-size:9.5px;color:#333;text-align:center;line-height:1.5}

/* ---------- 新单强提醒：铃铛角标 / 弹窗卡片 / 提醒面板 ---------- */
.icon-btn.bell.has-new{color:var(--danger)}
.icon-btn.bell.has-new::after{
  content:"";position:absolute;inset:3px;border-radius:var(--r-md);
  border:2px solid var(--danger);animation:bellPulse 1.7s ease-out infinite;
}
@keyframes bellPulse{0%{transform:scale(.84);opacity:.6}70%{transform:scale(1.08);opacity:0}100%{opacity:0}}

.alert-layer{position:fixed;top:14px;right:16px;z-index:320;display:flex;flex-direction:column;gap:10px;width:356px;pointer-events:none}
.alert-card{
  pointer-events:auto;display:flex;gap:11px;align-items:flex-start;
  background:var(--surface);border:1px solid var(--border);border-left:4px solid var(--primary);
  border-radius:var(--r-md);box-shadow:var(--shadow-3);padding:13px 14px;
  animation:alertIn .26s cubic-bezier(.2,.9,.3,1.15);
}
.alert-card.urgent{border-left-color:var(--danger)}
.alert-card>.ico{color:var(--primary);margin-top:1px;width:18px;height:18px}
.alert-card.urgent>.ico{color:var(--danger)}
.alert-card .ac-txt{flex:1;min-width:0}
.ac-title{font-size:12.5px;font-weight:700;display:flex;align-items:center;gap:6px}
.ac-urgent{background:var(--danger);color:#fff;font-size:10px;font-weight:700;padding:1px 6px;border-radius:8px}
.ac-sub{font-size:12.5px;margin-top:4px}
.ac-by{font-size:11px;color:var(--text-3);margin-top:3px}
.ac-act{display:flex;flex-direction:column;gap:6px;flex:none}
@keyframes alertIn{from{opacity:0;transform:translateX(26px) scale(.97)}to{opacity:1;transform:none}}

.menu.menu-nt{padding:0;min-width:332px;max-width:356px;overflow:hidden}
.nt-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 13px;border-bottom:1px solid var(--border);font-size:12.5px}
.nt-count{display:inline-block;margin-left:7px;background:var(--danger);color:#fff;font-size:10.5px;font-weight:700;border-radius:9px;padding:1px 7px;vertical-align:1px}
.nt-list{max-height:326px;overflow:auto}
.nt-item{display:flex;gap:9px;width:100%;text-align:left;padding:10px 13px;border-bottom:1px solid var(--border);border-radius:0;align-items:flex-start}
.nt-item:hover{background:var(--surface-3)}
.nt-item .nt-dot{width:7px;height:7px;border-radius:50%;background:var(--border-strong);margin-top:5px;flex:none}
.nt-item.un .nt-dot{background:var(--danger);box-shadow:0 0 0 3px var(--danger-soft)}
.nt-txt{flex:1;min-width:0}
.nt-top{display:flex;align-items:center;gap:6px;font-size:12.5px}
.nt-time{margin-left:auto;font-size:10.5px;color:var(--text-3)}
.nt-sub{display:block;font-size:11.5px;color:var(--text-2);margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nt-by{display:block;font-size:10.5px;color:var(--text-3);margin-top:2px}
.nt-empty{padding:22px 15px;text-align:center;font-size:12px;color:var(--text-2);line-height:1.75}
.nt-foot{display:flex;gap:6px;padding:9px 11px;border-top:1px solid var(--border);background:var(--surface-2);flex-wrap:wrap}
.nt-tip{padding:9px 12px 11px;font-size:10.5px;color:var(--text-3);line-height:1.65;background:var(--surface-2);border-top:1px solid var(--border)}

/* 建单弹窗里「＋ 新建客户」贴着标签右侧 */
.field>label .btn-link{float:right;font-size:11.5px;padding:0 2px;line-height:1.5}

/* 打印件上的串号：全部印出来，过长折行不溢出版心 */
.rc-v.rc-imei{word-break:break-all}
.rc-imei-n{margin-left:6px;color:#555;font-size:10.5px}

/* ---------- 表单辅助：单行字段与维度多选 ---------- */
.field-row-1{display:grid;grid-template-columns:1fr;gap:12px}
/* 规则里的「适用品类 / 等级」这类多选：勾「全部」= 不限制，
   与 store 的 normScopeList 一致（含 '*' 时其余勾选会被收敛掉）。 */
.chk-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:2px 10px;
  border:1px solid var(--border);border-radius:var(--r-md);padding:8px 11px;background:var(--surface-2)}
.chk-grid .chk{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-2);
  padding:2px 0;cursor:pointer;min-width:0}
.chk-grid .chk input{flex:none;margin:0}
.chk-grid .chk span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chk-grid .chk.all span{font-weight:600;color:var(--text)}

/* ---------- A4 员工工资条 ----------
   一条一页：员工拿到的是一张能裁下来的薪酬凭证，不能跟别人的挤在一起。
   行距比维修单松一档（要让人看清每一项），所以不套 .tight / .dense 两档压缩。 */
.rc-ps{font-size:11.5px}
/* 票据内的右对齐类是 .n / .c；工资条这边写的是 .num / .center，这里补一条，
   免得金额跟项目名一样左对齐、看串行。 */
.rc-ps .num{text-align:right;font-family:var(--ff-num)}
.rc-ps .center{text-align:center}
.rc-tb.rc-ps-info td{padding:5px 8px;vertical-align:middle}
.rc-ps-k{color:#6B7280;white-space:nowrap;background:#FAFBFC;width:1%}
.rc-ps-cols{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin-top:9px;align-items:start}
.rc-ps-items tfoot td{border-top:1.5px solid #111;border-bottom:none;padding:5px 8px;font-weight:600}
.rc-ps-net{display:flex;justify-content:space-between;align-items:baseline;
  margin-top:10px;padding:8px 11px;border:1.5px solid #111;border-radius:2px}
.rc-ps-net-label{font-size:11px;font-weight:600;letter-spacing:1px}
.rc-ps-net-val{font-family:var(--ff-num);font-size:21px;font-weight:700;letter-spacing:-.5px}
.rc-ps-sec{margin:11px 0 4px;padding:3.5px 8px;background:#F2F4F7;border-left:3px solid #111;
  font-size:10.5px;font-weight:600;color:#333}
.rc-ps-detail{font-size:10px}
.rc-ps-detail th,.rc-ps-detail td{padding:3px 7px}
/* 提成明细超过印数上限时收一档，保证签字栏不被挤到第二页 */
.rc-ps.ps-long .rc-ps-detail th,.rc-ps.ps-long .rc-ps-detail td{padding:1.8px 6px;font-size:9px}
.rc-ps-note{margin-top:8px;padding:5px 8px;background:#FAFBFC;font-size:10.5px;color:#444}
.rc-ps-sign{display:grid;grid-template-columns:1fr 1fr 1fr;gap:26px;margin-top:16px;
  padding-top:9px;border-top:1px dashed #BBB}
.rc-ps-sign-cell{display:flex;flex-direction:column;gap:4px}
.rc-ps-sign-cell span{font-size:10px;color:#6B7280}
.rc-ps-sign-cell i{display:block;border-bottom:1px solid #999;height:21px}
.rc-ps-foot{margin-top:10px;padding-top:6px;border-top:1px solid #EEE;font-size:9.5px;color:#777;line-height:1.5}

/* ---------- A4 结算台账 ----------
   一页装完：抬头 + 口径 + 四个 KPI + 分期间汇总表 + 明细摘要 + 签字栏。
   压缩靠「表行收一档」而不是缩字号到底 —— 数字要能一眼看清。 */
.rc-lg{font-size:11.5px}
.rc-lg .num{text-align:right;font-family:var(--ff-num)}
.rc-lg-kpi{
  display:grid;grid-template-columns:repeat(4,1fr);gap:0;margin-top:7px;
  border:1px solid #DDD;border-radius:3px;overflow:hidden;
}
.rc-lg-kpi-cell{
  padding:6px 9px;border-right:1px solid #EEE;display:flex;flex-direction:column;gap:1px;
}
.rc-lg-kpi-cell:last-child{border-right:none}
.rc-lg-kpi-cell .k{font-size:9.5px;color:#6B7280}
.rc-lg-kpi-cell .v{font-size:14px;font-weight:700;font-family:var(--ff-num);letter-spacing:-.3px}
.rc-lg-kpi-cell .s{font-size:9px;color:#8A8F98}
.rc-lg .rc-tb td,.rc-lg .rc-tb th{padding:3.4px 7px}
.rc-lg-detail{font-size:10px}
.rc-lg-detail th,.rc-lg-detail td{padding:3px 7px}
/* 财务两张纸（应付汇总单 / 应收对账单）的明细表要「一行就是一行」。
   这两张表的状态列原来只有 52px，「已逾期（逾期17天）」被折成三行，
   整行从 15px 撑到 50px —— 9 行明细就把签字栏顶到第二页，而且行高
   随数据长短漂移，预算根本没法算。改成固定表宽 + 不折行 + 溢出省略，
   行高写死 22px，页面上能放几行就能算准。
   结算台账 / 备件出入库单的明细表沿用 .rc-lg-detail，不受这里影响。 */
.rc-fin-detail{table-layout:fixed}
.rc-fin-detail th,.rc-fin-detail td{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rc-lg .rc-ps-sec{margin:8px 0 3px}
.rc-lg .rc-ps-sign{margin-top:11px}
.rc-lg .rc-ps-sign-cell i{height:17px}
.rc-lg .rc-ps-foot{margin-top:7px}

/* ---------- A4 备件入库 / 出库单 + 岗位结算台账 ----------
   这两张纸比工单多两级表（分桶汇总 + 人 / 岗位汇总 + 明细），
   所以「一张纸」靠三件事守住：表行再收一档、明细只印最近若干笔、
   超出的部分在标题里如实写明「共 N 笔，此处列出最近 K 笔」。 */
.rc-st .rc-tb td,.rc-st .rc-tb th{padding:3px 6px}
.rc-st .rc-lg-kpi-cell .v{font-size:12.5px}
.rc-role-tb{font-size:10.5px}
.rc-role-tb th,.rc-role-tb td{padding:3px 6px}
.rc-role-tb td:first-child{white-space:nowrap}
.rc-lg-more{margin-top:3px;font-size:9.5px;color:#8A8F98}
.rc-lg-note{
  margin-top:7px;padding:5px 8px;border:1px dashed #CCC;border-radius:3px;
  font-size:9.5px;line-height:1.6;color:#555;background:#FAFBFC;
}
.rc-lg-note b{color:#111}
.rc-role .rc-ps-sign{margin-top:9px}

/* 屏幕上的岗位对照表：11 列，把字号与内边距各收一档才不至于横向溢出 */
.ledger-role-tb{font-size:12px}
.ledger-role-tb th,.ledger-role-tb td{padding:6px 8px}
.ledger-role-tb td:first-child{min-width:132px}
.part-toolbar .seg button{white-space:nowrap}

/* ============================================================
   v11：通讯录 / 库存价值与滞销 / 供应商退货 / 财务中心
   ============================================================ */

/* ---------- 联系信息补全度 ---------- */
/* 一个细条就够：它不是 KPI，只是「这人能不能联系上」的先行指标。
   低于 60%（=没手机号）会整体转红，一眼能扫出通讯录的窟窿。 */
.cpbar{
  display:inline-block;vertical-align:middle;width:56px;height:5px;border-radius:99px;
  background:var(--gray-soft);overflow:hidden;flex:none;
}
.cpbar i{display:block;height:100%;border-radius:99px;background:var(--primary)}
.cpbar.bad i{background:var(--danger)}
.cpbar.mid i{background:var(--warn)}

/* 联系资料：左标签 / 中内容 / 右动作 三栏 ——
   号码要能点（tel:）、邮箱要能动，所以动作列必须固定宽度不随内容抖 */
.cf-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 22px}
.cf-grid.cf-edit{grid-template-columns:1fr 1fr;gap:11px 16px}
.cf-grid.cf-edit .field{margin:0}
.cf-row{
  display:grid;grid-template-columns:92px 1fr auto;gap:0 10px;align-items:center;
  padding:8px 0;border-bottom:1px dashed var(--border);min-height:38px;
}
.cf-row.miss{background:linear-gradient(90deg,var(--danger-soft),transparent 62%)}
.cf-lb{font-size:12px;color:var(--text-3);white-space:nowrap}
.cf-lb .req{color:var(--danger);margin-left:2px}
.cf-vl{font-size:12.5px;color:var(--text);word-break:break-all;min-width:0}
.cf-vl.mono{font-family:var(--ff-num);letter-spacing:.2px}
.cf-ac{display:flex;gap:6px;justify-content:flex-end}
.req-tip{font-size:10.5px;color:var(--danger);background:var(--danger-soft);padding:1px 6px;border-radius:99px;margin-left:4px}

/* 我的资料卡：默认展开，位置在人员信息页最上面 ——
   补全率的瓶颈通常是「大家不知道去哪填」，所以入口得先撞到眼睛 */
.me-contact{
  display:flex;gap:14px;align-items:flex-start;padding:15px 16px;border:1px solid var(--primary-line);
  border-radius:var(--r-lg);background:linear-gradient(180deg,var(--primary-soft),var(--surface));
}
.me-contact .mc-main{flex:1;min-width:0}

/* 人员信息页：左（待补全清单）右（全公司信息表）两栏 */
.pf-layout{display:grid;grid-template-columns:300px 1fr;gap:14px;align-items:start}
.pf-group{border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface);overflow:hidden}
.pf-group+.pf-group{margin-top:9px}
.pf-group-head{
  display:flex;align-items:center;gap:8px;padding:8px 11px;background:var(--surface-2);
  border-bottom:1px solid var(--border);font-size:12.5px;font-weight:600;
}
.pf-group-head .spacer{flex:1}
@media (max-width:1180px){.pf-layout{grid-template-columns:1fr}}

/* ---------- 通讯录 ---------- */
.contact-toolbar{flex-wrap:wrap}
.cc-groups{display:grid;grid-template-columns:1fr;gap:14px}
.ccards{display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));gap:12px}
.ccard{
  border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);
  box-shadow:var(--shadow-1);padding:13px 14px;cursor:pointer;transition:.14s;
  display:flex;flex-direction:column;gap:9px;min-width:0;
}
.ccard:hover{border-color:var(--primary-line);box-shadow:var(--shadow-2);transform:translateY(-1px)}
.cc-head{display:flex;gap:10px;align-items:center}
.cc-intro{
  font-size:12px;color:var(--text-2);line-height:1.6;padding:7px 9px;border-radius:var(--r-sm);
  background:var(--surface-3);
}
.cc-lines{display:flex;flex-direction:column;gap:5px}
.cc-line{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--text-2);min-width:0;flex-wrap:wrap}
.cc-line svg{flex:none;color:var(--text-3)}
.cc-line .clink{color:var(--primary-dark);text-decoration:none;font-size:12.5px;letter-spacing:.2px}
.cc-line .clink:hover{text-decoration:underline}
/* 「手机号待本人补全」用虚线框单独标出来：它和「这人不接电话」是两回事 */
.cc-line.absent{color:var(--danger);background:var(--danger-soft);border-radius:var(--r-sm);padding:5px 8px}
.cc-foot{display:flex;gap:6px;align-items:center;margin-top:auto;padding-top:9px;border-top:1px solid var(--border)}
/* 客户头像：客户没有照片，用首字方块 —— 一眼分得清「这是客户，不是同事」 */
.cust-av{
  width:36px;height:36px;border-radius:var(--r-sm);flex:none;
  display:flex;align-items:center;justify-content:center;
  background:var(--cyan-soft);color:var(--cyan);font-size:15px;font-weight:700;
}
/* 供应商头牌：显示**简称**而不是首字（「原厂」「欣旺达」本身就是它的名字，取首字反而看不懂），
   色用紫，与客户（青）、同事（各自头像色）都能一眼区分 —— 同一页里三种卡片，不能长得像。 */
.sup-av{
  width:36px;height:36px;border-radius:var(--r-sm);flex:none;
  display:flex;align-items:center;justify-content:center;
  background:var(--purple-soft);color:var(--purple);font-size:12px;font-weight:700;
}
/* 客户号码被权限打码：这是**正常状态**而不是故障，所以走中性灰底，
   不跟「待补全」共用红色告警 —— 否则没权限的人打开就是一屏红。 */
.cc-line.locked{color:var(--text-3);background:var(--surface-3);border-radius:var(--r-sm);padding:5px 8px}

/* ---------- 滞销分级卡 ---------- */
.deadcard{
  border:1px solid var(--border);border-left:3px solid var(--text-3);border-radius:var(--r-md);
  background:var(--surface);padding:13px 14px;box-shadow:var(--shadow-1);
}
.deadcard.dead-watch{border-left-color:var(--warn);background:linear-gradient(180deg,var(--warn-soft),var(--surface) 62%)}
.deadcard.dead-slow{border-left-color:var(--purple);background:linear-gradient(180deg,var(--purple-soft),var(--surface) 62%)}
.deadcard.dead-dead{border-left-color:var(--danger);background:linear-gradient(180deg,var(--danger-soft),var(--surface) 62%)}
.dc-num{font-size:26px;font-weight:680;letter-spacing:-.6px;margin-top:8px;line-height:1.1;font-variant-numeric:tabular-nums}
.dc-num small{font-size:12px;font-weight:500;color:var(--text-3);margin-left:4px;letter-spacing:0}
.dc-sub{font-size:12px;color:var(--text-2);margin-top:3px}
.dc-act{font-size:11.5px;color:var(--text-3);line-height:1.65;margin-top:7px;padding-left:9px;border-left:2px solid var(--border)}

/* ---------- 退货流程线（复用 .flowline，补状态态） ---------- */
.flowline .fl.on{border-color:var(--primary);background:var(--primary-soft);box-shadow:var(--shadow-1)}
.flowline .fl.on b{color:var(--primary-dark)}
.flowline .fl.done{border-color:var(--border-strong);background:var(--ok-soft)}
.flowline .fl.done b{color:var(--ok)}

/* ---------- 提醒中心卡片 ---------- */
.alertcard{
  border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);
  box-shadow:var(--shadow-1);padding:14px 15px;display:flex;flex-direction:column;gap:9px;
}
.alertcard.alert-red{border-left:3px solid var(--danger);background:linear-gradient(180deg,var(--danger-soft),var(--surface) 58%)}
.alertcard.alert-amber{border-left:3px solid var(--warn);background:linear-gradient(180deg,var(--warn-soft),var(--surface) 58%)}
.alertcard.alert-blue{border-left:3px solid var(--primary);background:linear-gradient(180deg,var(--primary-soft),var(--surface) 58%)}
.alertcard.alert-gray{border-left:3px solid var(--text-3)}
.ac-head{display:flex;gap:10px;align-items:flex-start}
.ac-head>svg{flex:none;margin-top:2px}
.ac-num{font-size:24px;font-weight:680;letter-spacing:-.5px;font-variant-numeric:tabular-nums}
.ac-foot{display:flex;align-items:center;gap:8px;margin-top:auto}
.ac-foot .spacer{flex:1}

/* ---------- 选择卡（类型 / 处理方式 / 期间 的单选卡） ---------- */
/* 原生 radio 藏起来但保留可访问性：点整张卡都能选，比小圆点好按得多 */
.pick{
  display:flex;gap:9px;align-items:flex-start;padding:9px 11px;border:1px solid var(--border);
  border-radius:var(--r-md);background:var(--surface);cursor:pointer;transition:.14s;min-width:158px;
}
.pick:hover{border-color:var(--primary-line);background:var(--surface-2)}
.pick input{position:absolute;opacity:0;width:0;height:0}
.pick span{display:flex;flex-direction:column;gap:2px;min-width:0}
.pick b{font-size:12.5px;display:flex;align-items:center;gap:5px}
.pick small{font-size:11px;color:var(--text-3);line-height:1.55}
.pick.on{border-color:var(--primary);background:var(--primary-soft);box-shadow:inset 0 0 0 1px var(--primary-line)}
.pick.on b{color:var(--primary-dark)}

/* ---------- A4：内部通讯录 / 滞销清理单 / 退货单 / 应付汇总 / 应收对账 ---------- */
/* .rc-grp 是分组小标题行：居中、浅底、不可断行 ——
   一张长表如果没有分组标题，找人就得一行行扫。 */
.rc-grp td{
  background:#F1F3F7;border-top:1px solid #D9DDE4;border-bottom:1px solid #D9DDE4;
  font-size:9.5px;font-weight:600;color:#333;letter-spacing:.2px;padding:3px 6px;
}
.rc-grp td span.muted{font-weight:400;color:#777;font-size:9px}
.rc-dir{font-size:10px}
.rc-dir .rc-tb{font-size:9.5px}
.rc-dir-tb th,.rc-dir-tb td{padding:2.5px 5px;border:1px solid #DDD;vertical-align:top}
/* 通讯录也要「一行就是一行」，但理由和财务两张纸不一样：
   它是唯一一张**行数随人数增长**的纸，余量会被新同事吃光。
   原来岗位列只有 96px，「高级手机维修工程师」正好卡在边界上被折断成两行，
   人员行从 39px 变成 50.5px —— 11 个人就顶到 1056px，再进一个人就出第二页。
   固定表宽 + 不折行 + 溢出省略之后行高是死的，页面上能装几个人就能算准。 */
.rc-dir-tb{table-layout:fixed}
.rc-dir-tb th,.rc-dir-tb td{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rc-dir-src{font-size:8.5px;color:#888;margin-top:4px}
.rc-dead{font-size:10px}
.rc-dead-tb th,.rc-dead-tb td{padding:2.5px 5px;border:1px solid #DDD}
/* 打印件里的状态戳：灰 / 蓝 / 绿 / 红，黑白打印机上也能靠深浅区分 */
.rc-ap,.rc-ar,.rc-ret,.rc-void{font-size:10px}
.rc-head-right{display:flex;flex-direction:column;align-items:flex-end;gap:3px;font-size:9.5px;color:#555}
.rc-sub{font-size:8.5px;color:#888;font-weight:400}
.rc-empty-td{text-align:center;color:var(--text-3);font-size:12px;padding:22px 0!important}

/* 屏幕上空的打印预览容器：白纸效果，和出纸一致 */
.print-preview .rc-dir,
.print-preview .rc-dead,
.print-preview .rc-ap,
.print-preview .rc-ar,
.print-preview .rc-ret{box-shadow:0 4px 18px rgba(23,32,46,.12)}

/* ---------- 打印：只留票据，@page 由脚本动态切换 ---------- */
@media print{
  html,body{height:auto!important;overflow:visible!important;background:#fff!important}
  body>*:not(.print-area){display:none!important}
  body>.print-area{display:block!important}
  .print-area .receipt{width:auto!important;margin:0!important;padding:0!important;box-shadow:none!important;font-size:11.5px}
  .print-area .barcode{max-width:none!important}
  .rc-block,.rc-tb,.rc-signblock,.rc-tail,.tm-warranty{break-inside:avoid}
  .rc-head{break-after:avoid}
}
/* 条形图里值为 0 的那一条：标签写「—」，条形退成底色，
   别让读者以为「发生了，只是金额是零」 */
.hbar.is-zero .val{color:var(--text-3)}
/* 0 值行的灰色轨道整条隐掉：全宽的灰条会被读成「这一期是满的」，
   这正是「比例不对」的来源 —— 有钱的条画比例，没钱的行只留标签和 — */
.hbar.is-zero .trk{background:transparent}
.hbar.is-zero .trk>i{display:none}

/* ============================================================
   v13 · 机型字典 / 流转溯源 / 通道接入
   ============================================================ */

/* 字符口径说明：左右两栏的规则清单。左侧「做什么」用正常色，
   「不做什么」用警示色 —— 不做的那条同样重要，否则有人会问「为什么不顺便把『手机』删了」 */
.rule-list{margin:0;padding:0;list-style:none;font-size:11.5px;line-height:1.7}
.rule-list li{display:flex;gap:8px;padding:4px 0;border-bottom:1px dashed var(--border)}
.rule-list li:last-child{border-bottom:none}
.rule-list li>span{flex:none;width:132px;color:var(--text-3)}
.rule-list li>b{font-weight:600;font-family:var(--ff-num);min-width:0}
.rule-list li.warn>span,.rule-list li.warn>b{color:var(--warn)}

/* 溯源时间线：状态流转与字段变更各占一行，扫视时不会跟正文混在一起 */
.trace-tl .tl-text{line-height:1.75}
.trace-move{
  display:inline-block;margin-left:6px;padding:0 6px;border-radius:4px;
  background:var(--primary-soft);color:var(--primary-dark);font-size:11px;font-family:var(--ff-num);
}
.trace-chg{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px}
.trace-chg span{
  display:inline-flex;align-items:center;gap:4px;font-size:10.5px;
  background:var(--surface-3);border-radius:4px;padding:1px 7px;
}
.trace-chg span>i{font-style:normal;color:var(--text-3);font-family:var(--ff-num)}
.trace-chg span>b{font-family:var(--ff-num);color:var(--text)}

/* 短信配额条：很细的一条，不抢视线 */
.hbar-mini{height:4px;border-radius:2px;background:var(--surface-3);margin:4px 0;overflow:hidden;max-width:220px}
.hbar-mini>i{display:block;height:100%;background:var(--primary);border-radius:2px}

/* 云函数接口卡：入参 / 出参 / 权限三栏并排，接入时照着抄 */
.api-card{border:1px solid var(--border);border-radius:var(--r-md);padding:11px 12px;margin-bottom:10px;background:var(--surface)}
.api-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:9px}
.api-name{
  font-size:11.5px;font-weight:700;color:var(--primary-dark);
  background:var(--primary-soft);border-radius:4px;padding:2px 7px;
}
.api-grid{display:grid;grid-template-columns:1fr 1fr 190px;gap:12px;align-items:start}
@media (max-width:1100px){.api-grid{grid-template-columns:1fr}}
.api-lb{font-size:10.5px;color:var(--text-3);margin-bottom:4px;letter-spacing:.3px}
.api-f{display:flex;gap:6px;align-items:baseline;flex-wrap:wrap;margin-bottom:5px}
.api-f>span{font-size:11px;font-weight:700}
.api-f>em{font-style:normal;font-size:10px;color:var(--text-3);background:var(--surface-3);border-radius:3px;padding:0 5px}
.api-note{
  display:flex;gap:7px;align-items:flex-start;margin-top:9px;padding-top:9px;
  border-top:1px dashed var(--border);font-size:11px;line-height:1.65;color:var(--text-2);
}
.api-note svg{flex:none;margin-top:1px;color:var(--warn)}

/* 打印件的单行截断：留痕正文长短不一，不截断就会折行 → 行高不定 → 出第二页。
   溯源单靠它把每一行钉死在 22.8px。 */
.rc-ellip{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:0}
.rc-trace .rc-ps-sec{margin-top:7px}
.rc-trace .rc-tb td{padding:3.6px 6px;font-size:10px;vertical-align:middle}
.rc-trace .rc-tb th{padding:3.4px 6px;font-size:10px}

/* ---------- A4 质检单（维修前质检 / 完工质检）----------
   两张纸共用一套版式，只在联次与说明上分开（内部留存 / 随设备寄回）。
   12 项检查排成两列 6 行：一行一项要占 280px 高，会把结论和签字栏挤到第二页 ——
   而「签字栏印到第二页」等于没签字（同《溯源单》那条教训）。 */
.rc-qc .rc-tb td,.rc-qc .rc-tb th{padding:3.6px 7px;font-size:10.5px}
.rc-qc .rc-ps-sec{margin-top:8px}
.rc-qc-tb{table-layout:fixed}
.rc-qc-verdict{
  display:grid;grid-template-columns:repeat(3,1fr);gap:0;margin-top:4px;
  border:1px solid #DDD;border-radius:3px;overflow:hidden;
}
.rc-qc-v-cell{padding:6px 9px;border-right:1px solid #EEE;display:flex;flex-direction:column;gap:1px}
.rc-qc-v-cell:last-child{border-right:none}
.rc-qc-v-cell .k{font-size:9.5px;color:#6B7280}
.rc-qc-v-cell .v{font-size:13px;font-weight:700}
.rc-qc-note{
  margin-top:6px;padding:6px 8px;border:1px dashed #CCC;border-radius:3px;
  font-size:10px;line-height:1.6;color:#444;background:#FAFBFC;min-height:34px;
}
.rc-qc .rc-ps-sign{margin-top:12px}
.rc-qc .rc-ps-sign-cell i{height:19px}
/* 纸面上的机况标签：客户留存联要能一眼看见「进水 / 二修」有没有被标上。
   高风险项用深红描边（黑白打印也留得住边），不做浅底反白 —— 复印件里会糊掉。 */
.rc-qc-flags{display:flex;flex-wrap:wrap;gap:5px;margin-top:3px}
.rc-qc-flag{
  display:inline-block;padding:2px 9px;border:1px solid #BBB;border-radius:12px;
  font-size:10.5px;font-weight:600;color:#333;
}
.rc-qc-flag.risk{border-color:#C0392B;color:#B03024;background:#FDF2F1}

/* 环节耗时条：5 段小格，一眼看出这张单卡在哪一段。
   正在跑的那一段用暖色 —— 它是「现在时」，与已完成的冷色要能一眼分开 */
.stage-strip{display:grid;grid-template-columns:repeat(5,1fr);gap:6px;margin-bottom:6px}
.stage-cell{
  display:flex;flex-direction:column;gap:2px;padding:6px 8px;
  border:1px solid var(--border);border-radius:var(--r-sm);background:var(--surface);
}
.stage-cell>span{font-size:10.5px;color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.stage-cell>b{font-family:var(--ff-num);font-size:13px;font-weight:700;color:var(--text-3)}
.stage-cell.done{border-color:var(--primary-line);background:var(--primary-soft)}
.stage-cell.done>b{color:var(--primary-dark)}
.stage-cell.running{border-color:var(--warn);background:rgba(199,119,0,.08)}
.stage-cell.running>b{color:var(--warn)}

/* ============================================================
   v14 · 机型变体 / 影像证据 / 短信接入参数 / 保内返修单
   ============================================================ */

/* 分段控件上的计数小签：筛选器如果不显示数量，人就不知道切过去有没有东西 */
.seg-n{
  display:inline-block;margin-left:6px;padding:0 5px;border-radius:8px;
  background:var(--surface-3);color:var(--text-3);font-size:10.5px;font-family:var(--ff-num);
}
.seg button.on .seg-n{background:var(--primary-soft);color:var(--primary-dark)}

/* 常用项快捷勾选：点一下往文本框里加减。
   做成「按钮」而不是「复选框」——复选框要点击小方框，按钮整块可点，
   现场一只手拿机器一只手点屏幕时差别很明显 */
.chiprow{display:flex;flex-wrap:wrap;gap:6px;margin-top:7px}
.chip{
  padding:3px 9px;border:1px solid var(--border);border-radius:20px;
  background:var(--surface);font-size:11.5px;color:var(--text-2);cursor:pointer;transition:.12s;
}
.chip:hover{border-color:var(--primary-line);color:var(--text)}
.chip.on{border-color:var(--primary);background:var(--primary-soft);color:var(--primary-dark);font-weight:600}

/* 密钥输入 + 显示按钮 */
.cred-row{display:flex;gap:8px;align-items:center}
.cred-row .inp{flex:1;min-width:0}

/* 弹窗里的分节线：参数区与通用设置区要分开，否则人会以为签名也是服务商参数 */
.sec-line{
  margin:16px 0 10px;padding-top:12px;border-top:1px solid var(--border);
  font-size:12px;font-weight:650;color:var(--text-2);letter-spacing:.2px;
}

/* 被影像证据闸门拦住的动作：照旧可点，但**整套换色**。
   原先只覆盖 color / border-color、漏了 background —— 主按钮的蓝底留了下来，
   于是蓝底(#2B5CE6)压琥珀字(#C77700)，对比度约 1.6:1，基本读不出，
   再叠一条琥珀虚线边和残留的蓝色投影，就成了「颜色和对比度都难看」。
   做法：gated 一律走「浅琥珀底 + 深琥珀字 + 琥珀虚线边」，与 pill-amber 同族；
   不灰掉（灰=禁用，会被误读成点不动），hover 加深底色给出可点反馈。 */
.btn-gated{
  border-style:dashed!important;
  border-color:var(--warn-line)!important;
  background:#FFEECB!important;
  color:var(--warn-dark)!important;
  box-shadow:0 1px 2px rgba(199,119,0,.16)!important;
}
.btn-gated:hover{
  border-style:solid!important;
  border-color:var(--warn)!important;
  background:#FFE7BC!important;
  box-shadow:0 2px 6px rgba(199,119,0,.22)!important;
}

/* ---------- 工单抽屉：影像证据 ---------- */
.ph-stage{padding:10px 0;border-bottom:1px dashed var(--border)}
.ph-stage:last-child{border-bottom:none}
.ph-stage-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:8px}
.ph-stage-head>b{font-size:13px}
.ph-grid{display:flex;flex-wrap:wrap;gap:9px}
.ph-cell{
  position:relative;width:104px;margin:0;border:1px solid var(--border);border-radius:var(--r-sm);
  overflow:hidden;background:var(--surface);
}
.ph-img{display:block;width:100%;height:78px;object-fit:cover;cursor:zoom-in;background:var(--surface-3)}
.ph-meta{display:flex;flex-direction:column;gap:1px;padding:4px 6px;font-size:10px;color:var(--text-3);line-height:1.4}
.ph-meta b{font-size:10.5px;color:var(--text-2);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* ---------- 用 USB 摄像头现拍 ---------- */
/* 取景框固定 4:3 且深底：USB 摄像头出图比例五花八门，不钉住高度的话，
   弹窗会随着设备分辨率忽高忽低，右下角那两个按钮就跟着跳。 */
.cam-stage{
  position:relative;background:#101828;border-radius:var(--r-md);overflow:hidden;
  aspect-ratio:4/3;display:flex;align-items:center;justify-content:center;
}
.cam-stage video{width:100%;height:100%;object-fit:contain;display:block}
.cam-tip{
  position:absolute;bottom:10px;left:50%;transform:translateX(-50%);
  background:rgba(16,24,40,.84);color:#E7ECF5;font-size:11.5px;
  padding:5px 12px;border-radius:20px;max-width:88%;text-align:center;line-height:1.5;
}
.cam-tip-err{background:rgba(143,31,33,.95);color:#fff;border-radius:8px}
.cam-preview{
  display:block;max-width:100%;max-height:320px;border-radius:var(--r-md);
  border:1px solid var(--border);background:var(--surface-2);
}
.ph-del{
  position:absolute;top:3px;right:3px;width:18px;height:18px;border-radius:50%;
  background:rgba(17,17,17,.55);color:#fff;font-size:12px;line-height:17px;text-align:center;cursor:pointer;
}
.ph-del:hover{background:var(--danger)}
/* 缺口占位格：把「还差几张」画成格子，扫一眼就能看见缺在哪 */
.ph-hole{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  width:104px;height:104px;border:1px dashed var(--border-strong);border-radius:var(--r-sm);
  background:var(--surface-2);color:var(--text-3);font-size:11px;cursor:pointer;
}
.ph-hole:hover{border-color:var(--primary);color:var(--primary)}
.ph-view-wrap{display:flex;justify-content:center;background:var(--surface-3);border-radius:var(--r-md);padding:10px}
.ph-view{max-width:100%;max-height:62vh;object-fit:contain;border-radius:var(--r-sm)}

/* ---------- 派单看板：保内返修单 ---------- */
.kcard-wr{
  display:flex;gap:5px;align-items:flex-start;margin-bottom:6px;padding:4px 6px;
  background:var(--surface-3);border-radius:var(--r-sm);font-size:10.5px;color:var(--text-2);line-height:1.5;
}
.kcard-wr svg{flex:none;margin-top:1px;color:var(--purple)}
.kcard-act{width:100%;margin-top:7px;justify-content:center}

/* ---------- A4《工单影像证据单》 ----------
   3 列 × 3 行固定：图片区高度是死的（3×(150+26)=528），所以不管一单有几张照片，
   这张纸都恒定一页。多出来的照片只报数量，不挤版式 —— 挤出第二页就等于把签字栏丢了。 */
.rc-photos .rc-ph-grid{
  display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-top:4px;
}
.rc-ph-cell{
  position:relative;margin:0;border:1px solid #DDD;border-radius:3px;overflow:hidden;background:#fff;
}
.rc-ph-img{display:block;width:100%;height:150px;object-fit:cover}
.rc-ph-empty{height:176px;background:#FAFAFB;border-style:dashed}
.rc-ph-no{
  position:absolute;top:2px;left:2px;min-width:14px;height:14px;border-radius:7px;
  background:rgba(17,17,17,.6);color:#fff;font-size:9px;line-height:14px;text-align:center;padding:0 3px;
}
.rc-ph-cap{display:flex;flex-direction:column;gap:1px;padding:3px 5px;font-size:9px;color:#555;line-height:1.35}
.rc-ph-cap b{font-size:9.5px;color:#111;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rc-ph-more{
  margin-top:5px;padding:3px 7px;background:#F2F4F7;border-left:3px solid #999;
  font-size:9.5px;color:#555;line-height:1.5;
}

/* ==========================================================================
   设备出库（v18）
   契约只有一条：**超期必须是红的**。这张卡/这一行存在的全部理由就是
   「让机器准时发出去」，颜色不刺眼，它就会变成又一处没人看的装饰。
   ========================================================================== */
.ob-card.ob-over{border-left:3px solid var(--danger)}
.ob-kvs{display:flex;flex-wrap:wrap;gap:8px 26px;padding:12px 16px}
.ob-kv .k{font-size:11px;color:var(--text-3)}
.ob-kv .v{font-size:13px;font-weight:600;font-variant-numeric:tabular-nums}
.ob-kv .v.danger{color:var(--danger)}
/* 工单中心「收 / 发」列里的出库行：那格本来只讲货怎么进来 */
.ob-line{
  display:flex;align-items:center;gap:4px;margin-top:5px;
  font-size:11.5px;color:var(--text-3);font-variant-numeric:tabular-nums;
}
.ob-line.ob-line-over{color:var(--danger);font-weight:600}
.ob-line.ob-line-done{color:var(--ok)}

/* 影像环节的主责标签：谁该拍这一环。
   「代传」是**中性灰**不是警告色 —— 代拍本身不是错（人不在，活不能停），
   要的只是让屏幕和留痕说实话。染成红色会让人不敢代拍，最后机器没人拍。 */
.ph-own{
  font-size:10.5px;color:var(--text-3);background:var(--surface-3);
  padding:1px 6px;border-radius:99px;white-space:nowrap;
}
.ph-own.ph-own-agency{color:var(--text-2);background:var(--warn-soft);border:1px dashed var(--warn-line)}

/* ==========================================================================
   工单中心 / 派单看板的可阅读性（v18）
   共同目标只有一个：**扫一眼就知道该动哪一张**。
   ========================================================================== */
/* 工单号那一格的副行：建单时间 + 在本状态停了多久。
   停留 ≥48 小时标琥珀 —— 它比「还有几天到期」更早发出警告：
   离交期还有 3 天、却在「待派单」躺了两天，那叫没人管。 */
.c-sub{font-size:10.5px;color:var(--text-3);font-weight:400;font-variant-numeric:tabular-nums}
.c-sub .c-slow{color:var(--warn);font-weight:600}

/* 筛选开关分组：六个开关平铺时，读者要逐个读完才知道它们不是一类东西。
   一条细分隔就够 —— 加个分组标题反而更占地方。 */
.tb-grp{display:flex;align-items:center;gap:6px}
.tb-grp+.tb-grp{padding-left:9px;border-left:1px solid var(--border)}

/* 表格里的图标按钮：只有一个动作的列用它，把宽度让给有内容的列。 */
.btn-icon{
  display:inline-flex;align-items:center;justify-content:center;
  width:26px;height:26px;border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--surface);color:var(--text-2);transition:.14s;
}
.btn-icon:hover{border-color:var(--primary);color:var(--primary);background:var(--primary-soft)}

/* 看板卡片：客户名与停留时长同一行（名字左、时长右）。
   故障行已有两行截断，这里补一个等高下限 —— 卡片高低参差时，
   同一列里的卡片没法横向比较，而看板恰恰是用来比较的。 */
.kcard-meta{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--text-3);margin-bottom:6px}
.kcard-meta .kcard-age{
  margin-left:auto;flex:none;font-variant-numeric:tabular-nums;
  padding:1px 6px;border-radius:99px;background:var(--surface-3);color:var(--text-3);
}
.kcard-meta .kcard-age.kcard-age-slow{background:var(--warn-soft);color:var(--warn-dark);font-weight:600}
.kcard-fault{min-height:2.85em}

/* 台账页的第二条口径说明：讲清本页与「财务中心 · 应收对账」的分工。
   比第一条更轻 —— 它是给第一次看这页的人解释「两页为什么不冲突」，
   不是每次都要读的操作提示。 */
.ledger-scope.ledger-split{color:var(--text-3);border-top:1px dashed var(--border);margin-top:5px;padding-top:5px}

/* ===================== v21 平台数据大屏 =====================
   投屏驾驶舱：更密的 KPI、更大的数字、三栏图表。与普通工作台区分 ——
   大屏是「站远了看」，所以字号、间距、留白都比日常页面重一档。 */
.screen-head{display:flex;justify-content:space-between;align-items:flex-start;padding:4px 2px 16px;border-bottom:1px solid var(--border);margin-bottom:18px}
.screen-head h2{font-size:21px;margin:0 0 4px;letter-spacing:.5px}
.screen-kpis{display:grid;grid-template-columns:repeat(5,1fr);gap:12px;margin-bottom:18px}
.screen-kpi{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);padding:16px 18px}
.sk-label{font-size:12px;color:var(--text-2);margin-bottom:9px}
.sk-val{font-size:30px;font-weight:700;line-height:1;color:var(--text);font-variant-numeric:tabular-nums}
.sk-val small{font-size:14px;font-weight:600;color:var(--text-3);margin-left:4px}
.sk-sub{font-size:11px;color:var(--text-3);margin-top:9px}
.screen-grid{display:grid;grid-template-columns:1fr 1.35fr 1fr;gap:14px;margin-bottom:18px}
.screen-panel{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);overflow:hidden}
.screen-panel-h{font-size:13px;font-weight:600;color:var(--text-2);padding:13px 16px;border-bottom:1px solid var(--border)}
.screen-panel .card-body{padding:16px}
@media (max-width:1180px){
  .screen-kpis{grid-template-columns:repeat(3,1fr)}
  .screen-grid{grid-template-columns:1fr}
}
/* 分账结构（大屏专属）：横向条直观显示「营收被拆成抽成 + 净得」的比例 */
.fee-row{padding:13px 0;border-bottom:1px dashed var(--border)}
.fee-row:last-child{border-bottom:none;padding-bottom:0}
.fee-top{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:8px}
.fee-name{font-size:13px;font-weight:600;color:var(--text)}
.fee-rev{font-size:12.5px;color:var(--text-2);font-variant-numeric:tabular-nums}
.fee-bar{height:9px;border-radius:5px;background:var(--surface-3);overflow:hidden}
.fee-bar i{display:block;height:100%;background:linear-gradient(90deg,#C77700,#E09A2B);border-radius:5px}
.fee-bottom{font-size:11.5px;margin-top:8px}
.fee-bottom b{color:var(--text-2)}

/* ============================================================
   v22 视觉装修：质感统一升级（登录门面 / 侧栏 / 卡片 / 按钮）
   只追加覆盖、不改上面的原规则 —— 布局零风险，回退删这一段即可。
   ============================================================ */

/* ---------- 登录页 / 安装向导：品牌深蓝氛围 + 精致白卡 ---------- */
.gate{
  background:
    radial-gradient(1100px 560px at 8% -12%, rgba(93,134,244,.5) 0%, transparent 58%),
    radial-gradient(880px 520px at 102% 114%, rgba(14,148,110,.26) 0%, transparent 55%),
    linear-gradient(158deg,#0B1526 0%,#132447 48%,#1E45B8 135%);
}
.gate::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(640px 320px at 76% 16%, rgba(255,255,255,.09) 0%, transparent 62%);
}
.gate-card{
  position:relative;border:none;border-radius:22px;
  box-shadow:0 32px 84px rgba(5,14,36,.52), 0 2px 10px rgba(5,14,36,.3);
  padding:34px 36px 24px;
  animation:gateIn .45s cubic-bezier(.22,.9,.3,1) both;
}
@keyframes gateIn{from{opacity:0;transform:translateY(14px) scale(.985)}to{opacity:1;transform:none}}
.gate-logo{width:226px}
.gate-hint span:first-child{font-size:15.5px;letter-spacing:.3px}
.gate-brand-txt strong{font-size:15px}

/* ---------- 侧边栏：柔和渐变底 + 右缘光影 ---------- */
.sidebar{
  background:linear-gradient(180deg,#FFFFFF 0%,#F9FAFE 100%);
  border-right:none;
  box-shadow:1px 0 0 var(--border), 10px 0 30px rgba(23,32,46,.045);
}
.nav-item,.nav-out{transition:background .15s,color .15s,transform .15s}
.nav-item:hover,.nav-out:hover{transform:translateX(2px)}
.nav-item.active{
  background:linear-gradient(90deg,var(--primary-soft) 0%,rgba(237,242,254,.35) 100%);
  box-shadow:inset 0 0 0 1px var(--primary-line);
}

/* ---------- 顶栏：浮动感 ---------- */
.topbar{box-shadow:0 1px 0 var(--border), 0 6px 18px -12px rgba(23,32,46,.12)}

/* ---------- 卡片：更柔和的层次 + hover 微升 ---------- */
.card,.stat,.screen-panel{
  box-shadow:0 1px 2px rgba(23,32,46,.04), 0 6px 20px -8px rgba(23,32,46,.08);
  transition:box-shadow .18s,transform .18s;
}
.card:hover{box-shadow:0 2px 4px rgba(23,32,46,.05), 0 14px 34px -10px rgba(23,32,46,.14)}

/* ---------- 主按钮：品牌渐变 + hover 微升 ---------- */
.btn-primary{
  background:linear-gradient(135deg,#3B6BEE 0%,#2B5CE6 55%,#2450CE 100%);
  border-color:transparent;
  box-shadow:0 2px 6px rgba(43,92,230,.35), inset 0 1px 0 rgba(255,255,255,.18);
}
.btn-primary:hover{
  background:linear-gradient(135deg,#3262E4 0%,#2450CE 55%,#1E45B8 100%);
  transform:translateY(-1px);
  box-shadow:0 5px 14px rgba(43,92,230,.4), inset 0 1px 0 rgba(255,255,255,.18);
}
.btn-primary:active{transform:translateY(0)}

/* ---------- KPI 强调条：渐变 ---------- */
.stat.accent::after{background:linear-gradient(180deg,#4C7BEE,#2B5CE6)}
.stat.accent-ok::after{background:linear-gradient(180deg,#22B583,#0E9F6E)}
.stat.accent-warn::after{background:linear-gradient(180deg,#E09A2B,#C77700)}
.stat.accent-danger::after{background:linear-gradient(180deg,#E85558,#D93B3E)}

/* ---------- 输入框：聚焦光圈更柔 ---------- */
.inp:focus{border-color:var(--primary);box-shadow:0 0 0 3.5px rgba(43,92,230,.13)}

/* ---------- 滚动条 ---------- */
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-thumb{background:#C9D2E0;border-radius:6px;border:2px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:#AAB6C8;border:2px solid transparent;background-clip:content-box}
::-webkit-scrollbar-track{background:transparent}

/* ---------- 修复：统一登录页的表单卡占满整行 ----------
   .gate-list 原是给「身份卡片」用的两列网格；改成统一登录页后里面只有一张表单卡，
   不跨列的话表单挤在左半边、右边一大块空白。安装向导（#installList）同理。 */
.gate-list{display:block;max-height:none;overflow:visible}
.gate-list .card{max-width:none}

/* ============================================================
   v22 登录页两栏：左表单 + 右幻灯片轮播（幻灯片内容后台可改）
   ============================================================ */
.gate-panel{
  position:relative;display:flex;width:100%;max-width:900px;
  background:#fff;border-radius:22px;overflow:hidden;
  box-shadow:0 32px 84px rgba(5,14,36,.52), 0 2px 10px rgba(5,14,36,.3);
  animation:gateIn .45s cubic-bezier(.22,.9,.3,1) both;
}
.gate-main{flex:1.02;min-width:0;padding:34px 36px 24px}
.gate-side{
  flex:1;min-width:0;position:relative;overflow:hidden;
  background:
    radial-gradient(520px 360px at 90% 10%, rgba(93,134,244,.4) 0%, transparent 58%),
    linear-gradient(158deg,#132447 0%,#1E45B8 100%);
  display:flex;flex-direction:column;
}

/* ---------- 幻灯片 ---------- */
.slides{position:relative;flex:1;min-height:340px}
.slide{
  position:absolute;inset:0;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;
  padding:42px 44px 70px;color:#fff;opacity:0;transform:translateX(26px);
  transition:opacity .5s ease,transform .5s ease;pointer-events:none;
}
.slide.is-active{opacity:1;transform:none;pointer-events:auto}
/* v35.18：删掉 .slide-ico —— 它是 0 处使用的死 CSS，而且它那个背景色变量
   全站根本没定义（也没有内联赋值），真用起来会是一块透明底 + 一圈阴影。
   登录幻灯片的图标位已由 svgSlide 出图，不靠这个类。 */
.slide h3{font-size:23px;font-weight:700;margin:0 0 11px;letter-spacing:.3px;line-height:1.3}
.slide p{font-size:14px;line-height:1.75;color:rgba(255,255,255,.82);margin:0;max-width:340px}
.slide-dots{position:absolute;left:44px;bottom:28px;display:flex;gap:8px}
.sdot{width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,.34);transition:all .3s;cursor:pointer;padding:0}
.sdot.is-active{width:22px;border-radius:5px;background:#fff}

/* 窄屏：只留登录表单，幻灯片收起 */
@media (max-width:820px){
  .gate-side{display:none}
  .gate-panel{max-width:460px}
  .gate-main{padding:30px 28px 22px}
}

/* 修复：非激活幻灯片虽然 opacity:0，文字仍有次像素残留 —— 加 visibility 延迟隐藏 */
.slide{visibility:hidden;transition:opacity .5s ease,transform .5s ease,visibility 0s .5s}
.slide.is-active{visibility:visible;transition:opacity .5s ease,transform .5s ease,visibility 0s 0s}

/* ---------- 安装向导：左表单 + 右部署步骤（对齐登录页两栏风格） ---------- */
.install-sec{font-weight:600;font-size:13px;margin:16px 0 8px;color:var(--text-2)}
.install-side{position:relative;flex:1;display:flex;flex-direction:column;justify-content:center;padding:42px 44px;color:#fff}
.is-ico{width:52px;height:52px;border-radius:14px;background:rgba(255,255,255,.14);display:flex;align-items:center;justify-content:center;margin-bottom:20px}
.is-ico .ico{width:26px;height:26px;color:#fff}
.install-side h3{font-size:22px;font-weight:700;margin:0 0 10px;letter-spacing:.3px}
.install-side .is-sub{font-size:14px;line-height:1.7;color:rgba(255,255,255,.78);margin:0 0 26px;max-width:330px}
.is-steps{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:16px}
.is-step{display:flex;gap:13px;align-items:flex-start}
.is-step .n{flex:none;width:26px;height:26px;border-radius:50%;background:rgba(255,255,255,.16);display:flex;align-items:center;justify-content:center;font-size:12.5px;font-weight:600}
.is-step b{display:block;font-size:13.5px;font-weight:600}
.is-step span{display:block;font-size:12px;color:rgba(255,255,255,.72);margin-top:2px;line-height:1.55}

/* ============================================================
   公告横幅（工作台顶部）
   ============================================================ */
/* 业务主线流转条：报修→结算 横向流程，一眼看各环节卡单数 */
.flow-strip{display:flex;align-items:stretch;gap:4px}
.flow-node{flex:1;min-width:0;text-align:center;padding:0 2px}
.fn-name{font-size:11.5px;color:var(--text-2);white-space:nowrap}
.fn-num{font-size:16px;font-weight:700;margin:2px 0 5px;font-variant-numeric:tabular-nums}
.fn-num small{font-size:10.5px;font-weight:400;color:var(--text-3)}
.fn-bar{height:5px;border-radius:3px;background:var(--surface-3);overflow:hidden}
.fn-bar i{display:block;height:100%;background:linear-gradient(90deg,#4C7BEE,#2B5CE6);border-radius:3px}
.fn-arrow{flex:none;align-self:center;color:var(--text-3);font-size:16px;line-height:1;padding:0 2px}
.announce-bar{
  display:flex;align-items:center;gap:12px;
  background:linear-gradient(135deg,#EDF2FE 0%,#F5F8FF 100%);
  border:1px solid var(--primary-line);border-radius:var(--r-lg);
  padding:12px 16px;margin-bottom:14px;
}
.announce-bar .ico{color:var(--primary);flex:none}
.announce-txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.announce-txt b{font-size:13px;font-weight:650}
.announce-txt span{font-size:12px;color:var(--text-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.announce-bar .pill{flex:none}

/* ---- 公告未读状态（v35.20）----
   横幅从「一条」改成「最多三条、未读优先」，行内用 .ann-row；
   列表页用 .ann-card + .ann-sec-h 分区。
   未读用**蓝点 + 加粗**，已读用**降权**（不是删除线）—— 已读的仍然要能一眼找到。 */
.ann-row{display:flex;align-items:baseline;gap:6px;min-width:0;padding:2px 0}
.ann-row b{font-weight:600;flex:none;max-width:46%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ann-row .ann-one{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  color:var(--text-3);font-size:11.5px}
.ann-row.is-read b{font-weight:500;color:var(--text-2)}
.ann-row.is-read .ann-one{opacity:.72}
.ann-row:hover b{color:var(--primary)}
.ann-dot{width:6px;height:6px;border-radius:50%;background:var(--primary);flex:none;
  display:inline-block;vertical-align:middle}
.ann-sec-h{font-size:11.5px;color:var(--text-3);margin:2px 0 8px;font-weight:650;letter-spacing:.02em}
/* 已读的卡用**底色**区分，不要用 opacity：
   opacity 会把整卡（含正文与按钮）一起压淡，已读公告照样要能读清楚 ——
   「我上周看过的那条说了什么」是高频诉求，压淡等于逼人去别处找。 */
.ann-card.is-read{background:var(--surface-2)}
/* 送达看板（只给发布者/管理员）：应读 / 已读 / 未读名单 */
.ann-deliver{display:flex;gap:6px;align-items:flex-start;margin-top:9px;padding-top:8px;
  border-top:1px dashed var(--border);font-size:11px;color:var(--text-3);line-height:1.55}
.ann-deliver .ico{flex:none;margin-top:2px;opacity:.8}
/* 铃铛面板里的「未读公告」分组：与下面的工单提醒之间加一条分隔线 ——
   两类消息来源不同，混成一片会让人分不清哪些是公告、哪些要处理工单。 */
.nt-ann{border-bottom:1px solid var(--border);margin-bottom:4px;padding-bottom:4px}

/* ============================================================
   登录页改回浅色背景（用户反馈深蓝渐变偏老气）
   外层背景回浅色，白卡加回边框与浅阴影；右侧幻灯片区保留深色做内容对比
   ============================================================ */
.gate{
  background:
    radial-gradient(900px 480px at 12% -8%, #E4ECFD 0%, transparent 62%),
    radial-gradient(700px 420px at 92% 108%, #E6F6F2 0%, transparent 60%),
    var(--bg);
}
.gate::before{display:none}
.gate-panel{
  border:1px solid var(--border);
  box-shadow:0 20px 50px rgba(23,32,46,.14), 0 2px 8px rgba(23,32,46,.06);
}

/* ============================================================
   登录页幻灯片改为图片式（纯大图铺满，去掉图标/标题/文字）
   ============================================================ */
.slide{padding:0;display:block}
.slide-img{width:100%;height:100%;object-fit:cover;display:block}
.slide-ico,.slide h3,.slide p{display:none}
.slide-dots{left:50%;transform:translateX(-50%);bottom:22px}

/* ============================================================
   登录表单比例优化：去掉框中框、切换改分段控件、按钮与输入框同比例
   ============================================================ */
.gate-form{padding:2px 0 0}
.gate-switch{display:flex;gap:4px;background:var(--surface-3);border-radius:var(--r-md);padding:3px;margin-bottom:14px}
.gswitch{flex:1;padding:5px 0;border-radius:7px;font-size:12px;font-weight:550;color:var(--text-2);background:none;border:none;text-align:center;transition:.15s;cursor:pointer}
.gswitch.on{background:var(--surface);color:var(--primary);box-shadow:0 1px 3px rgba(23,32,46,.12);font-weight:600}
.gate-login{width:100%;justify-content:center;padding:8px 13px;font-size:13px;border-radius:var(--r-md)}

/* ============================================================
   折叠卡片（details）+ 防整页横向溢出
   ============================================================ */
.fold-sec summary{
  display:flex;align-items:center;gap:8px;padding:12px 16px;cursor:pointer;
  list-style:none;user-select:none;
}
.fold-sec summary::-webkit-details-marker{display:none}
.fold-sec summary b{font-size:13.5px}
.fold-sec summary .sub{font-size:11.5px;color:var(--text-3);font-weight:400;margin-left:8px}
.fold-sec summary::after{content:"▸";margin-left:auto;color:var(--text-3);transition:.2s;font-size:12px}
.fold-sec[open] summary::after{content:"▾"}
.fold-sec[open] summary{border-bottom:1px solid var(--border)}

/* 防整页横向滚动：长串折行、容器不撑破 */
.sec,.card{min-width:0}
.dl dd,.note-block,.hint,.tl-text,.kcard-fault{overflow-wrap:break-word;word-break:break-word}
.fold-sec{align-self:start}   /* 收起时不被 grid 拉伸出大片空白 */

/* ============================================================
   派单看板：整体竖向滚动（跟普通页面一样滚，不用列内滚）。
   横向滚动条加粗常显 + 左右翻页按钮（board-scroll）辅助；
   触控板双指横滑 / shift+滚轮 也可横向切列。
   ============================================================ */
.kanban{
  overflow-x:auto;
  overflow-y:visible;
  padding-bottom:10px;
}
.kanban::-webkit-scrollbar{height:12px}
.kanban::-webkit-scrollbar-thumb{background:#C2CCDB;border-radius:6px}
.kanban::-webkit-scrollbar-thumb:hover{background:#A5B1C4}
.kcol{display:block;min-height:190px}
.kcol-cards{overflow:visible}

/* ============================================================
   派单看板紧凑模式：7 列塞进一屏（列宽等分 + 卡片缩小）
   ============================================================ */
.kanban{grid-auto-columns:minmax(150px,1fr);gap:8px}
.kcol{padding:8px}
.kcard{padding:8px 9px;margin-bottom:6px;border-left-width:2px}
.kcard-code{font-size:10px}
.kcard-dev{font-size:12px;margin-bottom:2px}
.kcard-fault{font-size:11px;line-height:1.4;-webkit-line-clamp:1;margin-bottom:5px}
.kcard-meta{font-size:10.5px;margin-bottom:5px}
.kcard-foot{padding-top:5px}
.kcard-owner{font-size:10.5px;gap:4px}
.kcard-owner .avatar{width:17px;height:17px;font-size:9px}
.kcard-foot .mono{font-size:10.5px}

/* ============================================================
   v27 · 质检单填写页（维修前 / 完工共用一套版式）
   ------------------------------------------------------------
   一屏要判十多项，所以版式只服务三件事：
   ① 每一行尽量矮 —— 判定做成三段控件，一行放得下，不再三张卡叠三行；
   ② 三档位置固定（正常 / 异常 / 不适用 每次都在同一顺序、同一起点），
      连判十几项时手不用重新找目标；
   ③ 判过的项一眼可见 —— 正常绿、异常红、不适用灰，扫一遍就知道还剩哪几项。
   ============================================================ */
/* 宽度与打印预览（.print-modal）同宽：12 项分两列后，一列仍有富余放「提示」那一行，
   不然「要与收件核验照对得上」这种长提示会被拆成两行、把行高顶起来。
   同一张单的「填写」与「出纸预览」用同一个宽度，来回切也不跳。 */
.modal.qc-modal{max-width:940px}
.qc-lead{display:flex;gap:8px;align-items:flex-start;font-size:12px;color:var(--text-2);line-height:1.6;margin-bottom:12px}
.qc-lead .ico{width:15px;height:15px;flex:none;margin-top:2px;color:var(--primary)}

/* 进度条：报了数才知道还剩几项 */
.qc-bar{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:8px 12px;margin-bottom:12px;
  background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-md);
  font-size:11.5px;color:var(--text-3);
}
.qc-bar .qc-count{color:var(--text-2)}
.qc-bar .qc-count b{font-family:var(--ff-num);font-size:14px;color:var(--text);margin:0 2px}
.qc-bar.done .qc-count b{color:var(--ok)}
.qc-bar .qc-done{display:none;align-items:center;gap:4px;color:var(--ok);font-weight:600}
.qc-bar.done .qc-done{display:inline-flex}
.qc-bar .qc-legend{margin-left:auto;display:inline-flex;align-items:center;gap:4px}
.qc-bar .qc-legend i{display:inline-block;width:7px;height:7px;border-radius:50%;margin-left:8px}
.qc-bar .qc-legend i.ok{background:var(--ok)}
.qc-bar .qc-legend i.bad{background:var(--danger)}
.qc-bar .qc-legend i.na{background:var(--text-3)}

/* 清单：两列，一行一项；窄屏收成一列 */
.qc-list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
.qc-row{
  display:flex;align-items:center;gap:10px;padding:8px 12px;min-height:44px;
  border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface);transition:.14s;
}
.qc-row:hover{border-color:var(--primary-line)}
.qc-no{flex:none;width:16px;font-family:var(--ff-num);font-size:11px;color:var(--text-3);text-align:right}
.qc-name{flex:1;min-width:0}
.qc-name b{display:block;font-size:12.5px;font-weight:600;line-height:1.45}
.qc-hint{display:block;font-size:10.5px;color:var(--text-3);line-height:1.5;margin-top:2px}

/* 三段控件。选中态纯 CSS 上色：不加类、不等重绘，连判十几项也跟手 */
.qcseg{flex:none;margin-left:auto;display:inline-flex;gap:2px;padding:2px;background:var(--surface-3);border-radius:var(--r-md)}
.qcseg-i{position:relative;cursor:pointer;border-radius:var(--r-sm)}
.qcseg-i input{position:absolute;opacity:0;width:0;height:0}
.qcseg-i span{
  display:block;padding:4px 10px;border-radius:var(--r-sm);font-size:11.5px;color:var(--text-2);
  white-space:nowrap;transition:.14s;
}
.qcseg-i:hover span{background:var(--surface);color:var(--text)}
.qcseg-i input:checked+span{background:var(--surface);color:var(--text);font-weight:650;box-shadow:var(--shadow-1)}
.qcseg-i.ok input:checked+span{color:var(--ok)}
.qcseg-i.bad input:checked+span{color:var(--danger)}
.qcseg-i.na input:checked+span{color:var(--text-2)}

/* 结论两档等宽（.pick 自带 min-width，用网格分栏才不会一宽一窄） */
.qc-verdict{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
.qc-verdict .pick{min-width:0}

/* 机况标签（多选 chip）。样式沿用 .chip 的语言，但用 label + 隐藏 checkbox 实现多选：
   选中态靠 `input:checked + span` 上色，不动父元素 —— 不用 :has()，
   老一点的浏览器也不会「点了没反应」。 */
.qflags{display:flex;flex-wrap:wrap;gap:6px}
.qchip{display:inline-flex;cursor:pointer}
.qchip input{position:absolute;opacity:0;width:0;height:0}
.qchip span{
  padding:4px 11px;border:1px solid var(--border);border-radius:20px;background:var(--surface);
  font-size:11.5px;color:var(--text-2);transition:.12s;
}
.qchip:hover span{border-color:var(--primary-line);color:var(--text)}
.qchip input:checked+span{border-color:var(--primary);background:var(--primary-soft);color:var(--primary-dark);font-weight:600}
/* 高风险四项（进水 / 重摔 / 不开机 / 二修）单独给琥珀色：
   它们决定能不能修、报什么价、给不给质保，不该和「换过电池」长得一样 */
.qchip.risk input:checked+span{border-color:var(--warn);background:#FDF4E5;color:var(--warn-dark)}
/* 「无以上情况」是阴性结论，用绿色收口，避免和阳性标签混淆 */
.qchip.clear input:checked+span{border-color:var(--ok);background:#E9F7F1;color:#0A6E4C}

@media (max-width:820px){
  .qc-list{grid-template-columns:1fr}
  .qc-verdict{grid-template-columns:1fr}
}

/* ============================================================
   v32 大屏（工作大屏 / 收发大屏共用一套词汇）
   ------------------------------------------------------------
   为什么收成一套：工作台与收发大屏是同一类页面（站远了看），
   原先收发大屏把色值全内联写死在 views.js 里，改一次底色要改十几处。
   收成变量后，底色只是 `.scr[data-bg]` 的一次切换。
   **作用域只在 .scr 容器内** —— 全局浅色主题（:root）一行不动，
   避免拖累其余四十多页的对比度。
   ============================================================ */
.scr{
  --scr-bg:#0B1219; --scr-panel:#111A22; --scr-line:#223041;
  --scr-ink:#E8EEF5; --scr-dim:#7C8B9C; --scr-code:#8FC7FF;
  --scr-ok:#3FBF7F; --scr-warn:#F2B94B; --scr-danger:#F26D6D;
  background:var(--scr-bg); color:var(--scr-ink);
  /* 负外边距正好抵掉 .content 的 24px 内边距 —— 大屏要真正铺满，
     留一圈浅色边（原收发大屏用 -18px，四周各漏 6px）就不叫大屏了。 */
  margin:-24px; padding:24px 24px 24px;
  min-height:calc(100vh - var(--top-h));
}
/* 墨黑：OLED 挂机省电，长时间不烧屏 */
.scr[data-bg="ink"]{--scr-bg:#05070A;--scr-panel:#0C1014;--scr-line:#1B222B;--scr-code:#7FB6F0}
/* 浅灰：办公室/会议投屏，白墙不反光的环境下比深底耐看 */
.scr[data-bg="light"]{
  --scr-bg:#EEF1F6; --scr-panel:#FFFFFF; --scr-line:#DDE3EC;
  --scr-ink:#1A2333; --scr-dim:#5C6B80; --scr-code:#2B5CE6;
  --scr-ok:#0E7A54; --scr-warn:#8A5200; --scr-danger:#B3272A;
}

/* ---------- 大屏页头 ---------- */
.scr-head{display:flex;align-items:center;gap:14px;margin-bottom:14px;flex-wrap:wrap}
.scr-h1{font-size:26px;font-weight:800;color:var(--scr-ink);letter-spacing:.5px}
.scr-hsub{font-size:12.5px;color:var(--scr-dim)}
.scr-clock{font-size:30px;font-weight:800;color:var(--scr-ink);font-variant-numeric:tabular-nums}
.scr-actions{margin-left:auto;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
/* 企业标识（v34）：挂在墙上 / 摆在会客区的那一屏，是这台机器露在外面的「正面」，
   得看得出是哪家公司的屏。图是**全彩透明底**那一张（branding().logo）。
   两条约束：
     ① 尺度 —— 高 24px、最宽 150px、等比缩放（object-fit:contain）。
        页头的主人是标题（26px），标识是「这家公司」的署名；
        放开尺寸它就会自己长成页头里最大的那块，把标题挤到第二眼。
     ② 底色 —— 深蓝 / 墨黑两档下整张反相：invert 把黑字翻成白字，
        再接 hue-rotate(180°) 把品牌蓝**转回蓝**（只 invert 的话蓝会变成橙）——
        于是三档底色下都是「白字 + 蓝弧线」，不会有白底方块，
        也不会为了看得见而牺牲品牌色。浅灰档不反转（本来就该是黑字蓝弧线）。 */
.scr-brand{flex:none;display:flex;align-items:center}
.scr-logo{display:block;height:24px;width:auto;max-width:150px;object-fit:contain}
.scr[data-bg="dark"] .scr-logo,.scr[data-bg="ink"] .scr-logo{filter:invert(1) hue-rotate(180deg)}

/* ---------- KPI 行 ---------- */
.scr-kpis{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:12px;margin-bottom:14px}
.scr-kpis.k4{grid-template-columns:repeat(4,minmax(0,1fr))}
.scr-kpi{background:var(--scr-panel);border:1px solid var(--scr-line);border-radius:var(--r-md);padding:14px 16px;min-width:0}
.scr-kpi .k-label{font-size:12px;color:var(--scr-dim);display:flex;align-items:center;gap:6px;margin-bottom:8px}
.scr-kpi .k-val{font-size:28px;font-weight:800;line-height:1;color:var(--scr-ink);font-variant-numeric:tabular-nums}
.scr-kpi .k-val small{font-size:13px;font-weight:600;color:var(--scr-dim);margin-left:4px}
.scr-kpi .k-sub{font-size:11px;color:var(--scr-dim);margin-top:8px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.scr-kpi.acc-ok .k-val{color:var(--scr-ok)}
.scr-kpi.acc-warn .k-val{color:var(--scr-warn)}
.scr-kpi.acc-danger .k-val{color:var(--scr-danger)}
.scr-kpi.acc-accent .k-val{color:var(--scr-code)}

/* ---------- 面板 ----------
   栅格一律**一块整板**（g12 = 12 栏），面板按 12 栏分跨度，而不是一块一块地
   各自成行。原先的做法（每行一个 .scr-grid + align-items:start）在深色大屏上
   非常显眼：同一行里高的那格往下长，矮的那格原地结束，
   于是「东一块西一块」，边框参差、右下角空一大片 —— 像没加载完。
   现在的三条口径：
     ① 所有面板进同一张 12 栏网格，行与行之间自动对齐；
     ② align-items 用默认的 stretch，同一行的面板高度一律拉平，下边缘成一条线；
     ③ 面板内部 body 自己滚（max-height 封顶），所以「内容多少」不再决定「格子多高」，
        一屏里不会因为某一格有 20 行就把整行顶得老高。 */
.scr-grid{display:grid;gap:14px;margin-bottom:14px}
.scr-grid.g12{grid-template-columns:repeat(12,minmax(0,1fr))}
.scr-grid.g2{grid-template-columns:1fr 1fr}
.scr-grid.g3{grid-template-columns:1fr 1fr 1fr}
.scr-grid.g-main{grid-template-columns:minmax(0,1.5fr) minmax(320px,1fr)}
.scr-grid>[class*="sp"]{min-width:0}
.sp2{grid-column:span 2}.sp3{grid-column:span 3}.sp4{grid-column:span 4}
.sp5{grid-column:span 5}.sp6{grid-column:span 6}.sp7{grid-column:span 7}
.sp8{grid-column:span 8}.sp9{grid-column:span 9}.sp12{grid-column:span 12}
.scr-panel{background:var(--scr-panel);border:1px solid var(--scr-line);border-radius:14px;padding:14px 18px;display:flex;flex-direction:column;min-height:0;overflow:hidden}
.scr-panel-head{display:flex;align-items:baseline;gap:10px;margin-bottom:8px;flex:none}
.scr-panel-title{font-size:19px;font-weight:700;color:var(--scr-ink)}
.scr-panel-sub{font-size:12.5px;color:var(--scr-dim);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.scr-panel-count{margin-left:auto;font-size:30px;font-weight:800;font-variant-numeric:tabular-nums;flex:none}
/* body 撑满剩余高度并自己滚：格子高度由「这一行里最高的那格」决定，
   而不是由「内容最多的那一格」把整行顶长 —— 一屏能装下的格数因此可预期 */
.scr-panel-body{min-width:0;flex:1;overflow:auto;max-height:min(46vh,440px)}
/* 大屏里不画滚动条（v35.4）：那一屏是站在两米外看的，
   一条灰条杵在「张数」旁边只像一道裂缝，没有任何阅读价值；
   而滚动本身要保留（面板内容多时照常滚）—— 只藏外观，不藏能力。
   scrollbar-width 给 Firefox，::-webkit-scrollbar 给 Chrome / Safari / 内置浏览器。 */
.scr *{scrollbar-width:none}
.scr *::-webkit-scrollbar{display:none}
.scr-empty{font-size:14px;color:var(--scr-dim);padding:18px 0;text-align:center}
.scr-foot{margin-top:auto;padding-top:8px;font-size:12.5px;color:var(--scr-dim);flex:none}

/* ---------- 面板密度的自然形态（v35.3）----------
   「扑克收缩」（v34 的 deck）删了：把内容藏进 hover 里，正是「信息阅读不全」的来源；
   而且同一行里一张摊开、一张收着，布局高度随鼠标挪动而变 —— 挂机屏上最忌这种抖动。
   现在的口径是「满则滚、不满则开」，全部交给一条自然规则：
     · 内容少的格子按内容自然展开（整格读完，不留空白也不藏字）；
     · 内容多的格子 body 在 46vh 内部滚动（.scr-panel-body 的既有规则），
       格子不会把整屏无限拉长；
     · 全屏时整块 .scr 自己滚动（见「全屏后能上下滑动」）。
   同一行的底边由 grid 拉平（stretch），矮格拉伸、高格决定行高 —— 与 v33 同一套。 */

/* ---------- 面板内的行 ---------- */
.scr-row{display:flex;align-items:center;gap:12px;padding:8px 0;border-bottom:1px dashed var(--scr-line)}
.scr-code{font-family:ui-monospace,Menlo,monospace;font-size:15px;font-weight:700;color:var(--scr-code);min-width:120px;flex:none}
.scr-row-main{flex:1;min-width:0}
.scr-row-t{font-size:15px;font-weight:600;color:var(--scr-ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.scr-row-s{font-size:12.5px;color:var(--scr-dim);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.scr-row-r{font-size:14px;font-weight:700;white-space:nowrap;flex:none}

/* ---------- 待办条（工作大屏专用） ---------- */
.scr-todos{display:flex;flex-wrap:wrap;gap:8px}
.scr-todo{
  display:inline-flex;align-items:center;gap:8px;cursor:pointer;
  background:var(--scr-panel);border:1px solid var(--scr-line);border-radius:20px;
  padding:7px 14px 7px 12px;font-size:13.5px;color:var(--scr-ink);font-family:inherit;
}
.scr-todo:hover{border-color:var(--scr-code)}
.scr-todo .td-dot{width:8px;height:8px;border-radius:50%;flex:none}
.scr-todo .td-n{font-size:15px;font-weight:800;font-variant-numeric:tabular-nums}
.scr-todo .td-go{font-size:11.5px;color:var(--scr-dim)}
.scr-strip{margin-bottom:14px}
.scr-done{
  display:inline-flex;align-items:center;gap:8px;padding:11px 16px;border-radius:var(--r-md);
  background:var(--scr-panel);border:1px solid var(--scr-line);font-size:13.5px;color:var(--scr-ok);
}
/* 面板内的小节标题（一个面板回答两个相关问题时用它分栏） */
.scr-sub-h{font-size:11.5px;letter-spacing:.5px;color:var(--scr-dim);margin:10px 0 2px}

/* 业务主线流转条（大屏版）：与紧凑模式的 .flow-strip 同构，
   区别只在底色 —— 浅色主题那一套扣在深底上会看不见。
   v35.3：去掉 overflow-x:auto 与 min-width —— 七个节点 + 六个分隔符
   必须在一行内放下（这是「主线」：横着读完才看得出卡在哪一段），
   放不下就缩字号与间距，而不是让人左右拉。 */
.scr-flow{display:flex;align-items:flex-end;gap:2px}
.scr-flow-node{flex:1;min-width:0;text-align:center}
.scr-flow-node .fn-name{font-size:10.5px;color:var(--scr-dim);white-space:nowrap}
.scr-flow-node .fn-num{font-size:17px;font-weight:800;color:var(--scr-ink);font-variant-numeric:tabular-nums;margin:1px 0 4px}
.scr-flow-node .fn-bar{height:5px;border-radius:3px;background:var(--scr-line);overflow:hidden}
.scr-flow-node .fn-bar i{display:block;height:100%;background:var(--scr-code);border-radius:3px}
.scr-flow-sep{color:var(--scr-dim);font-size:13px;padding-bottom:16px;flex:none}

/* 可点的页头 KPI 卡（v32）：包住 .stat 的壳，本身不画底色。
   只给一点位移反馈 —— 否则「点卡即筛」这个交互没人知道存在。 */
.kpi-click{cursor:pointer;border-radius:var(--r-md);transition:transform .12s ease}
.kpi-click:hover{transform:translateY(-2px)}
.kpi-click>*{height:100%}

/* ---------- 大屏内的深浅色工具 ---------- */
/* 默认 .seg 是「浅底深字」，扣在深底上像贴了张白纸 —— 大屏里改成透明底描边 */
.scr .seg{background:transparent;border:1px solid var(--scr-line);color:var(--scr-dim)}
.scr .seg button{color:var(--scr-dim)}
.scr .seg button.on{background:var(--scr-code);color:var(--scr-bg);box-shadow:none}
.scr-dim{color:var(--scr-dim)}
.scr-ink{color:var(--scr-ink)}
.scr-ok{color:var(--scr-ok)}
.scr-warn{color:var(--scr-warn)}
.scr-danger{color:var(--scr-danger)}
.scr-code{color:var(--scr-code)}

/* ---------- 大屏模式下的全屏沉浸：藏掉侧栏与顶栏 ---------- */
body.is-screen .sidebar{display:none}
body.is-screen .main{margin-left:0}
body.is-screen .topbar{display:none}
body.is-screen .content{padding:0;overflow:auto}
body.is-screen .scr{margin:0;min-height:100vh}

/* ---------- 全屏之后还能上下滑动（v34） ----------
   把整块 .scr 送进全屏后，浏览器只渲染这一块，它落在 top layer 上 ——
   祖先的滚动条（.content / window）再也够不着它。于是内容一超高就是
   「明明看得到下边还有东西、就是滑不动」，大屏上等于下半屏作废。
   所以全屏时让 .scr 自己成为滚动容器，并把内边距重新写死一遍
   （UA 给全屏元素的那套规则里 padding 归零，四边会贴到屏幕边上）。
   -webkit- 那一行给旧 Safari 与内置浏览器。 */
.scr:fullscreen,.scr:-webkit-full-screen{
  overflow:auto;height:100vh;min-height:0;
  /* 上下对称（原 22px / 34px 不对称，全屏后顶部贴得近、底部留一大块 —— 挂墙屏最显眼） */
  padding:26px 24px 26px;
}
/* 页头吸顶：滚下去之后，企业标识、时钟、底色 / 全屏 / 刷新这些开关还留在手边 */
body.is-screen .scr-head{
  position:sticky;top:0;z-index:25;
  background:var(--scr-bg);padding:10px 0 12px;margin-bottom:8px;
}

/* ---------- 通用大屏的正文壳（v35） ----------
   日常页整页装进大屏时（见 views.js 的 SCR_PAGES），正文比平时放大一档：
   表头 13.5px 在三米外读不出来，而全站字号是 px 写死的 ——
   能让它们**等比**放大的只有 zoom（transform:scale 会留一块空白、
   还得自己算高度）。窄屏不放大：屏幕本来就不够宽时再放大，
   等于逼人左右拉，那一档自己回落。 */
.scr-page{zoom:1.2}
@media (max-width:1400px){.scr-page{zoom:1.08}}
@media (max-width:1180px){.scr-page{zoom:1}}

/* ---------- 响应式回落：窄屏不放大屏字号，避免每天滚三屏 ---------- */
@media (max-width:1400px){
  .scr-kpis{grid-template-columns:repeat(3,minmax(0,1fr))}
  /* 12 栏收成 6 栏：跨度按比例折半，两栏并排的仍然两栏并排 */
  .scr-grid.g12{grid-template-columns:repeat(6,minmax(0,1fr))}
  .scr-grid.g12>.sp12{grid-column:span 6}
  .scr-grid.g12>.sp8,.scr-grid.g12>.sp9,.scr-grid.g12>.sp7{grid-column:span 6}
  .scr-grid.g12>.sp6{grid-column:span 6}
  .scr-grid.g12>.sp5{grid-column:span 3}
  .scr-grid.g12>.sp4,.scr-grid.g12>.sp3,.scr-grid.g12>.sp2{grid-column:span 3}
}
@media (max-width:1180px){
  .scr-grid.g3,.scr-grid.g-main{grid-template-columns:1fr}
  /* 一栏到底：所有跨度都归 1，面板竖着排 */
  .scr-grid.g12{grid-template-columns:1fr}
  .scr-grid.g12>*{grid-column:span 1}
}
@media (max-width:900px){
  .scr-kpis,.scr-kpis.k4{grid-template-columns:repeat(2,minmax(0,1fr))}
  .scr-grid.g2{grid-template-columns:1fr}
  .scr{padding:14px 14px 20px}
  .scr-h1{font-size:20px}
  .scr-clock{font-size:22px}
  .scr-panel-title{font-size:16px}
  .scr-panel-count{font-size:24px}
  .scr-kpi .k-val{font-size:22px}
  .scr-code{min-width:0}
}
