/* ============================================================
   V02 · 组件样式
   ------------------------------------------------------------
   设计令牌全部来自 tokens.css（L1 原始 / L2 语义 / L3 组件三层）。
   ★ 本文件只写「组件怎么长」，不写「颜色是什么」——
     颜色一律 var(--token)，换肤因此只改 tokens.css 一处。
   ============================================================ */
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  background:var(--bg); color:var(--ink); font:var(--fs-md)/var(--lh-base) var(--font);
  -webkit-font-smoothing:antialiased;
}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums;letter-spacing:-.2px}
.num{font-family:var(--mono);font-variant-numeric:tabular-nums}

/* ★ 2026-11-04 用户第 1 条：「批量安排」为什么还常驻。
   根因不在 JS —— JS 早就写了 `pickBtn.hidden = PICK.size < 2`，
   但 `[hidden]` 的 `display:none` 来自**浏览器默认样式表**，
   而 `.btn{display:inline-flex}` 是作者样式：作者样式一律压过 UA 默认样式，
   与选择器权重无关。于是 hidden 属性设了、属性检查器里也看得到，
   元素照旧显示 —— 「置灰但不消失」正是这个现象。
   本文件里已经零散打过几次补丁（.site-foot[hidden] / .lg-wrap[hidden] /
   .adm-entry[hidden] / .segpane[hidden] …），但每遇到一个新元素就漏一个。
   这里一次性兜住：!important 才能压住 `.btn{display:inline-flex}` 这类
   带 display 的组件规则，否则这条规则本身也会被压掉。 */
[hidden]{display:none !important}

/* ============ 布局 ============ */
.app{display:flex;height:100vh;overflow:hidden}

/* 侧栏 */
/* 侧栏配色全部走令牌 —— 换肤时侧栏跟着变（用户 2026-10-30 第 4 项：
   之前侧栏是硬编码深绿，切皮肤只有内容区变了） */
.rail{
  width:var(--rail-w);flex:0 0 var(--rail-w);background:var(--rail-bg);color:var(--rail-ink);
  /* ★ 侧栏与画布之间必须有一条边界（用户 2026-10-31：「前端切换皮肤，会丢失左侧导航」）。
     病根：极简皮肤把侧栏做成白底，而画布也是白的 —— 两者同色、中间又没有任何分隔，
     缩放窗口后整条侧栏与内容区糊成一片，看着就像导航不见了。
     border 用 --rail-line：极简下是 #D8D8D8 的实线，深色皮肤下是侧栏同色系的暗线（几乎不显眼，无害）。
     box-sizing 是 border-box，扣的是内宽，侧栏总宽不变，台账表宽不受影响。 */
  border-right:1px solid var(--rail-line);
  display:flex;flex-direction:column;position:relative;z-index:30;
}
.rail.collapsed{width:var(--rail-w-narrow);flex:0 0 var(--rail-w-narrow)}
.brand{display:flex;align-items:center;gap:10px;padding:16px 16px 12px}
.brand .mark{
  width:26px;height:26px;flex:0 0 26px;border-radius:var(--radius-sm);
  background:linear-gradient(145deg,var(--rail-1),var(--rail-2));
  display:grid;place-items:center;color:var(--rail-ink);font-weight:700;font-size:var(--fs-base);
}
.brand b{font-size:var(--fs-md);letter-spacing:.3px;white-space:nowrap}
.rail.collapsed .brand b,.rail.collapsed .nav i,.rail.collapsed .proj-meta,.rail.collapsed .me-meta{display:none}

/* 项目切换器：常驻，防看错项目 */
.proj{
  margin:4px 12px 12px;padding:9px 10px;border-radius:var(--r-s);
  background:var(--rail-chip);border:1px solid var(--rail-line);cursor:pointer;
  display:flex;align-items:center;gap:9px;
}
.proj:hover{background:var(--rail-chip2)}
.proj .dot{width:7px;height:7px;border-radius:var(--radius-full);background:var(--rail-mark);flex:0 0 7px;box-shadow:0 0 0 3px var(--rail-mark-soft)}
.proj-meta{flex:1;min-width:0}
.proj-meta .t{font-size:var(--fs-base);font-weight:600;color:var(--rail-ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.proj-meta .s{font-size:var(--fs-xs);color:var(--rail-dim);font-family:var(--mono)}
.proj .car{color:var(--rail-dim);font-size:var(--fs-xs)}

.nav{padding:2px 10px;flex:1;overflow-y:auto}
.nav .grp{font-size:var(--fs-xs);color:var(--rail-dim);letter-spacing:1.2px;padding:12px 8px 6px;font-weight:600}
.nav a{
  display:flex;align-items:center;gap:10px;padding:8px 9px;margin:1px 0;border-radius:var(--r-s);
  color:var(--rail-ink2);text-decoration:none;font-size:var(--fs-base);position:relative;
}
/* ★ 用户 2026-10-30 第 9 轮第 1 项：「左侧导航…不使用斜体字」。
   菜单文字用的是 <i> 标签（renderRail 里 h("i",null,label)），浏览器默认 italic；
   之前没有对应的 font-style 复位 ⇒ 整条侧栏都是斜体。侧栏字号/字体族本就走
   --fs-* / --font（受「后台 → 界面外观」管控），这里只把斜体正过来。 */
.nav a i,.setnav a i{font-style:normal}
.nav a:hover{background:var(--rail-hover);color:var(--rail-ink)}
.nav a.on{background:var(--rail-on);color:var(--rail-on-ink);box-shadow:inset 2px 0 0 var(--rail-mark)}
.nav a .ic{width:16px;text-align:center;opacity:.85;flex:0 0 16px}
.nav a .badge{margin-left:auto;font-size:var(--fs-xs);background:var(--warn);color:var(--surface);border-radius:var(--radius-md);padding:1px 6px;font-family:var(--mono)}
.nav a .badge.gray{background:var(--rail-chip);color:var(--rail-dim)}

.me{padding:10px 12px;border-top:1px solid var(--rail-line);display:flex;align-items:center;gap:9px}
.me .av{width:26px;height:26px;border-radius:var(--radius-full);background:var(--rail-2);color:var(--rail-ink);display:grid;place-items:center;font-size:var(--fs-sm);font-weight:600;flex:0 0 26px}
.me-meta .t{font-size:var(--fs-base);color:var(--rail-ink);font-weight:600}
.me-meta .s{font-size:var(--fs-xs);color:var(--rail-dim)}
.collapse-btn{
  position:absolute;right:-11px;top:50%;width:22px;height:22px;border-radius:var(--radius-full);
  background:var(--surface);border:1px solid var(--line);color:var(--ink2);cursor:pointer;
  display:grid;place-items:center;font-size:var(--fs-xs);box-shadow:var(--sh);z-index:40;
}

/* 主区 */
.main{flex:1;display:flex;flex-direction:column;min-width:0}
.cmdbar{
  height:54px;flex:0 0 54px;background:var(--panel);border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:14px;padding:0 20px;
}
.crumb{display:flex;align-items:center;gap:7px;font-size:var(--fs-base);color:var(--ink3)}
.crumb b{color:var(--ink);font-weight:600;font-size:var(--fs-md)}
.crumb .sep{color:var(--border-strong)}
.search{
  margin-left:auto;width:280px;display:flex;align-items:center;gap:8px;
  background:var(--panel-2);border:1px solid var(--line);border-radius:var(--radius-md);padding:6px 10px;color:var(--ink3);font-size:var(--fs-base);
}
.search kbd{margin-left:auto;font-family:var(--mono);font-size:var(--fs-xs);background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 4px;color:var(--ink3)}
.iconbtn{width:32px;height:32px;border-radius:var(--radius-md);border:1px solid var(--line);background:var(--surface);color:var(--ink2);cursor:pointer;display:grid;place-items:center}
.iconbtn:hover{background:var(--panel-2)}

/* 皮肤入口 —— 用户 2026-10-30：「连入口都迷你」⇒ 改成带文字的显眼按钮。
   32px 的裸图标在顶栏一排小圆钮里根本认不出来哪个是换肤。 */
.skbtn{
  height:32px;padding:0 13px;border-radius:var(--radius-md);
  border:1px solid var(--border);background:var(--surface);color:var(--text-2);
  cursor:pointer;display:inline-flex;align-items:center;gap:6px;
  font:inherit;font-size:var(--fs-sm);font-weight:600;white-space:nowrap;
}
.skbtn:hover{background:var(--surface-3);color:var(--text-1);border-color:var(--border-strong)}
.skbtn::first-letter{font-size:calc(14px * var(--font-scale))}
.bell{position:relative}
.bell::after{content:"";position:absolute;top:6px;right:6px;width:6px;height:6px;border-radius:var(--radius-full);background:var(--danger);border:1.5px solid var(--surface)}

.canvas{flex:1;overflow-y:auto;padding:20px 22px 40px}
/* 页脚（用户 2026-10-31 第 19 轮第 2 项，第 21 轮扩成多段）
   ------------------------------------------------------------
   第 21 轮用户原话：「底部除了备案号，还有其他信息组成，参照网上经验，提前预留位置」。
   所以这里不是"一条备案行"，而是**三段预留槽**：
     ① 版权行   © 年份 主体 版权所有 + ICP 备案 + 公安网备
     ② 联系行   电话 / 邮箱 / 地址 + 自定义链接（隐私政策、服务条款、技术支持…）
     ③ 附注行   版本号 / 免责声明之类
   ★ 单行 26px 是默认态（只填备案号时和以前一模一样）；每多一段长 18px 左右。
     用 min-height 而不是 height —— 写死高度会让第二段直接溢出被裁掉。
   ★ 段内 flex-wrap：窗口窄了自动折行，不横向溢出（页脚出现横向滚动条很难看）。 */
.site-foot{
  flex:0 0 auto;min-height:26px;padding:3px 14px;box-sizing:border-box;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;
  border-top:1px solid var(--line);background:var(--panel);
  font-size:calc(11px * var(--font-scale));color:var(--ink3);line-height:1.55;letter-spacing:.01em;user-select:none;
}
.site-foot[hidden]{display:none}
.site-foot .sf-row{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:0 6px;max-width:100%;text-align:center;
}
/* 单个词条不拆行（电话号码/备案号被拆成两半最难读），太长时退回允许折行 */
.site-foot .sf-i{white-space:nowrap;max-width:100%}
.site-foot a{color:var(--ink3);text-decoration:none}
.site-foot a:hover{color:var(--brand);text-decoration:underline}
.site-foot .sf-sep{opacity:.5}
/* 附注行（版本/免责）再淡一档：它是"说明"，不该和备案号抢注意力。
   ★ 只降到 10.5px + 0.85 透明度：再淡（0.7 以下）在 1080p 上就基本看不清了，
     而这一行恰恰是"有问题该找谁"的信息，不能当装饰。 */
.site-foot .sf-l3{opacity:.85;font-size:calc(10.5px * var(--font-scale))}
/* 后台「界面外观」里的页脚预览：借用同一套 .site-foot 类保证所见即所得，
   只去掉固定定位语义、加虚线框，让它老实躺在卡片里 */
.site-foot.sf-preview{
  flex:none;border:1px dashed var(--line);border-top:1px dashed var(--line);
  border-radius:var(--radius-md);background:var(--surface);padding:8px 12px;margin-top:2px;
}
@media (max-width:640px){
  .site-foot{padding:4px 10px}
  .site-foot .sf-i{white-space:normal;overflow-wrap:anywhere}
}
.site-foot .sf-sep{opacity:.55}
.screen{display:none}
.screen.on{display:block;animation:fade .18s ease}
@keyframes fade{from{opacity:0;transform:translateY(3px)}to{opacity:1;transform:none}}

/* ============ 通用组件 ============ */
.btn{
  height:32px;padding:0 13px;border-radius:var(--radius-md);border:1px solid var(--line);background:var(--surface);color:var(--ink);
  font-size:var(--fs-base);cursor:pointer;display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
}
.btn:hover{background:var(--panel-2)}
.btn.primary{background:var(--brand);border-color:var(--brand);color:var(--surface)}
.btn.primary:hover{background:var(--brand-ink)}
.btn.ghost{background:transparent;border-color:transparent;color:var(--brand)}
.btn.sm{height:27px;padding:0 10px;font-size:var(--fs-base)}
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh)}
.pad{padding:16px 18px}
.hd{display:flex;align-items:center;gap:10px;margin-bottom:14px}
.hd h2{font-size:var(--fs-md);font-weight:650;letter-spacing:.2px}
.hd .sub{font-size:var(--fs-sm);color:var(--ink3)}
.hd .right{margin-left:auto;display:flex;gap:8px;align-items:center}
.grid{display:grid;gap:14px}
.tag{
  display:inline-flex;align-items:center;gap:5px;height:21px;padding:0 7px;border-radius:var(--radius-sm);
  font-size:var(--fs-sm);font-weight:500;white-space:nowrap;
}
.tag.gray{background:var(--slate-soft);color:var(--slate)}
.tag.amber{background:var(--warn-soft);color:var(--warn)}
.tag.blue{background:var(--info-soft);color:var(--info)}
.tag.green{background:var(--ok-soft);color:var(--ok)}
.tag.red{background:var(--danger-soft);color:var(--danger)}
.tag.brand{background:var(--brand-soft);color:var(--brand)}
.tag .pt{width:5px;height:5px;border-radius:var(--radius-full);background:currentColor}

/* 阶段进度：6 小格 */
.flow{display:inline-flex;gap:2px;align-items:center}
.flow i{width:13px;height:5px;border-radius:var(--radius-sm);background:var(--border-soft);display:block}
.flow i.on{background:var(--brand-2)}
.flow i.cur{background:var(--warn)}
.flow i.late{background:var(--danger)}

/* KPI */
/* KPI 卡 —— 对齐 V01 v460-kpi（P0 样式基线）：auto-fit 栅格 / 12px 圆角 / 24px 数值 / 无左色条无阴影 */
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:12px;margin-bottom:14px}
.kpi{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius-lg);padding:13px 16px;position:relative;overflow:hidden}
.kpi::before{display:none}
.kpi.k1::before{background:var(--brand)}
.kpi.k2::before{background:var(--warn)}
.kpi.k3::before{background:var(--info)}
.kpi.k4::before{background:var(--slate)}
.kpi .l{font-size:var(--fs-sm);color:var(--ink3);display:flex;align-items:center;gap:6px}
.kpi .v{font-family:var(--mono);font-size:var(--fs-xl);font-weight:700;letter-spacing:-.4px;margin:3px 0 2px;line-height:1.15}
.kpi .f{font-size:var(--fs-sm);color:var(--ink3)}
.kpi .f em{font-style:normal;color:var(--ok)}
.kpi .f em.bad{color:var(--danger)}

/* 待办列表 */
.todo{display:flex;flex-direction:column}
.todo .it{
  display:grid;grid-template-columns:56px 1fr 96px 132px 74px;gap:12px;align-items:center;
  padding:11px 18px;border-bottom:1px solid var(--line-2);
}
.todo .it:last-child{border-bottom:0}
.todo .it:hover{background:var(--panel-2)}
.days{
  text-align:center;border-radius:var(--radius-sm);padding:3px 0;font-family:var(--mono);font-size:var(--fs-sm);font-weight:600;line-height:1.25;
}
.days small{display:block;font-size:var(--fs-xs);font-weight:400;opacity:.75;font-family:var(--font)}
.days.late{background:var(--danger-soft);color:var(--danger)}
.days.warn{background:var(--warn-soft);color:var(--warn)}
.days.norm{background:var(--slate-soft);color:var(--slate)}
.ti .a{font-size:var(--fs-md);font-weight:550}
.ti .b{font-size:var(--fs-sm);color:var(--ink3);margin-top:1px}
.ti .b .mono{color:var(--ink2)}

/* 表格 */
.tbl-wrap{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh);overflow:hidden}
.tbl{width:100%;border-collapse:collapse;font-size:var(--fs-base)}
.tbl th{
  text-align:left;font-weight:600;font-size:var(--fs-sm);color:var(--ink2);letter-spacing:.4px;
  background:var(--panel-2);border-bottom:1px solid var(--line);padding:9px 12px;white-space:nowrap;position:sticky;top:0;
}
.tbl td{padding:10px 12px;border-bottom:1px solid var(--line-2);vertical-align:middle}
.tbl tbody tr:hover{background:var(--panel-2);cursor:pointer}
.tbl tbody tr.sel{background:var(--brand-soft)}
.tbl .cb{width:34px;text-align:center;padding-right:0}
.tbl .r{text-align:right}
.tbl td .mono{font-size:var(--fs-base);color:var(--ink)}
.tbl td .sub{font-size:var(--fs-xs);color:var(--ink3)}
/* V01 台账列 1:1 还原所需的三个类（V01 v460/v465 系列同名） */
.tbl td.mut{color:var(--ink4)}
.tbl th.idx,.tbl td.idx{width:54px;text-align:right;color:var(--ink3);font-family:var(--mono);font-size:var(--fs-sm)}
.tbl td.wrap{white-space:normal}
.v2-temp{display:inline-block;padding:1px 6px;border-radius:var(--radius-md);font-size:var(--fs-xs);white-space:nowrap;font-family:var(--mono)}
.v2-temp.ok{background:var(--ok-soft);color:var(--ok-ink)}
.v2-temp.near{background:var(--warn-soft);color:var(--warn-ink)}
.v2-temp.low{background:var(--panel-2);color:var(--ink3)}
.bar{height:4px;border-radius:var(--radius-sm);background:var(--surface-3);overflow:hidden;width:64px}
.bar b{display:block;height:100%;background:var(--brand-2);border-radius:var(--radius-sm)}
.bar b.warn{background:var(--warn)}
.bar b.bad{background:var(--danger)}

/* 工具条 */
.toolbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;flex-wrap:wrap}
.chips{display:flex;gap:4px;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius-md);padding:3px}
.chip{padding:5px 11px;border-radius:var(--radius-sm);font-size:var(--fs-base);color:var(--ink2);cursor:pointer;display:flex;align-items:center;gap:6px;white-space:nowrap}
.chip:hover{background:var(--panel-2)}
.chip.on{background:var(--brand);color:var(--surface)}
.chip .c{font-family:var(--mono);font-size:var(--fs-xs);opacity:.7}
.chip.on .c{opacity:.85}
.spacer{flex:1}

/* 台账左栏 */
.split{display:grid;grid-template-columns:196px 1fr;gap:14px;align-items:start}
.domains{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh);padding:8px;position:sticky;top:0}
.domains .t{font-size:var(--fs-xs);color:var(--ink3);letter-spacing:1px;padding:6px 8px 4px;font-weight:600}
.domains a{display:flex;align-items:center;gap:8px;padding:7px 8px;border-radius:var(--radius-sm);color:var(--ink2);text-decoration:none;font-size:var(--fs-base)}
.domains a:hover{background:var(--panel-2)}
.domains a.on{background:var(--brand-soft);color:var(--brand);font-weight:600}
.domains a .n{margin-left:auto;font-family:var(--mono);font-size:var(--fs-xs);color:var(--ink3)}
.domains a.on .n{color:var(--brand-2)}

/* 分页 */
.pager{display:flex;align-items:center;gap:10px;padding:10px 14px;border-top:1px solid var(--line);font-size:var(--fs-base);color:var(--ink3)}
.pager .pages{display:flex;gap:3px;margin-left:auto}
.pager .pg{min-width:27px;height:27px;border-radius:var(--radius-sm);border:1px solid var(--line);background:var(--surface);display:grid;place-items:center;font-size:var(--fs-base);cursor:pointer;color:var(--ink2);padding:0 6px}
.pager .pg.on{background:var(--brand);border-color:var(--brand);color:var(--surface)}

/* 抽屉 */
.scrim{position:fixed;inset:0;background:rgba(18,36,31,.28);opacity:0;pointer-events:none;transition:.2s;z-index:50}
.scrim.on{opacity:1;pointer-events:auto}
.drawer{
  position:fixed;top:0;right:0;bottom:0;width:var(--drawer-w);max-width:92vw;background:var(--panel);
  border-left:1px solid var(--line);transform:translateX(100%);transition:transform .22s cubic-bezier(.4,0,.2,1);
  z-index:60;display:flex;flex-direction:column;box-shadow:-16px 0 40px -20px rgba(22,33,29,.3);
}
.drawer.on{transform:none}
/* 表格型抽屉（安排送检 / 待办清单）：列多，给足宽度 */
.drawer.wide{width:min(920px,94vw)}
.drawer.wide .dw-bd{padding:14px 16px}
/* ★ 用户 2026-10-31 第 18 轮第 4 项：「抽屉要自适应宽度，让数据完整显示」。
   取样单详单是 8 列（# / 进场日期 / 供货厂家 / 规格 / 炉批号 / 组数 / 最迟完成 / 取样要求），
   920px 下「供货厂家」「取样要求」两个自适应列会被压到几十px，
   炉批号与批次叠在一起 ⇒ 信息读不出来。
   xwide = 宽表格专用档；min(1180px,94vw) 本身随视口自适应，小屏不会溢出。 */
.drawer.xwide{width:min(1180px,94vw)}
.drawer.xwide .dw-bd{padding:14px 16px}
.dw-hd{padding:16px 18px;border-bottom:1px solid var(--line);display:flex;align-items:flex-start;gap:10px}
.dw-hd .x{margin-left:auto;cursor:pointer;color:var(--ink3);font-size:var(--fs-xl);line-height:1;padding:2px 4px}
.dw-bd{flex:1;overflow-y:auto;padding:18px}
/* 抽屉「← 返回」：靠右紧挨 ×（第 28 轮第 1 项）。
   margin-left:auto 让它与标题分开；字号压在 sm 档，免得抢标题视线。 */
.dw-hd .dw-back{margin-left:auto;align-self:center;font-size:calc(12px * var(--font-scale));padding:4px 9px;white-space:nowrap}
.dw-hd .dw-back + .x{margin-left:6px}
.dw-ft{padding:12px 18px;border-top:1px solid var(--line);display:flex;gap:8px}

/* 时间线 */
.tl{position:relative;padding-left:22px}
.tl::before{content:"";position:absolute;left:6px;top:6px;bottom:6px;width:1.5px;background:var(--line)}
.tl .n{position:relative;padding-bottom:16px}
.tl .n:last-child{padding-bottom:0}
.tl .n::before{
  content:"";position:absolute;left:-21px;top:4px;width:9px;height:9px;border-radius:var(--radius-full);
  background:var(--surface);border:2px solid var(--border-strong);
}
.tl .n.done::before{background:var(--brand-2);border-color:var(--brand-2)}
.tl .n.cur::before{background:var(--surface);border-color:var(--warn);box-shadow:0 0 0 3px var(--warn-soft)}
.tl .n.late::before{background:var(--danger);border-color:var(--danger)}
.tl .n .x{font-size:var(--fs-base);font-weight:600;display:flex;align-items:center;gap:8px}
.tl .n .y{font-size:var(--fs-sm);color:var(--ink3);margin-top:1px}
.tl .n.pending .x{color:var(--ink3);font-weight:500}

/* KV */
.kv{display:grid;grid-template-columns:88px 1fr;gap:8px 12px;font-size:var(--fs-base)}
.kv .k{color:var(--ink3)}
.kv .v{color:var(--ink)}
.sec-t{font-size:var(--fs-xs);color:var(--ink3);letter-spacing:1px;font-weight:600;margin:18px 0 10px;display:flex;align-items:center;gap:8px}
.sec-t::after{content:"";flex:1;height:1px;background:var(--line)}

/* 打印模板卡 */
.wall{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.tpl{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh);overflow:hidden;cursor:pointer}
.tpl:hover{border-color:var(--border-strong);box-shadow:0 2px 6px rgba(22,33,29,.08),0 14px 30px -16px rgba(22,33,29,.18)}
.tpl .pv{background:var(--surface-3);padding:14px;display:grid;place-items:center;height:186px}
.paper{
  width:126px;height:168px;background:var(--paper-edge);border-radius:var(--radius-sm);box-shadow:var(--shadow-1);
  padding:9px 8px;display:flex;flex-direction:column;gap:3px;
}
.paper .h{height:3px;background:var(--paper-ink);width:78%;margin:0 auto 3px;border-radius:1px}
.paper .h2{height:2px;background:var(--paper-line);width:56%;margin:0 auto 4px;border-radius:1px}
.paper .ln{height:2px;background:var(--paper-faint);border-radius:1px}
.paper .ln.s{width:70%}
.paper .g{display:grid;grid-template-columns:1fr 1fr 1fr;gap:3px;margin-top:2px}
.paper .g span{height:11px;border:.6px solid var(--paper-cell-line);border-radius:1px;background:var(--paper-cell)}
.paper .f{margin-top:auto;height:2px;background:var(--paper-faint);border-radius:1px}
.paper .stamp{width:26px;height:26px;border:.8px dashed var(--paper-stamp);border-radius:50%;margin-left:auto;margin-top:2px;opacity:.55}
.tpl .meta{padding:11px 14px;border-top:1px solid var(--line)}
.tpl .meta .n{font-size:var(--fs-md);font-weight:600;display:flex;align-items:center;gap:7px}
.tpl .meta .d{font-size:var(--fs-sm);color:var(--ink3);margin-top:3px;display:flex;gap:10px}
.tpl .meta .d .mono{color:var(--ink2)}

/* 表单 */
.form{display:grid;grid-template-columns:1fr 1fr;gap:14px 16px}
.fld{display:flex;flex-direction:column;gap:5px}
.fld.wide{grid-column:1/-1}
.fld label{font-size:var(--fs-sm);color:var(--ink2);font-weight:500}
.fld label em{font-style:normal;color:var(--danger)}
.fld input,.fld select,.fld textarea{
  height:34px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--surface);padding:0 10px;
  font:inherit;font-size:var(--fs-base);color:var(--ink);outline:none;
}
.fld input:focus,.fld select:focus{border-color:var(--brand-2);box-shadow:0 0 0 3px rgba(44,122,102,.12)}
.fld .hint{font-size:var(--fs-xs);color:var(--ink3)}

/* 设置左栏 */
.setnav{display:flex;flex-direction:column;gap:1px}
.setnav a{padding:8px 11px;border-radius:var(--radius-sm);font-size:var(--fs-base);color:var(--ink2);text-decoration:none;display:flex;align-items:center;gap:8px}
.setnav a:hover{background:var(--panel-2)}
.setnav a.on{background:var(--brand-soft);color:var(--brand);font-weight:600}
.setnav .grp{font-size:var(--fs-xs);color:var(--ink3);letter-spacing:1px;padding:12px 11px 5px;font-weight:600}

/* ============================================================
   一屏多段 + 后台合并屏（2026-11-05 设计稿 设置/后台重组 P1）
   ------------------------------------------------------------
   合并后的屏由多段组成：段之间只给一条细线和间距，靠各自卡片的头部
   当段标题（不再叠一层段标题 —— 同一句话说两遍）。
   .set-seg-h 只给"自带头部被摘掉"的段用（报料模板）。
   ============================================================ */
.set-seg-sp{margin-top:16px;padding-top:14px;border-top:1px solid var(--border-soft)}
.set-seg-h{font-size:calc(12.5px * var(--font-scale));font-weight:700;color:var(--ink2);margin:0 0 10px 2px}
.compose-part{margin-top:0}
.compose-part + .compose-part{margin-top:16px;padding-top:14px;border-top:1px solid var(--border-soft)}
.compose-seg{font-size:calc(12.5px * var(--font-scale));font-weight:700;color:var(--ink2);margin:0 0 10px 2px}

/* 统计卡 */
.rep{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh);padding:16px;display:flex;flex-direction:column;gap:10px;cursor:pointer}
.rep:hover{border-color:var(--border-strong)}
.rep .n{font-size:var(--fs-md);font-weight:600;display:flex;align-items:center;gap:8px}
.rep .d{font-size:var(--fs-sm);color:var(--ink3);line-height:1.6}
.rep .mini{display:flex;align-items:flex-end;gap:3px;height:38px;margin-top:auto}
.rep .mini i{flex:1;background:var(--brand-soft);border-radius:var(--radius-sm) 2px 0 0;display:block}
.rep .mini i.hi{background:var(--brand-2)}
.legend{display:flex;gap:14px;font-size:var(--fs-sm);color:var(--ink2);flex-wrap:wrap}
.legend span{display:flex;align-items:center;gap:5px}
.legend i{width:8px;height:8px;border-radius:var(--radius-sm);display:block}

.note{background:var(--brand-soft);border:1px solid var(--brand-soft);border-radius:var(--radius-md);padding:10px 12px;font-size:var(--fs-base);color:var(--brand-ink);line-height:1.6}
.note b{font-weight:650}
.empty{display:flex;flex-direction:column;align-items:center;gap:8px;padding:44px;color:var(--ink3);font-size:var(--fs-base)}
.empty .ic{width:40px;height:40px;border-radius:var(--radius-full);background:var(--panel-2);display:grid;place-items:center;font-size:var(--fs-xl)}

@media (max-width:1180px){
  .kpis{grid-template-columns:repeat(2,1fr)}
  .wall{grid-template-columns:repeat(2,1fr)}
  .split{grid-template-columns:1fr}
  .domains{position:static;display:flex;overflow-x:auto;gap:2px}
  .domains .t{display:none}
}

/* ===== v640：工作台分筐 / 排期日历 / 角色视角 ===== */
.rolebar{display:flex;gap:4px;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius-md);padding:3px}
.rolebar span{padding:5px 11px;border-radius:var(--radius-sm);font-size:var(--fs-base);color:var(--ink2);cursor:pointer;white-space:nowrap}
.rolebar span:hover{background:var(--panel-2)}
.rolebar span.on{background:var(--brand);color:var(--surface)}
.bk{margin-bottom:12px;border:1px solid var(--line);border-radius:var(--r);background:var(--panel);box-shadow:var(--sh);overflow:hidden}
.bk>.h{display:flex;align-items:center;gap:9px;padding:10px 16px;border-bottom:1px solid var(--line-2);background:var(--panel-2)}
.bk>.h .bar{width:3px;height:15px;border-radius:var(--radius-sm);background:var(--slate);width:3px}
.bk.bad>.h .bar{background:var(--danger)}.bk.now>.h .bar{background:var(--warn)}
.bk.plan>.h .bar{background:var(--info)}.bk.wait>.h .bar{background:var(--slate)}
.bk.doing>.h .bar{background:var(--brand-2)}
.bk>.h b{font-size:var(--fs-base)}
.bk>.h .c{font-family:var(--mono);font-size:var(--fs-sm);background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-full);padding:1px 8px;color:var(--ink2)}
.bk>.h .tip{font-size:var(--fs-sm);color:var(--ink3)}
.bk>.h .tg{margin-left:auto;font-size:var(--fs-sm);color:var(--ink3);cursor:pointer}
.row{display:grid;grid-template-columns:94px 1fr 112px 118px 78px;gap:12px;align-items:center;padding:10px 16px;border-bottom:1px solid var(--line-2)}
.row:last-child{border-bottom:0}
.row:hover{background:var(--panel-2)}
.row .when{text-align:center;border-radius:var(--radius-sm);padding:3px 2px;font-family:var(--mono);font-size:var(--fs-sm);font-weight:600;line-height:1.3}
.row .when small{display:block;font-size:var(--fs-xs);font-weight:400;opacity:.78;font-family:var(--font)}
.when.od{background:var(--danger-soft);color:var(--danger)}
.when.td{background:var(--warn-soft);color:var(--warn)}
.when.fu{background:var(--info-soft);color:var(--info)}
.when.nm{background:var(--slate-soft);color:var(--slate)}
.tag.dk{background:var(--rail-bg);color:var(--rail-ink)}
.cal{display:grid;grid-template-columns:repeat(7,1fr);gap:8px}
.cal .dh{text-align:center;font-size:var(--fs-xs);color:var(--ink3);font-weight:600;letter-spacing:1px;padding-bottom:2px}
.cal .d{border:1px solid var(--line);border-radius:var(--radius-md);background:var(--surface);min-height:96px;padding:7px 8px;position:relative}
.cal .d.off{background:var(--surface-2);border-style:dashed}
.cal .d.off .n{color:var(--ink3)}
.cal .d.today{border-color:var(--brand);box-shadow:0 0 0 2px rgba(44,122,102,.14)}
.cal .d .n{font-family:var(--mono);font-size:var(--fs-base);font-weight:600;display:flex;align-items:baseline;gap:4px}
.cal .d .n em{font-style:normal;font-size:var(--fs-xs);font-weight:400;color:var(--ink3);font-family:var(--font)}
.cal .d .off-tag{position:absolute;top:7px;right:8px;font-size:var(--fs-xs);color:var(--text-3);background:var(--surface-3);border-radius:var(--radius-sm);padding:0 4px}
.cal .d .it{margin-top:5px;font-size:var(--fs-xs);line-height:1.45;border-radius:var(--radius-sm);padding:2px 5px;background:var(--info-soft);color:var(--info-ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cal .d .it.w{background:var(--warn-soft);color:var(--warn-ink)}
.cal .d .it.g{background:var(--ok-soft);color:var(--ok-ink)}
.legend2{display:flex;gap:14px;font-size:var(--fs-sm);color:var(--ink3);flex-wrap:wrap;margin-top:10px}
.legend2 span{display:flex;align-items:center;gap:5px}
.legend2 i{width:9px;height:9px;border-radius:var(--radius-sm);display:block}

/* ============================================================
   以下是原型里没有、真系统必需的部分：登录、提示、弹窗、加载态。
   ============================================================ */

/* ---------- 登录遮罩 ---------- */
.lg-wrap{
  position:fixed;inset:0;z-index:200;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(160deg,var(--rail-bg),var(--brand) 60%,var(--rail-1));
}
.lg-wrap[hidden]{display:none}
.lg-card{
  width:100%;max-width:352px;background:var(--surface);border-radius:var(--radius-lg);padding:28px 26px 24px;
  box-shadow:0 24px 60px -20px rgba(0,0,0,.5);
}
.lg-card .lg-mark{
  width:36px;height:36px;border-radius:var(--radius-md);background:linear-gradient(145deg,var(--rail-1),var(--rail-2));
  display:grid;place-items:center;color:var(--rail-ink);font-weight:700;font-size:var(--fs-lg);margin-bottom:16px;
}
.lg-card h1{font-size:var(--fs-xl);margin:0 0 4px;font-weight:650;letter-spacing:-.01em}
.lg-sub{font-size:var(--fs-base);color:var(--ink3);margin:0 0 20px}
.lg-card label{display:block;font-size:var(--fs-base);color:var(--ink2);margin-bottom:14px}
.lg-card input{
  display:block;width:100%;margin-top:6px;padding:9px 11px;font:inherit;font-size:var(--fs-md);
  border:1px solid var(--line);border-radius:var(--radius-md);background:var(--surface);color:var(--ink);
}
.lg-card input:focus{outline:none;border-color:var(--brand-2);box-shadow:0 0 0 3px rgba(44,122,102,.14)}
.lg-err{background:var(--danger-soft);color:var(--danger);font-size:var(--fs-base);padding:8px 10px;border-radius:var(--radius-sm);margin-bottom:14px}
.lg-err[hidden]{display:none}
.lg-card button{
  width:100%;padding:10px;font:inherit;font-size:var(--fs-md);font-weight:600;color:var(--surface);
  background:var(--brand);border:0;border-radius:var(--radius-md);cursor:pointer;
}
.lg-card button:disabled{opacity:.6;cursor:default}
.lg-tip{margin-top:16px;font-size:var(--fs-sm);color:var(--ink3);line-height:1.6}

/* ---------- 提示条 ---------- */
.toast{
  position:fixed;left:50%;bottom:28px;transform:translate(-50%,12px);
  background:var(--rail-bg);color:var(--rail-ink);padding:10px 18px;border-radius:var(--radius-md);font-size:var(--fs-base);
  opacity:0;pointer-events:none;transition:.2s;z-index:300;max-width:76vw;
  box-shadow:0 12px 30px -12px rgba(0,0,0,.5);
}
.toast.on{opacity:1;transform:translate(-50%,0)}
.toast.err{background:var(--danger-ink)}
.toast.warn{background:var(--warn-ink)}

/* ---------- 弹窗 ---------- */
.msk{position:fixed;inset:0;background:rgba(18,36,31,.34);z-index:120;display:none;align-items:center;justify-content:center;padding:24px}
/* 项目切换器·顶栏版（用户 2026-10-30 第 12 项） */
.proj-top{display:inline-flex;align-items:center;gap:7px;height:34px;padding:0 14px;border:1px solid var(--line);
  border-radius:var(--radius-full);background:var(--card,var(--surface));font:inherit;font-size:var(--fs-base);color:var(--ink);cursor:pointer;
  /* ★ 用户 2026-10-31 第 11 轮第 13 项：「让工程名称显示完整，改为自动适应长度」。
     原来写死 max-width:300px，而真名是「大亚湾区惠州城城中村改造项目（三标段）」
     这类二十多字 —— 300px 只放得下「…（三标」，用户永远看不到标段号。
     改成：宽度跟着内容走（max-content），只受视口比例封顶（46vw / 720px），
     留 ellipsis 仅作极端兜底（视口极窄且名字超长时）。 */
  max-width:min(720px,46vw);width:max-content;white-space:nowrap}
.proj-top:hover{border-color:var(--brand-2)}
.proj-top .dot{width:8px;height:8px;border-radius:var(--radius-full);background:var(--brand);flex:0 0 auto}
.proj-top .proj-name{overflow:hidden;text-overflow:ellipsis;font-weight:600;flex:0 1 auto;min-width:0}
.proj-top .car{color:var(--ink3);font-size:var(--fs-xs);flex:0 0 auto}
.msk.on{display:flex}
/* 弹窗宽度自适应内容（用户 2026-10-30 第 1/2 项）：width:auto = 有多少内容撑多宽，
   顶到 max-width 封顶；min-width 兜底防提示语挤成一列。 */
.dlg{background:var(--surface);border-radius:var(--radius-lg);box-shadow:var(--shadow-3);width:auto;min-width:380px;max-width:720px;max-height:88vh;display:flex;flex-direction:column}
.dlg.wide{max-width:980px}
/* 个人中心（v648 · 第 33 轮）：窄卡 560px（宽窄走 openDlg 的 profile 选项，
   class 由 openDlg 每次重设，不往 #dlg 上写内联样式 —— 内联会残留污染下一个弹窗） */
.dlg.profile{max-width:560px;width:min(560px,94vw)}
/* 本批次流水号：五列，部位与流水号都是长串 —— 固定成 820px 再按比例分列 */
/* 用户 2026-10-31 第 22 轮第 6 项：「根据内容自动放大长宽比，减少出现竖向条」
   ------------------------------------------------------------
   ★ 症结不是字号，是**比例**：五列挤在 820px 里，工程部位与流水号两个长串
     各占 30% 就只剩 246px，HLS26102000008 这种 14 位流水号被折断后行高翻倍，
     于是 16 行就把 44vh 撑满 —— 竖向滚动条其实是"列太窄"逼出来的。
   ★ 修法：先把弹窗放宽到 1080（横向更宽 = 长宽比更接近内容的形状），
     再让表体高度跟随内容（上限按视口算），而不是写死 44vh。
     结果：同样 16 行，一屏放得下，竖向条不再出现；行数真的很多时才滚。 */
/* ★ 第 38 轮：宽度不再由 .serials 自己拍（原来是 1080，与 mtdoc 的 1120、
   wide 的 980 各说各话），统一交给 .sz-w3；这里只留表格相关样式。 */
.dlg.serials .tbl-serial{table-layout:fixed}
.dlg.serials .tbl-serial th,.dlg.serials .tbl-serial td{padding-left:10px;padding-right:10px}
.dlg.serials .tbl-serial td:first-child,.dlg.serials .tbl-serial th:first-child{padding-left:4px}
/* 行高收一点：17 行 × 40px 正好把 640px 的可用高度顶穿，竖向条又出来了。
   这里只收上下 padding（横向不动，横向是列宽的命） —— 收到 7px 后 17 行约 612px，
   一屏放完，竖向条消失。 */
.dlg.serials .tbl-serial th,.dlg.serials .tbl-serial td{padding-top:6px;padding-bottom:6px}
/* 行高收一点：17 行 × 40px 正好把 640px 的可用高度顶穿，竖向条又出来了。
   这里只收上下 padding（横向不动，横向是列宽的命） —— 收到 7px 后 17 行约 612px，
   一屏放完，竖向条消失。 */
.dlg.serials .tbl-serial th,.dlg.serials .tbl-serial td{padding-top:6px;padding-bottom:6px}
/* 拆模行淡一档：这一段是另一类试块，不该和送检行同样显眼 */
.dlg.serials .tbl-serial tr.is-brk td{color:var(--ink3)}
/* 第 13 轮第 3 项：表里现在列的是「当天参与统计的全部记录」，
   旺季一天十几批，表会顶到弹窗底部 —— 表内滚动，统计条和按钮始终可见 */
.dlg.serials .serials-cap{margin:0 0 8px;font-size:var(--fs-sm)}
/* 高度跟着内容走：视口减去头部/说明/统计条/底栏的固定高度，留 40px 余量 */
/* 高度跟着内容走：视口减去头部/说明/底栏的固定高度（约 200px）。
   ★ 240 时 17 行 + 统计条差 13px 放不下 → 统计条被顶进滚动区，正好压住最后一行。
     放到 200 之后一屏放完；行数真的更多时才滚动，统计条由下面的 sticky 兜住。 */
/* ★ 第 38 轮：弹窗改成定高（sz-w3 = 1120×700）之后，表体不能再用「视口 - 280」
   这类算式 —— 它和弹窗自己的高度是两套坐标，算大了就顶穿统计条与底栏
   （截图里最后一行压在「安排统计」上就是这个原因）。改成 flex 吃满剩余高度。 */
.dlg.serials .dlg-bd{display:flex;flex-direction:column;overflow:hidden}
.dlg.serials .serials-bd{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden}
.dlg.serials .serials-bd thead th{position:sticky;top:0;z-index:1;background:var(--panel)}
/* 统计条钉在表体底部（用户第 22 轮第 6 项）。
   ★ 放宽弹窗、托高表体之后，行数刚好把「安排统计」顶出可视区 —— 统计是最该一直看见的
     那一行（取试件的人照着它备箱），所以让它 sticky 在滚动区底部，行数再多也不丢。 */
/* 统计条在弹窗主体之外（.dlg-stat），固定可见、不参与滚动 */
.dlg.serials .dlg-bd{padding-bottom:2px}
.dlg.serials .dlg-bd{padding-bottom:2px}
.dlg.serials .dlg-stat{padding:0 20px 10px}
.dlg.serials .dlg-stat .arrstat{margin-top:0}
/* 统计条钉在表体底部（用户第 22 轮第 6 项）。
   ★ 放宽弹窗、托高表体之后，行数刚好把「安排统计」顶出可视区 —— 统计是最该一直看见的
     那一行（取试件的人照着它备箱），所以让它 sticky 在滚动区底部，行数再多也不丢。 */
.dlg-hd{padding:16px 20px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px}
.dlg-hd b{font-size:var(--fs-md)}
.dlg-hd .x{margin-left:auto;cursor:pointer;color:var(--ink3);font-size:var(--fs-xl);line-height:1;padding:0 4px}
/* ★ 2026-11-06（第 104 轮 · 回传预览）：加 min-height:0。
   .dlg 是 flex column，bd 默认 min-height:auto = 不小于内容高度，
   内容一长 bd 就把 .dlg-ft 顶出弹窗 —— 表现为"底部按钮不见了"，
   而按钮其实在 700px 之外。加这一行，内容超长时由 bd 自己滚，
   按钮永远钉在底部。对正常长度的弹窗没有任何影响。 */
.dlg-bd{padding:18px 20px;overflow-y:auto;min-height:0}
.dlg-ft{padding:12px 20px;border-top:1px solid var(--line);display:flex;gap:8px;justify-content:flex-end}

/* ---------- 勾选框 ---------- */
input[type=checkbox]{width:14px;height:14px;accent-color:var(--brand);cursor:pointer;vertical-align:-2px}

/* ---------- 数字输入框：去掉浏览器自带的上下步进箭头（用户 2026-10-30 第 4 项）────
   「全站所有数字输入框，都移除上下倒三角」。Chromium 是
   ::-webkit-inner/outer-spin-button，Firefox 是 -moz-appearance:textfield；
   两个都要写，只写一个在另一家浏览器里箭头照旧。键盘上下键仍可微调，不受影响。 */
input[type=number]{-moz-appearance:textfield;appearance:textfield}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}

/* ---------- 加载/空态 ---------- */
.loading{padding:48px;text-align:center;color:var(--ink3);font-size:var(--fs-base)}
.skel{height:12px;border-radius:var(--radius-sm);background:linear-gradient(90deg,var(--surface-3),var(--surface-2),var(--surface-3));background-size:200% 100%;animation:sk 1.1s infinite}
@keyframes sk{0%{background-position:200% 0}100%{background-position:-200% 0}}

/* ---------- 报料解析：草稿表 ---------- */
.draft{width:100%;border-collapse:collapse;font-size:var(--fs-base)}
.draft th{text-align:left;font-size:var(--fs-xs);color:var(--ink3);font-weight:600;padding:6px 8px;border-bottom:1px solid var(--line);background:var(--panel-2)}
.draft td{padding:5px 8px;border-bottom:1px solid var(--line-2)}
.draft input,.draft select{height:28px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 7px;font:inherit;font-size:var(--fs-base);width:100%;background:var(--surface)}
.draft input:focus,.draft select:focus{outline:none;border-color:var(--brand-2)}
.draft .warnrow{background:var(--warn-soft)}
/* 用户 2026-10-30 第 6 项：解析草稿列宽 —— 数字类小列（方量/接头数量）不再与
   文本长列（厂家/部位）平分宽度，常用屏宽一行放得下、不用横向滚动 */
.draft-pour th:nth-child(1){width:19%}
.draft-pour th:nth-child(2){width:10%}
.draft-pour th:nth-child(3){width:9%}
.draft-pour th:nth-child(4){width:13%}
.draft-pour th:nth-child(5){width:10%}
.draft-pour th:nth-child(6){width:23%}
/* ★ 第 44 轮追：套筒部位移出表格并入组标题（部位全单一致，不值得占一列），
   腾出来的宽度全部给两个厂家列 —— 全名（惠州市鑫奥机械有限公司）原来
   被挤成三四行，现在整行放下。 */
.draft-slv th:nth-child(1){width:30px}
.draft-slv th:nth-child(2){width:86px}
.draft-slv th:nth-child(3){width:80px}
.draft-slv th:nth-child(4){width:21%}
.draft-slv th:nth-child(5){width:16%}
.draft-slv th:nth-child(6){width:21%}
.draft-slv th:nth-child(7){width:118px}

/* ---------- 别名表 ---------- */
.alias{width:100%;border-collapse:collapse;font-size:var(--fs-base)}
.alias th{text-align:left;font-size:var(--fs-xs);color:var(--ink3);font-weight:600;padding:7px 8px;border-bottom:1px solid var(--line);background:var(--panel-2)}
.alias td{padding:6px 8px;border-bottom:1px solid var(--line-2);vertical-align:top}
.alias .k{width:96px;font-weight:600;color:var(--ink)}
.alias input{width:100%;height:28px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 8px;font:inherit;font-size:var(--fs-base)}

/* ============================================================
   工作台（V01 口径：左待办四类 + 右四卡）
   ============================================================ */
/* ★ 第 10 轮（用户：「感觉要溢出屏幕了，要有点边界感」）：
   右栏原来是死宽的 336px，窗口一窄左栏被压到几百像素、右栏还杵在那儿，
   两条卡片一行挤到贴边。改成有下限的弹性列 + 两档断点，
   并把两个格子的 min-width 归零 —— 否则里头的长部位名（nowrap）会把列撑开、
   整块内容被推到画布外面去（canvas 是 overflow:auto，溢出后只能靠横向滚才能看见）。 */
.wb-grid{grid-template-columns:minmax(0,1fr) clamp(340px,22vw,392px);align-items:start}
/* ★ 第 90 轮（用户 2026-11-05 第 4 条）：「中间『待办事项』让给右侧的『今日送检』」。
   右栏原来是 minmax(300px,336px) —— 一旦窗口收窄，它掉到 300 的下限，
   四张卡里的部位名被压成两行还带省略号，日期和「已安排」挤在同一行。
   现在改成 clamp(340px, 22vw, 392px)：大屏 392（1920 下左右 ≈ 77:23），
   1440 左右 340 起步，永不小于 340 —— 卡片里的信息密度是有下限的，
   再窄就只能靠折叠，而折叠会让人以为"没有今天的记录"。
   ★ 左栏仍是 minmax(0,1fr)：min-width 0 保住了横向滚动（.wb-tw overflow-x:auto），
     左表列再多也只是多一条滚动条，不会被右栏挤到变形。 */

.wb-grid>*{min-width:0}
.wb-card{padding:0}   /* P0：改用 .base-card（V01 v460-card）*/

/* 组头 */
.wb-g{border-top:1px solid var(--line-2)}
.wb-g:first-child{border-top:none}
.wb-gh{display:flex;align-items:center;gap:8px;padding:9px 2px;cursor:pointer;user-select:none}
.wb-gh:hover{background:var(--panel-2)}
.wb-caret{color:var(--ink4);font-size:var(--fs-xs);width:10px}
.wb-dot{width:7px;height:7px;border-radius:var(--radius-sm);flex:none}
.wb-gh b{font-size:var(--fs-base);font-weight:650}
.wb-cnt{font-family:var(--mono);font-size:var(--fs-sm);color:var(--ink3);background:var(--panel-2);border-radius:var(--radius-sm);padding:1px 6px}
.wb-note{margin-left:auto;font-size:var(--fs-sm);color:var(--ink4)}
.wb-allck{display:flex;align-items:center;gap:4px;font-size:var(--fs-sm);color:var(--ink3);cursor:pointer}
.wb-allck input{cursor:pointer}

/* 表 */
.wb-tw{overflow-x:auto;margin:0 -16px}
/* ★ 第 10 轮：待办表列多，窄屏必然横向滚。滚动条以前是"藏着"的
   （浏览器默认在 Windows 上只在悬停时出现），看起来就像最后一列被硬切掉、
   「到期」两字只露一半 —— 用户的"要溢出屏幕了"有一半是这个观感。
   给它一条常驻的细滚动条，切边就变成"还能往右看"，而不是"界面坏了"。 */
.wb-tw::-webkit-scrollbar,.sp-lw::-webkit-scrollbar{height:8px}
.wb-tw::-webkit-scrollbar-thumb,.sp-lw::-webkit-scrollbar-thumb{background:var(--line);border-radius:4px}
.wb-tw::-webkit-scrollbar-thumb:hover,.sp-lw::-webkit-scrollbar-thumb:hover{background:var(--ink4)}
.wb-tbl{font-size:var(--fs-base)}
.wb-tbl th{white-space:nowrap;padding:7px 10px}
.wb-tbl td{padding:8px 10px}
.wb-tbl tbody tr:hover{background:var(--brand-soft)}
.wb-tbl .cb{padding-left:14px}
.wb-tbl td.num,.wb-tbl td.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}
.wb-tbl td.mono{font-size:var(--fs-sm)}
.wb-due{font-size:var(--fs-sm);font-weight:600;white-space:nowrap}
.wb-red{color:var(--danger)}
.wb-org{color:var(--warn)}
.wb-gry{color:var(--ink3)}
.wb-empty{padding:16px 4px;font-size:var(--fs-base);color:var(--ink3)}

/* 底部批量操作条 */
.wb-bar{display:flex;align-items:center;gap:10px;padding:9px 0;border-top:1px solid var(--line);
  position:sticky;bottom:0;background:var(--panel);z-index:2;margin-top:4px}
.wb-bartxt{font-size:var(--fs-base);display:flex;align-items:center;gap:6px;min-width:0}
.wb-bartxt b{font-weight:650}
.wb-baract{margin-left:auto;display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}

/* 右侧四卡 */
.wb-mini{padding:0}
.wb-mini .base-chd{margin-bottom:8px}
.wb-mini .base-chd .wbtitle{font-size:var(--fs-base);font-weight:650}
.wb-n{font-family:var(--mono);font-size:var(--fs-sm);background:var(--brand-soft);color:var(--brand);border-radius:var(--radius-sm);padding:1px 6px}
.wb-mini .base-chd .sub{font-size:var(--fs-xs);margin-left:auto}
/* ★ 用户 2026-10-31 第 12 轮第 2 项：「右侧栏，左右边距缩进一点」。
   根因：卡头 .base-chd 左右各 14px 内边距，可卡体 .wb-minibd 是 0 ——
   条目行（.wb-mrow / .wb-fee / .wb-mft 全是 padding:X 0）直接顶到卡片边框上，
   卡头缩进、卡体贴边，右边那一列看着就"想溢出"。
   把间距给到卡体容器：一处改动四张卡同时对齐卡头的 14px。 */
.wb-minibd{display:flex;flex-direction:column;padding:0 14px 8px}
.wb-mrow{display:flex;align-items:flex-start;gap:8px;padding:6px 0;border-bottom:1px solid var(--line-2)}
.wb-mrow:last-child{border-bottom:none}
.wb-mrow:hover{background:var(--panel-2)}
.wb-mleft{min-width:0;flex:1}
.wb-mleft b{font-size:var(--fs-base);font-weight:620;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 条目名：不加粗（用户第 2 项）。靠字号 + 墨色区分层级，不靠字重。
   ★ 第 10 轮：改为最多两行折行。原来是单行 nowrap+ellipsis，
   长部位名（「2-14'轴-1-5轴交2-14'轴-2-Y轴地下顶板、梁」）被切在中间，
   右栏看着像"装不下要溢出去"；两行能完整读完，卡片也不会横向顶宽。 */
.wb-mleft .wb-mt{font-size:var(--fs-base);font-weight:400;color:var(--ink);display:-webkit-box;
  -webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere;line-height:1.45}
.wb-mmeta{font-size:var(--fs-xs);color:var(--ink3);margin-top:1px;overflow-wrap:anywhere}
.wb-mright{display:flex;align-items:center;gap:4px;flex:none}
.wb-mdate{text-align:right;line-height:1.25}
.wb-mdate b{font-size:var(--fs-sm);font-family:var(--mono)}
.wb-mdate small{display:block;font-size:var(--fs-xs);color:var(--ink3)}
/* 待取回：压了 7 天以上，日期徽标转红 —— 取报告没有法定红线，
   只有"压太久不像话"，所以是提示色不是错误色 */
.wb-mdate.late b,.wb-mdate.late small{color:var(--danger-ink)}
.wb-msep{display:flex;align-items:center;gap:6px;padding:7px 0 3px;font-size:var(--fs-xs);color:var(--ink3);letter-spacing:.5px}
.wb-msep .c{font-family:var(--mono);background:var(--panel-2);border-radius:var(--radius-sm);padding:0 5px}
.wb-mfee{font-size:var(--fs-base);font-weight:600}
.wb-mft{display:flex;align-items:center;gap:6px;padding-top:8px;border-top:1px solid var(--line);font-size:var(--fs-sm);color:var(--ink3)}
.wb-mft b{margin-left:auto;font-size:var(--fs-md);color:var(--ink)}

/* 断点：1440 以下把右栏收到 300（左表才是主战场）；1180 以下整块堆叠 */
@media (max-width:1440px){
  .wb-grid{grid-template-columns:minmax(0,1fr) 340px}   /* 第 90 轮：跟基准一致，不再掉到 300 */
}
@media (max-width:1180px){
  .wb-grid{grid-template-columns:1fr}
}

/* ============================================================
   安排送检 / 送检清单抽屉（V01 tdsm 口径）
   ============================================================ */
.inp{padding:5px 8px;border:1px solid var(--line);border-radius:var(--radius-sm);font:inherit;font-size:var(--fs-base);background:var(--panel);color:var(--ink)}
.inp:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-soft)}
.tdsm-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:0 0 12px}
.tdsm-f{display:flex;align-items:center;gap:7px;font-size:var(--fs-sm);color:var(--ink3)}
.tdsm-hint{font-size:var(--fs-sm);color:var(--ink4)}
.tdsm-bar .tdsm-f{margin-right:2px}
.tdsm-wrap{overflow:auto;max-height:calc(100vh - 260px);border:1px solid var(--line-2);border-radius:var(--radius-md)}
.tdsm-tb{font-size:var(--fs-base);min-width:100%}
.tdsm-tb th{white-space:nowrap;padding:8px 10px;position:sticky;top:0;background:var(--panel-2);z-index:1}
.tdsm-tb td{padding:7px 10px;vertical-align:middle}
.tdsm-tb tbody tr{border-top:1px solid var(--line-2)}
.tdsm-tb tbody tr:hover{background:var(--brand-soft)}
.tdsm-nm b{font-weight:620}
.tdsm-nm .mut{font-size:var(--fs-sm);color:var(--ink3)}
.tdsm-sub{font-size:var(--fs-xs);color:var(--ink4);margin-top:1px}
.tdsm-tb .tdsm-d{width:140px;padding:4px 6px;font-size:var(--fs-sm)}
.tdsm-tb .tdsm-w{width:104px;padding:4px 6px;font-size:var(--fs-sm);text-align:center}
.tdsm-ok{color:var(--ok);font-weight:600;white-space:nowrap;font-family:var(--mono);font-size:var(--fs-sm)}
.tdsm-no{color:var(--warn);font-weight:600;white-space:nowrap;font-family:var(--mono);font-size:var(--fs-sm)}
.tdsm-tb .mut{color:var(--ink4)}
/* 龄期后的累计温度（同条件专用）：不加粗、小一号，跟在龄期后面 */
.wb-temp{font-family:var(--mono);font-size:var(--fs-sm);color:var(--warn);margin-left:2px}
/* 列宽自动适应后，单元格默认不折行，实在放不下才挤 */
.wb-tbl td{white-space:nowrap}
.wb-tbl td:first-child{white-space:normal}

/* ============================================================
   设置 · 检测单位 / 供应商
   ============================================================ */
.labrow{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:10px 12px;
  border:1px solid var(--line-2);border-radius:var(--radius-md);margin-bottom:8px;background:var(--panel)}
.labrow.on{border-color:var(--brand);background:var(--brand-soft)}
.labrow b{font-size:var(--fs-base)}
.labchips{display:flex;gap:6px;flex-wrap:wrap}
.labacts{margin-left:auto;display:flex;gap:6px;flex-wrap:wrap}
.tplbox{border:1px solid var(--line-2);border-radius:var(--radius-md);padding:12px;margin-top:10px}
.tplbox>b{font-size:var(--fs-base);display:block;margin-bottom:8px}
.labrow .wb-n{font-family:var(--mono)}

/* ============================================================
   台账（2026-10-29 重做：取消左侧域栏、恢复平铺）
   ------------------------------------------------------------
   ★ 试件台账是 15 列宽表。V01 的做法是容器横向滚动 + 列不折行；
     上一版给每列写死 px 宽度，总和超过容器后浏览器把汉字压成竖排 ——
     所以这里一个宽度都不写，交给内容自己撑，放不下就横滚。
   ============================================================ */
.tbl-wrap.lg{overflow-x:auto}
.tbl.lg{min-width:100%}
.tbl.lg th{white-space:nowrap}
.tbl.lg td{white-space:nowrap;padding:9px 10px}
.tbl.lg th.idx,.tbl.lg td.idx{width:auto}
/* 长文本单元格：内部再套一层 .ell 才截得住（表格自动布局会忽略 td 的 max-width） */
.tbl .ell{display:inline-block;max-width:260px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;vertical-align:bottom}
/* 台账工具条的搜索框（V01 顶部 `.sch` 的位置） */
input.search{height:32px;width:230px;border:1px solid var(--line);border-radius:var(--radius-md);
  padding:0 10px;font:inherit;background:var(--panel);color:var(--ink)}
input.search:focus{outline:none;border-color:var(--brand)}

/* ============================================================
   送检三连抽屉 + 批次详情（2026-10-29 验收 1~3 / 6~7）
   ============================================================ */
/* 只读摘要：字段一行一条，虚线分隔（V01 v460 抽屉的 .f 行） */
.dw-sum{border:1px solid var(--line);border-radius:var(--radius-md);overflow:hidden}
.dw-sum-r{display:flex;gap:12px;padding:11px 14px;border-bottom:1px dashed var(--line);font-size:var(--fs-base)}
.dw-sum-r:last-child{border-bottom:none}
.dw-sum-r .k{color:var(--ink3);flex:0 0 84px}
.dw-sum-r .v{flex:1;color:var(--ink);word-break:break-all}
.dw-due{display:flex;gap:12px;align-items:center;padding:12px 2px 2px;font-size:var(--fs-base)}
.dw-due .k{color:var(--ink3);flex:0 0 84px}
.dw-due .v{font-weight:600}
/* 页脚提示语：整行、不跟按钮抢宽度 */
.dw-hint{flex:0 0 100%;font-size:var(--fs-sm);color:var(--ink3);margin-top:2px;line-height:1.5}
/* 抽屉里的批次清单小表 */
.tdsm-lst{margin-top:2px;border:1px solid var(--line);border-radius:var(--radius-md);overflow:hidden}
.tdsm-lstb{width:100%;border-collapse:collapse;font-size:var(--fs-base)}
.tdsm-lstb th{background:var(--surface2);color:var(--ink3);font-weight:500;text-align:left;padding:8px 10px;white-space:nowrap}
.tdsm-lstb td{padding:8px 10px;border-top:1px solid var(--line);white-space:nowrap}
/* 多值余数徽标（报告编号 +2 / 炉批号 +8） */
.v465-badge{display:inline-block;margin-left:5px;padding:0 5px;border-radius:var(--radius-sm);
  background:var(--surface3);color:var(--ink2);font-size:var(--fs-xs);line-height:17px;vertical-align:middle}
/* 钢筋连接 1 级弹窗顶部横排 */
.bt-pop{display:flex;flex-wrap:wrap;gap:18px;align-items:center;font-size:var(--fs-base);
  color:var(--ink3);margin-bottom:12px}
.bt-pop b{color:var(--ink)}
.bt-wrap{overflow-x:auto;max-height:56vh;border:1px solid var(--line);border-radius:var(--radius-md)}
.bt-wrap .tbl{min-width:100%}
.bt-wrap .tbl th,.bt-wrap .tbl td{white-space:nowrap;padding:8px 10px}
/* 批次详情（2 级） */
.bt-hd{margin-bottom:14px}
.bt-hd b{font-size:calc(15px * var(--font-scale))}
.bt-chip{display:inline-block;margin-top:6px;padding:3px 9px;border-radius:var(--radius-md);
  background:var(--surface2);border:1px solid var(--line);font-size:var(--fs-sm);color:var(--ink3)}
.bt-kv{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:var(--radius-md);overflow:hidden}
.bt-c{display:flex;gap:10px;background:var(--panel);padding:11px 14px;font-size:var(--fs-base)}
.bt-c .k{color:var(--ink3);flex:0 0 76px}
.bt-c .v{flex:1;color:var(--ink);word-break:break-all}
/* 确认弹窗正文 */
.cfm-bd{font-size:var(--fs-md);line-height:1.75;color:var(--ink2)}
.cfm-bd b{color:var(--ink)}
.cfm-bd p{margin:0 0 6px}
/* 弹窗正文里的条目清单（「哪几张取样单没建成」这类）。浏览器默认 ul 缩进 40px，
   在 w1 档（420px）里会把长理由挤成两行，收窄到 18px 刚好。 */
.cfm-bd ul{margin:0;padding:0 0 0 18px}
.cfm-bd li{margin:2px 0}

/* ── 台账单元格换行（用户 2026-10-29 验收第 3、5 条）────────────────
   为什么必须带 .tbl.lg 前缀：`.tbl.lg td{white-space:nowrap}` 的权重是 (0,2,1)，
   光写 `.tbl td.wrap` 是 (0,2,1) 打平后按源序输 —— 上一版就是这么"设了没生效"的。
   ★ 用 width 而不是 max-width：表格自动布局会忽略 td 的 max-width，
     长轴号串照样把整张表撑宽、把右边几列怼出屏幕。 */
/* ── 台账单元格换行（用户 2026-10-29 验收第 3、5 条）────────────────
   为什么必须带 .tbl.lg 前缀：`.tbl.lg td{white-space:nowrap}` 的权重是 (0,2,1)，
   光写 `.tbl td.wrap` 是 (0,2,1) 打平后按源序输 —— 上一版就是这么"设了没生效"的。
   ★ 用 width 而不是 max-width：表格自动布局会忽略 td 的 max-width，
     长轴号串照样把整张表撑宽、把右边几列怼出屏幕。
   ★ 18em = 「工程部位超过 18 字自动换行」（用户 2026-10-30 第 9 轮第 2 项）：
     em 跟随 --font-scale，字号调大列宽等比放宽，不会出现"调了字号列更挤"。 */
.tbl.lg td.partcell,.tbl.lg th.partcell{
  white-space:normal;word-break:break-word;line-height:1.55;
  width:18em;min-width:13em;max-width:18em;vertical-align:top;
}
/* 备注：一行约 6 个字（12.5px × 6 ≈ 75px + 左右 padding 24px），超了就换行 */
.tbl.lg td.notecell{
  white-space:normal;word-break:break-word;line-height:1.55;
  width:104px;min-width:96px;vertical-align:top;color:var(--ink2);
}
/* 部位列上限已统一为 18em（见上方 18 字换行规则），此处不再另行放宽 */

/* ── 页头「后台管理」入口（用户 2026-10-29 验收第 2 条）────────────────
   从左侧导航挪上来：后台是独立页面，放在页头右上角才符合「一进去就换站」的直觉。
   ★ 不用 .iconbtn：那是个 32×32 的方块，用户在图里框的是一段带字的区域。 */
.adm-entry{
  display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 12px;
  border:1px solid var(--line);border-radius:var(--radius-md);background:var(--surface);
  color:var(--ink2);font-size:var(--fs-base);font-weight:500;text-decoration:none;
  white-space:nowrap;flex:0 0 auto;
}
.adm-entry:hover{background:var(--panel-2);color:var(--ink);border-color:var(--line-2)}
.adm-entry[hidden]{display:none}

/* ── 待办事项表格：部位列定宽 16 字，其余列自适应（用户 2026-10-29 第 8 条）──
   「工程部位，超过16字，自动换行；剩的列宽，其他的自动分配」
   ★ 16em 而不是 16 个 px：字号是 12.5px，写死 200px 一旦改字号就对不上了。
   ★ 用 width 而不是 max-width：表格自动布局会忽略 td 的 max-width，
     长轴号串照样把表撑宽，右边几列被挤出屏幕（要靠横向滚动才看得见）。
   ★ 去掉 .wb-tw 的 overflow-x:auto：既然列宽改成自适应，正常情况就不该溢出；
     留着 auto 等于给"撑爆了"这种情况留了个只能横向拖的后路，反而看不见问题。
   ★★ 第 13 轮第 1 项（用户第三次报「部位显示不全」）——量出来的真因：
      `.wb-tw` 还留着老写法 `margin:0 -16px`（当年卡片有 16px 内边距时用来出血），
      而 `.wb-card` 现在是 `padding:0` + `.base-card{overflow:hidden}`，
      于是整张表被推到卡片外 15px，首列左半边直接被裁掉 ——
      实测 `td.left=175 / card.left=190`，轴线串开头的「2-」就是这么没的。
      现在：表不再外扩，组块左右各缩进 14px（与卡头 14px 对齐），
      首列左对齐 + 允许任意断行（overflow-wrap:anywhere），
      长轴号串只会在栏内折成多行，不会再顶出边界。 */
.wb-tw{overflow-x:visible;margin:0}
.wb-g{padding:0 14px}
.wb-tbl{width:100%;table-layout:auto}
.wb-tbl th:first-child,.wb-tbl td:first-child{
  width:16em;min-width:9em;max-width:16em;
  white-space:normal;word-break:break-word;overflow-wrap:anywhere;
  text-align:left;line-height:1.55;vertical-align:top;
  padding-left:0;
}
/* 末列右侧也不留半截内边距，保证最后一列字与组头右边缘齐 */
.wb-tbl th:last-child,.wb-tbl td:last-child{padding-right:0}
/* 其余列：不折行但允许被压窄（配合 table-layout:auto，浏览器会自己分配剩余宽度） */
.wb-tbl th:not(:first-child),.wb-tbl td:not(:first-child){
  white-space:nowrap;vertical-align:top;
}

/* 待办分组「展开全部 / 收起」（每页条数见设置 → 列表分页） */
.wb-more{
  /* 组块现在左右各缩进 14px（第 13 轮第 1 项），展开条跟着对齐卡片边 */
  margin:0 -14px;padding:9px 14px;text-align:center;font-size:var(--fs-sm);
  color:var(--brand);cursor:pointer;border-top:1px solid var(--line);
  background:var(--panel-2);user-select:none;
}
.wb-more:hover{background:var(--brand-soft)}

/* 「来自项目档案」来源徽标（设置 → 委托单抬头 / 报审表抬头，用户 2026-10-29 第 6 条）
   作用不是装饰：只读框必须让人一眼看出"这个值不在这儿改、去哪儿改"。 */
.srcbadge{
  display:inline-flex;align-items:center;gap:4px;margin-top:4px;
  font-size:var(--fs-xs);line-height:1.5;color:var(--ink4);
}
.srcbadge::before{content:"↗";font-size:var(--fs-xs);color:var(--info)}


/* ============ 2026-10-30 用户验收第 3/13 项 ============ */
/* 组数徽标：贴在工程部位后面（V01 同款），回答「这个部位几组」 */
/* 组数徽标：贴在工程部位后面。用户 2026-10-30 第 7 项要求「放小一点」——
   原来 18px 宽 / 17px 行高，比正文还高，一列十一行看下去像一排按钮。
   现在是「贴在字后面的小角标」尺寸，不抢部位名的注意力。 */
.grpbadge{display:inline-block;min-width:14px;padding:0 3px;margin-left:5px;
  font-family:var(--mono);font-size:var(--fs-xs);line-height:13px;text-align:center;
  color:var(--text-inv);background:var(--danger);border-radius:var(--radius-sm);vertical-align:1.5px;font-weight:600
  ;letter-spacing:0}
/* 首页四张卡标题：不加粗（用户第 13 项） */
.wb-mini .hd .wbtitle{font-weight:500;font-size:var(--fs-base);color:var(--ink2);letter-spacing:.2px}

/* 侧栏「我」那一格的退出按钮（用户第 9 项） */
.me .me-out{margin-left:auto;border:1px solid rgba(255,255,255,.18);background:transparent;
  color:rgba(255,255,255,.72);font-size:var(--fs-sm);padding:3px 8px;border-radius:var(--radius-sm);cursor:pointer;flex:none}
.me .me-out:hover{background:rgba(220,80,60,.85);border-color:transparent;color:var(--surface)}

/* 「安排统计」汇总条（用户第 14 项，对齐 V01 image#7） */
.arrstat{display:flex;align-items:center;gap:10px;margin-top:14px;padding:9px 13px;
  background:var(--surface-2);border-radius:var(--radius-sm);font-size:var(--fs-base);color:var(--text-2);
  /* ★ 2026-11-06（第 103 轮）：「送检」拆成「标养 + 同养」之后统计条多了一段，
     1120px 的弹窗里刚好卡在边界上 —— 不设 wrap 的话 flex 会**逐字**压窄每一个 span，
     「安排统」「计」被拆成两行，比换行难看得多。
     现在：段与段之间可以整体换行，段内绝不拆字。 */
  flex-wrap:wrap;row-gap:5px}
.arrstat>span{white-space:nowrap}
.arrstat b{font-weight:600;color:var(--ink3);font-size:var(--fs-sm);letter-spacing:.3px}
/* ★ 2026-11-06（第 103 轮）：「送检」拆成「标养 / 同养」两段 ——
   同养紧跟标养，之间只用间距分开（它们是同一趟车的两半，不该像拆模那样被竖线隔断）；
   拆模 / 钢筋仍带竖线，因为那两段确实不是送检那几箱。 */
.arrstat .same{color:var(--ink3);font-size:var(--fs-sm)}
/* 拆模统计：与送检并列、淡一档，前面加一道竖线分开（用户第 22 轮第 6 项） */
.arrstat .brk{color:var(--ink3);font-size:var(--fs-sm);padding-left:10px;border-left:1px solid var(--line)}
/* 钢筋（原材 / 连接）统计：第 28 轮第 5 项 —— 各自单列一段，不再混进「未标强度」。
   颜色比拆模再淡一档：钢筋试件不装在混凝土的箱子里，是另一批活。 */
.arrstat .mat{color:var(--ink3);font-size:var(--fs-sm);padding-left:10px;border-left:1px solid var(--line);opacity:.85}

/* ============ 资料清单（申领流水号 · 用户 2026-10-30 image#1） ============
   这张弹窗里的东西最终要印成纸送出去，所以屏幕上就按纸的样子摆：
   白底、居中标题、细边框、不留圆角 —— 屏上看着像纸，印出来才不会「不像一个东西」。 */
.dlg.mtdoc{max-width:1120px}
/* 打印模板 · 效果预览（第 35 轮）：纸面 297mm≈1123px，弹窗放得下才不用横拖 */
.dlg.tplprev{max-width:1280px}
/* ============================================================
   弹窗尺寸三档（第 38 轮 · 用户拍板 16:10）
   ------------------------------------------------------------
   以前只有 max-width、高度完全不管，比例是"内容的副产物"：
   内容宽就扁（批量编辑 9 列被压成 1.94:1），内容窄就方。
   现在宽度固定、高度按比例锁，头 / 主体 / 底栏三段固定，只有主体滚动。
     p   440  提示窗口，不锁比例
     w1  760  单栏表单，高度随内容、上限 475
     w2  980×612
     w3 1120×700
   ============================================================ */
/* 尺寸走 CSS 变量（第 41 轮）：后台「界面外观 › 交互与弹窗」可在三档间切换，
   只改这五个变量，不动任何调用点。变量未设置时用兜底值 = 今天线上的样子。 */
.dlg.sz-p{width:min(var(--dlg-p,440px),92vw);max-width:min(var(--dlg-p,440px),92vw);height:auto;max-height:60vh}
.dlg.sz-w1{width:min(var(--dlg-w1,760px),94vw);max-width:min(var(--dlg-w1,760px),94vw);height:auto;max-height:min(475px,88vh)}
.dlg.sz-w2{width:min(var(--dlg-w2,980px),94vw);max-width:min(var(--dlg-w2,980px),94vw);height:min(var(--dlg-h2,612px),88vh)}
.dlg.sz-w3{width:min(var(--dlg-w3,1120px),94vw);max-width:min(var(--dlg-w3,1120px),94vw);height:min(var(--dlg-h3,700px),88vh)}
/* ★ 报料解析窗（2026-11-04 用户：要独立出来，不与 w3 共用）
   它有自己的一对变量 --dlg-pd-w / --dlg-pd-h，后台单独存 ui.parseDlgPx。
   写成独立一档而不是复用 sz-w3，是为了"改 w3 不再顺带改它"这件事
   在 CSS 层就成立 —— 只靠后台界面上多一行选项是拦不住的。 */
.dlg.sz-pd{width:min(var(--dlg-pd-w,1280px),94vw);max-width:min(var(--dlg-pd-w,1280px),94vw);height:min(var(--dlg-pd-h,800px),88vh)}
/* ★ 安排送检窗（2026-11-04 用户第 4 条）：「为何不受后台管理管控？」
   它原来借 w3 档：线上 w3=1280，浏览器按 94vw 夹成满屏，而 w3 的三档最小
   1040 —— 调小了只窄 32px，用户点了"没反应"。
   这扇窗只有 6 个短列，本来就不是宽表；给它自己的变量与档名 plan，
   后台单独三选一（含真正小的 900×620）。默认 980×660。 */
.dlg.sz-plan{width:min(var(--dlg-plan-w,980px),94vw);max-width:min(var(--dlg-plan-w,980px),94vw);height:min(var(--dlg-plan-h,660px),88vh)}
/* 三段式：头与底不参与压缩，主体自己滚 —— 按钮永远可见 */
.dlg.sz-w2 .dlg-hd,.dlg.sz-w3 .dlg-hd,.dlg.sz-pd .dlg-hd,.dlg.sz-plan .dlg-hd,
.dlg.sz-w2 .dlg-ft,.dlg.sz-w3 .dlg-ft,.dlg.sz-pd .dlg-ft,.dlg.sz-plan .dlg-ft{flex:0 0 auto}
.dlg.sz-w2 .dlg-bd,.dlg.sz-w3 .dlg-bd,.dlg.sz-pd .dlg-bd,.dlg.sz-plan .dlg-bd{flex:1 1 auto;min-height:0}
/* 提示窗口：内边距收一档，一句话不必留 20px 的呼吸位 */
.dlg.sz-p .dlg-bd{padding:16px 20px}
.dlg.sz-p .cfm-bd{font-size:var(--fs-sm);line-height:1.7}

/* ============================================================
   「选一种录入方式」· 卡片列表档（第 91 轮 · 2026-11-05）
   ------------------------------------------------------------
   ★ 病灶不是"不好看"，是**结构错了**（用户 21:15 截图）：
     这扇窗只有 3 行字，却套了 w1 档（820 宽），右边白扔 400 多 px；
     三个选项是 `<button class="btn">` + 内联 style 写死 padding ——
     于是拿到的是"三张同款长条按钮"，图标还是 emoji（📄📋📷），
     emoji 在 Windows / 安卓 / 苹果上字形、大小、基线各不相同，
     同一个界面在三个设备上像三个产品。

     选项不是按钮，是**一张卡片一条路**：图标 + 一句话说清它是干什么的 + 去哪。
     所以这里给它自己的档名 pick（宽 520，跟 w1 那套像素无关），
     版式改成 grid 三列（图标 / 文字 / 箭头），文字两行（标题 + 一句解释）。
   ★ 为什么单开一档而不是借用 sz-p：
     p 是"一句话确认"，后台紧凑/标准/宽适会把它在 420~460 之间推来推去；
     520 是这类两行卡片的最小可读宽度（图标 38 + 间距 24 + 正文 ≈ 380），
     跟着 p 飘会在紧凑档掉到 420 把解释句挤成三行。特例就走特例，和
     .dlg.profile / .dlg.tplprev 一个待遇。
   ============================================================ */
.dlg.pick{width:min(520px,calc(100vw - 48px));max-width:min(520px,calc(100vw - 48px));min-width:0;
  height:auto;max-height:min(620px,86vh)}
.dlg.pick .dlg-hd{padding:15px 20px 13px}
.dlg.pick .dlg-bd{padding:2px 20px 20px}

.pick-lead{margin:2px 0 12px;font-size:var(--fs-sm);color:var(--ink3);line-height:1.6}

.pick-list{display:flex;flex-direction:column;gap:9px}

/* 一条 = 一个选项。用 <button> 是为了键盘可达（Tab / Enter / Space 都是免费的），
   但外观必须彻底脱掉 .btn 那一套（那是工具栏按钮的语汇）。 */
.pick-item{
  display:grid;grid-template-columns:38px 1fr 16px;align-items:center;gap:12px;
  padding:13px 14px;border:1px solid var(--line);border-radius:var(--radius-md);
  background:var(--surface);color:inherit;font:inherit;text-align:left;
  cursor:pointer;appearance:none;
  transition:border-color .16s ease,background .16s ease,box-shadow .16s ease,transform .12s ease;
}
.pick-item:hover{border-color:var(--brand);background:var(--brand-soft);box-shadow:var(--shadow-2)}
.pick-item:active{transform:translateY(1px)}
/* 键盘用户必须看得见自己在哪 —— 鼠标用户看不到 outline，互不干扰 */
.pick-item:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

/* 图标底盘：固定 38×38，不随文字长度变形。底色用 brand-soft，
   换皮肤时自动跟着变（硬编码底色的图标块在深色皮肤上会像贴纸）。 */
.pick-ico{
  width:38px;height:38px;border-radius:10px;display:grid;place-items:center;
  background:var(--brand-soft);color:var(--brand);flex:none;
}
.pick-ico svg{width:19px;height:19px;stroke:currentColor;fill:none;
  stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}

.pick-tx{display:block;min-width:0}
.pick-t{display:block;font-size:var(--fs-base);font-weight:600;line-height:1.35;letter-spacing:.01em}
.pick-d{display:block;margin-top:2px;font-size:var(--fs-sm);color:var(--ink3);line-height:1.5}

/* 右侧箭头：平时很淡（它是"可以进去"的暗示，不是装饰），悬停才亮 */
.pick-ar{color:var(--ink3);opacity:.5;transition:transform .16s ease,opacity .16s ease}
.pick-ar svg{width:16px;height:16px;stroke:currentColor;fill:none;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.pick-item:hover .pick-ar{opacity:1;color:var(--brand);transform:translateX(2px)}

/* 窄屏：箭头让位给文字（390px 上那 16px 就是一整行解释的空间） */
@media (max-width:560px){
  .dlg.pick .dlg-hd{padding:14px 16px 12px}
  .dlg.pick .dlg-bd{padding:2px 16px 16px}
  .pick-item{grid-template-columns:34px 1fr;gap:10px;padding:12px}
  .pick-ico{width:34px;height:34px;border-radius:9px}
  .pick-ico svg{width:17px;height:17px}
  .pick-ar{display:none}
}
@media (prefers-reduced-motion:reduce){
  .pick-item,.pick-ar{transition:none}
}


/* ---- 本批次流水号 · 按批次分组（第 38 轮 用户："批次之间层次要分明"）----
   平铺一张表时看不出哪几行属于同一批，而这张单子是照着装箱子的。
   ★ 第 57 轮（用户：「移除『批 N』，只需明显的间隔线即可」）：
     批头的浅底块与编号胶囊全部取消 —— 底色块把表格切成一坨一坨，
     反而比文字更抢眼。现在批次之间只靠一条 3px 实线断开，批头就是部位名本身；
     批内明细仍左缩进一档，层级由缩进承担。 */
.dlg.serials .tbl-serial tr.batch-hd td{
  background:transparent;
  border-top:3px solid var(--border-strong);
  padding-top:12px;padding-bottom:4px;
  font-weight:600;font-size:var(--fs-sm);
}
.dlg.serials .tbl-serial tr.batch-hd:first-child td{border-top:0}
/* 批内明细：部位列缩进，与批头形成层级；序号列淡一档（它是行号，不是数据） */
.dlg.serials .tbl-serial tr.grp-row td:first-child{color:var(--ink3)}
.dlg.serials .tbl-serial tr.grp-row td:nth-child(2){padding-left:20px}
/* 报告登记双屏（用户 2026-10-30 第 7 项，V01 v150 同构） */
/* 报告登记双屏（用户 2026-10-30 第 7 项，V01 v150 同构）
   ★ 第 9 轮第 4 项调整：左栏收窄 1/4 让给右栏（0.68 : 1.32）；两栏等高
     （align-items:stretch），左栏清单填满整列高度、内部滚动 —— 不再是
     max-height:60vh 截断后下面一大块空白（用户图3 红框）。 */
/* ★ 第 46 轮返工（用户）：「右栏居中跟随」第一版用 scrollIntoView，沿祖先链
   把整页 canvas 也滚了 —— 右栏表格短、新行靠页面顶部，整页被拽回顶，
   左栏的滚动位置跟着报废。现在两栏各自 sticky + 内部滚动，页面几乎不滚：
   - 左栏卡片限高视口，清单在 .rr-list 里滚；
   - 右栏卡片也 sticky，登记表在 .base-tbwrap 里滚（max-height 见下）。
   跟随时只滚 .base-tbwrap 自己，页面纹丝不动。 */
.rr-grid{display:grid;grid-template-columns:minmax(0,0.68fr) minmax(0,1.32fr);gap:14px;align-items:start}
.rr-left{position:sticky;top:8px;display:flex;flex-direction:column;max-height:calc(100vh - 16px)}
.rr-list{flex:1;min-height:0;overflow:auto}
.rr-right{position:sticky;top:8px}
.rr-right .base-tbwrap{max-height:48vh;overflow:auto}
@media (max-width:1024px){.rr-grid{grid-template-columns:1fr}.rr-left{position:static}.rr-right{position:static}}
/* 见证记录三栏（第 9 项，V01 wz3 同构） */
.wz-grid{display:grid;grid-template-columns:172px minmax(0,1fr) 318px;gap:14px;align-items:start}
@media (max-width:1180px){.wz-grid{grid-template-columns:156px minmax(0,1fr)}}
@media (max-width:860px){.wz-grid{grid-template-columns:1fr}}
/* 报料解析左右屏（用户 2026-10-30 第 6 项）：接近全屏的两栏，
   左原文右草稿；右列内部滚动，整页不出横竖滚动条 */
.dlg.rp-wide{max-width:min(1460px,96vw);width:100%;height:88vh}
/* ★ 用户 2026-10-30 第 6 项：「左侧报料区减少三分之一列宽，给至右侧」。
   原 0.9fr : 1.6fr ⇒ 左列占 36%；左列减 1/3 ⇒ 0.6fr，右列 1.6 → 1.9，
   左列降到 24%（-12pt）。左列只是贴原文，窄一点照样读得下；
   右列是草稿表（套筒 7 列 + 试件 6 列），宽一点才不用横向拖。 */
.rp-grid{display:grid;grid-template-columns:minmax(240px,0.6fr) minmax(0,1.9fr);gap:16px;height:100%;min-height:0}
.rp-left{display:flex;flex-direction:column;min-height:0}
.rp-left .fld{display:flex;flex-direction:column;flex:1;min-height:0}
.rp-left textarea{flex:1;resize:none;border:1px solid var(--line);border-radius:var(--radius-md);background:var(--panel-2)}
.rp-right{min-width:0;overflow-y:auto;padding-right:4px}
@media (max-width:900px){
  .rp-grid{grid-template-columns:1fr}
  .rp-left textarea{height:180px;flex:0 0 auto}
  .dlg.rp-wide{height:auto;max-height:92vh}
}
.mt-doc{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-sm);padding:22px 24px 18px}
.mt-h1{text-align:center;font-size:var(--fs-lg);font-weight:700;letter-spacing:2px;margin-bottom:6px;color:var(--ink)}
.mt-h2{text-align:center;font-size:var(--fs-base);font-weight:600;margin-bottom:12px;color:var(--ink2)}
.mt-tbl{width:100%;border-collapse:collapse;table-layout:fixed;font-size:var(--fs-sm)}
.mt-tbl th,.mt-tbl td{border:1px solid var(--border-strong);padding:5px 6px;vertical-align:middle;line-height:1.5;word-break:break-all}
.mt-tbl th{background:var(--surface-2);font-weight:600;text-align:center;color:var(--ink2);font-size:var(--fs-sm)}
.mt-tbl td.mt-c{text-align:center}
.mt-tbl td.mt-num{text-align:right;font-variant-numeric:tabular-nums}
.mt-tbl td.mt-wrap{text-align:left;font-size:var(--fs-sm);color:var(--ink2)}
/* 流水号格：空的高度给足，对方要在这一格里手写；已有的用灰字，表示这行不用再要 */
.mt-tbl td.mt-blank{height:30px;background:var(--surface-2)}
.mt-tbl td.mt-has{color:var(--text-3)}
.mt-note{margin-top:10px;font-size:var(--fs-sm);line-height:1.7;color:var(--ink3)}
.mt-warn{margin-top:10px;padding:9px 12px;border-radius:var(--radius-sm);background:var(--warn-soft);
  border-left:3px solid var(--warn);font-size:var(--fs-sm);line-height:1.65;color:var(--warn-ink)}

/* 抬头缺混凝土公司：下划线给人手写，颜色压暗，不像报错但一眼看得出要补 */
.mt-h2.mt-miss{color:var(--text-3);font-weight:400;letter-spacing:1px}

/* 今日账单：按材料类型一行一条 + 金额占比条（用户 2026-10-30 第 4 项，对齐 V01 图 9） */
.wb-fee{padding:7px 0;border-bottom:1px solid var(--line-2)}
.wb-fee:last-of-type{border-bottom:none}
.wb-feeln{display:flex;align-items:center;gap:7px}
.wb-feedot{width:7px;height:7px;border-radius:var(--radius-sm);background:var(--dot-alert);flex:none}
.wb-feet{font-size:var(--fs-base);color:var(--ink);flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wb-feeg{font-size:var(--fs-xs);color:var(--ink3);font-variant-numeric:tabular-nums}
.wb-fee .wb-mfee{font-size:var(--fs-base);font-weight:600;color:var(--ink);min-width:56px;text-align:right}
.wb-feebar{height:4px;border-radius:var(--radius-sm);background:var(--surface-3);margin-top:5px;overflow:hidden}
.wb-feebar i{display:block;height:100%;border-radius:var(--radius-sm);background:var(--dot-alert)}

/* 浇筑记录页的两类新卡（用户 2026-10-30 第 1 项，图 2） */
.kpi.k5::before{background:var(--danger)}
.kpi.k6::before{background:var(--info)}
/* 混凝土公司名很长（惠州市华丽盛混凝土有限公司 = 14 字），
   单行省略 + title 看全名，否则一行卡里会折三行把方量挤没 */
.kpi.k6 .l{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:var(--fs-sm);max-width:100%}
.kpi.k6 .v{font-size:calc(19px * var(--font-scale));margin-top:2px}
.kpis.many{grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}

/* ============ KPI 概览带（第 29 轮 · 用户：「首页增加V01同款KPI」） ============
   V01 q-band 的骨架：横排「大数字 + 标签」，竖线分隔，点击定位；
   档位色 r=逾期红 / w=临近橙 / b=品牌蓝 / c=流转青 / g=健康绿，零值灰。
   默认是普通卡片带；松山绿皮肤在 skins.css 里整条换成松绿渐变白字。 */
.qband{display:flex;align-items:stretch;flex-wrap:wrap;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--radius-lg);padding:8px 10px;margin:0 0 14px}
.qband .q-gr{flex:1 1 0;min-width:92px;display:flex;flex-direction:column;align-items:center;gap:1px;
  background:none;border:0;cursor:pointer;padding:7px 8px;border-radius:var(--radius-md);
  font:inherit;color:inherit}
.qband .q-gr:hover{background:var(--surface-3)}
.qband .q-gr .v{font-family:var(--mono);font-size:calc(24px * var(--font-scale));font-weight:700;line-height:1.15;
  letter-spacing:-.4px;color:var(--ink);font-variant-numeric:tabular-nums}
.qband .q-gr .v.zero{color:var(--ink3);opacity:.55}
.qband .q-gr .l{font-size:var(--fs-sm);color:var(--ink3);white-space:nowrap}
.qband .q-gr.r .v{color:var(--danger)}
.qband .q-gr.w .v{color:var(--warn)}
.qband .q-gr.b .v{color:var(--brand)}
.qband .q-gr.c .v{color:var(--info)}
.qband .q-gr.g .v{color:var(--ok)}
.qband .vr{width:1px;background:var(--line);margin:6px 0}
/* 窄屏：三列两行，竖线在行尾会显得突兀 —— 干脆藏掉 */
@media (max-width:860px){
  .qband .q-gr{flex:1 1 30%}
  .qband .vr{display:none}
}

/* ============ 流水号登记弹窗（用户 2026-10-30 第 1 项，对齐 V01 图 1） ============
   六列：部位/强度 · 方量 · 标养 · 同养 · 拆模 · 流水号，再右侧一个逐行删除。
   组数三格做成窄输入框：它们通常就是 1、2 这种个位数，宽了反而要拖动眼睛。 */
.pf-wrap{border:1px solid var(--line);border-radius:var(--radius-md);overflow:hidden}
.pf-tbl{margin:0;font-size:var(--fs-base)}
.pf-tbl th{background:var(--surface-2);font-weight:600;font-size:var(--fs-sm);color:var(--ink2);padding:8px 8px;border-bottom:1px solid var(--line)}
.pf-tbl td{padding:6px 8px;border-bottom:1px solid var(--line-2);vertical-align:middle}
.pf-tbl tbody tr:last-child td{border-bottom:none}
.pf-tbl th:first-child,.pf-tbl td:first-child{padding-left:12px}
.pf-tbl td.pf-part{white-space:nowrap}
.pf-pn{font-size:var(--fs-base);color:var(--ink);margin:0 4px}
/* 构件类型胶囊：墙柱偏红、梁板偏蓝 —— 与施工顺序一致（先竖向后水平） */
.ptag{display:inline-block;padding:0 5px;border-radius:3px;font-size:var(--fs-xs);
  line-height:15px;font-style:normal;margin-right:5px;font-weight:500}
.ptag.wall{background:var(--danger-soft);color:var(--danger-ink)}
.ptag.slab{background:var(--info-soft);color:var(--info-ink)}
.gtag{display:inline-block;padding:0 5px;border-radius:3px;font-size:var(--fs-xs);line-height:15px;
  font-style:normal;background:var(--surface-3);color:var(--text-2);font-family:var(--mono)}
.pf-num{width:72px;text-align:right;padding:5px 7px}
.pf-no{width:100%;min-width:118px;padding:5px 8px;letter-spacing:.3px}
/* 流水号前缀守卫（第 17 轮）：红框=前缀不符；虚线绿框=系统尾数 +1 带入 */
.sn-wrap{min-width:118px}
.sn-hint{font-size:var(--fs-xs);line-height:15px;min-height:15px;margin-top:2px;color:var(--ink3)}
.sn-hint.bad{color:var(--danger-ink,var(--danger))}
.sn-hint.auto{color:var(--ok-ink,var(--ok))}
.pf-no.pf-bad{border-color:var(--danger);box-shadow:0 0 0 1px var(--danger-soft) inset}
.pf-no.pf-auto{border-style:dashed;border-color:var(--ok,var(--brand))}
.pf-tbl td.pf-del{width:34px;text-align:center;padding-right:10px}
.btn-x{width:22px;height:22px;line-height:1;border-radius:var(--radius-sm);border:1px solid var(--line);
  background:var(--surface);color:var(--ink3);font-size:var(--fs-md);cursor:pointer;padding:0}
.btn-x:hover{background:var(--danger-soft);border-color:var(--danger);color:var(--danger-ink)}
/* 登记日期 / 混凝土公司 / 备注：两列一行，备注占满 */
.pf-meta{display:flex;gap:14px;margin-top:14px}
.pf-f{display:flex;flex-direction:column;gap:5px;flex:1;min-width:0}
.pf-f label{font-size:var(--fs-sm);color:var(--ink3)}
.pf-f.pf-wide{margin-top:10px}
.pf-f .inp{height:32px;padding:0 9px;border:1px solid var(--line);border-radius:var(--radius-sm);
  font:inherit;font-size:var(--fs-base);color:var(--ink);background:var(--surface);width:100%;box-sizing:border-box}
.pf-f select.inp{height:32px}

/* 危险动作按钮（删除本批 / 取消排期）：红字淡红底，不填满 —— 不用最重的样式喊人点它 */
.btn.danger{color:var(--danger);border-color:var(--danger-soft)}
.btn.danger:hover{background:var(--danger-soft);color:var(--danger-ink)}

/* ============ 见证组号录入弹窗（用户 2026-10-30 第 3 项，图 7） ============ */
.tabs-in{display:flex;gap:6px;margin-bottom:14px;border-bottom:1px solid var(--line)}
.tabs-in .tab{border:1px solid transparent;background:transparent;padding:7px 15px;border-radius:var(--radius-sm) 7px 0 0;
  font:inherit;font-size:var(--fs-base);color:var(--ink3);cursor:pointer;margin-bottom:-1px}
.tabs-in .tab:hover{color:var(--ink2)}
.tabs-in .tab.on{background:var(--surface);border-color:var(--line);border-bottom-color:var(--surface);
  color:var(--brand);font-weight:600}
.wg-bar{display:flex;gap:12px;align-items:flex-end;margin-bottom:12px;flex-wrap:wrap}
.wg-f{display:flex;flex-direction:column;gap:5px}
.wg-f label{font-size:var(--fs-sm);color:var(--ink3)}
.wg-f .inp{width:200px;height:32px;padding:0 9px;border:1px solid var(--line);border-radius:var(--radius-sm);
  font:inherit;font-size:var(--fs-base);font-family:var(--mono);color:var(--ink);background:var(--surface);box-sizing:border-box}
.wg-maker .wg-mk{height:32px;display:flex;align-items:center;font-size:var(--fs-base);color:var(--ink2)}

/* ============ 批量编辑（用户 2026-10-30 第 6 项，图 11） ============
   上排统一字段（填了覆盖全批）+ 下排差异明细，两列布局。
   用户 2026-10-30 第 5 项：每个字段压成一行（label 右对齐定宽 + 输入框 + 清空），
   7 个字段 4 行放下，整个表单区高度砍半。 */
.be-box{display:grid;grid-template-columns:1fr 1fr;gap:7px 14px;padding:10px 14px;
  border:1px solid var(--line);border-radius:var(--radius-md);background:var(--surface-2);margin-bottom:12px}
.be-f{display:flex;align-items:center;gap:7px;min-width:0;position:relative}
.be-f.span2{grid-column:1 / -1}
.be-f>label:first-child{font-size:var(--fs-sm);color:var(--ink3);flex:0 0 78px;text-align:right;white-space:nowrap}
.be-f .inp{height:28px;padding:0 8px;border:1px solid var(--line);border-radius:var(--radius-sm);
  font:inherit;font-size:var(--fs-base);color:var(--ink);background:var(--surface);flex:1;min-width:0;width:auto;box-sizing:border-box}
.be-clr{display:flex;align-items:center;gap:3px;font-size:var(--fs-xs);color:var(--ink3);margin:0;flex:0 0 auto;white-space:nowrap;cursor:pointer}
.be-clr input{width:12px;height:12px;margin:0}
.be-sec{font-size:var(--fs-base);color:var(--ink2);text-align:center;margin:4px 0 8px}
.be-state{font-size:var(--fs-sm);color:var(--ink3)}
/* 批量编辑 · 差异明细（第 35 轮④）：9 列放不进弹窗 —— 横向可滚 + 输入框贴列宽，
   钢筋母材厂家这类长值列不再被 overflow:hidden 裁掉 */
.be-tbl{overflow-x:auto}
.be-tbl table{width:100%;border-collapse:collapse}
.be-tbl th{white-space:nowrap}
.be-tbl td{padding:4px 6px}
.be-tbl td .inp{width:100%;min-width:0;box-sizing:border-box}
/* ★ 第 35 轮追加②（用户）：表头与数据**居中 + 垂直居中** */
/* ★★ 2026-11-01 第 37 轮（用户图 1：批量编辑「钢筋母材厂家」显示不全、备注被挤）：
   原来只给 4 列定了宽，其余列交给浏览器的 auto 布局 —— 而 auto 布局的原则是
   「按最长内容撑」，于是「河源德润钢铁有限公司」把母材厂家列撑到 190px，
   备注列被压到 80px 只剩两三个字，整张表还要横向滚动。
   改成 **table-layout:fixed + 九列全部定宽**：列宽与内容无关，永远一样宽，
   改哪一行都不会因为某个字变长而让整表跳一下。备注列吃剩余宽度。 */
.be-tbl table{table-layout:fixed}
.be-tbl th, .be-tbl td{text-align:center;vertical-align:middle;overflow:hidden;text-overflow:ellipsis}
.be-tbl th:nth-child(1), .be-tbl td:nth-child(1){width:36px}
.be-tbl th:nth-child(2), .be-tbl td:nth-child(2){width:92px}
.be-tbl th:nth-child(3), .be-tbl td:nth-child(3){width:128px}
.be-tbl th:nth-child(4), .be-tbl td:nth-child(4){width:126px}
.be-tbl th:nth-child(5), .be-tbl td:nth-child(5){width:88px}
.be-tbl th:nth-child(6), .be-tbl td:nth-child(6){width:62px}
.be-tbl th:nth-child(7), .be-tbl td:nth-child(7){width:126px}
.be-tbl th:nth-child(8), .be-tbl td:nth-child(8){width:140px}
.be-tbl td:nth-child(10){width:32px}

/* ============================================================
   账号与成员（第 35 轮追加⑪ · 按 _v649 设计稿实施）
   行卡式成员列表 + 单击行弹「成员详情」弹窗
   ============================================================ */
.mb-row{display:flex;align-items:center;gap:14px;padding:11px 16px;border-top:1px solid var(--line);cursor:pointer}
.mb-row:hover{background:var(--surface-2)}
.mb-row.off{opacity:.62}
.mb-ava{width:34px;height:34px;border-radius:50%;background:var(--brand);color:#fff;display:grid;place-items:center;
  font-size:calc(14px * var(--font-scale));font-weight:700;flex:none}
.mb-ava.dim{background:var(--ink3)}
.mb-mi{flex:1;min-width:0}
.mb-mi .n{font-weight:600}
.mb-mi .n small{color:var(--ink3);font-weight:400;margin-left:8px;font-family:var(--mono);font-size:calc(11.5px * var(--font-scale))}
.mb-mi .s{font-size:calc(11.5px * var(--font-scale));color:var(--ink3)}
.mb-rt{text-align:right;flex:none}
.mb-rt .t{font-size:calc(12px * var(--font-scale));color:var(--ink2)}
.mb-rt .s{font-size:calc(11px * var(--font-scale));color:var(--ink3)}
.mb-perm{display:inline-block;border:1px solid var(--line);border-radius:14px;padding:1px 10px;
  font-size:calc(11.5px * var(--font-scale));color:var(--ink2);margin:0 4px 4px 0}
.mb-perm.on{background:var(--brand-soft);border-color:var(--brand);color:var(--brand)}
.mb-perm.click{cursor:pointer}
.mb-perm.click:hover{border-color:var(--brand)}
.mb-ops{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.mb-op{border:1px solid var(--line);border-radius:10px;padding:9px 12px;font-size:calc(12.5px * var(--font-scale));background:var(--surface);
  cursor:pointer;text-align:left;font-family:inherit;width:100%;color:var(--ink)}
.mb-op:hover:not(:disabled){border-color:var(--brand)}
.mb-op b{display:block;font-size:calc(12.5px * var(--font-scale))}
.mb-op small{color:var(--ink3)}
.mb-op.dgr{border-color:#e5c4c1;background:#fdf7f6}
.mb-op.dgr b{color:var(--danger)}
.mb-op:disabled{opacity:.45;cursor:not-allowed}
.chips{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.chip{border:1px solid var(--line);border-radius:16px;padding:3px 12px;font-size:calc(12px * var(--font-scale));color:var(--ink2);
  background:var(--surface);cursor:pointer;font-family:inherit}
.chip.on{background:var(--brand-soft);border-color:var(--brand);color:var(--brand);font-weight:600}

/* ============================================================
   V01 样式基线（P0 · 用户 2026-10-30 批准「立即开工」）
   ------------------------------------------------------------
   从 V01 v465/v460 段抽出的台账视觉语言，落成 V02 的基线类：
     台账卡（.base-card）+ 卡头（.base-chd）+ 工具条（.base-tbar）
     + 紧凑居中表（.base-tb）+ 状态点（.base-st）+ 胶囊（.base-badge）
     + 分页条（.base-pg）。
   ★ 数值取自 V01 源码（v465css 段）：表 12.5px、表头 11.5px/500、
     单元格 9px 8px 居中、部位列左对齐 min-width 170px、行 hover 底色。
   ★ 只作用于「屏」的表格；设置页 / 抽屉 / 弹窗继续用 .tbl（用户要求保留现状）。
   ============================================================ */
.base-card{background:var(--card,var(--surface));border:1px solid var(--line);border-radius:var(--radius-lg);margin-bottom:14px;overflow:hidden}
.base-chd{display:flex;align-items:center;gap:10px;padding:11px 14px;border-bottom:1px solid var(--line-2);flex-wrap:wrap}
.base-chd h3{font-size:var(--fs-md);font-weight:700;margin:0}
.base-chd .n{font-size:var(--fs-sm);color:var(--ink3)}
.base-chd .r{margin-left:auto;font-size:var(--fs-sm);color:var(--ink3)}
.base-tbar{display:flex;align-items:center;gap:8px;padding:10px 14px;flex-wrap:wrap}
.base-tbar .sp{flex:1}
.base-tbwrap{overflow-x:auto}
/* ★ 第 13 轮：原子型单元格改成不折行后，16 列的试件台账在 1080 下必然需要横滚。
   滚动条不能"藏起来"—— 藏了看起来就是最后一列被硬切（第 10 轮右栏就是这么被吐槽的）。
   这里给它一条常驻细滚动条，与工作台待办表同一套观感。 */
.base-tbwrap::-webkit-scrollbar{height:8px}
.base-tbwrap::-webkit-scrollbar-thumb{background:var(--line);border-radius:4px}
.base-tbwrap::-webkit-scrollbar-thumb:hover{background:var(--ink4)}
.base-tbwrap::-webkit-scrollbar-track{background:transparent}
.base-tb{width:100%;border-collapse:collapse;font-size:var(--fs-base)}
.base-tb th{padding:9px 8px;text-align:center;vertical-align:middle;font-weight:500;color:var(--ink3);
  font-size:var(--fs-sm);background:var(--panel-2);border-bottom:1px solid var(--line-2);white-space:nowrap;position:sticky;top:0;z-index:2}
.base-tb td{
  /* ★ 第 13 轮：原子型单元格不许断字。公司名被拆成「惠州市华丽 / 盛混凝土有 / 限公司」、
     日期折成「2026- / 10-31」、流水号折成三截 —— 都是 word-break:break-word 干的。
     放不下就让 .base-tbwrap 横向滚（它本来就是 overflow-x:auto），不要断字。 */
  padding:9px 8px;text-align:center;vertical-align:middle;color:var(--ink2);
  border-bottom:1px solid var(--line-2);word-break:break-word}
.base-tb td.mono,.base-tb td.cmp{white-space:nowrap}
.base-tb td.pt{text-align:left;color:var(--ink);font-weight:500;min-width:170px}
.base-tb td.on{color:var(--ink);font-weight:700}
.base-tb tr.rw{cursor:pointer}
.base-tb tbody tr:hover{background:var(--panel-2)}
.base-tb .sn{font-family:var(--mono);font-size:var(--fs-sm)}
.base-tb .mut{color:var(--ink3);opacity:.45}
.base-badge{display:inline-block;font-size:var(--fs-xs);font-weight:600;padding:1px 7px;border-radius:var(--radius-full);
  background:var(--panel-2);color:var(--ink3);white-space:nowrap}
.base-badge.mix{background:var(--warn-soft);color:var(--warn)}
.base-st{display:inline-flex;align-items:center;gap:5px;font-size:var(--fs-sm);font-weight:600;white-space:nowrap}
.base-st i{width:6px;height:6px;border-radius:var(--radius-full);background:currentColor;flex:none}
.base-st.wait{color:var(--warn)}
.base-st.done{color:var(--ok)}
.base-st.over{color:var(--danger)}
.base-grow td{background:var(--panel-2);border-top:1px solid var(--line-2);font-size:var(--fs-sm);
  color:var(--ink3);padding:6px 10px;text-align:left}
.base-pg{display:flex;align-items:center;gap:8px;padding:9px 14px;font-size:var(--fs-sm);color:var(--ink3);flex-wrap:wrap}
/* ★ 用户 2026-10-30 第 9 轮第 5 项（图4）：「页序变形了」——
   台账分页的页码容器只有 .pager .pages 有样式（那是别的屏的前缀），
   台账的 .base-pg 下 .pages 一直裸奔：display:block、宽度塌到 40px，
   ‹ 1 2 › 四个按钮竖着叠成一坨，看着就像一个奇怪的输入框。 */
.base-pg .pages{display:flex;gap:3px;align-items:center}
/* 页码按钮样式同样只在 .pager 前缀下定义过 —— 台账这边一并补齐（与 .pager .pg 同款） */
.base-pg .pg{min-width:27px;height:27px;border-radius:var(--radius-sm);border:1px solid var(--line);background:var(--surface);display:grid;place-items:center;font-size:var(--fs-base);cursor:pointer;color:var(--ink2);padding:0 6px}
.base-pg .pg.on{background:var(--brand);border-color:var(--brand);color:var(--surface);font-weight:600}
.base-pg .sp{flex:1}
.base-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:12px;margin-bottom:14px}
.base-kpi{background:var(--card,var(--surface));border:1px solid var(--line);border-radius:var(--radius-lg);padding:13px 16px}
.base-kpi .t{font-size:var(--fs-sm);color:var(--ink3)}
.base-kpi .v{font-size:var(--fs-2xl);font-weight:700;letter-spacing:-.4px;margin:2px 0}
.base-kpi .s{font-size:var(--fs-xs);color:var(--ink3)}

/* V01 td.pt：部位列左对齐 + 最宽 170px（基线表专用） */
/* ★ 用户 2026-10-30 第 9 轮第 2 项：部位列宽收口为「超过 18 字自动换行」（18em，
   随 --font-scale 等比）。之前写死 115px：轴线串一挤，名称被硬折成碎片。
   white-space:normal 保留 —— 长轴号串在 18em 内自然折行。 */
.base-tb td.partcell{text-align:left;color:var(--text-1);font-weight:500;
  min-width:13em;max-width:18em;width:18em;
  line-height:1.5;white-space:normal}
/* ★ 用户 2026-10-31 第 11 轮第 2 项：钢筋原材的「工程部位」表头与数据居中、垂直居中。
   只作用于 rebar（ledger.js 里按域加 class）—— 其它域部位短，左对齐便于扫行。 */
.base-tb th.part-center,.base-tb td.part-center{text-align:center;vertical-align:middle}
/* ★ 第 11 轮第 12 项：轴线前缀与构件名拆开后的展示 —— 轴线是小字淡色，
   同一批多个部位共用一条轴线时只写一次（ledger.js 去重后置顶）。 */
.base-tb td.partcell .part-axis{display:inline-block;font-size:calc(11px * var(--font-scale));color:var(--ink3);font-weight:400;letter-spacing:-.2px;
  line-height:1.35;margin-bottom:1px}

/* ============================================================
   台账三处改版（用户 2026-11-01 第 39 轮拍板）
   ------------------------------------------------------------
   ① 养护五列并一列 ② 报告编号两行式 ③ 部位类型胶囊
   三条改动是同一个决定的三个面：省宽度 → 把宽度用在「部位」和「报告号」上。
   颜色全部走令牌（tag-* / brand / warn / info / ink3），深色皮肤下不掉字。
   ============================================================ */
/* ① 养护 chips —— 「标 12」「同 2」「拆模 1」，0 组不渲染
   ★ 第 44 轮追：列头改「养护类型」，数据垂直居中
   （行高被左侧多行部位撑高后，chips 原来贴着基线漂在上面）。 */
.base-tb td.curecell{white-space:nowrap;text-align:left;vertical-align:middle}
.cure{display:inline-flex;align-items:center;gap:4px;flex-wrap:nowrap}
.ct{display:inline-block;padding:0 5px;border-radius:4px;font-size:var(--fs-xs);line-height:16px;
  font-weight:600;font-family:var(--mono);background:var(--tag-mute-bg);color:var(--text-2);
  letter-spacing:0;white-space:nowrap}
.ct b{font-weight:700;color:var(--text-1);margin-left:1px}
.ct.std{background:var(--brand-soft);color:var(--brand)}
.ct.same{background:var(--warn-soft);color:var(--warn-ink)}
.ct.brk{background:var(--info-soft);color:var(--info-ink)}

/* ② 报告编号：固定两行，宽度锁死 —— 号再长也不会把第二行挤掉 */
.base-tb td.rnocell{min-width:9.5em;max-width:13em}
.rno{display:inline-flex;flex-direction:column;align-items:flex-start;line-height:1.45;max-width:100%}
/* ★ line-height 必须给绝对值（16px），不能只给倍数：
   `overflow:hidden`（要它做省略号）同时会裁掉纵向溢出，
   倍数行高算出来的行盒比汉字 em 框矮一点点，第二行的「等 / 个」下缘会被切掉。
   给一个比字号略大的固定行高，横向省略照旧、纵向不再掉笔画。 */
.rno1{font-family:var(--mono);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;
  letter-spacing:-.2px;line-height:18px}
.rno2{font-family:var(--mono);font-size:var(--fs-xs);color:var(--ink3);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;max-width:100%;letter-spacing:-.2px;line-height:16px}

/* ③ 部位：轴线一行淡化 + 构件名逐行 + 类型胶囊 */
.base-tb td.partcell .part-axis{display:block;font-size:calc(10.5px * var(--font-scale));color:var(--ink4);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:20em;line-height:1.3;margin-bottom:1px}
.base-tb td.partcell .cn{display:flex;align-items:center;gap:4px;line-height:1.45}
/* ★★ 第 57 轮（用户：「工程部位表头及数据居中垂直显示，之前处理过一次，为何恢复了」）
     原因不是谁把 CSS 删了，而是第 39 轮把部位格的内容换成了 .cn 弹性行（部位胶囊）：
     `text-align:center` 只管行内内容，**flex 容器的主轴对齐不看 text-align**，
     所以第 35 轮加的居中在那一轮之后就对数据格失效了（表头是纯文本，仍居中）。
     修法：给弹性行补 justify-content，与表头 part-center 同口径。 */
.base-tb td.part-center .cn{justify-content:center}
.base-tb td.part-center{text-align:center;vertical-align:middle}
.base-tb td.partcell .cn > span:not(.grpbadge){min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ptag{display:inline-block;font-style:normal;flex:0 0 auto;padding:0 4px;border-radius:4px;font-size:calc(10px * var(--font-scale));
  font-weight:700;line-height:15px;border:1px solid transparent;letter-spacing:0}
.ptag.wall{background:var(--brand-soft);color:var(--brand);border-color:var(--brand-soft)}
.ptag.slab{background:var(--info-soft);color:var(--info-ink);border-color:var(--info-soft)}
.ptag.base{background:var(--warn-soft);color:var(--warn-ink);border-color:var(--warn-soft)}
.base-tb td.idx,.base-tb td.num{font-variant-numeric:tabular-nums}
.base-tb td.grpbadge{text-align:center}
.base-tb td.idx,.base-tb td.num{font-variant-numeric:tabular-nums}
.base-tb td.grpbadge{text-align:center}

/* ============================================================
   后台「一级分类」两级树编辑器（重构阶段 E）
   ------------------------------------------------------------
   左栏组 / 右栏条目。两侧都 sticky，滚动长列表时另一侧不跑。
   ============================================================ */
.navtree{display:grid;grid-template-columns:minmax(260px,0.85fr) minmax(0,1.15fr);gap:14px;align-items:start}
.navtree-l,.navtree-r{min-width:0}
.navtree-l{position:sticky;top:8px}
.navtree .card.pad{padding:12px 14px}
.navtree .hd{display:flex;align-items:center;gap:8px;margin-bottom:9px;font-size:var(--fs-base)}
.navtree .hd b{font-weight:650;font-size:var(--fs-base)}
.navtree .hd .sub{margin-left:auto;font-size:var(--fs-xs);color:var(--ink3)}
.navtree-g{display:flex;align-items:center;gap:7px;padding:7px 9px;border:1px solid var(--line);
  border-radius:var(--radius-md);margin-bottom:5px;cursor:pointer;background:var(--panel,var(--surface))}
.navtree-g:hover{background:var(--panel-2)}
.navtree-g.on{border-color:var(--brand);background:var(--brand-soft)}
.navtree-g .nm{font-size:var(--fs-base);font-weight:500}
.navtree-i{display:flex;align-items:center;gap:7px;padding:7px 9px;border:1px solid var(--line);
  border-radius:var(--radius-md);margin-bottom:5px;background:var(--panel,var(--surface))}
.navtree-i:hover{background:var(--panel-2)}
.navtree-i.off{opacity:.5}
.navtree-i .nm{font-size:var(--fs-base);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.navtree-i .btn.sm{flex:none}
@media (max-width:900px){.navtree{grid-template-columns:1fr}.navtree-l{position:static}}

/* ============================================================
   响应式（皮肤重设计 · 补齐断点）
   ------------------------------------------------------------
   ★ 之前的 7 处媒体查询只覆盖了 3 个断点，且侧栏/抽屉是固定像素 ——
     1366×768（最常见的笔记本）下侧栏占掉 232px，内容区只剩 1134px，
     14 列的台账表必然横向挤压。

   断点策略（按内容需要，不是按设备）：
     ≤1440  内容区偏紧 → 侧栏略收、KPI 降列
     ≤1180  两栏屏（报告登记/见证）改为单列
     ≤1024  侧栏收成图标条（64px）—— 这是笔记本横屏的常见宽度
     ≤860   见证三栏折成单列
     ≤768   平板竖屏：抽屉全宽、KPI 两列、表单单列
     ≤480   手机：隐藏次要列、按钮竖排
   ============================================================ */

/* ≤1440：侧栏略收 + KPI 更紧凑 */
@media (max-width:1440px){
  :root{ --rail-w:176px; --drawer-w:460px; }
  .kpis{grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px}
  .kpi{padding:11px 13px}
  .kpi .v{font-size:calc(21px * var(--font-scale))}
}

/* ≤1180：内容区进一步收紧 */
@media (max-width:1180px){
  :root{ --rail-w:168px; }
  .kpi .v{font-size:calc(20px * var(--font-scale))}
  .base-tb{font-size:calc(12px * var(--font-scale))}
  .base-tb td{padding:8px 6px}
  .base-tb td.partcell{min-width:100px}
}

/* ≤1024：侧栏收成图标条（只留图标，悬停出文字） */
@media (max-width:1024px){
  /* 宽度由 .rail.collapsed 控制（JS 在窄屏自动加 collapsed 类），
     这里不再重复设 --rail-w —— 两处都设会出现"CSS 说的宽度"和
     "JS 折叠的宽度"打架的情况。 */
  /* ★ 侧栏收窄**复用** .rail.collapsed（core.js 里已有的折叠机制 + localStorage 记忆），
     不另写一套 —— 同一件事两处真相 = 改一处忘一处。
     JS 侧：core.js 在 ≤1024 时自动加 collapsed 类（见 renderRail 里的 autoCollapse）。
     这里只补 collapsed 态的宽度与图标放大：
       文字在 i（标签）、图标在 .ic（span）—— 别搞反，
       之前把 font-size:0 和 font-size:calc(15px * var(--font-scale)) 都加在 i 上，结果文字没藏住反而被放大，
       64px 宽的侧栏里文字竖成一列。 */
  .rail.collapsed{width:var(--rail-w-narrow);flex:0 0 var(--rail-w-narrow)}
  .rail.collapsed .nav a{justify-content:center;padding-left:0;padding-right:0;position:relative}
  .rail.collapsed .nav a .ic{font-size:calc(16px * var(--font-scale));width:24px;flex:0 0 24px}
  .rail.collapsed .nav a .badge{display:none}
  .rail.collapsed .brand{justify-content:center;padding-left:0;padding-right:0}
  .rail.collapsed .me{justify-content:center;padding-left:0;padding-right:0}
  .rail.collapsed .proj{justify-content:center}
  .rail.collapsed .nav .grp{text-align:center;overflow:hidden;white-space:nowrap}
  /* 悬停出文字（用 data-label，零 JS） */
  .rail.collapsed .nav a:hover::after{
    content:attr(data-label);position:absolute;left:calc(100% + 8px);top:50%;
    transform:translateY(-50%);background:var(--rail-on);color:var(--rail-ink);
    padding:5px 9px;border-radius:var(--radius-sm);font-size:var(--fs-sm);
    white-space:nowrap;z-index:40;box-shadow:var(--shadow-2);
  }
  .navtree{grid-template-columns:minmax(200px,.8fr) minmax(0,1.2fr)}
}

/* ≤768：平板竖屏 */
@media (max-width:768px){
  :root{ --rail-w:56px; --drawer-w:100vw; --topbar-h:48px; }
  .drawer{width:100vw;max-width:100vw}
  .kpis{grid-template-columns:repeat(2,minmax(0,1fr))}
  .form{grid-template-columns:1fr}
  .split{grid-template-columns:1fr}
  .wall{grid-template-columns:1fr}
  .cmdbar{padding-left:12px;padding-right:12px}
  .topbar,.cmdbar{gap:6px}
  .topbar .proj-top .proj-name{max-width:96px}
}

/* ≤480：手机 */
@media (max-width:480px){
  .kpis{grid-template-columns:1fr}
  .rail{display:none}
  .topbar{padding-left:8px;padding-right:8px}
  .dlg{min-width:0;max-width:96vw}
  .dlg-ft{flex-wrap:wrap}
  .dlg-ft .btn{flex:1}
  .base-tb{font-size:calc(11.5px * var(--font-scale))}
  .base-tb th,.base-tb td{padding:6px 4px}
  .base-tb td.partcell{min-width:88px}
}

/* ============================================================
   后台管理页专用（皮肤重设计：从 admin.html 内联样式迁来）
   ------------------------------------------------------------
   ★ 为什么要迁：内联样式里的硬编码色（#0F1C19 / #fff）不受令牌体系管 ——
     换肤时它就是最后一块没换的地方，深色模式下警示条直接变成"浅金底白字"。
   ============================================================ */
.rail.admin{background:var(--rail-bg);width:var(--rail-w);flex:0 0 var(--rail-w)}
.rail.admin .proj{background:var(--rail-chip);border-color:var(--rail-line)}
.adm-bar{
  height:34px;flex:0 0 34px;background:var(--warn-ink);color:var(--text-inv);
  display:flex;align-items:center;gap:10px;padding:0 20px;font-size:var(--fs-base);font-weight:500;
}
.adm-bar a{color:var(--text-inv);text-decoration:underline;margin-left:auto}
.m2{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.m3{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.big{font-family:var(--mono);font-size:var(--fs-2xl);font-weight:600;letter-spacing:-.5px}

/* ============================================================
   导出表格模板管理（第 28 轮 · 后台「输出 → 导出表格模板」）
   ------------------------------------------------------------
   左列清单、右预览：勾选 / 调序 / 改列宽都在左边，
   右边实时看到导出出来长什么样 —— 改样式这件事「看到」比「描述」快。
   ============================================================ */
.xtpl-tabs{display:flex;gap:8px;margin:0 0 14px;flex-wrap:wrap}
.xtpl-body{display:grid;grid-template-columns:minmax(320px,1fr) minmax(360px,1.1fr);gap:16px;align-items:start}
@media (max-width:980px){.xtpl-body{grid-template-columns:1fr}}
.xtpl-cols{border:1px solid var(--line);border-radius:10px;padding:12px;background:var(--card)}
.xtpl-cols-hd{display:flex;align-items:center;gap:8px;font-size:var(--fs-base);padding-bottom:8px;border-bottom:1px solid var(--line);margin-bottom:8px}
.xtpl-cols-hd .muted{font-size:calc(12px * var(--font-scale));color:var(--ink3)}
.xtpl-cols-bd{display:flex;flex-direction:column;gap:4px;max-height:52vh;overflow:auto}
.xtpl-col{display:flex;align-items:center;gap:8px;padding:5px 6px;border-radius:7px}
.xtpl-col:hover{background:var(--panel-2)}
.xtpl-col-lbl{min-width:88px}
.xtpl-w{width:74px;flex:0 0 74px}
/* ★ 第 51 轮：「＋ 添加列」下拉行（清单 = 导出集，移除的列从这里加回） */
.xtpl-addrow{display:flex;justify-content:flex-start;padding:8px 6px 2px;border-top:1px dashed var(--line);margin-top:6px}
.xtpl-add{max-width:240px}
.xtpl-side{display:flex;flex-direction:column;gap:12px}
.xtpl-opts{display:flex;flex-direction:column;gap:6px;border:1px solid var(--line);border-radius:10px;padding:10px 12px;background:var(--card)}
.xtpl-opts .ck{display:flex;align-items:center;gap:8px;cursor:pointer}
.xtpl-prev{border:1px solid var(--line);border-radius:10px;padding:12px;background:var(--card)}
.xtpl-table td{font-size:calc(12px * var(--font-scale));white-space:nowrap}
.xtpl-table thead th{background:var(--panel-2)}
.btn.xs{padding:1px 6px;font-size:calc(11px * var(--font-scale));line-height:1.5}


/* ============================================================
   极简皮肤专属处理（第二版皮肤系统）
   ------------------------------------------------------------
   ★ 极简不只是黑白 —— 还要「方角 + 无投影 + 无渐变」。
     靠令牌只能改圆角与阴影，渐变/圆环这些结构性的东西得单独压。
   ============================================================ */
[data-skin="minimal"] .btn,
[data-skin="minimal"] .inp,
[data-skin="minimal"] .card,
[data-skin="minimal"] .base-card,
[data-skin="minimal"] .iconbtn,
[data-skin="minimal"] .skbtn,
[data-skin="minimal"] .kpi,
[data-skin="minimal"] .base-tb th,
[data-skin="minimal"] .base-tb td,
[data-skin="minimal"] .dlg{
  box-shadow:none !important;
}
[data-skin="minimal"] .mark,
[data-skin="minimal"] .topbar .logo{
  background:var(--ink) !important;
  border-radius:var(--radius-sm) !important;
}
[data-skin="minimal"] .kpi::before{background:var(--ink) !important;opacity:.12}
[data-skin="minimal"] .btn.primary{background:var(--ink);color:var(--surface);border-color:var(--ink)}
[data-skin="minimal"] .btn.primary:hover{background:#000;color:#fff}
[data-skin="minimal"] .base-badge,
[data-skin="minimal"] .tag,
[data-skin="minimal"] .ptag{border-radius:var(--radius-sm) !important}
[data-skin="minimal"] .rail .brand .mark{border-radius:var(--radius-sm) !important}

/* ============================================================
   报告登记 · V01 整页复刻（用户 2026-10-30 第 6 项）
   ------------------------------------------------------------
   形态照 V01 截图：页签 → 统计卡 → 左（按送检日期分组）/ 右（登记面板）
   ============================================================ */
.rr-tabs{display:flex;gap:6px;margin:0 0 12px;flex-wrap:wrap;align-items:center}
.rr-tabs .btn{font-size:calc(12.5px * var(--font-scale))}
/* ----------------------------------------------------------------------------
   页签行里的搜索框（2026-11-04 用户第 1 条）
   ----------------------------------------------------------------------------
   ★ 上一版这个框的形状全写在 docs.js 的内联样式里：7px 圆角 + 近白描边 + 白底，
     30px 高的框压在浅色网格上就成了「胶囊/椭圆」；更要命的是它绕开了外观设置 ——
     换皮肤、调圆角，全站只有它不跟着变。
   ★ 现在宽度、圆角、描边、底色全部走令牌（--radius-sm / --line / --surface），
     与全站输入框同一套；外观设置改圆角它会跟着改。
   ★ 放大镜放进框内左侧（绝对定位），输入框用 padding-left 让位 ——
     把图标放框外时，框与图标各占一块，看起来像两个控件。
   ---------------------------------------------------------------------------- */
.rr-q{position:relative;display:inline-flex;align-items:center;margin-left:10px}
.rr-qico{position:absolute;left:9px;top:50%;transform:translateY(-50%);
  color:var(--ink3);font-size:calc(12.5px * var(--font-scale));pointer-events:none;line-height:1}
.rr-q .rr-qi{width:300px;height:30px;padding:0 10px 0 26px;
  border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--surface);
  color:var(--ink);font:inherit;font-size:calc(12.5px * var(--font-scale));
  transition:border-color .15s,box-shadow .15s}
.rr-q .rr-qi:hover{border-color:var(--border-strong)}
.rr-q .rr-qi:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-soft)}
.rr-q .rr-qi::placeholder{color:var(--ink3)}
.rr-qclr{padding:0 7px;height:26px;margin-left:6px}
@media (max-width:1180px){.rr-q .rr-qi{width:220px}}
.rr-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;margin-bottom:14px}
.rr-stat{background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:10px 13px}
.rr-stat .v{font-family:var(--mono);font-size:calc(22px * var(--font-scale));font-weight:700;color:var(--text-1);line-height:1.15}
.rr-stat .t{font-size:calc(11.5px * var(--font-scale));color:var(--text-3);margin-top:1px}
/* ★ 第 46 轮返工（用户）：「右栏居中跟随」第一版用 scrollIntoView，沿祖先链
   把整页 canvas 也滚了 —— 右栏表格短、新行靠页面顶部，整页被拽回顶，
   左栏的滚动位置跟着报废。现在两栏各自 sticky + 内部滚动，页面几乎不滚：
   - 左栏卡片限高视口，清单在 .rr-list 里滚；
   - 右栏卡片也 sticky，登记表在 .base-tbwrap 里滚（max-height 见下）。
   跟随时只滚 .base-tbwrap 自己，页面纹丝不动。 */
.rr-grid{display:grid;grid-template-columns:minmax(0,0.68fr) minmax(0,1.32fr);gap:14px;align-items:start}
.rr-left{position:sticky;top:8px;display:flex;flex-direction:column;max-height:calc(100vh - 16px)}
.rr-list{flex:1;min-height:0;overflow:auto}
.rr-right{position:sticky;top:8px}
.rr-right .base-tbwrap{max-height:48vh;overflow:auto}
.rr-grp{display:flex;align-items:center;gap:8px;padding:7px 12px;
  background:var(--surface-2);border-bottom:1px solid var(--border-soft);
  font-size:calc(11.5px * var(--font-scale));color:var(--text-3);position:sticky;top:0;z-index:2}
.rr-grp .d{font-weight:700;color:var(--text-1);font-size:calc(12px * var(--font-scale))}
.rr-grp .n{margin-right:auto}
.rr-grp input{width:13px;height:13px;margin:0;accent-color:var(--brand)}
.rr-it{display:flex;align-items:center;gap:9px;padding:7px 12px;
  border-bottom:1px solid var(--border-soft);cursor:pointer}
.rr-it:hover{background:var(--surface-2)}
.rr-it.on{background:var(--brand-soft)}
.rr-it input{width:14px;height:14px;margin:0;flex:none;accent-color:var(--brand)}
.rr-it .tx{flex:1;min-width:0}
.rr-it .t1{font-size:calc(12.5px * var(--font-scale));font-weight:600;color:var(--text-1);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rr-it .t2{font-size:calc(11px * var(--font-scale));color:var(--text-3);margin-top:1px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rr-dbar{display:flex;align-items:center;gap:9px;padding:9px 12px 11px;
  border-bottom:1px solid var(--border-soft);margin-bottom:8px}
.rr-dbar .lb{font-size:calc(12px * var(--font-scale));color:var(--text-2);font-weight:600}
.rr-foot{display:flex;align-items:center;gap:9px;padding-top:12px;margin-top:10px;
  border-top:1px solid var(--border-soft)}
.rr-foot .n{font-size:calc(12px * var(--font-scale));color:var(--text-2)}
.rr-foot .sp{flex:1}
@media (max-width:1180px){
  .rr-grid{grid-template-columns:1fr}
  .rr-left{position:static}
  .rr-right{position:static}
  .rr-right .base-tbwrap{max-height:44vh}
  .rr-list{max-height:44vh}
}

/* ============================================================
   监理见证记录 · V01 三栏（用户 2026-10-30 第 5 项）
   ------------------------------------------------------------
   照 V01 wz3 规格：左目录 172px / 中列表 1fr / 右详情 318px
   ============================================================ */
.wz-grid{display:grid;grid-template-columns:172px minmax(0,1fr) 318px;gap:14px;align-items:start;margin-top:12px}
.wz-dir{padding:8px;display:flex;flex-direction:column;gap:3px}
.wz-dir .base-chd{padding:6px 8px 3px;border:0}
.wz-dir .base-chd .n{font-size:calc(11px * var(--font-scale));font-weight:600;letter-spacing:.5px;color:var(--text-3)}
.wz-ni{display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:7px 9px;border-radius:8px;font-size:calc(12.5px * var(--font-scale));color:var(--text-2);
  cursor:pointer;border:none;background:none;text-align:left;width:100%}
.wz-ni:hover{background:var(--surface-2);color:var(--text-1)}
.wz-ni.on{background:var(--brand-soft);color:var(--brand-ink);font-weight:600}
.wz-ni .c{font-size:calc(11px * var(--font-scale));color:var(--text-3);font-weight:500}
.wz-ni.on .c{color:var(--brand-ink)}
.wz-list{padding:0;overflow:hidden;min-width:0}
.wz-tbar,.wz-row{display:grid;grid-template-columns:30px 116px minmax(0,1fr) 104px 62px 14px;
  gap:10px;padding:7px 12px;align-items:center}
.wz-tbar{background:var(--surface-2);font-size:calc(10.5px * var(--font-scale));color:var(--text-3);font-weight:600;
  border-bottom:1px solid var(--border-soft)}
.wz-row{border-top:1px solid var(--border-soft);cursor:pointer;min-height:52px}
.wz-row:hover{background:var(--surface-2)}
.wz-row.on{background:var(--brand-soft);box-shadow:inset 2px 0 0 var(--brand)}
.wz-row .no{font-family:var(--mono);font-size:calc(11.5px * var(--font-scale));font-weight:600;color:var(--text-1);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wz-row .nm{min-width:0}
.wz-row .nm b{display:block;font-size:calc(12.5px * var(--font-scale));color:var(--text-1);font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wz-row .nm small{display:block;font-size:calc(11px * var(--font-scale));color:var(--text-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wz-row .dt{font-size:calc(12px * var(--font-scale));color:var(--text-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wz-row .dt small{display:block;font-size:calc(10.5px * var(--font-scale));color:var(--text-3)}
.wz-row .st{justify-self:start}
.wz-row .arr{color:var(--text-3)}
.wz-detail{padding:14px;position:sticky;top:8px}
.wz-detail .base-chd{padding:0 0 8px;border-bottom:1px solid var(--border-soft)}
.wz-detail .base-chd h3{font-family:var(--mono);font-size:calc(14px * var(--font-scale));letter-spacing:.2px}
.wz-kv{display:flex;gap:10px;padding:6px 0;border-bottom:1px dashed var(--border-soft);font-size:calc(12.5px * var(--font-scale))}
.wz-kv span{flex:0 0 76px;color:var(--text-3)}
.wz-kv b{flex:1;min-width:0;color:var(--text-1);font-weight:500;word-break:break-all}
.wz-steps{display:flex;align-items:center;gap:6px;margin:13px 0 4px;flex-wrap:wrap}
.wz-stp{display:flex;align-items:center;gap:5px;font-size:calc(11.5px * var(--font-scale));color:var(--text-3)}
.wz-stp i{width:20px;height:20px;border-radius:99px;border:1px solid var(--border-strong);
  display:inline-flex;align-items:center;justify-content:center;font-style:normal;font-size:calc(10.5px * var(--font-scale));flex:none}
.wz-stp.d i{background:var(--ok-soft);border-color:transparent;color:var(--ok-ink);font-weight:700}
.wz-stp.d{color:var(--text-2)}
.wz-stp.c i{background:var(--brand);border-color:transparent;color:var(--surface);font-weight:700}
.wz-stp.c{color:var(--text-1);font-weight:600}
.wz-sep{flex:0 0 14px;height:1px;background:var(--border-strong)}
.wz-acts{display:flex;gap:8px;flex-wrap:wrap;margin-top:11px}
.wz-note{font-size:calc(11px * var(--font-scale));color:var(--text-3);margin-top:10px;line-height:1.7}
.wz-empty{border:1px dashed var(--border-strong);border-radius:10px;padding:30px 12px;
  display:flex;flex-direction:column;align-items:center;gap:9px;color:var(--text-3);
  text-align:center;line-height:1.8}
.base-badge.ok{background:var(--ok-soft);color:var(--ok-ink)}
.base-badge.mix{background:var(--warn-soft);color:var(--warn-ink)}
@media (max-width:1180px){
  .wz-grid{grid-template-columns:156px minmax(0,1fr)}
  .wz-detail{grid-column:1 / -1;position:static}
}
@media (max-width:760px){
  .wz-grid{grid-template-columns:minmax(0,1fr)}
  .wz-dir{flex-direction:row;flex-wrap:wrap}
  .wz-tbar{display:none}
}

/* ============================================================
   取样记录 · 1:1 复刻 V01 v520 版式（用户 2026-10-30 第 9 轮第 3 项）
   页头 → KPI 四卡 → 状态/类别/搜索筛选条 → 左表 + 右详情
   ------------------------------------------------------------ */
.sp-hd{display:flex;align-items:flex-start;gap:12px;margin-bottom:12px}
.sp-hd h2{margin:0;font-size:var(--fs-2xl)}
.sp-hd .sub{margin-top:4px}
.sp-hd-r{margin-left:auto;display:flex;gap:8px;flex:none}
.sp-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;margin-bottom:14px}
.sp-kpi{background:var(--surface);border:1px solid var(--line);border-radius:10px;padding:10px 14px}
.sp-kpi .l{font-size:calc(11.5px * var(--font-scale));color:var(--ink3)}
.sp-kpi .v{font-size:calc(22px * var(--font-scale));font-weight:700;margin-top:2px;font-family:var(--mono)}
.sp-fbar{display:flex;align-items:center;gap:12px;margin-bottom:12px;flex-wrap:wrap}
.sp-seg{display:flex;gap:4px;border:1px solid var(--line);border-radius:var(--radius-md);padding:3px;background:var(--panel-2)}
.sp-segb{border:none;background:transparent;color:var(--ink2);font:inherit;font-size:var(--fs-sm);
  padding:4px 10px;border-radius:var(--radius-sm);cursor:pointer;white-space:nowrap}
.sp-segb.on{background:var(--brand);color:var(--surface);font-weight:600}
/* ★ 第 10 轮（用户第 4 项：「右侧栏，减掉一半的宽度」）：
   原来是 1.75fr : 1fr（右栏 ≈ 36%，1680 下实测 505px），详情栏比左边清单还抢眼。
   现在右栏按 clamp(240px, 19%, 300px) 收：1680 下 505 → 275（减 46%），
   1280 下 367 → 240。宽度不再用 fr 是刻意的 —— fr 会让右栏跟着窗口一起长，
   窗口越大详情栏越宽（这正是"减不动"的原因）。
   左栏补 overflow-x —— 取样明细表 min-content 有一千多像素，
   不给它自己的滚动条，它就会横穿到右栏下面（1280 下实测右边界 1291 > 画布 1258）。 */
/* ── 未取样批次：按批次分组（V01 v105 形态 · 用户第 18 轮第 1 项）──
   组头一行放「整批勾选框 + 展开箭头 + 批次名 + 日期 + 已选 n/N + N 行·合计 N 组」，
   组内是可单独勾选的明细行。收起态的组没有 DOM（只渲染组头），
   所以「展开全部」靠 openSet 数据驱动重绘，不扫 DOM。 */
.sp-bgrp{border:1px solid var(--line);border-radius:var(--radius-md);overflow:hidden;background:var(--surface)}
.sp-bhd{display:flex;align-items:center;gap:8px;padding:7px 10px;background:var(--panel-2);
  border-top:1px solid var(--line);cursor:pointer;font-size:var(--fs-sm);user-select:none}
.sp-bgrp .sp-bhd:first-child{border-top:none}
.sp-bhd:hover{background:var(--line-2)}
.sp-bhd input[type=checkbox]{margin:0;flex:none}
.sp-arr{width:12px;flex:none;color:var(--ink3);font-size:calc(11px * var(--font-scale))}
.sp-gnm{font-weight:600;color:var(--ink);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sp-gdt{color:var(--ink3);font-size:calc(11.5px * var(--font-scale))}
.sp-gsel{color:var(--brand);font-size:calc(11.5px * var(--font-scale));font-weight:600}
.sp-gsum{margin-left:auto;color:var(--ink3);font-size:calc(11.5px * var(--font-scale));white-space:nowrap}
.sp-gtb{width:100%}
.sp-gtb th,.sp-gtb td{padding:5px 9px;white-space:nowrap}
.sp-gtb th{font-size:calc(11px * var(--font-scale));background:transparent;border-bottom:1px solid var(--line-2)}
.sp-gtb tbody tr{cursor:pointer}
.sp-gtb tbody tr:hover{background:var(--panel-2)}

/* ★ 2026-11-04 用户更正：「类别·规格」收成 Φ16-Φ28 省下的列宽是给**右栏**的。
   原来 clamp(240px,19%,300px) 在大屏上被 300px 顶死 —— 右栏里「供货厂家 / 取样人」
   这类四字标签 + 长值常常换行。现在下限抬到 300、上限放到 400，占比 26%：
   1680 视口下右栏 ~380px（+80px，正好是规格列收窄的量），左栏仍有余量。 */
.sp-main{display:grid;grid-template-columns:minmax(0,1fr) clamp(300px,26%,400px);gap:14px;align-items:start}
@media (max-width:1180px){.sp-main{grid-template-columns:minmax(0,1fr) clamp(280px,30%,340px)}}
@media (max-width:1024px){.sp-main{grid-template-columns:1fr}}
.sp-lhd,.sp-rhd{display:flex;align-items:center;gap:10px;padding:10px 14px;border-bottom:1px solid var(--line)}
.sp-lhd h3{margin:0;font-size:var(--fs-md)}
.sp-lhd .r,.sp-rhd .t{margin-left:auto;font-size:calc(11.5px * var(--font-scale));color:var(--ink3)}
.sp-rhd{flex-direction:column;align-items:flex-start;gap:2px}
.sp-rhd .t{margin-left:0}
.sp-rhd h3{margin:0;font-size:var(--fs-lg);font-family:var(--mono)}
.sp-lw,.sp-rw{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden}
/* 左栏自己滚：表格 min-content 超宽时只在这里横滚，不横穿到右栏下面 */
.sp-lw{min-width:0;overflow-x:auto}
.sp-rw{display:flex;flex-direction:column;min-width:0}
.sp-sec{padding:12px 14px;border-bottom:1px solid var(--line-2)}
.sp-sec:last-child{border-bottom:none}
.sp-sec .sh{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.sp-sec .sh b{font-size:var(--fs-base)}
.sp-sec .sh .r{margin-left:auto;font-size:calc(11.5px * var(--font-scale));color:var(--ink3)}
.sp-kv{display:grid;grid-template-columns:auto 1fr;gap:5px 12px;font-size:var(--fs-base);line-height:1.6}
.sp-kv .k{color:var(--ink3);font-size:calc(11.5px * var(--font-scale));padding-top:1px;white-space:nowrap}
/* 取样详情抽屉的「取样依据」盒（第 17 轮）：与纸质取样单底部同款 */
.sp-basis{margin-top:10px;border:1px solid var(--line);border-radius:var(--radius-md);
  background:var(--surface-2);padding:10px 12px;display:grid;gap:6px}
.sp-basis-row{display:flex;gap:10px;font-size:var(--fs-base);line-height:1.55}
.sp-basis-row .k{flex:0 0 64px;color:var(--ink3);font-size:calc(11.5px * var(--font-scale));padding-top:1px;white-space:nowrap}
.sp-basis-row .v{min-width:0;overflow-wrap:anywhere}
/* ★ 第 10 轮：右栏收窄到 240~300 后，长炉批号/部位名必须能断行，否则又会把栏顶宽 */
.sp-kv .v{overflow-wrap:anywhere;min-width:0}
/* ★ table-layout:fixed 在这里是**错的**：三列均分后「工程部位」只剩 80px，
   一句话折成五行（实测 1280 下就是这样）。改回 auto，
   让部位自己占需要的宽度，规格/组数按内容收窄。 */
.sp-mtb{width:100%;border-collapse:collapse;font-size:var(--fs-sm)}
.sp-mtb th,.sp-mtb td{overflow-wrap:anywhere;padding:6px 7px}
.sp-mtb th{background:var(--panel-2);text-align:left;padding:6px 9px;color:var(--ink3);font-weight:600;font-size:calc(11.5px * var(--font-scale))}
.sp-mtb td{padding:6px 9px;border-top:1px solid var(--line-2)}
/* 规格串「25-25 · 22-22」在窄栏里会被从连字符处拆成「25-2 / 5」——
   keep-all 只允许在空格/顿点处换行，号码本身不被切断 */
.sp-mtb td{word-break:keep-all;overflow-wrap:normal}
.sp-mtb .num{text-align:right;font-family:var(--mono)}
.sp-flow{display:flex;flex-direction:column;gap:2px}
.sp-fstep{display:flex;align-items:flex-start;gap:9px;padding:6px 0}
.sp-fstep .ic{width:20px;height:20px;border-radius:var(--radius-full);background:var(--panel-2);
  color:var(--ink3);display:grid;place-items:center;font-size:calc(11px * var(--font-scale));font-weight:700;flex:none;margin-top:1px}
.sp-fstep.done .ic{background:var(--ok-soft,var(--brand-soft));color:var(--brand)}
.sp-fstep .tx{display:flex;flex-direction:column}
.sp-fstep .tx b{font-size:var(--fs-sm)}
.sp-fstep .tx small{color:var(--ink3);font-size:calc(11.5px * var(--font-scale))}
.sp-rft{margin-top:auto;display:flex;gap:8px;padding:12px 14px;border-top:1px solid var(--line-2)}
/* ★ 2026-11-04（用户第 8 项：「数据多了，每次都要滚动到底部去找按键」）：
   右栏变成"钉住的详情栏 + 栏内滚动 + 底栏贴栏底"：
     · .sp-rw   position:sticky;top:0 —— 页面往下滚时栏钉在画布顶，不跟着走
     · 高度     fitRail() 按画布可视高度写死（CSS 这行只是 JS 没跑时的兜底）
     · .sp-rbody 中间那段自己滚，明细再多也只滚这里
     · .sp-rft  普通 flex 尾项，永远在栏底 —— 不用滚到底找按钮
   为什么不用 position:sticky;bottom:0 钉底栏：本页滚动容器是 .canvas，
   它的 padding-bottom 会让"底"比画布底高 40px，钉住的底栏下面会露出内容。 */
.sp-rw{position:sticky;top:0;max-height:calc(100vh - 360px)}
.sp-rbody{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;
  overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--line) transparent}
/* 底栏里的那句「两组按钮有什么区别？」—— 默认收起一行，点开才铺全文 */
.sp-why{flex:1 1 100%;margin-top:2px}
.sp-whyb{border:none;background:transparent;color:var(--ink3);font:inherit;
  font-size:calc(11px * var(--font-scale));line-height:1.6;padding:2px 0;cursor:pointer;text-align:left}
.sp-whyb::after{content:" ▾";color:var(--ink4)}
.sp-whyb.on::after{content:" ▴"}
.sp-whyb:hover{color:var(--brand)}
.sp-whyt{font-size:calc(11px * var(--font-scale));line-height:1.6;color:var(--ink3);
  border-top:1px dashed var(--line);padding-top:6px;margin-top:2px}
/* ★ 第 11 轮第 6 项：底栏五个按钮，右栏只有 260 多宽 —— V01 三连单独占一行，
   状态推进/删除另起一行，避免按钮被挤成竖排（.sp-rft 已设 flex-wrap）。 */
.sp-rft-row{display:flex;gap:6px;width:100%}
.sp-rft-row .btn{flex:1;min-width:0;padding-left:6px;padding-right:6px;font-size:var(--fs-sm);white-space:nowrap}
.sp-rempty{padding:60px 20px;text-align:center;color:var(--ink3);font-size:var(--fs-base);white-space:pre-line}
.sp-tb tbody tr{cursor:pointer}
.sp-tb tbody tr:hover{background:var(--panel-2)}
.sp-tb tbody tr.on{background:var(--brand-soft)}
/* ★ 用户 2026-10-31 第 11 轮第 6 项：取样单「类别 · 规格」列按 V01 两行展示
   （上：类别徽标；下：规格串）。规格串比类别字号小一档、颜色淡一档，
   这样一眼能分出"这行是钢筋连接"和"它有哪些规格"。 */
.sp-tb td.sp-catcell{white-space:normal;line-height:1.45}
.sp-tb td.sp-catcell .base-badge{font-size:calc(11px * var(--font-scale))}
.sp-tb .sp-spec{font-size:calc(11.5px * var(--font-scale));color:var(--ink3);margin-top:2px;font-family:var(--mono)}
/* ★ 取样单列表的日期 / 炉批号不允许折行。
   1680 下 9 列挤在 780px 里，浏览器会把「2026-10-31」折成「2026-10- / 31」、
   把「+2」徽标甩到第二行 —— 数字断行比省略号更难读（会看成两个日期）。
   宁可整表横向滚动：列完整、字不断。 */
.sp-tb td:nth-child(3),.sp-tb td:nth-child(6),.sp-tb th:nth-child(3),.sp-tb th:nth-child(6){white-space:nowrap}
/* ★ 第 11 轮第 6 项：窄屏不再隐藏「类别·规格」「炉批号」——
   用户要求这两列照 V01 展示，隐藏了等于没做。改为卡片内横向滚动。 */
.sp-lw .tbl-wrap{overflow-x:auto}
@media (max-width:1440px){
  .sp-tb th:nth-child(2),.sp-tb td:nth-child(2){white-space:nowrap}
}

/* ============================================================
   皮肤选择器网格（2026-10-31 第 20 轮，8 款）
   ------------------------------------------------------------
   桌面固定四列 × 两行；窄屏退两列（四列在 380px 上每列只剩 77px，
   「宣纸墨印」四个字会被挤断）。grid 的列数由 core.js 内联给出，
   这里只处理窄屏这一档。
   ============================================================ */
@media (max-width:640px){
  .dlg .sk-grid{grid-template-columns:repeat(2,minmax(0,1fr)) !important}
}

/* ============================================================
   后台 IA 重排（第 41 轮 · 用户「后台管理，经过多次修改，已变得凌乱」）
   ------------------------------------------------------------
   三件事：
     ① 内容宽收口 —— ★ 第 42 轮改口：上一轮把**整个页面**封在 1120，
        用户 2026-11-02 截图问「只有一半左右，这是刻意设计吗」。
        实测他的屏幕 2040 CSS px（2550 物理 × 125% 缩放），画布内宽 1812，
        封顶 1120 ⇒ 右侧空 690px（38%）。是他的实话，也是我的错层：
        该封的是"一行太长会读不下去"的表单栅格与预览块，**不是台账表格** ——
        12 列的表格越宽越好用。所以现在：页面不封顶，块级各自封顶
        （.fldgrid 1180 / .skbox 1120 / .dlg3 1120）。
     ② 页内分段条 segbar —— 用段替代"可折叠卡"：每段有名字、能直达
        （#ui/foot）、高度一样省，且不会出现"折起来以后什么都看不到"。
     ③ 段内小标题 h3 拉到 16.5px —— 原来分段标题 12px、正文 13px，
        只差 1px，用户说的"要认真看标题才看得清"就是这 1px。
   ============================================================ */
#adminView{max-width:none}

/* 段条：一条细底线 + 选中项用品牌色加粗下划线，不用胶囊块
   （胶囊块在深色皮肤下容易和卡片糊成一片） */
.segbar{display:flex;gap:2px;border-bottom:1px solid var(--line);margin:0 0 16px;overflow-x:auto}
.segbar .seg{
  appearance:none;-webkit-appearance:none;border:0;background:none;cursor:pointer;
  font:inherit;font-size:var(--fs-base);color:var(--ink3);
  padding:8px 13px 10px;border-bottom:2px solid transparent;margin-bottom:-1px;
  display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
}
.segbar .seg:hover{color:var(--ink)}
.segbar .seg.on{color:var(--brand);font-weight:650;border-bottom-color:var(--brand)}
.segbar .seg .n{
  font-family:var(--mono);font-size:var(--fs-xs);line-height:1;
  background:var(--surface-3);color:var(--ink3);border-radius:var(--radius-sm);
  padding:2px 5px;min-width:18px;text-align:center;
}
.segbar .seg.on .n{background:var(--brand-soft);color:var(--brand)}
.segpane[hidden]{display:none}

/* 段内小标题：比正文大 3.5px、比屏标题小 5.5px —— 三档层级一眼分开 */
.ui-sec{
  font-size:calc(16.5px * var(--font-scale));font-weight:650;letter-spacing:-.2px;margin:0 0 3px;
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
}
.ui-sec2{font-size:calc(14px * var(--font-scale));font-weight:650;margin:18px 0 2px;padding-top:14px;
  border-top:1px dashed var(--line);display:flex;align-items:center;gap:8px}
.ui-sub{font-size:calc(12px * var(--font-scale));color:var(--ink3);line-height:1.65;margin-bottom:14px;max-width:74ch}

/* 作用域标签：同一段里两个东西影响面不同（全项目 / 仅本机）时必须标出来，
   否则「我改的是自己的」这种误解会变成"别人怎么也被改了"的投诉 */
.scope{
  font-size:var(--fs-xs);font-weight:600;line-height:1;padding:3px 6px;border-radius:var(--radius-sm);
  letter-spacing:.2px;
}
.scope.all{background:var(--brand-soft);color:var(--brand)}
.scope.local{background:var(--warn-soft);color:var(--warn)}

/* 未保存提示：只在有改动时出现，不占常驻空间 */
.ui-dirty{
  font-size:var(--fs-xs);color:var(--warn);background:var(--warn-soft);
  padding:3px 8px;border-radius:var(--radius-sm);font-weight:600;
}
.ui-dirty[hidden]{display:none}

/* 表单栅格：宽屏封 1180（4 列 × 285 —— 再多一列就会把"备案号"这种短值
   排到屏幕最右边，眼睛要横跨 1800px 才找得到第二个框） */
.fldgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px;max-width:1180px}
/* 单个输入框最宽 360。
   ★ 为什么需要这一条：auto-fit + 1fr 在只有两三个字段时会把它拉到 578 ——
     「站点标题」这种 4~8 字的值配一个 578px 的输入框，看着像没做完。
     360 是 30 个汉字的宽度，本项目没有哪个设置项超过这个长度。 */
.fldgrid > *{max-width:360px}

/* 配置卡：卡片自身跟内容一起收口。
   ★ 这是用户那句「只有一半左右」的另一半答案 —— 上一轮只把**栅格**封了 1180，
     卡片还是吃满 1786，于是屏上出现"白框 1786、框里内容 1180"的白洞，
     比整页留白更像出错。现在卡片也封 1180，卡边 = 内容边。
   ★ 用 :has 而不是给每个卡加类名：这类卡是 JS 现场拼的，
     加类名要改十几处调用点，且以后新加一块又会忘。 */
.card:has(.fldgrid),
.card:has(.skbox),
.card:has(.dlg3){max-width:1180px}

/* ---- 登录页样式：左 6 行横条 + 右 16:10 示意 ----
   封 1120：预览框是 16:10，跟着页面涨到 1800 宽会高 700，横条那列反而空一半 */
.skbox{display:grid;grid-template-columns:minmax(0,1fr) minmax(280px,380px);gap:16px;align-items:start;max-width:1180px}
@media (max-width:980px){.skbox{grid-template-columns:1fr}}
.sklist{display:flex;flex-direction:column;gap:4px}
.skrow{
  display:flex;align-items:center;gap:9px;padding:5px 9px;cursor:pointer;
  border:1px solid transparent;border-radius:var(--radius-sm);
}
.skrow:hover{background:var(--panel-2)}
.skrow.on{background:var(--brand-soft);border-color:var(--brand-soft)}
.skrow input[type="radio"]{margin:0;flex:0 0 auto}
.skdot{width:26px;height:16px;border-radius:4px;flex:0 0 26px;border:1px solid var(--line)}
.sknm{font-size:var(--fs-base);font-weight:600;white-space:nowrap}
.sksub{font-size:var(--fs-sm);color:var(--ink3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.skrow .btn{margin-left:auto;flex:0 0 auto}

/* 16:10 示意：左品牌栏 + 右表单，配色随选中的款换（--p-side/--p-ac/--p-bg） */
.skpv{
  /* 三个私有变量先在这里定义（值 = 云白分栏），JS 再按选中的款往元素上覆盖。
     ★ 不写 var(--x, 兜底) 而是先定义：闸门 R8 会扫"引用了但没定义"的变量，
       兜底写法能跑，但下次别人改兜底值时找不到真源。 */
  --p-side:#0d3d31; --p-ac:#135f4d; --p-bg:#f3f5f6;
  aspect-ratio:16/10;display:flex;border-radius:8px;overflow:hidden;
  border:1px solid var(--line);background:var(--p-bg);position:relative;
}
.skpv .sl{
  width:42%;background:var(--p-side);color:#fff;padding:12px;
  display:flex;flex-direction:column;justify-content:center;gap:5px;
}
.skpv .sl .mk{
  width:17px;height:17px;border-radius:5px;background:rgba(255,255,255,.16);
  border:1px solid rgba(255,255,255,.22);display:grid;place-items:center;
  font-size:calc(9px * var(--font-scale));font-style:normal;
}
.skpv .sl b{font-size:calc(11px * var(--font-scale));font-weight:600;letter-spacing:.2px}
.skpv .sl em{font-style:normal;font-size:calc(8px * var(--font-scale));opacity:.6}
.skpv .sr{flex:1;display:grid;place-items:center;padding:10px}
.skpv .sfm{width:88%;display:flex;flex-direction:column;gap:5px}
.skpv .sfm i{
  height:15px;border-radius:4px;background:#fff;border:1px solid rgba(0,0,0,.09);
  font-style:normal;font-size:calc(7px * var(--font-scale));color:#98a3a0;display:flex;align-items:center;padding:0 5px;
}
.skpv .sfm button{
  height:16px;border:0;border-radius:4px;background:var(--p-ac);
  color:#fff;font-size:calc(7.5px * var(--font-scale));
}
.skcap{font-size:var(--fs-xs);color:var(--ink3);line-height:1.55;margin-top:6px}

/* ---- 弹窗三档：三张卡，卡内框图按真实比例画（封 1120：三卡各 360，再宽就成三张大海报） ---- */
.dlg3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;max-width:1180px}
@media (max-width:860px){.dlg3{grid-template-columns:1fr}}
.d3{
  border:1px solid var(--line);border-radius:var(--radius-md);padding:10px;
  cursor:pointer;background:var(--surface);display:block;
}
.d3:hover{background:var(--panel-2)}
.d3.on{border-color:var(--brand);box-shadow:0 0 0 2px var(--brand-soft)}
.dfr{
  aspect-ratio:16/10;border:1px solid var(--border-strong);border-radius:4px;
  background:var(--panel-2);display:flex;flex-direction:column;overflow:hidden;
}
.dfr i.a{height:20%;background:var(--surface-3);border-bottom:1px solid var(--line);display:block}
.dfr i.b{flex:1;display:block}
.dfr i.c{height:16%;background:var(--surface-3);border-top:1px solid var(--line);display:block}
.dnm{display:flex;align-items:baseline;gap:6px;margin-top:7px}
.dnm b{font-size:var(--fs-base);font-weight:650}
.dnm .sz{font-family:var(--mono);font-size:var(--fs-xs);color:var(--ink3)}
.d3 .ds{font-size:var(--fs-xs);color:var(--ink3);line-height:1.55;margin-top:2px}
.dlgbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:12px}
.dlgbar .hint{font-size:var(--fs-xs);color:var(--ink3)}

/* 只读参考条（权限矩阵那段）：用中性色，不用警示红 —— 它不是错误 */
.note-ro{background:var(--info-soft);border-color:var(--info-soft);color:var(--info-ink,var(--ink2))}

/* 后台表格：时间列不折行（第 41 轮）。
   折成「11-01」/「21:19」两行时，10 行的登录记录会多撑 200px，
   把整段顶出首屏 —— 明明一行放得下。 */
.tbl td.nowrap{white-space:nowrap}
/* 弹窗三档的比例框图居中，不贴左边（贴左会看成"框没画满"） */
.dfr{margin:0 auto}

/* ============================================================
   权限矩阵（第 42 轮 P0）：表头带人数、行按能力分组、能力键用等宽小字
   ------------------------------------------------------------
   ★ 表头第二行必须有人数：改这一列会影响谁，就是这个数字。
     以前矩阵上没有它，用户只知道"成员能做什么"，不知道"有几个成员"。
   ★ 分组行用 --surface-3 而不是粗体加空行：8 行里插两条空行会把表格
     切得像两张表，用一条浅色标题行才看得出"这是同一张表的两段"。
   ============================================================ */
.pmx th{padding-top:9px;padding-bottom:9px;vertical-align:top}
/* 首列（能力名）占 30%，剩下四列角色均分 —— 不设的话能力名那列会吃掉一半宽度，
   标签全挤到右边，一眼看过去像"两列空着" */
.pmx th:first-child,.pmx td:first-child{width:30%}
.pmx .pmx-nm{font-size:calc(13px * var(--font-scale));font-weight:650;color:var(--ink)}
.pmx .pmx-meta{
  font-family:var(--mono);font-size:calc(11px * var(--font-scale));font-weight:400;color:var(--ink3);
  margin-top:2px;white-space:nowrap;
}
.pmx .pmx-grp td{
  background:var(--surface-3);color:var(--ink2);
  font-size:calc(11.5px * var(--font-scale));font-weight:650;letter-spacing:.3px;
  padding:6px 10px;
}
/* 第 57 轮 P2：表头右上角的「设置」—— 改名 / 停用 / 删除。
   做成文字按钮而不是图标：这个动作不常用，图标反而要猜（且后台已有 13 个图标要认）。 */
.pmx .pmx-set{
  margin-top:3px;padding:1px 6px;border:1px solid var(--line);border-radius:var(--radius-sm);
  background:var(--card);color:var(--ink3);cursor:pointer;
  font-size:calc(11px * var(--font-scale));line-height:1.6;
}
.pmx .pmx-set:hover{color:var(--ink);border-color:var(--border-strong);background:var(--panel-2)}
.pmx .pmx-cap{font-size:calc(13px * var(--font-scale));color:var(--ink)}
.pmx .pmx-key{
  font-family:var(--mono);font-size:calc(11px * var(--font-scale));color:var(--ink3);
  margin-left:8px;background:var(--surface-3);
  border-radius:var(--radius-sm);padding:1px 5px;
}

/* ============================================================
   权限矩阵 · 三态可编辑（第 43 轮 P1）
   ------------------------------------------------------------
   ★ 为什么格子做成"整格可点"而不是"格子里放一个下拉"：
     32 格 × 下拉 = 32 个控件、32 次三击；而这里的操作是"翻一翻"，
     点一下就换一态最快。三态的顺序固定（继承→允许→禁止），
     点错了再点两下就回来。
   ★ 改动过的格必须一眼看出来：加一条左侧色条 + 淡黄底。
     没有这个标记，用户点了几格以后完全分不清"哪些还没保存"。
   ★ 恒允许那格（负责人 × 管成员）用虚线边框 + 不可点光标，
     让它看着就像"焊死的"，而不是"灰掉的按钮"（后者暗示还能恢复）。
   ============================================================ */
.pmx-edit td{height:36px}
.pmx-click{cursor:pointer;user-select:none;transition:background .12s}
.pmx-click:hover{background:var(--surface-3)}
.pmx-chg{box-shadow:inset 3px 0 0 var(--warn);background:var(--warn-soft)}
.pmx-lock{cursor:not-allowed;opacity:.85}
.pmx-lock .tag{border:1px dashed currentColor;background:transparent}

/* 保存条：只在有改动时出现，贴在矩阵下面 */
.pmx-bar{
  margin-top:12px;padding:10px 12px;border-radius:var(--radius-md);
  background:var(--surface-2);border:1px solid var(--line);
}
.pmx-bar-t{font-size:calc(13px * var(--font-scale));font-weight:600;color:var(--ink)}
.pmx-bar-b{display:flex;gap:12px;align-items:flex-start;justify-content:space-between;margin-top:6px}
.pmx-impact{font-size:calc(12.5px * var(--font-scale));color:var(--ink2);line-height:1.55;flex:1 1 auto;min-width:0}
.pmx-bar-a{display:flex;gap:8px;flex:0 0 auto}

/* 提示条 · 警示态（第 43 轮）：用于"改了也不会生效"这类必须先说的话 */
.note-warn{background:var(--warn-soft);border-color:var(--warn-soft);color:var(--warn-ink)}
.pmx-ov{margin-top:10px}

/* 继承态：虚线框 + 透明底，与"本项目明确规定"的实心标签分开。
   ★ 只靠文字"继承"会让整张表 32 格全长一个样；只靠颜色又分不出
     "规定过"和"没规定过"。虚线是唯一一个既不占地又能一眼看见的区分。 */
.pmx-inh .tag{background:transparent;border:1px dashed currentColor;opacity:.9}
.pmx-lg{font-size:calc(12px * var(--font-scale));color:var(--ink3)}

/* ============================================================
   报告登记 · 左栏列化（第 44 轮，参照 V01）
   ------------------------------------------------------------
   ★ 用户口径：「只增加列『批次内容』，要有这种小批次的勾选功能」。
     所以列是 勾选 / 工程部位 / 批次内容 / 报告编号 / 报告日期，五列，
     与 V01 那张图一致 —— 没有再加别的列（加列会把左栏挤窄，
     而这屏左栏只有约 0.68fr）。
   ★ .rr-it 从 flex 改成 grid：原来的 flex 里「部位两行 + 批次号」是自适应的，
     一旦要按列对齐（批次内容那一列要竖着对得齐）就必须有固定列宽。
   ★ 表头 sticky：左栏内部滚动（.rr-list 是 overflow:auto），
     滚到第 30 条时列名还在 —— 否则用户会忘了第三列是什么。
   ============================================================ */
.rr-th{
  display:grid;gap:8px;align-items:center;padding:6px 12px;
  background:var(--surface-2);border-bottom:1px solid var(--border);
  font-size:calc(11px * var(--font-scale));color:var(--text-3);position:sticky;top:0;z-index:2;
}
.rr-day{
  display:flex;align-items:center;gap:8px;padding:8px 12px;
  background:var(--surface-3);border-top:1px solid var(--border);
}
.rr-day .d{font-weight:700;font-size:calc(12.5px * var(--font-scale));color:var(--text-1);letter-spacing:.2px}
.rr-day .n{font-size:calc(11px * var(--font-scale));color:var(--text-3);margin-right:auto}
.rr-day input{width:14px;height:14px;margin:0;accent-color:var(--brand);flex:none}
.rr-grp .g{font-weight:650;font-size:calc(12px * var(--font-scale));color:var(--text-1)}
.rr-grp .cnt{font-size:calc(11px * var(--font-scale));color:var(--text-3)}
.rr-it{
  display:grid;align-items:center;gap:8px;
  padding:6px 12px;border-top:1px solid var(--border);
}
.rr-it .rr-cure{font-size:calc(11.5px * var(--font-scale));color:var(--text-2)}
.rr-it .rr-no,
.rr-it .rr-dt{
  font-size:calc(11.5px * var(--font-scale));color:var(--text-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  /* 第 56 轮：不再钉死等宽字体（字体族要跟后台），但数字仍按等宽位对齐 */
  font-variant-numeric:tabular-nums;
}

/* ---- 第 44 轮：台账「待取样 / 待安排」可点，跳回取样单 ---- */
.base-tb td.rnocell .rno-jump{
  cursor:pointer;border-bottom:1px dashed currentColor;
  padding-bottom:1px;
}
.base-tb td.rnocell .rno-jump:hover{filter:brightness(1.15)}
/* 取样单右栏「取样明细」：每行的送检状态 tag（挂在部位下方，不占列宽） */
.sp-mtb .sp-itag{margin-top:3px;display:flex}
.sp-mtb .sp-itag .tag{font-size:calc(10px * var(--font-scale));padding:0 5px;line-height:1.5}

/* ---- 第 45 轮：弹窗四档分开设置（后台「交互与弹窗」）---- */
.dlg4{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px;margin:8px 0 4px}
.dlg4 .d4{border:1px solid var(--line);border-radius:10px;padding:9px 11px;display:flex;flex-direction:column;gap:7px}
.dlg4 .d4>b{font-size:calc(12.5px * var(--font-scale))}
.dlg4 .d4r{display:flex;align-items:center;gap:6px}
.dlg4 .d4r .inp{padding:5px 8px;font-size:calc(12.5px * var(--font-scale))}
.dlg4 .d4x{color:var(--ink3);font-size:calc(11.5px * var(--font-scale));white-space:nowrap}

/* ============================================================
   第 50 轮（用户）：报告登记右栏登记表（.rr-reg）
   ① 表头与数据全部居中（水平 + 垂直）—— 部位/编号这些长文本列也居中；
   ② 说明文字的左缩进写在前端（docs.js desc.style），不在这里。
   ============================================================ */
.rr-reg th,.rr-reg td{text-align:center;vertical-align:middle}
.rr-reg td.partcell{text-align:center}
.rr-reg td .inp{margin:0 auto}

/* ============================================================
   ★★ 2026-11-06（用户第 102 轮）：报告三对（设计稿③ · 57 号令第二十一条）
   ------------------------------------------------------------
   三行「框 + 标题 + 一句我方口径 + 右侧值徽标」，勾上变主色。
   方框用 CSS 画（::after 的 ✓），不引 SVG —— 这一屏在首屏关键路径上。
   ★ 空间：右栏本来就挤（说明 + 统一日期 + 登记表 + 底部按钮），三行
     必须压扁：行距 6px、提示文字 11px 单行截断（全句靠 title 悬停看）。
     否则「批量登记」按钮会被挤出视口，用户以为按钮没了。
   ============================================================ */
.rr-three{padding:8px 12px 0;margin-top:8px;border-top:1px dashed var(--border)}
.rr-three-hd{
  font-size:calc(11px * var(--font-scale));color:var(--text-3);
  letter-spacing:.03em;margin-bottom:6px;
}
.rr-chk{
  display:flex;align-items:flex-start;gap:8px;padding:7px 9px;margin-bottom:6px;
  border:1px solid var(--border);border-radius:var(--radius-sm);cursor:pointer;
  background:var(--surface);transition:border-color .14s,background .14s;
}
.rr-chk:hover{border-color:var(--border-strong);background:var(--surface-2)}
.rr-chk .bx{
  flex:0 0 15px;width:15px;height:15px;margin-top:1px;border-radius:3px;
  border:1.5px solid var(--border-strong);background:var(--surface);
  display:flex;align-items:center;justify-content:center;transition:background .14s,border-color .14s;
}
.rr-chk .bx::after{
  content:"✓";font-size:10px;line-height:1;font-weight:700;color:var(--text-inv);
  opacity:0;transition:opacity .12s;
}
.rr-chk .tx{flex:1;min-width:0}
.rr-chk .tx .l1{font-size:calc(12px * var(--font-scale));color:var(--text-1);line-height:1.4}
.rr-chk .tx .l1 b{font-weight:650}
.rr-chk .tx .hint{
  font-size:calc(11px * var(--font-scale));color:var(--text-3);margin-top:1px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.rr-chk .val{
  flex:0 0 auto;max-width:46%;
  font-family:var(--raw-font-mono);font-size:calc(11px * var(--font-scale));
  padding:1px 7px;border-radius:var(--radius-full);
  background:var(--surface-3);color:var(--text-2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.rr-chk.on{border-color:var(--brand);background:var(--brand-soft)}
.rr-chk.on .bx{background:var(--brand);border-color:var(--brand)}
.rr-chk.on .bx::after{opacity:1}
.rr-chk.on .val{background:var(--surface);color:var(--brand-ink)}
.rr-three-why{font-size:calc(11.5px * var(--font-scale));color:var(--warn-ink);white-space:nowrap}
/* 紧跟三对之后的底栏：.rr-foot 本来自己带一条上边框，
   这里再画一条就成双线了 —— 三对的上边框已经把它和登记表分开。 */
.rr-three + .rr-foot{border-top:0;padding-top:8px;margin-top:6px}

/* ============================================================
   第 54 轮（设计稿 design-r53.html 第 1 节）：待办清单批量安排
   ------------------------------------------------------------
   表格最前面插了「勾选」「序号」两列，这会顶掉原来
   `.wb-tbl th:first-child`（部位列 16em / 可折行）的命中对象 ——
   那个选择器命中的将是勾选框，部位列会被挤成一列窄条。
   这里按 .wb-tbl-pick 重新指明 ① 勾选 ② 序号 ③ 部位。
   特异性与 `.wb-tbl td:first-child` 相同，靠「后写优先」生效，
   并且顺带把 1005 行左右的同类规则一并覆盖，不需要 !important。
   ============================================================ */
.wb-tbl-pick th:first-child,.wb-tbl-pick td:first-child{
  width:26px;min-width:26px;max-width:26px;
  padding:8px 0 8px 2px;text-align:left;white-space:nowrap;
  vertical-align:top;
}
.wb-tbl-pick th:nth-child(2),.wb-tbl-pick td:nth-child(2){
  width:36px;min-width:36px;max-width:36px;
  padding:8px 4px;text-align:center;white-space:nowrap;vertical-align:top;
  font-family:var(--mono);font-size:var(--fs-sm);color:var(--ink3);
  font-variant-numeric:tabular-nums;
}
.wb-tbl-pick th:nth-child(3),.wb-tbl-pick td:nth-child(3){
  width:16em;min-width:9em;max-width:16em;
  white-space:normal;word-break:break-word;overflow-wrap:anywhere;
  text-align:left;line-height:1.55;vertical-align:top;padding-left:0;
}
.wb-tbl-pick thead th:nth-child(2){text-align:center}
.wb-tbl-pick thead input[type=checkbox]{margin:0 0 0 2px}

/* 勾上的行：淡底 + 左侧品牌竖条。
   勾选是跨组累计的，滚到下面时得能一眼看出「这行已经选了」——
   只靠那个 14px 的小方框，在一屏十几行里找不到。 */
.wb-tbl tbody tr.sel{background:var(--brand-soft)}
.wb-tbl tbody tr.sel:hover{background:var(--brand-soft)}
.wb-tbl tbody tr.sel td:first-child{box-shadow:inset 3px 0 0 var(--brand)}

/* 不能排期的组（「其他待办」= 已送检但缺见证组号）：勾选列留白，不画禁用灰框 */
.wb-pick-na{color:var(--ink4);font-size:var(--fs-sm)}

/* 批量安排弹窗里的逾期提示条 */
.wb-warn{
  margin:10px 0;padding:8px 11px;border-radius:8px;
  background:var(--warn-soft);border:1px solid var(--warn-soft);
  color:var(--warn-ink);font-size:var(--fs-sm);line-height:1.6;
}

/* 项目设置「显示 · 列表分页」折叠区（第 54 轮 · 该项目从导航下沉到这里） */
.setfold{
  margin-top:14px;border:1px solid var(--line);border-radius:var(--radius-md);
  background:var(--card);
}
.setfold>summary{
  cursor:pointer;padding:11px 14px;font-size:var(--fs-sm);color:var(--ink2);font-weight:600;
  list-style:none;display:flex;align-items:center;gap:7px;user-select:none;
}
.setfold>summary::-webkit-details-marker{display:none}
.setfold>summary::before{
  content:"▸";color:var(--ink4);font-size:calc(10px * var(--font-scale));flex:none;
}
.setfold[open]>summary::before{content:"▾"}
.setfold[open]>summary{border-bottom:1px solid var(--line-2)}
.setfold-bd{padding:12px 14px}

/* 打印队列的折叠卡（第 57 轮：「单据模板」「打印历史」默认折叠）
   —— 复用 .setfold 的三角与开合，只把标题行做成「粗标题 + 灰说明」两段。 */
.setfold>summary{flex-wrap:wrap}
.pfold>summary .sub{
  font-weight:400;color:var(--ink3);font-size:var(--fs-xs);
  line-height:1.5;
}
.pfold>.setfold-bd{padding:14px}

/* ============================================================
   第 55 轮：批量安排送检的「排期预演表」
   ------------------------------------------------------------
   用户问「批量时同条件温度怎么算、标养龄期怎么算」。
   答案要当场看得见：统一日期之后，每条各自的龄期与累计温度是多少、
   够不够 —— 与单独安排抽屉里那两列同一件事。
   弹窗是 size:p（约 560px），5 列要塞得下，所以部位列截断、其余定宽。
   ============================================================ */
/* ★ 不设 max-height（用户 2026-11-02 第 55 轮追加：「高度自动调节？怎么还会出现竖向滚动条」）：
   弹窗本身 .dlg 已限高 88vh、.dlg-bd 已是滚动容器。表内再套一个 236px 的滚动框，
   一个弹窗里就有两个滚动条，滚到一半表头乱跳，行也看不全。
   这里只留横向兜底，高度随行数自然撑开。 */
.wb-pv{margin-top:12px;border:1px solid var(--line);border-radius:var(--radius-md);overflow-x:auto}
/* ★ 第 57 轮（用户：「列宽需要合理优化」）：改 fixed 布局 —— 组数/龄期定宽，
   剩余宽度全给部位列。auto 布局会把富余平摊给短列，判定列被挤到贴边。 */
.wb-pvtb{width:100%;border-collapse:collapse;font-size:var(--fs-sm);table-layout:fixed}
.wb-pvtb thead th{
  position:sticky;top:0;z-index:1;background:var(--panel-2);
  font-weight:600;color:var(--ink3);text-align:left;white-space:nowrap;
  padding:7px 8px;border-bottom:1px solid var(--line);
}
.wb-pvtb td{padding:6px 8px;border-bottom:1px solid var(--line-2);vertical-align:middle}
.wb-pvtb tbody tr:last-child td{border-bottom:0}
.wb-pvnm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink)}
.wb-pvmt{color:var(--ink3);white-space:nowrap;font-size:var(--fs-xs)}
/* 第 56 轮：养护与组数拆成两列后，组数单独一列右对齐 ——
   数字列左右对齐才能横向比大小，挤在「拆模 · 3 组」里是比不出来的。 */
.wb-pvgrp{
  white-space:nowrap;text-align:right;color:var(--ink2);
  font-size:var(--fs-xs);font-variant-numeric:tabular-nums;
}
.wb-pvtb thead th:nth-child(3){text-align:right}
.wb-pvtt{white-space:nowrap}

/* 判定徽标：不达标红、排晚橙、达标绿、不适用灰 */
.wb-jg{
  display:inline-block;padding:1px 7px;border-radius:var(--radius-md);
  font-size:var(--fs-xs);white-space:nowrap;
}
.wb-jg.ok{background:var(--ok-soft);color:var(--ok-ink)}
.wb-jg.bad{background:var(--danger-soft);color:var(--danger-ink)}
.wb-jg.warn{background:var(--warn-soft);color:var(--warn-ink)}
.wb-jg.na{background:var(--panel-2);color:var(--ink3)}

/* 全部达标时的一条绿提示（比"没有警告"更能让人放心点确认） */
.wb-okbar{
  margin-top:10px;padding:8px 11px;border-radius:8px;
  background:var(--ok-soft);color:var(--ok-ink);
  font-size:var(--fs-sm);line-height:1.6;
}
.wb-pvnote{margin-top:8px;color:var(--ink3);font-size:var(--fs-xs);line-height:1.6}

/* 预演表下方的「最早哪天能全部达标」建议（可点即填入日期框） */
.wb-pvsug{margin-top:6px;font-size:var(--fs-sm);color:var(--ink2);line-height:1.7}
.wb-pvsugb{
  border:0;background:none;padding:0 2px;cursor:pointer;
  font:inherit;font-family:var(--mono);font-weight:600;
  color:var(--brand);text-decoration:underline;text-underline-offset:2px;
}
.wb-pvsugb:hover{color:var(--brand-ink)}

/* 批量安排送检：高度随内容、到 88vh 才滚（第 55 轮 · 用户"高度自动调节？怎么还会出现竖向滚动条"）
   w1 档锁 475px 高是给单栏表单的，这里装的是「日期 + 预演表 + 汇总」，
   8 行就超 —— 结果表格在弹窗里又被裁一次，出现两个滚动条的观感。
   宽度仍走 w1（760，五列刚好），只解高度。 */
.dlg.wbplan{height:auto;max-height:88vh}
.dlg.wbplan .dlg-bd{flex:0 1 auto;min-height:0}

/* ============ 新建项目（第 57 轮 P0-P2） ============ */
/* 切换器底部的操作条：与上面的项目列表用一条线隔开 ——
   混在列表里会被当成"又一个项目"点进去。 */
.pick-bar{display:flex;gap:8px;flex-wrap:wrap;padding:12px 4px 2px;margin-top:10px;border-top:1px solid var(--line)}
/* 弹窗里连续三个字段之间给一条呼吸 */
.dlg-bd>.fld{margin-bottom:14px}
/* 预演块：建之前告诉人"会带什么、会清什么"。
   底色用画布色 --bg，不用卡片白 —— 它是说明文字，不是可填区域。 */
.pj-plan{margin-top:2px;padding:12px 14px;border:1px solid var(--line);border-radius:9px;background:var(--bg)}
.pj-plan .t{font-size:var(--fs-sm);font-weight:600;color:var(--ink2);margin-top:9px}
.pj-plan .t:first-child{margin-top:0}
.pj-plan .d{font-size:var(--fs-xs);color:var(--ink3);line-height:1.75}

/* ============================================================
   打印队列 · 标签式信息架构（2026-11-03）
   - .ptabs 标签栏吸顶（滚动容器是 .canvas，sticky top:0 即贴其顶）
   - 角标 .bdg 与表体同源计数，0 时不渲染
   - 窄屏（<768px）标签横向滑动，不折行不挤变形
   ============================================================ */
.ptabs{display:flex;gap:4px;position:sticky;top:0;z-index:3;margin:-6px -2px 14px;padding:8px 2px;
  background:var(--bg);border-bottom:1px solid var(--line);overflow-x:auto;scrollbar-width:none}
.ptabs::-webkit-scrollbar{display:none}
.ptab{flex:none;display:inline-flex;align-items:center;gap:6px;padding:7px 14px;border:1px solid transparent;
  border-radius:8px 8px 0 0;background:none;color:var(--ink2);font-size:var(--fs-base);cursor:pointer;white-space:nowrap}
.ptab:hover{color:var(--ink);background:var(--panel-2)}
.ptab.on{background:var(--panel);border-color:var(--line);border-bottom-color:var(--panel);color:var(--ink);font-weight:600}
.ptab .bdg{min-width:18px;padding:0 5px;border-radius:9px;background:var(--brand);color:#fff;
  font-size:var(--fs-xs);font-weight:600;line-height:18px;text-align:center;font-variant-numeric:tabular-nums}
.ptab.on .bdg{background:var(--brand)}
.ptpanel[hidden]{display:none}
.pt-bar{display:flex;align-items:center;gap:9px;padding-bottom:10px;border-bottom:1px solid var(--line);margin-bottom:10px}
.pt-frow{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:10px 0 12px}
.pt-frow input[type="date"],.pt-frow input[type="search"],.pt-frow select{
  padding:6px 9px;border:1px solid var(--line);border-radius:8px;background:var(--panel);
  color:var(--ink);font-size:var(--fs-sm);font-family:inherit}
@media (max-width:768px){
  .ptab{padding:7px 10px}
  .pt-frow input[type="search"]{max-width:none;flex:1}
}

/* ============================================================
   打印中心 · 工作台改造（2026-11-05 设计稿落地，用户拍板四项新增全做）
   ------------------------------------------------------------
   布局：命令条（.ptabs 右侧追加 .ptools）+ 主列表（.pc-main）+ 出票坞（.pc-dock）。
   密度：默认紧凑（行高≈34px，.pc-compact 作用域限 #s-print，全站 .tbl 不受影响）；
         舒适/紧凑切换按项目记忆（localStorage v02.pc-density:<project>）。
   断点：≥1280 双栏；1024~1280 坞转底部悬浮条；<1024 单列（坞并入列表上方）。
   铁律不动：默认不勾选（第 57 轮拍板）；点击打印视为已打；已打不移出；补打沿用原单号。
   ============================================================ */
:root{--pc-top:52px}

/* 命令条右侧工具：部位搜索 + 密度切换（挂在 .ptabs 内，随标签栏一起吸顶） */
.ptools{margin-left:auto;display:flex;align-items:center;gap:6px;padding-left:10px;flex:none}
.ptools input[type="search"]{width:150px;height:28px;padding:3px 8px;border:1px solid var(--line);
  border-radius:7px;background:var(--panel);color:var(--ink);font-size:var(--fs-sm);font-family:inherit}
.ptools input[type="search"]:focus{outline:none;border-color:var(--brand)}
.ptools .btn{white-space:nowrap;flex:none}

/* ① 区两栏：左主列表（无卡片框）+ 右出票坞 */
.pc-grid{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:14px;align-items:start}
.pc-main{min-width:0}
.pc-dock{position:sticky;top:var(--pc-top);z-index:2;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);box-shadow:var(--sh);padding:12px}
.pc-dock h4{margin:0 0 6px;font-size:var(--fs-base)}
.pc-sum{font-size:var(--fs-sm);color:var(--ink2);line-height:1.9}
.pc-sum b{color:var(--ink)}
.pc-line{display:flex;align-items:center;gap:6px;font-size:var(--fs-sm);padding:2px 0;color:var(--ink2)}
.pc-line .pc-n{margin-left:auto;font-variant-numeric:tabular-nums;color:var(--ink);font-weight:600}
.pc-paper{background:var(--panel-2);border:1px dashed var(--line);border-radius:6px;padding:10px;margin:10px 0}
.pc-paper .ln{height:3px;background:var(--line);border-radius:2px;margin:4px 0}
.pc-dock .pc-note{font-size:var(--fs-xs);color:var(--ink3);line-height:1.7;margin-top:8px}
.pc-dock .pc-acts{display:flex;gap:6px;margin-top:10px}
.pc-dock .pc-acts .btn{flex:1;justify-content:center;text-align:center}

/* 主列表组头吸顶：滚动时始终知道自己在哪一组 */
.pc-gh{position:sticky;top:var(--pc-top);z-index:2;background:var(--panel);
  padding:6px 4px;margin:0 -4px;border-bottom:1px solid var(--line)}

/* 密度：紧凑为默认（不加类即紧凑），.pc-comfy 切舒适；只作用 #s-print */
#s-print .tbl td.cb{width:30px}
#s-print.pc-comfy .tbl th{padding:10px 12px}
#s-print.pc-comfy .tbl td{padding:10px 12px}
#s-print .tbl th{padding:4px 8px}
#s-print .tbl td{padding:5px 8px}

/* 补打区快照 chips：一行一个批次，点击展开明细 */
.pc-chips{display:flex;flex-wrap:wrap;gap:6px;margin:8px 0 4px}
.pc-chip{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:999px;
  border:1px solid var(--line);background:var(--panel-2);color:var(--ink2);
  font-size:var(--fs-xs);cursor:pointer;user-select:none;max-width:100%}
.pc-chip:hover{border-color:var(--brand);color:var(--brand)}
.pc-chip.on{background:var(--brand-soft,#e8f0fa);border-color:var(--brand);color:var(--brand);font-weight:600}

/* 1024~1280：出票坞收起为底部悬浮条（设计稿断点 ②） */
@media (max-width:1279.5px) and (min-width:1024px){
  .pc-grid{grid-template-columns:minmax(0,1fr)}
  .pc-dock{position:fixed;left:16px;right:16px;bottom:0;top:auto;z-index:8;max-height:42vh;overflow:auto;
    border-radius:var(--r) var(--r) 0 0;box-shadow:0 -4px 18px rgba(16,24,40,.16);padding:8px 12px}
  .pc-dock .pc-paper,.pc-dock .pc-full{display:none}
}
/* <1024：单列，坞并入列表上方（order 提前，不再 sticky） */
@media (max-width:1023.5px){
  .pc-grid{grid-template-columns:minmax(0,1fr)}
  .pc-dock{position:static;order:-1}
}

/* ============================================================
   计费标准 · 左分类栏 + 右表（2026-11-04 用户第 2 条：界面重新设计）
   ------------------------------------------------------------
   为什么改成两栏：旧版把分类同时当"组头"和"一行一列"，滚两屏就对不上；
   改成左边选、右边看之后，「哪一类还差几项没配价」在左栏一眼可见，
   而且点得动（旧版组头只是文字）。
   ============================================================ */
.bill-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:2px 0 12px}
.bill-bar input.bill-q{width:280px;height:30px}
.bill-tools{margin-left:auto;display:flex;gap:8px;flex-wrap:wrap}
.bill-grid{display:grid;grid-template-columns:208px minmax(0,1fr);gap:12px;align-items:start}
.bill-rail{display:flex;flex-direction:column;gap:2px;border:1px solid var(--border);
  border-radius:10px;padding:6px;background:var(--surface)}
.bill-cat{display:flex;align-items:center;gap:6px;width:100%;text-align:left;
  border:1px solid transparent;background:transparent;border-radius:var(--radius-sm);
  padding:7px 9px;font:inherit;font-size:calc(12.5px * var(--font-scale));
  color:var(--ink);cursor:pointer;line-height:1.5}
.bill-cat:hover{background:var(--surface2)}
.bill-cat.on{background:var(--brand-soft);border-color:var(--brand);font-weight:700}
.bill-cat .n{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bill-cat .c{color:var(--ink3);font-family:var(--mono);font-size:calc(11.5px * var(--font-scale))}
.bill-cat.on .c{color:var(--ink2)}
.bill-cat .u{color:var(--warn);font-size:calc(10.5px * var(--font-scale));font-weight:700;white-space:nowrap}

.bill-main{min-width:0;overflow-x:auto}
.bill-tbl{min-width:830px;border:1px solid var(--border);border-radius:10px;overflow:hidden;background:var(--surface)}
.bill-hrow,.bill-row{display:grid;align-items:center}
.bill-hrow{background:var(--surface-3);color:var(--ink2);font-weight:700;
  font-size:calc(11.5px * var(--font-scale));border-bottom:1px solid var(--border)}
.bill-hrow .c,.bill-row .c{padding:8px 9px;min-width:0}
.bill-hrow .c.r,.bill-row .c.r{text-align:right}
.bill-row{border-top:1px solid var(--border);font-size:calc(12.5px * var(--font-scale))}
.bill-row.unset{background:repeating-linear-gradient(135deg,transparent,transparent 8px,
  rgba(0,0,0,.012) 8px,rgba(0,0,0,.012) 16px)}
.bill-row.voided{opacity:.62}
.bill-row .v{font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bill-row .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bill-row .fp{font-weight:700}
.bill-row .op{display:flex;gap:5px;justify-content:flex-end;flex-wrap:wrap}
.bill-gh{display:flex;align-items:baseline;gap:10px;padding:7px 9px;background:var(--surface-3);
  border-top:1px solid var(--border);border-left:3px solid var(--brand);
  font-size:calc(12.5px * var(--font-scale))}
.bill-empty{padding:34px 12px;text-align:center;color:var(--ink3);
  font-size:calc(12.5px * var(--font-scale));line-height:1.9}

/* 分类管理弹窗 */
.bill-catlist{max-height:320px;overflow:auto;border:1px solid var(--border);border-radius:9px}
.bill-catrow{display:flex;align-items:center;gap:8px;padding:7px 10px;
  border-top:1px solid var(--border);font-size:calc(12.5px * var(--font-scale))}
.bill-catrow:first-child{border-top:none}
.bill-catrow .hint{margin-right:auto}
.bill-mergerow{display:flex;align-items:center;gap:8px;margin-top:10px;padding-top:10px;flex-wrap:wrap}
.bill-mergerow input{flex:1;min-width:160px;height:30px;padding:0 8px;font:inherit;
  font-size:calc(12.5px * var(--font-scale));border:1px solid var(--line);
  border-radius:var(--radius-sm);background:var(--surface);color:var(--ink)}
/* 归类弹窗 */
.bill-movelist{max-height:300px;overflow:auto;border:1px solid var(--border);border-radius:9px;margin-top:8px}
.bill-moveopt{display:flex;align-items:center;gap:8px;padding:7px 10px;
  border-top:1px solid var(--border);font-size:calc(12.5px * var(--font-scale));cursor:pointer}
.bill-moveopt:first-child{border-top:none}
.bill-newcat{margin-left:auto;width:210px;height:28px;padding:0 8px;font:inherit;
  font-size:calc(12px * var(--font-scale));border:1px solid var(--line);
  border-radius:var(--radius-sm);background:var(--surface);color:var(--ink)}
.bill-newcat:disabled{opacity:.5}
@media (max-width:1024px){
  .bill-grid{grid-template-columns:1fr}
  .bill-rail{flex-direction:row;flex-wrap:wrap}
  .bill-cat{width:auto}
}

/* ============================================================
   工具箱（077）
   ------------------------------------------------------------
   ★ 全部颜色/圆角/阴影走令牌，一个裸色值都不写。
     第 3 轮用户指着报告登记那个搜索框说「为什么是椭圆的？不受主题管控吗？」
     —— 根因就是当时把圆角与底色内联在 JS 里。这里一个内联样式都没有。
   ★ 类名统一 tb- 前缀：app.css 里已有 .card/.tab/.btn/.tag 等通用类，
     直接复用名字会跟别处打架（.tabs 在别处就是另一套 tab 条）。
   ============================================================ */
.tb-tabs{display:flex;gap:2px;border-bottom:1px solid var(--border);margin:0 0 14px}
.tb-tabs .tab{
  border:0;background:none;padding:8px 15px 9px;font:inherit;font-size:13.2px;color:var(--text-2);
  cursor:pointer;position:relative;border-radius:var(--radius-sm) var(--radius-sm) 0 0;
}
.tb-tabs .tab:hover{background:var(--surface-3);color:var(--text-1)}
.tb-tabs .tab.on{color:var(--brand-ink);font-weight:600}
.tb-tabs .tab.on::after{
  content:"";position:absolute;left:10px;right:10px;bottom:-1px;height:2px;
  background:var(--brand);border-radius:2px;
}
.tb-tabs .tab .ti{color:var(--text-3);margin-right:6px;font-size:12px}
.tb-tabs .tab.on .ti{color:var(--brand)}
.tb-tabs .tab .n{font-size:11px;color:var(--text-3);margin-left:5px;font-weight:400}

.tb-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-1)}
.tb-panel{display:block}

/* ---------- 计算器 ---------- */
.tb-calc{display:grid;grid-template-columns:300px minmax(0,1fr);gap:16px;align-items:start}
.tb-picker{padding:16px}
/* ★ 左栏这一列叫 .prow，不能叫 .row。
   .row 在 app.css 第 415 行是「待办/台账」那套五列表格行
   （grid-template-columns:94px 1fr 112px 118px 78px），
   拿它当「标签 + 选项」的普通块用，右栏被挤成 1fr 只有 77px，
   分段按钮就一个一行地竖着摞 —— 用户 2026-11-04 截图里看到的就是这个。
   加上 .tb-seg 那次改名，同一个毛病这是第二回：**通用类名不许在组件里随手借。** */
.tb-picker .prow{margin-bottom:13px}
.tb-picker .prow:last-child{margin-bottom:0}
.tb-picker .lb{font-size:12px;color:var(--text-3);margin-bottom:6px}
/* .tb-seg 同理：产品里 .segbar .seg 是「页签」那一族，.seg 单独出现时别处也各有定义。 */
.tb-seg{display:flex;flex-wrap:wrap;gap:5px}
.tb-seg button{
  font:inherit;font-size:12.5px;padding:3px 10px;border-radius:var(--radius-sm);
  border:1px solid var(--border);background:var(--surface);color:var(--text-2);cursor:pointer;
}
.tb-seg button:hover{border-color:var(--border-strong)}
.tb-seg button.on{background:var(--brand-soft);border-color:var(--brand);color:var(--brand-ink);font-weight:600}
.tb-seg.dia button{min-width:42px;justify-content:center;display:inline-flex}
.diafree{display:flex;align-items:center;gap:7px;margin-top:7px}
.diafree input{width:68px;text-align:center}
.tb-ck{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--text-2);margin-top:6px;cursor:pointer}
.tb-ck input[type=checkbox]{width:auto;margin:0}

.tb-result{display:flex;flex-direction:column;gap:12px}
.bigrow{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
.tb-bigcard{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);
  padding:13px 16px 14px;box-shadow:var(--shadow-1);position:relative;overflow:hidden;
}
.tb-bigcard.main{
  border-color:color-mix(in srgb,var(--brand) 45%,var(--border));
  background:linear-gradient(180deg,var(--brand-soft),var(--surface) 62%);
}
.tb-bigcard .lb{font-size:12px;color:var(--text-3);display:flex;align-items:center;gap:5px}
.tb-bigcard .lb i{font-style:italic;font-family:var(--mono);font-size:12.5px;color:var(--text-2)}
.tb-bigcard .vv{font-size:27px;font-weight:600;letter-spacing:-.02em;line-height:1.25;margin-top:3px;font-variant-numeric:tabular-nums}
.tb-bigcard .vv small{font-size:13px;font-weight:400;color:var(--text-3);margin-left:3px;letter-spacing:0}
.tb-bigcard .fx{font-size:11.8px;color:var(--text-3);margin-top:2px;font-family:var(--mono)}

.tb-steps{padding:14px 16px 16px}
.tb-steps h4{margin:0 0 10px;font-size:13px;font-weight:600;display:flex;align-items:center;gap:7px}
.tb-steps h4 .tag{font-weight:400}
.tb-st{display:flex;gap:10px;padding:6px 0;font-size:12.8px;border-bottom:1px dashed var(--border)}
.tb-st:last-child{border-bottom:0}
.tb-st .k{width:104px;flex:none;color:var(--text-3)}
.tb-st .v{flex:1;font-family:var(--mono);font-size:12.3px}
.tb-st .v b{color:var(--brand-ink);font-weight:600}
.tb-st.off .v{color:var(--text-3)}

.tb-warnbox{
  display:flex;gap:9px;padding:10px 13px;border-radius:var(--radius-md);
  background:var(--warn-soft);color:var(--warn-ink);font-size:12.6px;line-height:1.7;
}
.tb-warnbox .ic{flex:none;font-weight:700}

/* ---------- 保护层 ---------- */
.tb-prot{display:grid;grid-template-columns:296px minmax(0,1fr);gap:16px;align-items:start}
.tb-matrix{overflow:hidden}
.tb-matrix .ph{display:flex;align-items:center;gap:10px;padding:13px 16px;border-bottom:1px solid var(--border)}
.tb-matrix .ph b{font-size:13.5px;font-weight:600}
.tb-matrix .ph .right{margin-left:auto}
.tb-matrix table{width:100%;border-collapse:collapse;font-size:12.6px}
.tb-matrix th,.tb-matrix td{padding:8px 10px;border-bottom:1px solid var(--border);text-align:center}
.tb-matrix thead th{background:var(--surface-3);color:var(--text-2);font-weight:600;font-size:12px}
.tb-matrix tbody th{text-align:left;color:var(--text-2);font-weight:500;background:var(--surface-3);white-space:nowrap}
.tb-matrix td{font-variant-numeric:tabular-nums;color:var(--text-1)}
.tb-matrix td .delta{display:block;font-size:10.5px;color:var(--text-3);line-height:1.35}
.tb-matrix tr.hl td{background:var(--brand-soft);color:var(--brand-ink);font-weight:600}
.tb-matrix tr.hl td .delta{color:var(--brand-ink);opacity:.75}
.tb-matrix tr.hl th{background:var(--brand-soft);color:var(--brand-ink)}
.tb-matrix td.pick{cursor:pointer}
.tb-matrix td.pick:hover{background:var(--surface-3)}
.tb-foot2{padding:10px 16px 14px;border-top:1px dashed var(--border)}
.tb-quick{
  display:flex;align-items:baseline;gap:8px;padding:9px 11px;border-radius:var(--radius-md);
  background:var(--brand-soft);
}
.tb-quick span{font-size:12px;color:var(--brand-ink)}
.tb-quick b{font-size:22px;color:var(--brand-ink);font-variant-numeric:tabular-nums;margin-left:auto}

/* ---------- 经验分享 ---------- */
.tb-list{overflow:hidden}
.tb-list .ph{display:flex;align-items:center;gap:10px;padding:13px 16px;border-bottom:1px solid var(--border)}
.tb-list .ph b{font-size:13.5px;font-weight:600}
.tb-list .ph .right{margin-left:auto;display:flex;gap:8px;align-items:center}
.tb-lrow{
  display:grid;grid-template-columns:76px minmax(0,1fr) 88px 84px 62px;
  gap:12px;align-items:center;padding:10px 16px;border-bottom:1px solid var(--border-soft);
  cursor:pointer;font-size:13px;
}
.tb-lrow:last-child{border-bottom:0}
.tb-lrow:hover{background:var(--surface-3)}
.tb-lrow .d{color:var(--text-3);font-size:12.3px;font-family:var(--mono)}
.tb-lrow .t{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tb-lrow .t em{font-style:normal;background:var(--warn-soft);border-radius:2px;color:var(--warn-ink)}
.tb-lrow .p{color:var(--text-2);font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tb-lrow .a{justify-self:end;display:flex;gap:4px;opacity:0;transition:.12s}
.tb-lrow:hover .a{opacity:1}

.tb-srch{
  display:inline-flex;align-items:center;gap:0;border:1px solid var(--line,var(--border));
  border-radius:var(--radius-sm);background:var(--surface);padding:0 8px;height:28px;
}
.tb-srch input{border:0;background:none;padding:0;height:26px;font-size:12.5px;width:168px;box-shadow:none}
.tb-srch input:focus{box-shadow:none}
.tb-srch .ic{color:var(--text-3);font-size:12px;margin-right:4px}

.tb-empty{padding:44px 20px;text-align:center;color:var(--text-3);font-size:13px}
.tb-empty .ic{font-size:26px;opacity:.4;display:block;margin-bottom:8px}

/* ---------- 抽屉 ---------- */
.tb-scrim{position:fixed;inset:0;background:rgba(22,33,29,.42);z-index:60}
.tb-drawer{
  position:fixed;top:0;right:0;bottom:0;width:520px;max-width:92vw;background:var(--surface);
  box-shadow:var(--shadow-3);z-index:61;display:flex;flex-direction:column;
}
.tb-drawer .dh{padding:15px 20px 12px;border-bottom:1px solid var(--border)}
.tb-drawer .dh .row1{display:flex;align-items:flex-start;gap:10px}
.tb-drawer .dh h3{margin:0;font-size:15px;font-weight:600;line-height:1.45;flex:1}
.tb-drawer .dh .m{font-size:12.3px;color:var(--text-3);margin-top:6px;display:flex;gap:12px;flex-wrap:wrap}
.tb-drawer .db{flex:1;overflow:auto;padding:16px 20px;font-size:13.4px;line-height:1.9;white-space:pre-wrap}
.tb-drawer .df{padding:11px 20px;border-top:1px solid var(--border);display:flex;gap:8px;align-items:center}
.tb-drawer .df .sp{flex:1}

/* ---------- 红头文件卡片 ---------- */
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(276px,1fr));gap:12px;padding:14px 16px;align-items:stretch}
.tb-fcard{
  border:1px solid var(--border);border-radius:var(--radius-md);padding:12px 13px 11px;
  background:var(--surface);cursor:pointer;transition:.14s;position:relative;
  display:flex;flex-direction:column;gap:6px;min-height:132px;height:100%;
}
.tb-fcard:hover{border-color:var(--brand);box-shadow:var(--shadow-2)}
.tb-fcard .top2{display:flex;align-items:flex-start;gap:9px}
.tb-fcard .doc{
  width:30px;height:36px;flex:none;border-radius:4px;background:var(--danger-soft);
  color:var(--danger);display:grid;place-items:center;font-size:11px;font-weight:700;
  border:1px solid color-mix(in srgb,var(--danger) 22%,transparent);
}
.tb-fcard .doc.net{background:var(--brand-soft);color:var(--brand-ink);border-color:color-mix(in srgb,var(--brand) 22%,transparent)}
.tb-fcard .nm{
  font-size:13.2px;font-weight:500;line-height:1.45;display:-webkit-box;-webkit-line-clamp:2;
  -webkit-box-orient:vertical;overflow:hidden;min-height:2.9em;
}
.tb-fcard .meta{font-size:11.9px;color:var(--text-3);line-height:1.6}
.tb-fcard .bot{display:flex;align-items:center;gap:7px;margin-top:auto;padding-top:6px;border-top:1px dashed var(--border)}
.tb-fcard .code{font-family:var(--mono);font-size:11.5px;background:var(--surface-3);border-radius:4px;padding:1px 6px;color:var(--text-2)}
.tb-fcard .bot .act{margin-left:auto;display:flex;gap:4px}

/* ---------- 常用网址 ---------- */
.tb-sitegrid{display:grid;grid-template-columns:minmax(0,1fr) 264px;gap:14px;align-items:start;padding:0 0 12px}
.tb-siterail{padding:12px 12px 14px;border-left:1px solid var(--border)}
.tb-siterail .rh{font-size:11.5px;color:var(--text-3);padding:0 6px 5px}
.srow{
  /* 2026-11-04：去掉「次数」列（见 tools.js rowHtml 注释）。
     原先是 30/1fr/132/92/58/106 —— 操作列 106px 装不下 5 个按钮（实测约 178px），
     溢出部分向左压住「次数」。现在列数跟着 DOM 走：图标 / 名称 / 项目账号 / 分组 / 操作，
     最后一列用 auto 按按钮实际宽度撑开，不再写死。 */
  display:grid;grid-template-columns:30px minmax(0,1fr) 132px 92px auto;gap:10px;align-items:center;
  padding:5px 16px;border-bottom:1px solid var(--border-soft);cursor:pointer;font-size:13px;
}
.srow:last-child{border-bottom:0}
.srow:hover{background:var(--surface-3)}
.srow:hover .dom{color:var(--brand-ink)}
.srow .fav{
  width:24px;height:24px;border-radius:var(--radius-sm);display:grid;place-items:center;
  font-size:11.5px;font-weight:700;color:#fff;flex:none;
}
.srow .nmw{min-width:0}
.srow .nm{font-weight:500;display:flex;align-items:center;gap:6px;line-height:1.4}
.srow .nm .pin{font-size:10px;color:var(--warn)}
.srow .dom{font-size:11.5px;color:var(--text-3);font-family:var(--mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.35}
.srow .catt{justify-self:start}
/* 078：网址行上的「当前项目账号」。有就显示账号，没有给一条虚线提示 ——
   空着不显示会让人以为"这站不需要登录"，虚线则明确说"你能存，但还没存"。 */
.srow .accc{
  justify-self:start;max-width:132px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-family:var(--mono);font-size:11.5px;color:var(--text-2);
  background:var(--surface-3);border-radius:4px;padding:1px 6px;line-height:1.6;
}
.srow .accc.none{
  font-family:inherit;font-size:11px;color:var(--text-3);background:transparent;
  border:1px dashed var(--border);padding:0 5px;
}
.srow:hover .accc{background:var(--brand-soft);color:var(--brand-ink)}
.srow:hover .accc.none{background:transparent;color:var(--text-2)}
.srow .op{justify-self:end;display:flex;gap:2px;opacity:0;transition:.12s;white-space:nowrap}
/* 操作列里的图标按钮不用 .btn.sm 的 10px 左右内边距 —— 那套内边距是给「文字按钮」的，
   图标本身只有 1 个字宽，撑出 34px 白边，5 个就是 170px。收紧到 6px 后一行放得下。 */
.srow .op .btn.sm{height:24px;min-width:26px;padding:0 6px;justify-content:center}
.srow:hover .op{opacity:1}
.grphead{
  padding:7px 16px 5px;font-size:11.5px;color:var(--text-3);background:var(--surface-3);
  border-bottom:1px solid var(--border);display:flex;align-items:center;gap:7px;
}
.grphead i{display:inline-block;width:7px;height:7px;border-radius:2px;flex:none}
.grphead b{font-weight:600;color:var(--text-2);font-size:11.8px}
.grphead .n{background:var(--surface);border:1px solid var(--border);border-radius:99px;padding:0 6px;font-size:10.5px}
.catbtn{
  display:flex;align-items:center;gap:8px;padding:5px 9px;border-radius:var(--radius-sm);
  border:1px solid transparent;background:none;font:inherit;font-size:12.7px;color:var(--text-2);
  cursor:pointer;text-align:left;width:100%;
}
.catbtn i{display:inline-block;width:8px;height:8px;border-radius:3px;flex:none}
.catbtn:hover{background:var(--surface-3)}
.catbtn.on{background:var(--brand-soft);border-color:color-mix(in srgb,var(--brand) 35%,transparent);color:var(--brand-ink);font-weight:600}
.catbtn .n{margin-left:auto;font-size:11px;color:var(--text-3)}
.catbtn.on .n{color:var(--brand-ink)}
.rec{
  display:grid;grid-template-columns:auto minmax(0,1fr);gap:7px;align-items:center;
  font-size:12.4px;color:var(--text-2);cursor:pointer;padding:4px 6px;border-radius:var(--radius-sm);
}
.rec:hover{background:var(--surface-3);color:var(--brand-ink)}
.rec i{display:inline-block;width:6px;height:6px;border-radius:2px;flex:none}
.rec .d{grid-column:2;font-size:10.8px;color:var(--text-3);font-family:var(--mono);line-height:1.2;margin-top:-3px}

/* ---------- 弹窗里的双列小格子 ---------- */
.tb-grid2{display:grid;grid-template-columns:1fr 1fr;gap:11px}

/* ---------- 页脚 ---------- */
.tb-foot{
  margin-top:14px;display:flex;gap:14px;flex-wrap:wrap;align-items:center;
  font-size:11.8px;color:var(--text-3);padding-top:11px;border-top:1px dashed var(--border);
}
.tb-foot b{color:var(--text-2);font-weight:600}

/* ---------- 窄屏 ---------- */
@media (max-width:1180px){
  .tb-calc{grid-template-columns:264px minmax(0,1fr)}
  .tb-prot{grid-template-columns:264px minmax(0,1fr)}
  .tb-sitegrid{grid-template-columns:minmax(0,1fr) 220px}
}
@media (max-width:900px){
  .tb-calc,.tb-prot{grid-template-columns:1fr}
  .bigrow{grid-template-columns:1fr}
  .tb-sitegrid{grid-template-columns:1fr}
  .tb-siterail{border-left:0;border-top:1px solid var(--border)}
  /* 窄屏：只留 图标 / 名称 / 操作。账号 chip 与分组标签都让位给按钮 ——
     52px 装不下 5 个按钮，硬留着又是同一处溢出。 */
  .srow{grid-template-columns:30px minmax(0,1fr) auto}
  .srow .catt{display:none}
  .srow .accc{display:none}
}

/* ============================================================
   弹窗尺寸页重做 · 一档一张卡（2026-11-04 · 用户「按方案稿实施」）
   ------------------------------------------------------------
   原来这一屏是「四行圆点 + 一段说明」：改 w1 一次动 37 个界面，
   可页面上只有「单栏表单」四个字，没人联想得到改密码/加人/编辑网址
   都在这一档。所以改成一档一张卡：像素、用途、窗口数、点名清单都在卡里。

   ★ 清单用 <details> 折叠：默认只露「N 个窗口」，展开才占地方 ——
     72 个窗口全铺开，这一屏要滚三屏才能到底。
   ★ 类名一律 dt- / dlgtier 前缀，不复用通用名（这文件里 .chip 已经有两套定义）。
   <<<V655DLG<<< */
.dlgtiers{display:grid;grid-template-columns:1fr;gap:10px}
.dlgtier{border:1px solid var(--line);border-radius:9px;background:var(--panel);padding:11px 13px}
.dt-row{display:flex;align-items:flex-start;gap:14px;flex-wrap:wrap}
.dt-l{flex:1;min-width:220px}
.dt-name{font-size:calc(13.5px * var(--font-scale));font-weight:650}
.dt-cnt{margin-left:8px;font-size:var(--fs-xs);color:var(--ink3);background:var(--panel-2);
  border:1px solid var(--line);border-radius:999px;padding:1px 7px;white-space:nowrap}
.dt-use{font-size:calc(12px * var(--font-scale));color:var(--ink3);line-height:1.6;margin-top:3px}
.dt-opts{display:flex;gap:8px;flex-wrap:wrap;flex:none;align-items:center}
.dt-bar{display:flex;align-items:center;gap:8px;margin-top:9px;flex-wrap:wrap}
.dt-more{margin-top:9px;border-top:1px dashed var(--line);padding-top:7px}
.dt-more>summary{font-size:calc(12px * var(--font-scale));color:var(--brand);cursor:pointer;
  list-style:none;display:inline-flex;align-items:center;gap:5px;user-select:none}
.dt-more>summary::-webkit-details-marker{display:none}
.dt-more>summary::before{content:"▸";font-size:11px;opacity:.75}
.dt-more[open]>summary::before{content:"▾"}
.dt-list{display:flex;flex-wrap:wrap;gap:5px;margin-top:8px}
.dt-win{font-size:calc(11.5px * var(--font-scale));color:var(--ink2);background:var(--panel-2);
  border:1px solid var(--line);border-radius:5px;padding:2px 7px;cursor:default}
.dt-win:hover{border-color:var(--brand);color:var(--brand)}

/* ============================================================
   复制小图标（2026-11-04 用户第 5 条 · 加急）
   录入见证组号窗口：炉批号 / 施工部位 / 套筒厂家 后面各一枚。
   图标本身 12px，按钮盒 18px、圆角 4px —— 比文字小半号，
   正好挂在词尾不当成"又一个可点的东西"抢注意力；
   hover 才出边框，静止时几乎融进表格。
   <<<V656COPY<<<
   ============================================================ */
.cp-ico{display:inline-flex;align-items:center;justify-content:center;
  width:18px;height:18px;margin-left:4px;padding:0;flex:0 0 18px;
  border:1px solid transparent;border-radius:4px;background:transparent;
  color:var(--text-3);cursor:pointer;vertical-align:-3px;line-height:1;
  transition:background .12s,color .12s,border-color .12s}
.cp-ico:hover{background:var(--panel-2);border-color:var(--line);color:var(--text-1)}
.cp-ico:active{transform:scale(.92)}
.cp-ico:focus-visible{outline:2px solid var(--brand);outline-offset:1px}
.cp-ico svg{width:12px;height:12px;display:block;pointer-events:none}
/* 表格里那一列是 mono 字体，图标别跟着等宽拉伸 */
td .cp-ico,.wg-mk .cp-ico{font-family:var(--font)}

/* ============================================================
   第 90 轮（2026-11-05 · 用户第 2 条）
   ------------------------------------------------------------
   ① 打印中心数据行：整行可点选。以前只有第一列 13px 的复选框能点，
      工地平板上要瞄准；现在点行即选中，再点一次取消，Shift+点整段勾。
      选中态必须"看得见"：底色 + 左缘一道 2px 品牌色，光靠复选框太小。
   ② 两栏顶边对齐：左栏第一组的 14px 上边距与分隔线由 print.js 去掉，
      这里只兜住组头内边距，保证组头的字与出票坞标题在同一条基线上。
   ============================================================ */
#s-print .tbl tbody tr.pc-row{cursor:pointer}
#s-print .tbl tbody tr.pc-row:hover td{background:var(--brand-soft)}
#s-print .tbl tbody tr.pc-picked td{background:var(--brand-soft)}
#s-print .tbl tbody tr.pc-picked td:first-child{box-shadow:inset 2px 0 0 var(--brand)}
/* 行内「单打」按钮自己也是热区 —— 悬停在行上时按钮必须比行更明显，
   否则人点按钮时会以为自己只是"又选了一下这行" */
#s-print .tbl tbody tr.pc-row .btn{position:relative;z-index:1}
/* 出票坞与第一组组头同一基线：坞内标题 12px 内边距，组头补到 6px→12px 的差值 */
.pc-grid>.pc-main>.pc-gwrap:first-child>.pc-gh{padding-top:9px}

/* ============================================================
   质量证明书 · 识别结果复核表（第 90 轮 · 2026-11-05）
   ------------------------------------------------------------
   旧版是"卡片 + 每行一个填入按钮"，点一下就关窗跳去单条录入表单；
   一张证 6 行要开关 6 次窗，用户实测「第 2 条填不到」。
   新版是一张能改的表：所有行一次铺开、每格直接编辑，改完一起入库。
   表格本身不设边框（弹窗里已经有框），靠隔行底色与聚焦态定位。
   ============================================================ */
.cert-bar{display:flex;flex-wrap:wrap;gap:10px;align-items:flex-end;padding:10px 12px;
  background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r);margin:0 0 8px}
.cert-bar .f{display:flex;flex-direction:column;gap:3px;font-size:calc(11.5px * var(--font-scale));color:var(--ink3)}
.cert-bar .f input[type="checkbox"]{width:14px;height:14px;accent-color:var(--brand)}
.cert-bar .f input:not([type="checkbox"]){height:28px;padding:2px 8px;border:1px solid var(--line);border-radius:6px;
  background:var(--panel);color:var(--ink);font:inherit;font-size:calc(12.5px * var(--font-scale));min-width:120px}
.cert-bar .f.part input{min-width:230px}
.cert-bar .f input:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-soft)}

.cert-tools{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin:6px 0}
.cert-tools .hint{margin-right:auto;color:var(--ink3);font-size:calc(11.5px * var(--font-scale))}

.cert-scroll{max-height:calc(56vh);overflow:auto;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.cert-tbl{width:100%;min-width:840px;border-collapse:collapse;font-size:calc(12.5px * var(--font-scale))}
.cert-tbl th{position:sticky;top:0;z-index:1;background:var(--panel-2);text-align:left;
  font-size:calc(11px * var(--font-scale));font-weight:600;color:var(--ink3);
  padding:6px 6px;border-bottom:1px solid var(--line);white-space:nowrap}
.cert-tbl td{padding:2px 4px;border-bottom:1px solid var(--line-2);vertical-align:middle}
.cert-tbl input{width:100%;height:26px;padding:2px 6px;border:1px solid transparent;border-radius:5px;
  background:transparent;color:var(--ink);font:inherit;font-size:inherit}
.cert-tbl input:hover{border-color:var(--line);background:var(--panel)}
.cert-tbl input:focus{outline:none;border-color:var(--brand);background:var(--panel);box-shadow:0 0 0 2px var(--brand-soft)}
.cert-tbl td.num input{text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums}
.cert-tbl td.mono input{font-family:var(--mono)}
.cert-tbl tr.off td{opacity:.42}
.cert-tbl tr.dup td{background:rgba(220,38,38,.06)}
.cert-tbl tr.warn td{background:rgba(217,119,6,.06)}
.cert-tbl td.cb{width:26px}
.cert-tbl input[type="checkbox"]{width:14px;height:14px;accent-color:var(--brand)}

/* ============================================================
   不合格处置 · 24 小时计时条（第 95 轮 · 2026-11-06）
   ------------------------------------------------------------
   两个状态，两个颜色，不用第三个：
     .warn = 6 小时内到期（还没违约，只是快到了）
     .over = 已过 24 小时红线（已经违约，且事实不可回撤）
   为什么不做"轻微超时"与"严重超时"两档：超时就是超时，
   细则不按超多超少分档；分了档，人会开始等"反正还没到严重"。
   ★ 颜色全部走令牌，六个皮肤都跟得上（不写死 #dc2626）。
   ============================================================ */
.nc-bar{display:flex;align-items:center;gap:12px;margin:0 0 12px;padding:11px 14px;
  border:1px solid var(--warn);border-left:4px solid var(--warn);border-radius:10px;
  background:var(--warn-soft);color:var(--warn-ink)}
.nc-bar.over{border-color:var(--danger);border-left-color:var(--danger);
  background:var(--danger-soft);color:var(--danger-ink)}
.nc-dot{flex:none;width:9px;height:9px;border-radius:50%;background:currentColor;
  box-shadow:0 0 0 4px color-mix(in srgb,currentColor 18%,transparent)}
.nc-txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.nc-txt b{font-size:var(--fs-md);font-weight:700}
.nc-txt span{font-size:var(--fs-xs);opacity:.82}
/* 窄屏：按钮换行到下一行，别把状态句挤成两行碎字 */
@media (max-width:640px){
  .nc-bar{flex-wrap:wrap}
  .nc-bar .btn{margin-left:21px}
}

/* 处置弹窗 */
.nc-sum{display:flex;flex-direction:column;gap:3px;margin-bottom:10px;font-size:var(--fs-base)}
.nc-sum b{font-size:var(--fs-md)}
.nc-sum span{color:var(--ink3);font-size:var(--fs-xs)}
.nc-empty{padding:22px;text-align:center;color:var(--ink3)}
.nc-tb{width:100%;border-collapse:collapse;font-size:var(--fs-base)}
.nc-tb th{text-align:left;font-weight:600;color:var(--ink3);font-size:var(--fs-xs);
  padding:6px 8px;border-bottom:1px solid var(--line);white-space:nowrap}
.nc-tb td{padding:8px;border-bottom:1px solid var(--line-2);vertical-align:top}
.nc-tb tr:last-child td{border-bottom:0}
.nc-why{font-weight:600}
.nc-obj{margin-top:2px;font-size:var(--fs-xs);color:var(--ink3)}
.nc-num{font-variant-numeric:tabular-nums;white-space:nowrap}
.nc-num.over{color:var(--danger-ink);font-weight:700}
.nc-num.warn{color:var(--warn-ink);font-weight:700}
.nc-over{margin-top:2px;font-size:var(--fs-xs);color:var(--danger-ink);font-weight:600}
.nc-chip{display:inline-block;padding:1px 8px;border-radius:999px;white-space:nowrap;
  font-size:var(--fs-xs);background:var(--panel-2);color:var(--ink3)}
.nc-chip.ok{background:var(--ok-soft, var(--brand-soft));color:var(--ok-ink, var(--brand-ink))}
.nc-chip.over{background:var(--danger-soft);color:var(--danger-ink)}
.nc-act{white-space:nowrap}
.nc-foot{margin-top:12px;padding-top:10px;border-top:1px dashed var(--line);
  font-size:var(--fs-xs);color:var(--ink3);line-height:1.7}

/* ============================================================
   送检确认码弹窗（第 95 轮）
   ------------------------------------------------------------
   这一块的核心是那 4 个数字：资料员要照着念给试验员，或者写到纸上。
   所以码必须大到"隔着一米也能读"，并且带按钮一键复制 / 打开手机页。
   ============================================================ */
.sc-lead{font-size:var(--fs-base);color:var(--ink2);line-height:1.7;margin-bottom:12px}
.sc-code{display:flex;justify-content:center;gap:10px;margin:18px 0 10px}
.sc-code span{width:62px;height:78px;display:flex;align-items:center;justify-content:center;
  font-family:var(--mono);font-size:38px;font-weight:700;color:var(--brand-ink);
  background:var(--brand-soft);border:1.5px solid var(--brand);border-radius:12px}
.sc-sub{text-align:center;font-size:var(--fs-xs);color:var(--ink3);margin-bottom:14px}
.sc-row{display:flex;gap:8px;margin-top:10px}
.sc-row .btn{flex:1}
.sc-link{width:100%;height:34px;padding:0 10px;font-family:var(--mono);font-size:var(--fs-sm);
  border:1px solid var(--line);border-radius:8px;background:var(--panel-2);color:var(--ink2)}
.sc-warn{margin-top:14px;padding:10px 12px;border-radius:9px;background:var(--warn-soft);
  color:var(--warn-ink);font-size:var(--fs-xs);line-height:1.7}

/* ============================================================
   打印队列 · 空态单栏（第 96 轮 · 用户第 3 项）
   ------------------------------------------------------------
   没有待打印记录时，出票坞（.pc-dock）整块不渲染，网格退成单栏。
   不写这条也能凑合（第二列空着），但那会让空态内容挤在左侧 1/3：
   网格的列宽是 minmax(0,1fr) + 320px，右边一空，左边并不会自动撑宽。
   ============================================================ */
.pc-grid.pc-solo{grid-template-columns:minmax(0,1fr)}

/* ============================================================
   今日补打 · 单列表工具条与养护分组行（第 96 轮 · 用户第 5 项）
   ------------------------------------------------------------
   旧版每类养护一张独立表，没有勾选框，合并打印无从下手。
   现在一张表 + 一条工具条，养护类型退成表内的分组小标题：
     .pc-rgrp  = 分组行（不可勾、不可点，只是视觉分隔）
     .pc-rtbar = 全选/清空/合并打印 + 实时张数
   ============================================================ */
.pc-rtbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:10px 0 8px}
.pc-rtcnt{font-weight:700;font-size:var(--fs-base)}
.pc-rtnote{font-size:var(--fs-xs);color:var(--ink3)}
#s-print .tbl tbody tr.pc-rgrp td{background:var(--panel-2);color:var(--ink2);
  font-weight:600;font-size:var(--fs-xs);letter-spacing:.02em;padding:6px 10px;
  border-top:1px solid var(--line)}
#s-print .tbl tbody tr.pc-rgrp:first-child td{border-top:0}
/* 合并打印按钮在窄屏右对齐会掉到第二行，给它一点上边距，别贴着表格 */
@media (max-width:720px){ .pc-rtbar .btn{margin-top:2px} }

/* ============================================================
   导出预览确认弹窗（第 96 轮 · 用户第 4 项）
   ------------------------------------------------------------
   所有 Excel / CSV 导出都先经过这一屏：统计 + 可勾选、可改的预览 + 二次确认。
   布局要点：
     · .xp-wrap 自己滚，表头吸顶 —— 200 行的表不能把弹窗撑出屏幕；
     · 表体用 fixed 布局 + 最小列宽，长部位名换行而不是把列压成竖排；
     · 取消勾选的行整行变灰（不是隐藏）：藏起来就看不出"还有多少没导"。
   ============================================================ */
.xp-lead{font-size:var(--fs-sm);color:var(--ink2);line-height:1.7}
/* ★ 第 99 轮（用户 2026-11-06 第 1 条）：把「⚙ 选列」并入预览，并在预览里加行筛选。
   工具条放在统计卡**上方**：先决定"看哪些行"，再看"共多少行"——
   顺序反过来会让人先读到一个马上要变小的数。 */
.xp-tool{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:10px 0 0}
.xp-tool .btn.on{border-color:var(--brand);color:var(--brand-ink);background:var(--brand-soft)}
.xp-kw{flex:1 1 180px;min-width:120px;height:30px;padding:0 10px;
  border:1px solid var(--line);border-radius:8px;background:var(--panel);
  font-size:var(--fs-sm);color:var(--ink)}
.xp-kw:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-soft)}
.xp-sel{height:30px;max-width:170px;padding:0 6px;border:1px solid var(--line);
  border-radius:8px;background:var(--panel);font-size:var(--fs-sm);color:var(--ink)}
.xp-colbox{margin-top:10px;padding:10px 12px;border:1px solid var(--line);
  border-radius:10px;background:var(--panel-2)}
.xp-colhd{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:8px}
.xp-colhd .sub{font-size:var(--fs-xs);color:var(--ink3)}
.xp-colgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(132px,1fr));gap:6px;
  max-height:34vh;overflow:auto}
.xp-colitem{display:flex;align-items:center;gap:6px;padding:4px 8px;border:1px solid var(--line);
  border-radius:7px;background:var(--panel);font-size:var(--fs-xs);cursor:pointer}
.xp-colitem input{width:14px;height:14px;accent-color:var(--brand);margin:0}
.xp-colitem.off{color:var(--ink3);background:transparent;text-decoration:line-through}
.xp-colbar{display:flex;gap:8px;margin-top:8px}
.xp-stat{display:flex;gap:10px;flex-wrap:wrap;margin:10px 0 12px}
.xp-k{display:flex;flex-direction:column;gap:1px;min-width:104px;padding:8px 12px;
  border:1px solid var(--line);border-radius:10px;background:var(--panel-2)}
.xp-k .l{font-size:var(--fs-xs);color:var(--ink3)}
.xp-k .v{font-size:calc(17px * var(--font-scale));font-weight:700;font-variant-numeric:tabular-nums}
.xp-k .f{font-size:var(--fs-xs);color:var(--ink3);max-width:280px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.xp-warn{flex:1 1 100%;padding:7px 11px;border-radius:9px;background:var(--warn-soft);
  color:var(--warn-ink);font-size:var(--fs-xs);line-height:1.6}
.xp-tabs{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:8px}
.xp-tab{display:flex;align-items:center;gap:6px;padding:4px 10px;border:1px solid var(--line);
  border-radius:999px;font-size:var(--fs-sm);cursor:pointer;color:var(--ink2);background:var(--panel)}
.xp-tab .c{font-size:var(--fs-xs);color:var(--ink3);font-variant-numeric:tabular-nums}
.xp-tab.on{border-color:var(--brand);color:var(--brand-ink);background:var(--brand-soft)}
.xp-tab.on .c{color:var(--brand-ink)}
.xp-wrap{max-height:min(46vh,380px);overflow:auto;border:1px solid var(--line);border-radius:10px}
.xp-tbl{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--fs-sm)}
.xp-tbl thead th{position:sticky;top:0;z-index:2;background:var(--panel-2);text-align:left;
  font-weight:600;font-size:var(--fs-xs);color:var(--ink2);padding:7px 9px;
  border-bottom:1px solid var(--line);white-space:nowrap}
.xp-tbl tbody td{padding:5px 9px;border-bottom:1px solid var(--line-2);vertical-align:top;
  min-width:64px;max-width:320px;line-height:1.6;outline:none}
.xp-tbl tbody td:focus{background:var(--brand-soft);box-shadow:inset 0 0 0 1px var(--brand)}
.xp-tbl tbody td.num{text-align:right;font-variant-numeric:tabular-nums}
.xp-tbl tbody tr.off td{color:var(--ink3);background:var(--panel-2)}
/* 筛选后一行都不命中：给一句"怎么恢复"，不要留一张空表让人以为数据没了 */
.xp-tbl tbody td.xp-empty{text-align:center;color:var(--ink3);padding:22px 10px;font-size:var(--fs-sm)}
.xp-tbl tbody tr.off td:first-child{opacity:1}
.xp-tbl .xp-ck{width:34px;min-width:34px;max-width:34px;text-align:center}
.xp-tbl .xp-ck input{width:15px;height:15px;accent-color:var(--brand)}
.xp-note{margin-top:9px;font-size:var(--fs-xs);color:var(--ink3);line-height:1.7}

/* ============================================================
   云文档回传预览（第 104 轮 · 用户：试算/回传细化 + 自选列 + 预览界面）
   ------------------------------------------------------------
   ★ 左栏列勾选固定 250px、右栏吃满剩余：列名最长「母材炉批号」5 字，
     再窄就换行；再宽差异表就没地方放「旧值 → 新值」了。
   ★ 差异行用 grid 而不是 flex：部位长短不一时，格子区要靠右对齐才能竖着扫。
     用 flex 的话每行格子起点都不一样，看十行就花了。
   ============================================================ */
.lgp{display:flex;gap:14px;align-items:stretch;min-height:360px}
.lgp-wait{padding:26px 4px;color:var(--ink3);font-size:var(--fs-sm)}
.lgp-cols{flex:0 0 250px;display:flex;flex-direction:column;gap:1px;
  border:1px solid var(--line);border-radius:var(--radius-sm);padding:9px 8px 7px;
  background:var(--panel-2)}
/* ★ 左栏不自己滚：19 列一屏正好放得下，让它跟弹窗一起滚就行。
   自己滚会出现"左栏一根滚动条、弹窗一根滚动条"的双层滚动 ——
   鼠标在左栏滚不动整个人会以为卡住（第 104 轮视觉核对时踩过）。 */
.lgp-lhd{display:flex;flex-direction:column;gap:2px;padding:0 3px 5px;border-bottom:1px solid var(--line-2)}
.lgp-lhd b{font-size:var(--fs-sm);color:var(--ink)}
.lgp-lhd .hint{font-size:var(--fs-xs);line-height:1.5}
.lgp-grp{display:flex;align-items:center;gap:6px;margin:7px 0 2px;padding:0 3px;
  font-size:var(--fs-xs);font-weight:600;color:var(--ink3);letter-spacing:.04em}
.lgp-grp .tip{font-weight:400;color:var(--ink3);opacity:.85}
.lgp-col{display:flex;align-items:center;gap:7px;padding:3px 5px;border-radius:5px;
  font-size:var(--fs-sm);color:var(--ink2);cursor:pointer;line-height:1.4}
.lgp-col:hover{background:var(--panel)}
.lgp-col.on{color:var(--ink);background:var(--brand-soft)}
.lgp-col.lock{cursor:default;opacity:.85}
.lgp-col input{width:14px;height:14px;margin:0;accent-color:var(--brand);flex:0 0 auto}
.lgp-col .nm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lgp-col .lk{font-size:calc(10px * var(--font-scale));padding:0 4px;border-radius:3px;
  background:var(--surface-3);color:var(--ink3)}
.lgp-lfoot{display:flex;gap:4px;margin-top:8px;padding-top:7px;border-top:1px solid var(--line-2)}

.lgp-side{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px}
.lgp-cards{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.lgp-card{border:1px solid var(--line);border-radius:var(--radius-sm);padding:7px 10px;background:var(--panel)}
.lgp-card em{display:block;font-style:normal;font-size:var(--fs-xs);color:var(--ink3)}
.lgp-card .num{display:flex;align-items:baseline;gap:3px}
.lgp-card b{font-size:calc(21px * var(--font-scale));font-weight:700;font-variant-numeric:tabular-nums;color:var(--ink)}
.lgp-card i{font-style:normal;font-size:var(--fs-xs);color:var(--ink3)}
.lgp-card.main{border-color:var(--brand);background:var(--brand-soft)}
.lgp-card.main b,.lgp-card.main i,.lgp-card.main em{color:var(--brand-ink)}
.lgp-tip{font-size:var(--fs-xs);color:var(--ink3);line-height:1.7}

.lgp-list{flex:1;min-height:180px;max-height:min(52vh,420px);overflow:auto;
  border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--panel)}
.lgp-row{display:grid;grid-template-columns:20px 52px minmax(80px,150px) 1fr;gap:8px;
  align-items:start;padding:5px 9px;border-bottom:1px solid var(--line-2);font-size:var(--fs-sm)}
.lgp-row:last-child{border-bottom:0}
.lgp-row.off{opacity:.45;background:var(--panel-2)}
.lgp-row .ck{padding-top:1px}
.lgp-row .ck input{width:14px;height:14px;margin:0;accent-color:var(--brand)}
.lgp-row .pt{color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lgp-badge{display:inline-block;padding:1px 6px;border-radius:3px;font-size:calc(10.5px * var(--font-scale));
  font-weight:600;text-align:center;background:var(--surface-3);color:var(--ink2)}
.lgp-badge.add{background:var(--ok-soft);color:var(--ok-ink)}
.lgp-badge.adopt{background:var(--info-soft);color:var(--info-ink)}
.lgp-badge.update{background:var(--brand-soft);color:var(--brand-ink)}
.lgp-badge.same{background:var(--surface-3);color:var(--ink3)}
.lgp-badge.skip{background:var(--warn-soft);color:var(--warn-ink)}
.lgp-cells{display:flex;flex-wrap:wrap;gap:4px 6px;min-width:0}
.lgp-cell{display:inline-flex;align-items:center;gap:4px;padding:1px 6px;border-radius:4px;
  background:var(--panel-2);border:1px solid var(--line-2);font-size:var(--fs-xs);
  max-width:100%;overflow:hidden}
.lgp-cell i{font-style:normal;color:var(--ink3);white-space:nowrap}
.lgp-cell s{color:var(--ink3);text-decoration:line-through;max-width:110px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.lgp-cell .ar{color:var(--ink3)}
.lgp-cell b{color:var(--brand-ink);font-weight:600;max-width:130px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.lgp-note{flex:1;font-size:var(--fs-sm);color:var(--ink2);line-height:1.6;padding-right:12px}
.dlg-ft .lgp-note{min-width:0}
