/* ══════════════════════════════════════════════════════════════════════════
   apple.css —— Apple 视觉层（2026-10-21）
   ──────────────────────────────────────────────────────────────────────────
   老板原话：「全面复刻苹果系统的字体、操作界面」。本文件就是那一层。

   ## 三条边界（违反会返工）
   1. **不定义任何色值令牌**。颜色唯一真源仍是 `work/wb2.html` + `work/app.css`
      的 `:root`（`tools/check_tokens_parity.py` 机器校验）。这里只 `var(--*)`。
   2. **不改任何宽度/定位**。`--gx/--gi/--edge` 决定的「内容左边缘 40px 对齐」
      由 `tools/check-layout.mjs` 卡 1px 公差，动 padding-left 就会红。
      本文件只改：字体、颜色、圆角、描边、阴影、行内密度、垂直节奏。
   3. **必须最后加载**（各页面 `</head>` 前）。同特异性下靠文档顺序胜出；
      提前加载 = 被页面自己的 `<style>` 压回去，改了等于没改。

   ## 为什么用「覆盖层」而不是逐页改 CSS
   全站 17 个页面、其中 `wb2.html` 单文件 550KB。逐页改 = 17 条漂移路径。
   覆盖层 = 1 处生效、1 处回滚（删掉这行 `<link>` 就回到旧版）。

   ## 设计依据（macOS 14 / apple.com 浅色）
   · 字体：SF Pro（系统字体）+ PingFang SC；字距 -0.003em，抗锯齿开启
   · 底色 #f5f5f7 / 面板 #fff / 正文 #1d1d1f / 次要 #6e6e73
   · 圆角：控件 8 · 卡片 14 · 弹窗 16 · 胶囊全圆
   · 阴影：只做 1px 级「贴纸感」，不做大面积投影
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 0. 字体：真·苹果栈 ─────────────────────────────────────────────────── */
html{-webkit-text-size-adjust:100%}
body{
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","SF Pro Display",
    "Helvetica Neue","PingFang SC","Hiragino Sans GB","Microsoft YaHei UI",
    "Microsoft YaHei",system-ui,sans-serif;
  font-size:var(--fs-base); line-height:1.5; letter-spacing:-.003em;
  color:var(--ink); background:var(--bg);
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
}
/* 标题走 SF Display 的紧字距；中文靠 PingFang 的 600 字重撑起来 */
h1,h2,h3,h4{letter-spacing:-.022em; font-weight:600; color:var(--ink)}
b,strong{font-weight:600}
/* 数字一律等宽（表格对不对得齐全看这一条） */
.dcard .v,.sig,.num,.af-v,.cn-cell.num,.kpi,.stat b,td.num,th.num{
  font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1;
}
::selection{background:rgba(0,113,227,.18)}
:focus-visible{outline:2px solid rgba(0,113,227,.6); outline-offset:2px}

/* ── 1. 侧边导航：macOS 侧栏（浅灰底 + 选中白胶囊） ─────────────────────
   🔴 2026-10-21 修：原来这里的选择器写的是 `.side-nav`（首页 wb2 用这个类），
      但另外 6 个页面（finance/handover/clients/apply/baodan/…）用的是 `.sidenav`
      —— 所以那 6 页的侧栏**从来没吃到过苹果样式**，还是 172px 带描边的老样子。
      现在两种类名一起覆盖，宽度统一 208px。
   ✅ 208px 已定稿（老板 2026-10-21）：宽度**只写在这里一处**，各页原有的 172/186px
      因为特异性相同、apple.css 后加载而被覆盖，不必逐页去删（删了反而失去回滚能力）。 */
:root{ --side-w:208px; --side-w-sm:64px }
:is(.side-nav,.sidenav){
  width:var(--side-w); flex:0 0 var(--side-w);
  background:#fbfbfd; border-right:1px solid rgba(0,0,0,.07);
  padding:14px 10px 10px; gap:1px;
}
.brand{padding:0 8px 18px}
.brand .mk{width:24px;height:24px;border-radius:7px;background:var(--blue)}
.brand .tx,:is(.side-nav,.sidenav) .slogo{
  font-size:15px; font-weight:600; letter-spacing:-.02em; color:var(--ink);
  padding:0 8px 18px;
}
:is(.side-nav,.sidenav) .grplabel,:is(.side-nav,.sidenav) .sgroup{
  font-size:12px; font-weight:500; color:var(--ink-3);
  letter-spacing:.02em; padding:16px 10px 6px;
}
:is(.side-nav,.sidenav) a.nv,:is(.side-nav,.sidenav) a.sitem{
  height:34px; padding:0 10px; border-radius:8px; gap:9px;
  font-size:14px; font-weight:400; color:#3c3c43;
  transition:background .14s ease,color .14s ease,box-shadow .14s ease;
}
:is(.side-nav,.sidenav) a.nv:hover,:is(.side-nav,.sidenav) a.sitem:hover{background:rgba(0,0,0,.045); color:var(--ink)}
:is(.side-nav,.sidenav) a.nv.on,:is(.side-nav,.sidenav) a.sitem.on{
  background:#fff; color:var(--blue); font-weight:600;
  box-shadow:0 1px 2px rgba(0,0,0,.07),0 0 0 .5px rgba(0,0,0,.05);
}
:is(.side-nav,.sidenav) a.nv svg,:is(.side-nav,.sidenav) a.sitem svg{width:16px; height:16px; stroke-width:1.5; opacity:.85}
:is(.side-nav,.sidenav) a.nv.on svg,:is(.side-nav,.sidenav) a.sitem.on svg{opacity:1}
.nav-foot{border-top:1px solid rgba(0,0,0,.06); padding-top:10px}
.viewbox{border:1px solid rgba(0,0,0,.08); border-radius:9px; background:#fff}

/* ── 2. 列表栏（企业 / 线索）：去边框、靠留白分组 ─────────────────────── */
.side-list{background:#fff; border-right:1px solid rgba(0,0,0,.07)}
.list-head{
  background:rgba(255,255,255,.92); border-bottom:1px solid rgba(0,0,0,.06);
  -webkit-backdrop-filter:saturate(180%) blur(20px);
  backdrop-filter:saturate(180%) blur(20px);
}
.list-title{font-size:20px; font-weight:600; letter-spacing:-.022em}
.list-title .n{font-size:13px; color:var(--ink-3); font-weight:400}
.list-rows{padding:4px 8px 14px; gap:1px}
.list-row{
  border:0; background:transparent; border-radius:10px; box-shadow:none;
  padding:11px 12px;
  transition:background .14s ease;
}
.list-row:hover{background:#f5f5f7; border:0; transform:none; box-shadow:none}
.list-row.on{background:var(--blue-bg); border:0}
.list-row.on::before{left:4px; top:12px; bottom:12px; width:3px; border-radius:2px; background:var(--blue)}
.list-row .nm{font-size:15px; font-weight:600; letter-spacing:-.01em}
.list-row .r2{color:var(--ink-2)}

/* ── 2b. 抽屉关着时：企业列表改**两列**（老板 2026-10-21「按你的建议来」）──
   🔴 原来抽屉没开时 `.side-list` 铺满 1512px，一行只有「公司名 …… 1份合同」，
      中间一大片空白，一屏只看得下 7 家 —— 这就是"空"的来源。
      改两列后同宽能看 14 家；抽屉一打开（body.drawer-open）自动回到单列，
      因为那时列表只有 262px 宽，两列会挤成竖条。 */
@media(min-width:1180px){
  body:not(.drawer-open) #rows.list-rows{
    display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
    gap:8px; padding:10px 3px 24px; align-items:start;
  }
  body:not(.drawer-open) #rows.list-rows > .list-row{
    border:1px solid rgba(0,0,0,.07); border-radius:12px; background:#fff;
    padding:12px 14px; min-height:64px; justify-content:center;
  }
  body:not(.drawer-open) #rows.list-rows > .list-row:hover{
    background:#fff; border-color:rgba(0,0,0,.12);
    box-shadow:0 4px 14px rgba(0,0,0,.07);
  }
  body:not(.drawer-open) #rows.list-rows > .table-empty,
  body:not(.drawer-open) #rows.list-rows > .empty-tip{grid-column:1 / -1}
}

/* ── 3. 工作台指标（#dash）──────────────────────────────────────────────
   🔴 指标卡在 1512 宽下每格约 370px，原来 21px 的数字 + 灰底 = 大片空白方块，
      是"空、乱"的观感来源。改成：**白卡 + 发丝边 + 30px 数字**，
      用字号撑起卡片（Apple 的统计卡就是这么做的），而不是用色块。 */
#dash{padding:16px 20px 6px; background:#fff}
#dash .dhead{margin-bottom:12px}
#dash .dhead b{font-size:20px; font-weight:600; letter-spacing:-.022em}
#dash .dtip{font-size:12px; color:var(--ink-3); letter-spacing:0}
#dash .dcards{gap:10px}
#dash .dcard{
  background:#fff; border:1px solid rgba(0,0,0,.07); border-radius:12px;
  padding:11px 14px; box-shadow:0 1px 2px rgba(0,0,0,.03);
  transition:border-color .15s ease,box-shadow .15s ease;
}
#dash .dcard:hover{border-color:rgba(0,0,0,.14); box-shadow:0 2px 8px rgba(0,0,0,.05)}
#dash .dcard .k{font-size:12px; color:var(--ink-2); font-weight:400; margin-bottom:2px}
#dash .dcard .v{font-size:30px; font-weight:600; letter-spacing:-.03em; line-height:1.15; color:var(--ink)}
#dash .dcard.on{background:var(--blue-bg); border-color:rgba(0,113,227,.28)}
#dash .dcard.on .v{color:var(--blue-ink)}
#dash .dband{
  gap:6px 8px; margin-top:12px; padding-top:12px;
  border-top:1px solid var(--line-2); font-size:13px;
}
#dash .dband .step{
  /* 🔴 这一条**必须重置 display**：`.step` 同时被工作流节点用（flex-column + min-width:76px），
     不重置就会变成「名字一行、数字一行」的竖排小块（实测截图里就是这么坏的）。 */
  display:inline-flex; flex-direction:row; align-items:baseline; gap:5px;
  min-width:0; min-height:0; cursor:pointer; white-space:nowrap;
  border:0; border-radius:7px; padding:4px 9px;
  background:var(--gray-bg); color:var(--ink-2);
  font-size:12px; font-weight:400;
  transition:background .14s ease,color .14s ease;
}
#dash .dband .step:hover{background:#e9e9ef; color:var(--ink)}
#dash .dband .step b{color:var(--ink); font-weight:600; margin:0; font-size:12px}
/* 顶栏里给「报单」一个主按钮身份 —— 5 个白按钮并排等于没有主次 */
#dash .dhead button[onclick="goBaodan()"]{
  background:var(--blue); border-color:transparent; color:#fff; font-weight:500;
  box-shadow:0 1px 2px rgba(0,113,227,.3);
}
#dash .dhead button[onclick="goBaodan()"]:hover{background:#0077ed}

/* ── 4. 按钮：macOS 控件 ─────────────────────────────────────────────── */
button,.btn,.btn-ghost{
  font-family:inherit; font-size:14px; font-weight:500; line-height:1.2;
  color:var(--ink); background:#fff; border:1px solid rgba(0,0,0,.1);
  border-radius:8px; padding:7px 14px;
  box-shadow:0 1px 1.5px rgba(0,0,0,.04);
  transition:background .14s ease,border-color .14s ease,box-shadow .14s ease,
             transform .06s ease;
}
button:hover,.btn:hover,.btn-ghost:hover{background:#fafafc; border-color:rgba(0,0,0,.14)}
button:active{transform:scale(.985)}
button.pri,.btn.pri{
  background:var(--blue); border-color:transparent; color:#fff; font-weight:500;
  box-shadow:0 1px 2px rgba(0,113,227,.3);
}
button.pri:hover,.btn.pri:hover{background:#0077ed}
button.ghost,.btn.ghost,.btn-ghost{background:#fff; color:var(--ink); border-color:rgba(0,0,0,.1)}
button.ghost:hover,.btn.ghost:hover{background:var(--gray-bg)}
button.ok,.btn.ok{background:var(--green-bg); border-color:transparent; color:var(--green)}
button.warn,.btn.warn{background:var(--amber-bg); border-color:transparent; color:var(--amber)}
button.sm,.btn.sm{font-size:13px; padding:4px 10px; border-radius:7px}
button:disabled,.btn:disabled{opacity:.4; box-shadow:none; cursor:not-allowed}

/* ── 5. 表单：浅灰描边 + 蓝色焦点环 ─────────────────────────────────── */
input,select,textarea{
  font-family:inherit; font-size:14px; color:var(--ink);
  background:#fff; border:1px solid rgba(0,0,0,.12); border-radius:8px;
  padding:7px 10px; box-shadow:inset 0 1px 1px rgba(0,0,0,.02);
  transition:border-color .14s ease,box-shadow .14s ease;
}
input:focus,select:focus,textarea:focus{
  outline:none; border-color:var(--blue);
  box-shadow:0 0 0 3.5px rgba(0,113,227,.15);
}
input:disabled,textarea[readonly]{background:var(--gray-bg); color:var(--ink-2)}
::placeholder{color:#a1a1a6}
label{font-size:13px; color:var(--ink-2); font-weight:500; margin:10px 0 4px}

/* ── 6. 表格：去掉外框，只留横向发丝线 ───────────────────────────────── */
table{border:0; background:transparent; border-radius:0}
th{
  background:transparent; color:var(--ink-2); font-size:13px; font-weight:500;
  letter-spacing:.01em; padding:9px 12px; border-bottom:1px solid rgba(0,0,0,.1);
}
td{border-bottom:1px solid var(--line-2); padding:11px 12px; font-size:14px}
tr:hover td{background:#fafafc}
tbody tr:last-child td{border-bottom:0}

/* ── 7. 标签 / 胶囊：去描边、用底色分层 ─────────────────────────────── */
.tag{
  height:auto; min-height:20px; padding:2px 8px; border-radius:6px;
  font-size:12px; font-weight:500; border:0;
  background:var(--gray-bg); color:var(--ink-2);
}
.tag.blue{background:var(--blue-bg); color:var(--blue-ink)}
.tag.green{background:var(--green-bg); color:var(--green)}
.tag.red{background:var(--red-bg); color:var(--red)}
.tag.amber{background:var(--amber-bg); color:var(--amber)}
.pill{
  height:26px; padding:0 10px; border-radius:13px; font-size:12px; font-weight:500;
  background:var(--gray-bg); color:var(--ink-2); border:1px solid transparent;
}
.pill.ok{background:var(--green-bg); border-color:transparent; color:var(--green)}
.pill.warn{background:var(--amber-bg); border-color:transparent; color:var(--amber)}
.pill.info{background:var(--blue-bg); border-color:transparent; color:var(--blue-ink)}
.pill.dang,.pill.danger{background:var(--red-bg); border-color:transparent; color:var(--red)}
.pill.clickable:hover{background:#e9e9ef; border-color:transparent}
.srcchip{
  height:auto; padding:1px 5px; border-radius:4px; border:0;
  font-size:11px; font-weight:600; background:var(--gray-bg); color:var(--ink-3);
}
.sig{height:18px; min-width:18px; padding:0 5px; border:0; border-radius:9px;
  background:var(--gray-bg); color:var(--ink-2); font-size:11px; font-weight:600}
.sig.over{background:var(--red-bg); color:var(--red)}
.cntp{border-radius:7px; padding:2px 7px; font-size:12px}
.cntp.many{background:#fff; border:1px solid rgba(0,0,0,.08); color:var(--blue-ink)}

/* ── 8. 卡片 / 面板 / 顶栏 ──────────────────────────────────────────── */
.panel-card{
  background:#fff; border:1px solid rgba(0,0,0,.06); border-radius:14px;
  box-shadow:0 1px 2px rgba(0,0,0,.04);
}
.panel-card h3{font-size:16px; font-weight:600; letter-spacing:-.012em}
.hd{
  background:rgba(255,255,255,.86); border-bottom:1px solid rgba(0,0,0,.08);
  -webkit-backdrop-filter:saturate(180%) blur(20px);
  backdrop-filter:saturate(180%) blur(20px);
  padding:14px 20px;
}
.hd h1,.archive-bar h1{font-size:22px; font-weight:600; letter-spacing:-.022em}
.grp{
  font-size:12px; font-weight:500; color:var(--ink-3); letter-spacing:.02em;
  margin:18px 0 8px; padding-bottom:6px; border-bottom:1px solid var(--line-2);
}
.tip{font-size:13px; line-height:1.55; color:var(--ink-2)}
.empty,.table-empty,.empty-tip{font-size:13px; color:var(--ink-3); padding:28px 0; text-align:center}

/* 分段控件（企业 / 线索 / 看板）—— macOS segmented control
   🔴 原页是 `.lsrc button{flex:1 1 0}` + 块级 flex 容器 → 三个格子平摊**整行**
      （1512 宽时每格 400px），这是"界面很散"的最大单点。
      改成 `inline-flex` + 内容宽度：控件收缩到文字大小，左侧对齐。 */
.lsrc{
  display:inline-flex; width:auto; background:rgba(120,120,128,.12);
  border:0; border-radius:9px; padding:2px; gap:2px;
}
.lsrc button{
  flex:0 0 auto; border:0; background:transparent; box-shadow:none;
  border-radius:7px; height:28px; padding:0 14px;
  font-size:13px; font-weight:500; color:#3c3c43;
}
.lsrc button:hover{background:transparent; color:var(--ink)}
.lsrc button.on{
  background:#fff; color:var(--ink); font-weight:600;
  box-shadow:0 1px 2px rgba(0,0,0,.12),0 0 0 .5px rgba(0,0,0,.05);
}

/* 筛选芯片（项目类型 / 环节 / 证书到期 …）
   🔴 原页 `.chipbar` 是 `repeat(auto-fill,minmax(116px,1fr))` 网格 →
      1512 宽下铺成 8~10 个等宽方框，像一张表单，这是"看着杂乱"的第二大来源。
      改成**按内容宽度的流式胶囊**：宽度只跟文字走，间距统一 8px。 */
.chipbar{display:flex; flex-wrap:wrap; gap:8px; margin-top:10px}
.fchip{
  width:auto; height:30px; padding:0 11px; border-radius:8px;
  border:1px solid rgba(0,0,0,.08); background:#fff;
  font-size:13px; color:var(--ink-2);
  box-shadow:0 1px 1px rgba(0,0,0,.02);
  transition:background .14s ease,border-color .14s ease,color .14s ease;
}
.fchip:hover{background:var(--gray-bg); border-color:rgba(0,0,0,.12)}
.fchip.on{
  background:var(--blue-bg); border-color:rgba(0,113,227,.28);
  color:var(--blue-ink); font-weight:600;
}
.fchip .k{color:var(--ink-3); font-weight:400; margin-right:6px}
.fchip i{font-size:13px; font-weight:600}

/* 列表栏顶部的搜索框与「新建 / 批量分配」小按钮 */
.side-list input{height:36px; border-radius:9px; border-color:rgba(0,0,0,.1)}
.side-list .searchbox svg{left:10px; color:var(--ink-3)}
.newlead{
  height:28px; padding:0 10px; border-radius:8px; font-size:13px; font-weight:600;
  border:1px solid rgba(0,113,227,.3); background:var(--blue-bg); color:var(--blue-ink);
}
.newlead:hover{background:#dcecff}

/* 经典页统计块（leads / unrep 等） */
.stat{
  background:#fff; border:1px solid rgba(0,0,0,.06); border-radius:12px;
  padding:10px 14px; box-shadow:0 1px 2px rgba(0,0,0,.04);
}
.stat b{font-size:22px; font-weight:600; letter-spacing:-.02em}
.stat span{font-size:12px; color:var(--ink-3)}
.kv{background:var(--gray-bg); border-radius:5px; padding:1px 6px; font-size:12px}

/* ── 9. 详情页：只读值不做「灰盒子」 ───────────────────────────────────
   🔴 这是详情页"密、乱"的第一大来源：每个只读字段都是一个灰底 + 描边的盒子，
      一屏 30 多个盒子，视觉上等于 30 个输入框。苹果的做法是
      **标签浅灰、值直接是深色文字**，只有可编辑的才给控件外形。 */
.ro,.f .ro{
  background:transparent; border:0; border-radius:0; padding:0;
  color:var(--ink);
}
.af-k{color:var(--ink-3); font-weight:400}
.af-v{color:var(--ink); font-weight:500}

/* ── 9b. 锁定态（只读）**不写文字标签，用"值变灰"表达** ──────────────────
   🔴 老板 2026-10-26：「只读请不要写成只读，把字段文字变灰的形式来表现」。
      原来卡头挂一颗「只读」pill —— 那是**叫人读一句话**；苹果的做法是让不可编辑的
      内容自己失去对比度，用户扫一眼就知道"这块现在动不了"。
   触发：`pDecl()` 在 `declare_locked` 时给「报单信息」卡加 `.decl-locked`。
   ⚠️ 只降对比度，不改字号/位置；`input/select` 一并覆盖，防止个别字段仍渲染成控件。 */
.panel-card.decl-locked .af-v,
.panel-card.decl-locked .af-v .ro,
.panel-card.decl-locked .af-v input,
.panel-card.decl-locked .af-v select,
.panel-card.decl-locked .af-v textarea{color:var(--ink-2)}
/* 🔴 2026-10-27 按环节锁定（老板：「提交后的字段内容自动变灰」）：
   已提交环节的字段由服务端在 `锁定字段` 里点名，前端给 `.af-v` 挂 `.stage-locked`。
   与上面 `.decl-locked` 同一套表达 —— 只降对比度，不加灰盒子、不加"只读"字样。 */
.af-v.stage-locked{color:var(--ink-2)}
.af-v.stage-locked .ro{color:var(--ink-2)}

/* 字段来源标记（启信/手填/已改）：信息有用，但不该抢戏 */
.srcchip{opacity:.72}

/* 工作流节点：1px 发丝边 + 淡蓝选中环（原来是 2px 硬边 + 3px 实色环） */
.step{
  border:1px solid rgba(0,0,0,.09); border-radius:10px; background:#fff;
  padding:8px 12px; transition:border-color .14s ease,box-shadow .14s ease;
}
.step .s1{font-size:14px; font-weight:600}
.step .s2,.step .s3{font-size:12px; color:var(--ink-3)}
.step.done{background:var(--green-bg); border-color:rgba(29,138,78,.32)}
.step.cur{border-color:rgba(0,113,227,.45); box-shadow:0 0 0 3px rgba(0,113,227,.10)}
.step.sel{border-color:var(--ink); box-shadow:0 0 0 3px rgba(0,0,0,.06)}
.step.stuck{border-color:rgba(215,0,21,.45)}
.arrow{background:rgba(0,0,0,.14); height:1px}
.arrow::after{border-color:rgba(0,0,0,.2); border-width:1.5px}

/* 小节标题：给足层级差（原来是 14px/常规字重/灰色，和正文分不开） */
.band-ttl{font-size:15px; font-weight:600; color:var(--ink); letter-spacing:-.012em}
.band-ttl .n{font-size:13px; color:var(--ink-3); font-weight:400}
.card-head .ttl{font-size:16px; font-weight:600; letter-spacing:-.012em}
/* 报表页的分布卡 */
.card{border:1px solid rgba(0,0,0,.07); border-radius:12px}
.card .ch{background:#fff; border-bottom:1px solid var(--line-2); font-size:14px; font-weight:600}
.row{font-size:13px; padding:6px 0; border-bottom:1px solid var(--line-2)}

/* 报表页页签：白底胶囊 → macOS 分段控件
   🔴 原页每个 ⓘ 说明也是 `.tb`，于是被渲染成**一排灰圆点**，
      和页签名混在一起，看着像坏掉的按钮。这里把带 title-plain 的还原成小字。 */
.tabs{
  display:inline-flex; flex-wrap:wrap; gap:2px; padding:3px;
  background:rgba(120,120,128,.12); border-radius:10px; margin-bottom:16px;
}
.tabs .tb{
  border:1px solid transparent; background:transparent; box-shadow:none;
  border-radius:8px; height:30px; padding:0 14px; font-size:13px; font-weight:500;
  color:#3c3c43; display:inline-flex; align-items:center;
}
.tabs .tb:hover{background:rgba(255,255,255,.6)}
.tabs .tb.on{background:#fff; color:var(--ink); font-weight:600;
  box-shadow:0 1px 2px rgba(0,0,0,.12),0 0 0 .5px rgba(0,0,0,.05)}
.tabs .tb[title-plain]{
  background:transparent; border:0; box-shadow:none; padding:0 6px;
  font-size:14px; color:var(--ink-3); opacity:.6;
}
.tabs .tb[title-plain]:hover{opacity:1; background:transparent}
/* 线索页顶部统计块：给足宽度与内距（原来 inline-block 挤成一排小方块） */
.topbar{gap:10px}
.topbar .stat{min-width:118px; padding:10px 16px}
/* 报表页指标卡：数字撑起来 */
.kpi{border:1px solid rgba(0,0,0,.07); border-radius:12px; padding:12px 16px}
.kpi .v{font-size:28px; font-weight:600; letter-spacing:-.02em; line-height:1.2}
.kpi .k{font-size:12px; color:var(--ink-2); margin-bottom:2px}
.kpi .n{font-size:12px; color:var(--ink-3); margin-top:4px; line-height:1.5}
.kpi.hot{background:var(--red-bg); border-color:transparent}
.kpi.hot b,.kpi.hot .v{color:var(--red)}
.kpi.good{background:var(--green-bg); border-color:transparent}
.bar{height:6px; background:var(--gray-bg); border-radius:3px}
.bar i{background:var(--blue)}
/* 线索行的右列：只留一个主按钮，其余降级成文字操作（原来 4 个同尺寸按钮竖排，抢视线） */
.lead .rt{gap:3px}
.lead .rt button.sm:not(.pri){
  border:0; background:transparent; box-shadow:none;
  color:var(--ink-3); font-size:12px; font-weight:400; padding:2px 6px;
}
.lead .rt button.sm:not(.pri):hover{background:var(--gray-bg); color:var(--ink)}
.lead .rt button.pri{height:28px; padding:0 12px; font-size:13px}
.lead .nm{font-size:15px; font-weight:600; letter-spacing:-.01em}
.lead .mt{font-size:13px; color:var(--ink-2); line-height:1.6}
/* 财务页指标：数字放大、卡等高 */
.kpi b{font-size:28px; font-weight:600; letter-spacing:-.02em}

/* 供应商表：第 4 列「税点政策」是**自由文本**（可能 60+ 字），
   而全站 `th,td` 是 nowrap → 文字溢出单元格、压在「合作价」上，肉眼看到的是
   两行字叠在一起（实测 suppliers 页横向溢出 1195px）。
   🔴 只放开第 4 列的换行；其余列保持 nowrap，否则「机构名」会被挤成两行、
      「编辑」按钮会被压成竖排两个字（第一版就是这么坏的）。 */
table.grid td{white-space:nowrap; vertical-align:top}
table.grid td:nth-child(4){white-space:normal; min-width:220px; max-width:460px; line-height:1.6}
/* 🔴 实测第 7 列「城市」被撑到 **1110px** —— 那不是城市，是某家机构写了整段地址；
   nowrap 下它一个人吃掉整张表的宽度（页面横向溢出 905px）。城市列必须允许换行并限宽。 */
table.grid td:nth-child(7){white-space:normal; max-width:170px; line-height:1.6}
table.grid th:nth-child(1),table.grid td:nth-child(1){min-width:190px}
table.grid th:nth-child(2),table.grid td:nth-child(2){max-width:220px; white-space:normal}
table.grid th:last-child,table.grid td:last-child{width:72px}

/* ── 10. 登录门：员工看到的第一屏 ─────────────────────────────────────
   原来是一张 330px 白卡 + 11px 说明字，像一个临时对话框。
   现在按苹果登录面板做：图标、20px 标题、40px 控件、单一主按钮。 */
.lg-mask{
  position:fixed; inset:0; z-index:999; display:flex;
  align-items:center; justify-content:center; background:var(--bg);
}
.lg-card{
  width:352px; background:#fff; border:1px solid rgba(0,0,0,.07);
  border-radius:18px; padding:30px 28px 22px;
  box-shadow:0 24px 64px rgba(0,0,0,.14),0 2px 8px rgba(0,0,0,.06);
}
.lg-logo{
  width:32px; height:32px; border-radius:9px; background:var(--blue);
  display:flex; align-items:center; justify-content:center; margin-bottom:14px;
}
.lg-title{font-size:20px; font-weight:600; letter-spacing:-.022em; color:var(--ink)}
.lg-sub{font-size:13px; color:var(--ink-3); margin:3px 0 20px}
.lg-card label{display:block; font-size:13px; color:var(--ink-2); font-weight:500; margin:0 0 6px}
.lg-card input{width:100%; height:40px; font-size:15px; border-radius:9px; margin-bottom:14px}
.lg-card #lgErr{
  color:var(--red); font-size:13px; margin:-4px 0 12px; line-height:1.45;
}
.lg-btn{
  width:100%; height:40px; border-radius:9px; font-size:15px; font-weight:500;
  margin-top:4px;
}
.lg-foot{
  margin-top:16px; padding-top:14px; border-top:1px solid var(--line-2);
  text-align:center; font-size:13px; color:var(--ink-3);
}
.lg-foot a{color:var(--blue); text-decoration:none; padding:0 4px}
.lg-foot a.muted{color:var(--ink-2)}
.lg-foot a:hover{text-decoration:underline}
.lg-foot span{color:var(--line); margin:0 2px}

/* ── 11. 弹窗 / 提示 ─────────────────────────────────────────────────── */
.mask{background:rgba(0,0,0,.32)}
.dlg{
  border-radius:16px; padding:22px 24px;
  box-shadow:0 24px 64px rgba(0,0,0,.22),0 0 0 .5px rgba(0,0,0,.06);
}
.toast{
  background:rgba(29,29,31,.94); border-radius:12px; padding:10px 18px;
  font-size:14px; box-shadow:0 8px 28px rgba(0,0,0,.2);
}

/* ── 12. 滚动条（macOS 悬浮细条） ───────────────────────────────────── */
::-webkit-scrollbar{width:11px; height:11px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{
  background:rgba(0,0,0,.16); border-radius:6px;
  border:3px solid transparent; background-clip:content-box;
}
::-webkit-scrollbar-thumb:hover{background:rgba(0,0,0,.3); background-clip:content-box}
::-webkit-scrollbar-corner{background:transparent}

/* ── 13. 窄屏：只收敛字号，不动布局 ────────────────────────────────── */
@media(max-width:820px){
  .hd h1,.archive-bar h1{font-size:20px}
  #dash .dcard .v{font-size:20px}
  .list-title{font-size:17px}
}

/* ══════════════════════════════════════════════════════════════════════════
   14. 统一外壳 —— 11 个原本"没有侧栏"的页面接上同一根左栏
   ──────────────────────────────────────────────────────────────────────────
   🔴 这是本文件里**唯一**破例写定位的一段（老板 2026-10-21 拍板「按你的建议来」）。
      破例的理由：外壳不是"样式"，是"页面结构" —— 不给这 11 页加左栏，
      它们永远是换了副面孔的另一套系统。
      约束：只加在 `body.has-shell` 上（由 tools/add_shell.py 注入），
      不影响首页 wb2 与已有侧栏的 5 页；「内容左边缘 40px」仍由
      `.main-shell` 内部的原有 padding 决定，没有被改写。
   ══════════════════════════════════════════════════════════════════════════ */
body.has-shell{display:flex; align-items:flex-start; min-height:100vh}
body.has-shell > .sidenav{position:sticky; top:0; height:100vh; overflow:hidden auto;
  display:flex; flex-direction:column; box-sizing:border-box}
/* 侧栏里的菜单是 0 行高的 a（inline）→ 这里统一成可点满宽的块 */
:is(.side-nav,.sidenav) a.sitem{
  display:flex; align-items:center; box-sizing:border-box; margin:0;
}
:is(.side-nav,.sidenav) a.sitem span{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
/* 侧栏底部：工作台入口 / 用户名（各页原 .suser 里那一坨） */
:is(.side-nav,.sidenav) .suser{
  margin-top:auto; padding:10px 10px 2px; display:flex; flex-direction:column; gap:6px;
  border-top:1px solid rgba(0,0,0,.06);
}
:is(.side-nav,.sidenav) .suser .pill{align-self:flex-start}
:is(.side-nav,.sidenav) .sgrow{display:none}

body.has-shell > .main-shell{
  flex:1 1 auto; min-width:0; min-height:100vh;
  display:flex; flex-direction:column; background:var(--bg);
}
/* 页头（.hd）在壳里变成"吸顶工具条"，滚动时长内容不会从它下面穿过 */
body.has-shell .hd{
  position:sticky; top:0; z-index:20;
  background:rgba(255,255,255,.86);
  -webkit-backdrop-filter:saturate(180%) blur(20px);
  backdrop-filter:saturate(180%) blur(20px);
  border-bottom:1px solid rgba(0,0,0,.08);
}
body.has-shell .hd h1{font-size:22px; letter-spacing:-.022em}

/* 有壳的页面里，第一行标题统一 22px（finance/clients 原来各自写 16px，
   跟别页的 22px 摆在一起像两个系统） */
:is(.main,.main-shell) > h2:first-child{font-size:22px; font-weight:600; letter-spacing:-.022em}

/* 宽表：让表格**自己**横向滚，别把整页撑出横向滚动条
   （suppliers 10 列，实测整页溢出 53px；且「税点政策」被压成每行 3 个字） */
body.has-shell #list:has(> table){overflow-x:auto; -webkit-overflow-scrolling:touch}
body.has-shell #list > table.grid{min-width:max-content}

/* 统计小卡条（#stats）：原来 flex + wrap，5 个卡会「4 个一行 + 1 个掉到第二行」，
   看着像排坏了。改成**永远一行、等宽**。 */
body.has-shell #stats.topbar{
  display:grid; grid-auto-flow:column; grid-auto-columns:160px;
  gap:8px; justify-content:start; max-width:100%; align-items:stretch;
}
body.has-shell #stats.topbar > .stat{min-width:0; height:100%}

/* 设置页顶部的分类条（#setTabs）：它是 body 内容的第一个节点，加了外壳之后会
   紧贴屏幕顶边（字被切一半）。这里补呼吸空间 + 变成一条正式的分类条。
   🔴 它的 padding/margin 是**内联**样式，只能 !important 覆盖；
      而且**不能移动这个节点** —— 页面 JS 用 `#setTabs ~ *` 认"通用"页的兄弟节点，
      挪走就会有一半内容归错页（本轮踩过，已回退）。 */
body.has-shell > .main-shell > #setTabs{
  padding:12px 16px 0 !important; margin-bottom:0 !important;
  background:#fff; border-bottom:1px solid rgba(0,0,0,.08) !important;
}

/* 窄屏：侧栏折叠成图标条（只留图标），再窄就藏起来 —— 手机端不挤内容 */
@media(max-width:1080px){
  body.has-shell > .sidenav{width:var(--side-w-sm); flex:0 0 var(--side-w-sm); padding:14px 8px}
  body.has-shell > .sidenav .slogo{font-size:0; padding:0 0 15px; text-align:center}
  body.has-shell > .sidenav .slogo::after{content:"YZ"; font-size:14px}
  body.has-shell > .sidenav .sgroup{font-size:0; padding:8px 0 2px; border-top:1px solid rgba(0,0,0,.06)}
  body.has-shell > .sidenav a.sitem{justify-content:center; padding:0}
  body.has-shell > .sidenav a.sitem span{display:none}
  body.has-shell > .sidenav .suser{display:none}
}
@media(max-width:720px){
  body.has-shell > .sidenav{display:none}
}

/* ══════════════════════════════════════════════════════════════════════════
   15. 动效 —— 苹果那套「有反应但不过火」
   ──────────────────────────────────────────────────────────────────────────
   🔴 三条纪律：
   ① 只动 transform / opacity（合成层，不触发重排）—— 动 left/top/width 会掉帧；
   ② **不给 .main-shell / .main-detail 加 transform** —— 它们里面有 position:fixed
      的浮层（抽屉、弹窗、toast），祖先一旦有 transform 就会变成 fixed 的参照物，
      浮层会跑到错误位置（这是最典型的"加了动画就坏布局"）；
   ③ 全段包在 `prefers-reduced-motion:no-preference` 里 —— 系统开了"减弱动态效果"
      的用户看到的是静态界面，不是卡住的界面。
   ══════════════════════════════════════════════════════════════════════════ */
@keyframes ap-fade-in{from{opacity:0} to{opacity:1}}
@keyframes ap-rise{from{opacity:0; transform:translateY(6px)} to{opacity:1; transform:none}}
@keyframes ap-pop{from{opacity:0; transform:scale(.965)} to{opacity:1; transform:none}}
@keyframes ap-slide-right{from{transform:translateX(22px)} to{transform:none}}
@keyframes ap-press{0%{transform:scale(1)} 45%{transform:scale(.96)} 100%{transform:scale(1)}}

@media(prefers-reduced-motion:no-preference){
  /* ① 首屏：内容淡入 + 上浮 6px（0.28s，苹果的标准缓动） */
  .main-shell, .main{animation:ap-fade-in .26s cubic-bezier(.22,.61,.36,1) backwards}
  .hd{animation:ap-fade-in .2s linear backwards}
  /* 🔴 fill-mode 必须是 backwards：both 会在动画结束后**永久占住 transform**，
     于是这些块自己的 :hover{translateY(-1px)} 从此永不生效（2026-10-21 踩过）。 */
  body.has-shell .main-shell > *:not(.hd){
    animation:ap-rise .34s cubic-bezier(.22,.61,.36,1) backwards;
  }

  /* ② 列表逐条入场（错峰 18ms，最多错到第 12 条就停，否则长列表像排队） */
  .list-rows > .list-row{animation:ap-rise .3s cubic-bezier(.22,.61,.36,1) backwards}
  .list-rows > .list-row:nth-child(1){animation-delay:0ms}
  .list-rows > .list-row:nth-child(2){animation-delay:18ms}
  .list-rows > .list-row:nth-child(3){animation-delay:36ms}
  .list-rows > .list-row:nth-child(4){animation-delay:54ms}
  .list-rows > .list-row:nth-child(5){animation-delay:72ms}
  .list-rows > .list-row:nth-child(6){animation-delay:90ms}
  .list-rows > .list-row:nth-child(7){animation-delay:108ms}
  .list-rows > .list-row:nth-child(8){animation-delay:126ms}
  .list-rows > .list-row:nth-child(n+9){animation-delay:144ms}

  /* ③ 点下去的"手感"：按压缩 3%，松手弹回（苹果每个按钮都有这一下） */
  button, .btn, .sitem, .list-row, .dcard, .fchip, .tabs .tb, .taction{
    transition:transform .16s cubic-bezier(.34,1.3,.64,1),
               background .14s ease, color .14s ease,
               box-shadow .16s ease, border-color .14s ease;
  }
  button:active, .btn:active, .tabs .tb:active, .taction:active{transform:scale(.97)}
  .list-row:active{transform:scale(.995)}
  .dcard:active{transform:scale(.985)}

  /* ④ 悬停：卡片轻轻抬起 1px（只抬卡片，不抬表格行 —— 表格行会抖） */
  .list-row:hover{transform:translateY(-1px)}
  .dcard:hover{transform:translateY(-1px)}
  .stat:hover, .kpi:hover{transform:translateY(-1px)}

  /* ⑤ 抽屉 / 弹窗 / 提示条：从右侧滑入、居中弹出 */
  body.drawer-open .main-detail{animation:ap-slide-right .26s cubic-bezier(.22,.61,.36,1) backwards}
  .dlg, #dlg > div, .modal{animation:ap-pop .22s cubic-bezier(.22,.61,.36,1) backwards}
  .mask, .backdrop{animation:ap-fade-in .18s linear backwards}
  #toast, .toast{animation:ap-rise .22s cubic-bezier(.22,.61,.36,1) backwards}

  /* ⑥ 页签切换：新面板淡入（不是"啪"地换掉） */
  .tabpane, .panel-body, #pane{animation:ap-fade-in .18s ease backwards}
}

/* ⑦ 进度条 / 步骤条：宽度变化用过渡补上（原来是一格一格跳） */
.bar > i, .progress > i, .step b i{transition:width .5s cubic-bezier(.22,.61,.36,1)}


/* ══════════════════════════════════════════════════════════════════════════
   16. 行内说明条（.note-bar）
   ──────────────────────────────────────────────────────────────────────────
   2026-10-21：合作方页要显示「N 个机构只有编号、没有名称」。
   ❌ 不能用 `.table-empty`：它是**空态**样式（上下 28px 留白、居中），
      拿来当提示条会把表格往下推一大截。
   ❌ 也不能用 `.tip`：`isExplainTip()` 对任何 div 都真 → 会被折叠进「?」气泡。
   ══════════════════════════════════════════════════════════════════════════ */
.note-bar{
  font-size:13px; line-height:1.55; color:var(--ink-3, #6e6e73);
  padding:9px 12px; margin:0 0 10px; background:#fff;
  border:1px solid rgba(0,0,0,.06); border-radius:10px;
}
.note-bar b{color:var(--ink, #1d1d1f); font-weight:600}

/* ══════════════════════════════════════════════════════════════════════════
   17. 「?」小圆标（2026-10-21）
   ──────────────────────────────────────────────────────────────────────────
   组织架构页原来有 3 段常驻小字说明（岗位/权限怎么算），每段都占一整行，
   老板的原话是「页面非常杂乱」——这些字**看第二遍就不需要了**。
   收进 hover 提示：信息一个字没丢，页面上只留一个 16px 的圆点。
   ⚠️ 用原生 `title`，不引第三方 tooltip：桌面为主、零 JS、不会挡住点击。
   ══════════════════════════════════════════════════════════════════════════ */
.qm{
  display:inline-flex; align-items:center; justify-content:center;
  width:16px; height:16px; margin-left:6px; border-radius:50%;
  background:rgba(0,0,0,.06); color:#6e6e73;
  font-size:11px; font-weight:600; line-height:1;
  vertical-align:middle; cursor:help; user-select:none; flex:0 0 auto;
  transition:background .14s ease, color .14s ease;
}
.qm:hover{background:rgba(0,0,0,.11); color:#1d1d1f}
