/* 视觉基线：直接取自生产系统 app/static/index.html 的 <style> 块，原样复制、不做改动。
   招商系统只在其后追加极少量本系统专属样式（extra.css），保证跨系统视觉语言一致。
   重新同步：2026-10-17 21:15（.cd-btn:disabled 的 background 由硬编码 rgba(255,255,255,.06)
             改为 var(--panel2) 令牌；删除招商私加的 .cd-link 死样式 —— 生产没有、招商也无引用）。
   校验方式：本文件「头部注释之后」的内容与生产 <style> 块逐字节相同，md5 必须一致。
            当前基准 md5 = 3dfd118c222727f2080908b72e41c4b4（287,850 字符）。 */
/* ★ 2026-10-05（岩峰定·B 方案「现状 − 环」）：按钮的边框流光**全站撤掉** ⇒
   原来那两个只服务于它的前置件（顶层 @property + @keyframes）一并删除（全站已无引用）。
   要恢复环：把这两件加回**顶层**（@property 必须在顶层才能驱动角度变量的插值），
   再给对应档补一条 ::before，它的背景写成以该角度变量为起点的锥形渐变即可。 */
/* ============================================================================
   响应式断点登记（2026-10-03 全量核对，仅登记、**未改动任何媒体查询**）
   ----------------------------------------------------------------------------
   本文件真实的媒体查询宽度只有下面几个取值（不含元素级 max-width 属性，
   如 `.login-card{max-width:440px}` —— 那是元素宽度、不是断点，别数错）：

   · 标准三档（公司视觉规范，**新增响应式布局一律用这三档**）：
       900px  宽屏栅格降列（.dash-grid / .dbv-ov-grid 等容器级降列）
       820px  端型判断主断点（手机 ↔ 桌面；与 JS isMobile()、openDetail() 的
              matchMedia('(max-width:820px)') **三处同源**，改一处必须改三处）
       380px  极小屏微调（顶栏/字号/单列栅格）

   · 允许存在的内容级微调宽度（**不是端型判断**，勿并档、勿随手扩散）：
       600px  登录页 logo/品牌字号、流程卡表头列宽等内容级微调
       560px  交付记录时间线字段列宽等内容级微调
       980px  Agent 页「侧栏 + 主区」的**上下堆叠**阈值 —— 内容级：双栏需 ~980px 才不挤，
              低于此值侧栏改为顶部通栏（上限 230px）、任务表收为两列并隐表头。
              2026-10-16 Agent 页落地时登记。
      1100px  我的待办「左队列 + 右关注栏(322px)」的**降列**阈值 —— 内容级：双栏需 ~1100px 才不挤，
              低于此值关注栏改为**堆叠并 order:-1 提到队列之前**（它是最该先看到的）。
              2026-10-04「B 分组＋关注栏」落地时登记。
     四者系有意保留的内容级适配（详见文件内 L7045 附近注释原文与各自定义处），
     与「端型判断」无关，故与标准三档并存。

   ⚠ 规则：**新增媒体查询宽度必须显式决策** —— 要么并入上面三档之一，
     要么像 600/560 一样在此登记为「内容级微调」并说明用途。禁止出现未登记的裸宽度。
   ========================================================================== */
:root{
  /* ★ 2026-10-04（批 3）：底色 #0f1420 → #0a0e17。
     缘由：玻璃是"半透明白 + 模糊"，底色越亮、它与实色数据面（--panel）的差就越小，
     结果是顶栏/导航/详情栏"看着和卡片一样"，等于没有玻璃。压深一档后才立得住层次。 */
  --bg:#0a0e17;--panel:#1a2030;--panel2:#222a3d;
  --border:#2a3344;--border-strong:#3a465c;
  --text:#e6e9ef;--muted:#9aa4b2;
  --accent:#4f8cff;--accent-text:#5f97ff;--accent-soft:rgba(79,140,255,.14);
  --nav-active-bg:rgba(10,14,23,.92);   /* ★ 第94批 C1：侧栏选中项实底（压掉背后光斑染色；来源=考核系统同日修法） */
  --good:#3ecf8e;--warn:#f5a623;--bad:#ff5c5c;--chip:#2a3344;
  --focus-ring:0 0 0 3px rgba(79,140,255,.38);
  --shadow-1:0 1px 2px rgba(0,0,0,.35),0 6px 16px rgba(0,0,0,.28);
  --shadow-2:0 2px 6px rgba(0,0,0,.4),0 12px 30px rgba(0,0,0,.34);
  --accent-d:#3a73e0;--hair:rgba(255,255,255,.06);
  --bg-glow:radial-gradient(1200px 560px at 50% -8%,var(--accent-soft),transparent 62%);
  --sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;--sp-5:20px;
  --r-sm:6px;--r-md:8px;--r-lg:12px;--r-xl:18px;--r-pill:999px;
  --fs-xs:12px;--fs-sm:13px;--fs-md:14px;--fs-lg:16px;--fs-xl:18px;--fs-display:30px;
  /* ★ 2026-10-04（统一改造 · 批 1）：补齐缺失档位 —— 之前裸值在用的 4 / 24 没有令牌可依 */
  --r-xs:4px;--sp-6:24px;--fs-2xl:24px;
  /* ★ 统一改造：卡片/面板的**顶边发丝高光**颜色（深色是提亮线，浅色换暖白避免看不见） */
  --rim-card:rgba(255,255,255,.12);
  /* ★ 2026-10-04（统一改造 · 批 2）：语义色 soft 令牌 —— 原来这些色散落在 179 个硬编码里，
     同一个"危险底"有 .10/.14/.15/.16 四种写法，永远调不齐。 */
  --ok-soft:rgba(62,207,142,.15);--wa-soft:rgba(245,166,35,.15);--ba-soft:rgba(255,92,92,.15);
  /* ★ 统一改造：补齐**被引用却从未定义**的两个变量（引用处原本静默失效、看不出报错） */
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;
  --danger:var(--bad);
  --h-ctl:36px;--h-dense:30px;--h-btn:36px;--h-btn-sm:28px;
  --text-2:#c4c9d4;--req:#ff7b7b;--on-accent:#fff;
  /* ★ 2026-10-03：补上此前**只被引用、从未定义**的 `--hint`（曾用于 .item 序号 / 时间轴时间 /
     字段名等 8 处），否则那些声明整条失效、静默退化成继承色。语义 = **弱化的标签色**
     （比 --muted 再淡一档，仍与 --text-2「值」明确区分）。取值经 WCAG 实测 ≥4.5:1。 */
  --hint:#8b94a3;
  /* ★ 2026-10-04（L1 改造 · 批 3·视觉）：玻璃材质令牌 —— **只新增**，上面任何既有令牌一字未动。
     ultra→thin→reg→thick = "越厚越亮"，对应"越靠近用户"的层次；rim = 镜面高光边；aura = 背景光斑。 */
  --m-ultra:rgba(255,255,255,.040);
  --m-thin:rgba(255,255,255,.075);
  --m-reg:rgba(255,255,255,.105);
  --m-thick:rgba(255,255,255,.150);
  /* ★ 2026-10-06（岩峰报「浅色主题下上期进度条看不见、轨道也看不见」）：
     上面 `--m-ultra/thin/reg/thick` 这套令牌的语义是**玻璃态遮罩**（在页面背景上叠白造磨砂），
     浅色下它们是 44%~80% 的**白** —— 画在**白色卡片**上必然隐形。
     而「进度条轨道 / 上期条 / 条形图的空槽」这类**卡片内的图形**必须两主题都看得见
     ⇒ 单独一对令牌：深色取原 `--m-reg/--m-thick` **同值**（深色零变化），浅色改用**黑**的一点点。 */
  --track:rgba(255,255,255,.105);
  /* ★ 2026-10-06（岩峰）：**「上期」进度条的填充色** —— 沿用「品牌构成」环形那套紫
     （对标 `_BCOL[1]` = #8b7cf6），与「本期」的强调蓝成对区分。
     **两主题同值**（紫在深浅底上都看得见）⇒ 浅色块**不再覆写**这一条。 */
  --track-fill:#8b7cf6;
  --rim-line:rgba(255,255,255,.46);   /* 顶边 1px 镜面高光（两端渐隐） */
  --rim-side:rgba(255,255,255,.09);   /* 左右侧光：刻意很弱，太强会在圆角处连成描边 */
  --rim-bot:rgba(255,255,255,.06);
  /* ★ 2026-10-04（第二批·按钮材料化）：按钮专用的**材料层** —— 走 background-image，
     **不动 background-color** ⇒ 实心/柔底/中性/危险任何变体都自动继承同一条高光。 */
  /* ★ 2026-10-09（v5）：--btn-sheen / --btn-sheen-soft 两条"顶部渐隐高光"渐变令牌已删 ——
     按钮不再有材质叠光（规范：只有底色/描边/文字色三样），全站零引用。 */
  --edge:rgba(255,255,255,.17);
  --lift:rgba(0,0,0,.66);
  --gl-ink:rgba(255,255,255,.95);
  --gl-ink2:rgba(255,255,255,.72);
  --gl-ink3:rgba(255,255,255,.50);
  --grain:.038;
  --aura1:#4f8cff;--aura2:#a78bfa;--aura3:#ff5c5c;   /* 光斑：沿用本系统强调色相（蓝/紫/红），不换色 */
  --aura-a:.55;--aura-b:.45;--aura-c:.30;
}
/* ★ 2026-09-29（岩峰定）：关掉浏览器**原生点击高亮**（tap highlight）。
   由来：移动端点按钮后，原生高亮由浏览器画在**所有 DOM 之上**，弹层遮不住；且清除时机不可控 →
   点「请假登记」这类"弹新页面"的按钮时，会在弹层上**残留一块直角矩形**（原生高亮不跟随 border-radius）。
   故直接关掉；若要点击反馈，用 :active 自实现（画在元素内、时机可控、可跟随圆角）。 */
*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
/* ===== 浅色主题（覆盖令牌 + 少量组件覆盖；深色零改动） ===== */
html[data-theme="light"]{
  /* ★ 2026-10-04（批 3）：浅色底由 #fbfbfd → #e9eef7（带一点蓝灰）。
     缘由：玻璃是"半透明白 + 模糊"，在**近纯白**底上等于没有 —— 层次全糊平。
     换成带蓝灰的浅底后，白卡（--panel #fff）自然浮起，玻璃面也才有梯度可读。 */
  --bg:#e9eef7;--panel:#ffffff;--panel2:#f3f4f7;
  --border:#e6e8ee;--border-strong:#d4d9e2;
  --text:#16181d;--text-2:#454c59;--muted:#646a73;
  /* ★ 2026-10-03（WCAG 2.1 AA 实测修，脚本按相对亮度公式实算，非目测）：
     浅色主题下有 5 个文字色令牌对页面底色**未过 4.5:1**，逐一对齐 —— 改前→改后（对 #fff / 对 --panel2）：
       --muted #787d87 4.13/3.76 → #646a73 5.45/4.96
       --good  #1d9e75 3.39/3.08 → #157a58 5.31/4.83
       --warn  #c07d12 3.40/3.09 → #96600a 5.28/4.80
       --bad   #e24b4a 3.93/3.58 → #c2352f 5.46/4.97
       --req   #d8453f 4.34/3.94 → #c93a34 5.07/4.61
     色相保持不变（红仍是红、绿仍是绿），只压暗以达标。其余令牌（--text / --text-2 /
     --accent / --accent-text）实测已过 AA，**未动**；暗色主题令牌零改动。
     ★ 2026-10-11（岩峰定·「这些颜色亮度提高，现在看上去感觉颜色不好看」）：
     `--warn` **回退 #c07d12**（= 压暗前那一版的确切值）—— 对比度放宽回 3.40/3.09，
     属**主观审美取舍**（其余 4 个令牌仍保持达标值；深色主题零改动）。 */
  --hint:#696e77;                            /* 弱化标签色：比 --muted 再淡一档，仍 AA（对 #fff 5.13 / 对 --panel2 4.66） */
  --accent:#185fa5;--accent-text:#185fa5;--accent-soft:rgba(24,95,165,.10);--accent-d:#134b85;
  --good:#157a58;--warn:#c07d12;--bad:#c2352f;--chip:#eef0f4;
  --focus-ring:0 0 0 3px rgba(24,95,165,.30);--rim-card:rgba(255,255,255,.9);
  --shadow-1:0 1px 2px rgba(16,24,40,.05),0 8px 22px rgba(16,24,40,.05);
  --shadow-2:0 2px 8px rgba(16,24,40,.06),0 16px 36px rgba(16,24,40,.08);
  --hair:rgba(16,24,40,.06);--bg-glow:none;--on-accent:#ffffff;--req:#c93a34;
  /* ★ 2026-10-04（L1 改造 · 批 3·视觉）：浅色材质令牌（与深色同构，白色系不透明/半透明梯度） */
  --m-ultra:rgba(255,255,255,.44);
  --m-thin:rgba(255,255,255,.60);
  --m-reg:rgba(255,255,255,.74);
  --m-thick:rgba(255,255,255,.80);
  /* 卡片内的「轨道 / 空槽 / 上期条」——浅色必须用**黑**的一点点才看得见（白在这没用，见深色块注释）。 */
  --track:rgba(16,24,40,.08);
  /* --track-fill 两主题同值（紫）—— 见深色块注释，这里刻意不覆写。 */
  --rim-line:rgba(255,255,255,.85);
  --rim-side:rgba(255,255,255,.42);
  --rim-bot:rgba(255,255,255,.26);
  /* 浅色：按钮底色本身就浅，高光要更实一点才看得出来；柔底档用近实白 */
  /* ★ 2026-10-09（v5）：浅色侧的两条 --btn-sheen* 令牌一并删除（同步深色，见上） */
  /* ★ 2026-10-07（上线前审计 A1）：浅色下 `--edge` 原来是**近实白** `rgba(255,255,255,.85)`，
     而它全站被当**描边**用（49 处 `border*:1px solid var(--edge)`，只有 2 处不是）——
     画在 `--panel:#ffffff` 的白卡片上 **≈1:1 对比 ⇒ 边界完全隐形**
     （违反 WCAG 1.4.11 非文本对比 ≥3:1）。真机实测 10 个页面每页 6~15 个元素中招
     （待办统计条 / 录单各面板与输入框 / 订单查询工具条 / 看板 KPI / 系统设置左右栏 /
     权限页卡片 / 个人设置卡 / 数据监控块…）。
     ⇒ 浅色下让 `--edge` **归到 `--border`**（这一步同时修好全部 49 处，且**深色主题零改动**）。
     ⚠ 顶边高光用的是 `--rim-card` / `--rim-line` / `--rim-side`（另一组白令牌，**不受影响**），
       所以"卡片顶部那道细高光线"照旧。 */
  --edge:var(--border);
  --lift:rgba(24,34,60,.16);
  --gl-ink:#0d1420;
  --gl-ink2:rgba(13,20,32,.68);
  --gl-ink3:rgba(13,20,32,.46);
  --grain:.022;
  --aura1:#7dd3fc;--aura2:#c4b5fd;--aura3:#fda4af;
  --aura-a:.55;--aura-b:.46;--aura-c:.30;
}
html[data-theme="light"] body{color-scheme:light;background-image:none}
html[data-theme="light"] header{background-color:var(--m-thin);border-bottom-color:var(--edge);box-shadow:0 12px 32px -22px var(--lift)}
html[data-theme="light"] nav{background-color:var(--m-thin)}
html[data-theme="light"] nav button{color:var(--muted);border-bottom:none}
html[data-theme="light"] nav button:hover{color:var(--text-2)}
html[data-theme="light"] nav button.active{color:var(--accent);font-weight:600;background:#fff;box-shadow:0 1px 3px rgba(16,24,40,.14),0 1px 1px rgba(16,24,40,.08);border-radius:var(--r-md);border-bottom-color:transparent;border-top-color:transparent;margin:4px 0}
html[data-theme="light"] .login-card{background:#fff;border-color:var(--border);box-shadow:var(--shadow-2)}
html[data-theme="light"] input[type=date]::-webkit-calendar-picker-indicator{filter:none}
html[data-theme="light"] .dash-icon{background:var(--panel2)}
html[data-theme="light"] .app-logos img,html[data-theme="light"] .login-logos img{filter:drop-shadow(0 1px 2px rgba(16,24,40,.12))}
html[data-theme="light"] .app-logos img.logo-white,html[data-theme="light"] .login-logos img.logo-white{display:none}
html:not([data-theme="light"]) .app-logos img.logo-black,html:not([data-theme="light"]) .login-logos img.logo-black{display:none}
/* ★ 2026-10-10（岩峰定·甲）：原「浅色主题下把登录按钮改成实心强调蓝 + 投影」的这条覆盖
   **已删除** —— 它让同一个按钮在浅色/深色下走两套来源（浅色＝野生特例，深色＝v5 主操作档）。
   现在两主题都走 v5 主操作令牌（`.btn-primary`）：浅色＝浅蓝底+深蓝字，深色＝深蓝底+亮蓝字。 */
html[data-theme="light"] .login-logos .logo-sep,html[data-theme="light"] .app-logos .logo-sep{background:linear-gradient(180deg,rgba(16,18,24,.12),rgba(16,18,24,.55) 50%,rgba(16,18,24,.12));box-shadow:0 0 1px rgba(16,18,24,.18);filter:drop-shadow(0 1px 1px rgba(16,18,24,.12))}
@media (max-width:820px){
  html[data-theme="light"] nav{background-color:var(--m-thick);box-shadow:0 -8px 24px -14px var(--lift)}
  html[data-theme="light"] nav button.active{background:var(--accent-soft);margin:4px 0}
}
/* 设置页 */
/* 卡片内小节标题（2026-09-12 照抄考核系统）：左侧 3px 强调色竖条 + 文字，与页面级 .section-title 同一形态。
   ⚠ 上间距必须为 0：卡片自身 padding 已提供上留白，再加 margin-top 会多出一截空白
     （.section-title 在卡片**外面**才用 var(--sp-3) 做上间距）。
   当前仅「个人设置」页使用；生产其他页面的卡片内标题暂未改造。 */
.card h2{font-size:var(--fs-md);font-weight:600;color:var(--text);padding-left:9px;border-left:3px solid var(--accent);margin:0 0 var(--sp-2)}
/* 「标题式标签 + 值同行」行（登录账号 / 请假登记）★ 2026-10-16 晚（岩峰定「个人设置参考考核系统
   **一模一样照抄**」）：改用考核同款实现 —— `.set-row`（flex + baseline）+ `.set-label.set-label-bar`
   （span 带与 .card h2 同一条 3px 蓝竖条）。弃用旧 `.set-row-h2`（h2 套 flex 行、要靠内联 margin
   兜底）—— 两实现外观逐像素一致，考核版更干净、两系统代码可逐行比对。 */
.set-row{display:flex;align-items:baseline;gap:10px;margin-bottom:14px;flex-wrap:wrap}
.set-label{font-size:var(--fs-md);font-weight:600;color:var(--text)}
.set-label-bar{border-left:3px solid var(--accent);padding-left:9px}
.set-hint{font-size:var(--fs-xs);color:var(--muted)}
.theme-opts{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}
.theme-opt{display:flex;flex-direction:column;gap:var(--sp-1);align-items:flex-start;text-align:left;padding:14px;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-md);cursor:pointer;font-family:inherit;color:var(--text);transition:border-color .15s,background .15s,box-shadow .15s}
.theme-opt:hover{border-color:var(--border-strong)}
.theme-opt .to-name{font-size:var(--fs-md);font-weight:600}
.theme-opt .to-desc{font-size:var(--fs-xs);color:var(--muted);line-height:1.5}
.theme-opt.sel{border-color:var(--accent);background:var(--accent-soft);box-shadow:0 0 0 1px var(--accent)}
.set-foot{margin-top:14px;font-size:var(--fs-xs);color:var(--muted)}
@media (max-width:600px){.theme-opts{grid-template-columns:1fr}}
/* ★ 2026-10-07（岩峰：「手机端每次点导航，底部导航栏的 UI 就跳一下」）：
   给根元素加 `overflow-x:clip` —— **挡住"过渡期的横向溢出把布局视口撑宽"**。
   病因（真机时序实测）：切页那一两帧里，新页的骨架/筛选条会短暂横向溢出
   （`#view-dashboard` 右缘 398 > 视口 390）⇒ 手机端浏览器把**布局视口从 390 撑到 398**
   ⇒ `nav{position:fixed;left:0;right:0}` 跟着变成 398 宽、top 从 794 掉到 812 ⇒ 看着"跳一下"，
   80ms 后内容收进屏幕才回稳。实测加这一条后 `innerW / navW / navT` **全程恒定 390/390/794**。
   ⚠ 用 `clip` 而不是 `hidden`：`clip` 不影响另一轴的 `visible`（纵向滚动照旧），
     也不会把根元素变成滚动容器；各区自己的横向滚动（如表格）都在**内层容器**里，不受影响。 */
html{overflow-x:clip}
body{background:var(--bg);background-image:var(--bg-glow);background-attachment:fixed;color:var(--text);color-scheme:dark;font-family:"PingFang SC","Microsoft YaHei","Segoe UI",system-ui,-apple-system,sans-serif;font-size:var(--fs-md);line-height:1.6;-webkit-font-smoothing:antialiased}
.hidden{display:none!important}
.app-topbar{position:sticky;top:0;z-index:50}
header{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-4) var(--sp-5);border-bottom:1px solid var(--edge);background-color:var(--m-thin);background-image:linear-gradient(90deg,transparent,var(--rim-line) 12%,var(--rim-line) 88%,transparent);background-size:100% 1px;background-position:0 0;background-repeat:no-repeat;-webkit-backdrop-filter:blur(18px) saturate(1.8);backdrop-filter:blur(18px) saturate(1.8);box-shadow:0 12px 32px -20px var(--lift)}
header h1{font-size:var(--fs-xl);margin:0;font-weight:600;letter-spacing:.4px;white-space:nowrap;flex:none}
/* ★ 2026-10-02（岩峰定）：窄屏顶栏「生产系统」被挤成两行 → 标题 nowrap 永不折行 + 折行检查器：
   header 横向放不下（= 原本会折成两行）→ 给标题挂 .h1-hide 整块隐藏（宁可不显示、绝不两行）。
   检查器 fitHeaderTitle 带**迟滞**：藏起后只有 header 变宽才尝试放回，防"显示→量→藏"振荡。 */
header h1.h1-hide{display:none}
header .user{font-size:var(--fs-sm);color:var(--muted)}
.app-logos{display:flex;align-items:center;gap:var(--sp-3);margin-right:4px;flex-shrink:0}
.app-logos img{height:28px;width:auto;object-fit:contain;filter:drop-shadow(0 1px 2px rgba(0,0,0,.35))}
.app-logos img.logo-weeduo{height:24px;transform:translateY(-1px)}
.app-logos .logo-sep{width:1px;height:22px;background:linear-gradient(180deg,transparent,rgba(255,255,255,.35),transparent);flex-shrink:0}
.pill{display:inline-flex;align-items:center;justify-content:center;line-height:1.2;padding:var(--sp-1) var(--sp-3);border-radius:var(--r-pill);font-size:var(--fs-xs);background:var(--chip);color:var(--muted);white-space:nowrap}
.pill.ok{background:var(--ok-soft);color:var(--good)}
.pill.warn{background:var(--wa-soft);color:var(--warn)}
.pill.na{background:rgba(154,164,178,.12);color:var(--muted)}
.pill.bad{background:var(--ba-soft);color:var(--bad)}
#cloudBadge{margin-left:auto;flex:none}   /* ★ flex:none：徽章也不许被压缩（否则窄屏文字被裁切出血）——窄屏空间不足时由折行检查器藏标题 */
/* ===== 云断开阻断遮罩：z-index 9999 压过顶栏50/弹窗60/日期层200，物理阻断一切操作 ===== */
#cloudDown{position:fixed;inset:0;z-index:9999;background:rgba(8,11,18,.88);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);display:flex;align-items:center;justify-content:center;padding:var(--sp-4)}
#cloudDown.hidden{display:none!important}
.cd-card{width:100%;max-width:360px;background:var(--panel);border:1px solid var(--border-strong);border-radius:var(--r-lg);box-shadow:var(--shadow-2);padding:var(--sp-5) var(--sp-4);text-align:center}
.cd-ico{width:52px;height:52px;margin:0 auto var(--sp-3);border-radius:50%;display:flex;align-items:center;justify-content:center}
.cd-ico.down{background:var(--ba-soft);color:var(--bad)}
.cd-ico.up{background:var(--ok-soft);color:var(--good)}
.cd-ico svg{width:26px;height:26px}
.cd-title{font-size:var(--fs-lg);font-weight:600;margin-bottom:var(--sp-2)}
.cd-body{font-size:var(--fs-sm);color:var(--text-2);line-height:1.75;margin-bottom:var(--sp-5)}
.cd-body b{color:var(--warn)}
.cd-btn{width:100%;min-height:44px;padding:var(--sp-3) var(--sp-4);border:1px solid transparent;border-radius:var(--r-md);font-size:var(--fs-md);font-weight:600;font-family:inherit;cursor:pointer;background:var(--accent);color:var(--on-accent);display:flex;align-items:center;justify-content:center;gap:var(--sp-2);line-height:1.4}
.cd-btn:active{filter:brightness(.92);transform:translateY(1px)}
.cd-btn:disabled{background:var(--panel2);border-color:var(--border);color:var(--muted);cursor:not-allowed;transform:none;filter:none}
.cd-sub{font-size:var(--fs-xs);color:var(--muted);margin-top:10px}
/* 网络降级提示条：非阻断，置于底部导航之上，波动网络时显示，不挡操作 */
.net-banner{position:fixed;left:8px;right:8px;bottom:60px;z-index:9000;background:var(--wa-soft);color:#241a06;font-size:var(--fs-xs);line-height:1.5;padding:9px var(--sp-3);border-radius:var(--r-md);text-align:center;box-shadow:var(--shadow-2)}
.net-banner.hidden{display:none}
/* 录单底部次要操作行（清空 / 存为草稿 / 草稿箱）：手机三按钮等宽一行；桌面与「提交订单」同排、居右 */
.order-actions{display:flex;flex-direction:column;gap:var(--sp-2);margin-top:8px}
.order-actions .btn-block{width:100%;margin-top:0}
.order-actions-sub{display:flex;gap:8px}
.order-actions-sub .btn{flex:1;min-width:0}
/* 草稿箱弹层：每条只有「客户名主行 + 一行摘要 + 删除」，不展示草稿全部内容 */
.draft-list{display:flex;flex-direction:column;gap:var(--sp-2);margin:4px 0 2px}
.draft-row{display:flex;align-items:center;gap:var(--sp-2);background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-md);padding:8px 10px}
.draft-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--sp-1);text-align:left;background:none;border:none;color:var(--text);font-family:inherit;cursor:pointer;padding:2px}
.draft-main:hover .draft-cust{color:var(--accent)}
.draft-cust{font-size:var(--fs-md);font-weight:600;color:var(--text);display:flex;align-items:center;flex-wrap:wrap;word-break:break-word}
.draft-sum{font-size:var(--fs-xs);color:var(--muted);line-height:1.5;white-space:normal;overflow-wrap:anywhere}
.draft-del{flex:0 0 auto;background:none;border:1px solid var(--border);border-radius:var(--r-sm);color:var(--bad);font-family:inherit;font-size:var(--fs-xs);padding:var(--sp-1) var(--sp-3);cursor:pointer}
.draft-del:hover{background:var(--ba-soft);border-color:var(--bad)}
.draft-badge{margin-left:6px;font-size:var(--fs-xs);padding:1px var(--sp-2);border-radius:var(--r-pill);background:var(--wa-soft);color:var(--warn);vertical-align:middle;font-weight:400}
.draft-foot{display:flex;justify-content:flex-end;margin-top:10px}
.draft-clear-all{background:none;border:none;color:var(--muted);font-family:inherit;font-size:var(--fs-xs);cursor:pointer;text-decoration:underline;padding:4px}
.draft-clear-all:hover{color:var(--bad)}
@media (min-width:821px){
  .order-actions{flex-direction:row;align-items:stretch}
  .order-actions .btn-block{flex:1 1 auto;width:auto;margin-top:0}
  .order-actions-sub{flex:0 0 auto}
  .order-actions-sub .btn{flex:0 0 auto;padding:0 var(--sp-4)}
}
/* 明细「按数量」输入行（2026-09-11 按数量部分流转）：缩进对齐复选框，视觉上挂在所属明细下 */
.qty-row{display:flex;align-items:center;gap:var(--sp-2);margin:var(--sp-2) 0 2px var(--sp-6);font-size:var(--fs-xs);color:var(--muted);flex-wrap:wrap}
.qty-row input{width:92px;padding:var(--sp-2) var(--sp-2);border:1px solid var(--border);border-radius:var(--r-sm);background:var(--panel2);color:var(--text);font-family:inherit;font-size:var(--fs-md)}
.qty-row input:focus{outline:none;border-color:var(--accent)}
.qty-unit{white-space:nowrap}
/* 工序交付字段（2026-09-21）：交付弹层里**每条明细一组输入框**，字段清单来自
   「系统设置 → 交付设置」。某工序没配字段 → 整块不出现（出厂就是空的）。
   auto-fit 两列自适应：字段少时不占宽，字段多时自动换行。 */
.df-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));gap:var(--sp-2);margin:6px 0 2px 24px}
.df-item{display:flex;flex-direction:column;gap:var(--sp-1);font-size:var(--fs-xs);color:var(--muted);min-width:0}
.df-item .rq{color:var(--req)}
.df-inp{width:100%;padding:var(--sp-2) var(--sp-2);border:1px solid var(--border);border-radius:var(--r-sm);background:var(--panel2);color:var(--text);font-family:inherit;font-size:var(--fs-sm);box-sizing:border-box}
.df-inp:focus{outline:none;border-color:var(--accent)}
/* ★ 2026-09-22：控件类型加「上传附件」—— 交付弹层里这个框就是"选择文件"。
   原生 file 控件各端长相不一，这里压成与其它输入框同一行高、同一圆角；
   ::file-selector-button 让"选择文件"按钮与本项目按钮同款（Chrome/Edge/Safari 都支持）。 */
.df-file{width:100%;padding:var(--sp-1) var(--sp-2);border:1px dashed var(--border);border-radius:var(--r-sm);background:var(--panel2);color:var(--text);font-family:inherit;font-size:var(--fs-xs);box-sizing:border-box}
.df-file:focus{outline:none;border-color:var(--accent)}
.df-file::file-selector-button{margin-right:8px;padding:var(--sp-1) var(--sp-3);border:1px solid var(--border);border-radius:var(--r-sm);background:var(--panel);color:var(--text);font-family:inherit;font-size:var(--fs-xs);cursor:pointer}
.df-file::file-selector-button:hover{border-color:var(--accent);color:var(--accent)}
.df-file-hint{font-size:var(--fs-xs);color:var(--muted)}
/* 附件字段独占一行：否则在窄列里原生 file 控件自带的"未选择文件"会被截断成"未…件"（手机端实拍发现） */
.df-item.df-item-file{grid-column:1/-1}
/* （2026-10-06 删除 `.df-echo{color:var(--muted)}` —— 它只服务已退役的 `_fieldEcho`） */
/* ★ 2026-10-03（岩峰报的 BUG 修复）：「修正字段」弹层里的**附件只读行** ——
   附件字段不在此修改（它的值是上传凭证 token，手改一下下载链接就废了），只显示上传时的文件名。 */
.fx-ro{color:var(--text-2);word-break:break-all}
.fx-ro-hint{color:var(--muted);font-size:var(--fs-xs);margin-left:6px}
/* ★ 2026-10-03（岩峰定）：明细卡附件字段的「下载」按钮 = **全站唯一下载口**（渲染见 `_fvVal(v,true)`）。
   小号描边按钮，与字段值同基线、不撑高行；无 `op.attach_download` 权限时**整个按钮不渲染**。 */
.df-dlbtn{display:inline-block;margin-left:8px;padding:0 var(--sp-2);font-size:var(--fs-xs);line-height:20px;
  border:1px solid var(--accent);border-radius:var(--r-sm);color:var(--accent);text-decoration:none;
  vertical-align:middle;white-space:nowrap}
.df-dlbtn:hover{background:var(--accent);color:#fff}
/* ★ 2026-09-22（P0-4）：手机端「更多」抽屉的桌面兜底 —— 只在 ≤820 块里改成 flex */
#moreNavMask{display:none}
nav{display:flex;gap:var(--sp-1);padding:0 var(--sp-5);border-bottom:1px solid var(--edge);background-color:var(--m-thin);-webkit-backdrop-filter:blur(18px) saturate(1.8);backdrop-filter:blur(18px) saturate(1.8);box-shadow:0 8px 24px -22px var(--lift);overflow-x:auto;scrollbar-width:none}
nav::-webkit-scrollbar{display:none}
nav button{position:relative;padding:var(--sp-3) var(--sp-4);border:none;border-bottom:2px solid transparent;background:none;font-size:var(--fs-md);color:var(--muted);cursor:pointer;font-family:inherit;white-space:nowrap;transition:color .15s,border-color .15s,background .15s}
nav button:hover{color:var(--text-2)}
nav button.active{color:var(--accent);font-weight:600;border-bottom-color:var(--accent);background:var(--accent-soft)}
/* 桌面/手机 导航标签响应式：桌面显长名，手机显短名 */
nav button .nav-m{display:inline}
nav button .nav-d{display:none}
/* ★ 2026-10-10（消息提醒）：导航「消息」上的未读红点。放在两个文案 span **之外** ——
   手机端 `.nav-m` 显示、桌面端 `.nav-d` 显示，红点两种形态都要看得见。
   纯色圆点、无光晕无动画（守全站扁平规范）。数字用 tabular-nums，多位数不抖。 */
/* ⚠ 字号必须 ≥12px —— 门禁 `_regress_uix_audit` 的「全站字号 ≥12px」是硬判据
   （第一版写了 10px，当场被判红）。16px 胶囊 + 12px 字，既合规又能容下"99+"。 */
/* ⚠⚠ 必须是**绝对定位**：16px 高的角标若留在文档流里，会把整个导航条撑高 ⇒
   桌面端"整页不滚"的框架当场被破（实测文档高比视口多 24px）。
   绝对定位后**不占布局高度**，导航高度与不加角标时逐像素一致。
   ⚠ 同时字号必须 ≥12px（门禁 `_regress_uix_audit` 的硬判据，第一版写 10px 被判红）。
   ★ 2026-10-11（岩峰定）：「不要在右上角冒红数字，直接右边冒」——
   桌面端改为**右端垂直居中**（原 top:3px 右上角）；手机底栏按钮窄（~65px），
   居中会顶到文字，保持原「右上角」形态（见 820 媒体块内覆写）。 */
nav button .nav-dot{position:absolute;top:50%;right:3px;transform:translateY(-50%);min-width:16px;height:16px;padding:0 4px;
  box-sizing:border-box;border-radius:8px;background:var(--bad);color:var(--on-accent);
  font-size:12px;line-height:16px;font-variant-numeric:tabular-nums;text-align:center}
/* ── 消息页（2026-10-10）：消息条一律**不截断**（守全站「文字永不截断」铁律）── */
.nt-bar{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border)}
.nt-sum{flex:1;font-size:var(--fs-md);color:var(--text)}
.nt-list{display:flex;flex-direction:column;gap:8px;padding:var(--sp-3) var(--sp-4)}
.nt-item{display:flex;gap:10px;padding:10px 12px;background:var(--panel2);border:1px solid var(--border);
  border-radius:var(--r-md);cursor:pointer}
.nt-item:hover{background:var(--panel)}
.nt-item.unread{border-left:3px solid var(--accent)}
.nt-item.read .nt-dot{background:var(--muted);opacity:.35}
.nt-dot{flex:0 0 auto;width:7px;height:7px;border-radius:50%;background:var(--accent);margin-top:6px}
.nt-b{flex:1;min-width:0}
.nt-t{display:block;font-size:var(--fs-sm);color:var(--text);line-height:1.5;word-break:break-word}
.nt-s{display:block;font-size:var(--fs-xs);color:var(--muted);line-height:1.5;margin-top:2px;word-break:break-word}
/* ★ 第 85 批（岩峰拍板·需求3）：消息页改**电脑左右两栏（左未读 / 右已读）** ——
   分区标题带数量；未读为空显示「无未读消息」占位（分区不隐藏）。
   · 桌面：两栏等分（grid 1fr 1fr），各自内部纵向排消息条；
   · 手机（≤820px）：上下堆叠（grid-template-columns:1fr）—— 见下方媒体查询。 */
.nt-secs{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4);padding:var(--sp-3) var(--sp-4)}
.nt-sec-wrap{display:flex;flex-direction:column;gap:8px;min-width:0}
.nt-sec{display:flex;align-items:center;gap:var(--sp-2);padding:6px 2px;border-bottom:1px solid var(--border)}
.nt-sec-t{font-size:var(--fs-sm);font-weight:600;color:var(--text)}
.nt-sec-n{min-width:20px;height:18px;padding:0 6px;box-sizing:border-box;border-radius:9px;background:var(--chip);color:var(--muted);
  font-size:var(--fs-xs);line-height:18px;text-align:center;font-variant-numeric:tabular-nums}
.nt-sec-unread .nt-sec-t{color:var(--accent)}
.nt-sec-empty{padding:10px 12px;font-size:var(--fs-sm);color:var(--muted)}
/* ★ 第 85 批（岩峰拍板·需求3）：手机端（≤820px）两栏改**上下堆叠**（未读在上 / 已读在下）。 */
@media (max-width:820px){.nt-secs{grid-template-columns:1fr}}
/* 设置页「消息提醒」（★ 2026-10-15 布局统一·第三版 岩峰定）：
   四列定宽 grid（事件名 120px / 下拉 1fr / 站内 96px / 企微 96px）——所有行严格同列；
   事件名"首字对齐、尾字对齐、中间留空"＝**逐字 span + flex space-between**（JS 侧渲染），
   不再用 text-align-last:justify（在 nowrap/overflow 组合下有折行/截字的引擎边角行为）；
   「提醒谁」下拉缺失的行（c3 别名）渲染**空占位 div** 保持列位。
   ⚠ 必须用 `.sys-list .nt-row` 提权：通用 `.sys-row`（文件下部、同权重且后定义）
     的 display:flex/gap/padding 会把这里的 grid 静默盖掉 —— 2026-10-15 真机测量实锤。 */
.sys-list .nt-row{display:grid;grid-template-columns:120px minmax(0,1fr) 96px 96px;align-items:center;gap:14px;padding-right:24px}
.nt-row .nt-name{display:flex;justify-content:space-between;min-width:0;font-size:var(--fs-sm);color:var(--text);white-space:nowrap}
.nt-row .rg{display:inline-flex;align-items:center;gap:6px}
.nt-row .rg .sys-lab{width:auto!important;text-align:left!important;flex:0 0 auto}
/* ★ 第 90 批（岩峰定·需求1）：消息设置行「提醒谁」下拉（颜色**只走主题变量**，浅色/深色都对）。 */
.nt-row .nt-recip{width:100%;height:var(--h-dense);background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-sm);color:var(--text);font-family:inherit;font-size:var(--fs-sm);padding:0 var(--sp-2);min-width:0}
.nt-row .nt-recip:focus{outline:none;border-color:var(--accent)}
/* ★ 2026-10-15（岩峰定·指定人员）：下拉 +「选人…」按钮并排；弹层多选列表 */
.nt-recip-wrap{display:flex;gap:6px;align-items:center;min-width:0}
.nt-recip-wrap .nt-recip{flex:1 1 auto;min-width:0}
.nt-pick{flex:0 0 auto;white-space:nowrap}
.nt-pick-list{max-height:46vh;overflow-y:auto;display:flex;flex-direction:column;gap:2px;padding:2px 0}
.nt-pick-row{display:flex;align-items:center;gap:9px;padding:7px 10px;border-radius:9px;cursor:pointer}
.nt-pick-row:hover{background:var(--m-ultra)}
.nt-pick-row input{width:auto}
.nt-pick-row .np-n{font-weight:600}
.nt-pick-row .np-r{color:var(--hint);font-size:var(--fs-xs);margin-left:auto}
@media (min-width:821px){
  nav button .nav-m{display:none}
  nav button .nav-d{display:inline}
}
.filter-toggle{display:none;align-items:center;justify-content:center;gap:var(--sp-2);width:100%;min-height:44px;padding:0 var(--sp-3);background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-md);color:var(--text-2);font-size:var(--fs-md);cursor:pointer;font-family:inherit}
.filter-toggle:hover{border-color:var(--border-strong)}
.filter-badge{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 var(--sp-2);border-radius:var(--r-pill);background:var(--accent);color:var(--on-accent);font-size:var(--fs-xs);font-weight:600}
.filter-actions{display:flex;gap:var(--sp-2);align-items:center;flex-wrap:wrap}
/* ★ 2026-10-11 删除留档：`.kv-grid` / `.card-due`（旧看板卡的交期行，唯一使用者 = 已删的
   `bcardHtml`）专属样式已清理，删除原因与判据见 :7075 区留档注释。 */
.item-fields{display:flex;gap:6px}
main{padding:var(--sp-3);max-width:1180px;margin:0 auto;width:100%}
.section-title,.sec-title{font-size:var(--fs-md);font-weight:600;margin:var(--sp-3) var(--sp-1) var(--sp-2);padding-left:9px;border-left:3px solid var(--accent);color:var(--text)}
.card{background:var(--panel);border:1px solid var(--border);border-top-color:var(--hair);box-shadow:var(--shadow-1);border-radius:var(--r-lg);padding:var(--sp-4);margin-bottom:var(--sp-3)}
.card .row1{display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;gap:var(--sp-2)}
.order-no{font-weight:600;font-size:var(--fs-lg);color:var(--text)}
.tag{display:inline-flex;align-items:center;justify-content:center;line-height:1.2;vertical-align:middle;font-size:var(--fs-xs);padding:var(--sp-1) 9px;border-radius:var(--r-pill);background:var(--chip);color:var(--text-2);margin-left:4px;white-space:nowrap}
/* 订单号行（.row1 待办卡 / .r1 看板卡与列表卡）里的标签：vertical-align:middle 是
   按"基线 + 半个 x-height"近似对齐的，实测比同行 26px 高的 .order-no 低 1.01px，
   四视图一致。统一上移 1px 补正（实测四视图同源，改一处即可全对齐）。 */
.r1 .tag,.row1 .tag{position:relative;top:-1px}
.tag.urgent{background:var(--bad);color:var(--on-accent);font-weight:600}   /* ★ 2026-10-04 岩峰定：加急全系统统一＝红实底 */
.tag.done{background:var(--ok-soft);color:var(--good)}
/* ★ 2026-10-12（岩峰报 A）：**已作废**标签的样式 —— 此前 `.tag.void` 在全站**被用了却没定义**
   （待办卡 `_todoVCard` / 现新增的订单查询表格行都在用），落到基类 `.tag` 的灰底灰字、
   与「类型/品牌」等中性标签**长得一模一样**，起不到"这单废了"的警示作用。
   现补一条（红系软底 + 红字，与 `.tag.done` 绿系对称）。
   颜色全走**主题令牌**（与 `.tag.done` / `.tag.urgent` 同一套做法，**无需**单独写 `[data-theme=light]` 覆写）：
   · 前景 `--bad`：深色 `#ff5c5c` / 浅色 `#c2352f`（浅色红对白底实测 AA）—— 真机实测：
     深色 `color:rgb(255,92,92)` / 浅色 `color:rgb(194,53,47)`，**两主题均换色正确、均可读**。
   · 底色 `--ba-soft` = `rgba(255,92,92,.15)`（`:root` 定义，深浅共用；15% 红透明底在白/深底上都成立）。
   · `font-weight:600` 与 `.tag.urgent`/`.tag.borrow` 一致，让"作废/加急/借调"三类强语义标签等重。 */
.tag.void{background:var(--ba-soft);color:var(--bad);font-weight:600}
/* ⚠ 2026-10-12（第 89 批·位置调整的连锁）：本类**当前零引用** —— 原唯一用法（`_todoVCard` 的
   `tags` 行 / 订单查询表格 `no` 列）已按岩峰「已作废不要显示在订单号后面，显示到交期的位置」
   统一挪到**交期位置**并改走 `.due.danger`（与同列「准时交付」等胶囊同族）。
   **保留定义**（不按"死代码"清）：它是 `.tag` 家族的语义成员（`.urgent`/`.done`/`.borrow` 均在用），
   语义上「作废」与「完成」对称；且第 88 批踩过"被用了却没定义 → 静默落灰底灰字"的坑
   —— 将来再有宿主想用，定义已在，不会再静默降级。 */
/* ★ 2026-09-25（第七波）：借调中的明细行角标（琥珀色，与完成/加急区分开） */
.tag.borrow{background:var(--wa-soft);color:#f5a623;font-weight:600}
/* ★ 2026-09-26（第八波）：详情弹层「按工序分组」的推进块 + 待办卡片跨工序提示行 */
.sgroup{border:1px solid var(--border);border-radius:var(--r-md);padding:var(--sp-2) var(--sp-3);margin:0 0 var(--sp-2);background:var(--panel2)}
.sgroup-title{font-size:var(--fs-sm);font-weight:600;color:var(--text);margin-bottom:2px}
.sgroup-btns{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--sp-2);margin-top:6px}
.card-cross{font-size:var(--fs-xs);color:var(--muted);padding:3px 0 0}
/* ★ 2026-09-28（改版）：待办卡片「工序徽章行」—— 跨工序卡把我的各工序活清成可点徽章
   （质检 teal / 发货 blue / 其余按工序名哈希取盘色，同工序名恒同色）；行可换行，
   手机/桌面都显示（不涉及端型显隐，故无媒体查询对）。 */
.todo-badges{display:flex;flex-wrap:wrap;gap:var(--sp-2);padding:6px 0 0}
.todo-badge{display:inline-flex;align-items:center;gap:var(--sp-2);line-height:1;padding:var(--sp-1) var(--sp-3);border:1px solid;border-radius:var(--r-pill);font-family:inherit;font-size:var(--fs-xs);cursor:pointer}
.todo-badge .bn{font-variant-numeric:tabular-nums;font-weight:600;opacity:.85}
.todo-badge.qc{background:#085041;border-color:#5DCAA5;color:#9FE1CB}
.todo-badge.ship{background:#0C447C;border-color:#85B7EB;color:#B5D4F4}
.todo-badge.stock{background:#0B3B49;border-color:#5BC8DE;color:#B8E6F2}
.todo-badge.c0{background:#3C3489;border-color:#AFA9EC;color:#CECBF6}
.todo-badge.c1{background:#4A1B0C;border-color:#F0997B;color:#F5C4B3}
.todo-badge.c2{background:#633806;border-color:#EF9F27;color:#FAC775}
.todo-badge.c3{background:#27500A;border-color:#97C459;color:#C0DD97}
.todo-badge.c4{background:#72243E;border-color:#ED93B1;color:#F4C0D1}
.card .meta{font-size:var(--fs-md);color:var(--text-2);line-height:1.75}
.card .meta b{color:var(--text);font-weight:600}
/* .due（已完成/已作废/交付状态 pill）与 .due-label（交期：）等：全部 line-height:1 + 对称 padding，
   保证 glyph 在盒内绝对居中（line-height:1.2 会让文字被半行距顶高 2-4px，历史教训） */
.due{display:inline-flex;align-items:center;justify-content:center;line-height:1;vertical-align:middle;font-weight:600;padding:1px var(--sp-2);border-radius:var(--r-sm);font-size:var(--fs-md)}
.due.ok{color:var(--good)}.due.warn{background:var(--wa-soft);color:var(--warn);padding:0 var(--sp-2);line-height:20px;position:relative;top:1px}.due.danger{background:var(--ba-soft);color:var(--bad);padding:0 var(--sp-2);line-height:20px;position:relative;top:1px}.due.over{background:var(--bad);color:var(--on-accent);padding:0 var(--sp-2);line-height:20px;position:relative;top:1px}.due.done{background:var(--ok-soft);color:var(--good);padding:0 var(--sp-2);line-height:20px;position:relative;top:1px}
/* ★ 2026-09-22（P1-7）：「未设交期」用中性灰 —— 与"剩 N 天(绿)"区分开，不再把缺数据当安全 */
.due.none{background:var(--chip);color:var(--muted);padding:0 var(--sp-2);line-height:20px;position:relative;top:1px}
.due-label{display:inline-flex;align-items:center;line-height:1;vertical-align:middle;padding:1px 0;font-size:var(--fs-md);color:var(--text-2)}
.due-big{display:inline-flex;align-items:center;line-height:1;vertical-align:middle;padding:1px 0;font-size:var(--fs-lg);font-weight:700}
.due-big.ok{color:var(--good)}.due-big.warn{color:var(--warn)}.due-big.danger{color:var(--bad)}.due-big.over{color:var(--bad)}
/* ★ 2026-10-04（批 1）：交期/日期徽章**一律不折行**。
   根因：`.due` 是 `inline-flex` —— 文字在其中会被拆成多个匿名 flex 项（"剩 1 天" → 3 项），
   容器一窄就各自换行（批 1 的表格「交期」列 8% 宽 → 竖成三行）。弹层宽度下看不出来，
   所以是个**既有隐患**，批 1 第一个把它暴露出来。 */
.due,.due-label,.due-big{white-space:nowrap}
/* ★ 2026-10-09（岩峰定·第 74 批⑦）：详情汇总条里「剩 N 天」比同排的「进行中」小一号 ——
   根因是 `.due` 自带 `font-size:var(--fs-md)`(14px)，而 `.sum-value` 是 `--fs-lg`(16px)，
   于是同一行里两个值字号不同（实测：进行中 16px / 剩 7 天 12px）。
   改：汇总条内的交期文字**跟随所在格**（inherit）⇒ 与「进行中」同大。
   ⚠ 只作用于 `.detail-summary`，卡片/列表/表格里的 `.due` 字号一律不动。 */
.detail-summary .sum-value .due,.detail-summary .sum-value .due-big{font-size:inherit}
/* .stay（停留 N 天）：曾无任何规则，按 text baseline 对齐会整体高出 3-4px，现与 pill 同基线体系 */
.stay{display:inline-flex;align-items:center;vertical-align:middle;line-height:1;color:var(--text-2);font-variant-numeric:tabular-nums}
/* ★ 2026-10-03：原 `.due-date`（交期具体日期，与倒计时并列）已删除 —— 详情卡定稿只显示天数、不显示日期，
   该类无任何引用。⚠ 2026-10-08：当初"要日期走 fmtDate()"里的 `fmtDate` 也已随审计清死代码一并删除
   （见 :4832 的留档），要短日期串现在**按需现写**。 */
/* ══ 按钮集 v5（2026-10-09 定稿）· 七档 · 无实心 · 扁平 · 底色看得见 · 文字几何居中 ══════
   依据 = 考核系统《按钮集统一规范 v5》§三（跨系统唯一真相源）。
   本系统的四条本地决策（岩峰 2026-10-09 22:1x）：
     ① 30px「紧凑档」保留、自成一致的一档（因为同一行的输入框也是 30px）；
     ② 取消"桌面端把 .btn-sm 升到 36px"那条端型规则 ⇒ 小号档全端统一 28px；
     ③ 原「只管宽度」的 .btn-primary 改名 .btn-block（19 个按钮同步改名）；
     ④ 归类表里「退回上一道」= 告急（藕荷）。
   纪律：只有底色 / 1px 描边 / 文字色三样 —— 零实心、零发光、零外扩投影、悬停只改底色。 */
:root{
  --btnp-bg:#1c344a;--btnp-bd:#34587a;--btnp-fg:#90c3f4;--btnp-hbg:#263f55;--btnp-hfg:#a4d7ff;
  --btni-bg:#0d3744;--btni-bd:#1e5e71;--btni-fg:#7acbe6;--btni-hbg:#1a424f;--btni-hfg:#8edffb;
  --btns-bg:#203822;--btns-bd:#3b603d;--btns-fg:#99cd9c;--btns-hbg:#2b432c;--btns-hfg:#ade2af;
  --btnw-bg:#442737;--btnw-bd:#71455e;--btnw-fg:#e7a7cb;--btnw-hbg:#4f3242;--btnw-hfg:#fcbbdf;
  --btnd-bg:#482726;--btnd-bd:#774544;--btnd-fg:#f1a7a4;--btnd-hbg:#543230;--btnd-hfg:#ffbbb8;
  --btnx-bg:#392a45;--btnx-bd:#614a72;--btnx-fg:#cfaee9;--btnx-hbg:#443550;--btnx-hfg:#e3c2fd;
  --btnn-bg:#422d13;--btnn-bd:#6e4e27;--btnn-fg:#e3b47f;--btnn-hbg:#4d381e;--btnn-hfg:#f7c892;
}
html[data-theme="light"]{
  --btnp-bg:#daeafa;--btnp-bd:#b2d0ed;--btnp-fg:#1c5a8e;--btnp-hbg:#cfdfef;--btnp-hfg:#105184;
  --btni-bg:#d5edf5;--btni-bd:#a8d4e5;--btni-fg:#006280;--btni-hbg:#cae1ea;--btni-hfg:#005a77;
  --btns-bg:#ddeddd;--btns-bd:#b7d6b8;--btns-fg:#296630;--btns-hbg:#d2e2d2;--btns-hfg:#1f5d28;
  --btnw-bg:#f7e1ec;--btnw-bd:#e6bfd4;--btnw-fg:#7e3c64;--btnw-hbg:#ebd6e1;--btnw-hfg:#75335b;
  --btnd-bg:#fae1df;--btnd-bd:#edbfbd;--btnd-fg:#873b3b;--btnd-hbg:#efd6d4;--btnd-hfg:#7e3333;
  --btnx-bg:#eee3f6;--btnx-bd:#d7c3e6;--btnx-fg:#684482;--btnx-hbg:#e2d8eb;--btnx-hfg:#603c79;
  --btnn-bg:#f4e5d4;--btnn-bd:#e3c7a8;--btnn-fg:#7b4a00;--btnn-hbg:#e9dac9;--btnn-hfg:#724200;
}
/* 骨架 + 尺寸契约（写死；任何档位不许覆盖这几条）。
   ⚠ 底部内边距 = 中文字形下偏量的 2 倍补偿（v5 §4.2）：标准档 1.7px / 小号档 1.0px。 */
.btn{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-2);
  height:var(--h-btn);padding:0 var(--sp-4) 1.7px;border-radius:var(--r-md);
  border:1px solid transparent;box-sizing:border-box;
  font-family:inherit;font-size:var(--fs-md);font-weight:500;line-height:1;white-space:nowrap;cursor:pointer;
  transition:background-color .15s,border-color .15s,color .15s,transform .08s}
.btn:active{transform:translateY(1px)}
.btn:focus-visible{outline:none;box-shadow:0 0 0 3px var(--focus-ring)}
.btn:disabled{opacity:.42;cursor:not-allowed;box-shadow:none}
.btn-sm{height:var(--h-btn-sm);padding:0 var(--sp-3) 1.0px;font-size:var(--fs-xs);border-radius:var(--r-sm)}
/* 宽度类（承接原 .btn-primary 的"只管宽度"职责；见本地决策③） */
.btn-block{width:100%;margin-top:8px}
/* 表单控件禁用态（2026-09-18 编辑订单统一入口）：订单已动工后「订单编号/订单类型」、有已完成
   明细时的明细行都会被 disabled。仅靠默认 UA 样式几乎看不出差别（实测对比度太弱），
   这里统一压暗 + 划线光标，让「不可改」一眼可见 */
input:disabled,select:disabled,textarea:disabled{opacity:.55;background:var(--panel2);color:var(--muted);cursor:not-allowed;border-style:dashed}
/* 防呆：按钮上不许出现任何 ::before 装饰（v5 起全站一律不戴环） */
.btn::before,.btn-blue::before,.btn-info::before,.btn-success::before,.btn-warn::before,.btn-danger::before,
.btn-special::before,.btn-neutral::before,.btn-line::before,.btn-soft::before,.btn-gray::before,
.btn-quiet::before,.btn.ghost::before,.btn-red::before,.btn.danger::before,.btn.warn::before,
.btn.solid-bad::before,.btn.solid-warn::before,.btn-warn-soft::before{content:none}
/* ── 默认 = 次要档（v5 起是**橙色**）：取消 / 返回 / 编辑 / 重置 / 清空 ── */
.btn,.btn-neutral{color:var(--btnn-fg);background-color:var(--btnn-bg);border-color:var(--btnn-bd)}
.btn:hover,.btn-neutral:hover{background-color:var(--btnn-hbg);color:var(--btnn-hfg)}
/* ── 主操作（蓝）：提交 / 保存 / 查询 / 派单 —— 推进流程的那个 ── */
.btn-primary,.btn-blue,.btn-line,.btn-soft{color:var(--btnp-fg);background-color:var(--btnp-bg);border-color:var(--btnp-bd)}
.btn-primary:hover,.btn-blue:hover,.btn-line:hover,.btn-soft:hover{background-color:var(--btnp-hbg);color:var(--btnp-hfg)}
/* ── 信息（青）：导出 / 下载 / 打印 / 上传 —— 数据进出 ── */
.btn-info{color:var(--btni-fg);background-color:var(--btni-bg);border-color:var(--btni-bd)}
.btn-info:hover{background-color:var(--btni-hbg);color:var(--btni-hfg)}
/* ── 成功（绿）：通过 / 完成 / 交付 / 解决 —— 正向终态 ── */
.btn-success{color:var(--btns-fg);background-color:var(--btns-bg);border-color:var(--btns-bd)}
.btn-success:hover{background-color:var(--btns-hbg);color:var(--btns-hfg)}
/* ── 告急（藕荷）：加急 / 超期 / 催办 / 退回重做 ── */
.btn-warn,.btn.warn,.btn-warn-soft,.btn.solid-warn{color:var(--btnw-fg);background-color:var(--btnw-bg);border-color:var(--btnw-bd)}
.btn-warn:hover,.btn.warn:hover,.btn-warn-soft:hover,.btn.solid-warn:hover{background-color:var(--btnw-hbg);color:var(--btnw-hfg)}
/* ── 危险（红）：删除 / 不通过 / 作废 ── */
.btn-danger,.btn-red,.btn.danger,.btn.solid-bad{color:var(--btnd-fg);background-color:var(--btnd-bg);border-color:var(--btnd-bd)}
.btn-danger:hover,.btn-red:hover,.btn.danger:hover,.btn.solid-bad:hover{background-color:var(--btnd-hbg);color:var(--btnd-hfg)}
/* ── 特殊（紫）：规则 / 管理 / 配置 / 权限 ── */
.btn-special{color:var(--btnx-fg);background-color:var(--btnx-bg);border-color:var(--btnx-bd)}
.btn-special:hover{background-color:var(--btnx-hbg);color:var(--btnx-hfg)}
.close{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;border-radius:var(--r-sm)}
.close:hover{background:var(--panel2);color:var(--text)}

/* 空状态：内联 SVG（mask 上色，跟随主题，无外部依赖） */
.empty{display:flex;flex-direction:column;align-items:center;gap:var(--sp-2);padding:var(--sp-5) var(--sp-3);color:var(--text-2);font-size:var(--fs-md)}
.empty::before{content:'';display:block;width:44px;height:44px;margin-bottom:4px;background-color:var(--muted);opacity:.55;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4'%3E%3Crect x='3' y='4' width='18' height='16' rx='2'/%3E%3Cpath d='M3 9h18M8 13h8M8 17h5'/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4'%3E%3Crect x='3' y='4' width='18' height='16' rx='2'/%3E%3Cpath d='M3 9h18M8 13h8M8 17h5'/%3E%3C/svg%3E") center/contain no-repeat}

/* 骨架屏（加载态，零依赖） */
.skel-card{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);padding:var(--sp-4);margin-bottom:var(--sp-3)}
.skel-line{height:12px;border-radius:var(--r-sm);margin-bottom:9px;background:linear-gradient(90deg,var(--panel2) 25%,var(--border) 37%,var(--panel2) 63%);background-size:400% 100%;animation:skel 1.2s ease-in-out infinite}
.skel-line.w40{width:40%}.skel-line.w60{width:60%}.skel-line.w80{width:80%}
.skel-line:last-child{margin-bottom:0}
/* 骨架超时兜底「加载失败」卡（2026-09-23）：复用骨架卡同一套 CSS 变量，不引入新样式体系；
   按钮直接复用既有 .btn.btn-sm。它**不是骨架**（不带 .skel-card），判据才不会与「无骨架残留」冲突。 */
.skel-fail{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);padding:var(--sp-4);margin-bottom:var(--sp-3);display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);flex-wrap:wrap}
.skel-fail .skf-msg{color:var(--text-2);font-size:var(--fs-md)}
@keyframes skel{0%{background-position:100% 50%}100%{background-position:0 50%}}
@media (prefers-reduced-motion:reduce){.skel-line{animation:none}}

/* 弹层底部常驻操作区（移动端主操作不被滚走） */
.sheet-actions{display:flex;gap:var(--sp-2);flex-wrap:wrap;margin-top:14px}
/* 区块内的按钮行（功能键归位后，每个区块的按钮都放这里）
   ★ 2026-09-29（岩峰定）：**右对齐**（原左对齐）—— 操作靠右，与内容左起的阅读方向错开，
   区块的"数据在左、操作在右"更清楚。
   ★ 2026-10-09（v5 本地决策②）：**删除**原「桌面端把 .rowbtn .btn-sm 升到 36px」的端型规则 ——
     规范硬要求"同一尺寸档几何完全一致"，端型升档会让小号档出现两个高度、几何自证必红。 */
.rowbtn{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--sp-2);margin-top:10px}
/* ★ 2026-10-17（岩峰定：分组块改**上下架构**）：
   分道时 `.rowbtn` 里除了「派单/退回」两颗按钮，还塞着两个 `.sgroup` 分组块。
   并排的两种做法都试过、都不行：`flex:0 1 auto`（只按内容宽、还被压窄）和"平分剩余宽度"
   —— **只要并排，1 项那块必然留白**（两块内容量天然不等：撑成等高就下半截空，不撑就参差）。
   故改上下堆叠：每块占满整行、按自身内容高度，**任何一端都没有空白带**。
   ⚠ `flex-basis:100%` 会强制换行 ⇒「派单/退回」两颗按钮留在上面单独一行（右对齐），
     语义上也顺：那是整单级动作，下面两块是"哪批活、怎么交"。
   ⚠ `margin-bottom:0`：原来 `.sgroup` 自带 8px 下边距，与 `.rowbtn` 的 gap 叠加会变 16px，
     这里交给 gap 统一管（块与块、块与按钮行间距一致）。
   ⚠ 只作用于 `.rowbtn` 里的 `.sgroup`：其它地方（明细区/右栏）的分组块布局一字不动。 */
.rowbtn .sgroup{flex:1 1 100%;min-width:0;align-self:flex-start;margin-bottom:0}
.card-actions{display:flex;gap:var(--sp-2);margin-top:var(--sp-3);flex-wrap:wrap}
  .load-more{text-align:center;padding:14px;color:var(--text-2);cursor:pointer;font-size:var(--fs-md);border-top:1px dashed var(--border)}
/* ============================================================================
   ★ 2026-10-04（L1 改造·批 1）：「订单查询」主从布局 —— 左队列 + 右操作台
     · 左 = 队列：表格（table-layout:fixed + 每列写死宽度 ⇒ 零溢出、右侧不留空白）
     · 右 = 操作台：常驻详情栏，复用 detailBodyHtml 的**同一份**渲染
     · ≤820px 由 JS 退回旧卡片列表 + 右栏隐藏（手机行为与改造前一致）
     · 回退开关 = JS 常量 BOARD_SPLIT
   全部走 --* 令牌（浅色主题自动成立），不写死颜色。
   ============================================================================ */
.bsplit{display:flex;gap:var(--sp-3);align-items:flex-start}
.bsplit-l{flex:1 1 auto;min-width:0}
.bsplit-r{flex:0 0 392px;width:392px;position:sticky;top:12px;
  max-height:calc(100vh - 132px);overflow:auto;
  background-color:var(--m-thick);
  background-image:linear-gradient(90deg,transparent,var(--rim-line) 12%,var(--rim-line) 88%,transparent);
  background-size:100% 1px;background-position:0 0;background-repeat:no-repeat;
  -webkit-backdrop-filter:blur(22px) saturate(1.75);backdrop-filter:blur(22px) saturate(1.75);
  border:1px solid var(--edge);border-radius:var(--r-lg);padding:var(--sp-3);
  box-shadow:0 20px 50px -24px var(--lift)}
.bsplit-r.hidden{display:none}
.dpane-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);
  padding-bottom:var(--sp-2);margin-bottom:var(--sp-2);border-bottom:1px solid var(--hair)}
.dpane-head b{font-size:var(--fs-lg);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:clip}
.dpane-empty{text-align:center;color:var(--text-2);font-size:var(--fs-md);line-height:1.95;padding:var(--sp-5) var(--sp-2)}
/* 常驻右栏宽 392px（≈弹层的一半）—— 汇总条按弹层的 4/5 列排会每格只剩 ~78px、值被挤断行。
   这里**只覆盖右栏内**：4 格排 2 列、5 格排 3 列（3+2，不留孤卡）。弹层那份原样不动。 */
.bsplit-r .detail-summary{grid-template-columns:repeat(2,1fr);gap:var(--sp-3);padding:var(--sp-3);margin:10px 0}
.bsplit-r .detail-summary.c5{grid-template-columns:repeat(3,1fr)}
/* ★ 第 68 批（交付日期第 6 格）：右栏 6 格与 5 格同为 3 列，不留孤卡。 */
.bsplit-r .detail-summary.c6{grid-template-columns:repeat(3,1fr)}
.bsplit-r .detail-card{padding:var(--sp-3);margin-bottom:10px}
.bsplit-r .info-grid-3{gap:10px 12px}
.bsplit-r .sum-value{white-space:nowrap}
@media (max-width:820px){
  .bsplit{display:block}
  .bsplit-r{display:none!important}   /* 手机退回旧的底部抽屉详情，右栏不参与 */
}

  .load-more.done{cursor:default;opacity:.7}
input,select,textarea{background:var(--panel2)!important;border:1px solid var(--border)!important;color:var(--text)!important;border-radius:var(--r-sm);padding:0 var(--sp-3);font-size:var(--fs-md);width:100%;font-family:inherit;height:var(--h-ctl);transition:border-color .15s,box-shadow .15s}
textarea{height:auto;resize:vertical;min-height:56px;padding:var(--sp-2) var(--sp-3);line-height:1.5}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--accent)!important;box-shadow:var(--focus-ring)!important}
:focus-visible{outline:none;box-shadow:var(--focus-ring)!important}
.stat-card .num,.bar-num,.bcard .stay,.due,.due-big,.sum-value{font-variant-numeric:tabular-nums}
input::placeholder,textarea::placeholder{color:var(--muted)}
input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
input[type=number]{-moz-appearance:textfield}
input[type=checkbox],input[type=radio]{width:auto!important;height:auto!important;margin:0;accent-color:var(--accent);padding:0}
.item input[type=checkbox]{width:18px!important;height:18px!important}
label{color:var(--text-2);font-size:var(--fs-sm);display:block;margin-bottom:var(--sp-1);font-weight:500}
/* ===== 登录界面（移动优先 / 高大上） ===== */
.login-screen{position:relative;min-height:100vh;min-height:100dvh;display:flex;align-items:center;justify-content:center;padding:var(--sp-4);overflow:hidden;background:
  radial-gradient(1100px 560px at 12% -8%, var(--accent-soft), transparent 60%),
  radial-gradient(900px 480px at 108% 112%, rgba(122,92,255,.13), transparent 55%),
  var(--bg)}
.login-glow{position:absolute;border-radius:50%;filter:blur(90px);opacity:.55;pointer-events:none;z-index:0}
.login-glow-a{width:440px;height:440px;background:radial-gradient(circle,var(--accent),transparent 70%);top:-140px;left:-90px}
.login-glow-b{width:400px;height:400px;background:radial-gradient(circle,#7a5cff,transparent 70%);bottom:-150px;right:-70px}
.login-logos{position:absolute;top:calc(var(--sp-4) + env(safe-area-inset-top) + 10px);left:calc(var(--sp-4) + 16px);z-index:10;display:flex;align-items:center;gap:26px}
.login-logos img{height:clamp(38px,5.6vw,46px);width:auto;object-fit:contain;filter:drop-shadow(0 2px 6px rgba(0,0,0,.55))}
.login-logos img.logo-weeduo{height:clamp(31px,4.6vw,38px);max-width:220px;transform:translateY(-2px)}
.login-logos .logo-sep{width:1px;height:26px;background:linear-gradient(180deg,transparent,rgba(255,255,255,.30),transparent);flex-shrink:0}
.login-card{position:relative;z-index:1;width:100%;max-width:400px;background:linear-gradient(180deg,rgba(255,255,255,.07),rgba(255,255,255,.025));border:1px solid rgba(255,255,255,.10);border-radius:var(--r-xl);box-shadow:var(--shadow-2),inset 0 1px 0 rgba(255,255,255,.10);-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);padding:var(--sp-5) var(--sp-4)}
.brand{text-align:center;margin-bottom:var(--sp-5)}
.brand-name{font-size:var(--fs-2xl);font-weight:700;color:var(--text);letter-spacing:1px}
.brand-sub{margin-top:8px;font-size:var(--fs-sm);color:var(--muted);letter-spacing:.5px}
.login-foot{position:absolute;bottom:calc(var(--sp-4) + env(safe-area-inset-bottom));left:0;right:0;text-align:center;font-size:var(--fs-xs);color:var(--muted);opacity:.7;z-index:10}
.login-form{display:flex;flex-direction:column;gap:var(--sp-3)}
.field{position:relative;display:flex;align-items:center;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-sm);transition:border-color .15s,box-shadow .15s}
.field:focus-within{border-color:var(--accent);box-shadow:var(--focus-ring)}
.field-ico{display:flex;align-items:center;justify-content:center;width:46px;color:var(--muted);flex-shrink:0}
.field-ico svg{width:18px;height:18px}
.field select,.field input{background:transparent!important;border:none!important;box-shadow:none!important;width:auto!important;flex:1 1 auto!important;min-width:0!important;height:50px;padding:0 var(--sp-3)!important;font-size:var(--fs-lg);color:var(--text);font-family:inherit}
.field select{appearance:none;-webkit-appearance:none;padding-right:40px!important;cursor:pointer}
.field select:has(option[value=""]:checked){color:var(--muted)!important}
.field select option{color:var(--text);background:var(--panel)}
.field-chev{position:absolute;right:14px;color:var(--muted);pointer-events:none;display:flex}
.field-chev svg{width:16px;height:16px}
.field-toggle{background:none;border:none;color:var(--muted);cursor:pointer;width:46px;height:46px;display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0}
.field-toggle:hover{color:var(--text)}
.field-toggle svg{width:18px;height:18px}
.field-toggle.on{color:var(--accent)}
/* ★ 2026-10-10（岩峰定·最终口径：「**别动考核系统，按 50px 做**」）：
   登录页按钮的**尺寸**＝**登录页专档 50px / --fs-lg(16px) / 字重 600**，
   与考核系统登录页**逐值一致**（岩峰实测两系统截图后拍板）。
   ★ 2026-10-17：登录页现在**只剩「进入系统」一个按钮** —— 原「继续登录（退出另一处）」
     （2026-10-10 并入本专档、当日逐值对齐的那个）已按岩峰决定**整块删除**（见下方原规则处的说明）。
     专档本身不变；`.login-force` 规则与其 CSS 一并删除（不留死规则）。
   ⚠ 这是**唯一**一处允许偏离 v5「28/30/36 三档」的地方 ——
   登录页是独立落地页、没有同排控件要对齐，大号 CTA 是有意的，不是漏改。
   规则已写进跨系统《按钮集统一规范》§4.4「登录页专档」（v5.2）。
   而**颜色**仍走 v5 主操作令牌（下面不再有任何实心蓝覆盖）：
     · 浅色 #daeafa 底 + #1c5a8e 字；深色 #1c344a 底 + #90c3f4 字。
   ⚠ 2026-10-09 那次「字看不见」＝当年的 `html[data-theme="light"] .login-submit{background:--accent}`
     与 `.btn-primary` 打架造成的；那条覆盖已删，**颜色现在只有 v5 一个来源**。 */
.login-submit{height:50px;margin-top:var(--sp-2);font-size:var(--fs-lg);font-weight:600;gap:8px}
.login-submit .arr{width:18px;height:18px}
/* ★ 2026-10-17（岩峰定）：`.login-force`（「继续登录（退出另一处）」按钮）**已删除** —— 规则与
   markup 一并清掉（不留死 CSS）。它的历史：2026-10-03 随「单端登录」新增（409 时亮出、本人二次
   确认才顶号）；2026-10-10 并入登录页专档（50px / 16px / 600，与「进入系统」逐值一致，
   判据曾是 `_probe_b74_verify.js` ① 段）。删除后**单端登录的"确认"＝点「进入系统」这一次点击本身**
   （409 时前端自动带 force 重试，用户看不见）。该判据 ① 段已同步改写。
   ⚠ 跨系统《按钮集统一规范》§4.4「登录页专档」条文里提到"两个按钮"的地方需随之下调为"一个"（已记待办）。 */
/* 移动端交互优化：内联报错 / 加载态 / 按压反馈 / 视图淡入淡出 */
.login-error{display:none;margin:-var(--sp-1) 2px 0;font-size:var(--fs-sm);color:var(--bad);line-height:1.45}
/* 「记住口令」（原名「记住密码」，2026-09-12）：勾了把账号 + 口令存本机 localStorage，下次打开自动预填。
   纯本机行为 —— 不上云、不随请求传输，所以只在自己的电脑上勾。 */
.login-remember{display:flex;align-items:center;gap:var(--sp-2);margin:-var(--sp-1) 2px 0;font-size:var(--fs-sm);color:var(--text-2);cursor:pointer;user-select:none;-webkit-user-select:none}
/* ⚠ 必须带 !important：全局那条 `input[type=checkbox]{width:auto!important}`（见上）会把它压回浏览器默认 13px
   —— 2026-09-12 真实浏览器实测抓到的（桌面 13×13、手机 20×20）。
   手机端由 @media 内的 20px!important 覆盖（那份在文件更后面，同优先级后者赢）→ 桌面 18 / 手机 20。 */
.login-remember input[type=checkbox]{width:18px!important;height:18px!important;flex:none;margin:0;padding:0;accent-color:var(--accent);cursor:pointer}
/* 个人设置 · 修改口令表单（2026-09-12） */
.pwd-form{display:flex;flex-direction:column;gap:12px}
.pwd-form .pf-row{display:flex;flex-direction:column;gap:6px}
.pwd-form .pf-row label{margin:0}
.pwd-form input{max-width:320px}
.login-error.show{display:block}
/* ★ 2026-10-13（岩峰定 · UI 审计 12）：报错**贴住出错的那一栏** ——
   错误条原来夹在「姓名」和「口令」中间，看着既像姓名的错、也像口令的错。
   现在：① 它已移到「口令」框正下方（登录失败绝大多数是口令问题）；
   ② 出错时**口令框自己变红**（一眼知道该改哪一栏）。
   ⚠ 标红的是 **`.field` 外框**、不是 input 本身 —— 输入框是 `border:none!important`
      （边框画在外层 `.field` 上，见 :647「框里不套框」）。
   ⚠ 用显式 class（而不是 `.login-form:has(...)`）：实测本机 headless Chrome
      不支持 `:has()`，整条选择器会被忽略（2026-10-13 真机验过）。
   ⚠ 409「账号正在别处使用」不标红（口令其实是对的）—— ★ 2026-10-17 起 409 在 doLogin 内部
      就被自动顶号消化掉（用户看不见），更不会走到这里标红；能标红的只剩真正的口令/限频/锁定失败。 */
.field.err-field{border-color:var(--bad);box-shadow:0 0 0 3px var(--ba-soft)}
.field-hint{margin:var(--sp-1) 2px 0;font-size:var(--fs-xs);color:var(--muted);opacity:.82;line-height:1.45}
.login-submit{transition:transform .08s ease,filter .08s ease;position:relative}
.login-submit:active{transform:scale(.975)}
/* ★ 2026-10-10：转圈原为**白色**（配当年的实心蓝底）——收进 v5 后浅色主题是**浅蓝底**，
   白圈会看不见 ⇒ 改用 `currentColor`（＝按钮自己的前景色，深浅主题都跟得上）。 */
.login-submit .spinner{display:none;width:16px;height:16px;border:2px solid currentColor;border-top-color:transparent;opacity:.55;border-radius:50%;animation:spin .7s linear infinite}
.login-submit.loading .spinner{display:inline-block}
.login-submit.loading .arr{display:none}
.login-submit.loading{pointer-events:none;opacity:.85;filter:brightness(.96)}
@keyframes spin{to{transform:rotate(360deg)}}
.field-toggle{transition:transform .08s ease,color .15s}
.field-toggle:active{transform:scale(.9);color:var(--text)}
#login,#app{transition:opacity .15s ease}
.login-screen.fade-out{opacity:0;pointer-events:none}
@media (min-width:820px){.login-card{max-width:440px;padding:36px 40px}.login-glow{opacity:.7}}
@media (max-width:600px){
  .login-logos{left:var(--sp-4);gap:14px}
  .login-logos img{height:26px}
  .login-logos img.logo-weeduo{height:22px;max-width:150px;transform:translateY(-1px)}
  .app-logos{gap:8px}
  .app-logos img{height:24px}
  .app-logos img.logo-weeduo{height:20px}
  .app-logos .logo-sep{height:18px}
  .brand-name{font-size:var(--fs-xl)}
  .brand-sub{font-size:var(--fs-xs)}
}
@media (max-height:520px){
  .login-logos{top:calc(var(--sp-3) + env(safe-area-inset-top))}
  .brand{margin-bottom:var(--sp-3)}
  .brand-name{font-size:var(--fs-xl)}
  .brand-sub{margin-top:4px;font-size:var(--fs-xs)}
  .login-foot{display:none}
  .login-card{padding:var(--sp-4)}
  .field select,.field input{height:46px}
}
.filter{display:flex;flex-direction:column;gap:var(--sp-1);margin-bottom:var(--sp-3)}
.filter-row + .filter-row{margin-top:var(--sp-2)}
.filter-row{display:flex;gap:var(--sp-2);flex-wrap:wrap;align-items:flex-end}
.filter-row select,.filter-row input{flex:1;min-width:120px;height:var(--h-ctl);width:auto}
.filter-row input#fKeyword{flex:2;min-width:180px}
.filter-row .btn{height:var(--h-ctl);min-width:84px;flex:0;width:auto;margin:0}
.filter-row .btn-line{width:auto}
.filter-date-group{display:flex;flex-direction:row;align-items:center;gap:var(--sp-2);flex:0 1 230px;max-width:250px;min-width:200px}
.filter-date-group label{font-size:var(--fs-xs);color:var(--muted);margin-bottom:0;line-height:1.3;flex-shrink:0}
.filter-date-group input[type=date]{width:auto;flex:1;padding:0 8px}
input[type=date]::-webkit-calendar-picker-indicator{filter:invert(1);cursor:pointer;opacity:.7}
input[type=date]::-webkit-calendar-picker-indicator:hover{opacity:1}
.date-trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);width:100%;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-sm);color:var(--muted);font-size:var(--fs-md);height:var(--h-ctl);padding:0 var(--sp-3);cursor:pointer;font-family:inherit;transition:border-color .15s,box-shadow .15s}
.date-trigger:hover{border-color:var(--border-strong)}
.date-trigger.formal{color:var(--text)}
.date-trigger.has-val{color:var(--text)}
.date-trigger .dp-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.date-trigger .dp-ico{flex-shrink:0;color:var(--muted)}
.date-trigger:focus,.date-trigger:active{border-color:var(--accent)!important;box-shadow:var(--focus-ring)!important;outline:none}
.filter-date-group .date-trigger{flex:1;min-width:0}
.date-pop{position:fixed;z-index:200;width:264px;background:var(--panel);border:1px solid var(--border-strong);border-radius:var(--r-lg);box-shadow:var(--shadow-2);padding:var(--sp-3);color:var(--text)}
.date-pop.hidden{display:none}
.date-pop .dp-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}
.date-pop .dp-title{font-weight:600;font-size:var(--fs-md)}
.date-pop .dp-nav{width:30px;height:30px;border:none;background:var(--panel2);color:var(--text);border-radius:var(--r-sm);cursor:pointer;font-size:var(--fs-xl);line-height:1}
.date-pop .dp-nav:hover{background:var(--accent-soft)}
.date-pop .dp-week{display:grid;grid-template-columns:repeat(7,1fr);font-size:var(--fs-xs);color:var(--muted);text-align:center;margin-bottom:4px}
.date-pop .dp-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
.date-pop .dp-cell{height:32px;display:flex;align-items:center;justify-content:center;border-radius:var(--r-sm);font-size:var(--fs-sm);cursor:pointer;color:var(--text)}
.date-pop .dp-cell:hover{background:var(--panel2)}
.date-pop .dp-cell.other{color:var(--muted);opacity:.45}
.date-pop .dp-cell.today{box-shadow:inset 0 0 0 1px var(--accent)}
.date-pop .dp-cell.sel{background:var(--accent);color:var(--on-accent)}
.date-pop .dp-foot{display:flex;justify-content:space-between;margin-top:8px;gap:8px}
.date-pop .dp-foot button{flex:1;padding:var(--sp-2);border:none;background:var(--panel2);color:var(--text);border-radius:var(--r-sm);cursor:pointer;font-size:var(--fs-xs)}
.date-pop .dp-foot button:hover{background:var(--accent-soft)}
/* ★ 时间行（datetime-local 场景，2026-09-22 本批）：复用同一套 CSS 变量（--panel2/--border/--r-sm/
   --focus-ring…），**不引入新的颜色 / 字体体系**；视觉节奏与上方 .dp-foot 一致（同字体、同间距）。
   加/不加 .hidden 由 JS 按模式切换（全局 .hidden 是 !important，故这里无需再写隐藏规则）。 */
.date-pop .dp-time{display:flex;align-items:center;gap:var(--sp-2);margin-top:8px;padding-top:8px;border-top:1px solid var(--border)}
.date-pop .dp-time .dp-time-lb{color:var(--muted);font-size:var(--fs-xs);flex:0 0 auto}
.date-pop .dp-time select{flex:1;height:30px;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-sm);color:var(--text);font-size:var(--fs-sm);font-family:inherit;padding:0 var(--sp-2);cursor:pointer}
.date-pop .dp-time select:hover{border-color:var(--border-strong)}

/* ══ 录单页 · 客户候选浮层（2026-10-09）═══════════════════════════════════════
   不复用 .date-pop：那套内距/网格是给日历定的；这里要的是"一行一家客户"的列表。
   但**定位约定照抄它**（position:fixed 挂 body + 先隐后量再显形 + 视口夹取）。
   ⚠ 为什么必须 fixed 而不能 absolute：录单页整块在 .oe-tscroll
     （overflow:auto + overflow-x:hidden）里 —— absolute 浮层会被那个滚动容器
     **裁掉**，下拉一展开就被切半截。fixed 挂 body 则不受任何祖先 overflow 影响。
     代价：fixed 不跟随滚动 ⇒ 自己监听 scroll 重定位（见 clReposition）。 */
#clPop{position:fixed;z-index:260;display:none;width:340px;max-width:calc(100vw - 16px);
  max-height:300px;overflow-y:auto;overscroll-behavior:contain;
  background:var(--panel);border:1px solid var(--border-strong);border-radius:var(--r-lg);
  box-shadow:var(--shadow-2);color:var(--text)}
#clPop.on{display:block}
#clPop .cl-hd{position:sticky;top:0;z-index:1;padding:7px var(--sp-3);font-size:var(--fs-xs);
  color:var(--muted);background:var(--panel2);border-bottom:1px solid var(--border)}
#clPop .cl-it{padding:9px var(--sp-3);cursor:pointer;border-bottom:1px solid var(--border)}
#clPop .cl-it:last-child{border-bottom:none}
#clPop .cl-it:hover,#clPop .cl-it.hot{background:var(--accent-soft)}
#clPop .cl-nm{font-size:var(--fs-md);line-height:1.45;word-break:break-word}
#clPop .cl-sub{display:flex;gap:var(--sp-2);flex-wrap:wrap;font-size:var(--fs-xs);
  color:var(--muted);margin-top:3px;word-break:break-word}
#clPop .cl-tip{padding:11px var(--sp-3);font-size:var(--fs-sm);color:var(--muted);line-height:1.65}
#clPop .cl-tip.warn{color:var(--warn)}
@media (max-width:820px){#clPop{width:auto;left:8px!important;right:8px;max-width:none}}
.date-pop .dp-time select:focus{border-color:var(--accent)!important;box-shadow:var(--focus-ring)!important;outline:none}
.date-pop .dp-time .dp-colon{color:var(--muted)}
.overlay{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:60;display:flex;align-items:flex-end}
/* ★ 2026-09-30（岩峰手机实测后修）：三层的**层叠顺序**必须靠 z-index 明确区分 ——
   列表弹层(60) < 详情(64) < 操作弹层(68) < 确认框(70，#askMask 自带) 。
   为什么必须拆元素：同一个宿主不可能"既在详情下面、又在详情上面"。
   症状（改前）：从列表点进详情 → 详情被同样 60 且 DOM 更靠后的 #modal 盖住 → 点订单"没反应"。 */
#listModal{z-index:60}
/* ★ 2026-10-05（岩峰定）：列表弹层（数据页「总订单」下钻 / 看板统计卡下钻 / 待处理异常）
   的订单卡片，改成与看板右栏「进行中的订单」**同一张新版卡**（.vcard）。
   卡片自带 1px 下边框做行分隔（.vcard{border-bottom}）⇒ 列表末张去掉；
   列表整体给一圈轻框，与弹层底区分开（不用 .panel：它有 rim 高光与大投影，嵌在弹层里发脏）。
   ⚠ 描边用 --border 不是 --edge：浅色下 --edge = 白 85%（弹层也是白底）⇒ 等于没画（见 §106.2）。 */
#listModalBody #lmItems{padding:0;overflow:hidden;border:1px solid var(--border);border-radius:var(--r-lg)}
#listModalBody #lmItems .vcard:last-child{border-bottom:0}
#detail{z-index:64}
#modal{z-index:68}
.sheet{background:var(--panel);width:100%;max-height:88vh;overflow-y:auto;border-radius:var(--r-lg) var(--r-lg) 0 0;border-top:1px solid var(--border-strong);box-shadow:var(--shadow-2);padding:var(--sp-4)}
.sheet h2,.sheet h3{font-size:var(--fs-lg);margin-bottom:var(--sp-2)}
/* ★ 2026-10-01（岩峰定 + 行业最佳实践）：全系统动效统一 **Material 3 动效令牌**。
   时长（跨设计体系收敛值 —— M3 short3 / IBM Carbon / Shopify Polaris / Tailwind 都是 150ms）：
   · --t-1 = 150ms：状态确认类（页签淡入、遮罩、小弹层、chip/开关切换）
   · --t-2 = 150ms：大面积入场（底部抽屉/弹层滑入）—— ★ 2026-10-01 岩峰定：全线统一 150ms
     （M3 对大面积定 250ms·手机 0.8 倍 ≈ 200ms 的"平衡点"他仍嫌慢 → 按他的手感来）。
   缓动：M3 standard `cubic-bezier(.2,0,0,1)` —— 前段快、尾段缓收（"落定"感，比 ease-out 更好）。
   ⚠ 只用 opacity/transform（GPU 合成、不触发重排）；只做**入场**（出场仍即时 ——
     出场要"播完再隐藏"，得改各关闭函数，风险大；嫌不对称再议）。
   ⚠ 只在真"显示"时播（.hidden 是 display:none —— display 从 none 变化时动画会重头播）。 */
:root{--t-1:150ms;--t-2:150ms;--t-view:300ms;--ease-m3:cubic-bezier(.2,0,0,1)}
@keyframes uiFade{from{opacity:0}to{opacity:1}}
@keyframes uiViewIn{from{opacity:0;transform:translateX(16px)}to{opacity:1;transform:translateX(0)}}
@keyframes uiSheetUp{from{transform:translateY(100%)}to{transform:translateY(0)}}
@keyframes uiPop{from{opacity:0;transform:translateY(-6px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}
.overlay:not(.hidden){animation:uiFade var(--t-1) var(--ease-m3)}
.overlay:not(.hidden)>.sheet{animation:uiSheetUp var(--t-2) var(--ease-m3)}
#moreNavMask:not(.hidden){animation:uiFade var(--t-1) var(--ease-m3)}
#moreNavMask:not(.hidden) .more-nav-box{animation:uiSheetUp var(--t-2) var(--ease-m3)}
main>[id^="view-"]:not(.hidden){animation:uiViewIn var(--t-view) var(--ease-m3)}
/* ↑ ★ 2026-10-01（岩峰反馈"切换没有任何动画"）：纯淡入在 150ms 内**肉眼不可辨**
     （真机验证过规则在跑、只是看不见）→ 改 **滑动 16px + 淡入**（导航方向感，Material shared-axis 的简化版）。
     ★ 时长单独走 `--t-view:300ms`（岩峰随后定：切换要慢一点、看得清；其余动效仍 150ms）。 */
.date-pop:not(.hidden){animation:uiPop var(--t-1) var(--ease-m3)}
#cloudDown:not(.hidden){animation:uiFade var(--t-1) var(--ease-m3)}
.net-banner:not(.hidden){animation:uiFade var(--t-1) var(--ease-m3)}
/* 状态切换过渡补齐（原先瞬跳的：筛选 chip / 权限状态字 / 权限开关旁文字；
   其余 nav/.btn/输入框/开关等本就有 150ms 过渡，不动） */
.sf-chip{transition:background-color var(--t-1),border-color var(--t-1),color var(--t-1)}
.pp-state{transition:color var(--t-1)}
.pm-tg-txt{transition:color var(--t-1)}
@media (prefers-reduced-motion:reduce){   /* 系统开了"减少动态"就尊重它（无障碍，W3C 惯例） */
  .overlay:not(.hidden),.overlay:not(.hidden)>.sheet,
  #moreNavMask:not(.hidden),#moreNavMask:not(.hidden) .more-nav-box,
  main>[id^="view-"]:not(.hidden),.date-pop:not(.hidden),
  #cloudDown:not(.hidden),.net-banner:not(.hidden),
  #modal:not(.hidden)>.sheet{animation:none}   /* ★ 2026-10-17：电脑端居中卡的入场动画（下方新块）也要被这条关掉 */
}
/* ★ 2026-10-17（岩峰定 · 照抄考核系统）：**电脑端操作弹层 = 屏幕正中卡片**，不再从最底下升起。
   起因：岩峰「我比较喜欢考核系统的点了加号是在中间弹出一个框来输入信息，而不是从最下面弹出来，
         这个要照抄一下考核系统的，但要记住不是只改这一处」——所以不是只改「新建角色」一处，
         而是 **#modal 这一整个宿主下的全部操作弹层**（派单/交付/发货入库/退回/质检不通过/返工/
         编辑订单/修正字段/异常上报/新建角色/编辑人员/重置口令/请假/指定人员/Agent 任务…共 23 处）一起改。
   范围边界（只有这三条）：① #detail（订单详情）与 #listModal（下钻列表）**不动** —— 它们是
     「看内容的大面板」，不是「填信息的小框」，居中收窄会把表格挤坏；② ≤820 手机端**不动**（仍是
     全屏弹层，见下方 mobile 块 —— 手机屏小，居中卡片反而浪费空间）；③ #askMask 二次确认框本来就
     是居中（2026-09-11 定的），无需改。
   宽度两档（考核系统只有一档 460 ——它的弹层内容都轻；本系统有带明细列表的重弹层，故加宽档）：
     · 默认 max-width:460px ＝ 与考核系统同款（轻表单：新建/编辑角色、编辑人员、重置口令、
       异常上报/退回/解决、返工、修改返工类型、请假）
     · `.sheet-wide` → 880px（带明细列表或大表单的：交付、发货/入库、质检不通过、退回、派单、
       编辑订单、修正交付字段、草稿箱、指定人员、Agent 新建任务/原始记录/报告）
     档位由弹层自己加在 `#modal` 上（`_modalWide()`；关弹层时统一还原，不会串档）。
   居中方式 = 「align-items:flex-start + justify-content:center + margin:auto」的**安全居中**：
     内容比屏幕高时能滚、不高时仍垂直居中；直接写 align-items:center 会把超高卡片的顶部裁掉
     （生产系统 #askMask、考核系统 .modal 两处都踩过这个坑，这里沿用同一套做法）。
   ⚠ 只改**形态**：z-index(68) / DOM 层级 / 关闭函数 / RJ_OVERLAY_ORDER 一律不动 —— 层级一动
     就会牵连断网遮罩、日期选择器与三层弹层的覆盖关系（那套是 2026-09-30 按实测定的）。 */
@media (min-width:821px){
  #modal{align-items:flex-start;justify-content:center;padding:var(--sp-4);overflow-y:auto}
  #modal>.sheet{
    max-width:460px;
    /* 高度加 `dvh` 回退（vh 在前、dvh 紧跟）——与本文件 .login-screen / .ask-sheet 同一写法 */
    max-height:calc(100vh - 32px);
    max-height:calc(100dvh - 32px);
    margin:auto;                                  /* 吃掉剩余空间 → 真·垂直居中 */
    border:1px solid var(--border-strong);        /* 四边描边：卡片浮在遮罩上，不能再"只有上边" */
    border-radius:var(--r-lg);                    /* 四角圆角（底部抽屉原本只圆上面两角） */
  }
  #modal.sheet-wide>.sheet{max-width:880px}
  /* 入场动画：底部抽屉是"从下往上滑"(uiSheetUp)，居中卡片照考核系统用 uiPop（轻微下移+放大淡入） */
  #modal:not(.hidden)>.sheet{animation:uiPop var(--t-1) var(--ease-m3)}
}
.flow-step{display:flex;align-items:center;font-size:var(--fs-sm);color:var(--muted);margin:6px 0}
.flow-step .dot{width:10px;height:10px;border-radius:50%;background:var(--border-strong);margin-right:6px;flex-shrink:0}
.flow-step.done .dot{background:var(--good)}.flow-step.done{color:var(--good)}
.flow-step.cur .dot{background:var(--bad);box-shadow:0 0 0 2px var(--panel), 0 0 0 3px var(--ba-soft);width:12px;height:12px}
.flow-step.cur{color:var(--bad);font-weight:600}
.flow-step .arrow{color:var(--border-strong);margin:0 4px}
.item{background:var(--panel2)!important;border-radius:var(--r-sm);padding:var(--sp-2) var(--sp-3);margin:var(--sp-2) 0;font-size:var(--fs-sm);display:flex;justify-content:space-between;align-items:center;gap:var(--sp-2);border:1px solid var(--border)}
.item input[type=checkbox]{width:18px;height:18px}
/* ★ 2026-09-29（岩峰定）：**详情页「订单明细」行**的版式（画稿 B 版：两栏对齐）。
   为什么用**修饰类**而不是直接改 `.item`：`.item` 是录单页/编辑弹层的输入行共用的
   （那两处靠内联 `flex-direction:column` 覆盖方向），改默认值会波及它们。
   病灶：详情页明细行沿用 .item 的默认 `justify-content:space-between + align-items:center`，
   而左右两个 span **都没有宽度约束** → 左侧长文本（商品名+色号+规格+数量+备注）把右侧
   「工序N · 负责人」挤到换行，`align-items:center` 又把它**垂直居中到左侧多行高度的正中**
   → 看起来像"叠在一起"（岩峰 1140 截图）。
   这里：左栏 `flex:1;min-width:0`（可收缩、内部换行），右栏 `flex:0 0 auto;nowrap`（不换行）、
   **顶端对齐**（不再居中）。
   工序人状态色（岩峰定）：**未完成=蓝 / 逾期异常=红 / 完成=绿** ——
   红只留给真异常，不用作"未完成"的默认色（否则满屏红，真逾期反而跳不出来）。 */
/* ★ 2026-09-30（岩峰定·明细行 v8 版式）：改为**块布局**。
   原来是 left/right 两栏 —— 右栏那枚「工序N · 负责人」标签**只有一行高、却吃掉整条宽度**，
   于是下面每一行都短一截、右侧空出一条（岩峰截图框出的正是它）。
   现在工序标签放进主行（`.itm-head`），内容吃整卡宽度。 */
.item.itm{display:block;padding:11px 12px}
.item.itm .itm-main{flex:1 1 auto;min-width:0}
.item.itm .itm-title{font-size:var(--fs-sm);color:var(--text);line-height:1.45;overflow-wrap:anywhere}
.item.itm .itm-sub{font-size:var(--fs-xs);color:var(--muted);margin-top:4px;line-height:1.5;overflow-wrap:anywhere}
/* （2026-10-06 删除 `.item.itm .itm-sub .df-echo` —— `.df-echo` 已随 `_fieldEcho` 退役） */
.item.itm .itm-stage{flex:0 0 auto;white-space:nowrap;font-size:var(--fs-xs);line-height:1;padding:var(--sp-1) var(--sp-2);border-radius:var(--r-pill);border:1px solid transparent}
.item.itm .itm-stage.wait{background:var(--accent-soft);border-color:var(--accent-soft);color:var(--accent-text)}
.item.itm .itm-stage.done{background:var(--ok-soft);border-color:var(--ok-soft);color:var(--good)}
.item.itm.is-done .itm-title{color:var(--muted)}
.item.itm.is-done .itm-sub{color:var(--border-strong)}
/* ★ v8 明细行版式（2026-09-30 岩峰定）：
   主行(序号 + 品名 + 工序标签) ／ 规格·数量(**突出**) ／ 字段区(**标签 72px 定宽左对齐**)。
   约定：色号 / 快递单号 / 备注 各占一行；动态工序字段用 `.fduo` 网格并排（短的并排、长的撑高）。
   ⚠ 全篇**不截断**（明细是生产指令，省一个字就是事故）；日期类用 nowrap 防折断。 */
.item.itm .itm-head{display:flex;align-items:baseline;gap:var(--sp-2);flex-wrap:wrap}
.item.itm .itm-head .idx{color:var(--hint);font-variant-numeric:tabular-nums;flex:0 0 auto}
.item.itm .itm-head .nm{font-size:var(--fs-md);color:var(--text);flex:1 1 auto;min-width:0;word-break:break-word}
.item.itm .itm-head .itm-stage{margin-left:auto}
.item.itm .itm-spec{margin-top:5px;font-size:var(--fs-md);font-weight:500;color:var(--accent-text);word-break:break-word}
.item.itm .itm-spec .u{color:var(--accent-text)}
.item.itm .itm-fields{margin-top:10px;padding-top:10px;border-top:1px solid var(--border);
  display:flex;flex-direction:column;gap:6px}
.item.itm .fr{display:flex;align-items:baseline;gap:var(--sp-3);min-width:0}
/* ★ 2026-09-30（岩峰定）：**字段名 = 白色、字段内容 = 蓝色**。
   原来标签用 `--hint`(灰)、值用 `--text-2`(浅灰) → 两者都偏灰白，一眼分不出哪个是字段名。
   现在拉开：标签白（醒目、好定位）、值蓝（一眼知道"这是内容"）。 */
.item.itm .fr>.k{flex:0 0 72px;text-align:left;font-size:var(--fs-xs);color:var(--text)}
.item.itm .fr>.v{flex:1 1 auto;min-width:0;font-size:var(--fs-sm);color:var(--accent-text);
  word-break:break-word;line-height:1.7}
.item.itm .fduo{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:6px 18px}
.item.itm .fduo .fr>.k{flex:0 0 72px}
.item.itm .itm-tags{margin-top:7px;display:flex;flex-wrap:wrap;gap:5px}
/* 明细行内的文本输入框：与明细文字同号（--fs-sm）。
   ★ 2026-09-11 手机端 UI 审计：这些输入框原先是在 JS 模板里内联写死 font-size:13px 的，
   而内联样式会压过 ≤820 的 `input,select,textarea{font-size:16px}` → 手机上仍是 13px、
   iOS 聚焦会强制放大整页。同日把那 12 处内联删除，改在这里统一声明：
   桌面端保持与原内联一致的观感（13px），手机端由 ≤820 的 !important 规则提到 16px。
   不写成 `.item input{...}` 是为了不牵连 .partqty 等其它同容器控件。 */
.item .oDesc,.item .oColorNo,.item .oSpec,.item .oUnit,.item .oQty,.item .oItemRemark,
.item .emDesc,.item .emColorNo,.item .emSpec,.item .emUnit,.item .emQty,.item .emItemRemark{
  font-size:var(--fs-sm);
}
/* ★ 2026-09-19 岩峰：「录入界面应该是一个**字段后面跟着一个输入框**，而不是输入框里提示
   这个框里要填什么」→ 明细行改为**可见标签 + 输入框**。原先只用 placeholder 当字段名，
   内容一填进去字段名就没了，核对/回填时根本认不出哪一格是什么。
   版式沿用本项目「任职信息」卡（`.pm-prof`）的既有写法：**标签在左、输入框占满剩余**，
   保证两处观感一致；标签走 --muted + --fs-xs，不与正文抢注意力。
   `.item-field--wide` 是给「规格」这类内容较长的字段用的（保持原先 flex:2 的相对权重）。 */
.item-field{display:flex;align-items:center;gap:var(--sp-2);margin:0;min-width:0;flex:1}
.item-field--wide{flex:2}
.item-field>span{flex:0 0 auto;color:var(--muted);font-size:var(--fs-xs);white-space:nowrap}
.item-field>input,.item-field>select{flex:1;min-width:0;padding:var(--sp-2);border-radius:var(--r-sm);width:auto}
.rec{font-size:var(--fs-sm);color:var(--muted);padding:5px 0;border-bottom:1px dashed var(--border)}
.rec b{color:var(--text)}
/* 流转与审计时间轴（Feature 3）：合并 FlowRecord + OpLog，按时间倒序 */
.timeline{position:relative;padding-left:14px;margin:2px 0}
.timeline::before{content:'';position:absolute;left:4px;top:4px;bottom:4px;width:2px;background:var(--border-strong)}
.tl-item{position:relative;padding:7px 0 7px var(--sp-2);border-bottom:1px dashed var(--border)}
.tl-item:last-child{border-bottom:none}
.tl-dot{position:absolute;left:-14px;top:11px;width:9px;height:9px;border-radius:50%;border:2px solid var(--panel);box-sizing:border-box}
.tl-flow .tl-dot{background:var(--accent)}
.tl-log .tl-dot{background:var(--warn)}
.tl-head{font-size:var(--fs-sm);color:var(--muted);display:flex;align-items:baseline;gap:var(--sp-2);flex-wrap:wrap}
.tl-head b{color:var(--text)}
.tl-kind{font-size:var(--fs-xs);padding:1px var(--sp-2);border-radius:var(--r-pill);font-weight:600}
.tl-flow .tl-kind{background:var(--accent-soft);color:var(--accent)}
.tl-log .tl-kind{background:var(--wa-soft);color:var(--warn)}
.tl-time{margin-left:auto;color:var(--text-2);font-size:var(--fs-xs);white-space:nowrap}
.tl-note2{margin-top:3px}
.tl-note-line{font-size:var(--fs-sm);color:var(--text-2);line-height:1.5;word-break:break-word}
.tl-note-line+.tl-note-line{margin-top:1px}
.tl-note-first{color:var(--text);font-weight:600}
.rw-hint{font-size:var(--fs-xs);color:var(--text-2);margin-left:6px;font-weight:400}
.tl-link{font-size:var(--fs-xs);color:var(--accent);margin-left:8px;cursor:pointer;text-decoration:none}
.tl-items{margin-top:7px;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-md);padding:8px 10px}
.tl-item-row{font-size:var(--fs-sm);line-height:1.75;color:var(--text-2)}
.tl-item-remark{font-size:var(--fs-sm);color:var(--text-2);margin-left:6px}
.tl-shipping{font-size:var(--fs-xs);color:var(--warn);margin-left:8px}
/* ═══════════ ★ 2026-09-30（岩峰定·流转记录 v7 版式）═══════════
   时间轴 + **人名突出** + **明细卡（读 data）**。
   为什么新开 `.tl2-*` 而不是改 `.tl-*`：旧类名在别处（流转记录拆行/返工灰字等）仍有引用，
   直接改会连带炸；新类名只给**新的时间轴渲染**用，零风险。
   主次：动作+内容=主角（左、亮）；人名=突出一档（14px/600）；时间=配角（右、灰、小字）。 */
.tl2{position:relative;margin-left:5px;padding-left:18px;border-left:1px solid var(--border-strong)}
.tl2-day{position:relative;margin:14px 0 var(--sp-2);font-size:var(--fs-xs);color:var(--muted);font-weight:500}
.tl2-day:first-child{margin-top:2px}
.tl2-day::before{content:"";position:absolute;left:-23px;top:5px;width:9px;height:9px;border-radius:var(--r-xs);
  background:var(--border-strong)}
.tl2-item{position:relative;padding:9px 0 11px;border-bottom:1px dashed var(--border)}
.tl2-item:last-child{border-bottom:none}
.tl2-item::before{content:"";position:absolute;left:-23px;top:15px;width:9px;height:9px;border-radius:50%;
  background:var(--accent);box-shadow:0 0 0 3px var(--panel2)}
.tl2-log::before{background:var(--warn)}
.tl2-bad::before{background:var(--bad)}
/* 名字 · 动作 · 工序 **保证同一排**（时间右对齐）；左组内部才允许折行 */
.tl2-head{display:flex;align-items:baseline;gap:10px}
.tl2-lft{display:flex;align-items:baseline;gap:var(--sp-2);flex-wrap:wrap;min-width:0}
.tl2-who{font-size:var(--fs-md);color:var(--text);font-weight:600}
.tl2-act{font-size:var(--fs-xs);line-height:1;padding:var(--sp-1) var(--sp-2);border-radius:var(--r-pill);
  background:var(--accent-soft);color:var(--accent-text);white-space:nowrap}
.tl2-log .tl2-act{background:var(--wa-soft);color:var(--warn)}
.tl2-bad .tl2-act{background:var(--ba-soft);color:#ff8a8a}
.tl2-stp{font-size:var(--fs-xs);color:var(--text-2)}
.tl2-tm{margin-left:auto;font-size:var(--fs-xs);color:var(--hint);white-space:nowrap;
  font-variant-numeric:tabular-nums;padding-left:10px}
.tl2-raw{font-size:var(--fs-xs);color:var(--text-2);line-height:1.7;word-break:break-word;margin-top:5px}
/* 明细：**每条一张满宽卡** —— 第1排=明细名+色号，第2排=员工填的字段+值 */
.tl2-its{margin-top:7px;display:flex;flex-direction:column;gap:6px}
.tl2-it{background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-md);padding:8px 10px}
.tl2-it .h{font-size:var(--fs-sm);color:var(--text);line-height:1.5;word-break:break-word}
.tl2-it .h .no{color:var(--hint);margin-right:6px}
.tl2-it .h .cr{color:var(--accent-text);margin-left:8px}
.tl2-it .f{margin-top:5px;display:flex;flex-wrap:wrap;gap:5px 16px}
.tl2-it .f .kv{font-size:var(--fs-xs);line-height:1.6;word-break:break-word}
.tl2-it .f .kv .k{color:var(--hint);margin-right:6px}
.tl2-it .f .kv .v{color:var(--text-2)}
/* ★ 2026-09-30：字段多的时候（异常卡等）改**竖排**（横排会挤成一团） */
.tl2-it .f.col{flex-direction:column;gap:3px}
/* ★ 2026-09-30：明细卡的**头排**（明细编号 / 名称+色号 / 完成量） */
.tl2-it .tl2-hh{display:flex;align-items:baseline;gap:var(--sp-2);flex-wrap:wrap}
.tl2-it .tl2-lb{font-size:var(--fs-xs);color:var(--hint);white-space:nowrap}
.tl2-it .tl2-nm{font-size:var(--fs-sm);color:var(--text);font-weight:500;word-break:break-word}
.tl2-it .tl2-qt{margin-left:auto;font-size:var(--fs-xs);color:var(--good);white-space:nowrap}
/* 完成量两态（与旧圆点同语义）：做满/全额 = 绿；未做满（cum 非空）= 黄 */
.tl2-it .tl2-qt-ok{color:var(--good)}
.tl2-it .tl2-qt-part{color:var(--warn)}
/* ★ 2026-09-30：卡内「规格 · 数量」与「备注」—— 合并自原「订单明细」区块 */
.tl2-it .tl2-spec{margin-top:4px;font-size:var(--fs-sm);color:var(--text);display:flex;
  align-items:baseline;gap:var(--sp-2);flex-wrap:wrap;word-break:break-word}
.tl2-it .tl2-spec .sp{color:var(--text-2)}
.tl2-it .tl2-spec .u{color:var(--accent-text);font-weight:500;white-space:nowrap}
.tl2-it .tl2-rmk{margin-top:3px;font-size:var(--fs-xs);line-height:1.6;word-break:break-word}
/* ★ 2026-10-02（岩峰定）：**退回/不合格 = 关键信息行**（备注下一行、红色、完整换行）——
   不再挤在卡片头排右侧的小字里（退回去向填错工序就是生产事故，必须一眼看到） */
.tl2-it .tl2-key{margin-top:4px;font-size:var(--fs-xs);line-height:1.6;word-break:break-word;
  color:var(--bad);font-weight:500}
.tl2-it .tl2-rmk .k{color:var(--hint);margin-right:6px}
.tl2-it .tl2-rmk .v{color:var(--text-2)}
/* ★ 2026-10-02（岩峰定）：**结构化理由行**（.rr）—— 字段名弱色 + 值红色（与 .tl2-key 同源的关键信息）。
   数据源：新记录 FlowRecord.data {v:1,kind:'reason',label,value,machine,hot}；老记录按**同源 note 格式**
   解析（_reasonFromNote）。字段名 = 退回理由 / 不合格原因 / 返工原因（作废没有理由输入，不在此列）。 */
.tl2-it .tl2-rmk.rr .v{color:var(--bad);font-weight:500}
/* ★ 2026-09-30（岩峰定）：卡片右下角的操作按钮行（修正字段 / 修改返工类型） */
.tl2-acts{display:flex;justify-content:flex-end;gap:var(--sp-2);margin-top:7px}
/* `.tl-link` 自带 margin-left:8px 是为了"跟在文案后面"的行内场景；
   进了 flex 容器（.tl2-acts 已用 gap 控制间距）会多出一份左侧留白 → 清零，让链接右端贴齐。 */
.tl2-acts .tl-link{margin-left:0}
/* ★ 2026-09-30：异常卡容器（直接装现成的 `.anom` 组件）+ 区块标题后的提示小字 */
.tl2-ano{margin-top:7px}
.tl2-hint{font-size:var(--fs-xs);color:var(--hint);font-weight:400;margin-left:8px}
@media (max-width:820px){.tl2-who{font-size:var(--fs-md)}.tl2-act{font-size:var(--fs-xs);padding:3px 7px}}
/* ★ 2026-09-30 手机端：卡片内信息收紧 —— 卡头可换行、规格行折行、备注整行
   （岩峰特别提醒"注意手机端的适配性"；关键是不让长规格/备注撑破卡片、也不挤压完成量） */
@media (max-width:820px){
  .tl2-it{padding:7px 9px}
  .tl2-it .tl2-hh{gap:6px}
  .tl2-it .tl2-qt{margin-left:0;flex-basis:100%;text-align:right}
  .tl2-it .tl2-spec{font-size:var(--fs-xs);gap:6px}
  .tl2-it .tl2-rmk{font-size:var(--fs-xs)}
  .tl2-it .f.col .kv{display:flex;flex-wrap:wrap;gap:0 6px}
}
/* ★ 2026-09-25（第九波）：交付记录改「物流时间线式」（产品负责人三版稿定稿方案一，替代第六波 chips 卡片）。
   左列节点圆点+竖向连线（最后一个节点不画线），右列三级分层：
   头行（明细徽章+色号/商品名+行右完成量）→ 字段区（字段名定宽 86px｜值 两列对齐）。
   全额完成=绿点白勾(.tl-tl-dot-ok)、部分交付=黄点(.tl-tl-dot-part)、无进度/失效=灰点(.tl-tl-dot-none)。
   min-width:0 + overflow-wrap:anywhere → 手机档（≤820px，390 宽主场景）不撑破容器。 */
.tl-tl{margin-top:6px;display:flex;flex-direction:column;min-width:0}
.tl-tl-node{display:flex;gap:var(--sp-2);min-width:0}
.tl-tl-rail{display:flex;flex-direction:column;align-items:center;flex:0 0 14px;width:14px}
.tl-tl-dot{width:14px;height:14px;border-radius:50%;flex:0 0 14px;display:flex;align-items:center;justify-content:center;margin-top:2px}
.tl-tl-dot svg{width:9px;height:9px;display:block}
.tl-tl-dot-ok{background:var(--good)}
.tl-tl-dot-part{background:var(--warn)}
.tl-tl-dot-none{background:var(--border-strong)}
.tl-tl-line{flex:1 1 auto;width:2px;min-height:8px;margin:var(--sp-1) 0 2px;background:var(--border-strong)}
.tl-tl-body{flex:1 1 auto;min-width:0;padding-bottom:10px}
.tl-tl-head{display:flex;align-items:baseline;gap:var(--sp-2);flex-wrap:wrap;min-width:0}
.tl-tl-no{flex:0 0 auto;font-size:var(--fs-xs);font-weight:600;color:var(--text);background:var(--chip);border-radius:var(--r-xs);padding:1px var(--sp-2);white-space:nowrap}
.tl-tl-name{font-size:var(--fs-sm);font-weight:600;color:var(--text);min-width:0;overflow-wrap:anywhere}
.tl-tl-qty{margin-left:auto;flex:0 1 auto;max-width:100%;font-size:var(--fs-xs);font-weight:700;white-space:nowrap;overflow-wrap:anywhere}
.tl-tl-qty-ok{color:var(--good)}
.tl-tl-qty-part{color:var(--warn)}
.tl-tl-fields{margin-top:4px;display:flex;flex-direction:column;gap:2px;min-width:0}
/* ★ 2026-09-29：编辑订单变更卡片（C 版）—— 与上方「交付」时间线同一套视觉语言，看流转记录时不断档 */
.tl-ed-sum{margin-top:6px;background:var(--panel2);border-left:3px solid var(--accent);border-radius:var(--r-sm);padding:7px var(--sp-3);font-size:var(--fs-sm);color:var(--text-2);line-height:1.5}
.tl-ed-sec{font-size:var(--fs-xs);color:var(--muted);margin:9px 0 5px}
.tl-ed-card{background:var(--panel2);border:1px solid var(--border);border-left:3px solid var(--accent);border-radius:var(--r-md);padding:var(--sp-2) var(--sp-3);margin-bottom:7px}
.tl-ed-card-del{border-left-color:var(--bad)}
.tl-ed-chead{display:flex;align-items:baseline;gap:7px;flex-wrap:wrap;min-width:0}
.tl-ed-no{flex:0 0 auto;font-size:var(--fs-xs);font-weight:600;color:var(--text);background:var(--chip);border-radius:var(--r-xs);padding:1px var(--sp-2);white-space:nowrap}
.tl-ed-badge-add{background:var(--ok-soft);color:var(--good)}
.tl-ed-badge-del{background:var(--ba-soft);color:var(--bad)}
.tl-ed-name{font-size:var(--fs-sm);font-weight:600;color:var(--text);min-width:0;overflow-wrap:anywhere}
.tl-ed-name-del{color:var(--muted);text-decoration:line-through}
.tl-ed-qty{margin-left:auto;font-size:var(--fs-xs);color:var(--text-2);white-space:nowrap}
.tl-ed-fields{margin-top:5px;display:flex;flex-direction:column;gap:var(--sp-1);min-width:0}
.tl-ed-head{margin-top:0;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-md);padding:8px 10px}
.tl-ed-frow{display:flex;align-items:baseline;gap:var(--sp-2);flex-wrap:wrap;font-size:var(--fs-xs);min-width:0}
.tl-ed-fk{flex:0 0 56px;color:var(--muted)}
.tl-ed-old{color:var(--muted);text-decoration:line-through;overflow-wrap:anywhere}
.tl-ed-arrow{color:var(--accent)}
.tl-ed-new{color:var(--good);overflow-wrap:anywhere}
.tl-ed-locked{margin-top:6px;background:var(--panel2);border-left:3px solid var(--warn);border-radius:var(--r-sm);padding:7px var(--sp-3);font-size:var(--fs-sm);color:var(--text-2)}
.tl-tl-frow{display:flex;align-items:baseline;gap:var(--sp-2);min-width:0}
.tl-tl-fk{flex:0 0 86px;width:86px;font-size:var(--fs-xs);color:var(--muted);line-height:1.6;word-break:break-all}
.tl-tl-fv{flex:1 1 auto;min-width:0;font-size:var(--fs-xs);color:var(--text);line-height:1.6;overflow-wrap:anywhere}
.tl-tl-dead .tl-tl-no{color:var(--muted);font-weight:500}
.tl-tl-dead .tl-tl-name{color:var(--muted);font-weight:500}
@media(max-width:560px){.tl-tl-fk{flex-basis:72px;width:72px}}
/* 人工备注单独区：左侧 info 色竖条 +「备注：…」，置于汇总卡之后、时间线之前 */
.tl-tl-note{margin:2px 0 var(--sp-2);padding:var(--sp-1) var(--sp-2);border-left:3px solid var(--accent);background:var(--accent-soft);border-radius:0 6px 6px 0;font-size:var(--fs-xs);color:var(--text-2);line-height:1.5;word-break:break-word}
/* 汇总卡（第十一波 方案C，v2/老记录两来源共用）：N 条明细 + 合计完成量（按单位累计） */
.tl-tl-sum{margin:2px 0 var(--sp-2);padding:5px 9px;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-md);display:flex;flex-wrap:wrap;gap:2px var(--sp-3);align-items:baseline;font-size:var(--fs-xs);min-width:0}
.tl-tl-sum-no{font-weight:600;color:var(--text)}
.tl-tl-sum-qty{font-weight:600;color:var(--accent);overflow-wrap:anywhere}
/* 协作批注（Feature 6） */
.comment-list{display:flex;flex-direction:column;gap:var(--sp-2);margin:2px 0}
.cmt{background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-sm);padding:8px 10px}
.cmt-head{display:flex;align-items:baseline;gap:var(--sp-2);font-size:var(--fs-sm)}
.cmt-head b{color:var(--text)}
.cmt-time{margin-left:auto;color:var(--text-2);font-size:var(--fs-xs);white-space:nowrap}
.cmt-text{font-size:var(--fs-sm);color:var(--text);margin-top:3px;line-height:1.5;white-space:pre-wrap;word-break:break-word}
.comment-box{display:flex;flex-direction:row;align-items:center;gap:var(--sp-2);margin-top:8px}
.comment-box textarea{height:36px;min-height:36px;flex:1;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-sm);padding:var(--sp-2) var(--sp-3);color:var(--text);resize:none}
.comment-box textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft)}
.comment-actions{display:flex;justify-content:flex-end;flex-shrink:0}
/* ★ 2026-10-09（v5 §5.2）：删除原 `padding:0 18px` —— 同高 36 却有第二套内边距，
   会破坏"同尺寸档几何完全一致"；内边距一律继承 .btn 的 16px。 */
.comment-actions .btn{height:36px}
/* 数据看板（Feature 4） */
.dash-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-3);margin-bottom:14px}
.dash-card{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) 14px;background:linear-gradient(135deg,var(--accent-soft),var(--accent-soft));border:1px solid var(--accent-soft);border-radius:var(--r-lg);box-shadow:var(--shadow-1);position:relative;overflow:hidden;cursor:pointer;transition:transform .1s,border-color .15s,box-shadow .15s}
.dash-card::before{content:'';position:absolute;left:0;top:0;bottom:0;width:4px;background:var(--accent)}
.dash-card:hover{border-color:var(--accent-soft);box-shadow:0 0 0 2px var(--accent-soft)}
.dash-card:active{transform:scale(.97)}
.dash-card.good{background:linear-gradient(135deg,var(--ok-soft),var(--ok-soft));border-color:var(--ok-soft)}
.dash-card.good::before{background:var(--good)}
.dash-card.warn{background:linear-gradient(135deg,var(--wa-soft),var(--wa-soft));border-color:var(--wa-soft)}
.dash-card.warn::before{background:var(--warn)}
.dash-card.danger{background:linear-gradient(135deg,var(--ba-soft),var(--ba-soft));border-color:var(--ba-soft)}
.dash-card.danger::before{background:var(--bad)}
.dash-icon{width:40px;height:40px;border-radius:var(--r-md);display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.08);color:var(--accent);flex-shrink:0}
.dash-card.good .dash-icon{color:var(--good)}
.dash-card.warn .dash-icon{color:var(--warn)}
.dash-card.danger .dash-icon{color:var(--bad)}
.dash-icon svg{width:22px;height:22px}
.dash-body{flex:1;min-width:0}
.dash-body .num{font-size:var(--fs-display);font-weight:700;line-height:1;color:var(--text)}
.dash-body .lbl{font-size:var(--fs-xs);color:var(--text-2);margin-top:2px}
.dash-block{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);padding:var(--sp-3);margin-bottom:var(--sp-3);box-shadow:var(--shadow-1)}
.dash-block h4{font-size:var(--fs-md);font-weight:600;margin:0 0 var(--sp-2);display:flex;align-items:center;gap:8px}
.dash-block h4::before{content:'';width:4px;height:18px;background:linear-gradient(180deg,var(--accent),#6d9dff);border-radius:var(--r-xs)}
.bar-row{display:flex;align-items:center;gap:var(--sp-3);padding:7px var(--sp-2);font-size:var(--fs-sm);border-radius:var(--r-sm);transition:background .15s}
.bar-row:hover{background:var(--accent-soft)}
.bar-row.bar-clickable{cursor:pointer;user-select:none}
.bar-row.bar-clickable:hover{background:var(--accent-soft)}
.bar-rank{width:24px;height:24px;display:flex;align-items:center;justify-content:center;border-radius:50%;background:var(--panel2);color:var(--muted);font-size:var(--fs-xs);font-weight:700;flex-shrink:0}
.bar-row:first-child .bar-rank{background:linear-gradient(135deg,#ffd700,#ffb700);color:#332200}
.bar-row:nth-child(2) .bar-rank{background:linear-gradient(135deg,#e8eaed,#bfc3c9);color:#1a1a1a}
.bar-row:nth-child(3) .bar-rank{background:linear-gradient(135deg,#cd7f32,#b87333);color:#fff}
.bar-label{width:110px;flex-shrink:0;color:var(--text);text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bar-track{flex:1;background:var(--panel2);border-radius:var(--r-pill);height:18px;overflow:hidden;border:1px solid var(--border);position:relative}
.bar-fill{display:block;height:100%;background:linear-gradient(90deg,var(--accent),#6d9dff);border-radius:var(--r-pill);box-shadow:0 0 10px var(--accent-soft);transition:width .5s ease}
.bar-val{width:28px;flex-shrink:0;text-align:right;font-weight:700;color:var(--text)}
.bar-pct{width:46px;flex-shrink:0;text-align:right;font-size:var(--fs-xs);color:var(--text-2)}
.dash-table{width:100%;border-collapse:collapse;font-size:var(--fs-sm)}
/* ★ 2026-10-05（岩峰定·全站统一 C）：表头与内容一并居中 */
.dash-table th,.dash-table td{padding:var(--sp-2) var(--sp-2);text-align:center;border-bottom:1px solid var(--border)}
.dash-table th{color:var(--text-2);font-weight:600}
/* ===== 云端数据监控台（2026-09-17 岩峰重构定稿）=====
   定位：回答「云端数据在上传/下载/存储上正不正常」。**不是业务分析页**。
   ⚠ 全程 var(--*) 令牌，**绝不写死颜色** —— 浅色主题下写死的深色底会翻车（技能铁律）。
   表格复用上面的 .dash-table（同一套视觉，不另造 .dbv-table 以免两处漂移）。 */
.dash-table td.dim{color:var(--text-2);font-size:var(--fs-xs)}
/* ① 总体结论横幅：打开页面 1 秒就能看到「正常 / 待关注 / 异常」。
   三色由后端 verdict.level 决定，前端只负责挂 class —— 判定规则只写在后端一份，避免两处漂移。 */
.dbv-verdict{display:flex;align-items:flex-start;gap:var(--sp-3);padding:14px var(--sp-4);border-radius:var(--r-lg);
  border:1px solid var(--border);background:var(--panel);margin-bottom:var(--sp-3);box-shadow:var(--shadow-1)}
.dbv-verdict .v-dot{width:12px;height:12px;border-radius:50%;flex-shrink:0;margin-top:6px;background:var(--muted)}
.dbv-verdict .v-main{flex:1;min-width:0}
.dbv-verdict .v-title{font-size:var(--fs-lg);font-weight:700;color:var(--text);line-height:1.25}
.dbv-verdict .v-sub{font-size:var(--fs-sm);color:var(--text-2);margin-top:4px;line-height:1.55}
.dbv-verdict .v-issues{margin-top:8px;display:flex;flex-direction:column;gap:4px}
.dbv-verdict .v-issue{font-size:var(--fs-sm);color:var(--text-2);line-height:1.5;display:flex;gap:var(--sp-2);align-items:baseline}
.dbv-verdict .v-issue::before{content:'';width:6px;height:6px;border-radius:50%;background:var(--warn);flex-shrink:0;transform:translateY(-2px)}
.dbv-verdict .v-issue.bad::before{background:var(--bad)}
.dbv-verdict.ok{border-color:var(--ok-soft);background:linear-gradient(135deg,var(--ok-soft),var(--ok-soft))}
.dbv-verdict.ok .v-dot{background:var(--good);box-shadow:0 0 0 4px var(--ok-soft)}
.dbv-verdict.ok .v-title{color:var(--good)}
.dbv-verdict.warn{border-color:var(--wa-soft);background:linear-gradient(135deg,var(--wa-soft),var(--wa-soft))}
.dbv-verdict.warn .v-dot{background:var(--warn);box-shadow:0 0 0 4px var(--wa-soft)}
.dbv-verdict.warn .v-title{color:var(--warn)}
.dbv-verdict.bad{border-color:var(--ba-soft);background:linear-gradient(135deg,var(--ba-soft),var(--ba-soft))}
.dbv-verdict.bad .v-dot{background:var(--bad);box-shadow:0 0 0 4px var(--ba-soft)}
.dbv-verdict.bad .v-title{color:var(--bad)}
/* ② 监控状态卡：复用 .dash-card 视觉，但**不可点**（本页无下钻）→ 去掉手型与悬浮放大 */
.dbv-card{cursor:default}
.dbv-card:hover{border-color:var(--accent-soft);box-shadow:var(--shadow-1)}
.dbv-card:active{transform:none}
.dbv-card .num{font-size:var(--fs-lg)}
/* ③ 监控要点行：左标签 / 中值 / 右补充说明（手机端折两行） */
.dbv-list{display:flex;flex-direction:column;gap:2px}
.dbv-row{display:flex;align-items:baseline;gap:var(--sp-3);padding:var(--sp-2) var(--sp-2);border-radius:var(--r-sm);font-size:var(--fs-sm)}
.dbv-row:nth-child(odd){background:var(--panel2)}
.dbv-k{flex-shrink:0;min-width:118px;font-weight:600;color:var(--text)}
.dbv-v{flex:1;min-width:0;color:var(--text-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums}
.dbv-t{flex-shrink:0;font-size:var(--fs-xs);color:var(--muted);font-variant-numeric:tabular-nums}
/* 手机端（≤820）：监控要点行改为两行堆叠，避免长文案被挤成一字一行 */
@media (max-width:820px){
  .dbv-row{flex-wrap:wrap;gap:2px 8px}
  .dbv-k{min-width:0}
  .dbv-v{flex-basis:100%;order:3;white-space:normal}
  .dbv-verdict{padding:12px}
  .dbv-verdict .v-title{font-size:var(--fs-md)}
}
/* ★ 横条轨道保底最小宽（2026-09-17 加）：.bar-track 是 flex:1，容器一窄就被压到
   几乎为零 —— 实测在窄列里被压成 **2px**，等于区块白做。给个下限后最坏情况是
   行内容溢出（能被发现），而不是静默消失（发现不了）。52px ≈ 还能看出「有点/没点」。 */
.bar-track{min-width:52px}
/* ④ 读写活动趋势条（近 7 天）：
   条长按「7 天内最大值归 100%」。全为 0 时不画条，只显示「本周无新增」。
   ⚠ 本块的日期标签宽度用 .bar-label 的既有 110px 会太宽 → 覆盖成 92px + 左对齐。
      .bar-label 是共用的（订单数据页也在用），所以**只在本块的父类内覆盖**，不动它本身。 */
.dbv-trend .bar-label{width:92px;text-align:right}
.dbv-trend .bar-val{width:auto;min-width:34px}
.dbv-trend .bar-pct{width:52px}
/* ★ 本页总览栅格单独覆盖（2026-09-17）：
   目标 = 6 张卡排满整行、末行不留孤卡。6 的约数有 1/2/3/6。
   ⚠ 别用 auto-fit + minmax：列数随内容宽浮动，实测 1280 视口算出 5 列（比原来更糟）
     → 浮动列数无法保证整除，必须固定列数。
   ⚠ **断点规则的落位很关键**（这里踩过坑）：共用 `.dash-grid` 的 `@media(max-width:900px){...repeat(2,1fr)}`
     写在**本文件更靠后**的位置，特异性又与本条相同 → 只在本处写一份会被它覆盖，
     表现为「821 视口量到 2 列」而桌面 3 列的规则失效。所以本页的断点规则必须**写在 900 块之后**。
   → 桌面(>900) 3 列（6 = 3×2）｜ 381~900 **2 列**（6 = 2×3）｜ ≤380 1 列。 */
.dbv-ov-grid{grid-template-columns:repeat(3,1fr)}
.tag-ok{color:var(--good);font-weight:600}
.tag-late{color:var(--bad);font-weight:600}
/* ★ 2026-09-28：「产能利用率」环的 CSS（.cap-card/.cap-info/.cap-rate/.cap-num/.cap-sub/.cap-ring）
   已随产能功能整套移除。 */
/* 生产异常（Feature 2） */
.anom{background:var(--panel2);border:1px solid var(--border);border-left:3px solid var(--warn);border-radius:var(--r-sm);padding:var(--sp-2) var(--sp-3);margin:6px 0}
.anom.anom-resolved{border-left-color:var(--good);opacity:.78}
.anom-head{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;font-size:var(--fs-sm)}
.anom-st{padding:1px 7px;border-radius:var(--r-pill);font-size:var(--fs-xs);font-weight:600;background:var(--panel);color:var(--text-2)}
.anom-st.warn{background:var(--wa-soft);color:var(--warn)}
.anom-st.good{background:rgba(60,200,120,.16);color:var(--good)}
.anom-meta{color:var(--text-2);font-size:var(--fs-xs);margin-left:auto}
.anom-note{font-size:var(--fs-sm);color:var(--text);margin-top:4px;line-height:1.5;white-space:pre-wrap;word-break:break-word}
.anom-actions{display:flex;gap:var(--sp-2);margin-top:8px}
.anom-badge{display:inline-flex;align-items:center;gap:3px}
.my-anom{background:var(--ba-soft);border:1px solid var(--ba-soft);border-radius:var(--r-sm);padding:var(--sp-2) var(--sp-3);margin:6px 0}
.my-anom .ma-title{font-size:var(--fs-sm);font-weight:600;color:var(--bad);margin-bottom:4px}
.my-anom .ma-item{font-size:var(--fs-sm);color:var(--text);padding:3px 0}
/* ★ 2026-09-22：待补附件（必交·可后补）—— 待办页分区 + 详情页明细行下的提示 */
.todo-fu{background:var(--wa-soft);border:1px solid var(--wa-soft);border-radius:var(--r-sm);padding:var(--sp-2) var(--sp-3);margin:6px 0}
.todo-fu .tf-title{font-size:var(--fs-sm);font-weight:600;color:var(--warn);margin-bottom:4px}
.todo-fu .tf-item{font-size:var(--fs-sm);color:var(--text);padding:5px 0;cursor:pointer;display:flex;flex-wrap:wrap;gap:0 var(--sp-2);align-items:baseline}
.todo-fu .tf-item+.tf-item{border-top:1px dashed var(--border)}
.todo-fu .tf-item:hover{color:var(--accent)}
.todo-fu .tf-t{color:var(--warn)}
.todo-fu .tf-s{color:var(--muted)}
.fu-bar{font-size:var(--fs-xs);color:var(--warn);padding:0 var(--sp-3) var(--sp-2);margin-top:-4px;display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.fu-bar .fu-btn{font-size:var(--fs-xs);padding:2px var(--sp-3);border-radius:var(--r-sm);border:1px solid var(--wa-soft);background:transparent;color:var(--warn);cursor:pointer;height:auto;min-height:0}
.fu-bar .fu-btn:hover{background:var(--wa-soft)}
/* ★ 2026-10-02（岩峰定：× **改回最初的样子** —— 标题行右侧的素净 × 字符，只是颜色改红。
   上一版"固定+搬运"方案整体撤销（含 JS 搬运与 --sheet-top 跟随）。 */
.modal-title{display:flex;justify-content:space-between;align-items:center}
.modal-title .close{color:var(--bad)}

/* ===== 统一二次确认弹窗（替代原生 confirm，2026-09-11 自考核系统移植并适配）=====
   三档：normal 蓝（正向操作）/ caution 黄（有影响但可恢复）/ danger 红（不可恢复）
   外壳复用本系统的 .overlay(遮罩) + .sheet，但**形态是屏幕正中卡片**
   （岩峰 2026-09-11 定）—— 与其它弹层（底部抽屉、左右拉满）刻意不同：
   确认框要「打断」用户，而不是「展开一块面板」。 */
/* ★ 2026-09-11 岩峰定：确认框改为**屏幕正中卡片** —— 不再是底部抽屉、不再左右拉满。
   用「align-items:flex-start + margin:auto」做安全居中：内容比屏幕高时能滚动，
   内容不高时仍垂直居中（若直接写 align-items:center，高卡片的顶部会被裁掉）。 */
#askMask{
  z-index:70;                 /* 盖住业务弹层(.overlay=60)，低于日期选择器(200)与断网遮罩/toast(9999) */
  align-items:flex-start;
  justify-content:center;
  padding:var(--sp-4);
  overflow-y:auto;
}
.ask-sheet{
  width:100%;
  max-width:440px;            /* 最大宽度 440px：不左右拉满、四周留白 */
  /* ★ 2026-10-03：容器高度加 `dvh` 回退（vh 在前、dvh 紧跟）——
     手机浏览器可收起的地址栏会让 100vh 偏大 → 弹层底部按钮被顶出屏外。
     dvh 不支持的旧浏览器自动退回上一行 vh（写法与文件内 .login-screen 一致）。 */
  max-height:calc(100vh - 32px);
  max-height:calc(100dvh - 32px);
  margin:auto;
  border:1px solid var(--border-strong);
  border-left:3px solid var(--accent);
  border-radius:var(--r-lg);
  box-shadow:var(--shadow-2);
}
.ask-sheet.lv-caution{border-left-color:var(--warn)}
.ask-sheet.lv-danger{border-left-color:var(--bad)}
.ask-head{display:flex;align-items:center;gap:9px;margin-bottom:12px}
.ask-ico{width:22px;height:22px;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;border-radius:50%;font-size:var(--fs-xs);font-weight:500;background:var(--accent-soft);color:var(--accent)}
.lv-caution .ask-ico{background:var(--wa-soft);color:var(--warn)}
.lv-danger .ask-ico{background:var(--ba-soft);color:var(--bad)}
.ask-head h3{margin:0;font-size:var(--fs-lg)}
.ask-q{margin:0 0 7px;font-size:var(--fs-sm);line-height:1.7;color:var(--text)}
.ask-desc{margin:0 0 18px;font-size:var(--fs-sm);line-height:1.7;color:var(--muted)}
.ask-desc b{color:var(--text);font-weight:500}
.ask-desc .warn-txt{color:var(--bad);font-weight:500}
.ask-actions{display:flex;justify-content:flex-end;gap:var(--sp-3);margin-top:14px}
/* ===== 输入类弹窗的字段区（askInput 用；askConfirm 会把它隐藏）=====
   与 .ask-* 同卡片，不新造视觉语言。高度走 --h-ctl（36px）；≤820 抬到 44px 满足触控标准。
   字号不用管：≤820 已有全局 `input,select,textarea{font-size:16px!important}` 兜住。 */
.ask-field{margin:0 0 4px}
.ask-lbl{display:block;margin-bottom:6px;color:var(--muted);font-size:var(--fs-xs)}
.ask-inp{width:100%;height:var(--h-ctl);background:var(--panel2);border:1px solid var(--border-strong);border-radius:var(--r-md);padding:0 var(--sp-3);color:var(--text);font-family:inherit;font-size:var(--fs-sm)}
.ask-inp:focus{outline:none;border-color:var(--accent);box-shadow:var(--focus-ring)}
.ask-err{margin:var(--sp-2) 0 0;color:var(--bad);font-size:var(--fs-xs);line-height:1.5;display:none}
.ask-err.on{display:block}
@media (max-width:820px){ .ask-inp{height:44px} }
/* ★ 2026-10-09（v5）：原「实心危险/谨慎按钮」(.btn.solid-bad / .btn.solid-warn) 已并入
   危险档 / 告急档的**浅色填充**形态（规范第一条硬要求：全站没有实心档）。
   类名保留为兼容别名（见顶部 v5 块），markup 无需逐一改。 */
/* 确认框在手机上的形态：真·底部抽屉。
   ⚠️ ≤820 的 .sheet 是给「全屏弹层」用的（height:100vh / border-radius:0），
   确认框要按内容高度从底部升起，这几项必须显式覆盖回来（用 #askMask 前缀保特异性）。
   按钮竖排、危险项在上（破坏性操作离拇指最远，最不易误触），「取消」永远在最下面。 */
@media (max-width:820px){
  /* 手机端同样居中（岩峰 2026-09-11 定）。注意 ≤820 的 .sheet 是给「全屏弹层」用的
     （height:100vh / border-radius:0 / border-top:none / 无阴影），必须显式改回来，
     否则确认框会被拉成满屏 —— align-self 压不过显式的 height。 */
  #askMask .ask-sheet{
    height:auto;
    /* ★ 2026-10-03：dvh 回退（vh 在前、dvh 紧跟）——手机地址栏收起/展开时底部按钮不被裁 */
    max-height:calc(100vh - 32px);
    max-height:calc(100dvh - 32px);
    border-radius:var(--r-lg);
    border:1px solid var(--border-strong);
    border-left:3px solid var(--accent);     /* 简写 border 会重置左侧色条，这里按档补回 */
    box-shadow:var(--shadow-2);
    padding:var(--sp-4);
  }
  #askMask .ask-sheet.lv-caution{border-left-color:var(--warn)}
  #askMask .ask-sheet.lv-danger{border-left-color:var(--bad)}
  /* 按钮并排两列（取消在左 / 确认在右），各占一半 */
  #askMask .ask-actions{flex-direction:row;position:static;margin-top:12px}
  #askMask .ask-actions .btn{flex:1;width:auto}
}
.close{background:none;border:none;font-size:var(--fs-xl);color:var(--muted);cursor:pointer;line-height:1}
.empty{text-align:center;color:var(--text-2);padding:var(--sp-5) 0;font-size:var(--fs-md)}
.tip{background:var(--wa-soft);border:1px solid var(--wa-soft);color:var(--warn);font-size:var(--fs-xs);padding:var(--sp-2) var(--sp-3);border-radius:var(--r-sm);margin:var(--sp-2) 0;line-height:1.6}
.board-stats{display:flex;flex-direction:column;gap:var(--sp-3);margin-bottom:var(--sp-3)}
.stat-card-row{display:flex;gap:var(--sp-2);flex-wrap:wrap}
.stat-card{flex:1 1 64px;min-width:64px;background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);padding:var(--sp-2) var(--sp-1);text-align:center;box-shadow:var(--shadow-1);cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:56px;transition:transform .1s}
.stat-card:active{transform:scale(0.97);background:var(--panel2)}
/* ★ 2026-09-22（UI/UX 审计 P2）：看板 KPI 与「订单数据」页 KPI 原本是**两套视觉语言**
   （看板＝无图标纯数字直接染色；数据页＝图标片 + 彩色数字 + 标签）→ 管理者两页切换没有稳定预期。
   这里把看板卡片对齐到数据页那一族的语法：**左侧色条 + 同族渐变底**（蓝=常规 / 黄=预警 / 红=告警）。
   ★ 只加装饰层，不动数字与标签的位置（`.stat-card` 的数量与结构保持原样，冒烟断言不受影响）。 */
.stat-card{position:relative;overflow:hidden;background:linear-gradient(135deg,var(--accent-soft),var(--accent-soft));border-color:var(--accent-soft)}
.stat-card::before{content:'';position:absolute;left:0;top:0;bottom:0;width:4px;background:var(--accent)}
.stat-card.warn{background:linear-gradient(135deg,var(--wa-soft),var(--wa-soft));border-color:var(--wa-soft)}
.stat-card.warn::before{background:var(--warn)}
.stat-card.danger{background:linear-gradient(135deg,var(--ba-soft),var(--ba-soft));border-color:var(--ba-soft)}
.stat-card.danger::before{background:var(--bad)}
.stat-card .num{font-size:var(--fs-display);font-weight:700;color:var(--accent);line-height:1.1}
.stat-card .lbl{font-size:var(--fs-xs);color:var(--text-2);margin-top:3px}
.stat-card.warn .num{color:var(--warn)}.stat-card.danger .num{color:var(--bad)}
/* ★ 2026-10-11 删除留档：`.bg-title` / `.bg-cards`（旧看板分组折叠墙）与
   `.bcard` / `.card-stripe`（旧看板卡）专属 CSS 已随死链清理删除，原因见 :7075 区留档。
   ⚠ 全文 `:is(...)` / 组合选择器列表中残留的 `.bcard` 词条**有意保留**（零影响；避免触碰
   全局主题/玻璃样式链）—— 见它们时不必惊讶，`.bcard` 元素已不存在。 */
.bar-wrap{background:var(--panel);border-radius:var(--r-lg);padding:var(--sp-4);margin-bottom:var(--sp-3);box-shadow:var(--shadow-1)}
.bar-row{display:flex;align-items:center;margin:var(--sp-2) 0;font-size:var(--fs-sm)}
.bar-name{width:62px;color:var(--text);flex-shrink:0;font-weight:500}
.bar-track{flex:1;height:18px;background:var(--panel2);border-radius:var(--r-pill);overflow:hidden;display:flex;margin:0 10px}
.bar-fill{background:linear-gradient(90deg,var(--accent),var(--accent-d));height:100%;border-radius:var(--r-pill) 0 0 var(--r-pill)}
/* 工序负载**两段**互斥：正常(蓝) / 订单已逾期(红)。宽度已按总数算好，禁止 flex 收缩。
   ★ 2026-10-03：原第三段「工序已逾期(紫)」随概念退役删除。 */
.bar-track > div{flex-shrink:0}
.bar-overdue{background:var(--bad);height:100%}
.bar-num{color:var(--muted);flex-shrink:0;font-size:var(--fs-sm);min-width:70px;text-align:right;position:relative}
/* ★ 2026-09-22（UI/UX 审计 P2）：标记原来与"2单"同行 → 总宽度随文字变化，
   普通行数字靠最右、带"订单逾期1"的行数字落在页面中部，眼睛要在两个位置扫。
   改成标记**单独一行**（同样右对齐）→ 所有行的数字固定在同一列。
   ★ 2026-09-23（P2 续修）：标记改为**脱离文档流**（绝对定位挂在本行数字下方）。
     原来标记独占一行、把 .bar-num 撑成两行高；行内 align-items:center 居中的结果是
     带标记那行的数字相对同行的进度条上移（实测偏约 10px），与其它行的数字不在同一水平线上，
     看着"错位"。脱流后 .bar-num 恒为单行高、与进度条垂直居中 → 各行数字竖直对齐成一列；
     标记下移占位由 .bar-row.has-marks 的底部留白承担。 */
.bar-marks{display:block;position:absolute;left:0;right:0;top:100%;margin-top:1px;font-weight:600;text-align:right}
/* ★ 2026-09-29（岩峰定·方案乙·竖排两行）：原 `white-space:nowrap` 让两段挤在一行（实测 138px），
   而宿主 .bar-num 只有 70px → 右端溢出 68px 被裁。现改为**每段独立成行**（.bar-marks>b{display:block}），
   最宽一段仅 ≈75px，完整落在 70px 列内；横向零侵占（进度条宽度不变，手机端 154px 不被挤短）。
   代价：标记由 1 行变 2 行 → 行底留白从 20px 提到 37px（见下方 .bar-row 规则，所有行统一加、行高仍全等）。
   ★ 注意：`white-space` 只在下面这条规则里声明一次（原第一条也写了一份 nowrap，两条同权重靠顺序决胜负，
     属定时炸弹，已删——单一来源，日后调顺序不会复发）。 */
.bar-marks{font-size:var(--fs-xs);white-space:normal;line-height:1.35}
.bar-marks > b{display:block}
/* ★ 2026-09-23（岩峰定·行高抹平）：上一批只给**带标记的行**（.has-marks）加 padding-bottom，
   于是那一行比别的行高约 9px —— 行高不齐，「工序负载 / 各人当前持有」看着一高一低。
   改为给**所有行统一加同样的底部留白**：标记脱流后需要的下移空间人人都有，
   各行 offsetHeight 完全一致（布局探针断言全等）。保留了 .has-marks 规则（同值，不再单独加高）。
   ★ 2026-09-29（方案乙）：标记由 1 行变 2 行（≈17px）→ 留白同步 20px → 37px，**两处同值一起改**，
   否则带标记的行会比普通行高 17px、行高全等断言立刻红。 */
.bar-wrap .bar-row{padding-bottom:37px}
.bar-row.has-marks{padding-bottom:37px}
.mk-bad{color:var(--bad)}
.bar-legend{font-size:var(--fs-sm);color:var(--text-2);margin-top:10px;padding-top:8px;border-top:1px dashed var(--border)}
.bar-legend i{display:inline-block;width:12px;height:12px;border-radius:var(--r-xs);margin:0 var(--sp-1) 0 var(--sp-3);vertical-align:-2px}
*{scrollbar-width:thin;scrollbar-color:var(--border-strong) transparent}
*::-webkit-scrollbar{width:10px;height:10px}
*::-webkit-scrollbar-track{background:transparent}
*::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:var(--r-pill);border:2px solid var(--bg)}
*::-webkit-scrollbar-thumb:hover{background:var(--accent)}

.info-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3) var(--sp-4);margin:14px 0}
.info-item{display:flex;flex-direction:column;gap:3px}
.info-item.full{grid-column:1/-1}
.info-label{font-size:var(--fs-xs);color:var(--muted)}
.info-value{font-size:var(--fs-md);color:var(--text-2);word-break:break-word;line-height:1.5}
.info-value b{color:var(--text)}
.flow-grid{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--sp-2);margin:10px 0 14px}
/* ★ 2026-10-07（岩峰：手机端「工序进度」只露出一排半截弧形）：**不许被 flex 压扁**。
   根因（真机 390 实测）：<981px 时 `#detailBody` 是 `flex-direction:column`，`.flow-grid` 是它的
   flex 子项；而 `.flow-grid` 自己在 ≤820 上带 `overflow-x:auto` ⇒ **自动最小尺寸 = 0**
   ⇒ 一旦父容器高度受限，它就被压成「只剩 padding」的 8px（实测 grid h=8 / 内容 40、点 13px）
   ⇒ 13px 的圆点只画出一半，看起来就是"一排半截弧形"。
   修法：`flex:0 0 auto`（网格布局下该属性被忽略 ⇒ 桌面零影响）。 */
.flow-grid{flex:0 0 auto}
.flow-grid .flow-step{flex:1;display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--sp-2);font-size:var(--fs-xs);color:var(--muted);margin:0;position:relative;padding:0 2px}
.flow-grid .flow-step .dot{width:10px;height:10px;border-radius:50%;background:var(--border-strong)}
.flow-grid .flow-step.done .dot{background:var(--good)}
.flow-grid .flow-step.done{color:var(--good)}
.flow-grid .flow-step.cur .dot{background:var(--bad);box-shadow:0 0 0 2px var(--panel), 0 0 0 3px var(--ba-soft);width:12px;height:12px}
.flow-grid .flow-step.cur{color:var(--bad);font-weight:600}
.flow-grid .flow-step::after{content:'→';position:absolute;right:-7px;top:0;color:var(--border-strong);font-size:var(--fs-xs)}
.flow-grid .flow-step:last-child::after{display:none}

.detail-summary{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-3);margin:var(--sp-3) 0;padding:14px;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--shadow-1)}
/* ★ 2026-10-03（岩峰定稿）：详情卡汇总条新增「颜色交期」第 5 格 → 用**修饰类 c5** 只在**有**颜色交期时变列数。
   为什么不直接改上面的基础 4 列规则：没配颜色交期的单只有 4 格，若按 5 列排会**右侧空一格**（岩峰要"没配不占位"）。
   窄屏同理：≤820 / ≤380 时 5 格排成 3+2，**不留孤卡**（见下方两处 .c5 覆盖）。 */
.detail-summary.c5{grid-template-columns:repeat(5,1fr)}
/* ★ 第 68 批（交付日期第 6 格）：同时有「颜色交期 + 交付日期」时 6 格 → c6（沿用 c5「有才占位」思路，最多到 6）。 */
.detail-summary.c6{grid-template-columns:repeat(6,1fr)}
.sum-item{text-align:center}
.sum-label{font-size:var(--fs-xs);color:var(--muted);margin-bottom:4px}
.sum-value{font-size:var(--fs-lg);color:var(--text-2);font-weight:600}
.detail-card{background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-lg);padding:14px;margin-bottom:12px;box-shadow:var(--shadow-1)}
.detail-card-title{font-size:var(--fs-sm);color:var(--accent-text);font-weight:600;margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--border)}
.info-grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:12px 16px}
.kv{display:flex;flex-direction:column;gap:3px}
.kv.full{grid-column:1/-1;margin-top:4px}
.kv .k{font-size:var(--fs-xs);color:var(--muted)}
.kv .v{font-size:var(--fs-md);color:var(--text-2);word-break:break-word;line-height:1.5}
@media (max-width:900px){
  main{padding:var(--sp-3) var(--sp-2)}
  header{padding:var(--sp-3) var(--sp-4)}
  .card{padding:var(--sp-4)}
  .filter-row{gap:6px}
  .dash-grid{grid-template-columns:repeat(2,1fr)}
  /* 云端数据监控台·总览栅格（本页专有）：必须写在这块**之内/之后**才能压过上一行的 .dash-grid。
     6 张卡 ÷ 2 列 = 3 行，整除、末行不留孤卡。详见 .dbv-ov-grid 顶层那条注释。 */
  .dbv-ov-grid{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:820px){
  body{overflow-x:clip;padding-bottom:calc(66px + env(safe-area-inset-bottom))}
  input,select,textarea{font-size:var(--fs-lg)}
  .btn{min-height:44px;font-size:var(--fs-md)}
  .btn-sm{min-height:40px;height:auto}
  .detail-summary{grid-template-columns:repeat(2,1fr)}
  .detail-summary.c5{grid-template-columns:repeat(3,1fr)}
  /* ★ 第 68 批（交付日期第 6 格）：窄屏 ≤820 时 6 格与 5 格同为 3 列（3+3），不留孤卡。 */
  .detail-summary.c6{grid-template-columns:repeat(3,1fr)}
  .info-grid-3{grid-template-columns:repeat(2,1fr)}
  nav{position:fixed;left:0;right:0;bottom:0;z-index:50;gap:0;padding:0;border-bottom:none;border-top:1px solid var(--edge);background-color:var(--m-thick);-webkit-backdrop-filter:blur(22px) saturate(1.75);backdrop-filter:blur(22px) saturate(1.75);box-shadow:0 -8px 24px -12px var(--lift);overflow-x:visible}
  nav button{flex:1;min-width:0;padding:var(--sp-3) 2px;font-size:var(--fs-xs);min-height:44px;border-bottom:none;border-top:2px solid transparent}
  nav button.active{border-bottom:none;border-top-color:var(--accent)}
  /* ★ 2026-09-22（UI/UX 审计 P0-4）：底栏收敛 —— 只保留前 MOBILE_NAV_MAX 个可见页签，
     其余加 .nav-over 收进「更多」抽屉。**只改显隐、不改 DOM 顺序**，
     导航顺序铁律（DOM / TAB_FEAT / 权限页 三处同源）不受影响。
     为什么：9 项挤 375px 时每项约 43px、字号 11px，工人戴手套易点错隔壁（尤其误触「订单录入」）。 */
  nav button.nav-over{display:none}
  #moreNavMask{position:fixed;inset:0;z-index:65;background:rgba(0,0,0,.5);display:flex;align-items:flex-end}
  .more-nav-box{width:100%;background:var(--panel);border-top:1px solid var(--border);border-radius:var(--r-lg) var(--r-lg) 0 0;padding:var(--sp-3) var(--sp-3) 78px;box-shadow:0 -8px 24px rgba(0,0,0,.45)}
  .more-nav-title{font-size:var(--fs-sm);color:var(--muted);padding:2px 4px 10px}
  #moreNavList button{width:100%;min-height:48px;display:flex;align-items:center;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-md);color:var(--text);font-size:var(--fs-lg);font-family:inherit;padding:0 14px;margin-bottom:8px}
  #moreNavList button.active{border-color:var(--accent);color:var(--accent)}
  /* ★ 2026-09-22（UI/UX 审计 P2）：备注框右下角的 resize 小三角在触屏上是纯干扰
     （手指拖不动、还容易误触）→ 手机端关掉；桌面保留（有鼠标时确实有用）。 */
  textarea{resize:none}
  .filter-toggle{display:inline-flex}
  .filter-panel{display:none}
  .filter-panel.open{display:flex;flex-direction:column;gap:var(--sp-4)}
  .filter-row{flex-direction:column;gap:var(--sp-2)}
  .filter-row + .filter-row{margin-top:0}
  .filter-row select,.filter-row input,.filter-date-group{width:100%;min-width:0;flex:none;max-width:none}
  .filter-row input#fKeyword{width:100%;min-width:0;flex:none}
  .filter-date-group .date-trigger{width:100%;min-height:48px}
  .filter-row select,.filter-row input{min-height:48px}
  .filter-row input#fKeyword{min-height:52px}
  .filter-row .btn,.filter-actions .btn{flex:1;min-width:0;width:100%}
  .stat-card-row{display:grid;grid-template-columns:1fr 1fr;gap:8px}
  .stat-card{min-height:64px}
  .dash-grid{grid-template-columns:repeat(2,1fr)}
  .item-fields{display:grid;grid-template-columns:1fr 1fr}
  /* 日期触发器与原生 select 在手机端统一最小高度 44px（与苹果推荐触摸目标一致）；录单页「品牌」select 与「交期」date-trigger 高度对齐 */
  .date-trigger,select{min-height:44px}
  .sheet-actions{position:sticky;bottom:0;z-index:5;margin:14px calc(-1 * var(--sp-4)) 0;padding:var(--sp-3) var(--sp-4) calc(var(--sp-3) + env(safe-area-inset-bottom));background:var(--panel);border-top:1px solid var(--border);box-shadow:0 -8px 24px rgba(0,0,0,.45)}
  /* ★ 方案B（2026-09-11 岩峰定）：手机端详情弹层操作区收成两行 + 「更多」抽屉。仅 ≤820 生效。
     动机：超管视角 8 个按钮平铺占 225px（4 行），把内容区挤到只剩 603px。
     ⚠️ 断点 820 是**三处同源**：本 CSS 块 / isMobile() / openDetail() 的 matchMedia('(max-width:820px)')。
        改一处必须改三处（全盘 grep `max-width:820px` 与 `isMobile`）。
     ⚠️ 兜底与关键操作不进抽屉：交付/退回/质检/发货/派单/加急 恒定可见。 */
  /* ★ 2026-09-29（功能键归位）：本段原有的「操作区自适应网格 + 更多抽屉」样式
     —— `.sheet-actions .sa-row`（grid auto-fit / 行距 / 等宽 / 换行）、`.sa-more` /
     `.sa-more-btn` / `.sa-more-list`（抽屉面板与其内按钮）、`.sa-hint`（已随 09-29
     「删悬浮与提示」废弃）——**约 40 行已整段删除**。
     原因：详情弹层的**吸底操作区**与**「更多」抽屉**都已取消，按钮改为分散到各区块
     （`.rowbtn`，见其定义处）。保留下来的 `.sheet-actions` 规则服务的是**其它弹层**
     （askInput / 报告异常 / 统计列表等），它们仍在用这个容器。 */
  .sheet-actions>.btn{flex:1;min-width:calc(50% - 4px)}
  .sheet>.btn-block{position:sticky;bottom:0;margin-top:12px}
  /* ★ 2026-09-23（吸底按钮遮挡内容 P0 修）：手机端弹层改为「内容区独立滚动 + 底部栏不参与滚动」。
     原来 .sheet 是整屏滚动容器、主按钮 sticky 吸底 → 滚动时按钮浮在内容之上；当弹层内容总高
     略超视口时按钮正好压住最后一个字段（QA 实测：360×800 压住必填 textarea 44px，393×852 压住
     「编辑订单」明细输入框 34px）。内容由页内包装器（见下方 .sheet-body 包装 IIFE）包进 .sheet-body；底部主按钮/操作区
     留在其外，靠 flex 上下分开 → 按钮仍吸底可见，但永不遮内容。
     ⚠ 只在确实拆出 .sheet-body（宿主带 .sheet-hot）时生效；未拆分的弹层（如统计列表无吸底按钮）
       保持原滚动行为，避免"内容被 overflow:hidden 裁掉又滚不动"。 */
  #modalBody.sheet-hot,#detailBody.sheet-hot{display:flex;flex-direction:column;overflow:hidden}
  #modalBody.sheet-hot>.sheet-body,#detailBody.sheet-hot>.sheet-body{flex:1 1 auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}
  #modalBody.sheet-hot>.btn-block,#modalBody.sheet-hot>.btn-primary,#detailBody.sheet-hot>.sheet-actions{position:static;flex:0 0 auto}
  .overlay{align-items:stretch;padding:0;background:rgba(0,0,0,.9)}
  .sheet{height:100vh;height:100dvh;max-height:100vh;max-height:100dvh;border-radius:0;border-top:none;box-shadow:none;padding:var(--sp-4);padding-top:calc(var(--sp-4) + env(safe-area-inset-top))}
  .date-pop{width:calc(100vw - 24px);max-width:320px}
  .date-pop .dp-cell{height:44px}
  /* 移动端顶栏紧凑化：四元素（logo·标题·用户·云标）挤一行会横向溢出，隐藏用户、缩小字号与 logo */
  header{padding:var(--sp-3) var(--sp-3);gap:8px}
  header h1{font-size:var(--fs-lg);letter-spacing:.2px}
  header .user{display:none}
  .app-logos{gap:7px}
  .app-logos img{height:22px}
  .app-logos img.logo-weeduo{height:18px;transform:translateY(-1px)}
  .app-logos .logo-sep{height:18px}
  #cloudBadge{margin-left:auto;font-size:var(--fs-xs);padding:1px var(--sp-2);max-width:42vw;overflow:hidden;text-overflow:ellipsis}
  /* 工序链窄屏横向滚动：9 道工序并排 column 布局在窄屏文字会重叠。
     ★ 2026-10-08（岩峰：「进度UI好像被工序进度的背景UI挡住了，往下移一点」）——
       **真因 = 这里的 padding 与"当前工序"柔光的半径对不上了**：
       `overflow-x:auto` 按规范会把 `overflow-y` 也计算成 `auto` ⇒ 本元素是**会裁切的滚动容器**，
       内边距以外一律切平。当初只按「凸出 3px 的光环」留了 4px；后来柔光改成
       `0 0 0 4px … , 0 0 14px …`（**半径 14px**），padding 没跟着改 ⇒
       真机实测：容器上沿往上一点是纯背景（ΔE=0），到容器上沿**突然跳到 ΔE=96**，
       柔光被**齐刷刷切出一条硬边**，看上去就是"被上面的东西压住了"。
       ⇒ 修法：留 16px（柔光 14px + **2px 余量**，防亚像素舍入把它又蹭到边界上；
       下边不用留——点下方是标签区，柔光本来就在容器内）。
       ⚠ 以后若再调这里「当前工序」柔光的半径，**这个 padding-top 必须同步改**，否则又会被切。
       ★ 判据已挂门禁：`_tools/_verify_b60.js` ⑫「柔光外沿落在裁切边界内」，余量会打印出来。 */
  .flow-grid{overflow-x:auto;-webkit-overflow-scrolling:touch;padding:16px 0 4px 0}
  .flow-grid .flow-step{min-width:52px}
  /* 订单卡首行允许换行：长标签（加急+类型+品牌+状态）挤压单号的问题 */
  .card .row1{flex-wrap:wrap;row-gap:6px}
  .order-no{flex-shrink:0}
}
@media (max-width:380px){
  .card{padding:var(--sp-2)}
  .section-title{margin:var(--sp-2) var(--sp-1)}
  .info-grid-3{grid-template-columns:1fr}
  .detail-summary{grid-template-columns:1fr 1fr}
  .detail-summary.c5{grid-template-columns:repeat(3,1fr)}
  /* ★ 第 68 批（交付日期第 6 格）：极小屏 ≤380 时 6 格与 5 格同为 3 列（3+3），不留孤卡。 */
  .detail-summary.c6{grid-template-columns:repeat(3,1fr)}
  .dash-grid{grid-template-columns:1fr}
  /* 云端数据监控台·总览栅格（本页专有）：6 张卡 ÷ 1 列，整除、不留孤卡。同 900 块的说明。 */
  .dbv-ov-grid{grid-template-columns:1fr}
  .item-fields{grid-template-columns:1fr}
  nav button{font-size:var(--fs-xs);padding:8px 1px}
  .app-logos img{height:20px}
  .app-logos img.logo-weeduo{height:17px}
  .app-logos .logo-sep{height:16px}
  /* 极小屏：标题与云标进一步缩小；分布图标签收窄，避免挤压进度条 */
  header h1{font-size:var(--fs-lg)}
  #cloudBadge{font-size:var(--fs-xs);padding:1px 5px;max-width:38vw}
  .bar-label{width:84px;font-size:var(--fs-xs)}
  .bar-pct{width:36px}
  .bar-rank{width:22px;height:22px;font-size:var(--fs-xs)}
}
/* ===== 权限管理（角色导航 + 开关点即存；双色走变量，双端 820 断点） ===== */
.pm-layout{display:flex;gap:var(--sp-3);align-items:flex-start}
/* ★ 2026-09-11 岩峰定：左栏宽度 **190px → 250px**，与考核系统对齐（两页一起改：角色权限 + 人员管理）。
   这是共用类，改一处两页同时生效 —— 有意为之，别再"顺手"改回 190（详见交付物
   `deliverables/两系统人员管理UI尺寸对照/`）。手机端 ≤820 由 `.pm-side{width:100%}` 覆盖，不受影响。 */
.pm-side{width:250px;flex-shrink:0;background:var(--panel);border:1px solid var(--border);border-top-color:var(--hair);border-radius:var(--r-lg);padding:var(--sp-2);position:sticky;top:70px}
.pm-side-head{display:flex;align-items:center;justify-content:space-between;padding:2px var(--sp-2) var(--sp-2);border-bottom:1px solid var(--border);margin-bottom:6px;color:var(--muted);font-size:var(--fs-xs)}
.pm-role{padding:var(--sp-2) var(--sp-3);border-radius:var(--r-md);cursor:pointer;color:var(--text-2);display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);border:1px solid transparent;font-size:var(--fs-sm)}
.pm-role:hover{background:var(--panel2)}
.pm-role.active{background:var(--accent-soft);color:var(--text);border-color:var(--accent)}
/* 列表条目右侧的副信息（人员管理＝权限角色名 / 角色权限＝N 项）。
   ★ 2026-09-11 岩峰定：**去掉底色胶囊，改成裸文字**，与考核系统一致（两页一起改）。
   保留 `flex-shrink:0` —— 那是排版安全属性（防止长角色名把「N 项」挤扁），不影响外观，
   考核系统那边靠结构规避，这边保留更稳。 */
.pm-role .c{font-size:var(--fs-xs);color:var(--muted);flex-shrink:0}
/* ---- 人员管理左栏条目（两行结构，2026-09-11 照抄考核系统人员管理）----
   ⚠ 单起 .pm-role-p 修饰类、**不动共用的 .pm-role**：角色权限页的左栏是同款 .pm-role，
     但那是「姓名 + 项数」单行 flex；这里要「姓名+角色 / 岗位·部门」两行，
     若直接改 .pm-role 的 display，角色权限页左栏会被一起改坏。 */
.pm-role.pm-role-p{display:block}
.pm-role-main{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);min-width:0}
.pm-role-main>.n{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:var(--fs-xs);flex:1 1 auto;min-width:0;line-height:1.3}
.pm-role-main>.c{flex-shrink:0;margin-left:6px}
.pm-role-desc{font-size:var(--fs-xs);color:var(--muted);margin-top:3px;line-height:1.5;white-space:normal;overflow-wrap:anywhere}
/* ---- 任职信息（失焦即存）：标签 + 输入框 ---- */
.pm-prof{display:flex;flex-direction:column;gap:var(--sp-2);padding:var(--sp-3) var(--sp-4) var(--sp-4)}
.pm-prof label{display:flex;align-items:center;gap:var(--sp-3);margin:0}
/* ★ 2026-10-09（第 74 批③）：宽已固定 48px；补 `text-align-last:justify` 与设置页标签列同款
   （两端对齐 ⇒ 首字/尾字都齐；本页四个标签都是 2 字，视觉不变，只为口径统一）。 */
.pm-prof label>span{flex:0 0 48px;color:var(--muted);font-size:var(--fs-sm);text-align:justify;text-align-last:justify}
/* ★ 2026-10-12（第 89 批·岩峰报）：手机号（本卡唯一的文本输入）此前用 `--h-dense`(30px) + `--fs-sm`(13px)，
   而同行四个下拉（岗位/品牌/部门/级别）走全局 `input,select,textarea` 的 `--h-ctl`(36px) + `--fs-md`(14px)
   ⇒ 同一张卡里「手机号框比下拉矮 6px、字也小一号」（岩峰截图指出）。
   改：显式对齐到与下拉**完全同档**（36px / 14px；下方 `!important` 全局规则只压 bg/border/color，
   height/font-size 无 `!important` ⇒ 本处更高优先级生效）。 */
.pm-prof input{height:var(--h-ctl);font-size:var(--fs-md);flex:1;min-width:0}
.pm-empty{padding:var(--sp-4);color:var(--muted);font-size:var(--fs-sm)}
.pm-main{flex:1;min-width:0}
.pm-card{background:var(--panel);border:1px solid var(--border);border-top-color:var(--hair);box-shadow:var(--shadow-1);border-radius:var(--r-lg);margin-bottom:var(--sp-3);overflow:hidden}
.pm-head{display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border);flex-wrap:wrap}
.pm-title{font-size:var(--fs-lg);font-weight:500}
.pm-desc{color:var(--muted);font-size:var(--fs-xs);flex:1;min-width:0;white-space:normal;overflow-wrap:anywhere}
.pm-msg{font-size:var(--fs-xs);color:var(--muted);margin-left:auto}
.pm-msg.err{color:var(--bad)}
.pm-gh{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-2) var(--sp-4);background:var(--accent-soft);color:var(--accent);font-size:var(--fs-xs);font-weight:500;border-bottom:1px solid var(--border)}
.pm-gh a{cursor:pointer;text-decoration:underline;text-underline-offset:2px}
.pm-row{display:flex;align-items:center;gap:var(--sp-3);padding:9px var(--sp-4);border-bottom:1px solid var(--border);font-size:var(--fs-sm)}
/* ★ 2026-10-13（岩峰定 · UI 审计 10）：整行可点 —— 行给出手型与悬停底色，
   点标签/空白处都能切开关（原来只有右侧 38px 的开关可点，标签到开关之间是死区）。
   ⚠ 悬停底色用 `--panel2`（不是 `--m-*`）：`--m-*` 是玻璃遮罩，浅色主题下在白卡上看不见。 */
.pm-row[onclick]{cursor:pointer;min-height:44px}
/* ★ 2026-10-13（第37批探针咬合）：整行可点后，`.pm-row` 自己成了**触控目标** ——
   实测高 40px（9 内边距 + 22 开关 + 9），低于全站「触控热区 ≥44」的铁律。
   这里补 `min-height:44px`（只给可点行，不影响别的）。 */
.pm-row[onclick]:hover{background:var(--panel2)}
.pm-row:last-child{border-bottom:none}
.pm-row.danger .lbl{color:var(--bad)}
.pm-row.hid{display:none}
.pm-row .pm-spacer,.pm-gh .pm-spacer{flex:1}
/* ★ 2026-09-11 岩峰定：开关规格与考核系统对齐 —— 高度 20→22、圆点 14→16、开启时 left 20→18。
   （考核那边是在桌面基线上有意调的，有注释为证；不是 bug 导数）
   手机端命中区同步由 ±12px 收到 ±11px（22+22=44，仍达标），保持 44px 触控目标。 */
.pm-tgl{position:relative;width:38px;height:22px;border-radius:var(--r-pill);background:var(--chip);border:1px solid var(--border-strong);cursor:pointer;flex-shrink:0;transition:background .15s,border-color .15s}
.pm-tgl::after{content:'';position:absolute;left:2px;top:2px;width:16px;height:16px;border-radius:50%;background:var(--muted);transition:left .15s,background .15s}
.pm-tgl.on{background:var(--accent);border-color:var(--accent)}
.pm-tgl.on::after{left:18px;background:#fff}
.pm-tgl.busy{opacity:.5;pointer-events:none}
/* ★ 2026-09-22（P1-5）：开关旁的**文字状态** —— 触屏上没有 hover 提示，只靠颜色会看反 */
.pm-tg-txt{font-size:var(--fs-xs);color:var(--muted);margin-right:8px;flex-shrink:0;white-space:nowrap}
.pm-tg-txt.on{color:var(--accent)}
.pm-members{display:flex;flex-wrap:wrap;gap:var(--sp-2);padding:var(--sp-3) var(--sp-4)}
.pm-mem{display:inline-flex;align-items:center;gap:var(--sp-1);border:1px solid var(--border);border-radius:var(--r-pill);padding:var(--sp-1) var(--sp-3);color:var(--muted);cursor:pointer;font-size:var(--fs-sm);user-select:none;transition:border-color .15s,color .15s}
.pm-mem:hover{border-color:var(--border-strong);color:var(--text-2)}
.pm-mem.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.pm-mem.busy{opacity:.5;pointer-events:none}
@media (max-width:820px){
  .pm-layout{flex-direction:column}
  .pm-side{position:static;width:100%;display:flex;align-items:center;gap:var(--sp-2);overflow-x:auto;-webkit-overflow-scrolling:touch;padding:8px}
  .pm-side-head{border-bottom:none;margin-bottom:0;padding:0 2px;flex-shrink:0}
  .pm-side-head span{white-space:nowrap}
  .pm-role{flex-shrink:0;white-space:nowrap}
  /* 人员管理的两行条目：横向滚动条里要给出最小宽度，否则会被 nowrap 压成一条 */
  .pm-role.pm-role-p{width:auto;min-width:136px;white-space:normal}
  .pm-role-desc{white-space:nowrap}
  .pm-prof{padding:var(--sp-3)}
  .pm-desc{flex-basis:100%;white-space:normal}
  .pm-mem{padding:6px 14px}
}
@media (max-width:380px){
  .pm-row{padding:10px var(--sp-3)}
  .pm-members{padding:var(--sp-3)}
}
/* ---- 权限页二级页签 + 人员管理视图 ---- */
.pm-tabs{display:flex;gap:var(--sp-1);margin-bottom:var(--sp-3);background:var(--panel);border:1px solid var(--border);border-top-color:var(--hair);box-shadow:var(--shadow-1);border-radius:var(--r-lg);padding:var(--sp-1);width:fit-content;max-width:100%}
.pm-tab{border:none;background:transparent;color:var(--muted);padding:7px 18px;border-radius:var(--r-md);cursor:pointer;font-size:var(--fs-sm);font-family:inherit;white-space:nowrap}
.pm-tab:hover{color:var(--text-2)}
.pm-tab.active{background:var(--accent);color:var(--on-accent);font-weight:500}
.pm-addperson{padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border);background:var(--panel2);display:flex;flex-direction:column;gap:var(--sp-3)}
.pm-form-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:var(--sp-2) var(--sp-3)}
.pm-form-grid label{display:flex;flex-direction:column;gap:var(--sp-1);font-size:var(--fs-xs);color:var(--muted)}
.pm-form-grid input,.pm-form-grid select{height:var(--h-ctl);background:var(--panel);border:1px solid var(--border);border-radius:var(--r-md);padding:0 var(--sp-3);color:var(--text);font-family:inherit}
.pm-form-grid input:focus,.pm-form-grid select:focus{outline:none;border-color:var(--accent);box-shadow:var(--focus-ring)}
/* 表单栅格里的同行按钮（如「登录密码」右侧的「显示/隐藏」）要与输入框同高（2026-09-10 岩峰反馈）：
   .btn-sm 默认 28px、输入框是 --h-ctl 36px，一行里按钮矮 8px、底边不齐，看着"陷下去"。
   作用域安全：新增人员 / 编辑花名册两个栅格内都只有这一个按钮。 */
/* ★ 2026-10-09（v5 §5.2）：删除原 `padding:0 var(--sp-3)`（12px）—— 与 .btn 的 16px 冲突；
   只保留"与同排输入框等高"这一条目的。 */
.pm-form-grid .btn{height:var(--h-ctl)}
@media (max-width:820px){
  /* 移动端按钮有 40px 点击目标要求（见上方 .btn-sm{min-height:40px}）；
     让同排输入框一起提到 40px，否则会变成「按钮比输入框高 4px」的新错位。
     （本块必须放在上一条 .pm-form-grid 规则之后，靠源码顺序压过默认的 --h-ctl。） */
  .pm-form-grid input,.pm-form-grid select,.pm-form-grid .btn{height:40px;min-height:40px}
  /* 同一道理：601~820px 仍走表格布局（移动卡片阈值是 ≤600），
     此时表格内的保存/删除按钮被 .btn-sm 提到 40px，而输入框/下拉还是 30px ——
     整行参差。这里把表格内控件一并抬到 40px，保持与按钮等高。 */
  /* ★ 2026-10-09（第 74 批⑤）：`.cap-table.cap-steps td.cap-ops .btn` 已从本组**移除** ——
     该格里的「删除」已改成 `.sys-del`（纯红字、无按钮外观），不再有 `.btn`。 */
  .cap-table.cap-steps td input.st-name,
  .cap-table.cap-steps td input.cp-input,
  .cap-table.cap-steps td select{height:40px;min-height:40px}
}
.pm-form-label{font-size:var(--fs-xs);color:var(--muted);margin-bottom:6px}
.cap-table-wrap{overflow-x:auto}
/* ★ 2026-10-03（岩峰）：列表底部「+ 新建工序」整行按钮 ——
   原来挂在卡片标题行右侧（挤在表头边上、手机上单手够不着），改为**列表最后一行**的形态：
   整行可点、虚线描边、字号与表格一致，像台账「添一行」；手机上升高到 44px 触控高度。 */
.cap-addrow{display:flex;align-items:center;justify-content:center;gap:var(--sp-2);width:100%;height:38px;
  margin-top:var(--sp-2);background:transparent;border:1px dashed var(--border-strong);border-radius:var(--r-sm);
  color:var(--text-2);font-size:var(--fs-md);font-family:inherit;cursor:pointer;
  transition:border-color .15s,color .15s,background .15s}
.cap-addrow:hover{border-color:var(--accent);color:var(--accent)}
.cap-addrow:active{background:var(--panel2)}   /* --hover 不存在 → 用实有的 panel2 做按下反馈 */
.cap-addrow:focus-visible{outline:none;border-color:var(--accent);box-shadow:var(--focus-ring)}
@media (max-width:820px){.cap-addrow{height:44px;min-height:44px}}
.cap-table{width:100%;border-collapse:collapse;font-size:var(--fs-sm)}
/* ★ 2026-10-05（岩峰定·全站统一 C）：表头与内容一并居中 */
.cap-table th,.cap-table td{padding:var(--sp-2) var(--sp-3);border-bottom:1px solid var(--border);text-align:center}
.cap-table th{background:var(--panel2);color:var(--muted);font-weight:500;font-size:var(--fs-xs);position:sticky;top:0;z-index:1}
.cap-table td{color:var(--text);vertical-align:middle}
.cap-input{width:78px;height:28px;background:var(--panel);border:1px solid var(--border);border-radius:var(--r-sm);padding:0 var(--sp-2);color:var(--text);font-family:inherit;font-size:var(--fs-sm);text-align:right}
.cap-input:focus{outline:none;border-color:var(--accent);box-shadow:var(--focus-ring)}
/* ★ 2026-09-28：`.cap-input.cap-factor` / `.cap-unit` / `.cap-eq` / `.cp-grid`（产能专属样式）
   已随产能功能整套移除。 */
/* ⚠ 2026-09-11 人员管理改两栏后，以下旧"单栏人员行"样式已随 ppRow/ppBindToggle 一并删除：
   .pm-person / .pp-info / .pp-name / .pp-sub / .pp-roles / .pm-rolechip / .pp-addrole /
   .pp-binder / .pp-status / .pp-ops（人员行的角色胶囊改用通用的 .pm-mem，与考核系统同款）。
   新样式见上方 `.pm-role-p` / `.pm-prof` / `.pm-empty`。 */
/* ★ 2026-10-03（岩峰定·全站即时保存）：字段改动**已写库** → 该行/卡**闪一下绿底**。
   为什么不用 toast：一次改好几个字段就会连弹好几个，太吵；
   为什么不在行尾插「已保存」文字：会改变行的宽度/布局（工序表是定宽列，插一个元素就错位）。 */
.sys-ok{animation:sys-ok .9s ease-out}
@keyframes sys-ok{0%{background:var(--ok-soft)}100%{background:transparent}}
.pm-hidden{display:none!important}
@media (max-width:820px){
  .pm-tabs{width:100%}
  .pm-tab{flex:1;text-align:center}
}

/* ---- 权限管理 · 手机端重新适配（2026-09-09：新增工序管理第 4 视图后）---- */
@media (max-width:820px){
  .pm-layout{flex-direction:column;align-items:stretch}
  .pm-side{width:100%;position:static;flex-direction:row;flex-wrap:wrap;gap:var(--sp-2);border-radius:var(--r-md);padding:var(--sp-2);display:flex;align-items:center}
  .pm-side-head{width:100%;flex:none;margin-bottom:2px}
  .pm-role{flex:1 1 calc(50% - 8px);max-width:none}
  .pm-main{width:100%}
}
@media (max-width:560px){
  .pm-tabs{display:grid;grid-template-columns:repeat(2,1fr);gap:6px}
  .pm-tab{flex:none;padding:var(--sp-2) var(--sp-1);white-space:nowrap}
  .pm-role{flex:1 1 100%}
  .cap-table{min-width:600px}
}

/* ★ 2026-09-28：`.cp-grid`（产能卡片网格）已随产能功能整套移除。 */

/* 工序管理卡片（手机端卡片式 UI · 2026-09-09 重做） */
.st-card{padding:var(--sp-3)}
.st-top{display:flex;align-items:center;gap:var(--sp-2);margin-bottom:var(--sp-2)}
.st-name{flex:1;min-width:0;font-size:var(--fs-lg);font-weight:600;color:var(--text);background:transparent;border:1px dashed transparent;border-radius:var(--r-md);padding:var(--sp-2) var(--sp-2);font-family:inherit}
.st-name:hover,.st-name:focus{border-color:var(--accent);background:var(--panel);outline:none}
/* 工序管理·状态列：与「订单类型」一致 —— 文字「启用」+ 开关胶囊。
   .pm-tgl 是 <span>，在表格单元格里必须用 inline-flex 包一层才会按 38×22 渲染
   （纯 inline 元素的 width/height 会被忽略）。 */
.st-ena{display:inline-flex;align-items:center;gap:var(--sp-2);vertical-align:middle}
/* 工序表「状态」「操作」两列必须整行不折（2026-09-10 岩峰反馈）：
   这两列的单元格允许折行时，浏览器会把它压到「一个字宽」的最小值 ——
   结果「启用」竖成两行、保存/删除上下堆叠，列宽也被挤歪，表头看着就对不上内容了。
   加 nowrap 后它们顶住真实最小宽度，多出来的宽度由「工序名」列的富余（输入框固定 96px）让出。 */
.cap-table .st-ena,.cap-table .st-ena .sys-lab{white-space:nowrap}
.cap-table td.cap-ops{white-space:nowrap}
/* 工序表列宽固定（2026-09-10 岩峰反馈「启用两行 + 表头对不上内容」）：
   工序表有 7 列且多为定宽控件（输入框/下拉/开关/按钮），交给浏览器自动分配时，
   它会把能压缩的列（下拉、「启用」）压到最小值 —— 于是「启用」折成两行、
   「打板师」被截断、保存/删除上下堆叠，表头看着就跟内容对不上了。
   改成 table-layout:fixed + 逐列定宽后：每一列的宽度可预测、表头与内容恒对齐，
   窄窗口下由 .cap-table-wrap 横向滚动兜底（该容器本来就有 overflow-x:auto）。
   合计 790px；窗口更宽时多出的宽度由浏览器均分，不影响可读性。 */
.cap-table.cap-steps{table-layout:fixed;min-width:640px}
/* ★ 2026-10-03（岩峰定·空间利用率 A 版）：去掉「保存」列（字段本就即时写库，按钮是重复的第二条路径）后重排列宽。
   ① ★ 「状态」列由**可变宽改为固定 96px** —— 这是本次的核心病根：原来它没写宽度，
      `table-layout:fixed` 会把**全部剩余宽度**塞给它（940px 屏下多出约 300px 空白全落在这一列），
      就是岩峰截图里「执行角色」下拉与「质检」之间那条大缝；
   ② 让出来的宽度改由**工序名**（第 1 列）与**完成方式**（第 4 列）两列**自适应均分** ——
      名字长不必横向滚、勾选框间距更大更好点；
   ③ 「操作」只剩「删除」→ 130px 收成 76px。
   固定列合计 330px，其余全部宽度由上面两列平分。 */
.cap-table.cap-steps th:nth-child(2){width:158px}   /* 执行角色（容 6 字最长岗位：业务中心主管） */
.cap-table.cap-steps th:nth-child(3){width:96px}    /* ★ 状态（动态文字 + 开关），固定宽是关键 */
.cap-table.cap-steps th:nth-child(5){width:76px}    /* 操作（只剩「删除」） */
/* ★ 2026-10-03：行高由 8px 内边距压到 5px —— 行高 8+30+8=46px → 5+30+5=40px，
   一屏从 9 行涨到 14 行。只作用于工序表，不影响其它 .cap-table。 */
.cap-table.cap-steps th,.cap-table.cap-steps td{padding:5px 10px}
/* ★ 完成方式三格：`display:flex` 均分该列宽度 ——
   ① 均分是必须的：该列改造后是**自适应**的（吸收原来被「状态」列吃掉的宽度），
      三格若不跟着拉伸，多出来的宽度就全积在「派单」右侧 → 变成一段**新的空白**（正是本次要消灭的东西）；
   ② 外层必须有一个 `display:flex` 的包裹元素：`inline-flex` 的 label 是行内盒、要坐在基线上，
      **会多带一段 descender 把行盒撑到 34px**（实测行高因此是 45 而不是 40）—— 包成 flex 后行盒消失。
   实测：改造后行高 40px、三格铺满整列、行尾无空白。 */
.cap-table.cap-steps td.cap-ways .ways{display:flex;gap:var(--sp-2);align-items:center}
.cap-table.cap-steps td.cap-ways label{flex:1;min-width:0;display:inline-flex;align-items:center;
  justify-content:center;gap:var(--sp-1);font-size:var(--fs-xs);margin:0;height:30px;white-space:nowrap}
/* ★ 工序表「工序名」输入框（2026-09-10 岩峰反馈「工序名的框和执行角色的框重叠了」）
   根因：`.st-tbl{width:auto!important}` 这个 !important 盖掉了标记里的内联 width:96px，
   输入框于是退回浏览器默认宽度（实测 185px），而它所在的列只有 133px ——
   实测溢出 52px，直接压到下一列的「执行角色」下拉上面（下拉绘制在后，把输入框右边盖住了，
   所以肉眼只看到"两个框贴在一起/重叠"）。
   这里同时统一口径：宽度跟随单元格（与右侧 6 个控件同宽）、高度 30px（与同排控件等高）；
   并把 .st-name 的「透明 + 虚线」外观换成实心输入框 —— 那套外观是给移动端卡片用的，
   放进表格里既看不出可编辑，也和旁边 6 个实心控件不同款。
   作用域限定 .cap-table.cap-steps，移动端卡片（.pm-card.st-card .st-name）不受影响。 */
.cap-table.cap-steps td input.st-name{
  width:100%!important;min-width:0;height:30px;
  background:var(--panel)!important;border:1px solid var(--border)!important;
  border-radius:var(--r-sm);padding:0 var(--sp-2);font-size:var(--fs-sm);font-weight:500;box-sizing:border-box;
}
.cap-table.cap-steps td input.st-name:hover,
.cap-table.cap-steps td input.st-name:focus{border-color:var(--accent)!important}
/* 按钮（28px）与勾选框（13px）都比同排控件（30px）矮，整行底边参差；统一到 30px 口径 */
/* ★ 2026-10-09（v5）：30px 与 28px 只差 2px，并排就是"错位 2px" —— 这里按本地决策①
   保留 30px（与同排 30px 的输入框齐），但**不许与 28px 的小号档出现在同一排**。
   ⚠ 只改高度、**不动内边距** —— 居中补偿由档位自己带（.btn 1.7px / .btn-sm 1.0px，
   与字号成正比），此处若再写死 1.7px 会让 12px 字的小号按钮补偿过量。 */
/* ★ 2026-10-09（第 74 批⑤）：原 `.cap-table.cap-steps td.cap-ops .btn{height:30px}` 已删 ——
   「操作」列的删除按钮改 `.sys-del` 后本格不再有 `.btn`（精确 grep 验过源码零残留）。 */
/* ★ 2026-10-09（v5 本地决策①·**同档几何完全一致**）：
   30px 是生产系统自留的「紧凑档」，全站落 30px 的按钮**必须同一套外观**。
   这些位置的按钮 markup 是 `.btn-sm`（12px 字 / 12px 内边距 / 6px 圆角），
   而筛选条里落 30px 的是标准档（14px / 16px / 8px）—— 两个外观撞在同一个高度上，
   几何自证会当场报"同档不一致"。这里统一到**标准档的墨色/内边距/圆角**（只把高度收成 30）。 */
/* ★ 2026-10-09（v5 本地决策①·**同档几何完全一致**）：
   30px 是生产系统自留的「紧凑档」—— 全站落 30px 的按钮**必须同一套外观**。
   口径取**小号档的墨色**（12px 字 / 12px 内边距 / 6px 圆角 / 1.0px 居中补偿），只把高度收成 30：
   这样「系统设置行 / 工序表」保持原有观感（表头↔内容对齐轴也纹丝不动），
   而筛选条里那几个原本是标准档的按钮被一并收进同一档。
   ⚠ 别改用标准档墨色（14px/16px/8px）—— 实测会把工序表「操作」列的对齐轴顶偏 3px（T3 红）。 */
/* ★ 2026-10-09（第 74 批⑤）：`.cap-table.cap-steps td.cap-ops .btn` 已从本组移除（该格改 `.sys-del`）。 */
#view-system .sys-row .btn,#view-system .sys-add .btn,#view-system .sys-foot .btn,
:is(#view-dashboard,#view-perf) .fbar .btn,#view-board .fbar .btn{
  height:var(--h-dense);padding:0 var(--sp-3) 1.0px;font-size:var(--fs-xs);border-radius:var(--r-sm)}
.cap-table.cap-steps td label{height:30px}
.cap-table.cap-steps td label input[type=checkbox]{width:15px!important;height:15px!important;margin:0;vertical-align:middle}
/* ★ 2026-10-03：旧版工序卡的 `.st-grid / .st-f / .st-foot / .st-ops / .st-hint` 五条规则
   **已随「两行式工序卡」改造删除**（用精确 grep 验过：源码里只剩定义、再无任何引用点）。 */
/* ★ 2026-10-03：`.st-btn / .st-btn.ok / .st-btn.del` 三条已删除 ——
   它们是各设置页「保存」按钮的样式，而保存按钮**全站改即时保存后已全部移除**
   （精确 grep 验过：index.html 里再无 `st-btn` 元素，只剩样式定义）。
   删除按钮走 `.sys-del`（设置页）与 `.st-del`（工序卡，44px 命中区）。 */
.st-tbl{width:auto!important;min-width:96px;font-size:var(--fs-sm)}

/* 全局反馈弹窗（居中卡片，2026-09-10） */
/* ⚠️ width:100% 必须保留（2026-09-11 补）：本容器是 position:fixed + left:50%，
   按 CSS 规范其 shrink-to-fit **可用宽度 = containing block 宽 − left = 视口的一半**，
   手机长文案会被压成半屏宽、挤成多行。加 width:100% 后配合 left:50%+translateX(-50%) 仍精确居中；
   桌面完全不受影响（.toast 自身 max-width:420px 兜住）。实测 375 视口：文案高度 128 → 89。 */
.toast-host{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:100%;z-index:9999;display:flex;flex-direction:column;align-items:center;gap:var(--sp-3);pointer-events:none}
.toast{pointer-events:auto;min-width:280px;max-width:420px;background:var(--panel);color:var(--text);border:1px solid var(--border);border-left:4px solid var(--accent);border-radius:var(--r-md);box-shadow:0 12px 32px rgba(0,0,0,.4);padding:14px 18px;display:flex;align-items:center;gap:var(--sp-3);animation:toast-in .18s ease-out;font-size:var(--fs-sm)}
.toast.ok{border-left-color:var(--good)}
.toast.warn{border-left-color:var(--warn)}
.toast.err{border-left-color:var(--bad)}
.toast .ico{width:18px;height:18px;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;border-radius:50%;font-weight:700;font-size:var(--fs-xs);color:var(--on-accent)}
.toast.ok .ico{background:var(--good);color:#0a1a0a}
.toast.warn .ico{background:var(--warn);color:#1a1208}
.toast.err .ico{background:var(--bad);color:#fff}
/* ★ 2026-09-29（岩峰定）：**全系统删除悬浮提醒**（自研 data-tip 气泡）—— 原 #tipHost 样式块
   （2026-09-12 为替代原生 title 而引入）连同宿主元素与整套 JS 事件机制一并移除。
   随之失效的旧理由（原注释保留在此备查）：① 原生 title 移动端不显示 ② 默认延迟约 1s、样式不可控
   ③ 键盘 focus 不触发。→ 现在一律不提供 hover/长按/focus 气泡；元素的可点行为、role/aria 全保留。 */
.toast .msg{flex:1;line-height:1.5}
.toast .x{cursor:pointer;color:var(--muted);font-size:var(--fs-xl);line-height:1;padding:0 4px}
.toast .x:hover{color:var(--text)}
/* toast 入场动画：只做自己的透明度/缩放。
   ⚠️ 曾经错写成 translate(-50%,-50%) —— 那是**宿主** .toast-host 的居中位移，
   而 .toast 已经是宿主 flex 居中的子元素；再对它做 -50%,-50% 会让它先偏左上
   半个自身宽高，等 0.18s 动画结束（无 fill-mode）位移回退，就"跳"回正中。
   表现就是"先出现在左上一点，然后马上跳回中间"。别再往这里加 translate。 */
@keyframes toast-in{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}

/* 工序管理 · 紧凑样式（2026-09-10） */
/* ★ 2026-10-03（岩峰定·空间利用率 A 版 · 手机端按同一套结构适配）：
   每条工序由「3 行 ≈166px」压成「2 行 ≈114px」（一屏 4 条 → 5.6 条，省 31%），
   并顺手修两个真缺口：① 完成方式补上**漏掉的「派单」**（此前手机上根本设不了该标志位）；
   ② 状态文字由写死的「启用」改成随开关变（停用的工序以前也写着「启用」）。
   为什么是两行而不是缩小控件：移动端强制 `input,select{min-height:44px}`（触控目标规则），
   控件**不可能再矮** —— 压密度只能靠**减少每条的控件行数**。
   ⚠ 这里删掉了旧版 `.st-grid/.st-f/.st-foot/.st-ops`（它们只被本卡片用过，改造后无引用）。 */
.st-card{padding:8px 10px!important}
.st-row{display:flex;align-items:center;gap:8px}
.st-name{flex:1;min-width:0;font-size:var(--fs-lg);font-weight:600;color:var(--text);background:transparent;border:1px dashed transparent;border-radius:var(--r-sm);padding:var(--sp-1) var(--sp-2);font-family:inherit}
.st-name:hover,.st-name:focus{border-color:var(--accent);background:var(--panel);outline:none}
/* 第 2 行：执行角色（定宽）+ 完成方式三格（等分、44px 命中区） */
.st-row2{display:flex;align-items:center;gap:var(--sp-2);margin-top:6px}
.st-card .st-role{flex:0 0 118px;min-width:0;height:44px;background:var(--panel);border:1px solid var(--border);border-radius:var(--r-md);color:var(--text);font-size:var(--fs-sm);padding:0 var(--sp-2);font-family:inherit;box-sizing:border-box}
.st-card .st-role:focus{outline:none;border-color:var(--accent)}
.st-keys{display:flex;gap:var(--sp-2);flex:1;min-width:0}
.st-keys label{flex:1;min-width:0;display:flex;align-items:center;justify-content:center;gap:var(--sp-1);
  height:44px;border:1px solid var(--border);border-radius:var(--r-md);font-size:var(--fs-sm);color:var(--muted);box-sizing:border-box}
/* `:has()` 在本项目已有先例（见 .sys-row select:has(...) 与 ≤820 的 label:has(...)）。
   万一浏览器不支持：只剩底色不变化，**勾选框的勾本身仍在**，状态照样看得出来（优雅降级）。 */
.st-keys label:has(input:checked){background:var(--accent-soft);border-color:var(--accent-soft);color:var(--accent-text)}
/* 行尾「删除」：44×44 命中区，常驻（二次确认仍走 askConfirm.danger 兜底） */
.st-del{flex:0 0 auto;height:44px;padding:0 var(--sp-3);border:1px solid var(--border);background:transparent;
  color:var(--muted);border-radius:var(--r-md);font-size:var(--fs-xs);font-family:inherit;cursor:pointer}
.st-tbl{min-width:88px;font-size:var(--fs-sm)}
/* 订单类型卡（紧凑） */
.fl-card{padding:var(--sp-3) var(--sp-3)!important;margin-bottom:8px}
/* ★ 2026-10-09（第 74 批⑥）：原来是 `grid-template-columns:96px 1fr` 的**两列**
   （左 = 订单类型名，右 = 黄/红阈值输入组）。阈值设置下线后卡里只剩名字 ⇒ 改**单行 flex**。
   ⚠ 必须改，否则名字会被塞进 96px 那一列、被 ellipsis 截断。 */
.fl-head{display:flex;align-items:center;gap:10px}
.fl-name{font-size:var(--fs-md);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* ★ 2026-10-09（第 74 批⑥）：原 `.fl-nums` 一族（含两条 label / 一条 input 共 4 条规则）
   **整块删除** —— 黄/红阈值输入框已下线，本类名在源码里零引用（严格 grep 过）。 */
.flow-pills{display:flex;flex-wrap:wrap;gap:5px;margin-top:8px}
.flow-pills .pill{font-size:var(--fs-xs);padding:var(--sp-1) var(--sp-3);display:inline-flex;align-items:center;gap:6px}
.flow-pills .pill i{cursor:pointer;color:var(--muted);font-style:normal}
.flow-pills .pill i:hover{color:var(--bad)}
.flow-pills select{font-size:var(--fs-xs);height:26px;background:var(--panel);border:1px dashed var(--border-strong);border-radius:var(--r-sm);color:var(--muted);padding:0 var(--sp-2);font-family:inherit}
.fl-hint{font-size:var(--fs-xs);color:var(--text-2);margin-top:6px;line-height:1.6}
/* ★ 2026-10-09（第 74 批⑥）：原 `@media (max-width:600px){.fl-head{grid-template-columns:72px 1fr}}`
   已删 —— `.fl-head` 不再是 grid（见上），窄屏无需再调列宽。 */
/* ★ 2026-10-03：原 `@media (max-width:560px){.st-grid{repeat(2,1fr)}}` 已随工序卡改两行式删除
   （旧版 `.st-grid` 在 >560px 是**三列却只有两个子项** → 右侧 1/3 永远空着，是个白占位的 bug）。 */
/* 桌面表格行：紧凑整齐（≤820 桌面） */
.cap-table tbody tr.cap-row td{vertical-align:middle;padding:var(--sp-2) var(--sp-2);height:42px;border-bottom:1px solid rgba(255,255,255,.04)}
.cap-table tbody tr.cap-row:hover{background:var(--accent-soft)}
.cap-table th{font-size:var(--fs-xs);font-weight:500;letter-spacing:.02em;text-transform:none;padding:8px 10px}
/* 桌面行输入/选择统一高 30px */
.cap-table input.cp-input,.cap-table select{height:30px;background:var(--panel);border:1px solid var(--border);border-radius:var(--r-sm);padding:0 var(--sp-2);color:var(--text);font-family:inherit;font-size:var(--fs-sm);box-sizing:border-box}
.cap-table select.cond{width:120px;margin-right:6px}
.cap-table input.cond{width:80px;text-align:right;margin-right:6px}

/* ===== 系统设置（2026-09-10）：左侧分组导航 + 右侧配置区（Stripe/Notion 设置页范式） ===== */
.sys-layout{display:grid;grid-template-columns:184px minmax(0,1fr);gap:var(--sp-5);align-items:start}
.sys-side{background:var(--panel);border:1px solid var(--border);border-top-color:var(--hair);box-shadow:var(--shadow-1);border-radius:var(--r-lg);padding:var(--sp-2);position:sticky;top:70px}
.sys-g{font-size:var(--fs-xs);color:var(--muted);letter-spacing:.04em;padding:10px 10px 5px}
.sys-g:first-child{padding-top:4px}
.sys-block{margin-bottom:2px}
.sys-items{display:block}
.sys-item{display:block;width:100%;text-align:left;border:none;background:transparent;color:var(--text-2);font-family:inherit;font-size:var(--fs-sm);padding:7px var(--sp-3);border-radius:var(--r-md);cursor:pointer;transition:background .12s,color .12s}
.sys-item:hover{background:var(--panel2);color:var(--text)}
.sys-item.active{background:var(--accent-soft);color:var(--accent);font-weight:500}
.sys-body{min-width:0}
.sys-sec{font-size:var(--fs-lg);font-weight:500;margin-bottom:2px}
.sys-sec-desc{font-size:var(--fs-xs);color:var(--muted);line-height:1.6;margin-bottom:var(--sp-3)}
.sys-list{background:var(--panel);border:1px solid var(--border);border-top-color:var(--hair);box-shadow:var(--shadow-1);border-radius:var(--r-lg);overflow:hidden}
.sys-row{display:flex;align-items:center;gap:var(--sp-3);padding:9px var(--sp-4);border-bottom:1px solid var(--border)}
.sys-row:last-child{border-bottom:none}
.sys-row input[type=text],.sys-row input:not([type]){flex:1;min-width:0;height:var(--h-dense);background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-sm);color:var(--text);font-family:inherit;font-size:var(--fs-sm);padding:0 9px}
.sys-row input:focus{outline:none;border-color:var(--accent);box-shadow:var(--focus-ring)}
.sys-row .sys-lab{font-size:var(--fs-xs);color:var(--muted);white-space:nowrap}
/* ★ 2026-10-09（岩峰定·第 74 批③）：**行首标签列固定宽 + 两端对齐**。
   原状：`.sys-lab` 宽度随字数变（实测 24 / 36 / 48px 三种）⇒ 同一页里下拉框起点飘到
   489 / 501 / 513、长度 910 / 898 / 886 三种，看着"每行长一样长"。
   改法：行首标签固定 48px（= 4 个 12px 汉字，当前最长字段名「订单编号/收货地址」正好占满），
   并用 `text-align-last:justify` 让 2 字标签（客户/品牌/单位/色号…）在中间撑开 ⇒
   **所有标签的首字与尾字都对齐**，右侧下拉框起点与长度随之统一。
   ⚠ 只认 `:first-child` —— 其它位置的 `.sys-lab`（「启用」「必填」「可后补」「×」「→」）是行内小标签，
     不是标签列，绝不能跟着定宽。 */
.sys-row>.sys-lab:first-child{flex:0 0 auto;width:48px;text-align:justify;text-align-last:justify}
.sys-row select{height:var(--h-dense);background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-sm);color:var(--text);font-family:inherit;font-size:var(--fs-sm);padding:0 var(--sp-2);min-width:0}
.sys-row select:focus{outline:none;border-color:var(--accent)}
/* 未选择时下拉呈占位样式（value="" 的占位项被选中），一眼能看出"还没填"。
   注意：第 193 行的全局 input/select/textarea 规则带 color:var(--text)!important，
   这里必须同样加 !important 才能压过它（与 .field select:has(...) 的既有写法一致）。 */
.sys-row select:has(option[value=""]:checked),.sys-add select:has(option[value=""]:checked){color:var(--muted)!important}
.sys-row .grow{flex:1;min-width:0}
/* ── ★ 2026-10-17（岩峰定·派单规则品牌多选）：品牌从「单选下拉」改成「可点选标签组」──
   为什么不用 `<select multiple>`：它必须按住 Ctrl 才能多选，日常同事不会用；
   标签点一下就亮、再点一下灭，「到底选了哪几个」一眼看全。
   品牌只有 3~5 个，平铺放得下；再多也只是换行，不会撑破。
   ⚠ 文字永不折行（全站硬规则）⇒ chip 内 white-space:nowrap，宽度按内容自适应。
   ⚠ 「不限品牌」与具体品牌**互斥**（点不限=清空其它；点任一品牌=自动灭掉不限），
     互斥逻辑在 JS 的 _chipPick 里，纯视觉层不做判断。 */
.sys-row .rchips,.sys-add .rchips{display:flex;flex-wrap:wrap;align-items:center;gap:6px;
  flex:0 1 auto;min-width:0}
/* ★ 2026-10-17（真机截图抓到的）：**新增行**的标签组会被压到只剩一个 chip 宽 → 内部换行
   → 看起来「不限品牌」单独一行、瑞加/维朵掉到下一行，整行布局垮掉。
   根因：`.sys-add` 是 `display:flex`（桌面端不 wrap），三块内容按 flex-shrink 分压缩量，
   而 chips 的 `flex:0 1 auto` 允许它缩到远小于内容宽。
   修法：让 chips **不参与收缩**（0 0 auto），空间不够时由右边两个 select 让位
   （它们本来就有 `flex:1 1 auto;min-width:0`）—— chips 保持一行，「谁该让」由 flex 权重决定。 */
.sys-add .rchips{flex:0 0 auto}
.sys-row .rchip,.sys-add .rchip{font-size:var(--fs-xs);line-height:1;padding:6px 10px;
  border-radius:var(--r-pill);border:1px solid var(--border);background:var(--panel2);
  color:var(--muted);cursor:pointer;white-space:nowrap;user-select:none;
  transition:background .16s,color .16s,border-color .16s}
.sys-row .rchip:hover,.sys-add .rchip:hover{border-color:var(--edge);color:var(--text-2)}
.sys-row .rchip.on,.sys-add .rchip.on{background:var(--accent-soft);border-color:var(--accent);
  color:var(--accent-text);font-weight:600}
/* ★ 2026-10-17：规则里引用了「已停用 / 已不在品牌列表」的品牌 —— 照样显示（否则一保存就被抹掉），
   用虚线 + 降饱和区分，一眼看出"这个品牌现在不能给新单用，但这条规则还留着它"。 */
.sys-row .rchip.off-brand,.sys-add .rchip.off-brand{border-style:dashed;border-color:var(--warn);
  color:var(--warn);background:transparent;font-weight:600}
.sys-row .rchip:focus-visible,.sys-add .rchip:focus-visible{outline:none;box-shadow:var(--focus-ring)}
/* 品牌组里一个品牌都没有（品牌管理里全停用）时的兜底提示，避免一片空白 */
.sys-row .rchips.empty::after,.sys-add .rchips.empty::after{content:'（品牌管理里没有启用的品牌）';
  font-size:var(--fs-xs);color:var(--muted)}
/* 把「下拉 + 紧随的 ×/→ 分隔符」绑成一组，移动端才不会被拆成孤立的一行符号 */
.sys-row .rg{display:flex;align-items:center;gap:var(--sp-2);flex:1 1 auto;min-width:0}
.sys-row .rg select{flex:1 1 auto;min-width:0}
.sys-foot{display:flex;justify-content:flex-end;gap:var(--sp-2);padding:var(--sp-3) var(--sp-4);background:var(--panel2);border-top:1px solid var(--border)}
.sys-add{display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-3) var(--sp-4);background:var(--panel2);border-top:1px solid var(--border)}
.sys-add input{flex:1 1 auto;min-width:0;height:var(--h-dense);background:var(--panel);border:1px solid var(--border);border-radius:var(--r-sm);color:var(--text);font-family:inherit;font-size:var(--fs-sm);padding:0 9px}
.sys-add input:focus{outline:none;border-color:var(--accent);box-shadow:var(--focus-ring)}
.sys-add select{flex:1 1 auto;min-width:0;height:var(--h-dense);background:var(--panel);border:1px solid var(--border);border-radius:var(--r-sm);color:var(--text);font-family:inherit;font-size:var(--fs-sm);padding:0 8px}
.sys-add select:focus{outline:none;border-color:var(--accent)}
.sys-add .btn,.sys-foot .btn{width:auto;min-width:auto;margin:0;flex:0 0 auto;height:var(--h-dense)}
.sys-empty{padding:22px var(--sp-4);text-align:center;color:var(--muted);font-size:var(--fs-sm)}
.sys-del{border:none;background:transparent;color:var(--bad);font-family:inherit;font-size:var(--fs-xs);cursor:pointer;padding:var(--sp-1) var(--sp-2);border-radius:var(--r-sm);white-space:nowrap}
/* 交付设置（2026-09-21）：顶部工序 chips（带字段数），下方该工序的字段清单。
   字段行直接复用 .sys-row/.sys-list/.sys-add，跟其它设置页同款同高。 */
.sf-chips{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin-bottom:var(--sp-3)}
.sf-chip{display:inline-flex;align-items:center;gap:var(--sp-2);height:var(--h-dense);padding:0 var(--sp-3);border:1px solid var(--border);border-radius:var(--r-pill);background:var(--panel);color:var(--muted);font-family:inherit;font-size:var(--fs-xs);cursor:pointer}
.sf-chip:hover{color:var(--text);border-color:var(--accent)}
.sf-chip.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
.sf-chip .n{font-variant-numeric:tabular-nums;opacity:.6}
.sf-chip.on .n{opacity:1}
.sf-chip .n.zero{opacity:.35}
.sf-tag{font-size:var(--fs-xs);color:var(--muted);border:1px solid var(--border);border-radius:var(--r-sm);padding:1px var(--sp-2);white-space:nowrap}
/* ★ 2026-10-03（岩峰定·质检字段分组）：质检工序下的「质检通过 / 质检不通过」切换栏 ——
   两组字段清单彼此独立；字段行上的「移至另一组」与 chips 上的「通过/不通过」计数配套。 */
.sf-branches{display:inline-flex;gap:var(--sp-1);background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-md);padding:var(--sp-1);margin-bottom:6px}
.sf-br{display:inline-flex;align-items:center;gap:var(--sp-2);height:26px;padding:0 14px;border:none;border-radius:var(--r-sm);background:transparent;color:var(--muted);font-family:inherit;font-size:var(--fs-xs);cursor:pointer}
.sf-br:hover{color:var(--text)}
.sf-br.on{background:var(--panel);color:var(--text);box-shadow:var(--shadow-1)}
.sf-br .n{font-variant-numeric:tabular-nums;opacity:.6}
.sf-br.on .n{opacity:1}
.sf-br .n.zero{opacity:.35}
.sf-br-tip{margin:0 0 var(--sp-3);font-size:var(--fs-xs);color:var(--muted);line-height:1.5}
.sf-sep{opacity:.45;margin:0 2px}
.sf-move{flex:0 0 auto;height:var(--h-dense);padding:0 var(--sp-2);border:1px solid var(--border);border-radius:var(--r-sm);background:transparent;color:var(--muted);font-family:inherit;font-size:var(--fs-xs);cursor:pointer;white-space:nowrap}
.sf-move:hover{color:var(--accent);border-color:var(--accent)}
.sf-add-to{font-size:var(--fs-xs);color:var(--muted);white-space:nowrap}
.sf-req-off{display:flex;flex-direction:column;gap:var(--sp-1);padding:10px var(--sp-4)}
.sf-req-off-t{font-size:var(--fs-sm);color:var(--muted)}
.sf-req-off-h{font-size:var(--fs-xs);color:var(--muted);opacity:.8}
/* ★ 2026-09-22（交付设置）：工序级「交付要求」两开关 + 字段行的控件类型下拉 */
.sf-req{background:var(--panel);border:1px solid var(--border);border-top-color:var(--hair);box-shadow:var(--shadow-1);border-radius:var(--r-lg);margin-bottom:var(--sp-3);overflow:hidden}
.sf-req-row{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border)}
.sf-req-row:last-child{border-bottom:none}
/* ★ 2026-10-09（第 74 批③·同类排查）：三行标签 6 / 10 / 8 字不等 ⇒ 右侧开关起点参差。
   与设置页同一口径：固定 130px（= 最长「交期不得晚于订单交期」10 字 × 13px）+ 两端对齐。 */
.sf-req-t{font-size:var(--fs-sm);color:var(--text);white-space:nowrap;flex:0 0 auto;width:130px;text-align:justify;text-align-last:justify}
.sf-req-d{flex:1;min-width:0;font-size:var(--fs-xs);color:var(--muted);line-height:1.5}
/* ★ 2026-09-29（B）→ ★ 2026-10-08 第 72 批（岩峰定）：交期校验语义改为「**本工序所有日期
   字段**都不得晚于订单交期」⇒ 原「比对哪个字段」下拉（`.sf-duesel`）**已整体移除**；
   这里只剩右侧的说明文字（.sf-due-note）与「无日期字段」提示（.sf-due-none）。 */
.sf-due-wrap{display:flex;align-items:center;gap:var(--sp-2);min-width:0}
.sf-due-note{font-size:var(--fs-xs);color:var(--muted)}
.sf-due-none{font-size:var(--fs-xs);color:var(--danger)}
.sys-row select[data-f="kind"]{flex:0 0 auto;width:120px}
.sys-add select#sfNewKind{flex:0 0 auto;width:120px}
.sys-add .sys-lab{font-size:var(--fs-xs);color:var(--muted);white-space:nowrap}
/* 手机端：字段行多了一个下拉，一行塞不下 → 换行显示（标签占满一行，其余留在一行） */
@media (max-width:820px){
  .sf-req-row{flex-wrap:wrap;gap:8px}
  .sf-req-d{flex:1 1 100%;order:9}
  .sf-due-wrap{flex:1 1 100%;flex-wrap:wrap}
  .sys-row{flex-wrap:wrap}
  .sys-row input[data-f="label"]{flex:1 1 100%}
  .sys-row select[data-f="kind"]{flex:1 1 auto;width:auto;min-width:110px}
}
/* 字典行上的「规则」下拉（2026-09-21）：级别 / 异常类型等挂系统规则的字典用。
   固定宽度，别去抢名称输入框的空间；窄屏下 .sys-row 会整行换行，它跟着换。 */
.sys-rule{flex:0 0 auto;width:136px;height:var(--h-dense);background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-sm);color:var(--text);font-family:inherit;font-size:var(--fs-xs);padding:0 var(--sp-2);min-width:0}
.sys-rule:focus{outline:none;border-color:var(--accent)}
/* ★ 系统设置「字典行」整行统一到 --h-dense(30px)（2026-09-10 岩峰反馈「优化整个界面视觉」）
   原来一行的三个控件是三种高度：输入框/下拉 30px、保存按钮 26px、删除按钮 24px ——
   按钮彼此大小不一、跟输入框也不齐，是各设置页看着"不精致"的主要来源。
   统一成 .sys-row 全行 30px 后，底部基线一致、按钮同款同高。
   ★ 2026-10-03：保存按钮已随「全站即时保存」移除，本行现在只剩「删除」（.sys-del）。
   （作用域限 .sys-row；.sys-add / .sys-foot 里的 .btn 早就有 height:--h-dense，不受影响。） */
.sys-row .sys-del,.sys-row .btn{
  height:var(--h-dense);display:inline-flex;align-items:center;justify-content:center;
}
.sys-del:hover{background:var(--ba-soft)}
.sys-seq{display:flex;flex-wrap:wrap;gap:var(--sp-1);flex:1;min-width:0}
.sys-seq .pill{font-size:var(--fs-xs);padding:2px var(--sp-2);color:var(--muted)}
.sys-num{width:62px;height:var(--h-dense);background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-sm);color:var(--text);font-family:inherit;font-size:var(--fs-sm);padding:0 7px;text-align:right;box-sizing:border-box}
.sys-grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:var(--sp-3)}
.sys-thr{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap}
.sys-thr input{width:96px}
@media (max-width:820px){
  .sys-layout{grid-template-columns:1fr;gap:var(--sp-3)}
  /* ★ 2026-09-29（岩峰定·方案2「块式」）：组名独占一行、按钮在其下成行 —— 组名不再与按钮混排。
     （原「横条分组标签 + 换行」的写法已由本块式取代。） */
  .sys-side{position:static;display:block;padding:8px}
  .sys-block{margin-bottom:12px}
  .sys-block:last-of-type{margin-bottom:0}
  .sys-g{display:block;font-size:var(--fs-xs);padding:0 0 var(--sp-2);margin:0;border-left:none;color:var(--muted)}
  .sys-items{display:flex;flex-wrap:wrap;gap:6px}
  .sys-item{flex:0 0 auto;white-space:nowrap;background:var(--panel2);padding:7px 14px;border-radius:var(--r-pill)}
  .sys-item.active{background:var(--accent);color:var(--on-accent)}
  .sys-row{flex-wrap:wrap;padding:var(--sp-3) var(--sp-3);gap:8px}
  /* ★ 2026-10-15（布局统一·grid）：手机端 nt-row 改单列堆叠（名字/下拉/站内/企微 上下排）。
     ⚠ 同样用 `.sys-list` 提权（理由见上方主规则的提权注释）。 */
  .sys-list .nt-row{grid-template-columns:1fr;gap:6px}
  .sys-list .nt-row .nt-name{justify-content:flex-start}
  .sys-row input:not([type]){flex:1 1 100%}
  .sys-row .grow{flex:1 1 100%}
  .sys-row .rg{flex:1 1 100%}
  /* ★ 2026-10-17（品牌多选）：手机端标签组单独占一行（与 .grow 同待遇），
     否则会和「×」分隔符挤在一行、把品牌压到换行折断。
     ⚠ chip 高度在触屏上要够点（≥44px 是本项目硬约束）—— 这里用 padding 撑到 40px 上下，
       配合 6px 的组内间距，实际可点面积达标。 */
  .sys-row .rchips,.sys-add .rchips{flex:1 1 100%}
  .sys-row .rchip,.sys-add .rchip{padding:12px 14px;font-size:var(--fs-sm)}
  .sys-foot{padding:var(--sp-3)}
  .sys-add{flex-wrap:wrap}
  .sys-add input,.sys-add select{flex:1 1 100%}
  .sys-add .btn,.sys-foot .btn{margin-left:auto}
}
@media (max-width:380px){
  .sys-row{padding:9px 10px}
}

/* ★ 2026-10-03：工序卡「完成方式」行已改两行式（`.st-keys` + 原生勾选框），
   原 `.st-key` / `.st-keyopt` 两条规则随之删除（源码里再无引用点）。 */

/* ==========================================================================
   手机端触控目标与字号兜底（2026-09-11 手机端全量 UI/UX 审计后补）
   --------------------------------------------------------------------------
   为什么需要这一段「兜底」：
     ① ≤820 已有 input/select/textarea{font-size:16px}，但它特异性只有 (0,0,1)，
        被 .sys-row input:not([type]) / .cap-input / .grow / .st-name 等**类选择器**压过
        → 手机上仍是 13px，iOS Safari 聚焦时会强制放大整页。
     ② 录单 / 编辑订单的明细输入框曾把 font-size:13px 写在**内联样式**里
        （内联 > 媒体查询），只能靠 !important 压住（内联那 12 处已于同日删除，这里是双保险）。
     ③ 一批「桌面数据行里的小控件」（字典行 30px、开关 38×22、行内链接 24×19、
        看板条形行 35px…）是按鼠标密度设计的，没进手机触控标准。
   两档标准（沿用项目既有约定）：独立控件 ≥44px；数据行内的小按钮沿用 .btn-sm 的 40px。
   实测口径：390 / 360 / 768 三档窄视口，<36px 判硬伤、36–43px 判偏小。
   ⚠️ 全部规则仅在 ≤820 生效，桌面端零影响。
   ========================================================================== */
@media (max-width:820px){
  /* 1) 字号：!important 压过类选择器与内联样式；只作用于表单控件，不动按钮 */
  input,select,textarea{font-size:var(--fs-lg)!important}

  /* 2) 独立表单控件的高度（含日期触发器 / 排序输入 / 工序名） */
  input:not([type=checkbox]):not([type=radio]):not([type=hidden]),
  select,textarea,
  .date-trigger,.cap-input,.sys-num,.st-name{min-height:44px}

  /* ★ 2026-10-07（岩峰：录单页「下单日期」的框比别的框小）：只读显示块与输入框**同高**。
     「下单日期」不是 input 而是 `<div class="oe-ro">`，它只有 `--h-ctl`(36px)，
     而手机端输入框被上面那条提到 44px ⇒ 同一行里一个高一个矮（岩峰截图圈出）。
     ⚠ 2026-10-08 第 72 批：录单页「下单日期」整格**已删除**（栅格重排为 6 列）→ 本规则**已无宿主**。
       但**保留不删**：`_tools/_cloud_verify_b64.py:46` 断言静态文件里存在 `#view-order .oe-ro{min-height:44px}`
       （删/改它会让该检查变红）→ 属"当前无宿主、但被锚定"的死样式：只更新本注释，不动规则。 */
  #view-order .oe-ro{min-height:44px}

  /* 3) 原生勾选框：13×13 / 明细行 18×18 → 20×20（!important 为压过内联 width:auto）；
        flex:none 防止被同行长文本挤扁（.item 里「明细 1. 色号（工序3：质检）」那种长标签
        会把 20px 的勾选框压到 13px）；外层 label 同时撑出 44px 命中区 */
  input[type=checkbox],input[type=radio],
  .item input[type=checkbox],.item input[type=radio]{width:20px!important;height:20px!important;flex:none}
  /* 「记住口令」勾选框：手机端 20px。
     ⚠ 桌面端那条（18px!important）与它**特异性相同**，此处靠"媒体查询里后出现"取胜；
     若哪天把桌面那条挪到本块之后，手机端会退回 18px —— 改前先用 _mm_loginpwd.js 实量。 */
  .login-remember input[type=checkbox]{width:20px!important;height:20px!important}
  label:has(> input[type=checkbox]),label:has(> input[type=radio]){
    min-height:44px;display:flex;align-items:center;flex-wrap:wrap;gap:var(--sp-2);
  }

  /* 3b) 我的待办「待处理异常」条目（可点开详情）与权限页角色列表项 */
  .my-anom .ma-item{min-height:44px;display:flex;align-items:center}
  .pm-role{min-height:44px}

  /* 4) 系统设置
        ★ 同时修掉「基础规则 .sys-item{width:100%} 在 ≤820 没被重置」——
          flex-basis:auto 会解析成 100%，8 个子项各占满整屏、合计 3013px，
          手机上只看得到第一个子项，其余 7 个既看不见也没有滚动提示。 */
  .sys-item{width:auto;min-height:44px;display:inline-flex;align-items:center}
  .sys-row .sys-del,.sys-row .btn,.sys-add .btn{min-height:40px;height:auto}
  .sys-add input,.sys-add select{height:44px}
  /* 订单类型行：工序序列独占一行，别再被挤成 30px 宽导致 pill 溢出行外 */
  .sys-seq{flex:1 1 100%}
  .sys-seq .pill{max-width:100%;overflow:hidden;text-overflow:ellipsis}

  /* 5) 权限管理：二级页签、开关命中区、行内文字链接、角色小胶囊 */
  .pm-tab{min-height:44px;display:inline-flex;align-items:center;justify-content:center}
  /* 开关外观 38×22（2026-09-11 与考核对齐后），只把**命中区**外扩到 46×44。
     横向只扩 4px：.sys-row 里开关紧挨右边的「删除」按钮（gap 10px），扩太多会抢走旁边按钮的点击。
     ★ 2026-10-03：开关左边原先是「保存」按钮，已随全站即时保存移除 —— 这个 4px 口径保持不变。 */
  .pm-tgl::before{content:'';position:absolute;left:-4px;right:-4px;top:-11px;bottom:-11px}
  .pm-row a,.pm-gh a,.pm-mem{
    min-height:44px;display:inline-flex;align-items:center;padding-left:4px;padding-right:4px;
  }
  .pm-mem{padding-left:11px;padding-right:11px}

  /* 7) 日期选择器：上/下月按钮 与 「今天/清除/确定」 */
  .date-pop .dp-nav{width:44px;height:44px}
  .date-pop .dp-foot button{min-height:44px}

  /* 8) 订单看板 / 数据看板：可点击的条形负载行（33–35px → 44px） */
  .bar-row.bar-clickable{min-height:44px}

  /* 9) 订单类型 → 工序序列的「× 移除」图标：原来只有 9×14，且是不可逆感很强的操作，
        手机上基本点不中（点偏了会点到相邻的工序胶囊） */
  .flow-pills .pill{padding-right:2px}
  .flow-pills .pill i{
    display:inline-flex;align-items:center;justify-content:center;
    width:44px;height:44px;margin-left:2px;font-size:var(--fs-xl);line-height:1;
  }
}

/* ===== 人效统计（按人汇总 × 同岗位对比）★ 2026-09-30 =====
   视觉照预览稿（C:/Users/Rick/Desktop/人效统计-极致版.html）。分隔线一律用**实线**
   （岩峰定：Data-ink 原则，不用虚线做分隔）。全站字号 ≥12px。
   深色/浅色主题都走同一套令牌（--panel/--text/--good/--warn/--bad/--accent…），零主题分叉。 */
/* ★ 2026-10-07（岩峰定「UI 用同一种语言、计算逻辑参考订单数据页」）—— 本页四处改造：
     ① 环比：由「上期条 + 本期条 + 右侧『快 3%』」改成 **「本期条 / 上期条，值跟到各自条尾」**
        （对齐订单数据页 `.gb` 的双条语言）—— 那句百分比正是订单数据页**明确废掉**的形式
        （"换算过的数反而不如原始值可信"，见 `_vsPrev` 的注释）；
     ② 卡片改挂通用 `.panel`（同档圆角/边框/浮起），本组只留差异；
     ③ 「最慢 N 单」由自制列表改用**全站统一表格** `table.tb`（方案 C）；
     ④ 条底一律 `var(--track)` —— `--panel2` / `--m-*` 是**玻璃态遮罩**语义，在白卡上会隐形。 */
.pf-wrap{max-width:none}
/* ★ 2026-10-07（岩峰定·删提示词）：顶部那条**口径说明条**（`.pf-note`）已按要求撤掉
   —— 连同它的两条 CSS 一起删，不留"没人用的类"（门禁 `_cls_audit.py` 会扫类名孤儿）。 */
.pf-grp{margin-bottom:18px}
.pf-gh{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap;margin-bottom:8px}
.pf-gn{font-size:var(--fs-lg);font-weight:600;color:var(--text)}
.pf-gm{font-size:var(--fs-xs);color:var(--muted)}
.pf-gm b{color:var(--text-2)}
.pf-card{cursor:pointer;padding:12px 14px;margin-bottom:9px;transition:border-color .15s}
.pf-card:hover{border-color:var(--accent)}
.pf-top{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.pf-who{font-size:var(--fs-lg);font-weight:600;color:var(--text)}
.pf-caret{margin-left:auto;color:var(--muted);font-size:var(--fs-xs);white-space:nowrap}
/* 折叠态 5 格：标签 / 大字数值 / 下挂「上期 X」。
   ⚠ 卡片内放不下订单数据页那种「数值左端 + 上期右端」两端对齐（那边每格约 360px），
     这里格子约 200px ⇒ 上期值落在数值下一行；字号也相应降到 19px 一档。 */
.pf-meta{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:12px var(--sp-3);margin-top:12px}
.pf-kv .pf-k{display:block;font-size:var(--fs-xs);color:var(--hint)}
.pf-kv .pf-v{display:block;font-size:19px;font-weight:600;line-height:1.15;color:var(--text);
  font-variant-numeric:tabular-nums;margin-top:2px}
.pf-kv .pf-v.good{color:var(--good)}.pf-kv .pf-v.warn{color:var(--warn)}.pf-kv .pf-v.bad{color:var(--bad)}
.pf-kv .pf-v .pf-u{font-size:var(--fs-xs);font-weight:400;color:var(--muted);margin-left:3px}
.pf-kv .pf-prev{display:block;font-size:var(--fs-xs);color:var(--muted);margin-top:3px;font-variant-numeric:tabular-nums}
.pf-drill{display:none;margin-top:12px;padding-top:12px;border-top:1px solid var(--border)}
.pf-card.pf-open .pf-drill{display:block}
/* ★ 2026-10-07（岩峰："注意空间利用率"）：展开区四段由**竖着堆**改成**两栏网格** ——
   改前四段各自通栏堆叠 ⇒ 卡片很高、而每段右边一大片空。现在 ①|② 一行、③|④ 一行。
   ⚠ 窄屏（≤820）降级回单列，与全站断点一致。 */
/* ★ 2026-10-07：展开区由**两栏改单栏** —— 两栏时「逐工序对标」只有半宽 ⇒ 值区放不下
   「同岗 3 时 30 分」被**半路折断**（10-07 修过同类问题又复发）。单栏后条更长、对比更清楚。 */
.pf-grid{display:flex;flex-direction:column;gap:15px}
.pf-seg{min-width:0}
@media (max-width:820px){.pf-grid{grid-template-columns:minmax(0,1fr)}}
.pf-dt{font-size:var(--fs-xs);color:var(--muted);margin:11px 0 7px}
.pf-dt:first-child{margin-top:0}
.pf-dt b{color:var(--text-2)}
.pf-rng{color:var(--muted);font-size:var(--fs-xs);margin-left:8px;font-weight:400}
/* ① 环比：本期 / 上期 各一行「标签 + 条 + 值（值跟到条尾）」 */
.pf-cmp-row{padding:7px 0}
.pf-cmp-n{display:block;font-size:var(--fs-xs);color:var(--hint);margin-bottom:5px}
.pf-cmp-line{display:flex;align-items:center;gap:10px}
.pf-cmp-line+.pf-cmp-line{margin-top:4px}
.pf-cmp-line .lb{flex:0 0 auto;font-size:var(--fs-xs);color:var(--muted)}
.pf-cmp-bar{flex:1 1 auto;min-width:0;display:block;height:9px;border-radius:var(--r-xs);background:var(--track);overflow:hidden}
.pf-cmp-bar>i{display:block;height:100%;border-radius:var(--r-xs)}
.pf-cmp-v{flex:0 0 auto;min-width:78px;text-align:right;font-size:var(--fs-xs);color:var(--muted);
  white-space:nowrap;font-variant-numeric:tabular-nums}
.pf-cmp-line.now .pf-cmp-v{color:var(--text-2);font-weight:500}
/* 上一期完全没有他的记录时的整行提示（原 `.pf-cmp-d.pf-cmp-full`，长句不塞定宽列） */
.pf-cmp-full{display:block;font-size:var(--fs-xs);color:var(--muted);line-height:1.5;white-space:normal}
/* ② 每道工序（对照同岗位该工序均值，**竖线就是均值**）。
   ★ 2026-10-07（岩峰：「一排放不开就做成两排」）：第三列的值区改成**两个不可折的块** ——
   数值一块、同岗参照一块；放得下并排一行、放不下**整块**落到第二行。
   改前是纯文本自由折行 ⇒ 会出现「同岗 401 小时 / 59 分」这种**半路折断**（截图反馈）。
   列宽用固定 132px（不是 auto）⇒ 各行条的右端仍然对齐。 */
.pf-dr{display:grid;grid-template-columns:minmax(0,150px) minmax(0,1fr) 132px;gap:0 var(--sp-3);align-items:center;padding:5px 0}
.pf-dr .pf-s{font-size:var(--fs-sm);color:var(--text-2)}
.pf-dr .pf-s .pf-nn{color:var(--muted);font-size:var(--fs-xs)}
/* ★ 2026-10-07（岩峰裁决 C1）：「借调」小标 —— 这道工序是**别人把他借调过去**做的（非本职）。
   刻意用**暖色（warn）而不是红**：借调本身不是错，只是要一眼看出"这道不是他本职"，
   不剔除记录（"有记录就不怕捣乱"）。 */
.pf-dr .pf-s .pf-borrow{display:inline-block;margin-left:5px;padding:0 5px;border-radius:var(--r-xs);
  background:var(--wa-soft);color:var(--warn);font-size:var(--fs-xs);line-height:16px;
  white-space:nowrap;vertical-align:1px}
/* ★ 2026-10-07（C1 配套）：首列 150px → 220px，**专门为「借调 N」小标腾地方**。
   逐行实测量尺（nowrap 克隆 + getBoundingClientRect）：
     4 字工序名 + 「1 单」+「借调 1」 = 118px（原 150px 够）
     6 字工序名 + 「23 单 · 退回 12」+「借调 12」 = **215px**（原 150px 会挤成两行，实测行高 31→52）
   ⇒ 取 220px。中列是 `1fr`（条），窄 70px 无感；窄屏 `.pf-dr{display:block}` 下该列宽不生效。
   ⚠ 单独成条（不改进原行）——`_chk_text_clip.py` 的存量基线按行文本做键。 */
.pf-dr{grid-template-columns:minmax(0,220px) minmax(0,1fr) 132px}
.pf-dr .pf-b{height:8px;border-radius:var(--r-xs);background:var(--track);position:relative}
.pf-dr .pf-b>i{display:block;height:100%;border-radius:var(--r-xs);background:var(--good)}
.pf-dr.warn .pf-b>i{background:var(--warn)}
.pf-dr.bad .pf-b>i{background:var(--bad)}
.pf-dr .pf-b .pf-mk{position:absolute;top:-2px;bottom:-2px;width:2px;background:var(--text);opacity:.65}
.pf-dr .pf-t{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 7px;font-size:var(--fs-sm);color:var(--text);font-variant-numeric:tabular-nums}
.pf-dr .pf-t .pf-v{white-space:nowrap}
.pf-dr .pf-t .pf-nn{color:var(--muted);font-size:var(--fs-xs);white-space:nowrap}
/* ③ 最慢的 N 单 —— 改用通用 `table.tb`（方案 C），本页**不再自带列表样式**。
   （`.pf-slist` / `.pf-li` / `.pf-od` / `.pf-mn` / `.pf-bk` / `.pf-hh` 随之退役。） */
/* ④ 交付时刻（8–19 点柱状图，18 点后橙色） */
.pf-hbars{display:flex;align-items:flex-end;gap:5px;margin-top:6px}
.pf-hb{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:4px}
.pf-hb i{display:block;width:66%;max-width:20px;border-radius:var(--r-xs) 3px 0 0;background:var(--accent);opacity:.85}
.pf-hb.eve i{background:var(--warn)}
.pf-hb b{font-size:var(--fs-xs);font-weight:400;color:var(--muted)}
/* 空态 */
.pf-empty{padding:var(--sp-6) var(--sp-3);text-align:center;color:var(--text-2);font-size:var(--fs-sm)}
.pf-empty-none{color:var(--text-2)}

/* ===== 计入人效统计的人员面板（系统设置 → 人效统计 → 计入人员；★ 2026-09-30）===== */
/* ★ 2026-10-09（岩峰定·第 74 批④）：原 `max-width:760px` ⇒ 容器 1018px 只用 760，**右半边空着**。
   去掉上限，表格占满（与「订单类型」「品牌管理」等设置页同宽）。 */
.pp-wrap{max-width:none}
.pp-head{font-size:var(--fs-lg);font-weight:600;color:var(--text);margin-bottom:4px}
/* ★ 2026-10-12（第 88 批·需求5）：原 `.pp-note{...}` 已删除 —— 三处消费点（人效「计入人员」页
   的说明文案）本批一并删掉，CSS 随之零引用 ⇒ 按「不留死代码」清理。 */
.pp-empty{padding:var(--sp-6) var(--sp-3);text-align:center;color:var(--text-2);font-size:var(--fs-sm)}
/* ★ 2026-10-07（岩峰：「画红圈的地方需要优化」）：原来是「透明底 + 描边」——
   在深色主题下直接透出页面渐变 ⇒ 整块看着是灰的、**没有卡片感**，与同页的 `.sys-list` 白卡
   不是一套语言。补上卡片底色，圆角一并并入全站那一档（`--r-xl`）。 */
.pp-table{border:1px solid var(--edge);border-radius:var(--r-xl);overflow:hidden;background-color:var(--panel)}
.pp-tr{display:grid;grid-template-columns:1.2fr 2fr 140px;align-items:center;gap:var(--sp-2);padding:var(--sp-3) 13px;border-bottom:1px solid var(--border);font-size:var(--fs-sm)}
.pp-tr:last-child{border-bottom:none}
.pp-th{background:var(--panel2);color:var(--muted);font-size:var(--fs-xs);font-weight:500;padding:8px 13px}
.pp-c1{color:var(--text);font-weight:500;overflow-wrap:anywhere;min-width:0;text-align:center}
.pp-c1 .pp-off{font-size:var(--fs-xs);font-weight:400;color:var(--muted);background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-pill);padding:1px 7px;margin-left:6px;white-space:nowrap;vertical-align:middle}
.pp-c2{color:var(--muted);overflow-wrap:anywhere;font-size:var(--fs-xs);min-width:0;text-align:center}
.pp-c3{display:flex;align-items:center;justify-content:center;gap:9px}
.pp-state{font-size:var(--fs-xs);white-space:nowrap}
.pp-state.on{color:var(--good)}
.pp-state.off{color:var(--muted)}
.pp-switch{position:relative;flex:none;width:40px;height:22px;border:none;border-radius:var(--r-pill);background:#6b7480;cursor:pointer;transition:background .15s;padding:0}
.pp-switch::after{content:'';position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.3);transition:transform .15s}
.pp-switch.on{background:#3ecf8e}
.pp-switch.on::after{transform:translateX(18px)}
.pp-switch.off{background:#6b7480}
.pp-foot{margin-top:12px;font-size:var(--fs-xs);color:var(--muted)}

/* ★ 手机端适配（≤820）：容器级 —— 真机就是浏览器视口，直接 @media 即可。
   注意：.pf-caret 桌面显示、手机隐藏（默认 display:inline → 此处 display:none，成对写）。 */
@media (max-width:820px){
  .pf-gh{gap:6px}
  .pf-card{padding:10px 11px}
  .pf-caret{display:none}
  .pf-meta{grid-template-columns:repeat(2,1fr);gap:9px 10px}
  /* ★ 2026-10-07：`.pf-cmp-row` 已由「4 列 grid」改成「块级 + 内部两行 flex」
     ⇒ 旧的 `grid-template-columns` 已失效，这里只收紧间距/条高/值列宽。
     （`.pf-slist` 那三条覆写随之删除 —— 该列表已整体换成 `table.tb`，元素不存在了。） */
  .pf-cmp-row{padding:6px 0}
  .pf-cmp-bar{height:8px}
  .pf-cmp-v{min-width:64px}
  .pf-dr{display:block;padding:var(--sp-2) 0;border-bottom:1px solid var(--border)}
  .pf-dr:last-child{border-bottom:none}
  .pf-dr .pf-b{display:none}
  .pf-dr .pf-s{display:block}
  .pf-dr .pf-t{display:block;margin-top:2px}
  .pf-hbars{gap:4px}
  .pf-hb i{max-width:none;width:74%}
  /* 计入人员：手机端改两行（姓名 / 岗位·级别 左列，开关右列），零横向溢出 */
  .pp-th{display:none}
  .pp-tr{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:'n s' 'm s';gap:2px var(--sp-3);padding:10px 12px}
  .pp-c1{grid-area:n}
  .pp-c2{grid-area:m}
  .pp-c3{grid-area:s}
}
/* ==========================================================================
   手机端触控目标补漏（2026-10-03，WCAG 2.5.8 AA：目标 ≥24×24 CSS px）
   --------------------------------------------------------------------------
   由来：审计指出移动端仍有小于 24×24 的可点控件。核对既有「触控兜底块」后，
   下列控件**未被覆盖**，在此逐条抬到 ≥24×24。全部只在 ≤820 生效 → 桌面端零影响。
   · .toast .x      —— toast 上的「×」关闭图标按钮，实测 26×18（唯一命中"18-19px 图标按钮"者）
   · .pp-switch     —— 人效统计「计入人员」开关，40×22（高度不足）→ 用 ::before 扩命中区，外观不动
   · .todo-badge    —— 待办卡跨工序可点徽章，约 20px 高
   · .fu-bar .fu-btn—— 待办「待处理跟进」条上的按钮，约 23px 高
   · .tl-link       —— 流转记录卡片内独立文字链接（查看/修正），约 19px 高
   已核对无需改动（实测达标，勿重复动）：.pm-tgl(46×44)、.flow-pills .pill i(44×44)、
   .dp-nav(44×44)、.close(min 44×44)、.btn-sm(40)、.stat-card/dash-card(≥56)、.bar-row 可点行(44)。
   ========================================================================== */
@media (max-width:820px){
  .toast .x{min-width:24px;min-height:24px;display:inline-flex;align-items:center;justify-content:center}
  .pp-switch::before{content:'';position:absolute;left:-2px;right:-2px;top:-4px;bottom:-4px}
  .todo-badge{min-height:24px}
  .fu-bar .fu-btn{min-height:24px}
  .tl-link{min-height:24px;display:inline-flex;align-items:center}
}

/* ══════════════════════════════════════════════════════════════════════════════
   ★ 2026-10-04（L1 改造 · 批 3·视觉）
   ──────────────────────────────────────────────────────────────────────────────
   与预览稿 `_previews/L1-master-detail.html`（岩峰定稿）同一套材质语言：
     · 背景 = mesh 光斑（.bg-layer 的三个 <i>）+ 颗粒噪点（::before）
     · 玻璃 = **只给 chrome**（顶栏 header / 导航 nav / 常驻详情栏 #detpane）—— 预算 3
     · 数据面（.card / 表格 / 统计卡 / 字段卡）**一律不透明**（铁律）
     · 顶边高光 = 1px 渐隐横线（background-image）—— **不用 inset**：
       inset 会沿圆角绕成一道完整白弧（像给卡片描边）
   ⚠ 配色沿用本系统既有令牌（--accent #4f8cff），**不换色相** —— 高级感来自材质与层次。
   ⚠ 媒体特性默认**不响应**（<html data-glass="force">），保留 `html:not([data-glass="force"])`
     分支供"跟随系统"时优雅降级（保材质阶梯 + 保光斑，不是压成一片灰）。
   ══════════════════════════════════════════════════════════════════════════════ */

/* ── 背景层：mesh 光斑 + 颗粒噪点 ──
   fixed + z-index:-1 ⇒ 画在 body 背景之上、所有内容之下（不随滚动跑，玻璃才有东西可"透"）。
   光斑尺寸用**相对百分比**（配 aspect-ratio 锁圆）：固定像素会在宽屏被稀释成中性灰。 */
.bg-layer{position:fixed;inset:0;z-index:-1;overflow:hidden;pointer-events:none}
.bg-layer i{position:absolute;aspect-ratio:1;border-radius:50%;filter:blur(76px)}
.bg-layer i:nth-child(1){width:clamp(240px,41%,900px);background:var(--aura1);left:-9%;top:-20%;opacity:var(--aura-a)}
.bg-layer i:nth-child(2){width:clamp(220px,37%,820px);background:var(--aura2);right:-8%;top:2%;opacity:var(--aura-b)}
.bg-layer i:nth-child(3){width:clamp(280px,48%,960px);background:var(--aura3);left:30%;bottom:-43%;opacity:var(--aura-c)}
.bg-layer::before{content:"";position:absolute;inset:0;opacity:var(--grain);mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E")}
/* ── 数据面的"顶边高光" ──
   实色卡（不透明，铁律不变）也有一条 1px 渐隐亮线 —— 页面里的"精致感"就是这么一条线攒出来的。
   ⚠ 只加给**纯色底**（`background:var(--panel)`）的数据面；
     `.stat-card` 自己用 `background:` **简写**写了渐变底，加 background-image 会把它冲掉 —— 绝不碰。 */
html:not([data-theme="light"]) :is(.card,.bcard,.skel-card,.skel-fail,.dash-block){
  background-image:linear-gradient(90deg,transparent,rgba(255,255,255,.13) 16%,rgba(255,255,255,.13) 84%,transparent);
  background-size:100% 1px;background-position:0 0;background-repeat:no-repeat;
}
/* 玻璃构件在**玻璃禁用**时的兜底材质（不透明但有层次）：越"厚"越亮 */
@media (prefers-reduced-transparency:reduce){
  html:not([data-glass="force"]) header,html:not([data-glass="force"]) nav,
  html:not([data-glass="force"]) .bsplit-r{-webkit-backdrop-filter:none;backdrop-filter:none}
  html:not([data-glass="force"]) header,html:not([data-glass="force"]) nav{background-color:var(--panel2)}
  html:not([data-glass="force"]) .bsplit-r{background-color:var(--panel)}
  /* 光斑**保留**（它是背景装饰色、不是透明度），只把强度收一档。
     ⚠ 三个光斑强度各不相同，必须逐个降 —— 一把盖成同一个值会抹掉色彩氛围。 */
  html:not([data-glass="force"]) .bg-layer i:nth-child(1){opacity:calc(var(--aura-a) * .6)}
  html:not([data-glass="force"]) .bg-layer i:nth-child(2){opacity:calc(var(--aura-b) * .6)}
  html:not([data-glass="force"]) .bg-layer i:nth-child(3){opacity:calc(var(--aura-c) * .6)}
}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  header,nav{background-color:var(--panel2)}
  .bsplit-r{background-color:var(--panel)}
}
@media (forced-colors:active){
  .bg-layer{display:none}
  header,nav,.bsplit-r{-webkit-backdrop-filter:none;backdrop-filter:none;background-color:Canvas;border-color:CanvasText;box-shadow:none}
}

/* ══════════════════════════════════════════════════════════════════════════════
   ★ 2026-10-04（L1 改造 · 批 4·打磨）
   ══════════════════════════════════════════════════════════════════════════════ */
/* ── 细滚动条：滚动条本身也是界面的一部分（原来各页只有零星几处，这里统一） ──
   ⚠ nav 自己写了 `scrollbar-width:none`（更具体）→ 底栏仍不显示滚动条，不受影响。 */
*{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--text) 20%,transparent) transparent}
::-webkit-scrollbar{width:11px;height:11px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--text) 20%,transparent);
  border-radius:var(--r-md);border:3px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--text) 34%,transparent);
  background-clip:content-box}
::-webkit-scrollbar-corner{background:transparent}

/* ── 常驻详情栏的正文滚动条与内容右缘留出间距（避免滚动条压住文字） ── */
#detpane{padding-right:10px}

/* ══════════════════════════════════════════════════════════════════════════════
   ★ 2026-10-04（L1 对齐 · 批 A·外壳）
   ──────────────────────────────────────────────────────────────────────────────
   与预览稿 `_previews/L1-master-detail.html` 同构：
     · 导航从"顶部通栏横排"改为**左侧悬浮玻璃侧栏**（204px，可收窄成 60px 图标条）
     · 顶栏改为**卡片式**（圆角 + 与侧栏同样留 14px）
     · main 不再限宽居中（内容区撑满侧栏右侧）
   ⚠ 桌面用 `position:sticky` 而非"内容独立滚动"：**保持 body 滚动**，
     否则所有依赖 `pageYOffset` 的既有探针会一起崩。
   ⚠ 手机端 `.sidenav{display:contents}` —— 侧栏盒子消失、`nav` 恢复成底部固定栏，
     与改造前的手机行为**逐字一致**。
   ══════════════════════════════════════════════════════════════════════════════ */
/* ── 玻璃材质类（L1 的设计语言；构件用 class="gl m-*" 组合）──
   ⚠ 预览页那套 `.gl/.m-*` 只存在于 `_previews/assets/glass.css`，**生产系统没有** ——
     不补这段，`<aside class="sidenav gl m-thin">` 就是个"什么都没有"的空类：
     侧栏照旧透出底色、看着像玻璃其实没有模糊（实测 `#sidenav` 的 backdrop-filter = none）。
   数据面**不使用**这些类（不透明铁律）。 */
.gl{position:relative;background-color:var(--m-thin);
  background-image:linear-gradient(90deg,transparent,var(--rim-line) 12%,var(--rim-line) 88%,transparent);
  background-size:100% 1px;background-position:0 0;background-repeat:no-repeat;
  -webkit-backdrop-filter:blur(18px) saturate(1.8);backdrop-filter:blur(18px) saturate(1.8);
  border:1px solid var(--edge);
  box-shadow:inset 1px 0 0 var(--rim-side),inset -1px 0 0 var(--rim-side),
    inset 0 -1px 0 var(--rim-bot),0 16px 40px -18px var(--lift)}
.m-thin{background-color:var(--m-thin);-webkit-backdrop-filter:blur(18px) saturate(1.8);backdrop-filter:blur(18px) saturate(1.8)}
.m-reg{background-color:var(--m-reg);-webkit-backdrop-filter:blur(20px) saturate(1.9);backdrop-filter:blur(20px) saturate(1.9)}
.m-thick{background-color:var(--m-thick);-webkit-backdrop-filter:blur(22px) saturate(1.75);backdrop-filter:blur(22px) saturate(1.75)}
/* 玻璃兜底（跟随系统"减少透明度"时）：不透明但有层次。
   默认 `data-glass="force"` ⇒ 本段永不命中。 */
@media (prefers-reduced-transparency:reduce){
  html:not([data-glass="force"]) .gl{-webkit-backdrop-filter:none;backdrop-filter:none;background-color:var(--panel2)}
}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .gl{background-color:var(--panel2)}
}

#app{display:flex;align-items:stretch}

/* ── 左侧悬浮玻璃侧栏（thin）── */
.sidenav{flex:0 0 204px;width:204px;position:sticky;top:14px;align-self:flex-start;
  height:calc(100vh - 28px);margin:14px 0 14px 14px;box-sizing:border-box;
  border-radius:var(--r-xl);padding:13px 11px;display:flex;flex-direction:column;
  transition:width .26s var(--ease-m3),padding .26s var(--ease-m3),flex-basis .26s var(--ease-m3)}
.sn-brand{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-1) var(--sp-1) 13px;
  border-bottom:1px solid var(--edge);margin-bottom:10px}
.sn-logo{width:32px;height:32px;border-radius:var(--r-lg);flex:0 0 auto;
  background:linear-gradient(140deg,var(--accent),#a78bfa);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.5),0 4px 12px -4px var(--accent);
  display:grid;place-items:center;font:800 var(--fs-sm)/1 var(--mono);color:#fff}
.sn-bt{margin-right:auto;min-width:0;overflow:hidden}
.sn-bt b{font-size:var(--fs-sm);font-weight:600;display:block;letter-spacing:-.01em;white-space:nowrap;
  color:var(--gl-ink,#eef1f7)}
.sn-bt span{font-size:var(--fs-xs);white-space:nowrap}
.sn-cbtn{width:26px;height:26px;border-radius:var(--r-md);border:1px solid var(--edge);flex:0 0 auto;
  background:var(--m-reg);color:var(--gl-ink2);cursor:pointer;font-size:var(--fs-xs);line-height:1;
  display:grid;place-items:center;
  transition:background .2s var(--ease-m3),color .2s var(--ease-m3),transform .26s var(--ease-m3)}
.sn-cbtn:hover{color:var(--gl-ink);background:var(--m-thick)}
/* ★ 2026-10-07（岩峰定）：侧栏账号区**纯展示、一律不可点** ——
   去掉 `cursor:pointer` / `:hover` 高亮 / `:focus-visible` 焦点框，`>` 箭头元素与 `.sn-arrow`
   规则一并删掉（个人设置只能从左侧导航进）。这样它在视觉与属性两层都"没有可点的暗示"。 */
.sn-me{display:flex;align-items:center;gap:var(--sp-3);padding:11px var(--sp-2) var(--sp-1);
  border-top:1px solid var(--edge);margin-top:8px;border-radius:var(--r-md)}
.sn-av{width:28px;height:28px;border-radius:50%;display:grid;place-items:center;flex:0 0 auto;
  font:700 var(--fs-xs)/1 var(--mono);color:#fff;
  background:linear-gradient(140deg,#a78bfa,var(--accent));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45)}
.sn-mt{min-width:0;overflow:hidden;white-space:nowrap;flex:1 1 auto}
.sn-mt b{font-size:var(--fs-xs);font-weight:600;display:block;white-space:nowrap;
  color:var(--gl-ink,#eef1f7)}
.sn-mt #snLeaveDot{font-size:var(--fs-xs);color:var(--warn);white-space:nowrap}
/* ★ 2026-10-07：`.sn-arrow`（账号区那个 `›` 箭头）规则已删 —— 账号区改为纯展示、不可点，
   箭头元素也从 HTML 里摘掉了（没有它才不会有"这里能点进去"的暗示）。 */

/* ⚠ 2026-10-07（岩峰定）：顶栏手机端「请假」按钮**已删除**（连同 .gtb-leave 全部样式、
   `#topLeaveBtn`、以及 `applyLeaveEntry` 里对它的 perm-off 处理）——
   请假入口统一收在「个人设置 → 请假登记」卡。留此说明以免又被补回来。 */

/* ── 侧栏里的导航（原顶部横排的 nav 搬进来；只覆盖表现，不动 DOM 顺序）──
   ⚠ 必须带 `!important`：浅色主题写的是 `html[data-theme="light"] nav{...}`（0,1,2），
     与 `.sidenav nav`（0,1,1）比**特异性更高** —— 不加就会被浅色规则反盖回去
     （侧栏里凭空空出半透明白底 / 手机端冒出一条渐变底）。
   ⚠ 同理 `.sidenav nav button`（0,1,2）与既有的 `nav button.nav-over`（0,1,2）**同分**，
     而本文件在**最末尾** ⇒ 会吃掉 `.nav-over{display:none}`（手机端底栏收敛当场失效）。
     所以下面显式补一条更高分的 `.nav-over` 规则。 */
.sidenav nav{display:flex;flex-direction:column;gap:2px;flex:1;min-height:0;
  overflow-y:auto;overflow-x:hidden;padding:0;
  border:0!important;border-radius:0;background:none!important;background-image:none!important;
  box-shadow:none!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important}
.sidenav nav button{display:flex;align-items:center;gap:var(--sp-3);height:35px;padding:0 var(--sp-3);
  border-radius:var(--r-md);border:none;background:none;font-family:inherit;font-size:var(--fs-sm);
  font-weight:500;color:var(--gl-ink2,rgba(255,255,255,.72));cursor:pointer;
  white-space:nowrap;position:relative;text-align:left;
  transition:background .2s var(--ease-m3),color .2s var(--ease-m3)}
.sidenav nav button::before{content:"";width:6px;height:6px;border-radius:50%;flex:0 0 auto;
  background:currentColor;opacity:.45}
.sidenav nav button:hover{background:var(--m-reg);color:var(--gl-ink,#eef1f7)}
/* ★ 2026-10-13（第94批 · C1「深色侧栏选中项读不清」，来源=考核系统同日修法）：
   选中项原先用 `--accent-soft` 半透明底 ⇒ 背后光斑（--aura1 与选中文字 --accent **同值 #4f8cff**）
   透过玻璃侧栏把底色染成 rgb(≈45,104,217) —— 真机像素实测 CR 仅 **1.57**（正文阈值 4.5；考核当时
   1.59，同一根因）。改**深色实底** --nav-active-bg 后与"背后有什么"无关。
   ⚠ 手机端底栏的 .active 在下方 @media 里另有口径（transparent），不受本行影响、也不跟改。 */
.sidenav nav button.active{background:var(--nav-active-bg);color:var(--accent);font-weight:600}
.sidenav nav button.active::before{opacity:1}
.sidenav nav button .nav-m{display:none}
.sidenav nav button .nav-d{display:inline}

/* ── 内容列 ── */
.content{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;
  gap:var(--sp-3);padding:14px}
/* 顶栏卡片化：通栏 → 圆角卡片（仍 sticky 常驻） */
.content .app-topbar{position:sticky;top:14px;z-index:50}
.content header{border:1px solid var(--edge);border-radius:var(--r-lg);
  box-shadow:inset 1px 0 0 var(--rim-side),inset -1px 0 0 var(--rim-side),
    inset 0 -1px 0 var(--rim-bot),0 12px 32px -20px var(--lift)}
/* main 不再限宽居中（内容区撑满侧栏右侧） */
.content main{padding:0;max-width:none;margin:0;width:auto}

/* ── 手机端：侧栏盒子消失，nav 回到"底部固定栏"（行为与改造前一致）── */
@media (max-width:820px){
  #app{display:block}
  .content{padding:var(--sp-3) var(--sp-2);gap:var(--sp-2)}
  .content main{padding:0;max-width:none;margin:0;width:auto}
  .content .app-topbar{top:0}
  .sidenav{display:contents}
  .sidenav .sn-brand,.sidenav .sn-me{display:none}
  .sidenav nav{position:fixed;left:0;right:0;bottom:0;top:auto;z-index:50;flex-direction:row;
    gap:0;padding:0;height:auto;border-radius:0;overflow-x:visible;
    border:0!important;border-top:1px solid var(--edge)!important;
    background-color:var(--m-thick)!important;background-image:none!important;
    -webkit-backdrop-filter:blur(22px) saturate(1.75)!important;backdrop-filter:blur(22px) saturate(1.75)!important;
    box-shadow:0 -8px 24px -12px var(--lift)!important}
  /* ★ 手机端底栏收敛（既有能力）：被收起的页签必须真的消失 —— 见上方特异性说明 */
  .sidenav nav button.nav-over{display:none!important}
  .sidenav nav button{flex:1 1 0;min-width:0;height:auto;min-height:44px;padding:var(--sp-3) 2px;
    border-radius:0;flex-direction:column;justify-content:center;gap:var(--sp-1);font-size:var(--fs-xs);
    font-weight:500;text-align:center}
  .sidenav nav button::before{width:5px;height:5px}
  .sidenav nav button .nav-m{display:inline}
  .sidenav nav button .nav-d{display:none}
  /* ★ 2026-10-11：未读红点——桌面端改「右端垂直居中」，手机底栏按钮窄（~65px）居中会顶到
     文字 ⇒ 保持原「右上角」形态（两种形态各自最优，见基础规则处的注释）。 */
  .sidenav nav button .nav-dot{top:3px;transform:none}
  .sidenav nav button.active{background:transparent;color:var(--accent)}
}

/* ══════════════════════════════════════════════════════════════════════════════
   ★ 2026-10-04（L1 对齐 · 批 B·顶栏与KPI）
   ──────────────────────────────────────────────────────────────────────────────
   · 顶栏内部改成 L1 的排法：**页名 → 副标题 → 搜索框 → 弹簧 → 右角标区（云端 + 双 logo）**
   · 订单查询页顶部加 **5 格 KPI 条**（不透明数据面；hero 格用 color-mix 对实色合成）
   ══════════════════════════════════════════════════════════════════════════════ */
.content header{gap:11px;padding:11px 14px}
.content header h1{font-size:var(--fs-lg);font-weight:600;letter-spacing:-.012em;margin:0;flex:none}
.gsub{font-size:var(--fs-xs);color:var(--muted);white-space:nowrap;flex:0 1 auto;overflow:hidden}
/* ⚠ `flex:0 1 250px`（而不是 `0 0`）：窄桌面视口下必须能收缩，否则顶栏会横向溢出
   （`_probe_header_fit.js` 的 F2「header 无横向溢出」会当场变红）。 */
.gsearch{flex:0 1 250px;min-width:110px;height:32px;border-radius:var(--r-pill);background:var(--m-reg);
  border:1px solid var(--edge);display:flex;align-items:center;gap:var(--sp-2);padding:0 var(--sp-3);
  font-size:var(--fs-xs);box-shadow:inset 0 1px 0 var(--rim-side)}
.gsearch .gsi{width:14px;height:14px;flex:0 0 auto;opacity:.7}
/* ⚠ 全站 input 有 `background/height/padding !important` 的硬规则 —— 必须同样带 !important 才压得住 */
.gsearch input{flex:1;min-width:0;width:auto!important;height:auto!important;
  background:transparent!important;border:0!important;box-shadow:none!important;
  padding:0!important;font:inherit;color:var(--text)}
.gsearch input::placeholder{color:var(--muted)}
.gtb-spacer{flex:1}
.gtb-right{display:flex;align-items:center;gap:14px;flex:0 0 auto;
  padding-left:15px;border-left:1px solid var(--edge)}
.gtb-right #cloudBadge{margin-left:0;flex:none}

/* ── KPI 统计条（5 格 · 不透明数据面）── */
.kpi-row{display:grid;grid-template-columns:repeat(5,1fr);gap:var(--sp-3);margin-bottom:var(--sp-3)}
.kpi-row .kpi{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:var(--sp-3) 14px;display:flex;flex-direction:column;gap:5px;position:relative;overflow:hidden}
/* ⚠ 用 background-image 而不是 `background:` 简写 —— 简写会把 background-color 一起重置成 transparent */
.kpi-row .kpi.hero{background-image:linear-gradient(140deg,color-mix(in srgb,var(--accent) 9%,var(--panel)),var(--panel) 58%)}
.kpi-row .kpi .cap{font-size:var(--fs-xs);color:var(--muted);white-space:nowrap}
.kpi-row .kpi .v{font:650 var(--fs-2xl)/1 var(--mono);font-variant-numeric:tabular-nums;letter-spacing:-.025em;color:var(--text)}
.kpi-row .kpi .v.bad{color:var(--bad)}
.kpi-row .kpi .v.warn{color:var(--warn)}
.kpi-row .kpi .v.acc{color:var(--accent)}
.kpi-row:empty{display:none}

@media (max-width:820px){
  .content header{gap:9px;padding:9px 12px}
  .gsub{display:none}
  /* ★ L1 手机端本来就**隐藏搜索框**（`.stage[data-form="phone"] .search{display:none}`）——
     不隐藏的话 390px 顶栏会被它吃掉全部宽度，页名被压成竖排（实测破相）。 */
  .gsearch{display:none}
  .gtb-right{padding-left:0;border-left:0;gap:9px}
  .kpi-row{grid-template-columns:1fr 1fr;gap:8px}
  .kpi-row .kpi{padding:11px 12px}
  .kpi-row .kpi .v{font-size:var(--fs-xl)}
}
/* 极小屏（≤**380** —— 公司**登记过的断点档位**，别自创 400）：顶栏只剩「云端徽章 + 双 logo」，
   按 L1 的做法把 logo/徽章再收一档 —— 不然 320px 下 header 会横向溢出
   （实测溢出 11px，`_probe_header_fit.js` 的 F2 当场变红）。 */
@media (max-width:380px){
  .gtb-right{gap:7px}
  .gtb-right .app-logos{gap:7px}
  .gtb-right .app-logos img{height:18px}
  .gtb-right .app-logos img.logo-weeduo{height:15px}
  .gtb-right .app-logos .logo-sep{height:16px}
  .gtb-right #cloudBadge{padding:2px 7px}
}

/* ══════════════════════════════════════════════════════════════════════════════
   ★ 2026-10-04（L1 对齐 · 批 C·收尾）
   ══════════════════════════════════════════════════════════════════════════════ */
/* ── 列表卡片：标题行（.lhead）与表格合并成**同一张卡** ── */
.bsplit-l{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-md);overflow:hidden}
.lhead{display:flex;align-items:center;gap:9px;padding:11px 15px;border-bottom:1px solid var(--border)}
.lhead b{font-size:var(--fs-md);font-weight:600;color:var(--text);white-space:nowrap}
.lhead .n{font:600 var(--fs-xs)/1 var(--mono);color:var(--muted);background:var(--panel2);
  border-radius:var(--r-pill);padding:4px 9px}
.lhead .lchip{font-size:var(--fs-xs);color:var(--muted);background:var(--panel2);
  border:1px solid var(--border);border-radius:var(--r-pill);padding:var(--sp-1) 9px;white-space:nowrap}
.lhead .lchip.run{background:var(--accent-soft);border-color:transparent;color:var(--accent)}
.lhead .lchip.bad{background:var(--ba-soft);border-color:transparent;color:var(--bad)}
@media (max-width:820px){
  .bsplit-l{background:none;border:0;border-radius:0;overflow:visible}
  .lhead{display:none}
}

/* ══════════════════════════════════════════════════════════════════════════════
   ★ 2026-10-04（L1 对齐 · 批 D·详情栏）
   ──────────────────────────────────────────────────────────────────────────────
   ① 三段式：头部固定 / 正文滚动 / 底部动作固定（L1 的 .ph / .pbody / .pact）
   ② 字段**卡化**：汇总条与信息网格的每一项变成带边框小卡（L1 的 .dcell）
   ③ 区块标题降级成"弱标签"（L1 的 .dcell em / .dtable th）
   ⚠ 全部规则限定在 `.bsplit-r` 之内 —— **弹层那份详情一个字都不动**。
   ══════════════════════════════════════════════════════════════════════════════ */
.bsplit-r{display:flex;flex-direction:column;padding:0;overflow:hidden}
.dpane-head{flex:0 0 auto;padding:var(--sp-3) var(--sp-3) var(--sp-2);margin:0;
  border-bottom:1px solid var(--edge)}
#dpaneBody{flex:1;min-height:0;overflow:auto;padding:var(--sp-3)}

/* ① 字段卡化 */
.bsplit-r .detail-summary,
.bsplit-r .detail-summary.c5,
.bsplit-r .detail-summary.c6{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--sp-2);
  padding:0;margin:0 0 var(--sp-3);background:none;border:0}
.bsplit-r .detail-summary .sum-item{background:var(--panel2);border:1px solid var(--border);
  border-radius:var(--r-md);padding:8px 10px}
.bsplit-r .detail-summary .sum-label{font-size:var(--fs-xs);letter-spacing:.06em;color:var(--muted)}
.bsplit-r .detail-summary .sum-value{font-size:var(--fs-md);font-weight:600;color:var(--text)}
.bsplit-r .info-grid-3{grid-template-columns:1fr 1fr;gap:8px}
.bsplit-r .info-grid-3 .kv{background:var(--panel2);border:1px solid var(--border);
  border-radius:var(--r-md);padding:8px 10px}
.bsplit-r .info-grid-3 .kv .k{font-size:var(--fs-xs);letter-spacing:.06em;color:var(--muted)}
.bsplit-r .info-grid-3 .kv .v{font-size:var(--fs-md);font-weight:600;color:var(--text)}

/* ② 区块：去掉"卡片套卡片"，标题降级为弱标签 */
.bsplit-r .detail-card{background:none;border:0;padding:0;margin:0 0 12px}
.bsplit-r .detail-card-title{font-size:var(--fs-xs);font-weight:600;color:var(--muted);margin:0 0 7px}
.bsplit-r .section-title{font-size:var(--fs-xs);font-weight:600;color:var(--muted);
  border-left:0;padding-left:0;margin:0 0 7px}

/* ③ 底部动作：粘在正文底部（不随滚动消失）*/
.bsplit-r .rowbtn{position:sticky;bottom:0;z-index:2;justify-content:flex-start;
  background:var(--panel);border-top:1px solid var(--border);padding:var(--sp-3) 0 2px;margin:10px 0 0}

/* ══════════════════════════════════════════════════════════════════════════════
   ★ 2026-10-04（统一改造 · 批 3·组件归一）
   ──────────────────────────────────────────────────────────────────────────────
   位置说明：本段追加在样式表**最末尾**。与既有规则同分时"后者胜" ⇒ 无需 !important
   就能一次性收口；同时它也不删任何既有规则（回退 = 删掉本段）。
   保留不动：玻璃 .gl/.m-*、背景光斑 .bg-layer、材质令牌、--r-lg/--r-xl 大圆角。
   ══════════════════════════════════════════════════════════════════════════════ */

/* ── ① 卡片归一：所有"卡片类"共用一套形态（材质语言：实色底 + 发丝边 + 顶边高光 + 弱投影）── */
:is(.card,.bcard,.dash-block,.dbv-card,.skel-card,.skel-fail,.sgroup,.bsplit-l){
  background-color:var(--panel);
  border:1px solid var(--edge);
  border-radius:var(--r-lg);
  box-shadow:0 18px 44px -32px var(--lift);
  background-image:linear-gradient(90deg,transparent,var(--rim-card) 16%,var(--rim-card) 84%,transparent);
  background-size:100% 1px;background-position:0 0;background-repeat:no-repeat;}
/* 卡片内边距统一（原来 .card 16 / .dash-block 12 / .dbv-card 各写各的） */
:is(.card,.dash-block,.dbv-card,.sgroup){padding:var(--sp-4)}
/* 看板卡的左侧状态条是有意义的编码，明确保留 */

/* ── ② 统计卡归一：与「订单查询」页的 KPI 同一形态；蓝调底用 color-mix 对**实色**合成（数据面仍不透明）── */
:is(.stat-card,.stat-card.alt){
  background:linear-gradient(135deg,color-mix(in srgb,var(--accent) 10%,var(--panel)),
    color-mix(in srgb,var(--accent) 4%,var(--panel)));
  border:1px solid var(--edge);border-radius:var(--r-lg);
  box-shadow:0 18px 44px -32px var(--lift);
  padding:var(--sp-3) var(--sp-4);}

/* ── ③ 标签归一：统一胶囊 + 语义底（原来 .due 是小圆角、.pill/.tag 是胶囊，两套）── */
:is(.pill,.tag,.due,.lchip,.chip){
  display:inline-flex;align-items:center;justify-content:center;gap:5px;
  height:20px;padding:0 9px;border-radius:var(--r-pill);
  font-size:var(--fs-xs);line-height:1;white-space:nowrap;}
.due.over{background:var(--ba-soft);color:var(--bad)}
.due.warn{background:var(--wa-soft);color:var(--warn)}
.due.done{background:var(--ok-soft);color:var(--good)}
.due.none{background:var(--chip);color:var(--muted)}
/* ★ 2026-10-13（岩峰定·UI 审计 P0）：交期**离谱日期**的「待确认」—— 视觉同 warn 档（黄），
   但**故意不登记**进 `_bvRank` 权重表与 `dueStateClass` 映射表 ⇒ 看板不抢占前排、左色条不着色。 */
.due.chk{background:var(--wa-soft);color:var(--warn)}

/* ── ④ 输入框/包装归一：一套高度、圆角、边框、焦点 ── */
:is(.field,.date-trigger,.df-inp,.df-file,.ask-inp,.st-name,.cap-input,.sys-row input){
  border-radius:var(--r-md);}
:is(.df-inp,.df-file,.ask-inp,.st-name,.cap-input){height:var(--h-ctl)}
:is(.df-inp,.df-file,.ask-inp,.st-name,.cap-input,.date-trigger):focus{
  border-color:var(--accent);box-shadow:var(--focus-ring);outline:none}

/* ── ⑤ 区块标题归一：主标题带竖条，次级标题退成弱标签（原来 5 套各写各的）── */
:is(.section-title,.sec-title){font-size:var(--fs-md);font-weight:600;
  margin:var(--sp-4) 0 var(--sp-2);padding-left:9px;border-left:3px solid var(--accent);color:var(--text)}
:is(.detail-card-title,.sgroup-title,.lhead b){font-size:var(--fs-sm);font-weight:600;
  color:var(--text);margin:0 0 var(--sp-2);letter-spacing:0}
:is(.detail-card-title,.sgroup-title){letter-spacing:.02em}

/* ── ⑥ 交互补齐：按压 / 禁用 / 过渡，全站同一个手感 ── */
:is(.card,.bcard,.stat-card,.dbv-card,.dash-block,.todo-badge,.theme-opt,.mrow,
    .pm-row,.role-row)[onclick]:active,
button:active:not(:disabled),.btn:active:not(:disabled){filter:brightness(.96)}
:is(.btn,button):disabled{opacity:.42;cursor:not-allowed;filter:none;box-shadow:none;transform:none}
:is(.card,.bcard,.stat-card,.dbv-card,.dash-block,.pill,.tag,.due,.lchip,.chip,
    .btn,.btn-mini,.nav button,.snav nav button,.todo-badge,.theme-opt){
  transition:background-color 150ms cubic-bezier(.2,0,0,1),border-color 150ms cubic-bezier(.2,0,0,1),
    color 150ms cubic-bezier(.2,0,0,1),filter 150ms cubic-bezier(.2,0,0,1)}

/* ── ⑦ 页面级条：顶栏已有页名，页面里只留操作（不再重复标题）── */
.pagebar{display:flex;align-items:center;justify-content:flex-end;gap:var(--sp-2);
  margin:0 0 var(--sp-2);min-height:32px}
.pagebar:empty{display:none}

/* ── ⑧ 空态统一：图标 + 一句话 + 一个动作（原来只有 3 处有像样的空态）── */
.empty{gap:var(--sp-2);padding:var(--sp-6) var(--sp-4);color:var(--text-2)}
/* ★ 2026-10-13（岩峰定 · UI 审计 02）：空态**内容不铺满** ——
   一行小灰字横跨整屏（待办页、看板页的空态实测占满 60%+ 宽度）看着特别"空"。
   ⚠ 只收窄**空态自身的内容宽度**，不缩面板底色/边框 —— 那会破坏分栏与卡片结构。
   ⚠ `margin-top:auto` 的既有规则（`#view-dashboard .three>.panel>.empty`）仍生效：
      这里只动 left/right，不碰 top/bottom。 */
:is(.empty,.pf-empty,.sys-empty,.pm-empty){max-width:520px;margin-left:auto;margin-right:auto}
.empty .e-act{margin-top:var(--sp-2)}

/* ══════════════════════════════════════════════════════════════════════════════
   ★ 2026-10-04（统一改造 · 批 4·密度收口）
   ══════════════════════════════════════════════════════════════════════════════ */
/* 详情栏字段：2 列 → 3 列（同宽装下更多字段，少滚动）；内边距收到 6/9 */
.bsplit-r .detail-summary,.bsplit-r .detail-summary.c5{grid-template-columns:repeat(3,1fr);gap:6px}
/* ★ 第 68 批（交付日期第 6 格）：右栏密度收口后 6 格与 5 格同为 3 列（gap 由上面的基础规则继承）。 */
.bsplit-r .detail-summary.c6{grid-template-columns:repeat(3,1fr)}
.bsplit-r .detail-summary .sum-item{padding:6px 9px}
.bsplit-r .detail-summary .sum-value{font-size:var(--fs-md)}
.bsplit-r .info-grid-3{gap:6px}
.bsplit-r .info-grid-3 .kv{padding:6px 9px}
.bsplit-r .detail-card{margin-bottom:var(--sp-3)}

/* 页面顶部节奏统一：删掉重复的页面标题后，首个内容块统一贴顶间距 */
main>[id^="view-"]>*:first-child{margin-top:0}
.pagebar{margin:0 0 var(--sp-3)}
.pagebar:empty{margin:0}

/* 卡片内边距与块间距：让"卡片之间 12 / 卡片内部 16"成为全站唯一节奏 */
:is(.card,.dash-block,.dbv-card){padding:var(--sp-4);margin-bottom:var(--sp-3)}
:is(.stat-card-row,.dash-grid,.dbv-ov-grid){gap:var(--sp-3)}

/* ══════════════════════════════════════════════════════════════════════════════
   ★ 2026-10-04（B · 控制台 · 舒适版）：录单页重塑
   ──────────────────────────────────────────────────────────────────────────────
   骨架：单头带（6 列网格 × 2 行 = 10 字段）→ 密集明细表（行内编辑）→ 吸底操作条。
   元素语言沿用已定稿那套（玻璃 / 材质 / 大圆角 / 发丝边 / 顶边高光）—— 一处没换语言。
   全部规则 scoped 在 #view-order 内（ID 特异性 1,x,0）→ 稳压既有的 .card / :is(.card,...)
   规则，且不会波及详情弹层里的同名 `.item.itm`（那是另一套，带 .itm）。
   ══════════════════════════════════════════════════════════════════════════════ */
#view-order{display:flex;flex-direction:column;gap:var(--sp-3);min-height:calc(100vh - 132px)}
#view-order .oe-panel{position:relative;border-radius:var(--r-xl);background-color:var(--panel);
  border:1px solid var(--edge);box-shadow:0 30px 74px -36px var(--lift),0 2px 6px rgba(0,0,0,.22);min-width:0}
#view-order .oe-panel::before{content:'';position:absolute;left:var(--sp-4);right:var(--sp-4);top:0;height:1px;
  pointer-events:none;border-radius:inherit;
  background:linear-gradient(90deg,transparent,var(--rim-card) 14%,var(--rim-card) 86%,transparent)}
#view-order .oe-band{padding:var(--sp-4)}
#view-order .oe-grid6{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:11px var(--sp-3)}
#view-order .oe-fld{display:flex;flex-direction:column;gap:var(--sp-2);min-width:0}
#view-order .oe-fld.s2{grid-column:span 2}
/* ★ 2026-10-13（岩峰定 · UI 审计 11）：收货地址**单独占一整行** ——
   地址往往很长（"青岛市城阳区流亭街道空港工业园 12 号"），挤在 6 列里的 2 列，
   打字时看不全、容易填错。同时把「联系人 / 联系电话」各补成 2 列，
   让它们与「客户」凑满上面那一行，不留空槽。 */
#view-order .oe-fld.full{grid-column:1/-1}
#view-order .oe-fld>label{display:block;font-size:var(--fs-xs);font-weight:600;letter-spacing:.06em;color:var(--muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#view-order .req{color:var(--req)}   /* ★ 2026-10-11：选择器由 `.oe-fld .req` **放宽到全 `#view-order`** ——
   明细表头 th 里新增的必填星号（span[data-req]）也要吃这个色（原选择器只罩录单头 label）。 */
/* 手机端卡片「行内必填星号」（.oreq-i，≤820 卡片视图专用）：仅「配了必填」且卡片视图时显示；
   >820 横排视图**恒藏**（列名/星号都在表头 th，行内再挂一个就重复）。 */
#view-order .oe-itable .oreq-i{display:none;font-style:normal;font-weight:600}
/* ⚠ 2026-10-08 第 72 批：`下单日期` 只读块（`.oe-ro`）已无宿主（整格删除）；本组规则保留 —— 详见文件上方
   `#view-order .oe-ro{min-height:44px}` 处的说明（被 `_tools/_cloud_verify_b64.py` 锚定，删则检查变红）。 */
#view-order .oe-ro{display:flex;align-items:center;height:var(--h-ctl);padding:0 11px;border-radius:var(--r-md);
  background:var(--m-ultra);border:1px solid var(--edge);color:var(--text-2);font-size:var(--fs-md);
  font-variant-numeric:tabular-nums;overflow:hidden}
#view-order .oe-ro b{font-weight:600;white-space:nowrap}
#view-order .oe-urg{display:flex;align-items:center;justify-content:space-between;gap:10px;align-self:end;
  height:var(--h-ctl);padding:0 var(--sp-3);border-radius:var(--r-md);background:var(--m-ultra);
  border:1px solid var(--edge);cursor:pointer;min-width:0;
  /* ★ 2026-10-07（岩峰：「深色下加急这个框明显高于同行的框」）：
     它是 `<label>`，吃到了**全局 `label{margin-bottom:var(--sp-1)}`**（第 523 行，4px）；
     而它是 `align-self:end`（贴行底对齐）⇒ 被那 4px 顶上去。
     实测：`.oe-urg` 底 158 / 同排 INPUT 底 162 ⇒ **整体高 4px**。这里清零即可对齐。 */
  margin-bottom:0}
#view-order .oe-urg .t{font-size:var(--fs-sm);color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* ★ 2026-10-07（岩峰：「加急这个元素里面的文字在框内上移 1px」）：
   用 `position:relative;top` 而不是 `transform` —— 后者对 inline 元素无效。
   这是与"框整体下移 4px"配套的**框内微调**，两者互不抵消。
   ⚠ **另起一条规则、绝不改上面那条的行尾**：`_chk_text_clip.py` 的存量基线是**按行文本做键**的
     —— 把上一行的 `}` 改成 `;` 会让那行文本变样、存量 ellipsis 被误判成"新增截断"（本次真踩到）。 */
#view-order .oe-urg .t{position:relative;top:-1px}
/* 加急 = 开关行（设计稿）。⚠ 全局 `input[type=checkbox]{width:auto!important;height:auto!important}`
   用 !important 压死了尺寸 —— 这里必须同样 !important 才能立起来（本块在文件末尾，同分取胜）。 */
#view-order .oe-urg input.sw{appearance:none;-webkit-appearance:none;position:relative;flex:0 0 auto;
  width:38px!important;height:22px!important;border-radius:var(--r-pill);background:var(--panel2);
  border:1px solid var(--edge);cursor:pointer;margin:0;padding:0;
  transition:background-color .18s,border-color .18s}
#view-order .oe-urg input.sw::after{content:'';position:absolute;top:2px;left:2px;width:16px;height:16px;
  border-radius:50%;background:var(--muted);transition:left .18s,background-color .18s}
#view-order .oe-urg input.sw:checked{background:var(--bad);border-color:var(--bad)}
#view-order .oe-urg input.sw:checked::after{left:18px;background:var(--on-accent)}
#view-order .oe-urg input.sw:focus-visible{outline:none;box-shadow:var(--focus-ring)}
#view-order .oe-band3{display:grid;grid-template-columns:minmax(0,1fr) 190px;gap:var(--sp-3);align-items:end;margin-top:11px}
#view-order .oe-maker{font-size:var(--fs-xs);color:var(--hint);text-align:right;padding-bottom:9px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#view-order .oe-maker b{color:var(--muted);font-weight:600}
#view-order .oe-items{flex:1 1 auto;min-height:230px;display:flex;flex-direction:column;padding:var(--sp-4) var(--sp-4) 12px}
#view-order .oe-ihead{display:flex;align-items:center;gap:10px;margin-bottom:var(--sp-3);flex-wrap:wrap}
#view-order .oe-ihead .nm{font-size:var(--fs-xs);font-weight:600;letter-spacing:.08em;color:var(--muted)}
#view-order .oe-ihead .chip-n{font-size:var(--fs-xs);font-weight:600;color:var(--muted);background:var(--m-ultra);
  border:1px solid var(--edge);border-radius:var(--r-pill);padding:3px 10px;font-variant-numeric:tabular-nums}
#view-order .oe-ihead .oe-hint{font-size:var(--fs-xs);color:var(--hint)}
#view-order .oe-ihead .btn{margin-left:auto}
#view-order .oe-tscroll{flex:1 1 auto;min-height:0;overflow:auto}
/* ★ 2026-10-06（岩峰二次提出 ⇒ **直接删，不再调**）：这里原有一层「待填格线」背景 ——
   `repeating-linear-gradient` 每 38px 画一条 `--border` 横线，想让剩余空白看起来
   「还能继续填」而不是「没做完」。2026-10-05 曾因「线条跟前面的元素不搭」把 `--hair`
   换成 `--border`（浅色下中性灰 → 蓝灰，与输入框同族），10-06 仍被否 ⇒
   按「同一处视觉连否即停手」的约定**整层删除**（它只是隐喻，不承载信息）。
   删后：**有明细行的地方仍有横线**（由 `.oe-itable td` 的 `border-bottom` 提供），
   表头下框线也照旧；空白区是干净留白。 */
/* ⚠ .item 是**全局类**（详情页明细行：display:flex + background!important）。这里是 <tr> ——
   必须把 flex 布局整个还原成表格行，否则 <tr> 变 flex 容器、<td> 变 flex 项 ⇒ 整行被压成一条。 */
#view-order .oe-itable tr.item{display:table-row;background:none!important;border:0;border-radius:0;padding:0;margin:0}
#view-order .oe-itable tr.item>td{display:table-cell}
#view-order .oe-itable{width:100%;table-layout:fixed;border-collapse:separate;border-spacing:0}
#view-order .oe-itable th{font-size:var(--fs-xs);font-weight:600;letter-spacing:.06em;color:var(--hint);
  /* ★ 2026-10-05：表头下框线原来用 `--edge`（浅色 = rgba(255,255,255,.85)，白底上**看不见**）
     ⇒ 改成 `--border`，与格线同色；位置与第一条格线重合，不会出现双线。 */
  /* ★ 2026-10-05（岩峰定·全站统一 C）：表头居中 */
  text-align:center;padding:0 var(--sp-2) var(--sp-2);border-bottom:1px solid var(--border);white-space:nowrap}
/* ★ 第 85 批（岩峰拍板·需求7「明细字段标签首尾对齐」）曾在此加：
     `#view-order .oe-itable thead th{text-align:justify;text-align-last:justify}`
   ★ 2026-10-12（第 88 批·岩峰定·需求3）：**该规则已撤销（删除）** ——
     本意只在手机端好看，但它对**电脑端**（`#view-order .oe-itable` 桌面表头是块级 th）也生效，
     把「商品名称」这种 4 字列名两端撑开，很难看。岩峰要求**电脑端归回原样**。
     ⇒ 删掉这条后，桌面表头落到上面 `#view-order .oe-itable th` 的 `text-align:center`（普通居中）。
     ⚠ **手机端保持不变**：手机端用的是**媒体查询里 `::before` + 全角空格补位**（见下方 @media），
       与这条规则无关，删它不影响手机端首尾对齐。 */
/* ★ 2026-10-05：行分隔线原来用 `--hair`（中性灰 #f1f1f2），与同区格线 `--border`（蓝灰 #e6e8ee）
   仍是**两套灰**（08 轮只统一了"格线"那一半）⇒ 补完，全部收口到 `--border`。 */
/* ★ 2026-10-05（岩峰定·全站统一 C）：单元格内容与表头同轴居中。
   ⚠ 输入框撑满整格（`width:100%`）⇒ 控件位置不变，"表头与内容同轴"照样成立；
     输入框内的**文字**由下一行显式保持左对齐（录入时左对齐更顺，不被这条居中带走）。 */
#view-order .oe-itable td{padding:var(--sp-1);border-bottom:1px solid var(--border);white-space:nowrap;
  vertical-align:middle;text-align:center}
#view-order input.cell,#view-order select.cell{text-align:left}
#view-order .oe-itable tbody tr:last-child td{border-bottom:0}
#view-order .oe-itable .idx{font:600 12px/1 var(--mono);color:var(--hint);text-align:center}
#view-order .oe-itable .ctr{text-align:center}
#view-order .oe-itable col.c1{width:40px}#view-order .oe-itable col.c2{width:25%}
#view-order .oe-itable col.c3{width:13%}#view-order .oe-itable col.c4{width:17%}
#view-order .oe-itable col.c5{width:8%}#view-order .oe-itable col.c6{width:8%}
#view-order .oe-itable col.c7{width:auto}#view-order .oe-itable col.c8{width:34px}
/* ⚠ 必须写成 input.cell / select.cell —— 否则 (0,1,1) 的全局 input 规则会压过 (0,1,0) 的 .cell（上一轮踩过）
   ★ 2026-10-06：明细「单位」由输入框改为**下拉**（候选来自「系统设置 → 单位字段」），
     故本组规则同时挂到 `select.cell` 上，保证与其它单元格同高同底色。
     select 的原生箭头由 `color-scheme`（body 深色 / light 主题下 light，已全局设好）自动适配，无需自绘。 */
#view-order input.cell,#view-order select.cell{background:var(--panel2);border:1px solid var(--edge);border-radius:var(--r-sm);
  box-shadow:inset 0 1px 0 rgba(0,0,0,.28);height:30px;padding:0 var(--sp-2);font-size:var(--fs-sm);
  color:var(--text);width:100%;min-width:0;box-sizing:border-box;
  transition:background-color .12s,border-color .12s,box-shadow .12s}
#view-order select.cell{padding-right:4px;font-family:inherit;cursor:pointer}
#view-order input.cell:hover,#view-order select.cell:hover{border-color:var(--border-strong)}
#view-order input.cell:focus,#view-order select.cell:focus{outline:none;border-color:var(--accent);box-shadow:var(--focus-ring)}
/* ★ 2026-10-05（岩峰：明细背景灰线还没修好）——
   本按钮写着 `class="rowx close"`，全局 `.close{min-width:44px;min-height:44px}`（弹层关闭钮的触控尺寸）
   会**压过** `.rowx` 的 26px ⇒ 按钮变 44×44 ⇒ 行高被撑到 52px，而「待填格线」节奏是 38px
   ⇒ **行与线对不上**；同时最后一格 `ow=34/sw=48` 溢出 14px ⇒ `.oe-tscroll` 长出一条**横向滚动条**
   （岩峰看到的那条实心灰条）。
   ⇒ 这里补 `min-width:0;min-height:0` 把它拉回 26×26（行高回 38 == 格线节奏）。
   ⚠ 全局 `.close` 不动 —— 弹层关闭钮仍要 44px 触控尺寸。 */
#view-order .rowx{width:26px;height:26px;min-width:0;min-height:0;display:inline-flex;align-items:center;justify-content:center;
  background:none;border:1px solid transparent;border-radius:var(--r-sm);color:var(--hint);font-size:16px;
  line-height:1;cursor:pointer;transition:background-color .15s,color .15s,border-color .15s}
#view-order .rowx:hover{background:var(--ba-soft);border-color:var(--ba-soft);color:var(--bad)}
#view-order .oe-addrow{display:grid;grid-template-columns:40px 1fr;align-items:center;gap:6px;margin-top:var(--sp-2);
  padding:7px var(--sp-2);border:1px dashed var(--border-strong);border-radius:9px;color:var(--muted);
  font-size:var(--fs-sm);cursor:pointer;transition:border-color .15s,color .15s,background-color .15s}
#view-order .oe-addrow:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
#view-order .oe-addrow .p{text-align:center;font-size:15px}
/* 吸底操作条（玻璃；最后一项，随滚动常驻可及） */
#view-order .oe-actbar{position:sticky;bottom:0;z-index:6;flex:0 0 auto;display:flex;align-items:center;gap:var(--sp-3);
  padding:var(--sp-2) var(--sp-4);border-radius:14px;
  background-color:var(--m-thin);
  background-image:linear-gradient(90deg,transparent,var(--rim-line) 12%,var(--rim-line) 88%,transparent);
  background-size:100% 1px;background-position:0 0;background-repeat:no-repeat;
  -webkit-backdrop-filter:blur(18px) saturate(1.8);backdrop-filter:blur(18px) saturate(1.8);
  border:1px solid var(--edge);
  box-shadow:inset 0 1px 0 var(--rim-side),0 -8px 26px -18px var(--lift)}
#view-order .oe-actbar .oe-acthint{font-size:var(--fs-sm);color:var(--hint);margin-right:auto;
  font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#view-order .oe-actbar .oe-acthint b{color:var(--text-2)}
#view-order .oe-actbar .oe-acts{display:flex;align-items:center;gap:var(--sp-2);flex:0 0 auto}
@media (max-width:900px){
  #view-order{min-height:0}
  #view-order .oe-grid6{grid-template-columns:repeat(2,minmax(0,1fr))}
  #view-order .oe-fld.s2{grid-column:span 2}
  #view-order .oe-band3{grid-template-columns:minmax(0,1fr)}
  #view-order .oe-maker{text-align:left;padding-bottom:0}
  #view-order .oe-actbar{flex-wrap:wrap}
  #view-order .oe-actbar .oe-acthint{width:100%;margin-right:0}
  #view-order .oe-actbar .oe-acts{width:100%;justify-content:flex-end}
}
@media (max-width:820px){
  #view-order .oe-actbar{position:static}
  /* ★ 2026-10-06：「单位」变下拉后实测表格**溢出 15px**（容器 340 / 内容 355）——
     根因是 input/select 的**固有最小宽度**在 `table-layout:fixed` 下仍会撑列。
     `min-width:0`（见 `.cell` 规则）治本；这里再把两处固定宽各收一点**保底**，
     确保窄屏**不出横向滚动条**（岩峰明确不要）。 */
  #view-order .oe-itable col.c1{width:26px}#view-order .oe-itable col.c5{width:52px}
  #view-order .oe-itable col.c8{width:30px}
  /* 窄屏：收紧单元格与控件内边距 —— 8 列×2 边的合计很可观，是留给「单位」下拉最划算的空间。
     ★ 实测（真机 390，CDP 设备模拟）：不收紧时表格内容 351 > 容器 340 ⇒ 出横向滚动条。 */
  #view-order .oe-itable td{padding:2px}
  #view-order select.cell{padding:0 2px}
  /* 窄屏：容器内**不出横向滚动条**（岩峰明确不要）。
     实测溢出源 = 删除按钮 44px 热区在 30px 列里居中 → 右侧超 11px（表格本身 340 == 容器 340）。
     这里裁掉溢出（热区可点范围 33×44，仍大于按钮本身 26×26）。 */
  #view-order .oe-tscroll{overflow-x:hidden}
}

/* ★ 2026-10-07（上线前审计 A2）：**手机端明细行改「卡片堆叠」**。
   症状：8 列固定宽在 ≤560 被硬压进屏 —— 真机实测 390 下「数量」输入框 w=23px、
   「明细备注」w=18px，**基本没法点/没法看**（"不出横向滚动"达标了，代价是把表单压废）。
   业界依据：WCAG 2.5.8 Target Size (Minimum) AA 要求 ≥24×24 CSS px。
   修法：≤560 把表格**拆成卡片**（每行一张卡，每格一行、左侧用 `::before` 注入列名）——
   **纯 CSS**（列名是固定的 8 列，用 `nth-child` 写死即可），**不动 JS 渲染**，风险最低。
   ⚠ 选择器与 `tr.item>td{display:table-cell}`（:2654）**完全同形**且在其之后 ⇒ 稳定覆盖。 */
/* ★ 2026-10-07（岩峰二修：「手机端订单明细后面的框都压缩到那么小了，怎么填？」）：
   断点由 **560 提到 820** —— 820 才是全站「手机端」的统一断点（三处同源之一），
   560~820 之间的窄屏/小屏平板此前仍是横排 8 列 ⇒ 输入框依旧被压到没法填。 */
@media (max-width:820px){
  #view-order .oe-itable{display:block;table-layout:auto}
  #view-order .oe-itable colgroup,#view-order .oe-itable thead{display:none}
  #view-order .oe-itable tbody{display:block}
  #view-order .oe-itable tr.item{display:block;border:1px solid var(--border);border-radius:var(--r-md);
    padding:6px 9px;margin:0 0 9px}
  #view-order .oe-itable tr.item:last-child{margin-bottom:0}
  #view-order .oe-itable tr.item>td{display:flex;align-items:center;gap:9px;padding:3px 0;
    border-bottom:0;white-space:normal;min-width:0}
  #view-order .oe-itable tr.item>td::before{content:'';flex:0 0 62px;font-size:var(--fs-xs);
    color:var(--muted);white-space:nowrap}
  /* ★ 第 85 批（岩峰拍板·需求7）：手机端列名**首尾对齐** —— `::before` 是行内生成盒，
     `text-align-last:justify` 不生效（justify 需块级容器）⇒ 用**全角空格补位**（与汉字等宽，天然首尾对齐，
     不引入新 DOM）。2 字字段名 → 「X　Y」（2 字 + 1 全角空格 = 3 字宽）；4 字字段名占满 `62px`，无需补位。
     ⚠ 字段名**不改**（岩峰拍板）。 */
  #view-order .oe-itable tr.item>td:nth-child(1)::before{content:'#'}
  #view-order .oe-itable tr.item>td:nth-child(2)::before{content:'商品名称'}
  #view-order .oe-itable tr.item>td:nth-child(3)::before{content:'色　号'}
  #view-order .oe-itable tr.item>td:nth-child(4)::before{content:'规　格'}
  #view-order .oe-itable tr.item>td:nth-child(5)::before{content:'数　量'}
  #view-order .oe-itable tr.item>td:nth-child(6)::before{content:'单　位'}
  #view-order .oe-itable tr.item>td:nth-child(7)::before{content:'明细备注'}
  #view-order .oe-itable tr.item>td:nth-child(8)::before{content:'';flex:0 0 0}
  /* ★ 2026-10-11：手机端卡片「行内必填星号」——只给 ≤820 亮（`.on` 由 syncOrderReqMarks 按配置切） */
  #view-order .oe-itable .oreq-i{color:var(--req)}
  #view-order .oe-itable .oreq-i.on{display:inline}
  #view-order .oe-itable tr.item>td>input,#view-order .oe-itable tr.item>td>select{
    flex:1 1 auto;min-width:0}
  #view-order .oe-itable tr.item>td.idx{text-align:left}
  #view-order .oe-itable tr.item>td.ctr{text-align:left}
}

/* ══════════════════════════════════════════════════════════════════════════════
   ★ 2026-10-04（B · 分组 ＋ 关注栏）：我的待办重塑
   ──────────────────────────────────────────────────────────────────────────────
   骨架：统计条（工序卡 + 已逾期）→ 左：按工序分组的队列（组头吸顶）/ 右：焦点工作（6 分区）。
   卡片：订单交期单独一排 → 右上；颜色交期＋当前工序停留并排 → 右下；加急 = 红实底。
   全部 scoped 在 #view-todo（ID 特异性）→ 不波及其它页同名的 .card/.tag/.due。
   ══════════════════════════════════════════════════════════════════════════════ */
#view-todo{display:flex;flex-direction:column;gap:var(--sp-3)}
#view-todo .td-bar{display:flex;align-items:center;gap:var(--sp-3);min-height:28px}
#view-todo .td-sum{font-size:var(--fs-sm);color:var(--hint);font-variant-numeric:tabular-nums}
#view-todo .td-bar .btn{margin-left:auto}
/* 统计条 */
#view-todo .td-statbar{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:var(--sp-2)}
#view-todo .td-stat{position:relative;text-align:left;font-family:inherit;cursor:pointer;color:var(--text);
  padding:12px 14px;border-radius:var(--r-lg);background-color:var(--panel);border:1px solid var(--edge);
  background-image:linear-gradient(90deg,transparent,var(--rim-card) 16%,var(--rim-card) 84%,transparent);
  background-size:100% 1px;background-position:0 0;background-repeat:no-repeat;
  box-shadow:0 18px 44px -32px var(--lift);transition:border-color .15s,box-shadow .15s}
#view-todo .td-stat:hover{border-color:var(--border-strong)}
#view-todo .td-stat.on{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent-soft),0 18px 44px -32px var(--lift)}
#view-todo .td-stat .cap{font-size:var(--fs-xs);letter-spacing:.06em;font-weight:600;color:var(--hint);white-space:nowrap}
#view-todo .td-stat .v{font-size:var(--fs-2xl);font-weight:700;line-height:1;margin-top:5px;font-variant-numeric:tabular-nums}
#view-todo .td-stat .v.bad{color:var(--bad)}
#view-todo .td-stat .sub{font-size:var(--fs-xs);color:var(--hint);margin-top:5px;white-space:normal;
  overflow-wrap:anywhere;min-height:1em}
/* 左右分栏 */
#view-todo .td-split{display:grid;grid-template-columns:minmax(0,1fr) 322px;gap:var(--sp-3);align-items:start}
#view-todo .td-queue{min-width:0;border-radius:var(--r-lg);overflow:hidden;
  background-color:var(--panel);border:1px solid var(--edge);
  background-image:linear-gradient(90deg,transparent,var(--rim-card) 16%,var(--rim-card) 84%,transparent);
  background-size:100% 1px;background-position:0 0;background-repeat:no-repeat;
  box-shadow:0 18px 44px -32px var(--lift)}
#view-todo .td-queue>.empty{border:0}
#view-todo .td-ghead{position:sticky;top:0;z-index:2;display:flex;align-items:center;gap:9px;padding:9px 15px;
  background:var(--panel2);border-bottom:1px solid var(--border);font-size:var(--fs-sm);font-weight:600;
  letter-spacing:.04em;color:var(--text-2)}
#view-todo .td-ghead .n{font-variant-numeric:tabular-nums;background:var(--track);border-radius:var(--r-pill);
  padding:1px 8px;font-size:var(--fs-xs);color:var(--muted)}
/* 右栏（玻璃；与 #detpane 同构） */
#view-todo .td-watch{position:sticky;top:12px;max-height:calc(100vh - 132px);overflow:auto;border-radius:var(--r-lg);
  padding:var(--sp-4);
  background-color:var(--m-thick);
  background-image:linear-gradient(90deg,transparent,var(--rim-line) 12%,var(--rim-line) 88%,transparent);
  background-size:100% 1px;background-position:0 0;background-repeat:no-repeat;
  -webkit-backdrop-filter:blur(22px) saturate(1.75);backdrop-filter:blur(22px) saturate(1.75);
  border:1px solid var(--edge);box-shadow:0 20px 50px -24px var(--lift)}
#view-todo .td-watchhd{display:flex;align-items:center;gap:7px;
  font-size:var(--fs-xs);font-weight:600;letter-spacing:.08em;color:var(--text-2);
  padding-bottom:9px;margin-bottom:9px;border-bottom:1px solid var(--hair)}
#view-todo .td-watchhd .tw-tot{font-variant-numeric:tabular-nums;font-weight:700;font-size:var(--fs-xs);
  color:var(--bad);background:var(--ba-soft);border-radius:var(--r-pill);padding:1px 8px}
/* 关注栏里的分区：沿用旧类名（.todo-fu 家族），把"琥珀警告底"改成中性 —— 6 个分区全是琥珀会变噪音；
   唯独「待处理异常」(.my-anom) 保留红。 */
#view-todo .td-watch .todo-fu{background:transparent;border:0;border-radius:0;padding:0;margin:0 0 13px}
#view-todo .td-watch .my-anom{margin-bottom:13px}
#view-todo .td-watch>*:last-child{margin-bottom:0}
#view-todo .td-watch .tf-title{font-size:var(--fs-xs);font-weight:600;letter-spacing:.06em;color:var(--muted);
  margin-bottom:4px}
#view-todo .td-watch .tf-item{font-size:var(--fs-sm);color:var(--text-2);padding:6px 9px;border-radius:9px;
  display:flex;flex-wrap:wrap;gap:0 8px;align-items:baseline;cursor:pointer;transition:background-color .15s}
#view-todo .td-watch .tf-item:hover{background:var(--m-ultra)}
#view-todo .td-watch .tf-item+.tf-item{border-top:1px dashed var(--hair)}
#view-todo .td-watch .tf-t{color:var(--text);font-weight:600}
#view-todo .td-watch .tf-s{color:var(--hint);font-size:var(--fs-xs)}
#view-todo .td-watch .todo-fu>.tf-s{padding:6px 9px 0}
#view-todo .td-watch .tf-item .btn{margin-left:auto}
#view-todo .td-wempty{font-size:var(--fs-sm);color:var(--hint);padding:var(--sp-3) 0}
/* ── 待办卡（新形态）── */
.vcard{position:relative;display:block;padding:12px 15px;margin:0;border-radius:0;
  background:transparent;background-image:none;border:0;border-bottom:1px solid var(--hair);box-shadow:none;
  cursor:pointer;transition:background-color .15s}
#view-todo .vcard:last-child{border-bottom:0}
.vcard:hover{background:var(--m-ultra)}
.vcard::before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--track)}
.vcard.due-warn::before{background:var(--warn)}
.vcard.due-over::before,.vcard.due-danger::before{background:var(--bad)}
.vcard.due-ok::before{background:var(--good)}
.vcard .vc-body{display:flex;align-items:stretch;gap:18px}
.vcard .vc-left{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:7px}
.vcard .vc-right{flex:0 0 auto;display:flex;flex-direction:column;justify-content:space-between;
  align-items:flex-end;gap:8px}
.vcard .vc-h{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}
.vcard .order-no{font-size:var(--fs-md)}
.vcard .vc-sub{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;font-size:var(--fs-sm);
  color:var(--text-2);min-width:0}
.vcard .vc-sub .cust{color:var(--text);font-weight:600;max-width:58%;
  white-space:normal;overflow-wrap:anywhere}
.vcard .vc-sub .s{color:var(--hint);font-size:var(--fs-xs);white-space:nowrap;font-variant-numeric:tabular-nums}
.vcard .vc-l4{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:var(--fs-xs);
  color:var(--hint);font-variant-numeric:tabular-nums}
.vcard .vc-l4 .dtl{white-space:normal;overflow-wrap:anywhere;min-width:0}
.vcard .todo-badges{padding-top:1px}
/* ★ 2026-10-05（岩峰：颜色交期后面的「待定」跟标签没对齐 → 治本）：
   `.due-label` 与 `.due` 的**盒子高度不同**（label 14 / 下排胶囊 26 / 上排大胶囊 28）⇒
   `align-items:center` 只对齐**盒子中心**，对不齐**文字基线**（字号越大偏得越多：下排 +1.0px、上排 +2.2px）。
   改成 **baseline**：字号不同也自动对齐；配套把 `.due` 的 `top:1px` 归零（那是按某个字号凑的，基线对齐后只会添乱）。
   ⚠ `.sep` / `svg` **没有文字基线** —— baseline 行里它们会按"盒子底边"贴到基线上（整体偏高）
     ⇒ 必须 `align-self:center` 单独保持居中。
   ⚠ 行高不变（baseline 行高 = 最大上距 + 最大下距 = 最高那个盒子的高度）⇒ 卡片高度与列表节奏不动。 */
.vcard .mrow{display:flex;align-items:baseline;gap:7px;white-space:nowrap}
.vcard .mrow .sep,.vcard .mrow svg{align-self:center}
.vcard .mrow .due{top:0}
.vcard .mrow.top .due-label{font-size:var(--fs-xs);color:var(--muted)}
.vcard .mrow.top .due{font-size:15px;font-weight:700;padding:4px 12px;border-radius:8px}
.vcard .mrow.bot{gap:6px;justify-content:flex-end;flex-wrap:wrap}
.vcard .mrow.bot .due{font-size:var(--fs-xs);padding:3px 9px;border-radius:var(--r-pill);
  /* ★ 2026-10-05（岩峰：颜色交期后面的「待定」跟标签没对齐）：
     `.due` 家族有一条 `position:relative;top:1px` 的微调（见上方 .due 基础规则），
     那是按**上排 15px 大胶囊**调出来的；下排小胶囊是 12px，同一个 +1px 落到 12px 字上就**偏低 1px**
     —— 字形在行盒里的视觉中心随字号变，一条固定 +1px 不可能同时对两种字号成立。
     实测（2× DPI 逐像素量文字中线）：下排「颜色交期」497 /「当前工序停留」497 /「待定」499
     ⇒ 差 2 个图像像素 = 1 CSS px。**下排归零**即对齐。
     ★ 2026-10-05（第 27 批）：这条 `top` 已由下面的 `.vcard .mrow .due{top:0}` 统一收口 ——
     整行改成了 `align-items:baseline`（字号不同也自动按基线对齐），不再需要"按字号凑"的微调。 */}
.vcard .mrow .due-label{font-size:var(--fs-xs);color:var(--muted)}
.vcard .mrow .sep{width:1px;height:12px;background:var(--edge);margin:0 3px;flex:0 0 auto}
.vcard .mrow .num{font-size:var(--fs-sm);font-weight:700;font-variant-numeric:tabular-nums;color:var(--text)}
.vcard .mrow svg{width:12px;height:12px;flex:0 0 auto;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;opacity:.85;color:var(--hint)}
/* 语义色胶囊（沿用 A 方案那套：底软、字实；#view-todo 内覆盖掉旧 .due 的"只变色不铺底"） */
.vcard .due.ok{background:var(--ok-soft);color:var(--good)}
.vcard .due.warn{background:var(--wa-soft);color:var(--warn)}
.vcard .due.over,.vcard .due.danger{background:var(--ba-soft);color:var(--bad)}
.vcard .due.none,.vcard .due.mut{background:var(--m-ultra);color:var(--muted)}
@media (max-width:1100px){
  #view-todo .td-split{grid-template-columns:minmax(0,1fr)}
  /* ★ 2026-10-07（岩峰定）：窄屏**不再把「焦点工作」提到队列前面** ——
     原来这里写 `order:-1`（理由是"焦点工作最该先看到"），岩峰看到的是
     「统计条 → 焦点工作 → 队列」，要求改成 **「统计条 → 队列 → 焦点工作」**（与桌面同序）。
     ⇒ 只保留"堆叠 + 自己滚"，`order` 去掉。 */
  #view-todo .td-watch{position:static;max-height:none}
}
@media (max-width:900px){
  .vcard .vc-body{flex-direction:column;gap:9px}
  .vcard .vc-right{flex-direction:row;align-items:center;justify-content:flex-start;gap:10px;flex-wrap:wrap}
}

/* ══════════════════════════════════════════════════════════════════════════
   ★ 2026-10-09：原「按钮方案 A 深空 Deep Glow」（岩峰 2026-10-04 定稿）**整体撤除**，
     改由顶部「按钮集 v5 七档」统一承担（跨系统规范：考核 / 生产 / 客户同一套）。
     撤掉的：径向渐变叠光 / 文字发光（text-shadow）/ 外扩光晕（非 inset 的 box-shadow）/
             hover 的 filter:brightness() —— 全部落在 v5 的「零实心·零发光·零外扩」上。
     保留的：尺寸契约（--h-btn 36 / --h-btn-sm 28 / --r-md）、loading 态、::before 封死。
   ══════════════════════════════════════════════════════════════════════════ */
/* （原「边框流光环」封死规则已并入顶部 v5 块的 ::before 防呆，此处不再重复） */

/* （原「强调 / 中性 / 危险 / 告急」四档的深空皮肤已撤 —— 七档统一在顶部 v5 块） */

/* （原「浅色主题：光落在浅底上」整套多层外扩光晕已撤 ——
    浅色七档改由顶部 v5 的 `html[data-theme="light"]{--btn*-...}` 令牌承担） */

/* ══════════════════════════════════════════════════════════════════════════
   ★★ 规范 v1 新增：**按钮 loading 态**（第六态）—— 现状完全没有（实测命中 0）。
   痛点：交付 / 发货 / 派单 / 提交订单 这些动作要等后端，期间界面毫无反馈，
        用户会以为没点上 → 反复点（后端虽有 inflight 去重，前端观感仍很差）。
   做法：文字转透明（**不改宽度 ⇒ 不跳版**）+ 居中转圈；禁用指针避免连点。
   ⚠ 用 ::after —— ::before 曾留给主/危险/告急的边框流光（2026-10-05 已全站撤掉，::before 现在空着）。
   ══════════════════════════════════════════════════════════════════════════ */
.btn.is-loading{color:transparent!important;text-shadow:none!important;
  pointer-events:none;cursor:progress}
.btn.is-loading::after{content:"";position:absolute;left:50%;top:50%;width:15px;height:15px;
  margin:-8px 0 0 -8px;border-radius:50%;
  border:1.8px solid rgba(255,255,255,.34);border-top-color:#fff;
  animation:spin .7s linear infinite}
html[data-theme="light"] .btn.is-loading::after{
  border-color:rgba(20,48,96,.26);border-top-color:#1c4e9e}
/* 无障碍与降级：减少动效偏好下不转，只留静态圈（仍能看出"在忙"）。
   ★ 2026-10-05：原来这里还管着主/危险/告急三档的**边框流光动画** —— 环已全站撤掉，那半句随之删除。 */
@media (prefers-reduced-motion:reduce){
  .btn.is-loading::after{animation:none}
}


/* ══════════════════════════════════════════════════════════════════════════
   ★★ 订单详情 · L1 双栏主从  —— 岩峰 2026-10-04 定稿（五版布局里选 L1）
   为什么是**两条各自独立的竖轨**：早先预览版用 grid 跨行绑定两栏
   （flow 跨 1~2 行、logs 跨 3~4 行），右栏就被左栏行高牵着走 ——
   左栏头两行很高而块只占自身高度 ⇒ 工序进度下面空一大片（实测 263px）。
   现在的写法只有**两行**：第 1 行放标题+摘要（跨两列），第 2 行放两条轨。
   同一行里两个块各自 align-self:start ⇒ 各按自己内容高，**天然不会互相撑开**。
   窄屏：两个轨容器 display:contents 归零 ⇒ 回到原来的单列顺序。
   ══════════════════════════════════════════════════════════════════════════ */
#detailBody{display:flex;flex-direction:column;gap:14px}
#detailBody .dcol-l,#detailBody .dcol-r{display:contents}
#detailBody .dcol-l>*,#detailBody .dcol-r>*{margin-top:0;margin-bottom:0}
@media (min-width:981px){
  /* ⚠ 行号必须**逐个写死**：只写 grid-column 而让它自动排行，摘要会与写死 grid-row:2 的两条轨
     抢同一行 → 冲突后被推到隐式行，**整块摘要跑到弹层最底部**（2026-10-04 实测踩到）。 */
  #detailBody{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);
    grid-template-rows:auto auto 1fr;gap:12px 18px;align-items:start}
  #detailBody>.modal-title{grid-column:1/-1;grid-row:1}
  #detailBody>.detail-summary{grid-column:1/-1;grid-row:2}
  #detailBody>.dcol-l{grid-column:1;grid-row:3;display:flex;flex-direction:column;gap:14px;min-width:0}
  #detailBody>.dcol-r{grid-column:2;grid-row:3;display:flex;flex-direction:column;gap:14px;min-width:0}
}

/* ══ 工序进度：**连接步骤条**（连接线取代「→」箭头）══
   已完成＝实心绿点 + 绿线 · 当前＝蓝点带柔光 · 未到＝空心灰点。
   ⚠ 当前工序颜色由原来的**红**改为**蓝**：红在本系统是"危险/加急"的语义，
     用它标"当前工序"会和真正的告警撞车（预览定稿时已按蓝确认）。
   ⚠ 选择器要带 .flow-grid 前缀：既有规则是 `.flow-grid .flow-step.cur .dot`(0,4,0)，
     少一层就会因特异性不足而静默失效。 */
.flow-grid .flow-step::after{content:"";position:absolute;left:calc(50% + 12px);right:calc(-50% + 12px);
  top:6px;height:1.5px;background-color:var(--border);font-size:0}
.flow-grid .flow-step:last-child::after{display:none}
.flow-grid .flow-step.done:not(:last-child)::after{background-color:color-mix(in srgb,var(--good) 45%,transparent)}
.flow-grid .flow-step .dot{width:13px;height:13px;border-radius:50%;
  background-color:var(--panel);border:1.5px solid var(--border-strong)}
.flow-grid .flow-step.done .dot{background-color:var(--good);border-color:transparent}
.flow-grid .flow-step.done{color:var(--text-2)}
.flow-grid .flow-step.cur .dot{width:13px;height:13px;background-color:var(--accent);
  border-color:color-mix(in srgb,var(--accent) 50%,#fff);
  box-shadow:0 0 0 4px color-mix(in srgb,var(--accent) 20%,transparent),
    0 0 14px color-mix(in srgb,var(--accent) 75%,transparent)}
.flow-grid .flow-step.cur{color:var(--accent-text);font-weight:600}


/* ★ 2026-10-04 教训**保留**：曾把两个分布面板并排，结果行尾「订单逾期 N 单」标记放不下
   ⇒ 真机布局探针判「2 段越界」（文字不许折行/不许裁，系统铁律"信息完整 > 排版整齐"优先）。
   2026-10-05 定稿 R-B 改为左右两栏后，左栏宽度由 `minmax(0,0.8fr)` 决定 —— 仍须保证
   行尾标记放得下（.brow 第 3 列固定 78px）。 */


/* ══ 玻璃墨色三档（★ 2026-10-05 从单一来源 `_previews/assets/glass.css` 补移植）══
   glass.css 里 `.g-ink/.g-ink2/.g-ink3` 是「玻璃面上的三级墨色」；令牌 `--gl-ink*` 早已移植，
   **这三条类规则却漏了** ⇒ 侧栏副标题「生产系统 · MES」一直是继承色，不是设计的 --gl-ink3
   （由 `_tools/_cls_audit.py` 类名体检扫出来：用了类名却没有规则）。 */
.g-ink{color:var(--gl-ink);text-shadow:var(--gl-shadow)}
.g-ink2{color:var(--gl-ink2);text-shadow:var(--gl-shadow)}
.g-ink3{color:var(--gl-ink3)}

/* ══ 面板内边距（★ 2026-10-05）══
   定稿 S-dashboard 定义了 `.pad{padding:15px 17px}`；我搬了 `class="panel pad"` 却没搬这条规则，
   而生产 `.panel` 基础规则里**本来就没有 padding**（看板另补了 `#view-boardview .side .panel`）
   ⇒ 订单数据页 5 个面板 padding=0：内容贴边、右侧数值被裁。
   取值 14px 16px = 与看板一致（全站一套内边距；定稿 15/17 差 1px，不值得为 1px 两套语言）。 */
.pad{padding:14px 16px}

/* ══ 图表容器（定稿 S-dashboard 的 `.chart`）══ */
.chart{width:100%;display:block}

/* ══ 订单数据 · 近 N 天下单/交付趋势（2026-10-04 定稿：B 版 + 趋势）══
   折线用 SVG 直接画（零依赖）：Y 轴取"好看数"、4 段整数刻度；两条线语义色区分（下单=accent / 交付=good）。
   ⚠ 2026-10-05 更正：原先的写法是"viewBox 定宽 1000 ＋ 关闭等比 ＋ 高度锁 220"，
     注释里写的是「宽度自适应」。实测那不是自适应而是**非等比拉伸**：容器 1138px 时
     横向被拉 1.138 倍 —— **字形被抻宽**、末刻度右溢出界。
     现改为：viewBox 宽＝**真实像素宽**（JS 量 clientWidth）＋ 高度 `auto` 交给 viewBox 比例，
     容器变宽变窄一律**等比**缩放，字形永不变形。 */
#dashTrend .dash-sub{font-size:12px;color:var(--muted);margin:-2px 0 10px;line-height:1.6}
#dashTrend .dash-sub b{color:var(--text)}
/* ★ 2026-10-05：`height:220px` 改 `auto` —— 高度由 viewBox 的比例决定。
   改前写死 220 又用 `preserveAspectRatio="none"` 拉满宽 ⇒ 非等比拉伸，
   12px 的字被横向抻开近 14%（"字体不美观"）。现在容器变宽/变窄一律**等比**缩放。 */
.trend-svg{display:block;width:100%;height:auto}
.trend-svg .tgrid{stroke:var(--border);stroke-width:1;vector-effect:non-scaling-stroke}
.trend-svg .taxis{fill:var(--hint);font-size:12px;font-variant-numeric:tabular-nums}
.trend-svg .tarea{fill:color-mix(in srgb,var(--accent) 13%,transparent);stroke:none}
.trend-svg .tline{fill:none;stroke-width:2;vector-effect:non-scaling-stroke;
  stroke-linejoin:round;stroke-linecap:round}
.trend-svg .tput{stroke:var(--accent)}
.trend-svg .tdel{stroke:var(--bad)}
/* ★ 2026-10-08（第 67 批）：**单日窗口**的圆点 —— 一个点的折线路径画不出东西（见 loadDashTrend 的 dot()），
   所以单日时补点。`fill` 跟各自线的颜色走；`.tdot` 只负责"是实心圆"。 */
.trend-svg .tdot{stroke:none}
.trend-svg .tdot.tput{fill:var(--accent)}
.trend-svg .tdot.tdel{fill:var(--bad)}
.tlegend{display:flex;align-items:center;gap:14px;flex-wrap:wrap;font-size:12px;
  color:var(--muted);margin-top:8px}
.tlegend span{display:inline-flex;align-items:center;gap:6px}
.tlegend i{width:14px;height:2.5px;border-radius:2px;display:inline-block}
.tlegend i.tput{background-color:var(--accent)}
.tlegend i.tdel{background-color:var(--bad)}
.tlegend .thint{margin-left:auto;color:var(--hint)}
@media (max-width:600px){.tlegend .thint{margin-left:0}}


/* ══════════════════════════════════════════════════════════════════════════
   ★ 2026-10-05（岩峰定稿 R-B「指标台」）：订单看板重做
   出处 `_previews/R-boardview.html` 的 B 版，**逐条照搬**，作用域 `.B` → `#view-boardview`
   （`#view-boardview` 前缀是刻意的：`.k/.cap/.dot/.kpi` 全站已有同名类，不加前缀会污染别的页）。
   ⚠ 定稿 11.5px 一律提到 12px —— 生产系统硬规则「全站字号 ≥12px」（判据 _regress_uix_audit P2）。
   ══════════════════════════════════════════════════════════════════════════ */
/* ── 面板（定稿 .panel；生产系统原本没有这个类名 → 零冲突，订单数据页也会复用）── */
.panel{position:relative;border-radius:var(--r-xl);background:var(--panel);border:1px solid var(--edge);
  box-shadow:0 30px 74px -36px var(--lift),0 2px 6px rgba(0,0,0,.22);min-width:0}
.panel::before{content:'';position:absolute;left:16px;right:16px;top:0;height:1px;pointer-events:none;
  background:linear-gradient(90deg,transparent,var(--rim-card) 14%,var(--rim-card) 86%,transparent)}
/* ── ① 顶部 8 格指标条 ── */
/* ★ 第 72 批（岩峰定·④）：6 格 → 7 格（新增第 5 格，插在「订单已逾期」之后）。
   ★ 第 85 批（岩峰拍板）：第 5 格改名「24小时未接单」（计时扣除周日）。
   ★ 第 97 批（岩峰定）：7 格 → **8 格**（末尾新增「工序停留3天」——当前工序停留超过 3 天整的进行中单）。 */
#view-boardview .kpi{display:grid;grid-template-columns:repeat(8,minmax(0,1fr));gap:10px;margin-bottom:12px}
#view-boardview .k{position:relative;padding:13px 15px;border-radius:var(--r-lg);background-color:var(--panel2);
  border:1px solid var(--edge);box-shadow:inset 0 1px 0 var(--rim-side);cursor:pointer;transition:.15s;
  display:flex;flex-direction:column;gap:7px}
#view-boardview .k:hover{border-color:var(--border-strong)}
#view-boardview .k .cap{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--hint);white-space:nowrap}
#view-boardview .k .cap .dot{width:6px;height:6px;border-radius:50%;background:var(--border-strong);flex:0 0 auto}
#view-boardview .k.danger .cap .dot{background:var(--bad)}
#view-boardview .k.warn .cap .dot{background:var(--warn)}
#view-boardview .k.good .cap .dot{background:var(--good)}
#view-boardview .k .v{font-size:30px;font-weight:700;line-height:1;letter-spacing:-.02em;color:var(--text)}
#view-boardview .k.danger .v{color:var(--bad)}
#view-boardview .k.warn .v{color:var(--warn)}
#view-boardview .k.good .v{color:var(--good)}
#view-boardview .k.zero .v{color:var(--muted)}
#view-boardview .k .u{font-size:12px;color:var(--hint);margin-left:3px;font-weight:500}
#view-boardview .k .ctx{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--hint);white-space:nowrap}
#view-boardview .k .ctx b{color:var(--text-2);font-weight:600}
/* ── ② 左右两栏（左 sticky 负载 / 右长列表）── */
/* ★ 2026-10-07（岩峰定）：**只加宽左栏的工序名列**（见下方 .brow），两栏比例**不动** ——
   实测右栏（.panel.olist）的内容固有最小宽 ≈721px、原本就贴边（716px，已轻微溢出 5px），
   再缩右栏会把订单卡的规格/工序行裁掉。加宽工序名列同样能解决 6 字折行，且两边都不受损。 */
#view-boardview .cols{display:grid;grid-template-columns:minmax(0,0.8fr) minmax(0,1.3fr);gap:12px;align-items:start}
#view-boardview .side{display:flex;flex-direction:column;gap:12px;position:sticky;top:0;min-width:0}
#view-boardview .side .panel{padding:14px 16px}
/* ── 面板小标题（工序负载 / 各人当前持有）── */
#view-boardview .grp{display:flex;align-items:center;gap:10px;margin:0 0 11px;font-size:12px;
  font-weight:600;letter-spacing:.08em;color:var(--muted)}
#view-boardview .grp::after{content:'';flex:1;height:1px;background:linear-gradient(90deg,var(--edge),transparent)}
#view-boardview .grp .cnt{font-variant-numeric:tabular-nums;background:var(--track);border-radius:var(--r-pill);
  padding:1px 8px;font-size:12px;color:var(--muted);letter-spacing:0}
/* ── 负载行 .brow（工序 / 各人 共用一套，口径两段互斥：正常 + 订单已逾期 == 总数）── */
/* ★ 2026-10-07（岩峰定）：工序名列 74px→92px —— 让 6 字工序名（标准/定制样板接单）**单排放下**。 */
#view-boardview .brow{display:grid;grid-template-columns:92px minmax(0,1fr) 78px;gap:10px;align-items:center;
  padding:9px 4px;font-size:13px;border-radius:8px;cursor:pointer}
#view-boardview .brow:hover{background:var(--m-ultra)}
#view-boardview .brow .nm{color:var(--text-2);white-space:normal;overflow-wrap:anywhere}
#view-boardview .brow .bar{position:relative;height:6px;border-radius:var(--r-pill);background:var(--track);
  overflow:hidden;display:flex}
/* ⚠ 2026-10-07~08「红条比蓝条高」**已结案**（三轮，留档以免再走回头路）。
   ★ 结论：**不是本系统的渲染缺陷** —— 蓝段红段的几何完全一致；看见的"红更高"来自
     **色度抽样（chroma subsampling）**，属截图/显示链路，与 CSS 无关。**本处不要再改。**

   三轮经过：
     ① 第一轮：岩峰报「红条明显比蓝条高」→ 我改 `border-radius` 为 2px（猜是"蓝段左端被
        胶囊圆角削圆"造成）。**这个改动是错的，已撤回**（见上一条规则的 `--r-pill`）。
     ② 第二轮：岩峰报「放大齐平、**缩小页面**红条上移」→ 我实测 **6 档缩放（DSF 1/0.9/0.8/
        0.75/0.67/0.5）**：布局 rect 全等、截图逐像素也全等（顶差/底差/高差 = 0/0/0）。
     ③ 第三轮（2026-10-08）：拿到岩峰真机截图后**逐像素量了 25 条** —— 同一条内蓝段红段的
        **外沿与实心行号完全相同**（例：y148–153 外沿 6 行、149–152 实心 4 行，蓝红一致）。
        仍觉"红更粗"，是因为**那张 PNG 被存成了 JPEG，且用 4:2:0 抽样**
        （实测 SOF0：Y 分量采样 2x2、Cb/Cr 采样 1x1 ⇒ **颜色在竖直方向只有一半分辨率**）。
        红色是**纯色度**信号，边缘因此被糊开 1~2px（实测红侧溢出像素 rgb(76,13,22)、
        亮度低而色度强 = 典型 4:2:0 溢出）；蓝色自带较强亮度成分、亮度是全分辨率的，
        边缘依旧锐利 ⇒ **看上去红条更"厚"**。
   ⇒ 同类现象也会出现在**显示器走 YCbCr 4:2:0 输出**时（HDMI 4K@60 常见）——
     若要现场复核，看显卡驱动的「输出颜色格式」是否被设成 YCbCr 4:2:0 而非 RGB/4:4:4。
   ⇒ 判据侧：`_verify_b60.js` ⑪ 只断言"圆角是胶囊（不是 2px）"，**不**再断言任何高度差。 */

#view-boardview .brow .bar i{display:block;height:100%}
#view-boardview .brow .bar i.ok{background:var(--accent)}
#view-boardview .brow .bar i.bad{background:var(--bad)}
#view-boardview .brow .n{font-variant-numeric:tabular-nums;font-size:12px;color:var(--muted);text-align:right;white-space:nowrap}
#view-boardview .brow .n em{color:var(--bad);font-style:normal;font-weight:600}
#view-boardview .legend{display:flex;align-items:center;gap:14px;margin-top:9px;font-size:12px;color:var(--hint);flex-wrap:wrap}
#view-boardview .legend i{display:inline-block;width:9px;height:9px;border-radius:3px;margin-right:5px;vertical-align:-1px}
/* ── ③ 右栏「进行中的订单」（卡片＝.vcard，样式已是容器无关，这里只补列表外壳）── */
#view-boardview .olist{padding:0;overflow:hidden}
/* ★ 2026-10-07（岩峰：「订单卡片在进行中的订单的元素框内，不需要圆角」）——
   外层 `.panel.olist` 本身就是一张圆角卡，里面的订单卡再各自带圆角 = "卡中卡"，
   所以让它表现为**列表行**（行与行仍由 .vcard 自己的 border-bottom 分隔）。
   ⚠ 这条规则的真实作用不是"去圆角"，而是**防线**：`.vcard` 自身的 `border-radius` 本来就是 0
     （见 `.vcard{…border-radius:0…}`），所以它并不改变任何现有外观。它存在的意义是**兜住将来**——
     一旦再有 `.card` 级别的规则（如 ⑥ 段那种裸 `.card` 选择器）波及到 `class="card vcard …"` 的
     订单卡，能被这条以更高特异性（页面前缀 + 两级类）压回 0，防它从"列表行"异变成"一张张浮起的卡片"。
   ⚠ 只作用于看板右栏：待办页同款 .vcard 是**独立卡片**，那儿必须保留圆角。 */
#view-boardview .olist .vcard{border-radius:0}
#view-boardview .olist .ohead{display:flex;align-items:center;gap:9px;padding:13px 16px;border-bottom:1px solid var(--border)}
#view-boardview .olist .ohead .t{font-size:12px;font-weight:600;letter-spacing:.08em;color:var(--muted);white-space:nowrap}
#view-boardview .olist .ohead .cnt{font-variant-numeric:tabular-nums;background:var(--track);border-radius:var(--r-pill);
  padding:1px 8px;font-size:12px;color:var(--muted)}
#view-boardview .olist .ohead .hint{margin-left:auto;font-size:12px;color:var(--hint);white-space:nowrap}
#view-boardview .vcard:last-child{border-bottom:0}
#view-boardview .olist .more{text-align:center;padding:12px;color:var(--text-2);cursor:pointer;
  font-size:13px;border-top:1px solid var(--hair)}
#view-boardview .olist .more:hover{background:var(--m-ultra)}
#view-boardview .olist .more.done{cursor:default;color:var(--hint)}
#view-boardview .olist .more.done:hover{background:transparent}
/* ── ④ ★ 2026-10-07（岩峰定）：桌面端「整页不滚 · 左右两栏各自独立滚动」──
   由来（真机量测 1440×900）：整页滚动时滚过 450px 后，左栏（sticky top:0）顶部就被
   顶栏压住 **66px**（顶栏占 14~66）；而且要翻订单得整页滚，左侧负载与顶部指标一起滚走。
   现改为：>1100px 时本页**自己不滚**，只有左右两栏在各自框内滚 —— 鼠标停在哪个栏就滚哪个栏。
   · 高度**不写死 calc**：顶部占用里的 KPI 条高度随内容/断点变（这一刻是 110px），
     写死迟早错位 ⇒ 由 JS `_bvFit()` 按视口实时算，在渲染后与 resize 时刷新。
   · ≤1100px（含手机）单列布局**保持原整页滚动**，行为逐字不变。 */
@media (min-width:1101px){
  #view-boardview{display:flex;flex-direction:column;min-height:0}
  #view-boardview .kpi{flex:0 0 auto}
  #view-boardview .cols{flex:1 1 auto;min-height:0;align-items:stretch}
  /* 左栏：不再 sticky（本页已不整页滚，sticky 只会把顶部顶到顶栏下面去），改为框内滚动。
     ★ 2026-10-07 岩峰：「左边最下面也要像右边一样有圆弧」—— 右栏是**整张卡自己滚**，
     所以卡片圆角任何时候都在；左栏是"容器包两张卡"，滚到中间时内容被裁成**直角**。
     修法：给这个滚动容器加**同一档圆角**（--r-xl），内容就被"圆角矩形"裁切 ⇒
     滚到任何位置，容器底/顶两角都是圆弧，与右栏观感一致（整个系统所有同类分栏同此）。
     ★ 2026-10-07 二修（岩峰「左边有圆角，右边没有」）：padding 原来是 `2px 6px 8px 2px`
     —— **左右不对称**（左 2 / 右 6）。右栏滚动条还要占一条，右边视觉上就多出 ~16px 空档，
     于是"左边贴着圆角、右边看着像被切平"。改成**左右各 6px 对称**。 */
  /* ★ 2026-10-15（岩峰定·「所有滑动条都嵌在元素框内」）：左栏改「**每张卡自己滚**」——
     与右栏 .olist 同款：滚动条从此画在**卡片框内**（原来容器级滚动时，滚动条悬在
     "卡外的容器缘"上、看着在框外）。高度分配：卡 flex:0 1 auto（内容少=自然高、
     总高超=按比例收缩）⇒ 超出的卡各自在**自己框内**滚。
     ⚠ 容器保留原 padding/圆角（布局逐字不变）；滚动职责全部下放到卡。 */
  #view-boardview .side{position:static;min-height:0;
    border-radius:var(--r-xl);padding:2px 6px 8px 6px}
  #view-boardview .side > .panel{flex:0 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain}
  /* 右栏：hidden → auto（原本靠整页滚，现在自己滚）；滚动条不再贴着订单卡右侧文字 */
  #view-boardview .olist{min-height:0;overflow-y:auto;overscroll-behavior:contain}
  /* 「进行中的订单」标题吸顶常驻：滚订单时始终知道这列是什么、共多少单 */
  #view-boardview .olist .ohead{position:sticky;top:0;z-index:2;background-color:var(--panel)}
}
@media (max-width:1100px){
  /* ★ 第 72 批：7 格 → 4 列（7 = 4+3，**不落单**）。原来 6 格用 3 列刚好两行；
     7 格若仍走 3 列会变成 3+3+1 → 末行孤一张。改 4 列后两行 4+3，无孤格。 */
  #view-boardview .kpi{grid-template-columns:repeat(4,minmax(0,1fr))}
  #view-boardview .cols{grid-template-columns:minmax(0,1fr)}
  #view-boardview .side{position:static}
}
@media (max-width:600px){
  #view-boardview .kpi{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* ★ 第 97 批（岩峰定·第 8 格「工序停留3天」）：8 格偶数 → 2+2+2+2 天然整齐，
     **撤掉**原来"末格跨满整行"的补丁（那是第 72 批为 7 格奇数设计的：7 = 2+2+2+1 → 末格孤一张）。 */
  #view-boardview .brow{grid-template-columns:92px minmax(0,1fr) 70px;font-size:12px}
  /* ★ 2026-10-08（本地库工序名同步后）：上句第一列由 76px → **92px**（与 ≥601 的基础列宽一致）。
     为什么：工序名现最长 7 字（「无配方配色接单」「有配方配色接单」），76px 装不下 ⇒ `.nm` 换行
     ⇒ 那两行 offsetHeight 44→56，**与其余 20 行不齐**（布局探针「看板行高 各行完全相等」当场红；
     360/375/390/393/412 五档皆红，601+ 因基础列宽本就 92px 而正常）。改成 92px 后 7 字一行放得下、
     22 行齐高。与「当前工序列 need=122」同根因（工序名变长）的一处连带。 */
}

/* ══════════════════════════════════════════════════════════════════════════
   ⑤ ★ 2026-10-07（岩峰定）：**全站「桌面端整页不滚 · 内容区自己滚」统一框架**
   已适用：订单看板（上面 ④）· 我的待办 · 订单查询 · 系统设置 · 权限管理。
   ⚠ 一律只写在 `min-width:1101px` 里 —— ≤1100（含手机）保持原整页滚动，行为逐字不变。
   高度由 JS `_fitAll()` 统一算（口径：容器高 = 视口高 − 容器顶到视口顶 − 14），
   见 `FIT_PAGES`：加一页只要往那张表里加一个 id。
   ══════════════════════════════════════════════════════════════════════════ */
@media (min-width:1101px){
  /* ★ 2026-10-07（岩峰：「每次刷新后，待办和焦点工作先出现小的，0.4 秒后才拉长」）：
     **首屏高度用 CSS 给正确初值**，别等 JS。
     病因：`enterApp` 里登录屏是 `setTimeout(…, 160)` 之后才加 `.hidden` —— 那 160ms 内
     `#login` 还占着版面，此刻 JS 量到的"页面容器顶到视口顶"是错的大数 ⇒
     高度被 `Math.max(320,…)` 夹成 320px ⇒ 页面先以 320px 出现，等登录屏撤掉才被纠正
     （真机时序实测：t=45ms 是 320、t≈321ms 才跳到 808）。
     这里按实测值给一个 92px 的初始偏移（900 视口 ⇒ 808px，与 JS 算出来的一致）；
     JS 量准后会写 inline height 覆盖它，两者应当同值。 */
  :root{--fit-top:92px}
  #view-boardview,#view-todo,#view-board,#view-system,#view-perms{height:calc(100vh - var(--fit-top))}

  /* ── 我的待办 ──（.td-split 是 1fr + 322px 两栏，让两栏各自滚） */  #view-todo .td-split{flex:1 1 auto;min-height:0;align-items:stretch}
  #view-todo .td-queue{overflow-y:auto;min-height:0;overscroll-behavior:contain}
  /* 右栏原本靠 sticky + max-height 挂在整页滚动上；本页已不滚 ⇒ 交回框内滚动 */
  #view-todo .td-watch{position:static;max-height:none;min-height:0;overflow-y:auto;
    overscroll-behavior:contain}

  /* ── 订单查询 ──（筛选条常驻；表格区自己滚，表头仍吸顶）
     🔴 2026-10-07 修（岩峰「下边超了 + 空白处应该有数据」）：
       · 原来这里写了 `gap:12px` —— 但 `.gpanel` **本来就有 `margin-top:12px`**，
         两下一叠加 ⇒ 比原有设计多出 12px ⇒ `#view-board` 内容比容器高 12px（下边超了）。
         去掉 gap，间距仍由那条 margin 提供（与改造前逐字一致）。
       · `.gwrap` 原来有 `max-height:calc(100vh - 430px)`（老规则，靠"整页滚动"年代的估值），
         它把列表钉死在 470px ⇒ **底部空出一大块本该有订单行的地方**。
         现在整页不滚、由 flex 分配高度 ⇒ 用 `#boardList`（id，特异性够高）把 max-height 关掉，
         让它老老实实 `flex:1` 撑满第 3 行。
     ⚠ 必须用 id 覆盖：`#view-board .gwrap{max-height:…}` 那条老规则在 CSS 里**排在更后面**，
       同特异性的 `.gwrap` 规则会被它反超（这次就是栽在这上面）。 */
  #view-board{display:flex;flex-direction:column}
  /* 筛选条常驻；那 12px 间距改由它自己出 —— 原来是靠 `.gpanel{margin-top:12px}` 顶出来的，
     而在 flex 链里"子元素自己带 margin 又 height:100%"会算成 656+12 = 668 ⇒ 整页溢出 12px。 */
  #view-board .fbar{flex:0 0 auto;margin-bottom:12px}
  #view-board #boardSplit{flex:1 1 auto;min-height:0;display:flex;flex-direction:column}
  #view-board .panel.gpanel{flex:1 1 auto;min-height:0;margin-top:0;
    display:flex;flex-direction:column;overflow:hidden}
  #view-board #boardList{flex:1 1 auto;min-height:0;max-height:none}
  #view-board .ghead,#view-board .gfoot{flex:0 0 auto}

  /* ── 系统设置 ──（左 184px 分类栏 + 右内容栏） */
  #view-system{display:flex;flex-direction:column}
  #view-system #systemContent{display:flex;flex-direction:column;flex:1 1 auto;min-height:0}
  #view-system #sysHealth{flex:0 0 auto}
  #view-system .sys-layout{flex:1 1 auto;min-height:0;align-items:stretch}
  #view-system .sys-side{position:static;min-height:0;overflow-y:auto;overscroll-behavior:contain}
  /* ★ 2026-10-07 三修（岩峰深色下看出「圆角周围有一条被背景切断的阴影」）—— 见本段末 ⑦。
     `.sys-list` 这类卡自带 `--shadow-1`（深色下是 rgba(0,0,0,.35)+.28，相当明显），
     而它**贴着本滚动容器的左右边缘**；容器一给 overflow，卡的左右阴影就 100% 被裁掉
     （上下有空间、没被裁）⇒ 四边不对称，圆角那儿看着像被一刀切平。
     `padding:0 14px` 给阴影留 14px 的地方画（实测横向扩散 13~16px）；
     `margin:0 -14px` 把容器的裁切框整体外扩 14px ⇒ **内容盒位置一动不动**、
     卡片宽度与位置全不变。右侧正好到视口右缘（`.content` 本来就有 14px 内边距）⇒ 不出横向滚动条。 */
  #view-system .sys-body{min-height:0;overflow-y:auto;overscroll-behavior:contain;
    padding:0 14px;margin:0 -14px}

  /* ── 权限管理 ──（左 250px 角色/人员栏 + 右内容栏）
     ⚠ 结构是 `#permsContent` → `.pm-tabs` + `#permBody` → `.pm-layout`（两栏）——
       中间还隔了一层 `#permBody`，所以高度链要一段段接上，缺一段 `flex:1` 就整页还能滚。 */
  #view-perms{display:flex;flex-direction:column}
  #view-perms #permsContent{display:flex;flex-direction:column;flex:1 1 auto;min-height:0}
  #view-perms .pm-tabs{flex:0 0 auto}
  #view-perms #permBody{display:flex;flex-direction:column;flex:1 1 auto;min-height:0}
  #view-perms .pm-layout{flex:1 1 auto;min-height:0;align-items:stretch}
  #view-perms .pm-side{position:static;min-height:0;overflow-y:auto;overscroll-behavior:contain}
  /* ★ 2026-10-07 三修：同 ⑦ —— `.pm-card` 左缘贴死容器（实测 gap 左 0 / 右 10），
     加 overflow 后左侧阴影被裁。14px 内边距给阴影留地方，负外边距把内容盒原样抵回。 */
  #view-perms .pm-main{min-height:0;overflow-y:auto;overscroll-behavior:contain;
    padding:0 14px;margin:0 -14px}

  /* ══ ⑦ 原则（2026-10-07）：**滚动容器里「贴边」的卡片，阴影会被容器裁掉** ══
     CSS 没有"只在滚动方向裁切"这回事 —— 一个轴是 `auto`，另一个轴即使是 `visible`
     也会被算成 `auto`。所以给容器加 `overflow-y:auto` 的同时，就顺手把它的**左右也变成
     裁切边界**了；容器 `padding` 又是 0、子卡片又贴着左右边缘 ⇒ 那圈横向阴影被齐边切光，
     而上下因为容器里有空间、没被切 ⇒ **四边不对称**，圆角处看着就像被一刀切平。（深色下最明显：
     `--shadow-1` 深色是 rgba(0,0,0,.35)+.28，浅色只有 rgba(16,24,40,.05)，差约 6 倍。）
     修法固定两条，**缺一不可**：
       ① `padding:0 14px` —— 给阴影留 14px 的地方画（实测本项目 `--shadow-1` 横向扩散 13~16px）；
       ② `margin:0 -14px` —— 把裁切框整体外扩 14px，**内容盒位置原样不动**（卡宽 / 位置 / 间距全不变）。
     ⚠ 上界就是 14px：`.content` 的右侧内边距正好 14px，给到 15px 就会顶出视口 ⇒ 冒横向滚动条。
     ⚠ 以后**给任何容器加 overflow 之前，先自问：它里面有没有贴着左右边缘的阴影 / 发光？**
       有就把这两条一起写上。自查工具：`_tools/_diag_b57.js`（逐页扫「有阴影 + 被裁切祖先
       切在左右边缘」，无参数直接跑）。
     ⚠ 侧栏 `.sidenav nav`（`overflow-x:hidden`）里那 8 个 `.active` 导航按钮的阴影
       **改动前就是被切的**（老问题，不是本批引入），本批未动 —— 若要一起治，另说。 */
}

/* ══════════════════════════════════════════════════════════════════════════
   ⑥ ★ 2026-10-07（岩峰定）：把「系统设置 / 权限管理 / 数据监控 / 个人设置」四页的
   **卡片语言统一到全系统标准**（`.panel` 家族）—— 但**只统一圆角与描边**这两项。
   ⚠ 2026-10-07 二修（岩峰真机报的两个回归，都出在"统一得太多"上）：
     ① 原版还统一了 `box-shadow`（换成 `.panel` 同档大阴影）。而 `.sys-side` 与右栏只隔 24px，
        大阴影向右扩散 ⇒ **视觉上盖住了右栏的框**。⇒ 阴影交回各元素原有层级（`--shadow-1`），不再统一。
     ② 原版用裸 `.card` 当选择器，可看板右栏订单卡的类名是 `class="card vcard …"` ⇒ 被一起改了
        （18px 圆角 + `--edge` 描边 + 大阴影，从"列表行"变成"浮起的卡片"，与改造前不是一个东西）。
        ⇒ 一律加**目标页前缀**，不再用裸 `.card`。
     ③ 同时去掉上一版新加的顶部高光线（`::before`）：它的 inset 是 16px 而圆角半径 18px，
        会在四个角上穿进圆弧；且这些卡片原本就没有这道线。
     ④ ★ 2026-10-16 晚（岩峰定「统一」· 对照考核系统后拍板）：**圆角一项修订为 12px（`--r-lg`）** ——
        与考核系统同页同款、也与全站基础 `.card` 同款（原 18px = `--r-xl` 是 10-07 选定的
        `.panel` 档）。**描边（`--edge`）保持不动**。已随改动出具四页真机截图核对（浅色）。
        ⚠ 若日后观感要回退 18px：改下面这一行 `--r-lg` → `--r-xl` 即可（仅此一处）。
   ══════════════════════════════════════════════════════════════════════════ */
#view-settings .card,
#view-system .card,#view-dbview .card,#view-perms .card,
#view-system .sys-side,#view-system .sys-list,
#view-perms .pm-side,#view-perms .pm-card{border-radius:var(--r-lg);border-color:var(--edge);border-top-color:var(--edge)}
/* ★ 2026-10-16 晚（岩峰定「个人设置参考考核系统一模一样照抄」）：此处原有
   `#view-settings .card{max-width:560px}`（10-13 · UI 审计 06 岩峰定的"卡片收窄"）——
   按新指令**放开**、卡片恢复全宽：考核系统同页是全宽（用户指定照抄），
   且全宽后与本系统 `#view-system` 系统设置页同构（两页本就同族）。
   ⚠ 若将来又想收窄，先与岩峰确认（两版观感他都看过）。 */
/* 权限管理的分组条（「导航板块 / 操作」）原来是**蓝底蓝字** —— 全站唯一一处用色块当分组标题，
   看着像"另一套系统"。改成与看板 `.grp` 同一种语言：灰字小标题 + 字距（不再抢视觉）。 */
.pm-gh{background:transparent;color:var(--muted);font-weight:600;letter-spacing:.08em;border-bottom:0;
  padding:12px 16px 6px}

/* ══════════════════════════════════════════════════════════════════════════
   ★ 2026-10-05（岩峰定稿 S-B「诊断台」）：订单数据页重做
   出处 `_previews/S-dashboard.html` 的 B 版，**逐条照搬**；作用域 `.B` → `#view-dashboard`。
   ⚠ 定稿里的 11.5px / 10.5px 一律提到 12px（生产系统硬规则：全站字号 ≥12px）。
   ══════════════════════════════════════════════════════════════════════════ */
#view-dashboard .hd{display:flex;align-items:baseline;gap:10px;margin:0 0 12px}
#view-dashboard .hd .t{font-size:13px;font-weight:600;color:var(--text);white-space:nowrap}
#view-dashboard .hd .sub{font-size:12px;color:var(--hint);white-space:normal;overflow-wrap:anywhere}
#view-dashboard .hd .r{margin-left:auto;display:flex;align-items:center;gap:8px;white-space:nowrap}
/* 环比（2026-10-06 岩峰定：**两个值同屏**）——
   不再显示百分比 / 百分点（"个点 / pp"要额外解释，且加工过的数会误导），也不再显示箭头；
   直接把**上期值**摆出来，两个数一眼比高低。颜色只承担"本期相对上期是好是坏"。
   ★ 形态是**轻量文字**、不是徽标：上期值属于"参照信息"，不该和主数值抢视觉重量。
   ★ 百分比类指标的"差值"信息不再显式给出 —— 但两个原始值都在，随时能比。 */
:is(#view-dashboard,#view-perf) .delta{display:inline-flex;align-items:baseline;gap:4px;font-size:13px;
  font-weight:500;font-variant-numeric:tabular-nums;white-space:nowrap}
:is(#view-dashboard,#view-perf) .delta .lb{color:var(--muted);font-weight:400}
:is(#view-dashboard,#view-perf) .delta.up{color:var(--good)}
:is(#view-dashboard,#view-perf) .delta.down{color:var(--bad)}
:is(#view-dashboard,#view-perf) .delta.flat{color:var(--muted)}
/* ── ⓪ 筛选条（定稿 `.fbar`：常驻单行 / 30px 控件 / 右侧按钮组）──
   ⚠ 全局有 `input,select,textarea{width:100%;min-height:44px}`，不显式收回就会被撑成
     「一项一行」（订单查询页踩过一次，这里同样处理）。 */
:is(#view-dashboard,#view-perf) .fbar{display:flex;align-items:center;gap:9px;flex-wrap:wrap;padding:10px 13px;
  margin-bottom:12px;border-radius:var(--r-lg);--h-ctl:30px}
/* ★ 2026-10-09（按钮集 v5 · 岩峰决策）：筛选条由 32px 收到 **30px**，并入既有的「紧凑档」——
   原来全站有 28/30/32/36 四个高度，规范只认三档（标准 36 / 小号 28 / 紧凑 30），
   32px 是第四个、会让"同一个按钮在不同页高度不同"。收 2px 视觉几乎不可见。 */
/* ★ 2026-10-05（岩峰：这俩日期框也要调）：日期是 .date-trigger（读 --h-ctl），
   上面那条把本页 .fbar 的 --h-ctl 收到 32 ⇒ 与 #dKeyword 同高（原来 36，一排里高一头）。 */
:is(#view-dashboard,#view-perf) .fbar .fl{font-size:12px;color:var(--hint);white-space:nowrap}
:is(#view-dashboard,#view-perf) .fbar select,:is(#view-dashboard,#view-perf) .fbar input{height:30px;width:auto;min-height:0;
  border-radius:var(--r-md);background-color:var(--m-ultra);border:1px solid var(--edge);
  color:var(--text);font-size:12.5px;padding:0 10px;box-shadow:none}
:is(#view-dashboard,#view-perf) .fbar input#dKeyword{width:132px}
:is(#view-dashboard,#view-perf) .fbar select:focus,:is(#view-dashboard,#view-perf) .fbar input:focus{outline:none;
  border-color:var(--accent);box-shadow:var(--focus-ring)}
:is(#view-dashboard,#view-perf) .fbar .seg{display:inline-flex;background-color:var(--m-ultra);
  border:1px solid var(--edge);border-radius:var(--r-pill);padding:2px}
:is(#view-dashboard,#view-perf) .fbar .seg button{border:0;background:none;color:var(--muted);font-size:12px;
  padding:5px 12px;border-radius:var(--r-pill);cursor:pointer;white-space:nowrap;transition:.15s}
:is(#view-dashboard,#view-perf) .fbar .seg button.on{background-color:var(--accent);color:#fff;font-weight:600;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.26)}
:is(#view-dashboard,#view-perf) .fbar .sp{margin-left:auto;display:flex;gap:8px;align-items:center}
:is(#view-dashboard,#view-perf) .fbar .filter-date-group{flex:0 0 auto;max-width:none;min-width:0}
:is(#view-dashboard,#view-perf) .fbar .filter-date-group input[type=date]{width:118px;flex:0 0 auto;height:30px;min-height:0}
@media (max-width:1100px){
  :is(#view-dashboard,#view-perf) .fbar .filter-date-group{flex:1 1 150px;min-width:0}
  :is(#view-dashboard,#view-perf) .fbar .filter-date-group input[type=date]{width:auto}
  :is(#view-dashboard,#view-perf) .fbar .sp{margin-left:0;width:100%;justify-content:flex-end}
}

/* ── ① 紧凑指标条 ── */
/* ★ 2026-10-07（岩峰：「四个格要一模一样大」）：加 `grid-auto-rows:1fr` **把各行拉成等高**。
   为什么需要：默认 `grid-auto-rows:auto` 下**两行各按自己的内容撑高**——窄屏折成 2 列后，
   第二行（准时交付率 65.7% / 一次交付率 85.7%）的「上期 52.3%」在 186px 里放不下会换行，
   那一行就比第一行高十几像素（岩峰截图实测：上行 115 / 下行 132），四格看着大小不一。
   `1fr` 让所有行取同一高度（= 最高那行的内容高）⇒ 四格严格同尺寸。
   ⚠ 只影响**行高**，不动列宽与内边距。 */
:is(#view-dashboard,#view-perf) .kstrip{display:grid;gap:0;grid-auto-rows:1fr;margin-bottom:12px;
  border-radius:var(--r-lg);background-color:var(--panel2);border:1px solid var(--edge);overflow:hidden;
  /* ★ 2026-10-06（岩峰）：KPI 条原先**只有内高光、没有外阴影** ⇒ 比下面那些卡片"平"。
     现对齐 `.panel`（生产周期/类型分布等卡）的**同一档**阴影，做成同层的浮起感。
     内高光保留（`inset` 写在列表最后）。 */
  box-shadow:0 30px 74px -36px var(--lift),0 2px 6px rgba(0,0,0,.22),inset 0 1px 0 var(--rim-side)}
/* ★ 2026-10-07（岩峰截图抓出的真 bug）：列数**按页分开**（订单数据页 4 格 / 人效页 3 格）。
   ⚠ 上一次把这两行**插进了上一条规则的声明块内部** ⇒ CSS 解析器把两条规则连同其后的
   `border-radius` / `background-color` / `border` / `box-shadow` 一起**丢弃** ⇒
   人效页没有列定义（KPI 条**竖排成一列**）、且底色圆角阴影全失。**改 CSS 务必插在规则之外。** */
/* ★ 2026-10-08（第 70 批）：4 格 → 5 格（新增首格「下单数」）⇒ 桌面 5 列排一行。
   手机端**不加特例**：沿用下方 `≤1100 / ≤600` 的 2 列 +「末格跨满」机制 ⇒ 5 格自动排成 2+2+1
   （与人效页 3 格 → 2+1 是同一套规则，视觉语言保持一致）。 */
#view-dashboard .kstrip{grid-template-columns:repeat(5,minmax(0,1fr))}
#view-perf .kstrip{grid-template-columns:repeat(3,minmax(0,1fr))}
:is(#view-dashboard,#view-perf) .kstrip .c{display:flex;flex-direction:column;gap:8px;padding:14px 16px;transition:.15s}
/* ★ 2026-10-06（哑枪专项审计）：**只有真正能点的格子才给手型 / hover**。
   4 格里「准时交付率 / 一次交付率」没有下钻，原来也带 `cursor:pointer` + hover
   ⇒ 点下去毫无反应、看着像坏了。这正是"外观一样、行为不一样"那类会被当成 bug 的问题。 */
:is(#view-dashboard,#view-perf) .kstrip .c[onclick]{cursor:pointer}
:is(#view-dashboard,#view-perf) .kstrip .c+.c{border-left:1px solid var(--edge)}
:is(#view-dashboard,#view-perf) .kstrip .c[onclick]:hover{background:var(--m-ultra)}
/* ★ 2026-10-05（岩峰：这些的背景色不够白）：KPI 卡原来用 `--panel2` ——
   **两主题下语义相反**：浅色 #f3f4f7 比 --panel(#fff) **暗**（卡片发灰，就是"不够白"）；
   深色 #222a3d 比 --panel(#1a2030) **亮**（那是深色想要的卡片浮起）。⇒ **只修浅色**，深色零改动。
   同时把"看得见的分隔线"从 `--edge`（浅色=白 85%，等于隐形）换成 `--border`，
   否则白底白线，格子反而糊成一片。 */
html[data-theme="light"] #view-boardview .k,
html[data-theme="light"] :is(#view-dashboard,#view-perf) .kstrip{background-color:var(--panel);border-color:var(--border)}
html[data-theme="light"] :is(#view-dashboard,#view-perf) .kstrip .c+.c{border-left-color:var(--border)}
/* ★ 2026-10-05（QA F-1）：≤1100 断点把 KPI 条折成两行，行间用 `border-top:1px solid var(--edge)`；
   浅色下 `--edge = rgba(255,255,255,.85)` ⇒ 白线画在白卡上 = 看不见（左边框今天已改 --border，漏了上边框）。
   这里**只加浅色覆写**（深色 --edge 是刻意更淡的分隔，不动）。两块断点选择器相同 ⇒ 一条即可覆盖。 */
html[data-theme="light"] :is(#view-dashboard,#view-perf) .kstrip .c:nth-child(n+3){border-top-color:var(--border)}
html[data-theme="light"] :is(#view-dashboard,#view-perf) .kstrip .c[onclick]:hover{background:var(--panel2)}
:is(#view-dashboard,#view-perf) .kstrip .cap{font-size:12px;color:var(--hint);white-space:nowrap}
/* ★ 2026-10-06（岩峰定·**纯排版「乙」版**）：数值与上期**同一行、两端对齐**。
   改前 = 「数值一行 + 上期另起一行」且都靠左 ⇒ 每格 360px 里内容只占约 55px，右侧全空。
   现在数值占左端、上期贴右端 ⇒ **横向铺满**；数值同时放大到展示级（`--fs-display` = 30px，原 22px）。
   ⚠ 窄屏（≤820）已有 `.row{flex-wrap:wrap}` ⇒ 放不下时上期自动换行降级，不会横向溢出。 */
:is(#view-dashboard,#view-perf) .kstrip .row{display:flex;align-items:baseline;justify-content:space-between;gap:10px;min-width:0}
:is(#view-dashboard,#view-perf) .kstrip .v{font-size:var(--fs-display);font-weight:700;line-height:1.05;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
:is(#view-dashboard,#view-perf) .kstrip .v.r{color:var(--bad)}
:is(#view-dashboard,#view-perf) .kstrip .v.g{color:var(--good)}
:is(#view-dashboard,#view-perf) .kstrip .v.m{color:var(--muted)}
/* ★ 2026-10-07（岩峰二修：「如果只有三个，那就只显示三个，**不要显示四个还空着一个**」）：
   上一版为了「补十字分割线」补了一个**不可见的占位格** `.c.ghost` 去填右上角 ——
   它虽然看不见，但**确实占了一个格子**，岩峰看图就是"四个格空着一个"，而且第 3 格的内容
   被挤在左半、右半空着。**已整体撤销**。
   现在改为：**窄屏 2 列布局下，奇数个格子时最后一个 `grid-column:1/-1` 跨满整行** ——
   格子数不变（3 个就是 3 个）、没有空槽，且它照常吃 `border-top` ⇒ 横线仍是整条贯通。
   （桌面：数据页 4 列 / 人效页 3 列，条数正好整除 ⇒ 本规则不触发。） */
@media (max-width:1100px){
  /* ★ 2026-10-08（第 70 批）：跨满整行的那格**不要左边框** —— 它是该行唯一的格子，
     左边没有相邻格，留着 1px 竖线看着像"从中间劈开"（第 70 批真机 390 实测 borderLeft=1px）。
     顺带修正人效页同款（3 格 → 2+1 时第 3 格同样跨满）。 */
  :is(#view-dashboard,#view-perf) .kstrip>.c:last-child:nth-child(odd){grid-column:1/-1;border-left:0}
}
/* ── ② 三栏 ── */
#view-dashboard .three{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr) minmax(0,.95fr);
  gap:12px;margin-bottom:12px}
#view-dashboard .three>.panel{display:flex;flex-direction:column}
#view-dashboard .three .legend{margin-top:auto;padding-top:14px}
#view-dashboard .gbars{display:flex;flex-direction:column;gap:19px}
#view-dashboard .gb{display:grid;grid-template-columns:var(--lw,120px) minmax(0,1fr);gap:11px;align-items:center}
#view-dashboard .gb .lb{font-size:13px;color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#view-dashboard .gb .pr{display:flex;flex-direction:column;gap:4px}
#view-dashboard .gb .ln{display:flex;align-items:center;gap:7px}
#view-dashboard .gb .ln b{font-size:12px;color:var(--hint);font-weight:600;width:26px;flex:0 0 auto;white-space:nowrap}
#view-dashboard .gb .ln .tr{flex:1;height:9px;border-radius:var(--r-pill);background:var(--track);overflow:hidden}
#view-dashboard .gb .ln .tr i{display:block;height:100%;border-radius:var(--r-pill)}
#view-dashboard .gb .ln.now .tr i{background:var(--accent)}
#view-dashboard .gb .ln.pv .tr i{background:var(--track-fill)}
/* 每排条尾的**值**（2026-10-06 岩峰：原来合写在右侧 `.vl` 里 `11 / 5`，现在跟到各自那排后面）——
   固定宽度 + 右对齐 ⇒ 各行条的右端仍然对齐；本期值用正文色、上期值用提示色，主次自然分开。 */
#view-dashboard .gb .ln em{font-style:normal;font-variant-numeric:tabular-nums;font-size:12px;
  color:var(--text);width:32px;flex:0 0 auto;text-align:right}
#view-dashboard .gb .ln.pv em{color:var(--hint)}
/* ★ 2026-10-05（岩峰：里面的内容要在整个卡片的居中位置）：
   品牌构成面板的内容在卡片里**垂直居中**（标题「品牌构成」仍留在上方）。
   `.three>.panel` 已经是 flex column（见 #view-dashboard .three>.panel）⇒ 用 margin:auto 吃掉剩余空间即可，
   **零结构改动**（判据按 .donut-wrap svg / .dlist .it[data-brand] 取，全不受影响）。
   三种形态都要居到：环形（.donut-wrap 单块）/ 降级（.brandbars + .dlist 两块）/ 空库（.empty + .dlist 两块）。 */
/* ⚠ 只靠上面那套 margin:auto 会**偏下 17px**：标题 .hd 仍占着顶部 33px（21 高 + 12 下边距），
   内容是「标题之下的剩余空间」居中（实测内容中心 503 vs 卡片中心 486.5）。
   岩峰说的是「整个卡片的居中位置」⇒ 需让标题**不占流**（改法见下 ★★）。
   · 只作用于品牌面板（三栏里第 2 栏，渲染顺序固定：类型分布 / 品牌构成 / 交付质量）；
   · z-index:1：万一内容极高（降级形态品牌很多）也不会把标题盖住。
   ★★ 2026-10-08（第 69 批 · 岩峰报「筛选后数据少时品牌构成内容重叠」）：改「常规流 + 下方补等量留白」。
      原方案（标题 position:absolute 不占流）的硬伤：**卡片高度 == 内容高度时必然重叠** ——
      内容用 margin:auto 居中，没有剩余空间时它顶到卡片顶部，而标题也画在 top:14 ⇒ 两者完全重合。
      真机实测（1920 · 浅色 · 区间 10/01~10/01、三栏都空）：`.hd` t=262 与 `.empty` t=262 完全重合。
      ⇒ 现方案：标题**占流**（static；视觉位置不变 = 14 padding + 33 标题高），并给面板**下内边距 47px**
        （= 上侧的 14 + 33）⇒ 内容区 [47, H-47] 的中心仍是 H/2，**"内容居中到卡片几何中心"与原方案等价**；
        而空间不足时内容顶到标题下方 ⇒ **永不重叠**。 */
#view-dashboard .three>.panel:nth-child(2)>.hd{position:static;margin:0 0 12px}
#view-dashboard .three>.panel:nth-child(2){padding-bottom:47px}
#view-dashboard .three>.panel>.donut-wrap{margin-top:auto;margin-bottom:auto}
#view-dashboard .three>.panel>.brandbars{margin-top:auto}
#view-dashboard .three>.panel>.empty{margin-top:auto}
#view-dashboard .three>.panel>.brandbars+.dlist{margin-bottom:auto}
#view-dashboard .three>.panel>.empty+.dlist{margin-bottom:auto}
/* 品牌构成：环形（部分-整体，≤5 段）+ 右侧图例明细。定稿 `S-dashboard.html` 的 `.donut-wrap`。 */
#view-dashboard .donut-wrap{display:flex;align-items:center;gap:18px}
#view-dashboard .donut{flex:0 0 auto;line-height:0}
#view-dashboard .donut svg{display:block}
#view-dashboard .donut text{font-variant-numeric:tabular-nums}
/* 段数 >5 退回堆叠条（定稿规则：环形只吃 ≤5 段）—— 这里只是把旧形态的容器补上间距 */
#view-dashboard .brandbars+.dlist{margin-top:14px}
/* 品牌明细列表（既是环形的图例，也是降级形态的列表） */
#view-dashboard .dlist{flex:1;min-width:0;display:flex;flex-direction:column;gap:9px}
#view-dashboard .dlist .it{display:grid;grid-template-columns:10px minmax(0,1fr) auto auto;gap:9px;
  align-items:center;font-size:13px}
#view-dashboard .dlist .it i{width:10px;height:10px;border-radius:3px;display:block}
#view-dashboard .dlist .it .nm{color:var(--text-2);white-space:normal;overflow-wrap:anywhere}
#view-dashboard .dlist .it .v{font-variant-numeric:tabular-nums;color:var(--text);white-space:nowrap}
#view-dashboard .dlist .it .p{font-variant-numeric:tabular-nums;color:var(--hint);font-size:12px;min-width:44px;
  text-align:right;white-space:nowrap}
/* ── ★ 2026-10-05（岩峰定·方案 B「3×2 大数字格」）：生产周期（按订单类型）──
   取代原「交付质量」栏。原来那三条的**头部数字本来就在上面 KPI 条里**（准时交付率 / 一次交付率 /
   已逾期，都可点下钻）⇒ 换掉这一栏没有丢信息；换来的是"每一类订单各要多久"这个原来没有的口径。
   ⚠ 卡片宽度由 `.three` 栅格第 3 栏算出来（1440 视口 358px / 1920 视口 507px）⇒ 每格 ~102px：
     6 字类型名 12px×6=72px **刚好放得下**（不折行、不省略）；「N 单」「最久 X 天」两行排
     （一行排要 94px > 可用 82px，必溢出）。
   ⚠ `.hd` 开 flex-wrap：窄视口下标题与右侧汇总挤不进一行时**掉到第二行**，而不是撑破卡片。 */
#view-dashboard .three>.panel.cycle>.hd{flex-wrap:wrap}
#view-dashboard .cycle .ccg{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;
  margin-top:auto;margin-bottom:auto;min-height:0}
#view-dashboard .cycle .ccg>.empty{grid-column:1/-1}
#view-dashboard .cycle .cc{display:flex;flex-direction:column;gap:5px;padding:10px;min-width:0;
  border:1px solid var(--border);border-radius:12px;overflow:hidden}
#view-dashboard .cycle .cc .nm{font-size:12px;color:var(--text-2);white-space:nowrap;overflow:hidden}
#view-dashboard .cycle .cc .v{font-size:22px;font-weight:700;line-height:1;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;color:var(--text)}
#view-dashboard .cycle .cc .v small{font-size:12px;font-weight:600;color:var(--hint);margin-left:2px;letter-spacing:0}
#view-dashboard .cycle .cc .mb{height:6px;border-radius:var(--r-pill);background:var(--track);overflow:hidden}
#view-dashboard .cycle .cc .mb i{display:block;height:100%;border-radius:var(--r-pill);background:var(--accent)}
#view-dashboard .cycle .cc .mt{font-size:12px;color:var(--hint);font-variant-numeric:tabular-nums;white-space:nowrap}
#view-dashboard .cycle .cc.hot{border-color:var(--ba-soft)}
#view-dashboard .cycle .cc.hot .v{color:var(--bad)}
#view-dashboard .cycle .cc.hot .mb i{background:var(--bad)}
/* 迷你条的"未填充段"：浅色下 --m-reg 是白 74% ⇒ 在白卡上等于没画（深浅语义相反的老坑） */
html[data-theme="light"] #view-dashboard .cycle .cc .mb{background:var(--border)}
/* 窄视口回落两列：第 3 栏宽度 ≈ (.three × .95/3.05)、`.three` ≈ 视口 − 268 ⇒
   视口 < ~1320px 时每格就容不下 6 字类型名（12px × 6 + 20 内边距 = 92px）。
   1101~1365 是"三栏并排"且"每格 <92px"的唯一区间 ⇒ 只在这里回落（1366+ 三列；
   ≤1100 时 .three 本就是单栏、卡片通栏，三列反而更合适）。 */
@media (min-width:1101px) and (max-width:1365px){
  #view-dashboard .cycle .ccg{grid-template-columns:repeat(2,minmax(0,1fr))}
}
/* ── ③ 趋势 / 客户表格 ── */
#view-dashboard .legend{display:flex;align-items:center;gap:16px;font-size:12px;color:var(--hint);flex-wrap:wrap}
#view-dashboard .legend span{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
#view-dashboard .legend i{width:10px;height:10px;border-radius:3px;display:block;flex:0 0 auto}
#view-dashboard .legend i.ln{width:14px;height:3px;border-radius:2px}
:is(#view-dashboard,#view-perf) table.tb{width:100%;border-collapse:collapse;table-layout:fixed;font-size:13px}
/* ★ 2026-10-05（岩峰定·全站统一 C）：表头与内容一并居中（原来表头右对齐、前两列左对齐） */
:is(#view-dashboard,#view-perf) table.tb th{font-size:12px;font-weight:600;letter-spacing:.05em;color:var(--hint);
  text-align:center;padding:0 10px 8px;white-space:nowrap}
:is(#view-dashboard,#view-perf) table.tb th:first-child,:is(#view-dashboard,#view-perf) table.tb th:nth-child(2){text-align:center}
:is(#view-dashboard,#view-perf) table.tb td{padding:8px 10px;border-top:1px solid var(--hair);text-align:center;
  font-variant-numeric:tabular-nums;color:var(--text-2);white-space:nowrap}
:is(#view-dashboard,#view-perf) table.tb td:first-child{text-align:center;color:var(--hint);font-size:12px}
:is(#view-dashboard,#view-perf) table.tb td:nth-child(2){text-align:center;color:var(--text);white-space:normal;overflow-wrap:anywhere}
:is(#view-dashboard,#view-perf) table.tb tr.clk{cursor:pointer}
:is(#view-dashboard,#view-perf) table.tb tr.clk:hover td{background:var(--m-ultra)}
@media (max-width:1100px){
  :is(#view-dashboard,#view-perf) .kstrip{grid-template-columns:repeat(2,minmax(0,1fr))}
  :is(#view-dashboard,#view-perf) .kstrip .c:nth-child(3){border-left:0}
  :is(#view-dashboard,#view-perf) .kstrip .c:nth-child(n+3){border-top:1px solid var(--edge)}
  #view-dashboard .three{grid-template-columns:minmax(0,1fr)}
  /* ★ 2026-10-06（岩峰报「手机端品牌构成标题与环形重叠」）：
     单列后**每张卡片高度 = 自身内容高度**，于是上面那套「标题绝对定位 + 内容 margin:auto 居中」
     （见 3207~3224 的注释）会**把甜甜圈正好压在标题上** —— 标题不占流 ⇒ 容器高度只剩甜甜圈 168px
     ⇒ 居中后起点 == 标题起点。真机 390 实测：标题 y=1054、甜甜圈 y=1054、**gapY = -21px**（完全重叠）。
     ⚠ 单列下根本不需要"居中到卡片几何中心"（那是三栏**等高**才有的诉求）⇒ 标题回归常规流、内容不居中。 */
  #view-dashboard .three>.panel:nth-child(2)>.hd{position:static;margin:0 0 12px}
  #view-dashboard .three>.panel>.donut-wrap{margin-top:0;margin-bottom:0}
  #view-dashboard .three>.panel:nth-child(2){padding-bottom:14px}   /* ★ 第 69 批：单列本就不做"居中到卡片中心"，不需要下补留白 */
  #view-dashboard .three>.panel>.brandbars{margin-top:0}
  #view-dashboard .three>.panel>.empty{margin-top:0}
  #view-dashboard .three>.panel>.brandbars+.dlist{margin-bottom:0}
  #view-dashboard .three>.panel>.empty+.dlist{margin-bottom:0}
}
@media (max-width:600px){
  :is(#view-dashboard,#view-perf) .kstrip{grid-template-columns:repeat(2,minmax(0,1fr))}
  :is(#view-dashboard,#view-perf) .kstrip .c:nth-child(3){border-left:0}
  :is(#view-dashboard,#view-perf) .kstrip .c:nth-child(n+3){border-top:1px solid var(--edge)}
}

/* ══════════════════════════════════════════════════════════════════════════
   ★ 2026-10-05（岩峰定稿 T-A「数据表」）：订单查询页重做
   出处 `_previews/T-search.html` 的 A 版，**逐条照搬**，作用域 `#view-board`。
   ① .fbar 三行常驻筛选 ② .panel.gpanel 列表外壳（.ghead/.gwrap/.gfoot）
   ③ #detpane 从「常驻并排栏」改「右侧 fixed 抽屉」（**id 不变 ⇒ JS 零改动**）
   ⚠ 定稿 11.5/11/10px 一律提 12px（生产系统硬规则：全站字号 ≥12px）
   ══════════════════════════════════════════════════════════════════════════ */
#view-board{--row:44px}
/* ── ① 筛选条（常驻两排）──
   ★ 2026-10-05（岩峰：控件高度跟订单数据页的关键字框对齐）：把 --h-ctl/--h-btn 在**本条作用域内**
     收到 30px —— `.fsearch` / `select` / `.date-trigger` / `.btn` 全部读这两个令牌，一行收口。
     ⚠ 只在 `.fbar` 作用域内改（不是改 `:root`）⇒ 录单页等其它地方仍是 36px，零外溢。
     ★ 2026-10-09（v5）：32px → **30px**（并入紧凑档，全站高度只留 28/30/36 三档）。 */
#view-board .fbar{padding:12px 14px;--h-ctl:30px;--h-btn:30px}
#view-board .frow{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
#view-board .frow+.frow{margin-top:10px;padding-top:10px;border-top:1px solid var(--hair)}
/* ★ 2026-10-05（岩峰：搜索框"修复一下"）：改 `flex:0 1 360px` + max-width ——
   原来 `flex:1` 会把剩余空间**全部吃光**（1920 视口实测 988px、占整排六成），
   现在宽度锁在 220~360px，与下面那排控件同高同档。 */
#view-board .fsearch{flex:0 1 360px;max-width:360px;min-width:220px;height:var(--h-ctl);border-radius:var(--r-pill);
  background-color:var(--m-ultra);border:1px solid var(--edge);display:flex;align-items:center;gap:8px;
  padding:0 13px;box-shadow:inset 0 1px 0 var(--rim-bot)}
#view-board .fsearch svg{width:14px;height:14px;flex:0 0 auto;fill:none;stroke:var(--muted);
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
/* ★ 2026-10-05（岩峰：你不觉得这个很不好看吗）：内层 input 原本写的是 `border:0;background:none`
   而**没有 `!important`** —— 全局 `input,select,textarea{...!important}` 与 `input:focus{...!important}`
   会把它整条压掉 ⇒ 内层 input 一直带 1px 边框 + --panel2 底色，一聚焦边框变 accent 蓝、还叠焦点环，
   看着就是"框里又套了个框"。这里按本文件既有的正确写法（`.field select,.field input`）补 `!important`。 */
#view-board .fsearch input{flex:1;min-width:0;height:auto;width:auto;padding:0;font-size:13px;
/* ★ 2026-10-07（**举一反三** · 同第 5 条「框里控件没对齐」一类）：
   `.fsearch` 是**外壳**（负责边框 / 底色 / 焦点环 / 圆角），里面的 input 应当**铺满它** ——
   但上面那条写的是 `height:auto`，真机 1440 实测 **input 只有 17px、外壳 32px**
   ⇒ 可点/可输入的区域只剩中间一条（上下各 7~8px 点了不聚焦）。
   修：单独补一条 `height:100%`（不动原行文本 —— `_chk_text_clip.py` 的基线按行文本做键）。 */
#view-board .fsearch input{height:100%}
  background:transparent!important;border:none!important;box-shadow:none!important;border-radius:0;color:var(--text)}
/* ★ 全局 `input,select,textarea{width:100%}` + `min-height:44px` 会把筛选条每项撑成**独立一行**
   （2026-10-05 实测：整个 .fbar 变竖排）。这里必须显式收回：宽自适应 + 高度交还给 --h-ctl。 */
#view-board .frow select{width:auto;min-width:0;flex:0 0 auto;height:var(--h-ctl);min-height:0}
#view-board .frow .filter-date-group{flex:0 0 auto;max-width:none;min-width:0}
#view-board .frow .filter-date-group input[type=date]{width:auto;flex:0 0 auto;height:var(--h-ctl);min-height:0}
@media (max-width:600px){
  #view-board .frow select,#view-board .frow .filter-date-group{flex:1 1 140px;min-width:0}
}
/* ★ 焦点环挪到**外壳**上：内层被抹平后，焦点反馈由 `.fsearch:focus-within` 承担 ——
   整个搜索框亮起（点哪儿都看得见），既保住无障碍，也不会再出现"框里还有个框"。 */
#view-board .fsearch input:focus{background:transparent!important;border:none!important;
  box-shadow:none!important;outline:none!important}
#view-board .fsearch:focus-within{border-color:var(--accent);box-shadow:var(--focus-ring)}
/* ★ 2026-10-05（岩峰：这些的背景色不够白 / 把搜索框做成这个样子）——
   **只修浅色主题**，理由写在下一条注释里（--panel2 在两主题语义相反）。 */
html[data-theme="light"] #view-board .fsearch{background-color:var(--panel);border-color:var(--border);
  box-shadow:0 1px 2px rgba(16,24,40,.05)}
html[data-theme="light"] #view-board .fsearch:focus-within{border-color:var(--accent);box-shadow:var(--focus-ring)}
/* ★ 2026-10-05：日期区间整体一项 —— 换行时「开始日期 至 结束日期」一起换，
   不会被 `flex-wrap` 从中间劈开（实测 1258 视口下查询页会在"至"处断行）。 */
.fdate{display:inline-flex;align-items:center;gap:9px;flex:0 0 auto}
#view-board .frow .lab{font-size:12px;color:var(--hint);white-space:nowrap}
#view-board .frow .sp{margin-left:auto}
#view-board .chips{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
#view-board .chip{display:inline-flex;align-items:center;gap:7px;height:27px;padding:0 9px;
  border-radius:var(--r-pill);background:var(--accent-soft);
  border:1px solid color-mix(in srgb,var(--accent) 36%,transparent);color:var(--accent-text);
  font-size:12px;white-space:nowrap;cursor:pointer}
#view-board .chip i{font-style:normal;opacity:.75;font-size:13px;line-height:1}
#view-board .chip:hover i{opacity:1}
#view-board .chip.q{background:var(--m-ultra);border-color:var(--edge);color:var(--text-2)}
#view-board .chip.q:hover{border-color:var(--border-strong)}
#view-board .chip.q.on{background:var(--accent-soft);border-color:color-mix(in srgb,var(--accent) 46%,transparent);color:var(--accent-text)}
/* ── ② 列表面板 ── */
#view-board .gpanel{margin-top:12px;overflow:hidden}
#view-board .ghead{display:flex;align-items:center;gap:10px;padding:11px 14px;border-bottom:1px solid var(--edge);
  background:var(--m-ultra);white-space:nowrap}
#view-board .ghead .ttl{font-size:12px;font-weight:600;letter-spacing:.06em;color:var(--muted)}
#view-board .ghead .n{font:600 12px/1 var(--mono);color:var(--text-2);background:var(--track);
  border-radius:var(--r-pill);padding:4px 9px}
#view-board .ghead .sp{margin-left:auto}
#view-board .ghead .lab{font-size:12px;color:var(--hint)}
#view-board .seg{display:inline-flex;background:var(--m-ultra);border:1px solid var(--edge);
  border-radius:var(--r-pill);padding:2px}
#view-board .seg button{border:0;background:none;color:var(--muted);font-size:12px;padding:5px 13px;
  border-radius:var(--r-pill);cursor:pointer;white-space:nowrap;transition:.15s}
#view-board .seg button.on{background:var(--accent);color:#fff;font-weight:600;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.26)}
#view-board .gwrap{overflow:auto;max-height:calc(100vh - 430px)}
#view-board .gfoot{display:flex;align-items:center;gap:12px;padding:11px 14px;border-top:1px solid var(--edge);
  font-size:12px;color:var(--hint);white-space:nowrap}
#view-board .gfoot .sp{margin-left:auto}
/* ── 表格（九列）── */
#view-board table.dtable{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}
/* ★ 2026-10-05（岩峰定·方案 C）：**表头与内容一并在列内居中**。
   原先表头当"列标签"左/右对齐，而内容前面挂着看不见的东西
   （`.st` 的幽灵内边距 9px + 圆点 6 + 间距 6；`.stay` 前面还挂着 34px 热力条）
   ⇒ 两边各对一处、实测错位 5~21px（停留 −5 / 交期 −5 / 状态 −21）。
   改成"同列同轴居中"后与装饰无关，天然对齐 —— 而且**不需要给任何一列写死像素**。 */
#view-board table.dtable th,#view-board table.dtable td{padding:0 12px;height:var(--row);text-align:center;
  white-space:nowrap;overflow:hidden;font-size:13px;vertical-align:middle}
#view-board table.dtable thead th{position:sticky;top:0;z-index:1;height:34px;font-size:12px;font-weight:600;
  color:var(--muted);letter-spacing:.04em;background:var(--panel2);border-bottom:1px solid var(--edge)}
#view-board table.dtable thead th.sortable{cursor:pointer;user-select:none}
#view-board table.dtable thead th.sortable:hover{color:var(--text-2)}
#view-board table.dtable thead th i{font-style:normal;margin-left:5px;opacity:.45;font-size:12px}
#view-board table.dtable thead th.on{color:var(--accent-text)}
#view-board table.dtable thead th.on i{opacity:1}
/* ★ 2026-10-05：**空排序箭头不占位** —— 排序气泡里没字时 `<i>` 也照占 `margin-left:5px`，
   会把居中的表头挤偏 2.5px（右对齐时更糟：偏 5px）。`:empty` 只对"真的没有字"生效，
   激活排序（写入 ↓/↑）后自动恢复占位。 */
#view-board table.dtable thead th i:empty{display:none}
#view-board table.dtable tbody tr{border-bottom:1px solid var(--hair);cursor:pointer;transition:background-color .12s}
#view-board table.dtable tbody tr:last-child{border-bottom:0}
#view-board table.dtable tbody tr:hover{background:var(--m-ultra)}
#view-board table.dtable tbody tr.sel{background:var(--accent-soft);box-shadow:inset 3px 0 0 var(--accent)}
#view-board table.dtable td.num,#view-board table.dtable th.num{text-align:center;font-variant-numeric:tabular-nums}
#view-board .ono{font:600 13px/1 var(--mono);color:var(--text)}
#view-board .tagx{display:inline-flex;align-items:center;height:19px;padding:0 7px;border-radius:var(--r-pill);
  font-size:12px;font-weight:600;white-space:nowrap;vertical-align:1px}
#view-board .tagx.urgent{background:var(--bad);color:#fff}
/* ★ 2026-10-05（岩峰定）：**删掉热力条**，只留「N 天」。
   原因：条 34px + 间距 7 + 天数 ≈ 76px，而这一列可用宽只有 ~46px ⇒
   ① 浅色主题轨道色 `--m-reg` = 白 74%，画在白卡上等于没画，只剩填充那一小截 ⇒ 看着是个装饰点；
   ② 窄视口下条还会被 `td{overflow:hidden}` 整根裁掉。
   同一个元素在「窄屏消失 / 中屏是点 / 宽屏才是条」之间飘 ⇒ 读不出信息。
   ⚠ 信息不丢：`--warn` / `--bad` 的语义色移到**文字**上（原来只给条上色，见下一行）。 */
#view-board .stay{display:inline-flex;align-items:center}
#view-board .stay .t{font-variant-numeric:tabular-nums;color:var(--text-2)}
#view-board .stay.w .t{color:var(--warn)}
#view-board .stay.b .t{color:var(--bad)}
#view-board .due{display:inline-flex;align-items:center;gap:6px;height:24px;padding:0 9px;
  border-radius:var(--r-pill);font-size:12px;font-variant-numeric:tabular-nums;white-space:nowrap}
#view-board .due.ok{background:var(--ok-soft);color:var(--good)}
#view-board .due.soon{background:var(--wa-soft);color:var(--warn)}
#view-board .due.ov{background:var(--ba-soft);color:var(--bad)}
#view-board .due.mut{background:var(--m-ultra);color:var(--muted)}
/* ★ 2026-10-08（岩峰定）：以下 4 条 `#view-board .st*` 规则已**整条删除** ——
   它们是原 `_statusCell()` 渲染的「状态」列圆点样式（`.st` + 内部 `<s>` 圆点 + run/done 语义色）；
   随「订单查询」状态列一并移除后**零元素使用**（全仓严格 grep 过：无 `class="st "` / `class="st"` /
   `classList.add('st')` / `className='st'` 等任何变体），故清掉，不留幽灵样式。
   ⚠ `.st-row / .st-name / .st-card / .st-keys / .st-del …` 是**不同类名族**（工序/人员卡），**不受影响**。
（另：本批还在上面归一化选择器组 `:is(.pill,.tag,.due,…)` 里移除了 `.st` 成员，其余成员保留。） */
/* 「加载更多」仍在列表尾（既有 JS 生成，保留观感） */
#view-board .gwrap .load-more{text-align:center;padding:12px;color:var(--text-2);cursor:pointer;
  font-size:13px;border-top:1px solid var(--hair)}
#view-board .gwrap .load-more:hover{background:var(--m-ultra)}
#view-board .gwrap .load-more.done{cursor:default;color:var(--hint)}
#view-board .gwrap .load-more.done:hover{background:transparent}
#view-board .gwrap .empty{padding:26px;text-align:center;color:var(--hint);font-size:13px}
/* ── ③ 详情**抽屉**（替掉常驻栏；id 不变）── */
/* ★ 2026-10-05（岩峰：把画稿那层「半透明 + 毛玻璃」的外框和背景搬过来）——
   订单查询页点订单弹出的详情，从「贴边不透明抽屉」改成**浮起的玻璃面板**：
     · 四周留白 `var(--sp-4)`（16px）⇒ 不顶天立地；
     · 四角全圆 `var(--r-xl)`（18px）；
     · 玻璃材质 `--m-thin` + 顶边镜面高光 + `--edge` 细描边 + 外侧大投影；
     · `backdrop-filter:blur(18px) saturate(1.8)` —— 与顶栏 / 底部导航 / `.oe-actbar` / `.gl` 同一套参数。
   ⚠ `#dpaneBody` 的 `overflow-y:auto` **不动** ⇒ 内容照旧可下拉（岩峰：保留内容下拉功能）。
   ⚠ 内部 DOM / 字段 / 按钮**一行未改**：这一条只换外框与背景。 */
/* ★ 2026-10-05（岩峰定）：上沿 = 「查询结果」外壳（.gpanel）的上沿 —— 由 `_paneAlign()` 用
   `--pane-top` 下发（不写死像素：筛选条换行会把 .gpanel 推低）。
   下沿 `bottom` 锚在视口底 16px ⇒ 高度自适应，上沿怎么下移都不会把下边顶出屏幕。 */
/* ★ 2026-10-05（岩峰定「展开全部」）：抽屉有**两态**，靠 left/width 过渡（0.3s）。
   · 窄态（默认）＝ `left:calc(100% - 520px - 16px)` + `width:520px` ⇒ 右边缘距视口 16px；
   · 宽态 `.wide` ＝ `left:var(--pane-left)`（「查询结果」外壳左边，_paneAlign 实量）
                   + `width:calc(100% - left - 16px)` ⇒ 左边缘对齐卡片、右侧仍留 16px。
   ⚠ 用 left+width 而**不是** left/right 双锚：`width:auto` **不可插值**（过渡会跳变），
     而 `calc()` 之间可以插值 ⇒ 0.3s 动画才成立。
   ⚠ `bottom` 仍锚视口底 ⇒ 高度自适应（上沿下移不会把下边顶出屏幕）。 */
#view-board #detpane.drawer{position:fixed;top:var(--pane-top,var(--sp-4));bottom:var(--sp-4);
  left:calc(100% - 520px - var(--sp-4));width:520px;z-index:6;
  transition:left .3s cubic-bezier(.2,.8,.2,1),width .3s cubic-bezier(.2,.8,.2,1);
  display:flex;flex-direction:column;padding:0;overflow:hidden;
  border:1px solid var(--edge);border-radius:var(--r-xl);
  background-color:var(--m-thin);
  background-image:linear-gradient(90deg,transparent,var(--rim-line) 12%,var(--rim-line) 88%,transparent);
  background-size:100% 1px;background-position:0 0;background-repeat:no-repeat;
  -webkit-backdrop-filter:blur(18px) saturate(1.8);backdrop-filter:blur(18px) saturate(1.8);
  box-shadow:inset 1px 0 0 var(--rim-side),inset -1px 0 0 var(--rim-side),
    inset 0 -1px 0 var(--rim-bot),0 16px 40px -18px var(--lift)}
#view-board #detpane .dhead{display:flex;align-items:center;gap:9px;padding:13px 15px;
  border-bottom:1px solid var(--edge);flex:0 0 auto}
#view-board #detpane #dpaneBody{flex:1;min-height:0;overflow-y:auto;padding:14px 15px}
#view-board #detpane .close{margin-left:8px}
/* ★ 2026-10-05（岩峰：做成图8这个样子 / 「无配方色浆」不可以变为两排）：抽屉里汇总条改 2 列。
   原来抽屉里走**基础**规则 `repeat(4,1fr)` —— 412px 宽下每格只有 ~87px，
   五字类型名（如「无配方色浆」）必然折成两行（岩峰截图里就是它）。
   2 列后每格 ~224px，长值也不再折；这也正是宽弹层（图8）里的排法。
   `.c5`（多一格「颜色交期」）同步改 3 列，与 `.bsplit-r` 下同值，不留孤卡。 */
#view-board #detpane .detail-summary{grid-template-columns:repeat(2,1fr)}
#view-board #detpane .detail-summary.c5{grid-template-columns:repeat(3,1fr)}
/* ★ 第 68 批（交付日期第 6 格）：窄态抽屉 6 格与 5 格同为 3 列，不留孤卡。 */
#view-board #detpane .detail-summary.c6{grid-template-columns:repeat(3,1fr)}
/* ── ★ 2026-10-05（岩峰定「展开全部」）：宽态 ──
   左边缘对齐「查询结果」外壳；宽度撑满（右侧留 16px）；内部**回落详情页的列数**
   （482→1668px 宽之后 4/5 列本来就放得下，2 列是窄态才需要的压缩）。
   `min-width:520px`：极端窄窗口下展开也不会比窄态更窄。 */
#view-board #detpane.drawer.wide{
  left:var(--pane-left,232px);
  width:calc(100% - var(--pane-left,232px) - var(--sp-4));
  min-width:520px}
#view-board #detpane.drawer.wide .detail-summary{grid-template-columns:repeat(4,1fr)}
#view-board #detpane.drawer.wide .detail-summary.c5{grid-template-columns:repeat(5,1fr)}
/* ★ 第 68 批（交付日期第 6 格）：宽态抽屉回落详情页列数，6 格排 6 列。 */
#view-board #detpane.drawer.wide .detail-summary.c6{grid-template-columns:repeat(6,1fr)}
/* 「展开全部 / 收起」按钮：放在 × 左边（`.close` 的 margin-left:auto 收回来，改由本钮推右） */
#view-board #detpane .dpane-wide{display:inline-flex;align-items:center;height:24px;padding:0 10px;
  margin-left:auto;border-radius:var(--r-pill);border:1px solid var(--border);background:var(--panel2);
  color:var(--text-2);font-size:12px;line-height:1;white-space:nowrap;cursor:pointer;flex:0 0 auto}
#view-board #detpane .dpane-wide:hover{background:var(--m-reg);color:var(--text)}
@media (prefers-reduced-motion:reduce){   /* 尊重系统的"减少动态"（与全站同一口径） */
  #view-board #detpane.drawer{transition:none}
}
@media (max-width:820px){
  /* 手机：退回全屏、不透明、直角（与 .sheet 的处理同一口径 —— 玻璃只给桌面外壳） */
  #view-board #detpane.drawer{top:0;right:0;bottom:0;left:0;width:100%;max-width:100%;
    border:0;border-radius:0;background-color:var(--panel);
    -webkit-backdrop-filter:none;backdrop-filter:none;
    box-shadow:-30px 0 70px -30px var(--lift)}
  #view-board .gwrap{max-height:calc(100vh - 470px)}
  /* 手机全屏：宽/窄两态没有意义 ⇒ 展开钮藏起来（宽态也退回全屏） */
  #view-board #detpane .dpane-wide{display:none}
  #view-board #detpane.drawer.wide{left:0;width:100%;min-width:0}
}
@media (max-width:600px){
  #view-board .fsearch{flex:1 1 100%}
  #view-board .gwrap{max-height:none}
}

/* ══════════════════════════════════════════════════════════════════════════
   ★ 2026-10-06（第 37 批 · 手机端）—— 断点 820（与 isMobile / matchMedia 三处同源）
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width:820px){
  /* ── 4a：订单卡「明细摘要」允许换行显示**完整**（不裁切、不省略号）──
     原来 `.vcard .vc-sub .s{white-space:nowrap}` 且 flex 子项默认 `min-width:auto`（= min-content）
     ⇒ 退不到内容宽度以下：390 视口实测宽 706px、右缘 730（越界 340px），被 body{overflow-x:clip}
     **静默裁掉** = 明细截断事故（项目铁律：文字永不折行以外的截断）。 */
  .vcard .vc-sub{min-width:0}
  .vcard .vc-sub .s{white-space:normal;overflow-wrap:anywhere;min-width:0}
  .vcard .vc-sub .cust{max-width:100%}
}

@media (max-width:820px){
  /* ── 4b：订单数据页窄屏**零横向滚动** —— 内容自己收进屏幕（不靠横向滚动条）──
     越界根因 = 环比文字 `.delta` 撑破栅格 / 表行。 */
  :is(#view-dashboard,#view-perf) .kstrip .c{min-width:0}
  :is(#view-dashboard,#view-perf) .kstrip .row{flex-wrap:wrap;min-width:0}
  /* ★ 2026-10-06（第 37 批续）：环比文字**成句可读、不逐字竖排**（nowrap 规则保留）。
     旧内容「无上期数据」在窄列里被压成**一字一行**（table-layout:auto 把该列收到 ~44px ⇒ 实测 lines=5）。
     交付方向（岩峰定）：**自身不拆字**，由**所在容器 / 表列**给它够用的宽度。
     ⚠ 2026-10-06 同日改版后内容已变为「上期 <值>」（更短），但这条**继续保留** ——
       长数值（如「上期 1234」）同样不该被拆成竖排。 */
  :is(#view-dashboard,#view-perf) .delta{white-space:nowrap}
  /* 客户 TOP 表「上期单数」列：给足最短成句的最小宽度（「上期 342」≈60px + 左右内边距）。 */
  :is(#view-dashboard,#view-perf) table.tb th:last-child,:is(#view-dashboard,#view-perf) table.tb td:last-child{min-width:84px}
  /* 客户 TOP10 表：窄屏改**换行显示完整**，取消省略号截断（不丢信息、不截断）。 */
  :is(#view-dashboard,#view-perf) table.tb{table-layout:auto}
  :is(#view-dashboard,#view-perf) table.tb th,:is(#view-dashboard,#view-perf) table.tb td{white-space:normal;overflow-wrap:anywhere;
    padding-left:4px;padding-right:4px}
  :is(#view-dashboard,#view-perf) table.tb td:nth-child(2){overflow:visible;text-overflow:clip}
  /* 订单查询页：搜索框独占整行（不吃满后溢出） */
  #view-board .fsearch{flex:1 1 100%;max-width:none;min-width:0}

  /* ── 4c：触控有效热区 ≥44 ── */
  /* 各页通用按钮（原来 40） */
  .btn,#view-order .oe-acts .btn{min-height:44px}
  /* 订单看板负载行 39 → 44 */
  #view-boardview .brow{min-height:44px}
  /* 数据监控条状行 35 → 44 */
  .bar-row{min-height:44px}
  /* 订单录入「加一行明细」40 → 44 */
  #view-order .oe-addrow{min-height:44px}
  /* 明细行「删除」按钮：外观仍 26×26，用 ::before 把热区扩到 44×44（不撑破行高）
     ⚠ 2026-10-06 补充：格线已删（见 `.oe-tscroll` 注释），热区仍在。实测该热区在
     **最后一列（30px）居中**时右侧超出 11px ⇒ `.oe-tscroll` 内出现横向滚动条
     （就是岩峰 10-05 看到的那条"实心灰条"）。**不能向左扩**——左边紧邻「明细备注」输入框，
     扩过去会盖住它导致误点删除。故改为**裁掉这 11px**：热区可点范围变成 33×44（仍 > 26×26），
     容器内不再出滚动条。 */
  #view-order .rowx{position:relative}
  #view-order .rowx::before{content:'';position:absolute;left:50%;top:50%;width:44px;height:44px;
    transform:translate(-50%,-50%)}
  /* 筛选条控件（查询页 / 数据页）：32 → 44（原来被 scoped 规则收到 32） */
  #view-board .fbar select,#view-board .fbar input,#view-board .fbar button,
  :is(#view-dashboard,#view-perf) .fbar select,:is(#view-dashboard,#view-perf) .fbar input,:is(#view-dashboard,#view-perf) .fbar button{height:44px;min-height:44px}
  /* 胶囊 / 快捷筛选（27 → 44） */
  #view-board .chip,#view-dashboard .chip{min-height:44px;display:inline-flex;align-items:center}
  /* 系统设置「删除」按钮（40×40 → ≥44） */
  .sys-row .sys-del{min-width:44px;min-height:44px}
  /* 权限管理：行内文字链接最小宽/高（32×44 → ≥44×44）；开关已有 ::before 46×44 */
  .pm-gh a,.pm-row a{min-width:44px;min-height:44px;justify-content:center}
  /* 订单录入「加急」：真正的可点目标是外层 <label class="oe-urg">（含文字），input 只是外观 */
  #view-order .oe-urg{min-height:44px;display:inline-flex;align-items:center}
  /* 订单录入底部操作条：窄屏允许换行（原来 360 下「清空」按钮左侧越界 7px） */
  #view-order .oe-acts{flex-wrap:wrap}
  /* ★ 2026-10-06（审计 A-06 收尾 · 岩峰选 A）：数据页「下钻行」手机端要能点准 ——
     品牌明细行 21px、类型条 43px ⇒ 补到 44px（触控标准）。
     代价：窄屏下这两个列表会**变疏**（行高增加），桌面端不受影响。 */
  #view-dashboard .gb[data-order-type]{min-height:44px}
  #view-dashboard .dlist .it[data-brand]{min-height:44px}

  /* ★ 2026-10-08（本地库工序同步后 · 第 37 批触控探针）：我的待办「关注」栏**可点条目**
     `.todo-fu .tf-item`（待补附件 / 待派单 / 我借出去的 —— 都挂了 onclick="openDetail(...)"）
     实测仅 **33px**（单行文字 ≈21px + 上下内边距 10~12px）⇒ 补到 44（触控标准）。
     为什么此前漏网：这一批"可点行统一补 44"时补了 `.brow / .bar-row / .chip / .ma-item` 等，
     **独独漏了 `.tf-item`**（它不在任何一页的 `.chip/.brow` 之列）⇒ 探针的"两账号并集 ≥44"当场逮到。
     与同批条目**同一口径**补上，不给它开特例白名单。代价：手机端该栏条目变疏（行高 +11px），桌面不受影响。 */
  .todo-fu .tf-item{min-height:44px}

  /* 系统设置页：`:1935 .sys-row .btn{min-height:40px}`（特异性 0,2,0）压过通用 `.btn`（0,1,0）
     → 用 `#view-system`（1,1,0）抬到 44。sys-del 一并抬（原 `/sys-row .sys-del{min-height:40px}`）。 */
  #view-system .sys-row .sys-del,#view-system .sys-row .btn,
  #view-system .sys-add .btn,#view-system .sys-foot .btn{min-height:44px}
  /* 权限管理页：行内按钮实测 40 宽 → 抬到 ≥44。`.pm-form-grid .btn{height:40px}`（0,2,0）也被
     `#view-perms .btn`（1,1,0）覆盖。 */
  #view-perms .btn{min-width:44px;min-height:44px}
}

/* ============================================================
   ★ 2026-10-16（岩峰定）：Agent 智能分析页（导航第一位）
   ★ 2026-10-16 晚（岩峰定「整个页面的 CSS 跟全系统视觉语言统一」）：
     · 主色 = 系统 `--accent` 蓝（弃设计稿遗留的金色 rgba(212,162,74,…)，共 5 处）；
     · 材质/文字/边框一律走系统 token，**零裸色值**（深浅主题自动适配）；
     · 组件复用系统先例：会话项＝`.pm-role`、分段＝`.pm-tab.active`、开关＝`.pm-tgl`、
       按钮＝`.btn`、标签＝`.pill`、人员多选＝`.pm-mem`；
     · 原 `var(--line)` 是**未定义变量**（18 处 → border 简写失效），全改 `var(--border)`；
     · 字号归 `--fs-*` 刻度（12.5/11.5/13.5 → fs-sm/fs-xs）。
   对话规则：**AI 说的话在左、用户说的话在右**（岩峰明确要求）
   ============================================================ */
#view-agent{display:flex;flex-direction:column;min-height:420px}
#view-agent .ag-wrap{flex:1;display:grid;grid-template-columns:238px minmax(0,1fr);gap:var(--sp-3);min-height:0}
#view-agent .ag-side{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);padding:10px;display:flex;flex-direction:column;overflow-y:auto}
#view-agent .ag-top{display:flex;align-items:center;justify-content:space-between;padding:2px 6px 10px}
#view-agent .ag-top b{font-size:var(--fs-md);color:var(--text)}
#view-agent .ag-seg{display:flex;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-md);padding:3px;margin-bottom:10px}
#view-agent .ag-seg .s{flex:1;text-align:center;padding:6px 0;border-radius:var(--r-sm);color:var(--muted);font-size:var(--fs-sm);cursor:pointer}
#view-agent .ag-seg .s.on{background:var(--accent);color:var(--on-accent);font-weight:600}
#view-agent .ag-link{display:flex;align-items:center;gap:9px;padding:8px 9px;border-radius:var(--r-md);color:var(--text-2);font-size:var(--fs-sm);cursor:pointer;border:1px solid transparent}
#view-agent .ag-link:hover{background:var(--panel2);color:var(--text)}
#view-agent .ag-link .lm{color:var(--muted);width:15px;text-align:center}
#view-agent .ag-lbl{font-size:var(--fs-xs);color:var(--hint);padding:12px 9px 6px}
#view-agent .ag-conv{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:8px 9px;border-radius:var(--r-md);cursor:pointer;margin-bottom:2px;border:1px solid transparent;color:var(--text-2)}
#view-agent .ag-conv:hover{background:var(--panel2)}
#view-agent .ag-conv.on{background:var(--accent-soft);border-color:var(--accent);color:var(--text)}
#view-agent .ag-conv .t{font-size:var(--fs-sm);min-width:0;overflow-wrap:anywhere;line-height:1.4}
#view-agent .ag-conv .x{color:var(--hint);font-size:var(--fs-xs);flex:0 0 auto;padding:0 3px;visibility:hidden}
#view-agent .ag-conv:hover .x{visibility:visible}
#view-agent .ag-conv .x:hover{color:var(--danger)}
#view-agent .ag-main{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);display:flex;flex-direction:column;min-height:0;overflow:hidden}
#view-agent .ag-home{flex:1;display:flex;flex-direction:column;justify-content:center;align-items:center;padding:var(--sp-6);min-height:0}
#view-agent .ag-logo{width:64px;height:64px;border-radius:var(--r-xl);background:var(--accent-soft);display:flex;align-items:center;justify-content:center;font-size:30px;color:var(--accent);margin-bottom:18px}
#view-agent .ag-home h2{margin:0 0 8px;font-size:22px;color:var(--text);font-weight:700}
#view-agent .ag-home .d{color:var(--muted);font-size:var(--fs-sm);margin-bottom:var(--sp-6)}
#view-agent .ag-inbig{width:min(720px,88%);display:flex;gap:10px;align-items:flex-end;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-xl);padding:13px 15px}
#view-agent .ag-inbig:focus-within{border-color:var(--accent);box-shadow:var(--focus-ring)}
#view-agent .ag-inbig textarea{flex:1;background:none;border:none;outline:none;color:var(--text);font:inherit;resize:none;height:46px;min-height:0}
#view-agent .ag-send{background:var(--accent);color:var(--on-accent);border:none;border-radius:var(--r-lg);width:42px;height:42px;font-size:var(--fs-lg);cursor:pointer;flex:0 0 auto;transition:background-color .15s}
#view-agent .ag-send:hover{background:var(--accent-d)}
#view-agent .ag-send:disabled{opacity:.42;cursor:not-allowed}
#view-agent .ag-chips{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin-top:18px;width:min(720px,88%)}
#view-agent .ag-chip{border:1px solid var(--border);background:var(--panel2);color:var(--muted);border-radius:var(--r-pill);padding:7px 14px;font-size:var(--fs-sm);cursor:pointer}
#view-agent .ag-chip:hover{border-color:var(--accent);color:var(--accent)}
#view-agent .ag-warn{margin-top:14px;color:var(--warn);font-size:var(--fs-sm)}
#view-agent .ag-msgs{flex:1;overflow-y:auto;padding:20px 24px 6px}
#view-agent .ag-col{max-width:760px;margin:0 auto}
#view-agent .row{display:flex;gap:11px;margin-bottom:18px}
#view-agent .row.me{flex-direction:row-reverse}   /* ★ 用户消息在右（岩峰定） */
#view-agent .av{width:30px;height:30px;border-radius:var(--r-md);flex:0 0 auto;display:flex;align-items:center;justify-content:center;font-size:var(--fs-sm);background:var(--accent-soft);color:var(--accent)}
#view-agent .row.me .av{background:var(--accent);color:var(--on-accent)}
#view-agent .bub{background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-lg);padding:11px 14px;font-size:var(--fs-sm);min-width:0;max-width:82%;white-space:pre-wrap;overflow-wrap:anywhere}
#view-agent .row.me .bub{background:var(--accent-soft);border-color:var(--accent-soft)}
#view-agent .bub .k{color:var(--accent);font-weight:600}
#view-agent .bub table{border-collapse:collapse;font-size:var(--fs-xs);margin:8px 0}
#view-agent .bub th,#view-agent .bub td{padding:5px 10px;text-align:left;border-top:1px solid var(--border)}
#view-agent .bub th{color:var(--text-2);font-weight:600;font-size:var(--fs-xs)}
#view-agent .ag-trace{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
#view-agent .ag-tr{font-size:var(--fs-xs);color:var(--hint);border:1px solid var(--border);border-radius:var(--r-pill);padding:2px 10px}
#view-agent .ag-tr.link{color:var(--accent-text);cursor:pointer}
#view-agent .ag-tr.link:hover{border-color:var(--accent-text)}
#view-agent .ag-inb{border-top:1px solid var(--border);padding:11px 24px 13px}
#view-agent .ag-inbox{display:flex;gap:10px;align-items:flex-end;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-lg);padding:11px 13px}
#view-agent .ag-inbox:focus-within{border-color:var(--accent);box-shadow:var(--focus-ring)}
#view-agent .ag-inbox textarea{flex:1;background:none;border:none;outline:none;color:var(--text);font:inherit;resize:none;height:44px;min-height:0}
#view-agent .ag-tips{display:flex;gap:13px;color:var(--hint);font-size:var(--fs-xs);padding:7px 3px 0}
/* 定时任务页（右区）—— 「新建」按钮直接用系统按钮集（.btn .btn-primary .btn-sm）；
   逐行开关直接用系统开关（.pm-tgl）；「最近报告」行＝消息页列表项（.nt-item）同款语言 */
#view-agent .ag-tasks{flex:1;overflow-y:auto;padding:4px 2px;min-height:0}
#view-agent .ag-tadd{display:flex;justify-content:flex-end;margin:2px 0 12px}
#view-agent .ag-tcard{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;margin-bottom:11px}
#view-agent .ag-trow{display:grid;grid-template-columns:minmax(0,1.6fr) 130px 160px 140px 90px 64px;gap:10px;align-items:center;padding:12px 16px;border-bottom:1px solid var(--border);font-size:var(--fs-sm)}
#view-agent .ag-trow:last-child{border-bottom:none}
#view-agent .ag-trow.head{color:var(--text-2);font-weight:600;font-size:var(--fs-xs);background:var(--panel2)}
#view-agent .ag-tname{font-weight:600;min-width:0;overflow-wrap:anywhere;line-height:1.4}
#view-agent .ag-tname .sub2{display:block;font-weight:400;color:var(--hint);font-size:var(--fs-xs);margin-top:2px;overflow-wrap:anywhere;line-height:1.4}
#view-agent .ag-ttag{display:inline-block;font-size:var(--fs-xs);background:var(--chip);border-radius:var(--r-pill);padding:1px 8px;color:var(--muted);margin-right:5px}
#view-agent .ag-tool{color:var(--muted)}
#view-agent .ag-tst{font-size:var(--fs-xs)}
#view-agent .ag-tst .ok{color:var(--good)}#view-agent .ag-tst .bad{color:var(--danger)}
/* 任务行开关：`.pm-tgl` 是 <span>，默认 inline（宽高失效成一条线）——
   权限页/系统设置页在 flex 行里天然 blockified，本页容器是普通 div → 显式给 inline-flex（同 `.st-ena` 的做法） */
#view-agent .pm-tgl{display:inline-flex;vertical-align:middle}
#view-agent .ag-tedit{color:var(--accent-text);cursor:pointer;font-size:var(--fs-sm)}
#view-agent .ag-flow{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);padding:13px 17px;color:var(--muted);font-size:var(--fs-sm);line-height:2}
#view-agent .ag-flow b{color:var(--text)}#view-agent .ag-flow .arr{color:var(--accent);margin:0 5px}
#view-agent .ag-reports{margin-top:6px}
#view-agent .ag-rep{display:flex;justify-content:space-between;gap:10px;padding:9px 12px;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-md);margin-bottom:6px;cursor:pointer}
#view-agent .ag-rep:hover{background:var(--panel)}
#view-agent .ag-rep .rt{font-size:var(--fs-sm);min-width:0;overflow-wrap:anywhere;line-height:1.4}
#view-agent .ag-rep .rd{font-size:var(--fs-xs);color:var(--hint);flex:0 0 auto}
/* 任务/报告弹层（复用弹层壳，专有内部样式）
   ⚠ 输入框**不再自带皮肤** —— 全局 `input,select,textarea{…!important}` 是唯一皮源（v5 纪律），
     这里只声明布局差异（textarea 高度）。原来自带的 border/background 声明本就**被全局 !important
     压制**（写了也无效），且引用了未定义变量 `--line` → 2026-10-16 统一时一并清掉。 */
.ag-form label{display:block;font-size:var(--fs-xs);color:var(--muted);margin:11px 0 5px}
.ag-form textarea{height:84px;resize:vertical}
.ag-form .frow{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3)}
.ag-form .pickusers{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
/* 「发给谁」多选 chip —— 与权限页「成员」chip（.pm-mem）同款语言 */
.ag-form .pu{display:inline-flex;align-items:center;gap:var(--sp-1);border:1px solid var(--border);border-radius:var(--r-pill);padding:5px 13px;color:var(--muted);cursor:pointer;font-size:var(--fs-sm);user-select:none;transition:border-color .15s,color .15s}
.ag-form .pu:hover{border-color:var(--border-strong);color:var(--text-2)}
.ag-form .pu.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.ag-form .ffoot{display:flex;justify-content:flex-end;gap:10px;margin-top:18px}
.ag-rep-body{max-height:56vh;overflow-y:auto;white-space:pre-wrap;font-size:var(--fs-sm);line-height:1.8;color:var(--text);background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-md);padding:14px 16px}
@media (max-width:980px){
  #view-agent .ag-wrap{grid-template-columns:1fr}
  #view-agent .ag-side{max-height:230px}
  #view-agent .ag-trow{grid-template-columns:1fr 1fr;gap:6px}
  #view-agent .ag-trow.head{display:none}
}
