:root {
  /* F7.4 品牌变量（applyTenantBrand 驱动）：默认 = 平台品牌「海图」teal；
     租户（如 self=汇鑫达）由 me.tenant.brand_* 覆盖。--accent 保持系统紫不变（BRANDING_PLAN §7.5）。 */
  --brand-grad-a: #12886A;
  --brand-grad-b: #085041;
  --bg: #1e1e2e;
  --panel: #2a2a3c;
  --panel-2: #32324a;
  --text: #e6e6f0;
  --muted: #9a9ab0;
  --accent: #7f77dd;
  --border: #3a3a4c;
  --success: #1d9e75;
  --danger: #e24b4a;
  --warn: #ef9f27;
  /* 采购看板「卡片级备注」专用色（2026-09-28 第四轮）：暖红，刻意与 --danger 的纯红错开一点，
     免得备注看起来像报错；深浅两套主题各自配一个，保证两边对比度都够。 */
  --note-ink: #ff6b6b;
}

/* ==========================================================================
   ★ 设计系统 · 三层架构地基（2026-10-07 用户拍板）
   --------------------------------------------------------------------------
   视图层（只拼装） → 组件层 Layer 2（7 类公共组件） → 变量层 Layer 1（尺度唯一真源）

   为什么要做：index.html 是单文件多视图，10 个视图各自写了「局部样式覆盖全局」，
   导致同一件事有多套实现 —— 二级 tab 5 套并行、页头 2 套、控件尺度横跨
   6 种字号（12 / 12.5 / 13 / 13.33 / 13.5 / 14）与 19~40px 高度。

   三条硬规则（改前端前必读）：
     1. 新页面 / 新视图：**只准拼装 Layer 2 的公共类**，不准再写死 px 尺度；
     2. 需要新尺度：先在 Layer 1 加变量，再引用 —— 禁止在视图里写魔法数字；
     3. 动 Layer 1 = 全站生效 ⇒ 改完必须跑 8280 四组合（1920/1440 × 顶部/左侧）核对。

   兼容性承诺：本层全部为**新增**；老类名（.card / .toolbar / .notice / .pager /
   .btn / .section-title / .form-grid …）一律保留、取值不变 ⇒ 未换装的视图**零影响**。
   换装进度与差异清单见 docs/UI_SPEC.md（已退役→UI-017/018）。
   ========================================================================== */

/* ---------- Layer 1 · 变量层（尺度唯一真源） ---------- */
:root {
  /* ① 控件尺度（原来散落 19~40px / 6 种字号，收敛到这三档） */
  --ctl-h: 38px;          /* 常规控件高度：下拉 / 输入 / 工具条按钮 */
  --ctl-h-sm: 32px;       /* 紧凑控件：卡内、次级工具条 */
  --ctl-h-xs: 26px;       /* 极小：印章 / chip / 行内按钮 */
  --ctl-fs: 14px;         /* 常规控件字号 */
  --ctl-fs-sm: 13px;      /* 次级控件字号（原 12.5 / 13 / 13.33 / 13.5 统一于此） */
  --ctl-fs-xs: 12px;      /* 极小字号（原 12 系列） */
  --ctl-pad-x: 12px;      /* 控件左右内边距 */
  --ctl-radius: 10px;     /* 控件圆角（原 8px） */
  --ctl-radius-sm: 8px;   /* 紧凑控件圆角（表格内 / 卡内） */

  /* ② 字号阶梯 */
  --fs-page: 17px;        /* 视图标题 */
  --fs-sec: 14px;         /* 区块标题 / 二级 tab / 导航 */
  --fs-body: 13px;        /* 正文 */
  --fs-meta: 12px;        /* 元信息 / 表头 / 标签 */
  --fs-mini: 11px;        /* 字段小标签 */

  /* ③ 间距阶梯 */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px;  --sp-4: 16px;  --sp-5: 20px;

  /* ④ 圆角 / 容器 */
  --rad-card: 12px;             /* 卡片圆角 */
  --rad-ctl: var(--ctl-radius);
  --rad-chip: 999px;           /* 胶囊（徽标 / chip） */
  --card-bg: var(--panel);     /* 卡片底色（跟随主题） */
  --card-line: 1px solid var(--border);

  /* ⑤ 动效层（2026-10-07 预留，见 docs/UI_SPEC.md（已退役→UI-017/018） §八）
     ⚠️ 只预留令牌与降级开关，**尚未挂接具体动效**（避免影响换装验收）。
     用途：后续页面交互动画（视图切换 / tab 切换 / 展开折叠 / 弹窗进出场）统一从这里取值，
     视图层禁止自写 duration / easing，否则又会散成一套套。 */
  --anim-dur-1: 120ms;                       /* 微交互：hover / focus / 图标状态 */
  --anim-dur-2: 200ms;                       /* 状态切换：tab、折叠展开、筛选生效 */
  --anim-dur-3: 320ms;                       /* 进入出场：视图切换、弹窗、toast */
  --anim-ease: cubic-bezier(.2, .8, .2, 1);  /* 默认缓动：快起缓收 */
  --anim-ease-in-out: cubic-bezier(.4, 0, .2, 1);
  --anim-shift: 6px;                         /* 轻微位移量（克制，别做大位移） */
  --anim-dur-ambient: 6s;                    /* 环境动效（背景光晕 / 卡片扫光等**循环**动效）；
                                                上面三档是「状态切换」短时长，本档专供氛围类循环动画，
                                                禁止用 ambient 做 hover / tab 切换等交互反馈 */

  /* ⑥ 价格档位卡最小宽（planMask 的 .price-grid 走容器自适应，列数下限由此定）
     —— 按「改前端三条硬规则」第 2 条：新尺度先进 Layer 1，视图层只引用、不写死 px。 */
  --plan-card-min: 168px;
}

/* ---------- 动效层降级开关（2026-10-07 预留；真源见 docs/UI_SPEC.md（已退役→UI-017/018） §八）----------
   三条降级必须全部生效 —— 运营是**高频长时段**操作，动画一旦碍事就成了负担：
     ① 系统级：prefers-reduced-motion: reduce（无障碍 / 晕动症用户）
     ② 用户级：<html data-motion="off">（后续可在主题按钮旁挂一个开关）
     ③ 实现方式：把动效令牌**归零** ⇒ 所有已挂接的动效因 duration=0 立即完成，
        不必逐条改视图代码。所以规则是：动效一律写
        `transition: … var(--anim-dur-2) var(--anim-ease);`，禁止写死 200ms / ease。 */
@media (prefers-reduced-motion: reduce) {
  :root { --anim-dur-1: 0ms; --anim-dur-2: 0ms; --anim-dur-3: 0ms; --anim-dur-ambient: 0s; }
}
html[data-motion="off"] {
  --anim-dur-1: 0ms; --anim-dur-2: 0ms; --anim-dur-3: 0ms; --anim-dur-ambient: 0s;
}

/* ---------- 动效实现（2026-10-07 挂接第一批：低风险三件）----------
   ① 视图切换淡入  ② 内容重渲染淡入（.ui-enter）  ③ 弹窗 / toast 进出场
   三条自我约束（真源见 docs/UI_SPEC.md（已退役→UI-017/018） §八）：
   · 只用 opacity + transform ⇒ 不触发 layout / paint，订单总表 17 列数千行也扛得住；
   · 一律引用 --anim-dur-* 令牌，**禁止写死 ms / ease** ⇒ 降级时归零即自动「立即完成」；
   · ⚠️ 视图是 display:none ↔ block，而 display 不可过渡 ⇒ 用 @keyframes 做「进入动画」，
     不动可见性机制（改动面最小）；代价是没有出场动画 —— 高频后台本来也不需要出场。
   ⚠️ .view 的进入动画**只做 opacity、不做 transform**：给 .view 加 transform 会在动画期间
     创建 containing block，使内部 position:fixed 元素（页内 tooltip 等）改以 .view 为基准定位。
     需要上浮感的场景走 .ui-enter —— 它挂在内层容器上，且这类容器内无 fixed 后代。 */
@keyframes uiFadeIn  { from { opacity: 0; } to { opacity: 1; } }
@keyframes uiRiseIn  { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@keyframes uiToastIn { from { opacity: 0; transform: translate(-50%, -48%) scale(.97); }
                       to   { opacity: 1; transform: translate(-50%, -50%) scale(1); } }

/* ① 视图切换淡入：.active 每次落到新视图都会重放（display 由 none 转 block 时动画自然重置） */
.view.active { animation: uiFadeIn var(--anim-dur-3) var(--anim-ease); }
/* ② 内容淡入：JS 在数据落地后给「重渲染的容器」打一次 .ui-enter（翻页不打，避免高频刷屏） */
.ui-enter { animation: uiRiseIn var(--anim-dur-2) var(--anim-ease); }
/* ③ 弹窗 / toast：遮罩淡入、主体带一点上浮（必须保留 translate(-50%,-50%)，否则会跳位） */
.ui-toast-mask.show { animation: uiFadeIn var(--anim-dur-2) var(--anim-ease); }
.ui-toast.show { animation: uiToastIn var(--anim-dur-3) var(--anim-ease); }
.ops-toast-item { animation: uiRiseIn var(--anim-dur-2) var(--anim-ease); }

/* ---------- 动效第二批（2026-10-07 同批）----------
   ④ 展开类内容淡入：表格行 / SKU 单元格 / 左侧导航分组展开时淡入一次。
      这几处展开都是 `display` 切换（不可过渡）⇒ 同样走 @keyframes 进入动画。
   ⑤ 按下微反馈：active 瞬间缩 3%（不位移、不投影）—— 高频点按也不刺眼。 */
tr.rep-row.expanded td,
td.oo-sku.expanded,
.nav-group:not(.collapsed) .nav-group-body {
  animation: uiFadeIn var(--anim-dur-2) var(--anim-ease);
}
.btn {
  transition: transform var(--anim-dur-1) var(--anim-ease),
              filter var(--anim-dur-1) var(--anim-ease);
}
.btn:active:not(:disabled) { transform: scale(.97); }

/* ---------- Layer 2 · 组件层（8 类公共组件） ---------- */

/* ① 页头 .ui-head —— 收敛 .section-title（14px 纯标题）与 .view-head（17px + 统计）两套。
   结构：<div class="ui-head"><h2 class="ui-title">标题<span class="ui-sub">· 副标题</span></h2>
         <div class="ui-stats">…</div></div> */
.ui-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-4); flex-wrap: wrap; margin: 2px 0 14px;
}
.ui-title { font-size: var(--fs-page); font-weight: 500; margin: 0; }
.ui-sub { font-size: var(--fs-meta); color: var(--muted); font-weight: 400; margin-left: var(--sp-2); }
.ui-stats { font-size: var(--fs-meta); color: var(--muted); }
.ui-stats b { font-size: 16px; font-weight: 500; color: var(--accent); }
.ui-stats .st-warn { color: var(--warn); font-weight: 500; }
.ui-head-actions { display: flex; align-items: center; gap: var(--sp-2); }

/* ② 二级 tab .ui-tabs —— 终点：统一原来 6 套并行实现
   （bus-tabs 13.5px / ops-tabs 14px 页签态 / wh-subtabs 12.5px 胶囊 / 打单员 .seg 连体 /
     系统设置竖排 13.5px / 导出预报 .export-tabs）。
   `.col` 修饰符 = 竖排（原 settings-nav 形态）。
   ★ 2026-10-07 并轨：老类名进同一选择器组 ⇒ 「规则只有一处」，老标记（含 JS 生成的）自动吃到新样式；
     原各套的独立规则已删除，避免后定义者覆盖（CSS 同特异性下后者胜）。 */
.ui-tabs, .ops-tabs, .bus-tabs, .wh-subtabs, .export-tabs {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin: 10px 0 12px; padding-bottom: 8px; border-bottom: 1px solid var(--border);
}
.ui-tabs.col {
  flex-direction: column; align-items: stretch; gap: 2px;
  border-bottom: 0; padding-bottom: 0; margin: 0;
}
.ui-tab, .ops-tab, .bus-tab, .export-tab, .wh-subtabs button {
  background: transparent; border: 1px solid transparent; color: var(--muted);
  padding: 8px 16px; border-radius: var(--ctl-radius-sm); cursor: pointer;
  font-size: var(--fs-sec); font-weight: 500; white-space: nowrap; font-family: inherit;
  transition: background var(--anim-dur-1) var(--anim-ease),
              color var(--anim-dur-1) var(--anim-ease),
              border-color var(--anim-dur-1) var(--anim-ease);
}
.ui-tabs.col .ui-tab, .ui-tabs.col .settings-nav-btn { text-align: left; padding: 10px 14px; width: 100%; }
.ui-tab:hover, .ops-tab:hover, .bus-tab:hover, .export-tab:hover, .wh-subtabs button:hover { background: var(--panel-2); color: var(--text); }
.ui-tab.active, .ops-tab.active, .bus-tab.active, .export-tab.active, .wh-subtabs button.active,
.settings-nav-btn.active {
  background: var(--accent); color: #fff; font-weight: 600; border-color: var(--accent);
  opacity: 1; box-shadow: none;
}
.ui-tab:disabled, .settings-nav-btn:disabled { opacity: .45; cursor: not-allowed; }
.ui-tabs-end { margin-left: auto; }   /* 右侧动作（刷新 / 推送）不参与 tab 组 */

/* ②-b 计数 .ui-count（2026-10-07 新增，同日按用户口径改版）—— tab / chip 里的「数量」。
   ★ 外观：**与按钮文字同字号、同字重**，由 HTML 里的全角括号包住（`未采购订单（130）`）——
     用户反馈独立胶囊徽标「被包裹了感觉不明显」，改为与文字连读的写法。
   ★ 为什么仍保留独立 `<span>` 而不把计数拼进按钮文本：
     JS 只需更新这一点（`badge.textContent = n`），不必重写整个按钮的 textContent；
     配 `tabular-nums` 让数字等宽 —— 计数异步到位时宽度只按位数线性变化，不会因字形抖动换行。 */
.ui-count { font-variant-numeric: tabular-nums; }

/* ③ 工具条 .ui-bar（flex 形态）/ .ui-grid（网格形态）—— 收敛 .toolbar 与 .form-grid
   ★ 2026-10-07 并轨：`.toolbar` 直接进组（含 JS 生成的工具条），`.toolbar` 原 13px/33px 规则已删。 */
.ui-bar, .toolbar { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; margin-bottom: var(--sp-3); }
.ui-grid, .form-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 12px 14px; margin-bottom: var(--sp-3); }
.ui-fld { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.ui-label { font-size: var(--fs-mini); color: var(--muted); white-space: nowrap; }
.ui-fld select, .ui-fld input, .ui-input,
.ui-bar select, .ui-bar input, .toolbar select, .toolbar input,
.form-grid input, .form-grid select {
  height: var(--ctl-h); padding: 0 var(--ctl-pad-x); font-size: var(--ctl-fs);
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--ctl-radius);
  box-sizing: border-box; font-family: inherit;
}
/* ⚠️ 宽度分两种语境，别混：
   · 网格单元格里（.ui-fld / .form-grid）= 撑满单元格；
   · flex 工具条里（.ui-bar / .toolbar）= 按内容宽度。
     2026-10-07 踩坑：早先把 width:100% 写进共用组，结果采购看板的日期框
     在 flex 行里各自撑满一整行 → 工具条被撑成竖排（截图可见）。 */
.ui-fld select, .ui-fld input, .ui-input, .form-grid input, .form-grid select { width: 100%; }
.ui-bar select, .ui-bar input, .toolbar select, .toolbar input { width: auto; min-width: 0; }
.ui-fld select:focus, .ui-fld input:focus, .ui-input:focus,
.ui-bar select:focus, .ui-bar input:focus, .toolbar select:focus, .toolbar input:focus { outline: none; border-color: var(--accent); }
/* 勾选框 / 单选框 / 文件框：**不继承「文本控件」的高度与满宽**。
   ★ 2026-10-07 修复的真实 bug：`.ui-bar input` / `td input` 这类无差别选择器会命中 checkbox，
     把它撑成 `height: 38px; width: 100%` ⇒ 同行文字被挤到下一行（运营看板「含测试数据」
     整块变两行就是这么来的，见 data/ops_filter_measure.py 的 cb_h=38 实测）。
   这里用 `input[type=…]` 把特异性提到 (0,2,1)/(0,1,2)，高于那些无差别规则 ⇒ 无论它们写在
   文件哪个位置都盖不住本条；而 `.proc-banner .sel-all input`、`.stock-sel input` 等
   更高特异性的专用规则仍可正常覆盖。 */
.ui-bar input[type="checkbox"], .ui-bar input[type="radio"], .ui-bar input[type="file"],
.toolbar input[type="checkbox"], .toolbar input[type="radio"], .toolbar input[type="file"],
.ui-fld input[type="checkbox"], .ui-fld input[type="radio"], .ui-fld input[type="file"],
.form-grid input[type="checkbox"], .form-grid input[type="radio"], .form-grid input[type="file"],
td input[type="checkbox"], td input[type="radio"], td input[type="file"],
th input[type="checkbox"], th input[type="radio"], th input[type="file"] {
  width: auto; height: auto; padding: 0; border: 0; background: none;
  border-radius: 0; font-size: inherit; vertical-align: middle; accent-color: var(--accent);
}
.ui-fld.span2 { grid-column: span 2; }
.ui-fld.span3 { grid-column: span 3; }
.ui-grid .ui-fld-actions { flex-direction: row; align-items: flex-end; gap: var(--sp-2); }
/* 工具条 / 网格里的按钮与控件同高同字号 ⇒ 一行对齐（原 .btn 是 7px 12px / 12px，
   与 38px 的输入框并排时参差）。 */
.ui-bar .btn, .toolbar .btn, .ui-grid .btn {
  display: inline-flex; align-items: center; justify-content: center;
  height: var(--ctl-h); padding: 0 var(--sp-4);
  font-size: var(--ctl-fs); border-radius: var(--ctl-radius);
}
.ui-bar .muted { font-size: var(--ctl-fs-sm); }
/* 工具条右侧动作组：推到行尾。
   （原采购看板靠一个空 `<span style="margin-left:auto">` 占位撑开 —— 空元素宽度为 0，
     只在「行内还有富余」时有效；宽度一紧张它就先失效，动作被甩到下一行，是拥挤的帮凶之一） */
.ui-bar-actions { margin-left: auto; display: inline-flex; align-items: center; gap: var(--sp-2); }

/* ④ 卡片 .ui-card —— 收敛 .card / .filter-card / .table-card / .action-bar 的容器外观；
   `.plain` = 无内边距（给表格用，配合 overflow:hidden 收圆角）。 */
.ui-card {
  background: var(--card-bg); border: var(--card-line);
  border-radius: var(--rad-card); padding: 14px;
}
.ui-card.plain { padding: 0; overflow: hidden; margin-top: var(--sp-3); }
.ui-card.plain table { border-radius: 0; background: transparent; }
.ui-card.plain th, .ui-card.plain td { padding: 11px 10px; }
.ui-card.plain th { background: var(--panel-2); }
.ui-card.plain .ui-pager { padding: 10px 12px 2px; margin-top: 0; }

/* ⑤ 按钮 —— 复用既有 .btn（全站 100+ 处引用，不重命名），只补尺寸变体走变量 */
.btn.sm { padding: 5px 10px; font-size: var(--ctl-fs-xs); border-radius: 7px; }
.btn.lg { height: var(--ctl-h); padding: 0 var(--sp-4); font-size: var(--ctl-fs); border-radius: var(--ctl-radius); }

/* ⑥ 分页 .ui-pager —— 终点：统一 .pager / .bus-pager / .export-pager / .na-pager / .packer-pager
   ★ 并轨：老类名进同一组（原各自 margin-top 10/12px、gap 8/10/12px 不一，此处收敛）。 */
.ui-pager, .pager, .bus-pager, .export-pager, .packer-pager, .na-pager {
  display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-3);
  flex-wrap: wrap; font-size: var(--fs-meta); color: var(--muted);
}
.ui-pager.center, .na-pager { justify-content: center; }
/* [2026-10-07 并轨] `.na-pager` 基础样式已并入上方 `.ui-pager` 组，此处删除以免后定义者覆盖
   （仅保留上一行的居中修饰 `.ui-pager.center, .na-pager`）。 */

/* ⑦ 提示条 .ui-note —— 收敛 .notice 与各类提示 banner 的最小公约数（info/warn/danger 三态）
   ★ 并轨：`.notice` 直接进组 ⇒ JS 动态生成的 `<div class="notice">`（约 40 处）**不改标记也统一**。 */
.ui-note, .notice {
  background: var(--panel); border: var(--card-line); border-radius: var(--ctl-radius-sm);
  padding: 10px 12px; margin-bottom: var(--sp-3); color: var(--muted); font-size: var(--fs-meta);
  line-height: 1.6;
}
.ui-note b, .notice b { color: var(--warn); }
.ui-note.warn { background: rgba(239,159,39,.12); border-color: rgba(239,159,39,.5); }
.ui-note.danger { background: rgba(226,75,74,.12); border-color: rgba(226,75,74,.5); color: var(--danger); }

/* ⑧ 筛选胶囊 .ui-chip（2026-10-07 由 .ops-stage-chip 收编）—— 工具条内的「互斥筛选维度」
   （运营看板业务阶段 / 未到仓待办 / 采购积压筛选在用）。
   与 ② .ui-tabs 的分工：.ui-tabs = 切整个列表的**视图**（页头下方独占一行）；
   .ui-chip = 条内的一个**筛选维度**（可与其他筛选并排、可多个共存）。
   计数：老标记写 `<em>`（JS 生成用），新代码建议用 `.ui-count`。
   ★ 2026-10-07 并轨：老类名 `.ops-stage-chip` / `.ops-stage-bar` 进同一选择器组 ⇒ 规则只有一处；
     原独立规则已删除（CSS 同特异性下后定义者胜，留着会盖掉组件层）。 */
.ui-chip-bar, .ops-stage-bar { display: inline-flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.ui-chip, .ops-stage-chip, .na-chip, .na-phase {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px; border-radius: var(--rad-chip); cursor: pointer;
  background: var(--panel); color: var(--muted);
  border: 1px solid var(--border); font-size: var(--fs-sec); line-height: 1;
  font-family: inherit; font-variant-numeric: tabular-nums;
  transition: border-color var(--anim-dur-1) var(--anim-ease),
              color var(--anim-dur-1) var(--anim-ease),
              background var(--anim-dur-1) var(--anim-ease),
              transform var(--anim-dur-1) var(--anim-ease);
}
.ui-chip:active, .ops-stage-chip:active, .na-chip:active, .na-phase:active { transform: scale(.97); }
/* ★ 2026-10-07 字号 12px → 14px（用户口径：「运营看板下那一行字号有点小，在不换行的前提调整」）。
   运营看板「详细订单」阶段条一行 13 个 chip，最窄是**侧栏导航 1440**（内容区 1186px）：
   12px 时 13 个 chip 需 1012px、余 174px —— 只够放大 ~17%。
   ⇒ 放大字号的同时把内边距 5px 10px → 4px 9px、内部间距 6px → 5px（省约 64px），
     14px 下实测约 1061px，余量足够覆盖计数从 3 位涨到 4 位的宽度变化。 */
.ui-chip:hover, .ops-stage-chip:hover, .na-chip:hover, .na-phase:hover { border-color: var(--accent); color: var(--text); }
.ui-chip em, .ops-stage-chip em { font-style: normal; font-weight: 600; color: var(--text); }
.ui-chip.active, .ops-stage-chip.active, .na-chip.active, .na-phase.active { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.ui-chip.active em, .ops-stage-chip.active em { color: #fff; }
.ui-chip.zero, .ops-stage-chip.zero, .na-phase.zero { opacity: .42; }   /* 数量为 0 仍可点（点进去是空表，符合预期） */
.ui-chip.zero.active, .ops-stage-chip.zero.active { opacity: 1; }

* { box-sizing: border-box; }

/* 「hidden 属性失效」兜底（2026-10-04）：
   UA 样式表里的 [hidden]{display:none} 优先级最低，元素**只要自带内联 display**
   （典型就是通屏遮罩的 display:flex），hidden 就会被静默吃掉 —— 表现是面板从页面加载起
   就一直盖在页面上，JS 里再怎么 el.hidden = true 也关不掉（本次「采购单号去向核对」面板
   即此坑）。加这条 !important 把 hidden 的语义恢复成硬保证：带 hidden 的元素一律不可见。 */
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: -apple-system, "Segoe UI", "Microsoft YaHei", sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 13px;
}

header {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 20px;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
}

header h1 { font-size: 15px; margin: 0; font-weight: 500; white-space: nowrap; }
/* 顶栏品牌（2026-10-09 品牌化，BRANDING_PLAN P1-1）：小图标 + 中文名 + 英文小字 */
header h1.brand { display: flex; align-items: center; gap: 8px; font-weight: 600; }
header h1.brand .brand-ico {
  width: 20px; height: 20px; border-radius: 5px; flex: 0 0 auto; display: block;
}
header h1.brand .brand-en {
  font-size: 10.5px; font-weight: 500; letter-spacing: .1em; color: var(--muted);
}

/* ---- header 顶层分组（2026-10-10 重排）----
   原先 header 直接挂了 4 个控件（主题 / 品牌 / 布局切换 / 版本徽标），在左侧栏
   （flex-direction: column）里被拆成一列四行，既占竖向空间、又出现两个「海图」。
   现在分成两组：.brand-row（logo + 品牌名 + 版本角标）与 .hdr-tools（主题 + 布局切换），
   组内横排、组间由 header 的 gap 分隔；顶部模式仍是一整行。 */
.brand-row {
  display: flex; align-items: center; gap: 8px;
  flex: 0 0 auto; min-width: 0;
  flex-wrap: wrap;
}
.hdr-tools { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }

/* 左侧栏：两组都占满栏宽；工具按钮各占一半（原先各占一整行） */
body.nav-left-mode .brand-row { width: 100%; }
body.nav-left-mode .hdr-tools { width: 100%; }
body.nav-left-mode .hdr-tools .theme-btn,
body.nav-left-mode .hdr-tools .layout-toggle { flex: 1 1 0; justify-content: center; }

.tabs { display: flex; gap: 4px; margin-left: auto; min-width: 0; }
.tabs button {
  background: transparent; border: none; color: var(--muted);
  padding: 8px 14px; border-radius: 8px; cursor: pointer; font-size: 14px;
  white-space: nowrap; flex: 0 0 auto;
}
.tabs button.active { background: var(--accent); color: #fff; }
.tabs button:hover:not(.active) { background: var(--panel-2); color: var(--text); }

/* 导航布局切换按钮（2026-10-06 开放式导航：顶部 TAB ⇄ 左侧分组） */
.layout-toggle {
  background: transparent; border: 1px dashed var(--border); color: var(--muted);
  padding: 6px 12px; border-radius: 8px; cursor: pointer; font-size: 13px;
  white-space: nowrap; flex: 0 0 auto;
}
.layout-toggle:hover { border-color: var(--accent); color: var(--accent); }

/* 双布局导航（2026-10-06）：默认顶部模式；body.nav-left-mode = 左侧分组侧栏 */
.nav-top { display: flex; gap: 4px; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.nav-top::-webkit-scrollbar { display: none; }
.nav-left { display: none; }
body.nav-left-mode .nav-top { display: none; }
body.nav-left-mode .nav-left { display: flex; flex-direction: column; }

/* 左侧分组导航（2026-10-06，思路同 feature/1688-selection e71d60d） */
.nav-group { display: flex; flex-direction: column; }
.nav-group-title {
  display: flex; align-items: center; gap: 6px; padding: 7px 8px;
  border-radius: 6px; cursor: pointer; font-weight: 600; font-size: 13px;
  color: var(--muted); user-select: none; white-space: nowrap;
}
.nav-group-title:hover { background: rgba(127,119,221,.20); }
.nav-group-title .ng-arrow { font-size: 10px; transition: transform var(--anim-dur-1) var(--anim-ease); }
.nav-group.collapsed .ng-arrow { transform: rotate(-90deg); }
.nav-group-body { display: flex; flex-direction: column; gap: 2px; padding: 2px 6px 2px; }
.nav-group.collapsed .nav-group-body { display: none; }
.nav-left .nav-group-body button {
  display: flex; align-items: center; gap: 8px; justify-content: flex-start;
  width: 100%; padding: 9px 10px 9px 16px; text-align: left;
  /* ★ 2026-10-06 与顶部 TAB 字号对齐（用户：侧栏字偏小，要和顶部一致）：
     顶部 .tabs button 同为 14px，行高 33→35px，视觉重量两侧拉平。 */
  font-size: 14px;
}
.nav-left .nav-group-body button .nav-ico { font-size: 15px; line-height: 1; flex: 0 0 auto; }
/* 内联 SVG 线性图标（2026-10-06 取代 emoji）：尺寸 / 线宽 / 颜色统一由这里接管，
   stroke 走 currentColor ⇒ 选中时随文字一起变白；fill:none 保证是"线"而不是"块"。 */
.nav-left .nav-group-body button .nav-ico-svg {
  width: 16px; height: 16px; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
/* 侧栏「首页」（2026-10-09）：不属任何业务组，独立置顶、与组内按钮同一视觉规格。
   它不是 .nav-group，所以 .nav-group-body button 那套规则覆盖不到 ⇒ 这里单独对齐。 */
.nav-left > .nav-home {
  display: flex; align-items: center; gap: 8px; justify-content: flex-start;
  width: 100%; padding: 9px 10px; text-align: left;
  /* ★ 2026-10-10 用户要求：「左侧栏下，首页和上边的 logo 区之间的间距再宽一点」。
     上方间距由 header 的 gap(10px) + 这里的 margin-top 共同决定 ⇒ 合计 26px，
     把「品牌区 / 工具区」和业务导航明确分成两块。 */
  margin: 16px 0 10px;
  font-size: 14px; border-bottom: 1px solid var(--border); border-radius: 8px;
}
.nav-left > .nav-home .nav-ico-svg {
  width: 16px; height: 16px; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
body.nav-left-mode .nav-group-body .nav-disabled { opacity: .45; cursor: not-allowed; }

/* 左侧模式整体布局：header 变窄固定侧栏，main 右移 */
body.nav-left-mode header {
  position: fixed; left: 0; top: 0; bottom: 0; z-index: 100;
  width: 214px; flex-direction: column; align-items: stretch;
  gap: 10px; padding: 12px; border-bottom: none;
  border-right: 1px solid var(--border); overflow-y: auto;
}
body.nav-left-mode main { margin-left: 214px; }
body.nav-left-mode .tabs {
  flex-direction: column; margin-left: 0; gap: 2px; flex: 1; min-height: 0; overflow-y: auto;
}
body.nav-left-mode .sync-btn { width: 100%; text-align: center; }
body.nav-left-mode .scope-zone { margin-right: 0; flex-wrap: wrap; }
body.nav-left-mode .scope-zone select { flex: 1; min-width: 0; }

/* 顶栏用户区（F7.15 定稿）：纯圆头像 + 下拉菜单（毛子 ERP 式，无文字/无背景框） */
.user-zone {
  display: flex; align-items: center; gap: 0; margin-left: 6px;
  font-size: 12px; white-space: nowrap;
}
.user-zone .user-name { font-weight: 600; color: var(--accent); }
.user-zone .user-role { color: var(--muted); }
.user-zone .btn {
  background: transparent; border: 1px solid var(--border); color: var(--muted);
  padding: 4px 10px; border-radius: 6px; cursor: pointer; font-size: 12px;
}
.user-zone .btn:hover { border-color: var(--danger); color: var(--danger); }

/* F7.15 顶部功能区（毛子 ERP 式：右侧视图区一条 50px，替代原顶导航横条 + 顶部 TAB） */
.topbar {
  position: fixed; top: 0; left: 214px; right: 0; height: 50px; z-index: 150;
  background: var(--panel); border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 6px; padding: 0 14px;
}
body.nav-left-mode main { margin-left: 214px; padding-top: 66px; }  /* 50px topbar + 16px 原 padding */
.tb-left { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; min-width: 0; }
.tb-crumb { font-size: 14px; font-weight: 600; color: var(--text); white-space: nowrap; }
.tb-mid { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 8px; }
.tb-right { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.tb-btn {
  background: transparent; border: 1px solid var(--border); color: var(--muted);
  padding: 5px 12px; border-radius: 16px; font-size: 12.5px; cursor: pointer;
  white-space: nowrap; position: relative;
}
.tb-btn:hover { border-color: var(--accent); color: var(--accent); }
.tb-vip {
  background: linear-gradient(135deg, #f2c879, #e7b55c); border: none;
  color: #6b4a0a; font-weight: 700;
}
.tb-vip:hover { opacity: .9; color: #6b4a0a; border: none; }
.tb-dot {
  position: absolute; top: 2px; right: 4px; width: 8px; height: 8px;
  background: #e34d3d; border-radius: 50%;
}
.tb-backplat { margin-left: 4px; padding: 4px 10px; font-size: 12px; }
/* F7.15 套餐弹窗：状态小字（价格上边）+ 内嵌全部价格 */
.plan-state-line { font-size: 12.5px; color: var(--muted); margin: 0 0 8px; }
.plan-state-line b { color: var(--text); }
.plan-state-line .plan-days.over { color: var(--danger); }
.plan-panel .price-grid { margin-top: 6px; }
.plan-panel .price-note { font-size: 12px; color: var(--muted); margin: 4px 0 10px; }
/* 吸附按钮下方的下拉（客服 / 公告 · 点击任意位置关闭） */
.tb-pop-wrap { position: relative; display: flex; }
.tb-pop {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 500;
  width: 260px; background: var(--panel); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: 0 8px 28px rgba(0,0,0,.16); padding: 12px;
}
.tb-pop-wide { width: 340px; }
.tb-pop-title { font-size: 14px; font-weight: 600; margin-bottom: 6px; }
.tb-pop-sub { font-size: 12px; color: var(--muted); margin: 0 0 10px; }
.tb-pop .service-qr { width: 180px; height: 180px; display: block; margin: 0 auto; border-radius: 8px; border: 1px solid var(--border); }
.tb-pop .notice-list { max-height: 45vh; overflow-y: auto; font-size: 13px; margin: 0; }
/* 插件下载面板（2026-10-16）：吸附在顶部导航条「插件下载」按钮下方（原居中弹窗已废弃）。
   宽 440 = 两列卡片（180*2 + gap 8）+ padding，卡片不折行；整块紧凑不滚动。 */
/* top 用 12px（比通用 .tb-pop 的 8px 多 4px）：导航条高 50px、按钮容器 bottom≈40，
   8px 时面板上沿落在 48px —— 与导航条还有 2px 重叠。12px ⇒ 面板整块落在导航条下沿之外，
   严格「吸附在导航下方」（面板 z-index 500 > topbar 150，重叠也不遮挡，但口对齐更干净）。 */
.tb-pop-plugin { width: 440px; padding: 10px 11px; top: calc(100% + 12px); }
.plug-cards { display: flex; gap: 8px; flex-wrap: wrap; }
.plug-card {
  flex: 1 1 0; min-width: 180px;
  border: 1px solid var(--border); border-radius: 5px; padding: 4px 7px;
  background: var(--bg, transparent);
}
.plug-install {
  font-size: 10.5px; color: var(--muted); margin-top: 5px; line-height: 1.4;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topbar .sync-btn { width: auto; padding: 5px 12px; border-radius: 16px; }
body.nav-left-mode .topbar .sync-btn { width: auto; }  /* 压过旧侧栏全宽规则（specificity 更高） */
.topbar .theme-btn {
  background: transparent; border: 1px solid var(--border); color: var(--muted);
  padding: 5px 10px; border-radius: 16px; font-size: 12.5px; cursor: pointer;
  display: flex; align-items: center; gap: 4px; white-space: nowrap;
}
.topbar .theme-btn:hover { border-color: var(--accent); color: var(--accent); }
.topbar .scope-zone { margin: 0; }
.topbar .shell-switch { margin: 0; }
/* 客服 / 公告弹窗 */
.service-box .service-qr { width: 200px; height: 200px; display: block; margin: 0 auto 14px; border-radius: 8px; border: 1px solid var(--border); }
.notice-box { width: 380px; }
.notice-list { max-height: 50vh; overflow-y: auto; margin-bottom: 12px; font-size: 13px; }
.notice-item { padding: 10px 4px; border-bottom: 1px solid var(--border); }
.notice-item:last-child { border-bottom: none; }
.notice-item b { display: block; font-size: 13.5px; margin-bottom: 4px; }
.notice-item p { margin: 0; color: var(--muted); font-size: 12.5px; line-height: 1.6; white-space: pre-wrap; }
.notice-item time { display: block; margin-top: 6px; font-size: 11px; color: var(--muted); opacity: .7; }

/* 登录 / 改密遮罩（全屏） */
.auth-mask {
  position: fixed; inset: 0; z-index: 9999; background: rgba(0,0,0,.55);
  display: none; align-items: center; justify-content: center;
}
.auth-mask.show { display: flex; }
/* 独立登录页（2026-10-09）：整屏不透明，盖住底下的应用外壳（旧版是 55% 黑遮罩，
   能看到后面没加载完的看板，像"弹窗"而不像"页面"）。
   ⚠️ 只作用于 #authMask —— #pwdMask（首次登录强制改密）仍需半透明背景。 */
.auth-mask.auth-full {
  background:
    radial-gradient(1100px 620px at 16% 10%, rgba(127, 119, 221, .16), transparent 62%),
    radial-gradient(900px 520px at 88% 92%, rgba(15, 110, 86, .14), transparent 60%),
    var(--bg);
}
.auth-box {
  width: 320px; background: var(--panel); border: 1px solid var(--border);
  border-radius: 12px; padding: 24px; box-shadow: 0 8px 32px rgba(0,0,0,.4);
  max-height: calc(100vh - 40px); overflow-y: auto;   /* F7.15：注册面板行多，窄屏兜底 */
}
.auth-box h2, .code-box h2 { margin: 0 0 6px; font-size: 17px; }
.auth-box .auth-sub, .code-box .auth-sub { margin: 0 0 14px; color: var(--muted); font-size: 12px; }
.auth-box input, .auth-card input, .code-box input {
  width: 100%; box-sizing: border-box; margin: 6px 0; padding: 9px 12px;
  border-radius: 8px; border: 1px solid var(--border); background: var(--panel-2);
  color: var(--text); font-size: 14px;
}
.auth-box input:focus, .auth-card input:focus, .code-box input:focus { outline: none; border-color: var(--accent); }
.auth-remember { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); margin: 0; white-space: nowrap; }
/* F7.15 登录卡：密码下方一行 = 记住我（左）+ 忘记/修改密码（右） */
.auth-row { display: flex; justify-content: space-between; align-items: center; margin: 8px 0 2px; }
.auth-link-btn {
  background: transparent; border: none; color: var(--muted); padding: 2px 0 2px 8px;
  font-size: 11.5px; cursor: pointer; text-decoration: underline;
}
.auth-link-btn:hover { color: var(--accent); }
.auth-err { color: var(--danger); font-size: 12px; min-height: 18px; margin: 4px 0; }
.auth-box .btn, .auth-card .btn, .code-box .btn {
  width: 100%; margin-top: 8px; padding: 10px; border-radius: 8px; border: none;
  background: var(--accent); color: #fff; cursor: pointer; font-size: 14px; font-weight: 600;
}
.code-box .btn:disabled { opacity: .55; cursor: default; }
.auth-box .btn:hover, .auth-card .btn:hover, .code-box .btn:hover { opacity: .9; }

/* ---------- 登录页（2026-10-09 独立双栏版，BRANDING_PLAN.md P0-1） ----------
   左品牌区 + 右登录卡。旧的单卡片 .auth-box 保留（首次登录强制改密弹窗 #pwdMask 仍在用）。
   ⚠️ 品牌区文案只到「产品名 + 业务描述」为止：正式品牌名（海图 SeaChart）与 ICP 备案号
      都等前置条件满足（商标查询 / 备案通过）再加，见 BRANDING_PLAN §六。 */
/* 整屏版（用户 2026-10-09：「登录页太小，做成一整个页面吧，默认进网址之后就是登录页面」）：
   左右两栏**铺满视口**，去掉原先居中卡片的圆角 / 边框 / 阴影与四周留白。
   左栏透明 ⇒ 露出下层 #authFx 的动效（粒子 + 3D 球）；
   右栏实心 var(--panel) ⇒ 表单在动效之上始终保持清晰可读。 */
.auth-split {
  position: relative; z-index: 2;      /* 压住 .auth-fx 画布 */
  display: flex; width: 100%; height: 100%;
}
/* 动效画布：铺满整屏、不接鼠标事件（否则输入框点不动） */
.auth-fx {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; display: block; pointer-events: none;
}
.auth-brand {
  flex: 0 0 56%; min-width: 0; display: flex; flex-direction: column; gap: 18px;
  padding: 56px 52px; border-right: 1px solid var(--border);
}
.auth-brand-top { display: flex; align-items: center; gap: 12px; }
.auth-brand-logo {
  width: 46px; height: 46px; flex: 0 0 auto; border-radius: 13px;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: #fff;
}
.auth-brand-logo svg {
  width: 26px; height: 26px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.auth-brand-name { font-size: 16px; font-weight: 600; }
.auth-brand-en { font-size: 10.5px; letter-spacing: .12em; color: var(--muted); margin-top: 3px; }
.auth-brand-slogan { margin: 10px 0 0; font-size: 30px; line-height: 1.42; font-weight: 700; letter-spacing: .01em; }
.auth-brand-value { margin: 0; font-size: 13px; color: var(--muted); letter-spacing: .01em; line-height: 1.75; max-width: 32em; }
.auth-brand-points {
  list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 9px;
  font-size: 12.5px; color: var(--muted); line-height: 1.5;
}
.auth-brand-points b { color: var(--text); font-weight: 600; }
.auth-brand-foot { margin-top: auto; font-size: 11.5px; color: var(--muted); }
.auth-card {
  flex: 1; min-width: 0; display: flex; flex-direction: column;
  justify-content: center; align-items: center;
  padding: 48px 56px; background: var(--panel);
  position: relative;
}
/* 超宽屏别把输入框拉成一整行：宽度约束移到表单卡片 .auth-card-inner（F7.15+ 由 380→420） */
.auth-card > * { width: 100%; }

/* ---------- F7.15+ 登录页右栏重排（用户 2026-10-12：「右侧登录框布局不合适、有点空」）----------
   问题：右栏是 44% 宽的**实心**面板（1920 下 ~845px），而表单只有 380px 且垂直居中
        ⇒ 四周大片空白、重心孤立，与左栏（品牌 + 3D 粒子球）视觉重量严重失衡。
   三条遵守的边界：
     ① 右栏**保持不透明** —— 「右栏实心 ⇒ 表单始终清晰可读」是 2026-10-09 定下的取舍，不推翻；
     ② 装饰只用**极低对比度**光晕 / 细网格，把空白填成「有呼吸感」，绝不与表单抢注意力；
     ③ **不新增任何功能入口、不引入虚构数据** —— 纯布局 + 视觉。
   结构 = 中段 .auth-card-inner（表单卡片，给表单一个落点）+ 底部 .auth-card-foot（贴底页脚）。 */
/* 装饰强度刻意压到「几乎察觉不到、只把空白填出呼吸感」——首版 .13/.11 + .05 网格在浅色主题下
   明显发灰发粉（实测 1920 浅色截图），故整体降到 .085/.075 与 .030；浅色主题另给一套更弱的值。 */
/* 第二版调优（2026-10-12 复看首版截图）：首版光晕挂在**两角**、强度压到 .085，
   于是「卡片孤零零浮在大片均匀空白里」的观感并没有真正解决。改为：
     · 主光晕**移到卡片正后方**（50% 46%）⇒ 卡片像从光里浮出来，四周空白有了层次；
     · 再补两条极淡的对角光束，把上下的纵向空白也「接住」；
     · 强度仍守 2026-10-09「右栏保持干净、不与表单抢注意力」的底线（≤.10）。 */
.auth-card::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(760px 620px at 50% 46%, rgba(127,119,221,.100), transparent 68%),
    radial-gradient(900px 520px at 50% 108%, rgba(18,136,106,.070), transparent 62%),
    radial-gradient(900px 520px at 50% -8%,  rgba(127,119,221,.055), transparent 62%),
    repeating-linear-gradient(0deg,  rgba(150,150,195,.030) 0 1px, transparent 1px 34px),
    repeating-linear-gradient(90deg, rgba(150,150,195,.030) 0 1px, transparent 1px 34px);
}
html[data-theme="light"] .auth-card::before {
  background:
    radial-gradient(760px 620px at 50% 46%, rgba(91,84,214,.062), transparent 68%),
    radial-gradient(900px 520px at 50% 108%, rgba(15,122,85,.048),  transparent 62%),
    radial-gradient(900px 520px at 50% -8%,  rgba(91,84,214,.035), transparent 62%),
    repeating-linear-gradient(0deg,  rgba(80,85,110,.045) 0 1px, transparent 1px 34px),
    repeating-linear-gradient(90deg, rgba(80,85,110,.045) 0 1px, transparent 1px 34px);
}
.auth-card-inner {
  position: relative; z-index: 1;
  width: 100%; max-width: 460px; box-sizing: border-box;
  padding: 36px 34px 32px; border-radius: 18px;
  background: var(--panel-2); border: 1px solid var(--border);
  box-shadow: 0 24px 64px rgba(0,0,0,.36), 0 0 0 1px rgba(127,119,221,.06), inset 0 1px 0 rgba(255,255,255,.05);
  overflow: hidden;   /* 裁掉顶部扫光的多余部分（扫光会平移出界） */
}
/* 卡片下方一行「真实能力标签」（与左栏 4 条能力同源，只是换个更轻的形式）：
   既补掉卡片下方的纵向空白，又不引入任何虚构数据 / 新功能入口。 */
.auth-tags {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 8px;
  margin-top: 18px;
}
.auth-tags span {
  font-size: 11.5px; color: var(--muted); line-height: 1;
  padding: 6px 12px; border-radius: 999px;
  border: 1px solid var(--border); background: rgba(127,119,221,.06);
}
html[data-theme="light"] .auth-tags span { background: rgba(91,84,214,.055); }
/* 卡片内输入框：卡片与输入框若同用 --panel-2 会「隐身」⇒ 改用 --panel 造出凹陷层次 */
.auth-card-inner input { background: var(--panel); }
/* 顶部一道缓慢扫光（环境动效）：走 --anim-dur-ambient，prefers-reduced-motion 时归零=静止不动 */
@keyframes authSheen {
  0%   { transform: translateX(-130%); opacity: 0; }
  18%  { opacity: 1; }
  46%  { transform: translateX(130%); opacity: 0; }
  100% { transform: translateX(130%); opacity: 0; }
}
.auth-card-inner::after {
  content: ""; position: absolute; top: 0; left: 0; width: 42%; height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  animation: authSheen var(--anim-dur-ambient) var(--anim-ease) infinite;
}
/* 页脚贴底 ⇒ 右栏成为「中段卡片 + 底部页脚」，上下不再空旷 */
.auth-card-foot {
  position: absolute; z-index: 1; left: 0; right: 0; bottom: 26px;
  text-align: center; font-size: 11.5px; color: var(--muted); opacity: .78;
}
/* 备案号（管局法定展示位 · 2026-10-22）：与页脚同色同级，不抢视觉；
   可点（链工信部首页），hover 才给强调色 —— 合规但不像广告。 */
.auth-foot-sep { margin: 0 5px; color: var(--border); }
.auth-icp {
  color: inherit; text-decoration: none; white-space: nowrap;
  border-bottom: 1px dotted var(--border);
  transition: color .15s ease, border-color .15s ease;
}
.auth-icp:hover,
.auth-icp:focus-visible { color: var(--accent); border-bottom-color: var(--accent); }
.auth-card-head { margin-bottom: 14px; }
.auth-card-head h2 { margin: 0 0 6px; font-size: 22px; }
.auth-card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.auth-card-actions { display: flex; align-items: center; gap: 6px; white-space: nowrap; padding-top: 2px; }
.auth-card-sep { color: var(--border); font-size: 12px; }
.auth-card-signup {
  background: transparent; border: none; color: var(--accent); padding: 2px 0;
  font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.auth-card-signup:hover { text-decoration: underline; }
.auth-card .auth-sub { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.6; }
.auth-forget { margin: 14px 0 0; font-size: 11.5px; color: var(--muted); text-align: center; }
/* F7.15 登录卡重排：免费注册 = 卡片右上角文字链接；密码下方一行 = 记住我 + 忘记/修改密码 */
.auth-links {
  margin: 14px 0 0; font-size: 11.5px; color: var(--muted); text-align: center;
  display: flex; justify-content: center; align-items: center;
}
.auth-links button {
  background: transparent; border: none; color: var(--muted); padding: 2px 6px;
  font-size: 11.5px; cursor: pointer; text-decoration: underline;
}
.auth-links button:hover { color: var(--accent); }
.auth-links-dot { color: var(--border); padding: 0 4px; }
/* F7.15 注册面板验证码行 */
.auth-captcha-row { display: flex; gap: 8px; margin: 10px 0 0; align-items: center; }
.auth-captcha-row input { flex: 1; margin: 0; }
.auth-captcha-img {
  width: 96px; height: 34px; border: 1px solid var(--border); border-radius: 8px;
  cursor: pointer; background: #fff; flex: none;
}
/* F7.15 个人中心（邮箱验证 + 改密入口） */
.user-menu-wrap { position: relative; display: flex; align-items: center; gap: 6px; margin-left: 8px; }
.user-avatar {
  width: 30px; height: 30px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--accent); color: #fff; font-size: 13px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center; flex: none;
}
.user-avatar:hover { opacity: .88; }
.user-name { font-size: 13px; color: var(--text); white-space: nowrap; }
.user-menu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 500;
  min-width: 224px; background: var(--panel); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: 0 8px 28px rgba(0,0,0,.16); padding: 6px;
}
.user-menu-head { padding: 10px 12px 8px; border-bottom: 1px solid var(--border); margin-bottom: 4px; }
.um-name { font-size: 13.5px; font-weight: 600; color: var(--text); }
.um-role { font-size: 12px; color: var(--muted); margin-top: 2px; }
.um-email { font-size: 11.5px; color: var(--muted); margin-top: 2px; word-break: break-all; }
.um-item {
  display: block; width: 100%; text-align: left; padding: 8px 12px; border: none;
  background: transparent; border-radius: 6px; font-size: 13px; color: var(--text);
  cursor: pointer;
}
.um-item:hover { background: var(--panel-2); }
.um-danger { color: var(--danger); }
.um-sep { height: 1px; background: var(--border); margin: 4px 2px; }
.pf-row { display: flex; align-items: center; gap: 8px; font-size: 13px; margin: 6px 0; }
.pf-label { color: var(--muted); flex: none; }
.pf-email { flex: 1; word-break: break-all; }
.pf-badge { font-size: 11px; padding: 2px 8px; border-radius: 10px; flex: none; }
.pf-badge.pf-ok { background: rgba(16, 142, 60, .12); color: #108e3c; }
.pf-badge.pf-warn { background: rgba(255, 156, 0, .15); color: #b06f00; }
.pf-verify { margin: 8px 0 4px; padding: 10px; border: 1px dashed var(--border); border-radius: 8px; }
.pf-code-row { display: flex; gap: 8px; margin: 8px 0; }
.pf-code-row input { flex: 1; margin: 0; }
.pf-send-btn { margin: 0 !important; padding: 8px 12px !important; width: auto !important; font-size: 12px !important; }
/* 窄屏（平板 / 手机）：品牌区收成顶部标题条，隐藏大字与要点列表，登录卡占满剩余高度 */
@media (max-width: 820px) {
  .auth-split { height: 100%; flex-direction: column; }
  .auth-brand {
    flex: none; gap: 8px; padding: 18px 22px;
    border-right: none; border-bottom: 1px solid var(--border);
  }
  .auth-brand-slogan { font-size: 18px; }
  .auth-brand-value { font-size: 12px; line-height: 1.6; }
  .auth-brand-points, .auth-brand-foot { display: none; }
  .auth-card { padding: 26px 22px; }
  /* F7.15+ 窄屏：右栏高度有限，页脚改回文档流（继续贴底会与表单卡片重叠） */
  .auth-card-foot { position: static; margin-top: 18px; }
}

/* ---------- 登录页「套餐与价格」弹窗 + 激活码弹窗（2026-10-10） ----------
   样式参考 `data/毛子ERP定价参考.png`（毛子 ERP 的四档定价卡：彩色档名 + 大价格 +
   「开通会员」按钮 + 权益清单），**但改为我们的 5 档**（免费 / 基础 / 标准 / 专业 / 旗舰）。
   ⚠️ 这里展示的一律是**对客 list 价**（`COMMERCIALIZATION_PLAN.md` §三 方案 A）——
      批发 / 渠道价（d = 60% / 50%）**绝不出现在对客界面上**（同文档 §7.11 一）。
   ⚠️ 开通走**激活码**（`§7.11` 的渠道交付形态）⇒ 本弹窗**不含任何支付**。
   ⚠️ 价格是**方案值**，最终以合同为准；改价只改这里 + 后端价目表，不涉及数据迁移。 */
.auth-price-link { margin: 14px 0 0; text-align: center; }
.auth-price-link button {
  background: transparent; border: 1px solid var(--border); color: var(--text);
  padding: 8px 16px; border-radius: 8px; font-size: 12.5px; cursor: pointer;
}
.auth-price-link button:hover { border-color: var(--accent); color: var(--accent); }

.price-mask {
  position: fixed; inset: 0; z-index: 10000; display: none;
  align-items: center; justify-content: center; padding: 24px;
}
.price-mask.show { display: flex; }
.price-mask-bg { position: absolute; inset: 0; background: rgba(0,0,0,.62); }
.price-panel {
  position: relative; z-index: 1; width: 100%; max-width: 1180px;
  max-height: calc(100vh - 48px); display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--border); border-radius: 16px;
  box-shadow: 0 18px 60px rgba(0,0,0,.5); overflow: hidden;
}
.price-head { display: flex; align-items: flex-start; gap: 14px; padding: 20px 24px 14px; }
.price-head h2 { margin: 0; font-size: 19px; }
.price-head p { margin: 5px 0 0; font-size: 12px; color: var(--muted); line-height: 1.6; }
.price-head-fill { flex: 1; }
/* 计费周期切换（月付 / 季付 / 年付，2026-10-10）：点哪个，**下面所有档位的价格与
   折合月价一起切**。月付必须留在里面 —— 否则切走就回不到原价了。 */
.price-cyc {
  display: flex; gap: 2px; padding: 3px; border-radius: 999px; margin-top: 3px;
  background: var(--panel-2); border: 1px solid var(--border);
}
.price-cyc button {
  display: flex; align-items: center; gap: 5px; font-family: inherit;
  border: none; background: transparent; color: var(--muted);
  padding: 5px 12px; border-radius: 999px; font-size: 12.5px; cursor: pointer; white-space: nowrap;
}
.price-cyc button:hover { color: var(--text); }
.price-cyc button.active { background: var(--accent); color: #fff; }
.price-cyc button em {
  font-style: normal; font-size: 10.5px; padding: 1px 5px; border-radius: 999px;
  background: rgba(127,119,221,.18); color: #c9c4f5;
}
.price-cyc button.active em { background: rgba(255,255,255,.2); color: #fff; }
.price-close {
  border: none; background: transparent; color: var(--muted);
  font-size: 22px; line-height: 1; cursor: pointer; padding: 0 2px;
}
.price-close:hover { color: var(--text); }
.price-body { padding: 2px 24px 22px; overflow-y: auto; }
.price-grid { display: grid; grid-template-columns: repeat(5, minmax(0,1fr)); gap: 14px; }
.pc-card {
  position: relative; display: flex; flex-direction: column;
  background: var(--panel-2); border: 1px solid var(--border);
  border-radius: 12px; padding: 18px 16px 16px;
}
.pc-card[data-accent="free"]  { --pc: #9a9ab0; }
.pc-card[data-accent="basic"] { --pc: #1d9e75; }
.pc-card[data-accent="std"]   { --pc: #4f9cf0; }
.pc-card[data-accent="pro"]   { --pc: #ef9f27; }
.pc-card[data-accent="top"]   { --pc: #a99ef0; }
.pc-card.hot { border-color: rgba(79,156,240,.55); }
.pc-badge {
  position: absolute; top: -1px; right: -1px; font-size: 11px; padding: 3px 10px;
  border-radius: 0 12px 0 10px; background: #4f9cf0; color: #fff;
}
.pc-name { font-size: 15px; font-weight: 600; color: var(--pc); }
.pc-for { font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.pc-price { margin: 14px 0 3px; display: flex; align-items: baseline; gap: 4px; }
.pc-price b { font-size: 30px; font-weight: 600; letter-spacing: -.02em; color: var(--text); }
.pc-price span { font-size: 12px; color: var(--muted); }
.pc-cycle { font-size: 11.5px; color: var(--muted); min-height: 17px; }
.pc-cycle s { color: #6b7280; margin-right: 5px; }
.pc-btn {
  width: 100%; margin: 13px 0 14px; padding: 9px; border-radius: 8px; border: none;
  background: var(--accent); color: #fff; font-size: 13px; font-weight: 600; cursor: pointer;
}
.pc-btn:hover { opacity: .9; }
.pc-feat {
  font-size: 11px; color: var(--muted); margin: 0 0 9px; padding-bottom: 7px;
  border-bottom: 1px solid var(--border);
}
.pc-feats {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 7px; font-size: 12px;
}
.pc-feats li { display: flex; justify-content: space-between; gap: 8px; line-height: 1.45; }
.pc-feats li span { color: var(--muted); flex: 0 0 auto; }
.pc-feats li b { font-weight: 600; color: var(--pc); text-align: right; }
.pc-foot { margin: 14px 0 0; font-size: 11.5px; color: var(--muted); line-height: 1.7; }

.code-mask {
  position: fixed; inset: 0; z-index: 10001; display: none;
  align-items: center; justify-content: center; padding: 24px;
}
.code-mask.show { display: flex; }
.code-mask-bg { position: absolute; inset: 0; background: rgba(0,0,0,.6); }
.code-box {
  position: relative; z-index: 1; width: 380px; max-width: 100%; background: var(--panel);
  border: 1px solid var(--border); border-radius: 14px; padding: 22px;
  box-shadow: 0 18px 50px rgba(0,0,0,.5);
}
#codeInput {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  letter-spacing: .1em; text-align: center; font-size: 15px; text-transform: uppercase;
}
.code-note { margin: 10px 0 0; font-size: 11.5px; color: var(--muted); line-height: 1.7; }
.code-note b { color: #ef9f27; font-weight: 600; }

@media (max-width: 1100px) { .price-grid { grid-template-columns: repeat(3, minmax(0,1fr)); } }
@media (max-width: 780px) {
  .price-mask { padding: 12px; }
  .price-panel { max-height: calc(100vh - 24px); }
  .price-head { flex-wrap: wrap; padding: 16px 16px 12px; }
  .price-body { padding: 2px 16px 16px; }
  .price-grid { grid-template-columns: repeat(2, minmax(0,1fr)); gap: 10px; }
}
@media (max-width: 520px) { .price-grid { grid-template-columns: minmax(0,1fr); } }

.sync-btn {
  background: var(--panel-2); color: var(--text); border: 1px solid var(--border);
  padding: 8px 12px; border-radius: 8px; cursor: pointer;
  white-space: nowrap; flex: 0 0 auto;
}
.sync-btn:hover { border-color: var(--accent); }
.sync-status { font-weight: 600; margin-left: 4px; }
.sync-status.ok { color: var(--success); }
.sync-status.err { color: var(--danger); }

/* 版本角标（2026-10-10：由 header 直接子元素**收编进 .brand-row**，不再是独立按钮）
   —— 只显示版本号（v1.0），品牌名由同一行的 logo 承载，避免「海图」在同一行重复两次；
   视觉上弱化为小胶囊，不再与主控件抢注意力。 */
.version-badge {
  padding: 2px 9px; border-radius: 999px; cursor: pointer;
  font-size: 11px; font-weight: 600; line-height: 1.7;
  border: 1px solid rgba(53,138,221,.45); background: rgba(53,138,221,.13); color: var(--accent);
  display: inline-flex; align-items: center; flex: 0 0 auto;
  max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 分支名默认**不显示**（2026-10-09 实测）：顶部 TAB 布局里徽标可用宽度仅 ~110px，
   而「海图 v1.0·开发版」需要 ~127px ⇒ 必被截成省略号（此前只在左侧模式隐藏，
   顶部模式漏了）；左侧 214px 栏同样紧张。
   分支信息改由徽标悬停 title 承载（「点击查看当前版本说明与文档（当前分支：X）」）。
   ⚠️ 要重新显示分支名，只需删掉下面的 display:none —— JS 拼接与限宽省略样式都还在。 */
.version-badge .vb-branch {
  display: none; max-width: 92px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; opacity: .8;
}
.version-badge:hover { background: rgba(53,138,221,.26); }
.version-badge .v-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--success); margin-right: 4px; vertical-align: 1px; }

/* 通用居中弹窗：取代浏览器原生 confirm / alert（原生弹窗固定在浏览器顶部，无法定位） */
.ui-modal { position: fixed; inset: 0; display: none; z-index: 300; }
.ui-modal.show { display: block; }
.ui-modal-mask { position: absolute; inset: 0; background: rgba(0,0,0,.45); }
.ui-modal-box {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(460px, 92vw); max-height: 80vh; display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,.35); overflow: hidden;
}
.ui-modal-head { padding: 14px 16px 0; font-size: 14px; font-weight: 500; }
.ui-modal-body { padding: 10px 16px 16px; font-size: 13px; line-height: 1.75; color: var(--text); white-space: pre-wrap; overflow-y: auto; }
.ui-modal-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--border); background: var(--panel-2); }
.ui-modal-foot .btn { padding: 6px 14px; }
/* 紧凑弹窗变体（2026-10-16 加）：插件下载等**纯展示**弹窗用 ——
   整体高度压到常规版约一半（仅作用于加 .ui-modal-compact 的弹窗，不影响其它弹窗） */
.ui-modal-box.ui-modal-compact { width: min(460px, 92vw); }
.ui-modal-box.ui-modal-compact .ui-modal-head { padding: 6px 12px 0; font-size: 12.5px; }
.ui-modal-box.ui-modal-compact .ui-modal-body { padding: 4px 12px 6px; font-size: 11.5px; line-height: 1.35; }
.ui-modal-box.ui-modal-compact .ui-modal-foot { padding: 4px 12px; }
.ui-modal-box.ui-modal-compact .ui-modal-foot .btn { padding: 2px 10px; font-size: 12px; }

/* 轻量居中提示：取代原生 alert，不阻塞、可点击关闭 */
/* 常驻提示（2026-09-22 改）：原来 4.5s 自动消失太短、长文来不及看完。
   现改为常驻，必须点「确定」或点空白处才关闭；点提示本身不再关闭（避免误触看漏）。 */
.ui-toast-mask { position: fixed; inset: 0; z-index: 399; background: rgba(0,0,0,.38); display: none; }
.ui-toast-mask.show { display: block; }
.ui-toast {
  position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
  z-index: 400; max-width: min(560px, 92vw); padding: 16px 18px 14px; border-radius: 12px;
  background: var(--panel); border: 1px solid var(--border); color: var(--text);
  box-shadow: 0 12px 40px rgba(0,0,0,.35); font-size: 13px; line-height: 1.75;
  display: none; cursor: default; max-height: 80vh; overflow: auto;
}
.ui-toast.show { display: block; }
.ui-toast-msg { white-space: pre-wrap; word-break: break-word; margin-bottom: 14px; }
.ui-toast-ok { width: 100%; justify-content: center; }

/* 巴士推送页 */
.bus-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 10px 0 12px; }
.bus-check { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--muted); }
.bus-counts { margin-left: 14px; color: var(--muted); font-size: 13px; }
.bus-actions { margin-left: auto; display: flex; gap: 10px; align-items: center; }/* [2026-10-07 并轨] 原 `.bus-tabs` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.bus-tabs .bus-tab` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.bus-tabs .bus-tab:hover` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.bus-tabs .bus-tab.active` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 */
/* 推送按钮：醒目色（与 TAB 区分，是动作不是视图） */
.bus-tabs .bus-push-btn {
  margin-left: 12px;
  background: linear-gradient(180deg, #f0a020, #d9871a);
  color: #1a1200; font-weight: 700; border: 1px solid #b8730f;
  box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
.bus-tabs .bus-push-btn:hover { filter: brightness(1.08); }
.bus-tabs .bus-push-btn:disabled { opacity: .55; filter: grayscale(.5); cursor: not-allowed; }
/* 刷新放最后，弱化但不隐藏 */
.bus-tabs #busRefreshBtn { margin-left: auto; }

/* 推送中横幅（2026-09-30 事故修复）：刷新 / 切走再回来也能看到「推送中」，
   避免「以为没推完」→ 二次推送 → 两个任务并行建出重复草稿。 */
.bus-push-banner {
  display: flex; align-items: flex-start; gap: 10px;
  margin: 0 0 12px; padding: 10px 14px; border-radius: 8px;
  background: rgba(240,160,32,.12); border: 1px solid rgba(240,160,32,.55);
  color: var(--text); font-size: 13px; line-height: 1.7;
}
.bus-push-banner[hidden] { display: none; }
.bus-push-banner-text { white-space: pre-line; }
.bus-push-banner-text b { color: #f0a020; }
.bus-push-spin {
  flex: 0 0 auto; width: 14px; height: 14px; margin-top: 3px;
  border: 2px solid rgba(240,160,32,.35); border-top-color: #f0a020;
  border-radius: 50%; animation: bus-push-rot .8s linear infinite;
}
@keyframes bus-push-rot { to { transform: rotate(360deg); } }
.bus-tip {
  font-size: 12.5px; line-height: 1.8; color: var(--muted); background: var(--panel-2);
  border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; margin-bottom: 12px;
}
.bus-tip b { color: var(--text); }
.bus-badge { display: inline-block; padding: 2px 8px; border-radius: 6px; font-size: 12px; font-weight: 600; }
.bus-badge.pending { background: var(--panel-2); color: var(--muted); border: 1px solid var(--border); }
.bus-badge.synced { background: rgba(29,158,117,.18); color: var(--success); border: 1px solid rgba(29,158,117,.55); }
.bus-badge.failed { background: rgba(226,75,74,.16); color: var(--danger); border: 1px solid rgba(226,75,74,.55); }
.bus-badge:not(.pending):not(.synced):not(.failed) { background: var(--panel-2); color: var(--text); border: 1px solid var(--border); }
/* 库存流路径单元格（2026-09-27 修复配套）：巴士库存数 + 真/假流徽标 + 强制假流开关 */
.bus-stock-cell { display: flex; flex-direction: column; gap: 3px; align-items: flex-start; }
.bus-stock-n { font-size: 12px; color: var(--muted); }
.bus-stock-n b { color: var(--text); }
.bus-path { display: inline-block; padding: 1px 7px; border-radius: 6px; font-size: 12px; font-weight: 600; }
.bus-path.real { background: rgba(29,158,117,.18); color: var(--success); border: 1px solid rgba(29,158,117,.55); }
.bus-path.fake { background: rgba(150,150,160,.16); color: var(--muted); border: 1px solid var(--border); }
.bus-force { font-size: 12px; color: var(--muted); display: inline-flex; align-items: center; gap: 3px; cursor: pointer; }
.bus-force input { vertical-align: middle; }
.bus-force-all { font-size: 12px; color: var(--muted); display: inline-flex; align-items: center; gap: 4px; margin-left: 8px; cursor: pointer; }
.bus-force-all input { vertical-align: middle; }
/* 推送目标二选一（2026-10-15 自建打单截留）：label + select 内联，与途径选择器同格 */
.bus-target-wrap { display: inline-flex; align-items: center; gap: 6px; margin-left: 10px; font-size: 12px; color: var(--muted); }
.bus-target-wrap .bus-target-lbl { white-space: nowrap; }
.bus-target-wrap select.bus-sel { min-width: 168px; }
/* 「偏新」提示（2026-09-26）：距下单 <9h 的单关联易失败 → 黄色小标，非阻断 */
.bus-fresh {
  display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 6px;
  font-size: 11px; font-weight: 600; cursor: help; white-space: nowrap;
  background: rgba(224,164,25,.18); color: #d9a026; border: 1px solid rgba(224,164,25,.55);
}
.bus-sel, .bus-inp { padding: 5px 8px; border-radius: 6px; border: 1px solid var(--border); background: var(--panel); color: var(--text); font-size: 13px; }
.bus-inp { min-width: 210px; }
.bus-sep { width: 1px; height: 20px; background: var(--border); margin: 0 2px; }/* [2026-10-07 并轨] 原 `.bus-pager` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 */
.bus-pager .btn[disabled] { opacity: .45; cursor: not-allowed; }

main { padding: 16px 20px; }

.view { display: none; }
.view.active { display: block; }
/* [2026-10-07 并轨] 原 `.toolbar { … }` 与 `.toolbar select, .toolbar input { … }` 两条规则
   已并入文件顶部 Layer 2 组件层（`.ui-bar, .toolbar` 组），此处删除以免后定义者覆盖。 */
.toolbar input[type="text"] { min-width: 180px; }

/* ---------- 页面骨架：页头 / 筛选卡 / 操作条 / 表格卡（2026-10-06 订单总表试点）----------
   背景：原订单总表把 17 个控件平铺在 .toolbar 里（筛选 + 批量操作混在一起、无层级），
   字号又有 12/12.5/13/13.5 四种混用 → "小、杂、不搭"。
   本套为四段式：页头(标题+统计) → 筛选卡(网格对齐) → 操作条(批量动作) → 表格卡。
   ⚠️ 只作用于订单总表；其他视图的 .toolbar 一律不动（避免跨视图回归）。
   ★ 2026-10-07：--ctl-* 已迁并到文件顶部 Layer 1 变量层（尺度唯一真源），此处不再重复定义。
   本块待换装时整体并入 Layer 2 组件层（.view-head → .ui-head、.filter-card → .ui-card、
   .action-bar → .ui-bar、.table-card → .ui-card.plain），见 docs/UI_SPEC.md（已退役→UI-017/018）。 */
.view-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin: 2px 0 14px;
}
.view-title { font-size: 17px; font-weight: 500; margin: 0; }
.view-stats { font-size: 12px; color: var(--muted); }
.view-stats b { font-size: 16px; font-weight: 500; color: var(--accent); }
.view-stats .st-warn { color: var(--warn); font-weight: 500; }

.filter-card {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 12px; padding: 14px;
}
.filter-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 12px 14px; }
.filter-grid .fld { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.filter-grid .fld > span.fld-label { font-size: 11px; color: var(--muted); white-space: nowrap; }
.filter-grid .fld select,
.filter-grid .fld input {
  height: var(--ctl-h); padding: 0 12px; font-size: var(--ctl-fs);
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--ctl-radius);
  box-sizing: border-box; width: 100%; font-family: inherit;
}
.filter-grid .fld select:focus,
.filter-grid .fld input:focus { outline: none; border-color: var(--accent); }
.filter-grid .fld-search { grid-column: span 3; }
.filter-grid .fld-daterange { grid-column: span 2; }
.filter-grid .fld-chip .btn { height: var(--ctl-h); width: 100%; font-size: 13px; }
/* 筛选 chip 激活态（原先只 toggle 了 class、没有样式 → 开着筛查看不出区别） */
#fStaleMark.active { background: var(--accent) !important; border-color: var(--accent) !important; color: #fff !important; }
.filter-grid .inp-ico { position: relative; display: block; }
.filter-grid .inp-ico svg {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  color: var(--muted); pointer-events: none;
}
.filter-grid .inp-ico input { padding-left: 34px; }
.filter-grid .fld-btns { flex-direction: row; align-items: flex-end; gap: 8px; }
.filter-grid .fld-btns .btn { height: var(--ctl-h); padding: 0 16px; font-size: var(--ctl-fs); }
.filter-grid .fld-reset { justify-self: end; align-self: end; }
.filter-grid .drange { display: flex; align-items: center; gap: 6px; }
.filter-grid .drange input { flex: 1 1 0; min-width: 0; }
.filter-grid .drange i { font-style: normal; font-size: 12px; color: var(--muted); flex: 0 0 auto; }

.action-bar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 12px; padding: 10px 14px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
}
.action-bar .sel-count { font-size: 12px; color: var(--muted); white-space: nowrap; }
.action-bar .sel-count b { color: var(--accent); font-size: 14px; font-weight: 500; }
.action-bar .sep { width: 1px; height: 20px; background: var(--border); flex: 0 0 auto; }
.action-bar .spacer { margin-left: auto; }
.action-bar .btn { padding: 8px 13px; font-size: 13px; white-space: nowrap; }
.btn-danger-ghost { border-color: rgba(226,75,74,.5) !important; color: var(--danger) !important; }
.btn-danger-ghost:hover { background: rgba(226,75,74,.14) !important; }
/* 操作条视觉顺序（用 order 重排、不动 DOM，避免搬动超长 title 出错）：
   左＝视图开关；右＝批量动作；最右＝危险动作（红色）。 */
.action-bar .sel-count { order: 1; }
.action-bar .sep { order: 2; }
.action-bar #fExpandAll { order: 3; }
.action-bar .spacer { order: 10; }
.action-bar #batchHistBtn { order: 20; }
.action-bar #batchClearStockMark { order: 21; }
.action-bar #batchPackRefresh { order: 22; }
.action-bar #batchUndoNoshipBtn { order: 90; }
.action-bar #batchNoshipBtn { order: 91; }

.table-card {
  border: 1px solid var(--border); border-radius: 12px; overflow: hidden;
  background: var(--panel); margin-top: 12px;
}
.table-card table { border-radius: 0; background: transparent; }
.table-card th, .table-card td { padding: 11px 10px; }
.table-card th { background: var(--panel-2); }
.table-card .pager { padding: 10px 12px 2px; }

table { width: 100%; border-collapse: collapse; background: var(--panel); border-radius: 10px; overflow: hidden; }
th, td { padding: 9px 10px; text-align: left; border-bottom: 1px solid var(--border); }
th { background: var(--panel-2); color: var(--muted); font-weight: 500; font-size: 12px; }
td input, td select {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px; padding: 5px 7px; font-size: 12px;
  width: 100%;
}
tr:hover td { background: var(--panel-2); }

.badge {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; background: var(--panel-2); color: var(--muted);
}
.badge.merge { background: rgba(239,159,39,.18); color: var(--warn); }
.badge.done { background: rgba(29,158,117,.18); color: var(--success); }
.badge.todo { background: rgba(226,75,74,.18); color: var(--danger); }

/* 订单总表采购状态：醒目颜色区分 */
select.cPurchase.st-done { background: rgba(29,158,117,.22); color: var(--success); border-color: var(--success); font-weight: 600; }
select.cPurchase.st-todo { background: rgba(226,75,74,.16); color: var(--danger); border-color: var(--danger); }
select.cPurchase.st-hist { background: rgba(154,154,176,.18); color: var(--muted); border-color: var(--muted); }
select.cPurchase.st-noship { background: rgba(226,75,74,.28); color: var(--danger); border-color: var(--danger); font-weight: 600; }

/* 发货状态标签（由 Ozon 状态自动映射，只读） */
.ship-badge { display: inline-block; padding: 2px 8px; border-radius: 6px; font-size: 12px; font-weight: 600; }
.ship-badge.shipped { background: rgba(29,158,117,.20); color: var(--success); }
.ship-badge.pending { background: rgba(239,159,39,.18); color: var(--warn); }
.ship-badge.cancelled { background: rgba(154,154,176,.18); color: var(--muted); }
.ship-badge.empty { background: var(--panel-2); color: var(--muted); }

a { color: var(--accent); }

.card {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 10px; padding: 12px 14px; margin-bottom: 10px;
}
.card .row { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.card .meta { color: var(--muted); font-size: 12px; margin-top: 6px; }
.card .actions { display: flex; gap: 8px; }

.btn {
  background: var(--accent); color: #fff; border: none; border-radius: 8px;
  padding: 7px 12px; cursor: pointer; font-size: 12px;
}
.btn.ghost { background: var(--panel-2); color: var(--text); border: 1px solid var(--border); }
.btn:hover { filter: brightness(1.1); }

/* 采购看板：五区块横排（①图片+②SKU信息 并为一个 / ③数量 / ④采购·含逐SKU本次采购表 / ⑤操作）
   + ⑥合并订单（横跨整行）。
   2026-09-25 改版：grid 四列 → flex + wrap（区块各自成块、窄屏不溢出）；
   数量胶囊从②拆出独立成块并放大（「一眼看出还要买多少」）；
   「本次采购」逐 SKU 表由独立区块**并入④采购块**，全块统一外观（「统一一个风格」）。
   align-items: stretch —— 同一行内各块**等高**（不随内容长短参差；用户要求视觉一致）；
   各块 min-width/basis 已收紧，1280px 级窗口即不换行。 */
.proc-card { display: flex; flex-direction: column; gap: 10px; }
.proc-body { display: flex; flex-wrap: wrap; gap: 12px; align-items: stretch; }
/* ①+② 主信息区块：**图片 + SKU 信息 包成一个区块**（与右侧三个区块同风格、同高）。
   2026-09-25 用户要求：左侧这两块不再裸放在卡片上，收进一个背景块里统一。 */
.proc-main {
  flex: 1 1 360px; min-width: 300px;
  display: flex; gap: 12px; align-items: flex-start;
  padding: 10px 12px; background: var(--panel-2); border-radius: 8px;
  /* 备注块（①b）作为第二个整行子项排进来 → 必须允许换行 */
  flex-wrap: wrap;
}
/* ①b 卡片级备注（2026-09-28 用户需求，第四轮定稿）：放进第一区块的**图片下方**（`.proc-left` 列内）。
   用户口径（第三轮）：「不要默认就摊着一个输入框 —— 平时只显示备注文字 + 一个小笔图标，
   点小笔才出现输入框，写完点别处即保存并收回成一个只读文字」。
   用户口径（第四轮）：「不要外边框，文字再大点，红色或者其它和主题相配的颜色」⇒
   去掉琥珀色描边盒子，只留**两行纯文字**：第一行「备注」，第二行 备注正文 + 小笔；
   正文用 `--note-ink`（暖红，深浅两套主题各自配好），加粗放大到 15px，扫一眼就跳出来。
   ⇒ 两态一套 DOM：`.pn-view`（只读：正文 + 铅笔）/ `.editing`（切出 input），靠 class 切换，不重建节点。 */
.proc-note-block {
  display: flex; flex-direction: column; gap: 1px;
  width: 132px; box-sizing: border-box;
  padding: 0; background: none; border: none;   /* 第四轮：无外边框、无底色 */
}
.proc-note-block .pn-tag {
  font-size: 10px; font-weight: 700; letter-spacing: .6px;
  color: var(--note-ink); opacity: .8; line-height: 1.25;
}
/* 只读行：整行可点（点正文或点笔都进编辑），笔平时半透明、悬停才实心 */
.proc-note-block .pn-view {
  display: flex; align-items: center; gap: 4px; min-height: 20px; cursor: text;
}
.proc-note-block .pn-view:hover .pn-edit { opacity: 1; }
.proc-note-block .pn-text {
  flex: 1 1 auto; min-width: 0;
  font-size: 15px; font-weight: 700; line-height: 1.3; letter-spacing: .2px;
  color: var(--note-ink); word-break: break-word;
}
.proc-note-block .pn-text:empty { display: none; }   /* 没备注 → 只剩标签 + 笔，不占出空行 */
.proc-note-block .pn-edit {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; padding: 0; cursor: pointer;
  color: var(--note-ink); background: none; border: none;
  opacity: .55; transition: opacity var(--anim-dur-1) var(--anim-ease);
}
.proc-note-block .pn-edit:hover { opacity: 1; }
.proc-note-block .pn-edit svg { display: block; }
/* 两态互斥：只读行 / 输入框，永远只出现一个 */
.proc-note-block.editing .pn-view { display: none; }
.proc-note-input { display: none; }
.proc-note-block.editing .proc-note-input { display: block; }
.proc-note-input {
  width: 100%; box-sizing: border-box; padding: 3px 5px;
  font-size: 14px; line-height: 1.35; font-family: inherit; font-weight: 600;
  color: var(--note-ink); background: rgba(226, 75, 74, .1);
  border: 1px solid var(--note-ink); border-radius: 5px;
}
.proc-note-input::placeholder { color: var(--muted); font-weight: 400; font-size: 12px; }
.proc-note-input:focus { outline: none; box-shadow: 0 0 0 2px rgba(226, 75, 74, .28); }
/* 改过还没保存 → 换成主题色描边，明确「有未保存的改动」 */
.proc-note-input.dirty { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(127, 119, 221, .26); }
.proc-note-hint { font-size: 10px; line-height: 1.2; min-height: 12px; color: var(--success); }
.proc-note-hint.err { color: var(--danger); }
/* ★ 2026-10-03 批次锚定：写下这条备注时那批单**已全部离开本卡** → 降级为「历史备注」。
   不隐藏（信息不丢，采购可能还要照着看），只降权：标签与正文转灰、正文缩小到不抢眼，
   右侧多一个「清空」把旧备注收掉；改写一次即恢复有效态（后端保存时刷新批次锚点）。 */
.proc-note-block.stale .pn-tag { color: var(--muted); opacity: .95; }
.proc-note-block.stale .pn-text { font-size: 12px; font-weight: 400; color: var(--muted); }
.proc-note-block.stale .pn-edit { color: var(--muted); }
.proc-note-block.stale .proc-note-input { color: var(--muted); border-color: var(--border); }
.proc-note-block .pn-clear {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px; padding: 0; cursor: pointer; line-height: 1;
  font-size: 13px; color: var(--muted); background: none; border: none;
  opacity: .7; transition: opacity var(--anim-dur-1) var(--anim-ease);
}
.proc-note-block .pn-clear:hover { opacity: 1; color: var(--danger); }
/* ① 图片（规格已移到②区块） */
.proc-left { flex: 0 0 132px; position: relative; display: flex; flex-direction: column; gap: 6px; }
.proc-thumb {
  width: 132px; height: 132px; border-radius: 8px; border: 1px dashed var(--border);
  background: var(--panel-2); display: flex; align-items: center; justify-content: center;
  overflow: hidden; color: var(--muted); font-size: 11px; text-align: center; line-height: 1.3;
}
.proc-thumb img { width: 100%; height: 100%; object-fit: cover; border-radius: 7px; display: block; }
.proc-thumb a { display: block; width: 100%; height: 100%; }
/* hover 看原图浮层（浮于卡片右侧，不挤动布局、不溢出图片框） */
.thumb-zoom {
  position: absolute; left: 100%; top: 0; margin-left: 10px; width: 300px; max-height: 420px;
  overflow: hidden; border-radius: 10px; border: 1px solid var(--border);
  box-shadow: 0 8px 30px rgba(0,0,0,.4); background: var(--panel-2); display: none; z-index: 100;
}
.proc-left:hover .thumb-zoom { display: block; }
.thumb-zoom img { width: 100%; height: auto; border-radius: 0; display: block; }
/* 规格描述（在②区块显示） */
.proc-desc { font-size: 12px; color: var(--accent); font-weight: 500; line-height: 1.5; overflow-wrap: anywhere; margin-top: 4px; }
.proc-desc .desc-label { display: inline; font-size: 10px; color: var(--muted); font-weight: 400; margin-right: 4px; }
/* 运营备注回传（2026-09-24 需求）：运营在「详细订单」填的备注会随规格推给巴士，
   同时贴到采购卡片的规格后面，提醒采购「这个品的规格/发货方式有变动，打包前先核对」。
   用琥珀虚线胶囊，与紫色规格文本区分开，一眼能注意到。 */
.proc-order-notes { display: inline-flex; flex-wrap: wrap; gap: 5px; align-items: center; margin-left: 8px; vertical-align: middle; }
.proc-order-notes em { font-style: normal; font-size: 10px; color: var(--muted); font-weight: 400; }
.proc-note-tip {
  display: inline-block; padding: 1px 7px; border-radius: 999px;
  background: rgba(239,159,39,.16); color: var(--warn); border: 1px dashed rgba(239,159,39,.6);
  font-size: 11px; font-weight: 600; line-height: 1.5;
  max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* ② SKU 信息 */
.proc-info { flex: 1 1 240px; min-width: 200px; }
.proc-sku { font-size: 15px; font-weight: 600; overflow-wrap: anywhere; }
.proc-meta { color: var(--muted); font-size: 12px; margin-top: 4px; }
.proc-progress { margin-top: 4px; font-size: 12px; color: #b45309; background: #fef3c7; border: 1px solid #fcd34d; border-radius: 6px; padding: 2px 8px; display: inline-block; }
/* 来源平台徽标（分平台采购时直观区分） */
.src-badge { display: inline-block; padding: 2px 8px; border-radius: 6px; font-size: 12px; font-weight: 600; }
.src-1688 { background: rgba(45,132,226,.16); color: #2d84e2; border: 1px solid rgba(45,132,226,.5); }
.src-pdd { background: rgba(226,75,74,.16); color: #e24b4a; border: 1px solid rgba(226,75,74,.5); }
.src-taobao { background: rgba(239,159,39,.18); color: #d9822b; border: 1px solid rgba(239,159,39,.55); }
.src-empty { background: var(--panel-2); color: var(--muted); border: 1px solid var(--border); }
/* ③ 数量区块（胶囊体独立成块、数量放大；2026-09-25 用户要求） */
.proc-nums-block {
  flex: 0 1 170px; min-width: 150px;
  display: flex; flex-direction: column; gap: 6px;
  padding: 10px 12px; background: var(--panel-2); border-radius: 8px;
}
.proc-nums-empty { font-size: 12px; color: var(--muted); line-height: 1.5; }
/* 「本次采购」逐 SKU 明细表（2026-09-25 三次调整：不再单独成块，**并入 ⑤采购区块** 内）。
   结构：表头一行 + 每 SKU 一行，均为同一套 grid —— SKU 名 / 本次采购数 / 采购价。
   三列宽度固定（SKU 自适应、后两列定宽）→ 两列输入框**天然等长**且与表头严格对齐。 */
.proc-buy-table { display: flex; flex-direction: column; gap: 5px; margin-top: 2px; }
.buy-head, .buy-row {
  display: grid; grid-template-columns: minmax(0, 1fr) 62px 78px 86px;
  gap: 5px 6px; align-items: center;
}
.buy-head { padding-bottom: 2px; border-bottom: 1px dashed var(--border); }
.buy-th { font-size: 10.5px; color: var(--muted); white-space: nowrap; text-align: center; }
.buy-th:first-child { text-align: left; }
/* 采购单价（2026-09-30）：合计采购价 ÷ 数量自动算出，只读对照参考价 */
.buy-row-unit {
  display: inline-block; width: 100%; min-width: 0; text-align: center;
  font-size: 12.5px; font-weight: 700; color: var(--accent);
  padding: 4px 4px; white-space: nowrap;
}
/* 行数多时区块内滚动，避免采购块无限增高把同排其他区块一起撑高 */
.buy-rows { display: flex; flex-direction: column; gap: 5px; max-height: 148px; overflow-y: auto; }
.buy-sku {
  font-family: ui-monospace, Consolas, "Courier New", monospace;
  font-size: 11.5px; font-weight: 700; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.buy-row input {
  width: 100%; min-width: 0;
  background: var(--bg); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 4px 6px; font-size: 14px; font-weight: 700; text-align: center;
}
.buy-row input.skuFillQty { color: #f0b429; }
.buy-row input:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(127,119,221,.22); }
.buy-row input.err { border-color: var(--danger); box-shadow: 0 0 0 2px rgba(226,75,74,.18); }
/* ④ 采购区块（2026-09-25 三次调整：**并入「本次采购」逐 SKU 输入表**）。
   与其余区块**完全同一套外观**（同底色/圆角/内边距，无差别描边）——用户要求「统一一个风格」。
   内部收紧：标题 → 单号/快递/货源（紧凑 label 行）→ 逐 SKU 采购表 → 链接行 → 完成采购。 */
.proc-fill {
  flex: 0 1 360px; min-width: 320px;
  display: flex; flex-direction: column; gap: 6px;
  padding: 10px 12px; background: var(--panel-2); border-radius: 8px;
}
.proc-fill-title { font-size: 11px; color: var(--muted); font-weight: 600; letter-spacing: .3px; padding-bottom: 2px; border-bottom: 1px dashed var(--border); }
.proc-fill label { display: flex; align-items: center; justify-content: space-between; gap: 10px; color: var(--muted); font-size: 12px; white-space: nowrap; }
/* 只作用于采购块自己的 label 行；逐 SKU 表的输入框不受影响（避免 flex:1 污染） */
.proc-fill > label input, .proc-fill > label select {
  flex: 1; max-width: 168px; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px; padding: 5px 8px; font-size: 12px;
}
/* 采购链接 + 备用货源：一行两个等宽按钮（在采购区块内、完成采购按钮上方） */
.proc-link-row { display: flex; gap: 8px; }
.proc-link-row > * { flex: 1 1 0; min-width: 0; }
/* 等高拉伸后块内留白统一收在中段：采购块「完成采购」、操作块按钮组各自贴底，
   与③数量块（.proc-flow-nums 均匀铺满）视觉节奏一致，不留底部参差空档。 */
.proc-fill > .markBtn { margin-top: auto; }
/* ⑤ 操作区块：**只放操作按钮**（2026-09-25 用户口径：顶部那排彩色业务标签整排移除，
   信息在③数量块 / ④采购块 / ⑥合并订单块 / ②块 SKU 明细行里都已可见，不再重复）。
   按钮改为**整列等宽**（align-items:stretch）——与④采购块的整宽「完成采购」同风格；
   按钮组 flex:1 + justify-content:space-evenly —— 区块被拉高时按钮均匀铺开、不留中间大空档。
   按钮少（3 个）时不会浮成孤岛，按钮多（含撤销类，最多 6~7 个）时也不会溢出。 */
.proc-ops-block {
  flex: 0 1 240px; min-width: 208px;
  display: flex; flex-direction: column; gap: 8px;
  padding: 10px 12px; background: var(--panel-2); border-radius: 8px;
}
.proc-ops-btns {
  display: flex; flex-direction: column; align-items: stretch; gap: 8px;
  flex: 1 1 auto; justify-content: space-evenly;
}
.proc-ops-btns .btn { text-align: center; white-space: nowrap; }
.btn-hint { display: inline-flex; align-items: center; gap: 4px; padding: 9px 12px; border-radius: 9px; font-size: 13px; font-weight: 500; background: var(--panel-2); color: var(--muted); border: 1px dashed var(--border); cursor: help; }
/* 大标签（big-tag）系列：2026-09-25 起采购卡片⑤操作块的标签行已整排移除，
   下面这套样式目前**已无调用方**（保留以备其他视图复用；确认不再需要时可整段删除）。 */
.big-tag {
  display: block; padding: 9px 12px; border-radius: 9px; text-align: center;
  font-size: 13px; font-weight: 600; line-height: 1.2;
}
.big-tag.merge { background: rgba(239,159,39,.2); color: var(--warn); border: 1px solid rgba(239,159,39,.55); }
.big-tag.done { background: rgba(29,158,117,.2); color: var(--success); border: 1px solid rgba(29,158,117,.55); }
.big-tag.todo { background: rgba(226,75,74,.2); color: var(--danger); border: 1px solid rgba(226,75,74,.55); }
.big-tag.transit { background: rgba(127,119,221,.22); color: var(--accent); border: 1px solid rgba(127,119,221,.6); }
.big-tag.overflow { background: rgba(239,159,39,.2); color: var(--warn); border: 1px solid rgba(239,159,39,.6); }
.big-tag.stock-tentative { background: rgba(239,159,39,.18); color: var(--warn); border: 1px dashed rgba(239,159,39,.7); }
.big-tag.stock-confirmed { background: rgba(29,158,117,.2); color: var(--success); border: 1px solid rgba(29,158,117,.55); }
/* 库存标记原因（如「随便发其他货物」）：紫色描边与常规库存标记区分 */
.big-tag.stock-reason { background: rgba(127,119,221,.18); color: var(--accent); border: 1px solid rgba(127,119,221,.6); }
/* 混合品分区状态：采购部分 / 库存部分 各自显示「未完成(红) / 已完成(绿)」 */
.big-tag.mixed-part.part-todo { background: rgba(226,75,74,.16); color: var(--danger); border: 1px solid rgba(226,75,74,.55); }
.big-tag.mixed-part.part-done { background: rgba(29,158,117,.18); color: var(--success); border: 1px solid rgba(29,158,117,.55); }
/* 跨侧提示：同一品在另一侧视图还有件数（中性灰蓝，仅提示、非状态） */
.big-tag.cross { background: rgba(140,150,170,.16); color: var(--muted); border: 1px dashed rgba(140,150,170,.6); }
.btn.stock-confirm { background: var(--success); font-size: 13px; }
.btn-link {
  display: block; text-align: center; background: var(--accent); color: #fff;
  padding: 9px 12px; border-radius: 9px; text-decoration: none; font-size: 13px; font-weight: 500;
}
.btn-link:hover { filter: brightness(1.1); }
.btn-link.disabled { background: var(--panel-2); color: var(--muted); pointer-events: none; }
.btn-link.alt { background: var(--panel-2); color: var(--text); border: 1px solid var(--border); }
.btn-link.alt:hover { border-color: var(--accent); filter: none; }
.badge.multisku { background: rgba(127,119,221,.2); color: var(--accent); }
.badge.same-link { background: rgba(245,166,35,.2); color: #d98a00; border: 1px solid rgba(245,166,35,.5); }
.badge.incomplete { background: rgba(226,75,74,.22); color: var(--danger); border: 1px solid rgba(226,75,74,.5); }
.badge.complete { background: rgba(29,158,117,.18); color: var(--success); }
tr.row-incomplete td { background: rgba(226,75,74,.07); }
tr.row-incomplete td:first-child { border-left: 3px solid var(--danger); }
.btn.success { background: var(--success); }
.btn.mark { background: var(--accent); font-size: 13px; }
.btn.mark.done { background: var(--success); }

/* ⑥ 合并订单区块（横跨整行，罗列同品合并的订单） */
.proc-orders { flex: 1 1 100%; border-top: 1px dashed var(--border); padding-top: 8px; }
.proc-orders-title { font-size: 11px; color: var(--muted); font-weight: 500; margin-bottom: 6px; }
.proc-orders-list { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
/* 同链接多 SKU 合并条目：结构化 SKU 明细列表（规格跟随 SKU，深色主题适配） */
.proc-sku-detail { margin-top: 8px; border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; background: rgba(127,119,221,.06); }
.proc-sku-detail-title { font-size: 11px; color: var(--muted); font-weight: 600; margin-bottom: 6px; letter-spacing: .3px; }
.sku-detail-row { display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: 6px; background: var(--panel-2); margin-bottom: 4px; }
.sku-detail-row:last-child { margin-bottom: 0; }
.sku-detail-img { width: 30px; height: 30px; flex-shrink: 0; border-radius: 4px; overflow: hidden; background: var(--panel); display: flex; align-items: center; justify-content: center; }
.sku-detail-img img { width: 100%; height: 100%; object-fit: cover; }
.sku-detail-main { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.sku-detail-sku { font-weight: 600; font-size: 12px; font-family: ui-monospace, Consolas, "Courier New", monospace; color: var(--text); }
.sku-detail-spec { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 240px; }
.sku-detail-spec.none { opacity: .6; }
.sku-detail-qty-block { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.sku-detail-qty { font-size: 12px; font-weight: 600; color: var(--warn); }
.sku-detail-qty b { font-size: 14px; }
.sku-detail-transit { font-size: 11px; color: var(--accent); display: block; margin-top: 2px; }
.sku-detail-overflow { font-size: 11px; color: var(--warn); display: block; margin-top: 1px; }
.sku-detail-purchased { font-size: 11px; color: var(--success); }
/* 仓库现有库存（选品源维护）：原来只在 ⑤操作块的「库存 N 件」大标签里显示，
   标签整排移除后挪到 SKU 明细行内（信息不丢、也不占版面）。 */
.sku-detail-stock { font-size: 11px; color: #58a6e8; }
.sku-detail-cnt { font-size: 11px; color: var(--muted); }
/* 逐 SKU 明细：店铺归属提示 + 「明细 N 笔」按钮（复用 .order-more 的弹窗逻辑） */
.sku-detail-stores { font-size: 10.5px; color: var(--muted); max-width: 240px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; opacity: .85; }
.sku-detail-more { padding: 2px 8px; font-size: 11px; flex-shrink: 0; }
/* 逐 SKU「本次采购数/采购价」输入框已并入 ④采购区块内的 .proc-buy-table（见上），
   原 .sku-detail-fill / .sku-detail-row input 相关样式已废弃（该行现只剩图片 + 信息 + 数量）。 */
.order-chip {
  display: inline-block; padding: 3px 8px; border-radius: 6px; font-size: 12px;
  background: var(--panel-2); border: 1px solid var(--border); color: var(--text);
}
.order-chip .oq { color: var(--muted); margin-left: 4px; }
/* 订单 chip 上的运营备注标记：运营的备注是**订单级**的，直接标在对应订单上最精准，
   采购一眼看清是「这一笔」有变动（2026-09-24，解决备注聚到卡片顶部丢失归属的问题） */
.order-chip-note {
  display: inline-block; margin-left: 5px; padding: 0 6px;
  border-radius: 999px; background: rgba(239,159,39,.22); color: var(--warn);
  font-size: 11px; font-weight: 600; vertical-align: bottom;
  max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* ★ 2026-10-07：未到仓「有快递单号」分支 —— 明细行内直接带出运单号（催到仓/签收时一眼可见） */
/* ★ 2026-10-08（改）：max-width 150→260 —— 长单号（15 位如 773445027021745）此前被
   ellipsis 截断、节奏区挤压，用户报「查按钮显示不出来」。现整个 pill 是链接，放宽到
   容纳长单号完整可点；仍留 ellipsis 兜底极端超长。 */
.na2-trk {
  display: inline-block; margin-left: 5px; padding: 0 6px;
  border-radius: 999px; background: rgba(29,158,117,.16); color: var(--success);
  font-size: 11px; font-weight: 600; vertical-align: bottom;
  max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.order-more { padding: 3px 10px; border-radius: 6px; font-size: 12px; background: var(--accent); color: #fff; border: none; cursor: pointer; }
.order-more:hover { filter: brightness(1.1); }

/* 合并订单明细浮窗 */
.orders-modal { position: fixed; inset: 0; display: none; z-index: 200; }
.orders-modal.show { display: block; }
.orders-modal-mask { position: absolute; inset: 0; background: rgba(0,0,0,.45); }
.orders-modal-box {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  /* 拉宽：13 列（订单号/SKU/店铺SKU/数量/店铺/采购价/售价/运费/利润/时间/状态/采购标记/运营备注）一屏可读，长文本列 .ow 折行、无横向滚动条 */
  width: min(1200px, 96vw); max-height: 88vh; display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,.35); overflow: hidden;
}
.orders-modal-head { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; border-bottom: 1px solid var(--border); }
.orders-modal-head b { font-size: 14px; font-weight: 500; }
.orders-modal-close { border: none; background: transparent; color: var(--muted); font-size: 20px; cursor: pointer; line-height: 1; }
.orders-modal-body { padding: 8px 16px 16px; overflow-y: auto; overflow-x: hidden; }
/* 表格 min-width 不再使用（2026-10-06）：曾给订单详情弹窗加 od-wide{min-width:1180px}
   导致 1200px 宽的弹窗里出现左右滚动条；采购面板同款 13 列表格在同样容器里无横滚
   （靠 .ow 列 max-width+折行）。对齐采购面板，去掉强制宽度，保持 overflow-x:hidden。 */
.orders-modal-body table { width: 100%; border-collapse: collapse; table-layout: auto; }
.orders-modal-body th, .orders-modal-body td { text-align: left; padding: 7px 8px; border-bottom: 1px solid var(--border); font-size: 12px; white-space: nowrap; vertical-align: middle; }
.orders-modal-body th { color: var(--muted); font-weight: 500; }
/* 长文本列（订单号/SKU/店铺SKU/店铺/时间/状态/运营备注）允许折行，防 13 列撑出横向滚动条 */
.orders-modal-body tbody td.ow { white-space: normal; overflow-wrap: anywhere; max-width: 160px; }
/* 利润配色：亏损=红（买入即亏），盈利=绿（买入即赚）—— 一眼判断采购是否赔钱 */
.pm-loss { color: #e24b4a; font-weight: 600; }
.pm-gain { color: #16a34a; font-weight: 600; }
.pm-zero { color: var(--muted); }
.pm-note { font-size: 10.5px; font-weight: 400; color: var(--muted); margin-left: 3px; }
/* 弹窗顶部数量汇总提示 */
.orders-modal-summary { display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center; padding: 6px 0 12px; margin-bottom: 8px; border-bottom: 1px solid var(--border); font-size: 12px; color: var(--muted); }
.orders-modal-summary b { color: var(--text); font-weight: 600; }
.orders-modal-summary .m-purchased { color: #3884e8; }
.orders-modal-summary .m-pending { color: #6b7280; }
.orders-modal-summary .m-noship { color: #e24b4a; }
.orders-modal-summary .m-stock { color: #7f77dd; }
/* 合并订单明细弹窗（只读：核对合单构成；逐单填写采购单号/快递单号已移除，改走卡片「单号 + 数量」） */
.om-field { width: 130px; box-sizing: border-box; background: var(--bg); color: var(--text); border: 1px solid var(--border); border-radius: 6px; padding: 4px 6px; font-size: 12px; }
.om-field:focus { outline: none; border-color: var(--accent); }
.orders-modal-tip { font-size: 12px; color: var(--muted); background: var(--panel-2); border: 1px solid var(--border); border-radius: 6px; padding: 6px 10px; margin: 8px 0; }

/* 采购看板顶部②筛选行的「窄屏不换行」约束（2026-10-07 重排）
   验收标准是「顶部1920 / 侧栏1920 / 顶部1440 / 侧栏1440 四个组合高度一致」，
   最窄组合 = 侧栏导航 1440（内容区 1226px，去 main 内边距后 1186px）。
   ★ flex 分行用的是**基础尺寸**，flex-shrink 在分行阶段不生效 —— 所以「靠收缩救回来」救不了，
     只差 5px 也会整块掉到下一行。对策是**让每个子项的基础宽度都别超标**：
     ① 原生 datetime-local 默认宽 ~211px ⇒ 定宽 190px；
     ② 口径摘要 #procSummary 的文本长度会随筛选/计数变化（172px → 300px+），
        已上移到页头右侧（.ui-head 内的 .ui-stats），不再参与筛选行的宽度计算。 */
.proc-filter input[type="datetime-local"],
.ops-global-filter input[type="datetime-local"] { width: 190px; flex: 0 0 auto; }

/* 已完成采购的品：整卡变灰但保留（可继续修改），不消失 */
.proc-card { position: relative; }
.proc-card.done { opacity: .62; filter: grayscale(.5); }
.proc-card.done .proc-thumb { background: var(--panel-2); }
/* 已导出徽章：蓝色，与绿色「已采购」、紫色「库存完成」区分 */
.proc-card .done-tag.exported { background: rgba(56,132,232,.18); color: var(--info, #3884e8); border-color: rgba(56,132,232,.55); }
/* 历史已导出（OLD202509）徽章：灰色，只读、不可撤销，与蓝色「已导出」区分，避免三流程全亮 */
.proc-card .done-tag.exported-hist { background: rgba(120,120,120,.16); color: #6b7280; border-color: rgba(120,120,120,.45); }
/* 变灰卡片里，撤销类按钮保持高亮、不跟随变灰，便于一眼定位可撤销操作 */
.proc-card.done .revertBtn,
.proc-card.done .unmarkStockBtn,
.proc-card.done .undoExportBtn {
  opacity: 1 !important; filter: none !important;
  background: var(--warn); color: #fff; border-color: var(--warn);
  font-weight: 700;
}
.proc-card.done .revertBtn:hover,
.proc-card.done .unmarkStockBtn:hover,
.proc-card.done .undoExportBtn:hover { background: #d9531e; }
/* 采购看板流程标记：一流程一基色，状态靠「底色深浅 / 描边样式」区分 */
.flow-status { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; }
.flow-tag { display: inline-block; padding: 3px 10px; border-radius: 999px; font-size: 12px; font-weight: 700; line-height: 1.4; }
/* 流程基色：采购流=蓝 / 库存流=紫 / 运营自购=青 / 不发货=灰 */
.flow-tag.flow-purchase { --fc: 56,132,232; --fc-hex: #3884e8; }
.flow-tag.flow-stock    { --fc: 127,119,221; --fc-hex: #7f77dd; }
.flow-tag.flow-selfbuy  { --fc: 39,174,193;  --fc-hex: #27aec1; }
.flow-tag.flow-noship   { --fc: 107,114,128; --fc-hex: #6b7280; }
/* 状态样式：pending=浅色虚线 / ready=实色描边 / pushed=实底填充(流程色，强完成感) */
.flow-tag.st-pending { background: rgba(var(--fc),.14); color: var(--fc-hex); border: 1px dashed rgba(var(--fc),.5); }
.flow-tag.st-ready   { background: rgba(var(--fc),.22); color: var(--fc-hex); border: 1px solid rgba(var(--fc),.55); }
.flow-tag.st-pushed  { background: var(--fc-hex); color: #fff; border: 1px solid var(--fc-hex); }
/* 共享紧急态：失败=红(通用) / 待建档=琥珀虚线(通用) / 不发货=灰实底 */
.flow-tag.st-failed  { background: rgba(226,75,74,.18); color: var(--danger,#e24b4a); border: 1px solid rgba(226,75,74,.55); }
.flow-tag.st-archive { background: rgba(239,159,39,.16); color: var(--warn,#ef9f27); border: 1px dashed rgba(239,159,39,.7); }
.flow-tag.st-noship  { background: rgba(107,114,128,.2); color: #6b7280; border: 1px solid rgba(107,114,128,.5); }
.proc-card .done-tag { display: inline-block; margin-left: 8px; padding: 2px 8px; border-radius: 6px; background: rgba(29,158,117,.22); color: var(--success); font-size: 12px; font-weight: 600; }
/* 积压预警徽章（2026-09-24 用户需求）：该品最早的待采购单已压了 N 天。
   默认排序按「最新下单」倒序，老单容易被新单盖住 → 用这个徽章让久压的品一眼可见；
   ≥3 天加深、≥7 天转红。 */
.stale-tag {
  display: inline-block; margin-left: 6px; padding: 1px 8px; border-radius: 6px;
  font-size: 11px; font-weight: 700; white-space: nowrap;
  background: rgba(239,159,39,.18); color: var(--warn); border: 1px solid rgba(239,159,39,.5);
}
.stale-tag.warn { background: rgba(239,159,39,.28); border-color: var(--warn); }
.stale-tag.danger { background: rgba(226,75,74,.2); color: var(--danger); border-color: rgba(226,75,74,.6); }
/* 采购看板：搜索栏里的积压快捷筛选（复用阶段统计 chip 的样式，仅补个间距） */
.proc-stale-filter { margin-left: 6px; }
/* 已标库暂存徽章：蓝色，与绿色「已采购」区分，明确本卡是库存暂存而非已采购 */
.proc-card .done-tag.marked { background: rgba(56,132,232,.18); color: var(--info, #3884e8); }
/* 已采购印章：圆形封印，明确标识该品已完成采购（右上角，避开正中库存/问题印章） */
.proc-stamp {
  position: absolute; top: 14px; right: 14px; z-index: 8;
  transform: rotate(-15deg);
  width: 84px; height: 84px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; font-weight: 800; letter-spacing: 3px; line-height: 1.1;
  color: var(--danger); border: 3px solid var(--danger);
  box-shadow: inset 0 0 0 2px var(--danger);
  background: rgba(226,75,74,.08);
  opacity: .85; pointer-events: none; user-select: none;
}
/* 货源问题印章：长方形(问题类型文字较长)，黄色，位于整个订单条目正中（与已采购/库存印章位置区分） */
.issue-stamp {
  position: absolute; top: 50%; left: 50%; z-index: 5;
  transform: translate(-50%, -50%) rotate(-8deg);
  max-width: 210px; padding: 7px 14px; border-radius: 3px;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 800; line-height: 1.3; text-align: center;
  color: var(--warn); border: 2px solid var(--warn);
  box-shadow: inset 0 0 0 1px var(--warn), 0 1px 4px rgba(0,0,0,.18);
  background: rgba(239,159,39,.15);
  opacity: .93; pointer-events: none; user-select: none;
}
/* 运营已处理：转绿色，采购一眼看出「问题已处理过」（待处理黄 → 已处理绿） */
.issue-stamp.resolved {
  color: var(--success); border-color: var(--success);
  box-shadow: inset 0 0 0 1px var(--success), 0 1px 4px rgba(0,0,0,.18);
  background: rgba(29,158,117,.15);
}
/* 「不发货」印章：长方形·红色·整个订单条目正中（与问题印章同位置，故问题印章下移避让） */
.noship-stamp {
  position: absolute; top: 50%; left: 50%; z-index: 7;
  transform: translate(-50%, -50%) rotate(-6deg);
  max-width: 200px; padding: 7px 16px; border-radius: 3px;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 800; letter-spacing: 2px; line-height: 1.3; text-align: center;
  color: var(--danger); border: 2px solid var(--danger);
  box-shadow: inset 0 0 0 1px var(--danger), 0 1px 4px rgba(0,0,0,.18);
  background: rgba(226,75,74,.16);
  opacity: .95; pointer-events: none; user-select: none;
}
/* 同时存在「不发货」与「货源问题」印章时，问题印章下移避让，避免叠字 */
.issue-stamp.shift-down { top: 76%; }
/* 2026-10-05（续二）「问题件」视图：整卡灰度（.proc-card.done = 订单已采购完成）会盖掉问题件状态
   —— 该视图 31 张卡的工单**全是待处理**，但 29 张因订单已完成被灰掉，用户读成「只有 2 张待处理」。
   这里整体关闭灰度，状态交给黄色问题印章表达（与「已采购（未推送）」视图同一手法）。 */
#procList.issue-view .proc-card.done { opacity: 1; filter: none; }
/* 「已采购（未推送）」视图：这些是已采购但尚未推送跨境巴士的单，用于核查/改错，不再整卡灰掉，只盖章标识 */
#procList.purchased-view .proc-card.done { opacity: 1; filter: none; }

/* 校验缺失的输入框高亮 */
.proc-fill input.err { border-color: var(--danger); box-shadow: 0 0 0 2px rgba(226,75,74,.18); }

/* 导出预报预览 */
.export-table { border-collapse: collapse; }
.export-table td { border: 1px solid var(--border); padding: 8px 10px; }
.export-table .exp-head td { background: var(--panel-2); color: var(--muted); font-weight: 500; }
.export-table .exp-real td { background: rgba(29,158,117,.16); }
.export-table .exp-stock td { background: rgba(239,159,39,.2); }
.export-summary { font-size: 12px; color: var(--muted); margin: 2px 0 8px; }
.export-summary .seg-stock { color: var(--warn); font-weight: 600; }
.export-summary .seg-order { color: var(--success); font-weight: 600; }
.export-tabs { display: flex; gap: 8px; margin: 12px 0 0; }
.export-tab { padding: 8px 18px; border-radius: 9px; border: 1px solid var(--border);
  background: var(--panel-2); color: var(--muted); font-size: 13px; font-weight: 500; cursor: pointer; }
.export-tab.active { background: var(--accent); color: #fff; border-color: var(--accent); }/* [2026-10-07 并轨] 原 `.export-pager` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 */
.export-pager .pager-info { color: var(--muted); font-size: var(--ctl-fs-sm); }
.export-pager button[disabled] { opacity: .45; cursor: not-allowed; }
#exportSearch { display: none; gap: 8px; align-items: center; flex-wrap: wrap; }
#exportSearch input { padding: 7px 10px; border: 1px solid var(--border); border-radius: 8px; min-width: 260px; }
#exportSearch .muted { font-size: 13px; }
.batch-list { display: flex; flex-direction: column; gap: 10px; margin: 10px 0; }
.batch-card { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 14px; border: 1px solid var(--border); border-radius: 10px; background: rgba(239,159,39,.1); }
.batch-card .batch-info { display: flex; flex-direction: column; gap: 2px; }
.batch-card .batch-info b { font-size: 14px; color: var(--warn); }
.batch-card .batch-meta { font-size: 12px; color: var(--muted); }

/* 标记有库存弹窗 */
.stock-modal-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px; margin-bottom: 8px; background: var(--panel-2); }
.stock-modal-row .sm-main { display: flex; flex-direction: column; min-width: 0; flex: 0 1 auto; }
.stock-modal-row .sm-sku { font-family: var(--mono, monospace); font-weight: 600; font-size: 13px; }
.stock-modal-row .sm-spec { color: var(--muted); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ⚠️ 2026-09-26：参考文案从单行变多行（新增「可标库候选 / 无可标库订单」），
   故 sm-ref 需允许收缩换行，否则长文案把输入框挤出弹窗（页面错乱）。 */
.stock-modal-row .sm-ref { font-size: 11px; color: var(--muted); margin-left: auto; text-align: right; flex: 1 1 auto; min-width: 0; line-height: 1.5; }
.stock-modal-row input { width: 92px; margin-left: 10px; flex: 0 0 92px; }
/* 无可标订单的行：整行降透明度 + 斜纹底，明确「本行不可操作」 */
.stock-modal-row.sm-disabled { opacity: .6; background: repeating-linear-gradient(45deg, var(--panel-2), var(--panel-2) 6px, rgba(120,120,120,.08) 6px, rgba(120,120,120,.08) 12px); }
.stock-modal-row.sm-disabled input { cursor: not-allowed; }
.stock-modal-result { font-size: 12px; margin-top: 8px; padding: 8px 10px; border-radius: 8px; background: var(--panel-2); white-space: pre-wrap; }/* [2026-10-07 并轨] 原 `.pager` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 */
/* 分页条里的页码按钮组（2026-09-28 用户需求：多做几个页码，可跳首页/尾页） */
.pager-pages { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; }
.pager-pages .pg-btn {
  min-width: 30px; padding: 3px var(--sp-2); font-size: var(--ctl-fs-xs); line-height: 1.5;
  border: 1px solid var(--border); border-radius: 6px; cursor: pointer;
  background: transparent; color: var(--muted);
}
.pager-pages .pg-btn:hover { border-color: var(--accent); color: var(--text); }
.pager-pages .pg-btn.active {
  background: var(--accent); color: #fff; border-color: var(--accent); font-weight: 700;
}
.pager-pages .pg-dots { color: var(--muted); font-size: var(--ctl-fs-xs); padding: 0 2px; }
.pager-jump { display: flex; gap: 4px; align-items: center; font-size: var(--ctl-fs-xs); color: var(--muted); }
.pager-jump input {
  width: 56px; background: var(--bg); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 3px 6px; font-size: var(--ctl-fs-xs); text-align: center;
}
/* 两侧悬浮「回顶部 / 回底部」（2026-09-28 用户需求）：左侧=顶部、右侧=底部，竖向居中固定。
   只在「不在顶部 / 不在底部」时才由 JS 加 .show 显形，避免长期占用视线。 */
.page-nav { position: fixed; inset: 0; pointer-events: none; z-index: 900; }
.page-nav-btn {
  position: fixed; top: 50%; transform: translateY(-50%);
  width: 34px; height: 52px; border-radius: 8px;
  border: 1px solid var(--border); background: rgba(30, 32, 40, .82); color: var(--text);
  font-size: 13px; cursor: pointer; pointer-events: auto;
  opacity: 0; visibility: hidden; transition: opacity var(--anim-dur-2) var(--anim-ease), visibility var(--anim-dur-2) var(--anim-ease);
  backdrop-filter: blur(3px);
}
.page-nav-btn.show { opacity: .72; visibility: visible; }
.page-nav-btn:hover { opacity: 1; border-color: var(--accent); }
.page-nav-btn.disabled { opacity: .16; cursor: default; }
#pageNavTop { left: 6px; }
#pageNavBottom { right: 6px; }
.muted { color: var(--muted); }
.section-title { font-size: var(--fs-sec); margin: 4px 0 12px; font-weight: 500; }/* [2026-10-07 并轨] 原 `.form-grid` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.form-grid input` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.notice` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.notice b` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 */
.edit-row input { width: 100%; margin-bottom: 4px; }

/* 货源问题：标记按钮 + 状态徽标 */
.btn.issue { background: var(--warn); font-size: 13px; }
.issue-tag { display: inline-block; margin-left: 8px; padding: 2px 8px; border-radius: 6px; font-size: 12px; font-weight: 600; }
.issue-tag.pending { background: rgba(239,159,39,.22); color: var(--warn); border: 1px solid rgba(239,159,39,.5); }
.issue-tag.resolved { background: rgba(29,158,117,.18); color: var(--success); border: 1px solid rgba(29,158,117,.45); }
.issue-tip { margin-top: 6px; font-size: 12px; }
.issue-tip.pending { color: var(--warn); }
.issue-tip.resolved { color: var(--success); }

/* 货源问题弹窗（复用 orders-modal 风格） */
.issue-modal { position: fixed; inset: 0; display: none; z-index: 210; }
.issue-modal.show { display: block; }
.issue-modal-mask { position: absolute; inset: 0; background: rgba(0,0,0,.45); }
.issue-modal-box {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(560px, 92vw); max-height: 86vh; display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,.35); overflow: hidden;
}
.issue-modal-head { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; border-bottom: 1px solid var(--border); }
.issue-modal-head b { font-size: 14px; font-weight: 500; }
.issue-modal-close { border: none; background: transparent; color: var(--muted); font-size: 20px; cursor: pointer; line-height: 1; }
.issue-modal-body { padding: 16px; overflow-y: auto; }
.issue-form label { display: block; margin-bottom: 12px; font-size: 12px; color: var(--muted); }
.issue-form label b { display: block; margin-bottom: 4px; color: var(--text); font-weight: 500; }
.issue-form select, .issue-form input, .issue-form textarea {
  width: 100%; background: var(--panel); color: var(--text); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 10px; font-size: 13px; box-sizing: border-box;
}
.issue-form textarea { resize: vertical; min-height: 56px; }
.issue-form .actions { display: flex; gap: 10px; margin-top: 4px; }/* [2026-10-07 并轨] 原 `.ops-tabs` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.ops-tab` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.ops-tab:hover` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.ops-tab.active` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 */
.ops-panel { margin-top: 8px; }
/* 「被取消」清单表格（2026-10-15 用户口径：运营看板承接打单员取消的单） */
  .ops-tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; background: var(--panel); }
  .ops-tbl th, .ops-tbl td { padding: 6px 9px; border-bottom: 1px solid var(--border);
    text-align: left; vertical-align: middle; word-break: break-word; }
  .ops-tbl th { background: var(--panel-2); font-weight: 600; white-space: nowrap; }
  .ops-tbl tbody tr:hover td { background: var(--panel-2); }

/* [2026-10-07 并轨] 原 `.ops-stage-bar / .ops-stage-chip` 规则已并入 style.css 顶部 Layer 2 组件层
   （⑧ 筛选胶囊 `.ui-chip`，`.ops-stage-chip` 保留为兼容别名），此处删除以免后定义者覆盖。
   原注释保留：详细订单·业务阶段统计条：每单唯一归一档，数字相加=全部；点谁筛谁 */

/* 详细订单：仿采购表卡片（只读） */
.ops-orders { display: flex; flex-direction: column; gap: 12px; margin-top: 10px; }
.ops-order-card { display: flex; gap: 14px; padding: 12px 14px; border: 1px solid var(--border); border-radius: 10px; background: var(--panel); }
.ops-order-card.oo-problem { border-color: var(--warn); }
.ops-order-card .oo-thumb { width: 64px; height: 64px; border-radius: 8px; object-fit: cover; background: #222; flex: 0 0 auto; }
.ops-order-card .oo-thumb.ph { display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: 22px; }
.ops-order-card .oo-body { flex: 1; min-width: 0; }
.ops-order-card .oo-sku { font-weight: 600; font-size: 14px; }
.ops-order-card .oo-meta { color: var(--muted); font-size: 12px; margin: 2px 0 6px; }
.ops-order-card .oo-orders { display: flex; flex-direction: column; gap: 6px; }
.ops-order-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 6px 8px; border: 1px solid var(--border); border-radius: 7px; background: rgba(255,255,255,.02); }
.ops-order-sep td { border-top: 1px dashed var(--border); height: 7px; padding: 0; opacity: .6; }
.ops-order-row .oo-pn { font-family: monospace; font-size: 12px; }
.ops-order-row .oo-store { color: var(--muted); font-size: 12px; }
.ops-order-row .oo-qty { color: var(--muted); font-size: 12px; }
.oo-badges { display: flex; gap: 5px; flex-wrap: wrap; margin-left: auto; }
.oo-summary { color: var(--muted); font-size: 12px; margin: 4px 0; }
.st-badge { font-size: 11px; padding: 1px 8px; border-radius: 10px; white-space: nowrap; }
.st-badge.ship { border: 1px solid rgba(148,163,184,.4); }
.st-badge.erp { border: 1px solid rgba(148,163,184,.25); opacity: .92; }
.ship.s-wait { background: rgba(148,163,184,.18); color: #cbd5e1; }
.ship.s-shipped { background: rgba(59,130,246,.18); color: #93c5fd; }
.ship.s-transit { background: rgba(168,85,247,.18); color: #d8b4fe; }
.ship.s-delivered { background: rgba(34,197,94,.18); color: #86efac; }
.ship.s-cancel { background: rgba(239,68,68,.18); color: #fca5a5; }
.erp.e-unbuy { background: rgba(250,204,21,.16); color: #fde68a; }
.erp.e-buy { background: rgba(34,197,94,.16); color: #86efac; }
.erp.e-stock { background: rgba(168,85,247,.16); color: #d8b4fe; }
.erp.e-pushed { background: rgba(14,165,233,.18); color: #7dd3fc; }
.erp.e-noship { background: rgba(239,68,68,.16); color: #fca5a5; }
/* ★ 2026-10-03 处理进度单值递进新增三档：已打包（青绿·完成）/ 自购（品红·特殊流程）/
   问题件各类型（橙·待办警示，货源不对/价格高/打不开/超起订/无数据/缺规格共用） */
.erp.e-pack { background: rgba(20,184,166,.18); color: #5eead4; }
.erp.e-selfbuy { background: rgba(217,70,239,.16); color: #f0abfc; }
.erp.e-issue { background: rgba(249,115,22,.18); color: #fdba74; }
/* ★ 2026-10-03（续）「历史已购」档：订单总表原采购状态列并入后新增，中性灰（归档标记、
   既不是待办也不是完成）—— 全量 160 行，其中 147 行只靠这一档才能看出「曾归档」 */
.erp.e-hist { background: rgba(154,154,176,.20); color: #cbd5e1; }
/* 拆单提示：整包实际重量超出该仓承接上限（需拆 N 包）；合单 = 同订单多 SKU 已合并计运费 */
.erp.e-split { background: rgba(239,68,68,.22); color: #fca5a5; border-color: rgba(239,68,68,.5); font-weight: 600; }
.erp.e-merged { background: rgba(14,165,233,.16); color: #7dd3fc; }
/* 订单总表·单号列（采购单号 / 快递单号）：2026-10-03 原为输入框 → 纯文本 + 点击复制；
   （续）再加尾部小「复制」按钮、单号一行省略显示（长号不再折行把行高撑开）。 */
.copyable { cursor: pointer; border-bottom: 1px dashed rgba(148,163,184,.45); }
.ccell { display: flex; align-items: center; gap: 6px; }
.ccell .ctext { flex: 1 1 auto; min-width: 0; max-width: 170px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.copy-mini {
  flex: none; padding: 0 6px; font-size: 11px; line-height: 18px; cursor: pointer;
  border: 1px solid var(--border); border-radius: 6px; background: transparent; color: var(--muted);
}
.copy-mini:hover { color: var(--text); border-color: rgba(148,163,184,.6); }
/* ★ 2026-10-08 快递单号「查」→ 2026-10-08（改）单号文本本身即链接：点单号开百度查物流。
   text-decoration + hover 变色给"可点"暗示；white-space 保住长单号不折行。 */
.trk-link {
  color: var(--accent); text-decoration: underline; text-decoration-style: dotted;
  text-underline-offset: 2px; cursor: pointer;
}
.trk-link:hover { color: var(--text); text-decoration-style: solid; }
/* ★ 2026-10-03（续）订单总表列宽收敛（用户：订单编号一行显示；商品名/规格收一收）——
   单号、编号类一律不折行；长文本列仍保留省略号 + title 悬停看全文。 */
#ordersTable td.nowrap { white-space: nowrap; }
/* ★ 2026-10-06 店铺列宽度兜底：店铺名恒为 6~7 个全角字（「陈2（刘浩）」），14px 下需 ~118px。
   不给 min-width 时列宽随容器被等比压缩：1920 顶部模式 115px（差 3px）、左侧导航模式 93px
   → 一律折成两行，行高从 40 撑到 60。这里兜住下限，腾出的空间由商品名/规格/备注同步收紧。 */
#ordersTable td.col-store { min-width: 118px; }
/* 采购单号/快递单号：单号本身较长，但整列占位不能挤掉「店铺」这类关键短列
   （与 2026-10-03「商品名/规格收一收」同一口径：长文本列让位给关键标识列）。 */
#ordersTable .ccell .ctext { max-width: 140px; }
/* A1 模拟模式：醒目的测算提示条 + 工具栏控件 */
.ops-sim-banner {
  margin: 6px 0 4px; padding: 7px 10px; border-radius: 8px;
  border: 1px dashed rgba(250,204,21,.55); background: rgba(250,204,21,.10);
  color: #fde68a; font-size: 12px; line-height: 1.5;
}
.sim-toggle { display: inline-flex; align-items: center; gap: 4px; cursor: pointer;
              font-size: 12px; color: var(--muted); user-select: none; }
.sim-box { display: inline-flex; align-items: center; gap: 4px;
           padding: 2px 8px; border: 1px dashed var(--border); border-radius: 8px; }
.sim-box .muted { font-size: 11px; }
.sim-box input { width: 72px; }
/* ── 问题件「卡牌」九宫格（2026-10-05 改版） ──────────────────────────────
   原先是纵向长条（flex column + 卡内横向布局），一屏只能看 2~3 条，运营要一直滚。
   现改为 **3 列网格卡牌**：一屏 9 张，先扫状态/类型再点进去处理。
   窄屏自动降 2 列 / 1 列。卡牌内纵向排布，按钮用 margin-top:auto 贴底 ⇒ 同排卡牌
   等高时按钮排成一条线，观感整齐。 */
.issue-board {
  display: grid;
  /* 竖长方形卡牌 + 每行自适应列数（2026-10-05 用户要求：「横长方形看着不舒服，
     改成竖长方形的卡牌，每行根据页面自适应放几个」）。
     · auto-fill + minmax(240px, 1fr)：列数随可用宽度自动增减（每列不小于 240px），
       1fr 让各列均分剩余宽度 ⇒ 宽屏一行 6~7 张、窄屏自动降到 1~2 张，**无需断点**。
     · 用 auto-fill 而非 auto-fit：最后一行不足时保持与上面等宽，不会被拉伸成宽卡。 */
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 12px;
  align-items: stretch;
}
/* 网格子项默认 min-width:auto：卡内长文本（货源链接 / 订单号）会把该列撑宽 ⇒ 显式归零 */
.issue-board > * { min-width: 0; }

/* 卡片向采购看板卡片靠拢：圆角描边 + hover 提亮；顶边 3px 色条区分处理状态 */
.issue-card {
  min-width: 0;   /* 同上：卡是网格子项，卡内长文本不能把整列撑宽 */
  min-height: 300px;   /* 竖长方形（高 > 宽）：卡内容少的也保持竖向比例，按钮 margin-top:auto 贴底 */
  display: flex; flex-direction: column; gap: 8px;
  border: 1px solid var(--border); border-radius: 12px; padding: 12px;
  background: var(--panel);
  position: relative;   /* 缩略图悬浮放大要盖过相邻卡片，需为本卡建层叠上下文（见 .ic-thumb:hover） */
  transition: border-color var(--anim-dur-1) var(--anim-ease), background var(--anim-dur-1) var(--anim-ease), transform var(--anim-dur-1) var(--anim-ease);
}
/* ⚠️ 2026-10-08：原 `.issue-card:hover`（border-color 半透明紫 + 提亮 + translateY(-1px) + z-index:5）
   已**并入**下方「卡片悬浮即选中」统一段（问题件 / 自购 / 不发货 与采购看板主列表 .proc-card、
   未到仓 .na2-card 共用同一套选中态；原 1px 上浮 + 半透明边够不上"选中"）。
   z-index:5 那条**必须留着**（.ic-thumb:hover 要放大 3.2 倍盖过相邻卡），已在新段里补回。 */
.issue-card.pending { border-top: 3px solid var(--warn); }
/* 2026-10-05 续七：「已完结」三态里的中性一档 —— 工单 status 仍是「待处理」，但归属订单
   已走完采购流程（已采购/已标库/不发货/已预报/已发货/已取消），**无需处理**。
   刻意用中性灰：① 与黄(待处理)/绿(已处理)三分天下，一眼可辨；② 灰色天然表达"归档、不用管"。
   ⚠️ **不给它加 opacity 变暗** —— 本项目踩过"整卡灰度盖掉状态表达"的坑
   （见 #procList.issue-view .proc-card.done 那段），底色一暗、灰章就更读不出来了。 */
.issue-card.closed { border-top: 3px solid var(--muted); }
.issue-card.resolved { border-top: 3px solid var(--success); opacity: .72; }
.issue-card.resolved:hover { opacity: 1; }

/* 卡头：缩略图 + SKU + 胶囊 */
/* 卡头：缩略图 + SKU + 胶囊。flex-wrap：卡牌改竖长方形后每张只有 ~240px 宽，
   卡头三件（缩略图 / 标题 / 印章）挤一行会把标题压没，允许换行（印章落到第二行更醒目）。 */
.issue-card .ic-top { display: flex; gap: 10px; align-items: flex-start; flex-wrap: wrap; }
.issue-card .ic-thumb {
  width: 56px; height: 56px; flex: 0 0 56px; border-radius: 8px; overflow: hidden;
  border: 1px solid var(--border); background: var(--panel-2);
  display: flex; align-items: center; justify-content: center;
  /* 悬浮放大（2026-10-05 用户要求「运营看板下问题件的图片需要悬浮放大效果」）：
     56×56 的缩略图看不清商品，鼠标悬停时放大 3.2 倍浮在上层（竖长方形卡牌内宽约 218px，
     3.2×56=179px 恰好放得下、不会溢到相邻卡）。
     · transform-origin 取**左上角** ⇒ 向右下扩展，不顶出卡片上沿、不遮左侧 SKU；
     · .issue-card 没有 overflow:hidden（本来就没有），所以放大图不会被卡片裁掉；
     · z-index 抬到 60，并让 .issue-card:hover 抬到 5，保证能盖住相邻卡片。 */
  position: relative; z-index: 1;
  transition: transform var(--anim-dur-2) var(--anim-ease), box-shadow var(--anim-dur-2) var(--anim-ease), border-color var(--anim-dur-2) var(--anim-ease);
}
.issue-card .ic-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.issue-card .ic-thumb:hover {
  transform: scale(3.2); transform-origin: top left;
  z-index: 60; border-radius: 6px; border-color: var(--accent);
  box-shadow: 0 14px 36px rgba(0, 0, 0, .55);
}
.issue-card .ic-title { min-width: 0; flex: 1 1 auto; }
.issue-card .ic-sku { font-size: 13px; font-weight: 600; line-height: 1.3; word-break: break-all; }
.issue-card .issue-head { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin-top: 4px; }
.issue-card .issue-head b { font-size: 13px; font-weight: 600; }
.issue-card .issue-type { display: inline-block; padding: 2px 8px; border-radius: 6px;
  font-size: 11px; font-weight: 600; }
.issue-card .issue-type.pending { background: rgba(239,159,39,.2); color: var(--warn); }
.issue-card .issue-type.resolved { background: rgba(29,158,117,.18); color: var(--success); }
/* 历史工单未指定订单：不会把任何订单移出「未采购」视图，需人工核对补锚（2026-09-30 加）
   虚线边框把它与「待处理」（实心琥珀）区分开，扫一眼就能认出哪些工单还没落到具体订单上。 */
.issue-card .issue-type.anchor-todo { background: rgba(239,159,39,.14); color: var(--warn);
  border: 1px dashed rgba(239,159,39,.7); }
/* 问题件「印章」（2026-10-05 续二）：替代原先的两个小胶囊 —— 用户反馈「改成九宫格之后
   问题件的标签不清晰明了」，要求「用采购看板下那种问题件印章的方式打在格子上」。
   观感与采购看板 .issue-stamp 同源：描边 + 内阴影 + 轻微旋转 + 字间距；黄=待处理 / 绿=已处理。
   放在 .ic-top 行尾（flex 项，**不用绝对定位** ⇒ 永远不会压住 SKU / 缩略图）。 */
.issue-card .ic-stamp {
  flex: 0 0 auto; max-width: 176px;
  padding: 4px 11px; border-radius: 4px;
  font-size: 12.5px; font-weight: 800; letter-spacing: 1px; line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: var(--warn); border: 2px solid var(--warn);
  box-shadow: inset 0 0 0 1px var(--warn), 0 1px 4px rgba(0,0,0,.18);
  background: rgba(239,159,39,.16);
  transform: rotate(-3.5deg);
  user-select: none;
}
.issue-card .ic-stamp.resolved {
  color: var(--success); border-color: var(--success);
  box-shadow: inset 0 0 0 1px var(--success), 0 1px 4px rgba(0,0,0,.18);
  background: rgba(29,158,117,.16);
}
/* 「已完结」印章（2026-10-05 续七）：中性灰 + 文案「已完结 · 问题类型」。
   病根：印章原先只看工单 status（`待处理`→黄），而「已完结」档的工单 status **也是待处理**
   ⇒ 该档全部盖成黄「待处理」章，与「未处理」档逐字相同（实测 60 张）。现按后端 `stage` 分三色。 */
.issue-card .ic-stamp.closed {
  color: var(--muted); border-color: var(--muted);
  box-shadow: inset 0 0 0 1px var(--muted), 0 1px 4px rgba(0,0,0,.18);
  background: rgba(154,154,176,.14);
}
html[data-theme="light"] .issue-card .ic-stamp.closed { background: rgba(107,114,128,.14); }
.issue-card .issue-meta { font-size: 11px; color: var(--muted); line-height: 1.55; word-break: break-word; }
.issue-card .issue-note { font-size: 12px; background: var(--panel-2); border-radius: 7px;
  padding: 6px 9px; word-break: break-word; }
.issue-card .issue-resolve { font-size: 12px; color: var(--success); line-height: 1.55; word-break: break-word; }
.issue-card .issue-noimg { width: 100%; height: 100%; display: flex; align-items: center;
  justify-content: center; color: var(--muted); font-size: 11px; }
.issue-card .issue-source { font-size: 12px; color: var(--muted); display: flex;
  flex-direction: column; gap: 3px; min-width: 0; }
/* 货源链接折叠（2026-10-05）：默认**单行省略**，点文本展开/收起全文，跳转交给右侧「↗」。
   为什么改：1688 长链（带一长串查询参数）原先整条铺出来能占 2 行以上，把卡片顶高，
   一屏看不到 9 张；折叠后卡高可预期，要看全链点一下即可，跳转也仍是「一次点击」。 */
.issue-card .src-row { display: flex; align-items: baseline; gap: 5px; min-width: 0; }
.issue-card .src-label { flex: 0 0 auto; }
.issue-card .src-label::after { content: "："; }
.issue-card .src-wrap { display: flex; align-items: baseline; gap: 5px;
  flex: 1 1 auto; min-width: 0; }
.issue-card .src-text { flex: 1 1 auto; min-width: 0; color: var(--accent); cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.issue-card .src-text:hover { text-decoration: underline; }
.issue-card .src-wrap.open .src-text { white-space: normal; overflow-wrap: anywhere; }
.issue-card .src-open { flex: 0 0 auto; color: var(--accent); font-weight: 600;
  text-decoration: none; }
.issue-card .src-open:hover { text-decoration: underline; }
.issue-card .src-price { color: var(--text); font-weight: 500; }
/* 卡底操作区：贴底对齐（margin-top:auto），同排卡牌等高时按钮成一条线 */
.issue-card .ic-actions { margin-top: auto; padding-top: 8px; border-top: 1px solid var(--border);
  display: flex; gap: 8px; flex-wrap: wrap; }
/* 不发货视图操作区三按钮尽量同行（2026-10-06 用户口径：撤销不发/完成工单/随便发）。
   flex-wrap 保留作为窄屏兜底；按钮文字已精简，减少换行误点。 */
/* 三个视图（不发货/问题件/自购单）卡操作区按钮尽量同行（2026-10-06 用户口径：
   文字已精简，别换行误点）。flex-wrap 保留作为窄屏兜底。
   ⚠️ 自购卡最多 4 个按钮（填单号/撤销采购/改为不发/撤销自购），240px 卡宽放不下时
   仍会 wrap —— nowrap 只在能放下时生效，是"尽量同行"而非"强制同行"。 */
#noshipBoard .issue-card .ic-actions,
#issueBoard .issue-card .ic-actions,
#selfbuyBoard .issue-card .ic-actions { flex-wrap: nowrap; }
#noshipBoard .issue-card .ic-actions .btn,
#issueBoard .issue-card .ic-actions .btn,
#selfbuyBoard .issue-card .ic-actions .btn { flex: 1 1 auto; padding: 6px 6px; font-size: 12px; white-space: nowrap; }
/* 「随便发」订单级勾选（2026-10-06 方案 A）：候选订单逐笔勾选，精确指定走假发货的单 */
.fs-cands { display: flex; flex-direction: column; gap: 5px; max-height: 46vh; overflow-y: auto; }
.fs-cand { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 7px;
  border: 1px solid var(--border); background: var(--panel); cursor: pointer; font-size: 12px; }
.fs-cand:hover { border-color: var(--accent); }
.fs-cand.on { border-color: var(--accent); background: rgba(127,119,221,.12); }
.fs-cand.dis { opacity: .5; cursor: not-allowed; }
.fs-cand.dis:hover { border-color: var(--border); }
.fs-cand input { accent-color: var(--accent); }
.fs-pn { font-family: ui-monospace, Consolas, monospace; color: var(--text); word-break: break-all; }
.fs-bad { color: var(--danger); font-size: 11px; margin-left: auto; flex: none; }
/* 问题件卡片：关联订单（平台订单号 / 采购单号 / 快递单号）——2026-09-22 加；
   2026-10-05 改卡牌布局：窄卡内改为「订单号一行 + 采购/快递一行」上下叠放 */
.issue-orders { padding: 7px 9px; background: var(--panel-2); border: 1px solid var(--border); border-radius: 7px; }
/* 2026-10-06：io-title 改 flex —— 标题文字 + 右侧 ⓘ 同一行（详情按钮从操作区移来） */
.issue-orders .io-title { display: flex; align-items: center; gap: 6px; font-size: 11px;
  color: var(--muted); margin-bottom: 4px; }
.issue-orders .io-title-txt { flex: 0 1 auto; }
.issue-orders .io-title .btn { flex: none; padding: 1px 6px; font-size: 11px; line-height: 1.5;
  border-radius: 6px; border: 1px solid var(--border); background: transparent;
  color: var(--muted); cursor: pointer; }
.issue-orders .io-title .btn:hover { color: var(--text); border-color: var(--accent); background: rgba(127,119,221,.1); }
.issue-orders .io-row { font-size: 11px; padding: 2px 0; line-height: 1.5; }
.issue-orders .io-pn { font-family: ui-monospace, Consolas, monospace; color: var(--text);
  font-weight: 500; word-break: break-all; }
.issue-orders .io-row .muted { display: block; word-break: break-word; }
/* 仅看问题件 按钮激活态 */
  #procIssueOnly.active { background: var(--warn); color: #fff; border-color: var(--warn); }
  /* 未采购订单视图激活态：琥珀色（待处理），与其余视图配色都不重复
     —— 问题件=橙(warn) / 已采购=绿 / 已标库=蓝 / 不发货=红 / 运营自购=主题色 */
  #procUnpurchasedOnly.active { background: #d97706; color: #fff; border-color: #d97706; }
  #procPurchasedOnly.active { background: var(--success); color: #fff; border-color: var(--success); }
  #procMarkedOnly.active { background: #2f6fb0; color: #fff; border-color: #2f6fb0; }
  /* 「已确认数量」视图激活态：库存流下一档，用蓝紫与「已标库」同族但可分辨 */
  #procConfirmedOnly.active { background: #6b4ea0; color: #fff; border-color: #6b4ea0; }
  /* 数量胶囊（③区块内）：竖向排列、数字放大到 22px —— 用户要求「胶囊体太小、不够突出」。
     口径互斥且相加守恒（= 本卡需求），故并排成一组而非散落徽章；已推送/已导出不计入。
     flex:1 + space-evenly：区块被等高拉伸时，胶囊均匀铺满高度（不留底部空档）。 */
  .proc-flow-nums { flex: 1 1 auto; display: flex; flex-direction: column; justify-content: space-evenly; gap: 6px; }
  .proc-flow-nums .fn {
    display: block; text-align: center;
    font-size: 13px; color: var(--muted); background: rgba(154,154,176,.12);
    border: 1px solid transparent; border-radius: 8px; padding: 6px 10px; white-space: nowrap;
  }
  .proc-flow-nums .fn b { font-size: 22px; font-weight: 800; line-height: 1.1; margin: 0 2px; vertical-align: -2px; }
  .proc-flow-nums .fn-pend.on { color: #f0b429; background: rgba(240,180,41,.16); border-color: rgba(240,180,41,.4); }
  .proc-flow-nums .fn-stock.on { color: #58a6e8; background: rgba(88,166,232,.16); border-color: rgba(88,166,232,.4); }
  .proc-flow-nums .fn-pur.on { color: #35c48f; background: rgba(53,196,143,.14); border-color: rgba(53,196,143,.34); }
  .proc-flow-nums .fn-total { color: var(--text); background: rgba(154,154,176,.2); }
  /* ⭐ 2026-10-05（续十一）新增两段：问题件（橙红·待运营处理）/ 运营自购（紫·运营自行购买）。
     两段**动态显示**（件数 >0 才渲染胶囊，常驻的仍是「待采购 / 已标库」），语义与
     「流程基色」表一致（自购=紫）；问题件避开待采购的黄，改用橙红以免两枚黄胶囊混淆。 */
  .proc-flow-nums .fn-issue.on { color: #e07a4a; background: rgba(224,122,74,.16); border-color: rgba(224,122,74,.4); }
  .proc-flow-nums .fn-selfbuy.on { color: #a99cf0; background: rgba(127,119,221,.2); border-color: rgba(127,119,221,.45); }
  /* 库存流视图（已标库待核对 / 已确认数量）：不显示采购表单，改为本流程的动作提示。
     ⚠️ 2026-09-26 修「页面错乱」：本块继承 .proc-fill 的 min-width:320px / flex:0 1 360px，
     而库存流下它只放两行纯提示文字 → 白占 320px 把同排挤爆、③数量块被单独换行挤成窄条。
     库存流的动作已由横幅 + 卡片勾选框承担，故此处收紧为「自适应窄块」。 */
  .proc-fill.stock-flow-hint {
    flex: 1 1 200px; min-width: 180px;
    background: rgba(47,111,176,.12); border: 1px dashed rgba(88,166,232,.45);
  }
  .proc-flow-tip { font-size: 12px; color: var(--muted); line-height: 1.6; }
  #procNoshipOnly.active { background: var(--danger); color: #fff; border-color: var(--danger); }
  /* 库存标记订单（快递单号 0915A 式批次号）区别于正常采购完成 */
  .done-tag.stock-done { background: #6b4ea0; color: #fff; border-color: #6b4ea0; }
  .done-tag.confirmed { background: #2f6fb0; color: #fff; border-color: #2f6fb0; }
  .proc-stamp.stock-done-stamp { background: #6b4ea0; }
  #procSelfBuyOnly.active { background: var(--accent); color: #fff; border-color: var(--accent); }
  .btn.noship-mark { background: var(--danger); color: #fff; font-size: 13px; }
  /* 「完成此工单」按钮（不发货归档，2026-09-26）：绿色主按钮，语义 = 正向完结（区别于红色的"标记不发货"） */
  .btn.done-noship { background: var(--success); color: #fff; font-size: 13px; }
  /* 「已完成工单」徽章：灰绿，表示已归档离场、不再占流程 */
  .proc-card .done-tag.noship-done { background: rgba(107,114,128,.22); color: #9ca3af; border-color: rgba(107,114,128,.5); }
  html[data-theme="light"] .proc-card .done-tag.noship-done { color: #4b5563; }
  /* ── 采购看板各视图顶部横幅（banner）· 2026-10-07 配色重做 ────────────────────
     口径（用户原话）：「未采购订单视图是橙色，把下边的 banner 也修改成按钮的色彩；后边的
     其他几个视图尽量也和按钮的主色统一，保持页面统一性（参考已标库和不发货的感觉）」。
     ⇒ **每个视图的横幅色 = 该视图 tab 的激活色**（对照下方各 `#id.active` 的取值）。
     实现：一套 `.proc-banner` 结构 + 三个派生变量，加视图只需加一行配色变体。
     并轨前是 noship / selfbuy / marked 三套结构并行、各写各的色（marked 还会因后定义覆盖）。 */
  .proc-banner, .noship-banner, .selfbuy-banner, .marked-banner {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    background: var(--vb-fill, rgba(127,119,221,.12));
    border: 1px solid var(--vb-line, rgba(127,119,221,.4));
    border-radius: 10px; padding: 10px 14px; margin-bottom: 12px;
    font-size: 13px; color: var(--text);
  }
  .proc-banner span, .noship-banner span, .selfbuy-banner span, .marked-banner span {
    flex: 1 1 auto; min-width: 200px;
  }
  .proc-banner b, .noship-banner b, .selfbuy-banner b, .marked-banner b { color: var(--vb-ink, var(--accent)); }
  /* 勾选区（显示已处理 / 显示已完成 / 全选）：右对齐、不参与换行挤压 */
  .proc-banner .noship-banner-actions, .proc-banner .marked-banner-actions {
    flex: 0 0 auto; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0;
  }
  .proc-banner .sel-all { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; cursor: pointer; }
  .proc-banner .sel-all input { width: 15px; height: 15px; cursor: pointer; accent-color: var(--vb-ink, var(--accent)); }
  .proc-banner .sel-count { color: var(--vb-ink, var(--accent)); font-weight: 600; }
  .proc-banner .stock-confirm { white-space: nowrap; }
  /* 吸顶变体（已标库 / 已确认）：原来就只有这两个视图吸顶 —— 勾完几十张卡后不用滚回顶部点确认。
     ⚠️ 吸顶必须给**不透明底色**，否则卡片会从横幅后面透出来：
        这里用 `background-color: var(--panel)` 打底 + 半透明视图色叠一层。 */
  .proc-banner.sticky {
    position: sticky; top: 0; z-index: 60;
    background-color: var(--panel);
    background-image: linear-gradient(var(--vb-fill), var(--vb-fill));
    box-shadow: 0 8px 16px rgba(0, 0, 0, .26);
  }
  /* 八个配色变体 —— 与下方「采购看板视图激活态」各 #id.active 的取值一一对应。
     v-blue / v-violet 的 --vb-ink 刻意比 tab 底色亮一档（#2f6fb0 / #6b4ea0 在深色底上做正文色偏暗）。 */
  .proc-banner.v-amber   { --vb-fill: rgba(217,119,6,.13);   --vb-line: rgba(217,119,6,.45);   --vb-ink: #d97706; }
  .proc-banner.v-green   { --vb-fill: rgba(29,158,117,.13);  --vb-line: rgba(29,158,117,.45);  --vb-ink: var(--success); }
  .proc-banner.v-blue    { --vb-fill: rgba(47,111,176,.14);  --vb-line: rgba(47,111,176,.40);  --vb-ink: #58a6e8; }
  .proc-banner.v-violet  { --vb-fill: rgba(107,78,160,.15);  --vb-line: rgba(107,78,160,.45);  --vb-ink: #a98fe0; }
  .proc-banner.v-orange  { --vb-fill: rgba(239,159,39,.13);  --vb-line: rgba(239,159,39,.45);  --vb-ink: var(--warn); }
  .proc-banner.v-accent  { --vb-fill: rgba(127,119,221,.14); --vb-line: rgba(127,119,221,.45); --vb-ink: var(--accent); }
  .proc-banner.v-red     { --vb-fill: rgba(226,75,74,.12);   --vb-line: rgba(226,75,74,.40);   --vb-ink: var(--danger); }
  .proc-banner.v-neutral { --vb-fill: rgba(154,154,176,.10); --vb-line: rgba(154,154,176,.32); --vb-ink: var(--muted); }
  /* 已标库视图·勾选式确认：卡片左上角勾选框（右上角被「库存/印章」占用）+ 选中高亮 */
  .stock-sel { position: absolute; top: 12px; left: 12px; z-index: 9; display: inline-flex; align-items: center; gap: 6px; padding: 4px 9px; border-radius: 8px; background: var(--panel); border: 1px solid rgba(47,111,176,.55); font-size: 12px; font-weight: 600; color: #2f6fb0; cursor: pointer; user-select: none; }
  .stock-sel input { width: 15px; height: 15px; cursor: pointer; accent-color: #2f6fb0; }
  .proc-card.proc-sel { outline: 2px solid #2f6fb0; outline-offset: -2px; }
  /* 可选中卡片：整卡可点（点一下选中、再点一下取消），给出手型光标与 hover 反馈 */
  .proc-card.proc-selectable { cursor: pointer; }
  .proc-card.proc-selectable:hover { background: rgba(47,111,176,.06); }
  .proc-card.proc-selectable.proc-sel { background: rgba(47,111,176,.09); }
  /* 卡内的按钮/链接/输入框等仍按各自功能响应，不触发整卡选中 */
  .proc-card.proc-selectable button, .proc-card.proc-selectable a,
  .proc-card.proc-selectable input, .proc-card.proc-selectable label,
  .proc-card.proc-selectable select, .proc-card.proc-selectable textarea { cursor: auto; }
  /* 全部日期 按钮激活态：未选日期(看全部)时高亮，选了日期区间则取消高亮 */
  #procDateClear.active { background: var(--accent); color: #fff; border-color: var(--accent); }

  /* 同步全屏遮罩 */
  .sync-mask {
    position: fixed; inset: 0; z-index: 9999;
    background: rgba(15, 18, 28, .82);
    display: flex; align-items: center; justify-content: center;
    backdrop-filter: blur(2px);
  }
  .sync-mask-box {
    width: min(560px, 92vw); max-height: 84vh; overflow: auto;
    /* --fg 在 :root 里未定义，兜底 #1c2330 是近黑色，配深色底会让文字完全看不见，改用 --text */
    background: var(--bg, #1e1e2e); color: var(--text);
    border-radius: 14px; padding: 26px 28px;
    box-shadow: 0 18px 60px rgba(0,0,0,.4);
  }
  .sync-mask-title { font-size: 19px; font-weight: 700; margin-bottom: 4px; }
  .sync-mask-sub { color: var(--muted); font-size: 13px; margin-bottom: 16px; }
  .sync-progress { display: flex; flex-direction: column; gap: 8px; }
  .sync-row {
    display: flex; align-items: center; gap: 10px; font-size: 14px;
    padding: 8px 10px; border-radius: 8px; background: rgba(127,119,221,.08);
  }
  .sync-row .dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
  .sync-row.run .dot { background: #f0a020; animation: pulse 1s infinite; }
  .sync-row.ok .dot { background: #2bb673; }
  .sync-row.err .dot { background: #e5484d; }
  .sync-row .msg { flex: 1 1 auto; }
  .sync-row .tag { font-size: 12px; color: #8a93a6; }
  @keyframes pulse { 0%,100% { opacity: 1 } 50% { opacity: .35 } }
  .sync-mask-actions { margin-top: 18px; text-align: right; }

  /* 运营报表 */
  .rep-totals { display: flex; flex-wrap: wrap; gap: 12px; margin: 4px 0 16px; }
  .rep-card {
    flex: 1 1 130px; min-width: 130px; padding: 12px 14px; border-radius: 10px;
    background: var(--panel-2); border: 1px solid rgba(127,119,221,.18);
  }
  /* 原为浅色卡片 + 深色小字（浅色主题遗留）：在深色主题下 .v 未设颜色会继承近白文字，
     白底白字完全看不见。统一改为深色底 + --muted / --text。 */
  .rep-card .k { font-size: 12px; color: var(--muted); }
  .rep-card .v { font-size: 20px; font-weight: 700; margin-top: 2px; color: var(--text); }
  .rep-card .v.profit { color: #2bb673; }
  .rep-card .v.loss { color: #e5484d; }
  .rep-table-wrap { overflow: auto; max-height: 64vh; border: 1px solid rgba(127,119,221,.15); border-radius: 10px; }
  /* 注1：border-collapse: collapse 下 Chrome 的 th sticky 会失效（滚动后表头消失），必须 separate
     注2：全局 table{overflow:hidden} 会让表格自身成为 sticky 容器而表头不吸附，这里必须显式 visible，
          圆角裁剪交给外层 .rep-table-wrap 完成 */
  .rep-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; overflow: visible; }
  .rep-table th, .rep-table td { padding: 7px 9px; border-bottom: 1px solid rgba(127,119,221,.12); text-align: right; white-space: nowrap; }
  /* 表头吸附在滚动容器顶部，纵向滚动时始终可见（等价于把表头提到滚动区外） */
  /* 背景必须用已定义的深色变量：--bg2 在 :root 里并不存在，写 var(--bg2, #f3f4f8)
     会落到 #f3f4f8（近白），在深色主题下白底 + 浅色文字会看不清。统一改用 --panel-2。 */
  .rep-table th { position: sticky; top: 0; background: var(--panel-2); z-index: 3; }
  /* 图片 / SKU / 实际仓库 / 推荐仓库 左对齐，其余数值列右对齐 */
  .rep-table th:nth-child(1), .rep-table td:nth-child(1),
  .rep-table th:nth-child(2), .rep-table td:nth-child(2),
  .rep-table th:nth-child(7), .rep-table td:nth-child(7),
  .rep-table th:nth-child(11), .rep-table td:nth-child(11) { text-align: left; }
  /* 核对参考列（预估运费 / 推荐仓库 / 预估利润）：加左侧竖线 + 淡紫底，
     与实际运营数据列在视觉上分层；hover 时底色加浓但分隔线保留 */
  /* 加 #view-ops 前缀是为了压过「#view-ops .rep-table th{background}」的 id 级优先级 */
  #view-ops .rep-table th.col-check { color: #a99bff; font-weight: 600; background: rgba(127, 119, 221, .13); }
  #view-ops .rep-table td.col-check { background: rgba(127, 119, 221, .07); }
  .rep-table th.col-check, .rep-table td.col-check {
    box-shadow: inset 1px 0 0 rgba(127, 119, 221, .35);
  }
  .rep-table tr.rep-row:hover td.col-check { background: rgba(127, 119, 221, .14); }
  .rep-table img { width: 34px; height: 34px; object-fit: cover; border-radius: 6px; }
  .rep-margin-pos { color: #2bb673; }
  .rep-margin-neg { color: #e5484d; }
  /* 详细订单金额列色块分组：4 个扣费项（琥珀）+ 利润/利润率（按盈亏绿红），
     与右侧核对参考列（col-check 紫）形成三组色系，横向扫读时一眼能分清「钱出在哪 / 最后赚没赚」。
     盈亏配色沿用项目既有约定（正=绿 #2bb673、负=红 #e5484d），文字同色系提亮以保证底色上可读。 */
  #view-ops .ops-orders-table th.oo-cost { background: rgba(239, 159, 39, .17); color: #f0c07a; font-weight: 600; }
  #view-ops .ops-orders-table td.oo-cost { background: rgba(239, 159, 39, .085); }
  #view-ops .ops-orders-table tr.rep-row:hover td.oo-cost { background: rgba(239, 159, 39, .17); }
  #view-ops .ops-orders-table th.oo-profit { background: rgba(148, 163, 184, .13); font-weight: 600; }
  #view-ops .ops-orders-table td.oo-profit { background: rgba(148, 163, 184, .10); }
  #view-ops .ops-orders-table td.oo-profit.rep-margin-pos { background: rgba(43, 182, 115, .16); color: #52d39a; }
  #view-ops .ops-orders-table td.oo-profit.rep-margin-neg { background: rgba(229, 72, 77, .16); color: #ff7b7f; }
  #view-ops .ops-orders-table tr.rep-row:hover td.oo-profit.rep-margin-pos { background: rgba(43, 182, 115, .26); }
  #view-ops .ops-orders-table tr.rep-row:hover td.oo-profit.rep-margin-neg { background: rgba(229, 72, 77, .26); }
  /* 运费/预估运费未算：紧凑徽标 + 悬浮小贴士，避免长文案撑宽列（点击仍用于展开行） */
  .rep-flag {
    display: inline-flex; align-items: center; gap: 2px;
    margin-left: 5px; padding: 1px 7px; border-radius: 999px;
    font-size: 11px; line-height: 1.5; white-space: nowrap; cursor: help;
    color: #e5484d; background: rgba(229, 72, 77, .12);
    border: 1px solid rgba(229, 72, 77, .35);
  }
  .rep-flag::before { content: "\26A0"; font-size: 10px; margin-right: 1px; }
  .rep-tip {
    position: fixed; z-index: 9999; max-width: 300px;
    padding: 7px 10px; border-radius: 8px;
    background: #2a2a35; color: #fff; font-size: 12px; line-height: 1.55;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .35); pointer-events: none;
    white-space: normal; word-break: break-word;
  }
  /* 实际仓库与推荐仓库不一致：标黄提示渠道可能不是最优 */
  .rep-table td.wh-mismatch { color: var(--warn, #d0a215); font-weight: 600; }
  .rep-table td.td-spec, .rep-table td.td-wh { text-align: left; }
  .rep-table td.td-spec { max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* 主表可点行：默认收起成本明细，点行展开 */
  .rep-table tr.rep-row { cursor: pointer; }
  .rep-table tr.rep-row:hover td { background: rgba(127,119,221,.08); }
  .rep-table tr.rep-row.expanded td { background: rgba(127,119,221,.12); }
  .rep-table tr.rep-detail { display: none; }
  .rep-table tr.rep-detail.show { display: table-row; }
  .rep-table tr.rep-detail > td { padding: 10px 14px; background: var(--panel-2); text-align: left; }
  .rep-detail-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px 18px; font-size: 12px; }
  .rep-detail-grid > div { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
  .rep-detail-grid em { font-style: normal; color: var(--muted); flex: 0 0 auto; }
  .rep-detail-grid b { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .rep-detail-grid .rep-detail-wide { grid-column: span 2; }

  /* 详细订单·利润明细全表（28 列）专属对齐，压过通用 .rep-table 的 nth-child 规则 */
  /* 整页宽、内容撑开、页级横向滚动（无内嵌滚动条，与「订单总表」同感） */
  #view-ops .ops-orders-table { width: max-content; min-width: 100%; table-layout: auto; }
  #view-ops .ops-orders-table td,
  #view-ops .ops-orders-table th { white-space: nowrap; }
  /* 第 1 列：备货勾选框（仅「待备货」订单可勾，其余禁用并给提示） */
  #view-ops .ops-orders-table th.oo-chk,
  #view-ops .ops-orders-table td.oo-chk { text-align: center; width: 40px; padding-left: 8px; padding-right: 4px; }
  #view-ops .ops-orders-table td.oo-chk input { width: 15px; height: 15px; cursor: pointer; accent-color: var(--accent); }
  #view-ops .ops-orders-table td.oo-chk input:disabled { cursor: not-allowed; opacity: .3; }
  /* 店铺列：名字长时截断，不把表格撑宽（运营名进 title） */
  #view-ops .ops-orders-table td.oo-store { max-width: 140px; overflow: hidden; text-overflow: ellipsis; }
  /* 勾选中的行给淡底，批量操作时一眼看清选了哪几笔 */
  #view-ops .ops-orders-table tr.rep-row.row-checked > td { background: rgba(124,131,255,.10); }
  /* 同品聚合排序：换品时用更明显的分隔线，同品内按日期用细虚线 */
  #view-ops .ops-orders-table tr.ops-sku-sep td { border-top: 2px solid var(--border); }
  /* 轻提示（重量保存等）：右下角堆叠、自动消失，不打断操作 */
  .ops-toast-box { position: fixed; right: 18px; bottom: 18px; z-index: 9999; display: flex;
                   flex-direction: column; gap: 8px; align-items: flex-end; pointer-events: none; }
  .ops-toast-item { background: var(--panel-2); color: var(--text); border: 1px solid var(--border);
                    border-left: 3px solid var(--success); border-radius: 8px; padding: 8px 12px;
                    font-size: 12px; box-shadow: 0 6px 18px rgba(0,0,0,.35);
                    transition: opacity var(--anim-dur-2) var(--anim-ease),
                                transform var(--anim-dur-2) var(--anim-ease); }
  .ops-toast-item.out { opacity: 0; transform: translateY(6px); }
  /* 左对齐：文本 / 编码类列（第 1 列是备货勾选框，居中见下） */
  #view-ops .ops-orders-table td:nth-child(2),   /* 日期 */
  #view-ops .ops-orders-table td:nth-child(3),   /* 店铺 */
  #view-ops .ops-orders-table td:nth-child(4),   /* SKU */
  #view-ops .ops-orders-table td:nth-child(15),  /* 采购订单编号 */
  #view-ops .ops-orders-table td:nth-child(16),  /* 订单号 */
  #view-ops .ops-orders-table td:nth-child(17),  /* 快递单号 */
  #view-ops .ops-orders-table td:nth-child(22),  /* 仓库标识 */
  #view-ops .ops-orders-table td:nth-child(24),  /* 货源 */
  #view-ops .ops-orders-table td:nth-child(25),  /* 规格 */
  #view-ops .ops-orders-table td:nth-child(26),  /* 备注 */
  #view-ops .ops-orders-table td:nth-child(28)   /* 推荐仓库 */
    { text-align: left; }
  /* 下单日期分两行（2026-09-30）：日期 + 时分秒，避免一长串时间撑宽列；同字号不缩 */
  #view-ops .ops-orders-table td:nth-child(2) .oo-date-d { display: block; white-space: nowrap; }
  #view-ops .ops-orders-table td:nth-child(2) .oo-date-t { display: block; color: var(--muted); white-space: nowrap; }
  /* 右对齐：金额 / 数量 / 重量 */
  #view-ops .ops-orders-table td:nth-child(5),   /* 数量 */
  #view-ops .ops-orders-table td:nth-child(7),   /* 采购成本 */
  #view-ops .ops-orders-table td:nth-child(8),   /* 售价 */
  #view-ops .ops-orders-table td:nth-child(9),   /* 跨境运费 */
  #view-ops .ops-orders-table td:nth-child(10),   /* 尾程配送 */
  #view-ops .ops-orders-table td:nth-child(11),  /* 收单业务 */
  #view-ops .ops-orders-table td:nth-child(12),  /* 银行手续费 */
  #view-ops .ops-orders-table td:nth-child(13),  /* 利润 */
  #view-ops .ops-orders-table td:nth-child(14),  /* 利润率 */
  #view-ops .ops-orders-table td:nth-child(23),  /* 重量(g) */
  #view-ops .ops-orders-table td:nth-child(27),  /* 预估运费 */
  #view-ops .ops-orders-table td:nth-child(29)   /* 预估利润 */
    { text-align: right; font-variant-numeric: tabular-nums; }
  #view-ops .ops-orders-table tr.rep-row { cursor: default; }
  #view-ops .ops-orders-table td.oo-spec { max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #view-ops .ops-orders-table td img { width: 34px; height: 34px; border-radius: 5px; object-fit: cover; background: #222; display: block; }
  #view-ops .ops-orders-table th:nth-child(6),
  #view-ops .ops-orders-table td:nth-child(6) { text-align: center; width: 46px; }
  #view-ops .ops-orders-table td:nth-child(18),
  #view-ops .ops-orders-table td:nth-child(19),
  #view-ops .ops-orders-table td:nth-child(20),
  #view-ops .ops-orders-table td:nth-child(21) { text-align: center; white-space: nowrap; }
  /* 可编辑备注单元格：默认留空 —— 早期回退展示「选品源备注」做占位，
     但那串文本常常很长会把整列撑宽。运营自己填的是「发1个」「发一半」这类短备注。
     这里再限制列宽 + 允许换行，避免长备注把表格撑变形。 */
  .oo-note { outline: 1px dashed transparent; min-width: 88px; max-width: 150px;
             white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; }
  .oo-note:hover { outline-color: rgba(148,163,184,.4); background: rgba(255,255,255,.03); }
  .oo-note:focus { outline-color: #7c83ff; background: rgba(124,131,255,.08); }
  .oo-note-ph { color: var(--muted); font-style: italic; }
  .oo-note-ph:empty::before { content: "点此备注"; }
  /* SKU 超长截断 + 点击展开（第 3 列） */
  #view-ops .ops-orders-table td.oo-sku { max-width: 132px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; }
  #view-ops .ops-orders-table td.oo-sku:hover { color: #b3b8ff; }
  #view-ops .ops-orders-table td.oo-sku.expanded { white-space: normal; max-width: 360px; overflow: visible; word-break: break-all; }
  /* 详细订单表 / 概览利润明细表 底部汇总行 */
  #view-ops .ops-orders-table tr.oo-sum { font-weight: 600; background: var(--panel-2); }
  #view-ops .ops-orders-table tr.oo-sum td { border-top: 2px solid var(--border); padding-top: 9px; padding-bottom: 9px; }
  #view-ops .ops-orders-table tr.oo-sum td.oo-sum-label { text-align: left; }

  /* ===== 运营看板（ops） ===== */
  /* 全局筛选栏：置于三选项卡之上，是各 Tab 的共同前置条件 */
  .ops-global-filter { margin: 2px 0 12px; flex-wrap: wrap; row-gap: 8px; }
  #opsToday.active {
    background: rgba(124, 131, 255, .18); color: #b3b8ff;
    border-color: rgba(124, 131, 255, .55);
  }
  /* 8 张 KPI 卡：4 列 × 2 行；行间距略小于列间距，两行不显松散 */
  .ops-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px 12px; margin: 2px 0 14px; }
  @media (max-width: 900px) { .ops-kpis { grid-template-columns: repeat(2, 1fr); } }
  .ops-kpi {
    padding: 12px 14px; border-radius: 10px;
    background: var(--panel-2); border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
  }
  .ops-kpi.g-success { border-left-color: var(--success); }
  .ops-kpi.g-warn { border-left-color: var(--warn); }
  .ops-kpi.g-muted { border-left-color: var(--border); }
  .ops-kpi .k { font-size: 12px; color: var(--muted); }
  .ops-kpi .v { font-size: 24px; font-weight: 700; margin-top: 4px; line-height: 1.15; font-variant-numeric: tabular-nums; }
  .ops-kpi .s { font-size: 11px; color: var(--muted); margin-top: 3px; }
  .ops-kpi .v.pos { color: var(--success); }
  .ops-kpi .v.neg { color: var(--danger); }
  /* 次要指标文字条：主线 4 个 KPI 之外的指标收成一行，不抢视线 */
  .ops-substats {
    grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px 22px;
    padding: 9px 14px; border-radius: 9px; background: var(--panel);
    border: 1px solid var(--border); font-size: 12px;
  }
  .ops-substat { display: inline-flex; align-items: baseline; gap: 6px; color: var(--muted); }
  .ops-substat em { font-style: normal; }
  .ops-substat b { color: var(--text); font-weight: 600; margin-left: auto; font-variant-numeric: tabular-nums; }

  .ops-charts { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 6px; align-items: start; }
  @media (max-width: 980px) { .ops-charts { grid-template-columns: 1fr; } }
  .ops-chart-card {
    background: var(--panel); border: 1px solid var(--border);
    border-radius: 12px; padding: 14px 16px; min-width: 0; align-self: start;
  }
  /* 左栏「利润排行」为空时不再被右栏拉高 */
  .ops-bars { min-height: 0; }
  .ops-chart-full { grid-column: 1 / -1; }
  .ops-chart-title { font-size: 13px; font-weight: 600; margin-bottom: 10px; }
  .ops-empty { color: var(--muted); font-size: 12px; padding: 20px 0; text-align: center; }

  /* 横向条形图 */
  .ops-bar-row { display: flex; align-items: center; gap: 10px; margin: 7px 0; font-size: 12px; }
  .ops-bar-label { width: 96px; flex: 0 0 96px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ops-bar-track { flex: 1; height: 18px; background: var(--panel-2); border-radius: 6px; overflow: hidden; }
  .ops-bar-fill { height: 100%; border-radius: 6px; background: linear-gradient(90deg, var(--accent), #a99ff0); }
  .ops-bar-fill.neg { background: linear-gradient(90deg, #b3534d, var(--danger)); }
  /* 第二序列（2026-10-18 采购报表「采购 vs 出库」双轨）：出库件数用绿色，与采购额的主色区分 */
  .ops-bar-fill.alt { background: linear-gradient(90deg, #2f8f68, var(--success)); }
  .ops-bar-val { width: 104px; flex: 0 0 104px; text-align: right; font-variant-numeric: tabular-nums; }
  .ops-bar-val.pos { color: var(--success); }
  .ops-bar-val.neg { color: var(--danger); }

  /* 折线图（近 7 日趋势） */
  .ops-line svg { display: block; width: 100%; height: auto; }
  .ops-legend { display: flex; flex-direction: column; gap: 5px; font-size: 12px; min-width: 0; }
  .ops-legend-item { display: flex; align-items: center; gap: 6px; color: var(--muted); }
  .ops-legend-dot { width: 9px; height: 9px; border-radius: 3px; flex: 0 0 9px; }
  .ops-legend-item b { color: var(--text); font-weight: 600; margin-left: auto; padding-left: 8px; }

  /* 问题件子功能面板 */
  .ops-sub { margin-top: 18px; background: var(--panel); border: 1px solid var(--border); border-radius: 12px; }
  .ops-sub-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 12px 14px; border-bottom: 1px solid var(--border); }
  .ops-sub-head b { font-size: 14px; font-weight: 600; }
  /* 折叠时隐藏的附加操作区（状态筛选 + 刷新），展开才显示 */
  .ops-sub-head .iss-extra { display: flex; align-items: center; gap: 8px; margin-left: auto; }
  /* 问题件列表：**去掉内嵌滚动条**（用户 2026-09-24 要求），随页面自然滚动，
     不再用 64vh 的小窗口把卡片憋在里面 */
  #opsIssBody { padding: 14px; }
  /* 运营自购 Tab 列表容器：与问题件面板**逐字同构**（同一套九宫格卡牌，2026-10-05 续四） */
  #opsSbBody { padding: 14px; }
  /* 问题件筛选：全部 / 未处理 / 已处理（复用阶段统计 chip 的视觉，保持一致） */
  .iss-filter { display: inline-flex; gap: 6px; align-items: center; flex-wrap: wrap; }

  /* 运营看板内的报表区统一深色，避免浅色卡片在深色主题下文字看不清 */
  #view-ops .rep-card,
  #view-ops .rep-table th { background: var(--panel-2); color: var(--text); }
  #view-ops .rep-card { border: 1px solid var(--border); }
  #view-ops .rep-card .k { color: var(--muted); }
  #view-ops .rep-table th,
  #view-ops .rep-table td { border-bottom: 1px solid var(--border); }
  #view-ops .rep-table-wrap { border-color: var(--border); max-height: 60vh; }

  /* 各店铺统计 */
  .ops-stores { margin-top: 18px; background: var(--panel); border: 1px solid var(--border); border-radius: 12px; }
  .ops-stores-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 12px 14px; border-bottom: 1px solid var(--border); }
  .ops-stores-head b { font-size: 14px; font-weight: 600; }
  .ops-store-table th, .ops-store-table td { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
  .ops-store-table th:first-child, .ops-store-table td:first-child,
  .ops-store-table th:nth-child(2), .ops-store-table td:nth-child(2) { text-align: left; }
  .ops-store-table td:first-child { font-weight: 600; }
  /* 合计行吸附在滚动容器底部，与表头（sticky top）对称：纵向滚动时始终可见，
     等价于把合计提到滚动区外；放在 tfoot 里可继续沿用表格列宽，与上方数据精确对齐。
     注：与 th 一样依赖 .rep-table 的 border-collapse: separate，否则 Chrome 下 sticky 会失效。 */
  .ops-store-table tfoot .st-sum td,
  .ops-store-table .st-sum td {
    position: sticky; bottom: 0; z-index: 3; font-weight: 600;
    background: var(--panel-2); color: var(--text);
    border-top: 1px solid var(--border); border-bottom: 0;
  }
  .rep-num.pos { color: var(--success); }
  .rep-num.neg { color: var(--danger); }

  /* ===== 打单员视图（预报之后的打单/打包环节） ===== */
  #view-packer .packer-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 10px 0 14px; }
  #view-packer .packer-toolbar .seg { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
  #view-packer .packer-toolbar .seg button { border: 0; background: transparent; color: var(--text); padding: 6px 12px; cursor: pointer; }
  #view-packer .packer-toolbar .seg button.active { background: var(--accent); color: #fff; }
  #view-packer .packer-counts { margin-left: auto; color: var(--muted); font-size: 13px; }/* [2026-10-07 并轨] 原 `#view-packer .packer-pager` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 */
  #view-packer .packer-pager select { padding: 4px 8px; border: 1px solid var(--border); border-radius: 6px; background: var(--panel-2); color: var(--text); }
  #view-packer .packer-pager .btn { padding: 4px 10px; font-size: 12.5px; }
  #view-packer .packer-pager .btn:disabled { opacity: .45; cursor: not-allowed; }
  /* —— 打单员列表：表格化卡片（对标跨境巴士打单条目 · 列宽固定 ⇒ 各行纵向对齐） ——
     卡片 = grid：头条整行（grid-column:1/-1）+ 5 列
     ① pk-track 快递状态 ② pk-goods 商品 ③ pk-plat 平台/物流/条码 ④ pk-info 订单信息 ⑤ pk-acts 按钮 */
  .pack-list { display: flex; flex-direction: column; gap: 10px; }
  .pack-card { background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
    overflow: hidden; display: grid;
    grid-template-columns: 200px 345px minmax(0, 1fr) 250px 190px; }
  /* 已打包（2026-10-15 用户口径 · 二次修正，参考巴士打单员打包完成图）：
     ① 原 `opacity:.72` 太轻 —— 用户「变灰变的不明显……图片都能变灰的那种，整卡和正常卡是很明显的区别」
        ⇒ 加**整体灰度**（含商品图，对齐巴士连图都灰）+ 换灰底 + 更低的透明度；
        卡头刻意**不参与灰度** ⇒ 卡头「已打包」徽标仍可辨认（不然状态就彻底读不出来了）。
     ② 边框**改中性**：原先与「已处理问题件」(.pack-card.issue-done) 同用 var(--success) 绿
        ⇒ 两态在卡面上**分不出来**（用户报障）。现在颜色分工固定为：
        待处理问题件 = 红（danger）/ 已处理问题件 = 绿（success）/ **已打包 = 中性灰**（靠整卡变灰表达）。 */
  .pack-card.packed {
    background: var(--panel-2);
    border-color: var(--border);
    opacity: .62;
  }
  .pack-card.packed > .pk-track,
  .pack-card.packed > .pk-goods,
  .pack-card.packed > .pk-plat,
  .pack-card.packed > .pk-info,
  .pack-card.packed > .pk-acts { filter: grayscale(1); }
  .pack-card.problem { border-color: var(--danger); }
  /* ★ 2026-10-21（草稿箱区块换序 · 用户口径）：草稿箱卡片 DOM 顺序是
     goods(图片+基本信息) → plat(店铺/平台/物流/条码) → track(采购单号/快递单号) → info(状态时间) → acts(操作)。
     ⚠️ grid 列宽是**按列位置**分配的，不跟元素走 ⇒ 换序后必须单独给一套列宽，
        否则商品大图会挤进 200px 那列（图被压扁）。打单页（仓库域）顺序不变、列宽也不变。 */
  .pack-card.pk-draft { grid-template-columns: 345px minmax(0, 1fr) 200px 250px 190px; }
  /* 头条（整行）：勾选 + 状态 + 订单号/批次/预报/打包/仓库/店铺 */
  .pack-card .pk-head { grid-column: 1 / -1; display: flex; align-items: center; gap: 12px;
    flex-wrap: wrap; padding: 7px 12px; font-size: 12.5px; background: var(--panel-2);
    border-bottom: 1px dashed var(--border); }
  .pack-card .pk-check { display: inline-flex; align-items: center; flex: 0 0 auto; }
  .pack-card .pk-check input { width: 15px; height: 15px; cursor: pointer; accent-color: var(--success); }
  .pack-card .pk-hitem { color: var(--muted); }
  .pack-card .pk-hitem .pk-pn { font-family: monospace; color: var(--text); }
  /* 批次：2026-10-15 用户口径「批次的绿色字改掉和正常字体颜色一样」——去绿，用正常字色 */
  .pack-card .pk-hitem .pk-batch { color: var(--text); font-family: monospace; }
  .pack-card .pk-hitem.pk-done { color: var(--success); }
  .pack-card .pk-hitem.pk-wh { color: #606266; max-width: 200px; overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap; }
  /* 店铺：2026-10-15 用户口径「店铺的黄字也改成和正常字颜色一样」——去黄，用正常字色 */
  .pack-card .pk-hitem.pk-store2 { color: var(--text); }
  /* 各列统一内边距/字号（列间竖线分隔，读起来像表格） */
  .pack-card > .pk-track, .pack-card > .pk-goods, .pack-card > .pk-plat,
  .pack-card > .pk-info, .pack-card > .pk-acts {
    padding: 10px 12px; border-right: 1px dashed var(--border); min-width: 0; }
  .pack-card > .pk-acts { border-right: 0; }
  /* ① 快递状态列：三态（未签收=蓝可点跳百度 / 已签收=绿+签收人 / 无号=采购单号+手动签收） */
  /* ① 第一区块（快递状态）按 SKU 分行（2026-10-15 用户口径，对齐巴士参考图3）：
     合单下每 SKU 一行，各显各自的采购单号/快递单号/签收状态；
     ⚠️ 每行高度、行间距与第二区块（商品大图 148px + gap 8px）**逐行对齐** ——
        用户原话「第一区块的上下两部分要和第二区块的大图对齐」。 */
  .pack-card .pk-track { display: flex; flex-direction: column; align-items: stretch;
    gap: 8px; font-size: 12.5px; line-height: 1.5; }
  .pk-trk-row { display: flex; flex-direction: column; align-items: flex-start;
    justify-content: center; gap: 2px; min-height: 148px; box-sizing: border-box;
    padding: 8px; border-radius: 6px; background: var(--panel-2); }
  /* 快递最新位置（2026-10-15 预留窗口）：快递单号下方一行；暂无数据显示「—」弱化 */
  .pk-pos { font-size: 11.5px; color: var(--muted); max-width: 100%; overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap; }
  .pk-pos.none { opacity: .45; }
  .pk-stock-tag { color: #d9a441; font-weight: 600; }
  .pack-card .pk-meta { color: var(--muted); }
  .pk-trk { font-family: monospace; font-weight: 700; text-decoration: none; word-break: break-all; }
  .pk-trk-wait { color: #409eff; }
  .pk-trk-done { color: #00b06e; }
  .pk-unrecv { color: #409eff; font-weight: 600; }
  .pk-recv { color: #00b06e; }
  .pk-po { color: #606266; font-family: monospace; font-weight: 600; word-break: break-all; }
  .pk-track .btn { padding: 2px 10px; font-size: 12px; cursor: pointer; margin-top: 2px; }
  /* ② 商品列：大图（对标巴士约 150px 见方）+ SKU/颜色/数量 */
  .pack-card .pk-goods { display: flex; flex-direction: column; gap: 8px; }
  .pack-item { display: flex; align-items: flex-start; gap: 12px; }
  .pack-item img { width: 148px; height: 148px; object-fit: cover; border-radius: 8px;
    border: 1px solid var(--border); flex: 0 0 auto; }
  .pack-item .pi-line { font-size: 12.5px; line-height: 1.6; min-width: 0; word-break: break-word; }
  .pack-item .pi-sku { font-family: monospace; }
  .pack-item .pi-spec { color: var(--muted); font-size: 12px; }
  .pack-item .pi-qty { font-weight: 700; }
  /* 验货内容（2026-10-15 用户口径：与巴士推送 describe 同款，红色加粗醒目） */
  .pack-item .pi-check { color: var(--danger); font-weight: 700; }
  /* ③ 平台/物流/条码列 */
  .pack-card .pk-plat { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; line-height: 1.6; }
  .pk-plat .pk-store { color: var(--text); }
  .pk-plat .pk-qty { color: #409eff; }
  /* 条码行 + 两个图标按钮（更新订单信息 / 预览面单，对齐巴士） */
  .pk-barcode { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
  .pk-ico { display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; padding: 0; border: 1px solid var(--border); border-radius: 5px;
    background: var(--panel-2); color: var(--muted); cursor: pointer; }
  .pk-ico:hover { color: #409eff; border-color: #409eff; }
  .pk-ico:disabled { opacity: .45; cursor: default; color: var(--muted); border-color: var(--border); }
  /* 已有本地面单 → 预览图标亮蓝（对齐巴士：有面单才可预览） */
  .pk-ico.on { color: #409eff; border-color: #409eff; }
  .pk-ico.on:hover { background: #409eff; color: #fff; }
  .pk-muted { color: var(--muted); }
  /* 打单备注块（2026-10-15）：左「备注」标签 + 右内容区；已存备注只读、可继续追加 */
  .pk-notes { display: flex; align-items: flex-start; gap: 8px; margin-top: 7px;
    padding-top: 6px; border-top: 1px dashed var(--border); }
  .pk-notes-label { flex: 0 0 auto; color: var(--muted); font-size: 12.5px; line-height: 1.7; }
  .pk-notes-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
  .pk-note-item { font-size: 12.5px; line-height: 1.6; color: var(--text);
    background: var(--panel-2); border-left: 2px solid var(--border); border-radius: 4px;
    padding: 2px 6px; word-break: break-word; }
  .pk-note-add { font-size: 12.5px; color: #409eff; cursor: pointer; padding: 1px 0; }
  .pk-note-add:hover { text-decoration: underline; }
  .pk-note-input { width: 100%; padding: 3px 6px; font-size: 12.5px; border: 1px solid #409eff;
    border-radius: 5px; background: var(--panel-2); color: var(--text); box-sizing: border-box; }
  /* 到仓问题件反馈块（2026-10-15 用户口径 · 回到首版）：
     用户确认「卡片中间的问题还保持第一版就行」⇒ 已处理 = **整块变绿**（边框 + 全部文字）。
     ⚠️ 「订单号左边的问题件**徽标** + **整卡外边框**变绿」是**另一处**，
        不在本块上，见下方 .pack-card.issue-done 那段（2026-10-15 二次修正踩过的误解）。
     ⚠️ 本块只做「状态回显」，不改 pack_status —— 单子仍留在打单页「问题件」tab，
        何时点「转正常件」由打单员决定（用户口径：状态由人掌控）。 */
  .pk-issue-fb { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; margin-top: 7px;
    padding: 5px 8px; border: 1px solid var(--warn); border-radius: 7px;
    font-size: 12.5px; line-height: 1.6; color: var(--warn); }
  .pk-issue-fb .pk-ifb-label { flex: 0 0 auto; font-weight: 700; }
  .pk-issue-fb .pk-ifb-body { flex: 1 1 auto; min-width: 0; word-break: break-word; }
  .pk-issue-fb.resolved { border-color: var(--success); color: var(--success); }
  .pk-issue-fb .pk-ifb-hint { opacity: .85; }
  /* ══ 打包（扫码工作台）══ 2026-10-15 用户口径：参考巴士独立扫码页 ——
     「打包」子导航默认页：大扫码框 + 命中结果区，不列全部订单。 */
  .pack-scan-desk { padding: 16px 18px; }
  /* 子导航视图提示条（2026-10-15 二次重构：仓库打包一级分组下的独立子视图）：
     库存 = 库存流订单视图的顶部说明；与 .pk-sub-note 配套。 */
  .pk-sub-note { padding: 8px 12px; margin-bottom: 10px; font-size: 12.5px;
    color: var(--muted); border: 1px dashed var(--border); border-radius: 6px; }
  .pack-scan-bar { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }
  .pack-scan-input { display: flex; align-items: center; gap: 12px; flex: 1 1 auto; }
  .pack-scan-label { font-size: 14px; font-weight: 700; color: var(--accent); white-space: nowrap; }
  .pack-scan-input input {
    flex: 1 1 auto; max-width: 560px; padding: 10px 14px; font-size: 16px;
    border: 2px solid var(--accent); border-radius: 8px;
    background: var(--panel-2); color: var(--text);
    font-family: monospace; letter-spacing: 1px;
  }
  .pack-scan-input input:focus { outline: none; border-color: var(--success); box-shadow: 0 0 0 3px rgba(29,158,117,.15); }
  .pack-scan-hint { color: var(--muted); font-size: 12px; margin: 0 0 12px; }
  .pack-scan-head { font-size: 13px; margin-bottom: 8px; }
  .pack-scan-card { border: 1px solid var(--border); border-radius: 10px;
    background: var(--panel); margin-bottom: 10px; overflow: hidden; }
  .pack-scan-card .pk-head { padding: 8px 12px; border-bottom: 1px dashed var(--border); }
  .pack-scan-error { border: 1px solid var(--danger); color: var(--danger);
    background: rgba(214,69,69,.08); border-radius: 8px; padding: 12px 14px;
    font-size: 13px; margin-top: 8px; }
  /* ④ 订单信息列 */
  .pack-card .pk-info { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; line-height: 1.6; }
  .pk-badge, .pack-badge { display: inline-block; font-size: 12px; padding: 1px 8px;
    border-radius: 999px; font-weight: 600; }
  .pack-badge.b-wait { background: rgba(0,0,0,.06); color: var(--muted); }
  .pack-badge.b-packed { background: rgba(29,158,117,.18); color: var(--success); }
  .pack-badge.b-problem { background: rgba(214,69,69,.18); color: var(--danger); }
  /* ⚠️ 2026-10-15 起**暂无使用者**：打单页「出库重量 / 体积」两行已按用户口径移除
     （「打单没有录入重量这块，后期有需求的时候再做」）。样式**刻意保留** ——
     恢复入口只需贴回两行 `.pk-wrow` + 事件分支，不必重写样式。 */
  .pk-wrow { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
  .pk-wrow input { width: 54px; padding: 2px 5px; border: 1px solid var(--border); border-radius: 6px;
    background: var(--panel-2); color: var(--text); font-size: 12px; }
  .pk-wrow .vol { color: #409eff; font-size: 12px; }
  .pk-wrow .w-save { padding: 2px 8px; font-size: 12px; cursor: pointer; }
  .pack-note { width: 100%; min-height: 26px; height: 26px; padding: 3px 6px; border: 1px solid var(--border);
    border-radius: 6px; background: var(--panel-2); color: var(--text); font-size: 12px;
    resize: vertical; box-sizing: border-box; }
  /* ⑤ 操作按钮列：两列网格 */
  /* ★ 2026-10-15 用户口径：按钮「做成采购看板的操作区那种，一排一个」。
     原 `1fr 1fr` 两列在 190px 宽的按钮列里挤成一团、主次不分；
     改单列 = 一排一个、每个按钮撑满列宽、文字居中（对齐采购看板 .proc-ops-btns 的竖排观感）。
     ⚠️ 窄屏断点（下方 @media）保持 3 列不变 —— 那里 .pk-acts 已跨整行（grid-column: 1/-1），
        整行宽下横排更省纵向空间，与「一排一个」不冲突。 */
  .pack-card .pk-acts { display: grid; grid-template-columns: 1fr; gap: 5px; align-content: start; }
  .pack-card .pk-acts .btn { padding: 5px 6px; font-size: 12.5px; text-align: center; cursor: pointer;
    border-radius: 6px; }
  .pack-card .pk-acts .btn.danger { color: #fff; background: var(--danger); border-color: var(--danger); }
  /* 动作已执行（如已打印面单）→ 按钮转灰；仍可点（会先二次确认） */
  .pack-card .pk-acts .btn.printed { background: var(--panel-2); color: var(--muted);
    border-color: var(--border); }
  /* 操作条附属：全选本页 / 分页 */
  .pack-allchk { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; cursor: pointer;
    color: var(--text); }
  .pack-allchk input { width: 15px; height: 15px; cursor: pointer; accent-color: var(--success); }
  .pack-pager { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; font-size: 13px; }
  .pack-empty { color: var(--muted); padding: 30px; text-align: center; }
  @media (max-width: 1500px) {
    .pack-card { grid-template-columns: 175px 300px minmax(0, 1fr) 225px 170px; }
    /* 草稿箱：goods / 店铺 / 采购单号 / 状态时间 / 操作（顺序不同，列宽跟着单独排） */
    .pack-card.pk-draft { grid-template-columns: 300px minmax(0, 1fr) 175px 225px 170px; }
    .pack-item img { width: 120px; height: 120px; }
  }
  @media (max-width: 1200px) {
    .pack-card { grid-template-columns: 1fr 1fr; }
    .pack-card > .pk-track, .pack-card > .pk-goods, .pack-card > .pk-plat, .pack-card > .pk-info {
      border-right: 0; border-bottom: 1px dashed var(--border); }
    .pack-card > .pk-acts { grid-column: 1 / -1; grid-template-columns: repeat(3, 1fr); }
  }

  /* ===== 财务报表（P&L，2026-09-23 开发 / 2026-09-29 摘取上线补回 CSS） ===== */
  .fin-warn { margin: 10px 0; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--border);
              background: var(--panel-2); color: var(--text); font-size: 13px; line-height: 1.75; }
  .fin-warn.warn { border-color: var(--warn); }
  .fin-warn b { color: var(--warn); }
  .fin-pos { color: var(--success); font-weight: 700; }
  .fin-neg { color: var(--danger); font-weight: 700; }
  /* 单品经营：规格列截断 + 缩略图列（2026-10-18 用户要求；放大用 UI-016 全局机制） */
  #spTable th.sp-img-col { width: 52px; }
  #spTable td.sp-sku { max-width: 230px; }
  #spTable .sp-spec { display: block; max-width: 214px; overflow: hidden; text-overflow: ellipsis;
    white-space: nowrap; font-size: 11.5px; color: var(--muted); }
  #spTable img.zoomable { width: 40px; height: 40px; object-fit: cover; border-radius: 4px; display: block; }
  .sp-pane { padding-top: 2px; }
  /* 经营分析加载态（2026-10-18 用户要求「加个加载动画」）：
     骨架块 + 顶部 indeterminate 进度条。让 3~4s 的等待有明确反馈，不是白屏。 */
  #bizLoadBar { height: 3px; margin: 2px 0 8px; border-radius: 2px; overflow: hidden;
    background: rgba(128,128,128,.15); display: none; }
  #bizLoadBar.on { display: block; }
  #bizLoadBar i { display: block; height: 100%; width: 35%; border-radius: 2px;
    background: var(--accent); animation: bizBarMove 1.1s ease-in-out infinite; }
  @keyframes bizBarMove { 0% { transform: translateX(-100%); } 100% { transform: translateX(320%); } }
  .biz-skel { background: linear-gradient(90deg, rgba(128,128,128,.10) 25%,
    rgba(128,128,128,.22) 37%, rgba(128,128,128,.10) 63%);
    background-size: 400% 100%; border-radius: 4px; animation: bizShimmer 1.25s ease-in-out infinite; }
  @keyframes bizShimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }
  .biz-skel-line { height: 11px; margin: 5px 0; }
  /* 经营分析：可排序表头（2026-10-17 用户要求「其他列数也要能排」） */
  #bizOpTable th[data-sk], #bizStoreTable th[data-sk] { cursor: pointer; user-select: none; white-space: nowrap; }
  #bizOpTable th[data-sk]:hover, #bizStoreTable th[data-sk]:hover { color: var(--accent); }
  .biz-arrow { font-size: 9px; margin-left: 3px; opacity: .3; }
  .biz-arrow.on { opacity: 1; color: var(--accent); }
  /* 运营行展开：名下店铺明细（默认折叠） */
  .op-toggle { cursor: pointer; }
  .op-toggle:hover { color: var(--accent); text-decoration: underline; }
  .biz-opdetail > td { background: rgba(127, 119, 221, .07); padding: 8px 10px !important; }
  .biz-opdetail table { width: 100%; background: transparent; }
  .biz-opdetail table th, .biz-opdetail table td { padding: 3px 8px; font-size: 12.5px; border: none; }
  .biz-opdetail table th { color: var(--muted); font-weight: 500; border-bottom: 1px solid var(--border); }
  .biz-opdetail .opd-hint { font-size: 11.5px; color: var(--muted); margin-bottom: 4px; }
  .fin-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px 12px; margin: 4px 0 14px; }
  @media (max-width: 980px) { .fin-kpis { grid-template-columns: repeat(2, 1fr); } }
  .fin-kpi {
    padding: 12px 14px; border-radius: 10px;
    background: var(--panel-2); border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
  }
  .fin-kpi.g-success { border-left-color: var(--success); }
  .fin-kpi.g-warn { border-left-color: var(--warn); }
  .fin-kpi.g-muted { border-left-color: var(--border); }
  .fin-kpi .k { font-size: 12px; color: var(--muted); }
  .fin-kpi .v { font-size: 22px; font-weight: 700; margin-top: 4px; line-height: 1.15; font-variant-numeric: tabular-nums; }
  .fin-kpi .s { font-size: 11px; color: var(--muted); margin-top: 3px; }
  .fin-legs { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start; }
  @media (max-width: 980px) { .fin-legs { grid-template-columns: 1fr; } }
  .fin-card {
    background: var(--panel); border: 1px solid var(--border);
    border-radius: 12px; padding: 14px 16px; min-width: 0;
  }
  .fin-card-title { font-size: 13px; font-weight: 600; margin-bottom: 10px; }
  .fin-card-sub { font-weight: 400; font-size: 11.5px; color: var(--muted); margin-left: 6px; }
  .fin-leg-table { width: 100%; border-collapse: collapse; font-size: 13px; }
  /* 2026-10-17：成本腿改双列（按实重 / 按选品源）→ 需要表头 */
  .fin-leg-table th { text-align: left; font-weight: 500; color: var(--muted); font-size: 11.5px;
    padding: 0 0 4px; border-bottom: 1px solid var(--border); }
  .fin-leg-table th.num { text-align: right; width: 118px; }
  .fin-leg-table th.note { width: auto; }
  .fin-leg-table td { padding: 5px 0; border-bottom: 1px solid var(--border); }
  .fin-leg-table tr:last-child td { border-bottom: none; }
  .fin-leg-table td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; width: 118px; }
  .fin-leg-table td.note { color: var(--muted); font-size: 11.5px; }
  .fin-leg-table tr.sep td { border-top: 2px solid var(--border); font-weight: 700; padding-top: 8px; }
  .fin-leg-table tr.total td { font-weight: 700; }
  #finStoreTable td.num, #finStoreTable th.num,
  #roiOpTable td.num, #roiOpTable th.num,
  #roiStoreTable td.num, #roiStoreTable th.num,
  #wdTable td.num, #wdTable th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
  /* 2026-10-17：分店明细成本拆分列的表头悬浮提示（ⓘ） */
  #roiStoreTable th sup { cursor: help; font-size: 10px; margin-left: 2px; color: var(--muted);
    border-radius: 50%; padding: 0 1px; }
  #roiStoreTable th sup:hover { color: var(--accent); background: rgba(127,127,127,.15); }
  #view-finance h3 { margin: 24px 0 8px; font-size: 15px; }
  #view-finance .ui-bar input[type="text"],
  #view-finance .ui-bar input[type="number"] { max-width: 170px; }

  /* ===== 系统设置（配置中心 CONFIG_CENTER_PLAN.md，2026-09-29） ===== */
  .settings-hint { color: var(--muted); font-size: 12.5px; line-height: 1.7; margin: 0 0 12px; }/* [2026-10-07 并轨] 原 `.settings-nav-btn` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.settings-nav-btn:hover` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.settings-nav-btn.active` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.settings-nav-btn:disabled` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 */
  .settings-panel .tbl td, .settings-panel .tbl th { padding: 7px 9px; font-size: 12.5px; }
  .pack-item .pi-spec { color: var(--muted); font-size: 12px; }
  .pack-item .pi-qty { font-weight: 700; }
  /* ③ 平台/物流/条码列 */
  .pack-col-plat { flex: 1 1 220px; display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; line-height: 1.55; }
  .pack-col-plat .pk-store { color: var(--text); }
  .pack-col-plat .pk-qty { color: #409eff; }
  /* ④ 状态信息列：状态/截止出货/出库重量/备注 */
  .pack-col-info { flex: 0 0 240px; display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; line-height: 1.55; }
  .pack-col-info .pk-muted { color: var(--muted); }
  .pack-col-info b { font-weight: 600; }
  .pack-badge { display: inline-block; font-size: 12px; padding: 1px 8px; border-radius: 999px; font-weight: 600; }
  .pack-badge.b-wait { background: rgba(0,0,0,.06); color: var(--muted); }
  .pack-badge.b-packed { background: rgba(29,158,117,.18); color: var(--success); }
  .pack-badge.b-problem { background: rgba(214,69,69,.18); color: var(--danger); }
  /* 到仓问题件「已处理」→ 卡头「问题件」徽标 + **整卡外边框**一起变绿
     （2026-10-15 用户口径：「订单号左边的问题件三个字变绿，整卡的外边框变绿」）。
     红 = 待处理（异常中，等采购/运营核实）→ 绿 = 已处理（打单员看到绿即知：
     这单已经有人管了，接下来等新货到仓 / 假库存打单）。
     ⚠️ 选择器以 .pack-card.issue-done 作前缀提特异性（0,3,0），压过本文件里
        两处同名的 .pack-badge.b-problem（0,2,0）—— 不依赖书写顺序，避免以后挪动区块时失效。 */
  /* ★ `:not(.packed)` 不可省：已打包是**终态**，它的中性灰边框优先于「已处理问题件」的绿 ——
     否则同特异性下后定义的 .issue-done 会赢，绿色又被打包卡占回去（就是用户报的那个重复）。 */
  .pack-card.issue-done:not(.packed) { border-color: var(--success); }
  .pack-card.issue-done .pack-badge.b-problem {
    background: rgba(29,158,117,.18); color: var(--success); }
  .pack-weight { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
  .pack-weight input { width: 58px; padding: 2px 5px; border: 1px solid var(--border); border-radius: 6px; background: var(--panel-2); color: var(--text); font-size: 12px; }
  .pack-weight .vol { color: #409eff; font-size: 12px; }
  .pack-weight .w-save { padding: 2px 8px; font-size: 12px; cursor: pointer; }
  .pack-note { width: 100%; padding: 3px 6px; border: 1px solid var(--border); border-radius: 6px; background: var(--panel-2); color: var(--text); font-size: 12px; resize: vertical; }
  /* ⑤ 动作按钮列：竖排，对标跨境巴士右侧按钮堆 */
  .pack-col-acts { flex: 0 0 96px; display: flex; flex-direction: column; gap: 5px; justify-content: center; }
  .pack-col-acts .btn { padding: 4px 6px; font-size: 12.5px; width: 100%; text-align: center; }
  .pack-col-acts .btn.danger { color: #fff; background: var(--danger); border-color: var(--danger); }
  .pack-empty { color: var(--muted); padding: 30px; text-align: center; }
  @media (max-width: 1100px) { .pack-card .pack-body { flex-wrap: wrap; } .pack-col-acts { flex-direction: row; flex-wrap: wrap; flex-basis: 100%; } }

  /* =========================================================================
     主题：常规白色底（2026-09-24 加）
     · 切主题只覆盖 CSS 变量，布局/尺寸/交互一律不动；
     · 另对被写死的「深色底专用浅色字」（状态徽标等）逐个给浅色变体，
       否则白底上会变成浅色字压白底、基本看不见；
     · 放在样式块**末尾**，同特异度下靠顺序覆盖前面的深色规则；
     · color-scheme 让 select / 日期选择器 / 滚动条等原生控件跟着变浅色。
     ========================================================================= */
  html[data-theme="light"] {
    --bg: #f4f5f7;
    --panel: #ffffff;
    --panel-2: #eceef2;
    --text: #1f2430;
    --muted: #6b7280;
    --accent: #5b54d6;
    --border: #d7dbe2;
    --success: #0f7a55;
    --danger: #c02b2f;
    --warn: #a06008;
    --note-ink: #c8342c;
    color-scheme: light;
  }
  /* 状态徽标：发货状态 */
  html[data-theme="light"] .ship.s-wait { color: #475569; }
  html[data-theme="light"] .ship.s-shipped { color: #1d4ed8; }
  html[data-theme="light"] .ship.s-transit { color: #7e22ce; }
  html[data-theme="light"] .ship.s-delivered { color: #15803d; }
  html[data-theme="light"] .ship.s-cancel { color: #b91c1c; }
  /* 状态徽标：ERP 处理进度 */
  html[data-theme="light"] .erp.e-unbuy { color: #92400e; }
  html[data-theme="light"] .erp.e-buy { color: #15803d; }
  html[data-theme="light"] .erp.e-stock { color: #7e22ce; }
  html[data-theme="light"] .erp.e-split { color: #b91c1c; background: rgba(239,68,68,.14); }
  html[data-theme="light"] .erp.e-merged { color: #0369a1; }
  html[data-theme="light"] .ops-sim-banner { color: #92400e; background: rgba(250,204,21,.14); }
  html[data-theme="light"] .erp.e-pushed { color: #0369a1; }
  html[data-theme="light"] .erp.e-noship { color: #b91c1c; }
  html[data-theme="light"] .erp.e-pack { color: #0f766e; }
  html[data-theme="light"] .erp.e-selfbuy { color: #a21caf; }
  html[data-theme="light"] .erp.e-issue { color: #b45309; }
  html[data-theme="light"] .erp.e-hist { color: #475569; background: rgba(100,116,139,.14); }
  /* 盈亏配色：深色底用提亮色，白底要压深才读得清 */
  html[data-theme="light"] .rep-margin-pos { color: #0f7a55; }
  html[data-theme="light"] .rep-margin-neg { color: #c02b2f; }
  html[data-theme="light"] .rep-card .v.profit { color: #0f7a55; }
  html[data-theme="light"] .rep-card .v.loss { color: #c02b2f; }
  html[data-theme="light"] #view-ops .ops-orders-table td.oo-profit.rep-margin-pos { color: #0b6b4a; }
  html[data-theme="light"] #view-ops .ops-orders-table td.oo-profit.rep-margin-neg { color: #b02528; }
  html[data-theme="light"] #view-ops .ops-orders-table th.oo-cost { color: #8a5510; }
  html[data-theme="light"] .rep-flag { color: #b02528; }
  /* 核对参考列（紫）/ SKU 截断展开的 hover 提示 */
  html[data-theme="light"] #view-ops .rep-table th.col-check { color: #4b45c6; }
  html[data-theme="light"] #view-ops .ops-orders-table td.oo-sku:hover { color: #4b45c6; }
  /* 备注单元格的 hover/focus 底色：原为「白 3%」提亮，白底上改「黑 3%」压深 */
  html[data-theme="light"] .oo-note:hover { background: rgba(0,0,0,.035); }
  html[data-theme="light"] .oo-note:focus { background: rgba(91,84,214,.07); }
  /* 表格 hover：深色主题靠提亮一档，白底改成浅灰一档（--panel-2 已够浅，再补一点灰） */
  html[data-theme="light"] tr:hover td { background: #e9ecf1; }
  html[data-theme="light"] #view-ops .ops-orders-table tr.rep-row.row-checked > td { background: rgba(91,84,214,.10); }
  /* 小字灰：深色底用的 #8a93a6 在白底偏淡 */
  html[data-theme="light"] .sync-row .tag { color: #6b7280; }
  /* 抽奖/统计条等零散提亮色 */
  html[data-theme="light"] .pm-gain { color: #15803d; }
  html[data-theme="light"] .pm-loss { color: #b02528; }
  html[data-theme="light"] .orders-modal-summary .m-pending { color: #6b7280; }
  html[data-theme="light"] .proc-card .done-tag.exported-hist { color: #6b7280; }
  html[data-theme="light"] .flow-tag.st-noship { color: #6b7280; }
  /* 主题切换按钮（左上角） */
  .theme-btn {
    display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto;
    background: var(--panel-2); color: var(--text); border: 1px solid var(--border);
    padding: 6px 11px; border-radius: 8px; cursor: pointer; font-size: 12.5px;
  }
  .theme-btn:hover { border-color: var(--accent); color: var(--accent); }
  .theme-btn .tb-ico { font-size: 14px; line-height: 1; }
  /* ===== 仓配异常（2026-09-26：未到仓迁入作首个面板 / 已到仓 / 质检取消 / 消息解析）=====
     四条线是同一条履约链的不同阶段（未到仓 → 到仓 → 问题件/假单），
     样式各自成块，不与采购卡混用，避免改一处动全身。 */
  /* ---- 未到仓专用工具条（2026-09-26 优化：仅未到仓面板显示）---- */
  /* 未到仓筛选区（2026-10-07 换装）：外壳保留灰底卡片感，内部拆成 3 个语义行 .ui-bar
     （① 统计 / ② 筛选维度 / ③ 视图控制），解决原先 20+ 控件挤成一行的拥挤问题。 */
  .na-bars { border: 1px solid var(--border); border-radius: var(--ctl-radius);
             background: var(--panel-2); padding: var(--sp-2) var(--sp-3) 0; }
  .na-bars .ui-bar { margin-bottom: var(--sp-2); }
  .na-bars .na-stat { font-size: var(--fs-body); }
  .na-bars .na-crit { color: var(--danger); font-weight: 600; }
  .na-bars .na-warn { color: var(--warn); font-weight: 600; }/* [2026-10-07 并轨] 原 `.na-toolbar input[type="text"]` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.na-toolbar select` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 */
  .na-gap { margin-left: auto; }
  /* [2026-10-07 并轨] 原 `.na-chip` / `.na-chip:hover` / `.na-chip.active` 三条规则
     已并入 style.css 顶部 Layer 2 组件层（`.ui-chip` 组），此处删除以免后定义者覆盖。
     `.na-chip-warn` 变体（下方）与 `.na-chip b` 计数样式保留 —— 前者特异性更高、仍生效。 */
  /* 「欧众已备货」这条排除规则带风险（口径上「备货完成 ≠ 已发货」），未启用时用琥珀色描边
     提醒「这条和后两条不是一个性质」；启用后仍走统一的 active 蓝，避免两套颜色打架。 */
  .na-chip.na-chip-warn:not(.active) { border-color: #d97706; color: #d97706; }
  .na-chip.na-chip-warn:not(.active):hover { background: rgba(217,119,6,.12); color: #d97706; }
  .na-chip b { font-weight: 700; margin-left: 2px; }
  .na-more { display: block; width: 100%; margin: 10px 0; padding: 10px; font-size: 13px; }
  #naList { display: flex; flex-direction: column; gap: 8px; }
  /* ---- 未到仓卡片（2026-09-26 改版：对齐采购看板「分组卡」骨架 + 时间线）----
     骨架：左商品 / 中数量 / 右采购单号+排查进度；下方时间线（下单 → 预报 → 逾期）+ 明细订单。 */
  .na-card { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px;
             border: 1px solid var(--border); border-radius: 10px; background: var(--panel); }
  .na-card.crit { border-left: 4px solid var(--danger); }
  .na-card.warn { border-left: 4px solid var(--warn); }
  .na-card.ok   { border-left: 4px solid var(--success); }
  /* 通用行容器：未到仓侧栏用 .na-progline；消息解析预览仍用 .na-head（同一套横排布局）*/
  .na-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .na-body { display: flex; gap: 14px; align-items: flex-start; flex-wrap: wrap; }
  .na-goods { flex: 1 1 280px; min-width: 240px; display: flex; flex-direction: column; gap: 5px; }
  .na-item { display: flex; align-items: center; gap: 7px; min-width: 0; }
  .na-thumb { width: 38px; height: 38px; object-fit: cover; border-radius: 5px;
              background: var(--panel-2); flex: none; }
  .na-item-txt { font-size: 12px; line-height: 1.35; min-width: 0; }
  .na-spec { color: var(--muted); white-space: nowrap; overflow: hidden;
             text-overflow: ellipsis; max-width: 300px; }
  .na-nums { flex: 0 0 156px; display: flex; gap: 8px; }
  .na-num { flex: 1; text-align: center; padding: 6px 4px; border-radius: 8px; background: var(--panel-2); }
  .na-num i { display: block; font-style: normal; font-size: 11px; color: var(--muted); }
  .na-num b { font-size: 16px; font-weight: 600; }
  .na-side { flex: 0 0 292px; display: flex; flex-direction: column; gap: 6px; }
  .na-po { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 13px; font-weight: 600; }
  .na-progline { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
  /* ---- 时间线：下单 → 预报 → 逾期 ---- */
  .na-tl { display: flex; align-items: center; gap: 8px;
           border-top: 1px dashed var(--border); padding-top: 8px; }
  .na-tl-date { font-size: 11.5px; color: var(--muted); white-space: nowrap;
                font-variant-numeric: tabular-nums; }
  .na-tl-track { position: relative; flex: 1; height: 8px; border-radius: 4px; min-width: 110px;
                 background: var(--panel-2); border: 1px solid var(--border); }
  .na-tl-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 4px; }
  .na-tl-fill.ok { background: var(--success); }
  .na-tl-fill.warn { background: var(--warn); }
  .na-tl-fill.crit { background: var(--danger); }
  .na-tl-mark { position: absolute; top: -4px; width: 12px; height: 12px; border-radius: 50%;
                box-sizing: content-box; border: 2px solid var(--panel); }
  .na-tl-mark.now { background: var(--text); }
  .na-tl-mark.fc { top: -6px; width: 16px; height: 16px; background: var(--accent); }
  .na-tl-badge { font-size: 11.5px; padding: 2px 9px; border-radius: 10px; white-space: nowrap; }
  .na-tl-badge.ok { background: rgba(29,158,117,.18); color: var(--success); }
  .na-tl-badge.warn { background: rgba(239,159,39,.18); color: var(--warn); }
  .na-tl-badge.crit { background: rgba(226,75,74,.18); color: var(--danger); }

  /* ---- 未到仓 v2（2026-09-28 用户口径：与采购看板同构的分块卡）----
     ① 大图区 ② 分 SKU 区块 ③ 数量构成 ④ 跟进/回填 ⑤ 操作按钮
     这里的类一律前缀 na2-，避免与采购看板的 proc-* 语义混淆（视觉复用 proc-*）。 */

  /* ---- 未到仓卡片改造（2026-10-06，docs/NA_VIEW_UI_REDESIGN_PROPOSAL.md（已退役→PLAN-NA-VIEW） v2）----
     ③数量构成/④跟进回填/⑤操作 三块 → **单个状态区 .na2-track**（右区）+ **瀑布流双列**。
     为什么双列：实测未到仓在办 53 组里 **50 组只有 1 个 SKU**（42 组只有 1 笔订单），
     却用 `flex-direction: column` 一张卡占满整行 ⇒ 横向空间大量浪费、纵向翻页 20 屏。
     改双列瀑布流后 1080p 一屏可见 2→6~8 张卡（50 张从 ~20 屏降到 ~7 屏）。
     ⚠️ 用 column-count 而非 grid：卡高悬殊（那 2 组有 29/36 笔订单），
        grid 会强制同行等高留大片空白；多列瀑布流让每列独立流动。 */
  #naList { display: block; column-gap: 10px; }
  #naList .na2-card { break-inside: avoid; margin-bottom: 10px; display: inline-block; width: 100%; }
  @media (min-width: 1500px) { #naList { column-count: 2; } }
  @media (max-width: 1499px)  { #naList { column-count: 1; } }

  /* 状态区：五个状态按钮（一次点击即生效）+ 备注（失焦即存）+ 重购单号
     ★ 2026-10-07：档位定为 5 档，2 列网格下自然成 3 行 —— 前两行是主线四档
     （待跟进 / 转采购处理 / 已联系商家 / 已重新购买），末行单列是旁路「无需处理」，
     流程与旁路在视觉上正好分开。 */
  .na2-track { gap: 8px; flex: 0 1 300px; }
  /* ⚠️ 卡片改成双列瀑布流后单卡只有 ~774px 宽，而 .proc-body 是 flex-wrap: wrap，
     .na2-skus 有 min-width:320px ⇒ 状态区会被挤到**下一行**（实测 trackRightOf=false）。
     这里把状态区固定到右侧一列、订单信息自适应，避免瀑布流下左信息区把右区顶下去。 */
  #naList .na2-card .proc-body { flex-wrap: nowrap; align-items: flex-start; }
  #naList .na2-card .na2-skus { flex: 1 1 auto; min-width: 0; }
  #naList .na2-card .na2-thumb { width: 72px; height: 72px; }   /* 双列下 104px 大图过大 */
  .na2-statebtns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 5px; }
  .na2-st { width: 100%; font-size: 12.5px; padding: 7px 4px; line-height: 1.3; }
  /* ⚠️ 2026-10-06 用户口径修正：**激活态必须逐档可辨**。
     之前几档全用 var(--accent)（同一个紫），所以「全部」视图下
     50 张卡全是一片紫 —— 运营根本看不出某张卡到底停在哪一档。
     ★ 2026-10-07 档位定为 5 档后一档一色，并按**归属**冷暖分组：
       运营侧（暖）：待跟进=琥珀(要动) / 无需处理=绿(办结)；
       采购侧（冷）：待采购处理=蓝(已交出去) / 已联系商家=青(等商家回) / 已重新购买=紫(换货了)。
     🚨 选择器里的档位名必须与 warehouse.TRACK_PROGRESS **逐字一致** —— 档位改名后
        旧选择器会**静默失效**（按钮退回默认底色，控制台不报错），改档位表时务必同改这里。 */
  .na2-st.on { font-weight: 600; color: #fff; border-color: transparent; }
  .na2-st[data-prog="待跟进"].on     { background: #d97706; }
  .na2-st[data-prog="待采购处理"].on { background: #2563eb; }
  .na2-st[data-prog="已联系商家"].on { background: #0891b2; }
  .na2-st[data-prog="已重新购买"].on { background: #7c3aed; }
  .na2-st[data-prog="无需处理"].on   { background: #1d9e75; }
  /* ★ 2026-10-07 归属提示（用户口径③「运营这边作为一个总的全流程视图，但不用运营操作」）：
     采购的三档照常显示；**但运营不能点它们**（用户 2026-10-07 追加口径：
     「运营还能点击已联系商家和已重新购买，原则上这个入口只能通过采购那边反馈过来才点亮」）
     ⇒ 用 .ro（read-only）标出"这档不归你动手"，而不是藏掉按钮 —— 藏了就看不出版流程走到哪。 */
  .na2-st:not(.on).own-pu { border-color: rgba(99,102,241,.45); color: #a5b4fc; }
  .na2-st:not(.on).own-pu:hover { border-color: rgba(99,102,241,.85); opacity: .95; }
  /* 未激活档位：明确压灰并去掉 hover 变色 —— 否则「看不出当前在哪一档」 */
  .na2-st:not(.on) { background: var(--panel); color: var(--muted); opacity: .6; }
  .na2-st:not(.on):hover { opacity: .95; border-color: var(--border); }
  /* ★ 2026-10-07「只读档」（.ro）：运营侧那两颗采购档按钮 —— 只能由采购动手后
     **反馈回来点亮**，运营点了不生效（同时置 `disabled`，见 naCardHtml）。
     与 .dis 的区别（刻意不复用 .dis）：
       · .dis 带 `filter: grayscale(1)` —— 会连**激活态**一起褪成灰，
         而这里恰恰要求"采购点亮后保留档位原色"（这就是用户说的「点亮」）；
       · .ro 只压"未点亮"那半边：虚线描边 = 这件事还没发生过。
      ⇒ 未点亮：淡、虚线、不可点；点亮：走上面的 data-prog 配色，仅禁用手势。

     ★ 2026-10-07 追加第二种「只读」用途（用户口径：「当采购标记过状态之后，运营看板还能
       恢复成待跟进和转采购处理，是否也一并归类为不可点击状态，等待订单自动完结」）：
       采购动过手之后，流程**只进不退** ⇒ 运营侧的「待跟进 / 转采购处理」也套 .ro。
       两类共用一套视觉是**刻意**的 —— 对运营来说都是同一个意思：「这颗现在点不了」，
       差别只在 tooltip 里说清为什么（角色不归你 / 流程不可退回）。
       ⚠️ 别给第二类另造样式：同一个"点不动"用两种长相，反而会让人以为页面坏了。 */
  .na2-st.ro { cursor: not-allowed; }
  .na2-st.ro:not(.on) { opacity: .3; border-style: dashed; }
  .na2-st.ro:not(.on):hover { opacity: .3; background: var(--panel); border-color: var(--border); }
  .na2-st.ro.on { cursor: not-allowed; }
  /* 「本组无我名下订单」⇒ 禁用写操作（2026-10-06 用户口径）。
     ⚠️ 用 `disabled` + 灰化**双保险**：光靠 CSS 灰化拦不住点击，
     而灰化但不置 disabled 会让运营以为页面坏了。
     ⚠️ grayscale(1) 会把四档彩色激活态一并褪成灰 —— 这是**故意的**：
        无我名下订单时该卡只能看不能改，彩色会误导成「我标的」。
     ⚠️ 与上面的 .ro 是两回事、可同时命中（noMine 时以 .dis 为准）：
        .dis = 你**本来能标**但本组没你的单；.ro = 这档**从头就不归你**标。 */
  .na2-st.dis, .na2-st.dis.on { opacity: .42; cursor: not-allowed; filter: grayscale(1); }
  .na2-st.dis:hover { background: inherit; border-color: var(--border); }
  .na2-st.dis:not(.on):hover { background: var(--panel); }
  /* ★ 2026-10-08 采购侧「撤销处理」（用户口径「采购侧可以给一个撤销处理的按钮」）：
     它是**纠错出口**，不是流程节点 ⇒ 视觉上必须比档位按钮弱一档，不能抢注意力。
     做法：单列整行（不挤进 .na2-statebtns 的两列格）+ 降低不透明度。
     ⚠️ 不要复用 .dis 的 `filter: grayscale(1)` —— 那会把文字一起褪掉；
        这里只是"低调"，按钮本身完全可用。 */
  .na2-undorow { margin-top: 6px; }
  .na2-undo { width: 100%; font-size: 12px; padding: 5px 4px; line-height: 1.3; opacity: .8; }
  .na2-undo:hover { opacity: 1; }
  /* 当前状态文字行（2026-10-06）：颜色与对应激活按钮**同一套**，
     保证「文字说的」和「按钮亮的」永远是同一个状态，不会打架。 */
  .na2-curstate { font-size: 12px; color: var(--muted); line-height: 1.4;
                  padding: 3px 7px; border-radius: 6px; background: var(--panel);
                  border: 1px solid var(--border); }
  .na2-curstate b { color: var(--text); font-weight: 600; }
  .na2-curstate[data-cur="待跟进"] b     { color: #d97706; }
  .na2-curstate[data-cur="待采购处理"] b { color: #60a5fa; }
  .na2-curstate[data-cur="已联系商家"] b { color: #22d3ee; }
  .na2-curstate[data-cur="已重新购买"] b { color: #a78bfa; }
  .na2-curstate[data-cur="无需处理"] b   { color: #34d399; }
  /* 「推进方：运营 / 采购」徽标（★ 2026-10-07）—— 卡片上一眼看出「这单现在轮到谁」。
     归属由档位推导（warehouse.NA_PROGRESS_OWNER），卡片不存这个字段。 */
  .na2-owner { margin-left: 6px; font-size: 11px; padding: 1px 7px; border-radius: 999px;
               white-space: nowrap; border: 1px solid transparent; }
  .na2-owner.op { color: #fbbf24; background: rgba(217,119,6,.14); border-color: rgba(217,119,6,.45); }
  .na2-owner.pu { color: #a5b4fc; background: rgba(99,102,241,.14); border-color: rgba(99,102,241,.45); }
  .na2-nomine { color: var(--muted); font-size: 11px; line-height: 1.45; }
  .na2-notewrap { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
  .na2-notetag { flex: none; font-size: 11px; padding: 2px 6px; border-radius: 4px;
                  background: var(--panel); border: 1px solid var(--border); color: var(--muted); }
  .na2-note { flex: 1 1 150px; min-width: 0; font-size: 12px; padding: 5px 7px;
              border-radius: 6px; border: 1px solid var(--border); background: var(--panel); color: var(--text); }
  .na2-note:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
  /* 留痕：谁标的 / 谁填的备注。跨运营共享状态下这是唯一互相告知的线索 */
  .na2-trace { flex: none; font-size: 11px; color: var(--muted); white-space: nowrap; }
  .na2-rebuy { display: flex; flex-direction: column; gap: 5px; padding-top: 7px;
               border-top: 1px dashed var(--border); }
  .na2-rebuy-row { display: flex; gap: 5px; }
  .na2-rebuy-row input { flex: 1 1 90px; min-width: 0; font-size: 12px; padding: 5px 7px;
                         border-radius: 6px; border: 1px solid var(--border);
                         background: var(--panel); color: var(--text); }
  .na2-busync { width: 100%; font-size: 11.5px; }

  #naList .na2-card { position: relative; }
  .na2-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .na2-po { font-family: ui-monospace, Consolas, monospace; font-size: 14px; font-weight: 700;
            color: var(--accent); letter-spacing: .3px; }
  .na2-thumb { width: 104px; height: 104px; flex: none; border-radius: 9px; overflow: hidden;
               background: var(--panel-2); border: 1px solid var(--border);
               display: flex; align-items: center; justify-content: center; }
  .na2-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .na2-thumb span { font-size: 11px; color: var(--muted); }
  .na2-skus { flex: 1 1 420px; min-width: 320px; display: flex; flex-direction: column; gap: 6px; }
  .na2-skus-title { font-size: 11px; color: var(--muted); font-weight: 600; letter-spacing: .3px; }
  .na2-sku { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 8px;
             background: var(--panel-2); border: 1px solid var(--border); flex-wrap: wrap; }
  .na2-sku.picked { border-color: var(--accent); background: rgba(47,111,176,.13); }
  .na2-sku img { width: 40px; height: 40px; border-radius: 6px; object-fit: cover; flex: none; }
  .na2-sku-main { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1 1 160px; }
  .na2-sku-code { font-family: ui-monospace, Consolas, monospace; font-size: 12px; font-weight: 600; }
  .na2-sku-spec { font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis;
                  white-space: nowrap; max-width: 230px; }
  .na2-sku-num { font-size: 11.5px; color: var(--muted); white-space: nowrap; }
  .na2-sku-num b { color: var(--text); font-size: 13px; }
  .na2-orders { flex: 1 1 220px; display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
  .na2-pick { display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
              padding: 3px 8px; border-radius: 6px; font-size: 12px;
              background: var(--panel-2); border: 1px solid var(--border); }
  .na2-pick.on { background: rgba(47,111,176,.18); border-color: var(--accent); }
  .na2-pick input { cursor: pointer; margin: 0; }
  .na2-pick .oq { color: var(--muted); margin-left: 3px; }
  .na2-block { display: flex; flex-direction: column; gap: 6px; padding: 8px 10px; border-radius: 9px;
               background: var(--panel-2); border: 1px solid var(--border); }
  .na2-nums { display: flex; gap: 8px; flex-wrap: wrap; }
  .na2-num { display: flex; flex-direction: column; align-items: center; min-width: 62px;
             padding: 5px 9px; border-radius: 8px; background: var(--panel-2);
             border: 1px solid var(--border); }
  .na2-num i { font-style: normal; font-size: 11px; color: var(--muted); white-space: nowrap; }
  .na2-num b { font-size: 17px; font-variant-numeric: tabular-nums; }
  .na2-num.todo b { color: var(--warn); }
  .na2-num.done b { color: var(--success); }
  .na2-num.all b { color: var(--text); }
  .na2-ops { display: flex; flex-direction: column; gap: 6px; min-width: 190px; }
  .na2-ops .btn { width: 100%; }
  .na2-ops-row { display: flex; gap: 6px; }
  .na2-ops-row .btn { flex: 1; }
  .na2-done-tag { display: inline-block; padding: 2px 8px; border-radius: 6px; font-size: 12px;
                  font-weight: 600; background: rgba(107,114,128,.22); color: #9ca3af;
                  border: 1px solid rgba(107,114,128,.5); }
  /* ★ 2026-10-07：未到仓卡头「快递单号已回填」徽标（组级）—— full=全部回填(绿) / none=全未回填(灰) */
  .na2-trk-badge { display: inline-block; padding: 2px 8px; border-radius: 6px; font-size: 12px;
                   font-weight: 600; background: rgba(29,158,117,.16); color: var(--success);
                   border: 1px solid rgba(29,158,117,.5); }
  .na2-trk-badge.none { background: rgba(136,135,128,.16); color: var(--muted);
                        border-color: rgba(136,135,128,.5); }
  /* ★ 2026-10-08 聚合键类型徽标（无采购单号的卡：库存流占位 / 按快递单号）——
     与「已回填 / 未回填」徽标同尺寸，避免卡头一行里高低不齐。 */
  .na-keytag { display: inline-block; padding: 2px 8px; border-radius: 6px; font-size: 12px;
               font-weight: 600; white-space: nowrap; }
  .na-keytag.batch { background: rgba(124,92,255,.16); color: #7c5cff;
                     border: 1px solid rgba(124,92,255,.5); }
  .na-keytag.trk { background: rgba(45,140,240,.16); color: #2d8cf0;
                   border: 1px solid rgba(45,140,240,.5); }
  .na-keytag.none { background: rgba(136,135,128,.16); color: var(--muted);
                    border: 1px solid rgba(136,135,128,.5); }
  .na2-info-line { font-size: 11.5px; color: var(--muted); }
  .na2-info-line b { color: var(--text); }
  .na2-sku-orders { font-size: 11px; color: var(--muted); }

  /* ---- 仓配异常全局筛选（运营 → 归属店铺 二级，2026-09-28：复用运营看板方式、不做日期）---- */
  .wh-global-filter { flex-wrap: wrap; row-gap: 6px; }
  .wh-global-filter #whStore { max-width: 230px; }
  /* ---- 未到仓阶段分区条（按「下单 + 12 天自动取消」倒排，用户 2026-09-28 口径）---- */
  .na-phasebar { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
                 margin: 0 0 10px; padding: 6px 10px; border: 1px solid var(--border);
                 border-radius: 10px; background: var(--panel-2); }
  /* [2026-10-07 并轨] 原 `.na-phase` / `.na-phase:hover` / `.na-phase.active` 三条规则
     已并入 style.css 顶部 Layer 2 组件层（`.ui-chip` 组）；`.na-phase.zero` 亦并入。
     保留 `.na-phase .n`（计数）与 `.u-warn` / `.u-crit`（未到仓特有）不变。 */
  /* ===== 采购看板「未到仓待办」：★ 2026-10-07 **采购侧独立视图**（tab 化） =====
     ① 形态（用户口径：「做在这个位置不太合适，到时候会有几十个上百个这个未处理工单悬挂，
        是否能单开一个 tab 放到不发货订单后边」）：
        由 .ui-head 下的**常驻面板**改为 `#procTabs` 里的第 8 个 tab（`#procNaOnly`）。
        面板默认 `display:none`，只有 `#view-proc.na-only` 时才出现；同一时间把常规采购
        那套（筛选条 / 搜索条 / 列表 / 分页）整体藏掉 —— 否则两份列表一屏堆。
     ② 卡片**复用未到仓的 .na2-* 类** —— 它们绝大多数是全局的，
        只有 3 条被 scoped 到 `#naList .na2-card`（瀑布流 / position / 右区宽度），
        这里按**单列**布局补回等价规则 ⇒ 两处视觉同源、又互不干扰。 */
  .proc-na { display: none; margin: 0 0 12px; border: 1px solid var(--border); border-radius: var(--rad-card); background: var(--panel); }
  #view-proc.na-only .proc-na { display: block; }
  /* 「未到仓待办」tab 独占时：藏掉常规采购的筛选 / 搜索 / 列表 / 分页（四块一起，别漏） */
  #view-proc.na-only .proc-filter,
  #view-proc.na-only .proc-searchbar,
  #view-proc.na-only #procList,
  #view-proc.na-only #procPager { display: none; }
  /* 「到仓问题件」面板（2026-10-15）：与 na-only 同一套独占显隐机制 */
  .proc-pkissue { display: none; margin: 0 0 12px; border: 1px solid var(--border);
    border-radius: var(--rad-card); background: var(--panel); }
  #view-proc.pk-issue-only .proc-pkissue { display: block; }
  #view-proc.pk-issue-only .proc-filter,
  #view-proc.pk-issue-only .proc-searchbar,
  #view-proc.pk-issue-only #procList,
  #view-proc.pk-issue-only #procPager { display: none; }
  .proc-pkissue .ui-count { padding: 1px 9px; border-radius: var(--rad-chip);
    background: rgba(226,107,10,.18); color: #e26b0a; font-variant-numeric: tabular-nums;
    font-size: var(--fs-meta); }
  /* 卡牌网格（2026-10-15 续）：排列直接复用全局 `.issue-board`（运营看板问题件同一套
     3 列自适应网格 + `.issue-card` 竖长方形卡牌），这里只补容器的内边距。
     ⚠️ 原 `.pkissue-card / -main / -type / -acts` 私有类**整段删除** ——
        它们就是「同一件事第 4 套实现」，正是本卡（UI-017）要消除的漂移面。
     状态色沿用全局口径：黄=待处理（`.issue-card.pending` + 默认 `.ic-stamp`）/ 绿=已处理。 */
  .proc-pkissue .issue-board { padding: 12px; }
  .proc-na-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 8px 12px; border-bottom: 1px solid var(--border); }
  .proc-na-head b { font-size: var(--fs-sec); }
  .proc-na-sub { color: var(--muted); font-size: var(--fs-meta); }
  .proc-na-sum { margin-left: auto; color: var(--muted); font-size: var(--fs-meta); font-variant-numeric: tabular-nums; }
  /* 计数徽标：用采购档同一套靛色，和卡片上采购档按钮视觉同源 —— 一眼知道"这是我这边的活" */
  .proc-na .ui-count { padding: 1px 9px; border-radius: var(--rad-chip); background: rgba(99,102,241,.18);
                       color: #a5b4fc; font-size: var(--fs-meta); font-weight: 700; font-variant-numeric: tabular-nums; }
  .proc-na.zero .ui-count { background: rgba(154,154,176,.16); color: var(--muted); }
  .proc-na-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
                 padding: 6px 12px; border-bottom: 1px dashed var(--border); }
  .proc-na-bar input { min-width: 220px; height: var(--ctl-h-sm); }
  /* ★ 2026-10-07 改**瀑布流**（用户口径：「采购看板的未到仓改成瀑布流形式，复用运营看板的模式，
     这样信息能更快处理」）—— 与 `#naList` **同一套写法与断点**（block + column-count +
     inline-block + break-inside:avoid），保证两处视觉同源、宽屏下都是双列。
     原先是单列 flex：卡片靠 `gap` 撑开；瀑布流下 gap 对 column 布局不管用，
     行距改由 `margin-bottom` 承担（与 `#naList` 逐字一致，别一处 margin 一处 gap）。 */
  #procNaList { display: block; column-gap: 10px; padding: 10px 12px; }
  #procNaList .na2-card { break-inside: avoid; margin-bottom: 10px; display: inline-block;
                          width: 100%; position: relative; }
  @media (min-width: 1500px) { #procNaList { column-count: 2; } }
  @media (max-width: 1499px) { #procNaList { column-count: 1; } }
  #procNaList .na2-card .proc-body { flex-wrap: nowrap; align-items: flex-start; }
  #procNaList .na2-card .na2-skus { flex: 1 1 auto; min-width: 0; }
  #procNaList .na2-card .na2-thumb { width: 72px; height: 72px; }
  /* ★ 2026-10-08 用户口径：「采购侧的瀑布流视图 UI 不规整，看看运营侧是如何处理单卡还有
     卡与卡之间关系的」——查下来的**根因就在右区宽度**：
       · `.na2-track` 原本是全局的 `flex: 0 1 300px`（basis 300、可收缩到 min-content），
         它实际拿多宽取决于**左区 `.na2-skus` 内容有多宽**（左区是 `flex: 1 1 auto`）——
         左区内容窄 ⇒ 右区膨胀；左区内容宽 ⇒ 右区被压。**每张卡的左右内容都不一样**
         ⇒ 实测采购侧 5 张卡的右区宽 = 184 / 209 / 351px，同一对档位按钮在
         79px / 91px / 162px 之间来回跳，同一段标题时折行时不折行。这就是"不规整"。
       · 运营侧看起来整齐是**巧合**而非设计：那边每张卡的 SKU 区都塞了「本 SKU 全选」
         标签 + 订单行，内容一律够宽，把右区**一律压到同一个下限 184px**（实测 50 张卡
         全是 184/185）⇒ 按钮尺寸自然全等。换句话说，运营侧的"整齐"来自"全都压到底"。
     ⇒ 采购侧**把右区宽度钉死**，不再参与左右分配：`flex: 0 0 200px`。
        宽度恒定后：两个档位按钮每张卡都是同一个尺寸、标题折行与否也一致（这才是用户要的
        "卡与卡之间的关系"）。剩余空间由左区吸收（`.na2-skus` 已有 `min-width: 0`，
        不会横向溢出）。
     ⚠️ 取 200px（运营侧自然值 184px 同量级、留 ~20px 余量给字体渲染差异）：
        `.na2-track` 内宽 = 200 - 20(padding) = 180，`.na2-statebtns` 两列各 ~87px，
        「已联系商家」这类 5 字按钮（≈63px + 左右 padding 8px = 71px）排得开，
        不会被迫换行或掉成竖排。
     ⚠️ 只覆盖 `#procNaList`，**不动全局 `.na2-track`** —— 运营侧 50 张卡的观感已验收过
        （它当前恒 184 也成立），别为一个页面的毛病去动另一个页面的既有表现。 */
  /* ⚠️ 必须同时给 `min-width: 0`：`.na2-track` 是 flex item，默认 `min-width: auto`
        ⇒ 它会**不小于自身 min-content 宽**，`flex: 0 0 200px` 也压不住。
        实测漏了这条时，带「重购单号」两个输入框 + 长文案「已重新购买 → 新采购单号
        773445027021745」的那张卡仍会被撑到 351px（其余 4 张是 200px）⇒ 又只剩它不齐。
        `min-width: 0` 后宽度严格锁 200，超长内容由内部元素自行换行 / 收缩
        （`.na2-rebuy-row input` 已有 `min-width: 0`，`.na2-curstate` 文本可正常折行）。 */
  #procNaList .na2-card .na2-track { flex: 0 0 200px; min-width: 0; }
  #procNaPager { display: flex; align-items: center; gap: 8px; justify-content: center; padding: 6px 12px 10px; }
  #procNaPager span { color: var(--muted); font-size: var(--fs-meta); }
  /* ★ 2026-10-08 订单行：**不再另起一套**（原 `.pn-ord`：小字号 + 无背景 + `<code>` 单号），
     改为直接复用运营侧的 `.na2-pick` pill —— 两侧同一段内容占位/高度才一致（用户口径：
     「主要是占位保持宽度这些一致，不能太死板」）。
     采购侧唯一的差异是**没有勾选框**（那是运营侧 `naSel` 的批量入口，采购侧无那条链路），
     于是 pill 里没有 `<input>`，但没有 input 时 `.na2-pick` 仍带 `cursor: pointer`
     ⇒ 会假装可点。`.ro`（read-only）只改手势、**不动外观**：背景/边框/内边距/字号
     与运营侧逐字相同，所以两边看起来是一套东西。
     ⚠️ 刻意不复用 `.dis`（`filter: grayscale(1)`）—— 那会把文字一起褪色，与"同款 pill"背道而驰。 */
  .proc-na .na2-pick.ro { cursor: default; }

  /* ---- 卡片悬浮动效（2026-10-08 用户口径，全看板统一）----
     用户原话：「另外瀑布流是否能加动画，鼠标悬浮时当前卡片被选中的状态」，
     随后追加：「采购看板下其他视图都要加一下动画，未采购，已采购，已标库，已确认数量，
     问题件，自购，不发货订单」，再追加：
     「**动画可以参考运营看板-问题件，不发货这几个视图的感觉**」。
     覆盖采购/运营看板里**全部三类卡片外壳**（一卡一实体的视图都落在这三类里）：
       ① `.na2-card`   —— 未到仓（#naList 运营侧 / #procNaList 采购侧，双列瀑布流）
       ② `.proc-card`  —— 采购看板主列表 #procList（未采购 / 已采购 / 已标库 / 已确认数量，
                          以及该看板的问题件 / 运营自购 / 不发货三档 —— 它们是从同一份
                          分组数据渲染进 #procList 的 `.proc-card`，不是另一个板）
       ③ `.issue-card` —— 问题件 / 运营自购 / 不发货（网格 board）
     ★ 手感基准 = **`.issue-card` 原来那一套**（用户点名的"感觉"），逐字沿用、不另造：
         轻上浮 1px + 底色提亮到 --panel-2 + 边框转**半透明紫** rgba(127,119,221,.5)。
       刻意**不加**外圈 accent ring / 实色 accent 边 —— 试过更重的"框住整卡"版本，
       用户明确要求以问题件那档的轻手感为准：这些卡要连着扫过几十张，
       重描边在长时段操作里是噪音。
     ⚠️ 只用 transform / 颜色，**不碰 layout**（50 张卡 hover 也不掉帧）。
     ⚠️ 时长 / 缓动一律引用 Layer 1 令牌，降级（prefers-reduced-motion / data-motion=off）
        归零即「立即完成」，视图代码不需要任何分支。
     ⚠️ 这里**刻意不做**"逐卡错峰进入动画"：卡片在每次点档位 / 翻页时都会重画，
        挂进场动画会让高频操作一屏一屏地闪（与 `.ui-enter` 既有约定「翻页不打」同一条理由）。
     ⚠️ **不碰任何缩略图**：`.proc-thumb`（采购看板主图配 .thumb-zoom 300px 框）、
        `.ic-thumb`（问题件/自购/不发货，自身已 `scale(3.2)`）都是用户验收过的行为。
        用户更正：「**我说的动画是整个聚合卡片，不是单独的图片，单独的图片只用
        一个悬浮放大就可以**」⇒ 缩略图只有"悬浮放大"（`img.zoomable` → #imgZoomLayer），
        **不做缩放动效**（曾写过的 `.na2-thumb img { scale(1.06) }` 已删）。 */
  #naList .na2-card,
  #procNaList .na2-card,
  #procList .proc-card,
  .issue-card {
    transition: transform var(--anim-dur-1) var(--anim-ease),
                border-color var(--anim-dur-1) var(--anim-ease),
                background var(--anim-dur-1) var(--anim-ease);
  }
  #naList .na2-card:hover,
  #naList .na2-card:focus-within,
  #procNaList .na2-card:hover,
  #procNaList .na2-card:focus-within,
  #procList .proc-card:hover,
  #procList .proc-card:focus-within,
  .issue-card:hover,
  .issue-card:focus-within {
    transform: translateY(-1px);
    background: var(--panel-2);
  }
  /* 边框转半透明紫：`.na2-card` / `.proc-card` 没有状态色条，整圈转色即可。
     （`.proc-card.proc-sel` 用的是 `outline`，与这里不冲突：一个说"鼠标指着这张"、
       一个说"这张被勾选了"，两层同时出现正好。） */
  #naList .na2-card:hover,
  #naList .na2-card:focus-within,
  #procNaList .na2-card:hover,
  #procNaList .na2-card:focus-within,
  #procList .proc-card:hover,
  #procList .proc-card:focus-within { border-color: rgba(127, 119, 221, .5); }
  /* ⚠️ `.issue-card` **不能**整圈改色：它的 `border-top: 3px solid` 是**状态色条**
     （pending 琥珀 / closed 灰 / resolved 绿，见上面三条规则）。基类 `.issue-card` 与
     `.issue-card.pending` 同为 (0,2,0)，hover 规则也 (0,2,0) 且在后 ⇒ 一旦写 `border-color`
     就会把顶边状态色一起染掉，"这张工单是什么状态"当场丢掉。故只染其余三边。 */
  .issue-card:hover,
  .issue-card:focus-within {
    border-left-color: rgba(127, 119, 221, .5);
    border-right-color: rgba(127, 119, 221, .5);
    border-bottom-color: rgba(127, 119, 221, .5);
    z-index: 5;   /* 必须留着：`.ic-thumb:hover` 放大 3.2 倍时要盖过相邻卡 */
  }
  /* ⚠️ 采购看板「未采购」视图里卡片可整卡点选（`.proc-selectable`，点一下=选中该卡），
     蓝色底纹就是"点它=勾上"的反馈 —— 上面统一段把它覆盖成了 --panel-2。这里按原样补回来：
     选中语义优先于悬浮提亮，否则运营会以为整卡点选那个入口没了。
     ⚠️ 选择器必须带 `#procList` 才压得过统一段（统一段是 (1,2,0)）。 */
  #procList .proc-card.proc-selectable:hover,
  #procList .proc-card.proc-selectable:focus-within { background: rgba(47, 111, 176, .06); }
  /* ⚠️ `.proc-card.done`（已采购 / 已标库 / 已确认数量的卡）整卡 `opacity: .62` —— hover 时把
     不透明度还原（与既有 `.issue-card.resolved:hover { opacity: 1 }` 同一手感），
     否则提亮落在一张半透明的卡上根本看不出来。
     ⚠️ 不动 `filter: grayscale(.5)`：灰掉表达的是"这张单已走完采购流程"，为 hover 恢复彩色
     会让鼠标扫过时忽彩忽灰（比看不出来更糟）。 */
  #procList .proc-card.done:hover,
  #procList .proc-card.done:focus-within { opacity: 1; }

  .na-phase .n { font-weight: 700; margin-left: 4px; font-variant-numeric: tabular-nums; }
  /* [2026-10-07] 「进度」/「推进方」两排 chips 改为动态渲染（`renderNaProgChips` /
     `renderNaOwnerChips`）后补两条：计数与空档灰化 —— 原来只有 phase chips 有这两条。
     空档**仍可点**（点进去是空表，符合预期），只做视觉弱化。 */
  .na-chip .n { font-weight: 700; margin-left: 4px; font-variant-numeric: tabular-nums; }
  .na-chip.zero { opacity: .42; }
  /* 推进方 chips 激活色：运营(暖琥珀) / 采购(冷靛) —— 与卡片档位按钮同一套色系，
     一眼看出"现在这一屏看的是哪一半的活"。 */
  .na-chip.u-op.active { background: #d97706; border-color: #d97706; }
  .na-chip.u-pu.active { background: #4f46e5; border-color: #4f46e5; }
  /* [2026-10-07 并轨] `.na-phase.zero` 已并入顶部 `.ui-chip.zero` 组，此处删除。 */
  .na-phase.u-warn { border-color: var(--warn); }
  .na-phase.u-crit { border-color: var(--danger); }
  .na-phase-tag { font-size: 11.5px; padding: 2px 9px; border-radius: 9px; white-space: nowrap; }
  .na-phase-tag.wait { background: rgba(29,158,117,.16); color: var(--success); }
  .na-phase-tag.push { background: rgba(239,159,39,.18); color: var(--warn); }
  .na-phase-tag.crit { background: rgba(226,75,74,.2); color: var(--danger); }
  /* ---- 阶段图例（2026-09-28 用户要求：一线人员不知道每个胶囊代表什么，需要常驻说明）----
     <details open> 默认展开 —— 光有 title 悬浮提示不够，用户不会去悬停。 */
  .na-legend { margin: 0 0 10px; padding: 8px 11px; border: 1px dashed var(--border);
               border-radius: 10px; background: var(--panel-2); font-size: 12px; }
  .na-legend > summary { cursor: pointer; color: var(--muted); font-weight: 600;
                         user-select: none; list-style: none; }
  .na-legend > summary::-webkit-details-marker { display: none; }
  .na-legend > summary::before { content: "▸ "; display: inline-block; width: 12px; }
  .na-legend[open] > summary::before { content: "▾ "; }
  .na-legend > summary:hover { color: var(--text); }
  .na-legend-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
                    gap: 5px 16px; margin-top: 9px; }
  .na-legend-item { display: flex; gap: 8px; align-items: baseline; }
  .na-legend-item .lg-k { flex: 0 0 auto; }
  .na-legend-item .lg-d { color: var(--muted); line-height: 1.5; }
  .na-legend-hint { margin-top: 9px; padding-top: 7px; border-top: 1px dashed var(--border);
                    color: var(--muted); line-height: 1.6; }
  .na-legend-sub { margin-top: 10px; padding-top: 8px; border-top: 1px dashed var(--border);
                   color: var(--muted); font-weight: 600; }
  .na-problem { font-size: 12px; color: var(--muted); }
  .na-orders { font-size: 12px; color: var(--muted); max-height: 150px; overflow: auto;
               border-top: 1px dashed var(--border); padding-top: 6px; }
  .na-orders table { width: 100%; border-collapse: collapse; table-layout: fixed; }
  .na-orders td { padding: 2px 8px 2px 0; overflow: hidden;
                  text-overflow: ellipsis; white-space: nowrap; }/* [2026-10-07 并轨] 原 `.na-pager` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.wh-subtabs` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.wh-subtabs button` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 *//* [2026-10-07 并轨] 原 `.wh-subtabs button.active` 规则已并入 style.css 顶部 Layer 2 组件层，此处删除以免覆盖。 */
  .wh-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
  .wh-table th, .wh-table td { border-bottom: 1px solid var(--border); padding: 5px 8px;
                               text-align: left; vertical-align: middle; }
  .wh-table th { color: var(--muted); font-weight: 600; background: var(--panel-2); }
  .wh-table tbody tr:hover { background: var(--panel-2); }
  .wh-empty { color: var(--muted); padding: 18px; text-align: center;
              border: 1px dashed var(--border); border-radius: 10px; background: var(--panel-2); }
  .wh-msg { width: 100%; min-height: 130px; font-family: ui-monospace, Menlo, Consolas, monospace;
            background: var(--panel-2); color: var(--text); border: 1px solid var(--border); border-radius: 8px; padding: 8px; }
  .wh-form { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 10px;
             padding: 7px 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--panel-2); }
  .wh-form .muted { flex: none; }
  .wh-pill { font-size: 11px; padding: 1px 7px; border-radius: 9px; border: 1px solid var(--border); color: var(--muted); }
  .wh-pill.qc { background: rgba(226,75,74,.16); color: var(--danger); border-color: rgba(226,75,74,.5); }
  .wh-pill.ok { background: rgba(29,158,117,.16); color: var(--success); border-color: rgba(29,158,117,.5); }
  /* 已到仓 / 解析预览：物品缩略图 + 文案（2026-09-28：解析关联 ERP 后展示）*/
  .wh-thumb { width: 34px; height: 34px; object-fit: cover; border-radius: 6px; vertical-align: middle; margin-right: 6px; }
  .wh-item { display: inline-block; vertical-align: middle; max-width: 210px; }
  .na-oprog { font-size: 12px; padding: 2px 4px; max-width: 120px; }

  /* ---- 台账「反查原始订单」展示（2026-09-28）----
     三个台账（未到仓 / 已到仓 / 质检件）都只记单号，反查回订单后才能看清
     「名称 / 采购单号 / 快递单号 / 采购数量 / 采购单价 / 利润 / 归属店铺」。
     列变多 → 用横向滚动容器，避免把整个页面撑破。 */
  .wh-scroll { overflow-x: auto; }
  .wh-scroll .wh-table { width: max-content; min-width: 100%; }
  .wh-itemcell { display: flex; align-items: center; gap: 6px; max-width: 260px; }
  .wh-itemcell img { width: 34px; height: 34px; object-fit: cover; border-radius: 6px; flex: none; }
  .wh-itemcell .ic-txt { min-width: 0; }
  .wh-itemcell .ic-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis;
                          white-space: nowrap; max-width: 210px; }
  .ic-sub { color: var(--muted); font-size: 11px; }
  .wh-itemcell .ic-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
                         max-width: 210px; }
  .wh-money { font-variant-numeric: tabular-nums; }
  .wh-profit-pos { color: var(--success); }
  .wh-profit-neg { color: var(--danger); }
  .wh-nonum { color: var(--muted); }
  /* 物流商消息解析：写入前后的状态条 + 结果文字（2026-09-28）
     用户原话「写入台账之后没有确认完成的反馈，再次进入之后还有之前遗留的历史，
     不知道是否已经写入」→ 预览态与已写入态必须一眼能分清。 */
  .wh-parse-state { padding: 7px 10px; border-radius: 7px; margin-bottom: 8px;
                    border: 1px solid var(--border); font-size: 12.5px; }
  .wh-parse-state.pending { background: rgba(210,153,34,.10); border-color: rgba(210,153,34,.45);
                            color: var(--warn); }
  .wh-parse-state.ok { background: rgba(29,158,117,.12); border-color: rgba(29,158,117,.5);
                       color: var(--success); }
  .wh-parse-ok { color: var(--success); font-weight: 600; }
  .wh-parse-pending { color: var(--warn); }
  /* 未到仓明细 / 解析预览的表格列变多（加了名称 / 采购单号 / 数量 / 单价 / 利润 等反查列），
     默认 `table-layout: fixed` + `width:100%` 会把 12 列压成每列 ~50px 全被省略号吃掉，
     改为按内容宽度排布 + 横向滚动（容器 `.na-orders` 本来就是 overflow:auto）。 */
  #view-wh .na-orders table { table-layout: auto; width: max-content; min-width: 100%; }

  /* ---- 图片悬浮放大（2026-09-26 用户需求）----
     订单总表 / 采购看板（子 SKU 组内小图）/ 运营看板-详细订单 里的缩略图都太小，
     鼠标移上去浮出原图。用 position:fixed 的全局浮层 + JS 跟随光标，
     所以**不受卡片 overflow / 表格横向滚动裁剪**，也不会挤动布局。 */
  img.zoomable { cursor: zoom-in; }
  #imgZoomLayer {
    position: fixed; z-index: 9998; display: none; pointer-events: none;
    padding: 4px; border: 1px solid var(--border); border-radius: 10px;
    background: var(--panel-2); box-shadow: 0 10px 40px rgba(0,0,0,.5);
    max-width: 460px;
  }
  #imgZoomLayer img { display: block; width: 100%; max-width: 452px; height: auto;
                      max-height: 452px; object-fit: contain; border-radius: 7px; }
  /* 浮层右下角的「原图」小标：提示这是放大预览，不是换图 */
  #imgZoomLayer .zl-tag { position: absolute; right: 8px; bottom: 6px; font-size: 10px;
                          color: var(--muted); background: rgba(0,0,0,.45); padding: 1px 6px; border-radius: 6px; }
  /* 运营看板-详细订单：可点选的行鼠标变手型（仅「待备货」，见 .ship-clickable） */
  #view-ops .ops-orders-table tr.rep-row.ship-clickable > td { cursor: pointer; }
  /* 但行内的可编辑单元格（备注 / 重量）保持文本光标，避免误以为整格都能点选 */
  #view-ops .ops-orders-table tr.ship-clickable > td[contenteditable] { cursor: text; }
  #view-ops .ops-orders-table td.oo-chk input { cursor: pointer; }
  /* 已勾选的行再给左边界一条竖线，翻页/长表里更容易回看选了哪几笔 */
  #view-ops .ops-orders-table tr.rep-row.row-checked > td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

  /* 店铺绑定·同步工具条（2026-09-26）：快捷范围按钮 + 店铺范围下拉 + 主按钮排在日期后面。
     2026-10-07 换装：按钮尺度改走 --ctl-* 令牌（原 2px 9px / 12px，与同行 38px 控件不等高）。 */
  .sync-bar { flex-wrap: wrap; row-gap: 6px; }
  .sync-quick { display: inline-flex; gap: 4px; }
  .sync-quick .btn { padding: 0 var(--ctl-pad-x); font-size: var(--ctl-fs-sm); }
  .sync-bar #syncScopeStore { max-width: 190px; }
  .sync-bar #syncRangeTip { font-size: var(--ctl-fs-xs); }


/* ===== 选品池改造（2026-09-25 / P2 摘取 2026-09-27）：我的选品校对 + 费用列配色 ===== */
/* ---- 校对：可编辑单元格（我的选品）---- */
th.edcol { background: rgba(29,158,117,.12); }
td.edcell { background: rgba(29,158,117,.05); cursor: text; outline: none;
  min-width: 72px; max-width: 230px; word-break: break-all; }
td.edcell:hover { background: rgba(29,158,117,.13); }
td.edcell:focus { background: var(--panel); box-shadow: inset 0 0 0 2px var(--success); }
td.edcell.ednum { text-align: right; font-variant-numeric: tabular-nums; }
td.edcell.saving { background: rgba(250,204,21,.28); }
td.edcell.saved { background: rgba(29,158,117,.30); }
td.edcell.failed { background: rgba(226,75,74,.28); }
/* 「我的选品」费用列配色：沿用「详细订单」三组色系
   （扣费=琥珀 / 利润=盈亏绿红 / 优化建议=紫），横向扫读时一眼分清
   「钱出在哪、最后赚没赚、换个仓能省多少」。 */
.ms-table { width: max-content; min-width: 100%; table-layout: auto; }
.ms-table th.mg-cost { background: rgba(239,159,39,.17); color: #f0c07a; font-weight: 600; }
.ms-table td.mg-cost { background: rgba(239,159,39,.085); }
.ms-table th.mg-profit { background: rgba(148,163,184,.13); font-weight: 600; }
.ms-table td.mg-profit { background: rgba(148,163,184,.10); }
.ms-table td.mg-profit.rep-margin-pos { background: rgba(43,182,115,.16); color: #52d39a; }
.ms-table td.mg-profit.rep-margin-neg { background: rgba(229,72,77,.16); color: #ff7b7f; }
.ms-table th.mg-rec { background: rgba(127,119,221,.16); color: #b8b2f0; font-weight: 600; }
.ms-table td.mg-rec { background: rgba(127,119,221,.085); }
.ms-table tfoot td { font-weight: 600; background: var(--panel-2); }
/* 文本列左对齐（数字列保持右对齐，便于比大小）*/
.ms-table th:nth-child(3), .ms-table td:nth-child(3),
.ms-table th:nth-child(4), .ms-table td:nth-child(4),
.ms-table th:nth-child(5), .ms-table td:nth-child(5),
.ms-table th:nth-child(6), .ms-table td:nth-child(6),
.ms-table th:nth-child(8), .ms-table td:nth-child(8),
.ms-table th:nth-child(12), .ms-table td:nth-child(12),
.ms-table th:nth-child(13), .ms-table td:nth-child(13),
.ms-table th:nth-child(23), .ms-table td:nth-child(23),
.ms-table th:nth-child(28), .ms-table td:nth-child(28) { text-align: left; }
/* 模拟生效的列：描边提醒「这行数字不是库里的值」 */
.ms-table td.ms-sim { box-shadow: inset 0 0 0 2px rgba(250,204,21,.55); }

/* ===== 可见范围选择器（ORG_SCOPE_PLAN.md，2026-10-02）=====
   只在运营 / 组长出现；跟在顶栏右上角，用主题变量配色，浅色/深色主题都不额外适配。 */
.scope-zone { display: flex; align-items: center; gap: 6px; margin-right: 10px; }
.scope-zone .scope-label { font-size: 12px; color: var(--muted); white-space: nowrap; }
.scope-zone select {
  padding: 5px 9px; font-size: 12.5px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--panel-2); color: var(--text); cursor: pointer;
}
.scope-zone select:hover { border-color: var(--accent); }

/* ===== 组织架构配置页（团队 / 小组 / 运营 三列）===== */
.org-col { min-width: 210px; max-width: 320px; }
.org-col-head {
  display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 13px;
  margin-bottom: 6px; padding-bottom: 5px; border-bottom: 1px solid var(--border);
}
.org-col-head .btn { margin-left: auto; }
.org-list {
  display: flex; flex-direction: column; gap: 4px;
  max-height: 420px; overflow: auto; padding-right: 2px;
}
.org-item {
  display: flex; align-items: center; gap: 6px; padding: 6px 8px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--panel-2);
}
.org-item.active { border-color: var(--accent); box-shadow: inset 0 0 0 1px rgba(127,119,221,.45); }
.org-item .org-name { font-size: 13px; cursor: pointer; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.org-item .org-name:hover { color: var(--accent); text-decoration: underline; }
.org-item .org-meta { font-size: 11px; color: var(--muted); white-space: nowrap; }
.org-item .org-acts { display: flex; gap: 3px; }
.org-empty { font-size: 12px; color: var(--muted); padding: 8px; line-height: 1.7; }
.org-op {
  display: flex; align-items: center; gap: 7px; padding: 5px 8px; font-size: 13px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--panel-2); cursor: pointer;
}
.org-op:hover { border-color: var(--accent); }
.org-op input { cursor: pointer; }
.org-op .org-meta { font-size: 11px; color: var(--muted); }
.org-tag {
  font-size: 10.5px; padding: 1px 6px; border-radius: 6px; white-space: nowrap;
  background: rgba(239,159,39,.18); color: var(--warn);
}
.btn.sm { padding: 4px 8px; font-size: 11.5px; border-radius: 7px; }

/* =========================================================================
   订单总表 / 巴士待推送单 —— 2026-10-02 多维查询改造
   · th.th-sort   表头点击排序（含升降序标记）
   · .ogroup-*    合单（同一订单编号多行）分组折叠
   · .otype-*     欧众状态列按订单类型着色（采购流 / 库存流 / 运营自购）
   配色沿用全站既有语义：采购=success 绿、库存=warn 橙、自购=accent 紫，
   深浅两套主题靠 var() 自动跟随，无需额外覆盖。
   ========================================================================= */
#ordersTable thead th.th-sort,
#busTable thead th.th-sort { cursor: pointer; user-select: none; white-space: nowrap; }
#ordersTable thead th.th-sort:hover,
#busTable thead th.th-sort:hover { color: var(--accent); }
#ordersTable thead th.th-sort::after,
#busTable thead th.th-sort::after { content: " ⇅"; opacity: .28; font-size: 11px; }
#ordersTable thead th.th-sort.sort-asc::after,
#busTable thead th.th-sort.sort-asc::after { content: " ▲"; opacity: 1; color: var(--accent); }
#ordersTable thead th.th-sort.sort-desc::after,
#busTable thead th.th-sort.sort-desc::after { content: " ▼"; opacity: 1; color: var(--accent); }

/* 合单分组：组头一行汇总，子行默认折叠、点组头展开 */
tr.ogroup-head { cursor: pointer; background: var(--panel-2); font-weight: 600; }
tr.ogroup-head:hover { background: var(--panel); }
tr.ogroup-head .ogroup-caret { display: inline-block; width: 13px; color: var(--accent); font-size: 10px; }
tr.ogroup-head .ogroup-badge {
  display: inline-block; margin-right: 8px; padding: 1px 8px; border-radius: 6px;
  font-size: 12px; font-weight: 600;
  background: rgba(127,119,221,.18); color: var(--accent); border: 1px solid rgba(127,119,221,.5);
}
tr.ogroup-item > td:first-child { border-left: 3px solid rgba(127,119,221,.6); }
tr.ogroup-item[hidden] { display: none; }

/* 欧众状态：按订单类型着色 */
td.otype-buy { color: var(--success); }
td.otype-stock { color: var(--warn); }
td.otype-self { color: var(--accent); font-weight: 600; }

/* ===== 「加入运营自购」：卡片按钮 + 订单多选弹窗（2026-10-05 续四）===== */
/* 按钮：与「标记不发货」并列、位于其上方。用 accent(indigo) 系与问题件/不发货区分，
   呼应卡片上「运营自购」流程标签的 flow-selfbuy 配色。 */
.btn.selfbuy-mark {
  background: rgba(127,119,221,.16); color: var(--accent);
  border: 1px solid rgba(127,119,221,.55);
}
.btn.selfbuy-mark:hover { background: rgba(127,119,221,.30); }
/* 弹窗里的订单多选列表：定高滚动 —— 同品挂几十笔未采购单时不能把弹窗撑爆 */
.selfbuy-list {
  max-height: 320px; overflow: auto;
  display: flex; flex-direction: column; gap: 6px;
  margin-bottom: 12px;
}
.selfbuy-row {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; border: 1px solid var(--border); border-radius: 8px;
  font-size: 12.5px; cursor: pointer; background: var(--panel);
}
.selfbuy-row:hover { border-color: rgba(127,119,221,.60); }
.selfbuy-row .sb-pn {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--text);
}
.selfbuy-row .sb-meta { color: var(--muted); margin-left: auto; white-space: nowrap; }

/* ===== 「处理方式」分段按钮（2026-10-05 续六）=====
   原先是两个裸 radio（`.radio-inline`）挤在一行 notice 里，用户反馈「看着不舒服」。
   改成分段控件：两格并排、选中格高亮，与看板上的「档位 chip」视觉统一。
   语义仍是 `input[type=radio]`（`name="resvMode"` 不变 ⇒ 前端 `querySelector` 取值逻辑无需改），
   radio 本体做**视觉隐藏但保留在无障碍树里**（用 opacity:0 而非 display:none）。 */
.seg-radio {
  display: inline-flex; align-items: stretch;
  border: 1px solid var(--border); border-radius: 9px; overflow: hidden;
  background: var(--panel-2);
}
.seg-radio label {
  position: relative; display: inline-flex; align-items: center;
  cursor: pointer; user-select: none;
}
.seg-radio input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; margin: 0; cursor: pointer;
}
.seg-radio span {
  display: inline-flex; align-items: center;
  padding: 6px var(--sp-4); font-size: var(--ctl-fs-sm); line-height: 1.4;
  color: var(--text); border-right: 1px solid var(--border);
  transition: background var(--anim-dur-1) var(--anim-ease), color var(--anim-dur-1) var(--anim-ease);
}
.seg-radio label:last-child span { border-right: 0; }
.seg-radio label:hover span { background: rgba(127,119,221,.14); }
.seg-radio input:checked + span {
  background: var(--accent); color: #fff; font-weight: 600;
}
.seg-radio input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: -2px; }
/* 右侧一行动态说明（两种模式的文案不同，写在这里就不必把长文案塞进两格里撑宽控件） */
.seg-hint { font-size: 12.5px; color: var(--muted); }

/* ===== 运营自购：采购看板「只读状态块」+ 运营看板卡片动作（2026-10-05 续八）=====

   用户口径：「采购看板尽量只做展示，不留按钮，有需要操作在运营看板操作，把业务独立出来……
   包括后期分权限之后运营也不用看采购看板，各自独立」
   ⇒ 采购看板自购视图只留状态 + 两个单号；填单号 / 完成采购 / 撤销采购 / 标记不发货 /
     撤销运营自购 全部搬到运营看板卡片（按钮沿用既有 .btn 体系，不新增配色）。
   三档配色沿用「黄=要动 / 绿=已完成 / 灰=已出流程或异常」，与问题件三态印章同一套语义。 */
.sb-ro-state {
  display: inline-block; margin: 6px 0 8px; padding: 4px 10px;
  border-radius: 999px; font-size: 12.5px; font-weight: 600;
  border: 1px solid var(--border); background: var(--panel-2); color: var(--text);
}
.sb-ro-state.pending { color: var(--warn); border-color: var(--warn); background: rgba(239,159,39,.12); }
.sb-ro-state.resolved { color: var(--success); border-color: var(--success); background: rgba(29,158,117,.12); }
.sb-ro-state.closed { color: var(--muted); border-color: var(--muted); background: rgba(154,154,176,.14); }
.sb-ro-kv {
  display: flex; align-items: baseline; gap: 8px; font-size: 12.5px;
  padding: 3px 0; border-bottom: 1px dashed var(--border);
}
.sb-ro-kv > span { color: var(--muted); min-width: 62px; }
.sb-ro-kv > b { font-weight: 500; word-break: break-all; }
.sb-readonly .proc-flow-tip { margin-top: 6px; }
.sb-readonly-ops .btn-hint { width: 100%; justify-content: center; }
html[data-theme="light"] .sb-ro-state.pending { background: rgba(160,96,8,.10); }
html[data-theme="light"] .sb-ro-state.resolved { background: rgba(15,122,85,.10); }
html[data-theme="light"] .sb-ro-state.closed { background: rgba(107,114,128,.12); }


/* =========================================================================
   财务报表 V2（2026-10-06）：周期对比 / SKU 卡片 + 悬浮放大图 / 采购建议分级
   全部用主题变量，深浅两套自动适配（light 在 html[data-theme="light"] 里重定义了变量）
   ========================================================================= */

/* ---- 周期对比：颜色按「好坏方向」而不是「涨跌」----
   采购额↑ 中性、货损额↑ 是坏、毛利率↑ 是好。统一套「红涨绿跌」会把坏消息显示成喜报。 */
.fin-kpi .s.cmp-good { color: var(--success); }
.fin-kpi .s.cmp-bad { color: var(--danger); }
.fin-kpi .s.cmp-neutral { color: var(--muted); }
.cmp-good { color: var(--success); }
.cmp-bad { color: var(--danger); }

/* ---- SKU 卡片 ---- */
.sku-cards { display: flex; flex-direction: column; gap: 6px; }
.sku-card {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  background: var(--panel-2); border: 1px solid var(--border);
  border-left: 3px solid var(--border); border-radius: 8px; min-width: 0;
}
.sku-card.lv-risk { border-left-color: var(--danger); }
.sku-card.lv-warn { border-left-color: var(--warn); }
.sku-card.lv-ok { border-left-color: var(--success); }
.sku-thumb {
  width: 46px; height: 46px; border-radius: 6px; object-fit: cover;
  background: var(--panel); flex: none; display: block; cursor: zoom-in;
}
.sku-thumb.ph {
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; color: var(--muted); text-transform: uppercase;
}
.sku-body { flex: 1; min-width: 0; }
.sku-name { font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sku-code { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.sku-metas { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 3px; }
.sku-m { font-size: 12px; color: var(--text); font-variant-numeric: tabular-nums; }
.sku-m i { font-style: normal; color: var(--muted); margin-right: 4px; }
.sku-right { flex: none; }
.sku-lv { font-size: 12px; padding: 2px 9px; border-radius: 5px; white-space: nowrap; }
.sku-lv.lv-risk { background: rgba(226,75,74,.16); color: var(--danger); }
.sku-lv.lv-warn { background: rgba(239,159,39,.16); color: var(--warn); }
.sku-lv.lv-ok { background: rgba(29,158,117,.16); color: var(--success); }
.sku-lv.lv-idle, .sku-lv.lv-tail { background: var(--panel); color: var(--muted); }

/* ---- 悬浮放大图（fixed 跟随缩略图，避免被卡片/表格裁切）---- */
.sku-hover {
  position: fixed; z-index: 9999; width: 336px; padding: 8px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,.45); pointer-events: none;
}
.sku-hover img {
  width: 320px; height: 320px; object-fit: contain; display: block;
  border-radius: 6px; background: var(--panel-2);
}
.sku-hover-info { padding: 7px 2px 1px; }
.sku-hover-info .n { font-size: 12.5px; line-height: 1.45; margin-bottom: 2px; }
.sku-hover-info .c { font-size: 11.5px; color: var(--muted); margin-bottom: 5px; }
.sku-hover-info .m { display: flex; gap: 12px; flex-wrap: wrap; }

/* ---- 采购建议分级条 ---- */
.adv-chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.adv-chip { font-size: 12px; padding: 3px 10px; border-radius: 6px; cursor: help; }
.adv-chip.lv-risk { background: rgba(226,75,74,.16); color: var(--danger); }
.adv-chip.lv-warn { background: rgba(239,159,39,.16); color: var(--warn); }
.adv-chip.lv-ok { background: rgba(29,158,117,.16); color: var(--success); }
.adv-chip.lv-idle, .adv-chip.lv-tail { background: var(--panel-2); color: var(--muted); }

/* ============================================================
   选品源管理（2026-10-07 改造）—— 点击编辑 / 仓库下拉 / 软删除
   ============================================================ */
/* ---- 行高一致 / 长链接不撑爆（2026-10-07 续三，用户口径）----
   根因：`table-layout` 默认 auto 时，长 URL 要么**换行把行撑高**、要么配合 nowrap
   **把整列撑宽**（截图里 00001 都被挤成两行）。只有「定宽 + 单行省略号」能两头都管住：
   列宽交给 HTML 里的 <colgroup>，这里保证每格单行、超出省略、行高恒定。
   窄屏交给外层 .p-tablewrap 横向滚动，不把整页顶宽。 */
.p-tablewrap { overflow-x: auto; }
#productsTable { table-layout: fixed; min-width: 1550px; }
#productsTable tbody td {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  vertical-align: middle; height: 45px; padding-top: 7px; padding-bottom: 7px;
}
/* 编辑态放开：长 URL 要能横向滚动看光标，且不许把行撑高 */
#productsTable tbody td.edcell:focus {
  overflow-x: auto; overflow-y: hidden; text-overflow: clip;
}
/* 规格 / 备注：**两行 + 小字号**（用户口径「要显示全，一行不够换行或缩小字」）。
   实测规格列里混进了 446 字宽的 1688 链接（脏数据），放开换行会顶成 20 行高，
   所以用内层 .p-wrap 做 line-clamp:2 —— 既把 99% 的规格（最长 45 字）显示全，
   又把行高锁死在 2 行内，整表恒定 45px/行。第 3 行起的溢出内容靠 tooltip 看。 */
#productsTable tbody td.edcell[data-f="spec"],
#productsTable tbody td.edcell[data-f="note"] { font-size: 11.5px; white-space: normal; }
#productsTable .p-wrap {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; word-break: break-word; overflow-wrap: anywhere;
  white-space: normal; line-height: 15px; max-height: 30px;
}
/* 一旦进入编辑，两行限制解除 —— 改规格 / 备注时要能看全自己在写什么 */
#productsTable tbody td.edcell:focus .p-wrap {
  display: block; -webkit-line-clamp: none; max-height: none;
}
/* 空单元格占位：内容为空时显示灰色「—」，一眼看出哪格没填。
   用 ::before 而不是写进文本 —— 保证 innerText 仍为空，不会把占位符当数据存进库。 */
#productsTable td.edcell:empty::before { content: "—"; color: var(--muted); }
/* SKU 列：定宽列下仍显式 nowrap，防回归 */
#productsTable th:first-child,
#productsTable td:first-child { white-space: nowrap; }
#productsTable td:first-child code { white-space: nowrap; }
/* 仓库下拉单元格。
   ⚠️ 行高由**最高的单元格内容**决定，不设死就管不住。实测两个元凶：
     · 操作列的「删除」按钮 33px（+ 上下 padding 18 + 边框 = 整表 52px/行）
     · 仓库下拉的 select 固有高度
   两个都显式钉住后，整表行高才是我们说了算（现为 43px/行）。 */
#productsTable td.p-selcell { padding: 4px 6px; }
#productsTable select.p-wh {
  width: 100%; height: 24px; line-height: 15px; padding: 0 4px;
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px; font-size: 12.5px;
}
#productsTable tbody .btn { height: 24px; padding: 0 9px; font-size: 12px; line-height: 22px; }
#productsTable select.p-wh:focus { outline: none; border-color: var(--accent); }
#productsTable select.p-wh.saved { border-color: var(--success); background: rgba(29,158,117,.18); }
/* 缩略图 + 悬浮放大预览层（2026-10-07 追加口径）
   ⚠️ 图片行最容易比别的行高：`<img>` 是行内元素，会带上基线以下的 descent 空间
   （实测把有图的行顶到 46px，无图行 43px ⇒ 行高不一致）。
   治法：a 设 block + line-height:0（把行盒压成图片本身的高度），img 设 block；
   缩略图再压到 22px，**严格低于**决定行高的 24px，留出余量避免卡在临界值上。 */
#productsTable a.p-thumblink { display: block; line-height: 0; }
#productsTable td img.p-thumb {
  max-height: 22px; display: block; margin: 0 auto;
  border-radius: 4px; cursor: zoom-in;
}
#imgZoom {
  position: fixed; z-index: 9999; display: none; pointer-events: none;
  padding: 3px; background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; box-shadow: 0 8px 28px rgba(0, 0, 0, .45);
}
#imgZoom img { display: block; max-width: 340px; max-height: 340px; border-radius: 6px; }
/* 软删除行：整行置灰（操作列的按钮保持可见，方便恢复） */
tr.p-deleted td { opacity: .45; }
tr.p-deleted td:last-child { opacity: 1; }

/* ---------- 疑似质检单小字标记（2026-10-09 临时小功能）----------
   口径：订单号命中「疑似质检单号段」（默认 021/024/027/028，可配置）=
   疑似质检单（仅参考，以物流商「质检单」标签为准）。
   形态：**小字标记**（比 12.5px 正文更小、不撑宽列）——订单号下方换行的小字
   或同一格内贴尾的迷你标签；琥珀色（黄底棕字），区别于绿=正常/红=异常/蓝=信息。 */
.qc-flag {
  display: block; margin-top: 1px; padding: 0;
  font-size: 10.5px; line-height: 14px; font-weight: 600;
  color: #b45309; background: transparent;
  white-space: nowrap;
}
.qc-flag i {
  font-style: normal;
  background: rgba(245, 158, 11, .16);
  border: 1px solid rgba(245, 158, 11, .45);
  border-radius: 3px; padding: 0 3px; line-height: 13px;
}
.qc-flag:hover i { background: rgba(245, 158, 11, .28); }


/* ---------- M1 F1.1 工作台外壳（shell）骨架（2026-10-09）----------
   3 套外壳按角色显隐导航；shell 是权限域的命名分组，纯界面层。 */
.shell-hidden { display: none !important; }
.shell-switch {
  display: inline-flex; align-items: center; gap: 2px;
  margin-left: 10px; padding: 3px; border-radius: 8px;
  background: var(--panel-2, rgba(127,127,127,.12));
  vertical-align: middle;
}
.shell-btn {
  border: none; background: transparent; cursor: pointer;
  padding: 5px 12px; border-radius: 6px;
  font-size: 12.5px; color: var(--muted, #888);
  white-space: nowrap;
}
.shell-btn.active {
  background: var(--accent, #3b82f6); color: #fff; font-weight: 600;
}


/* ---------- M1 F1.4 今日待办（S0 任务状态层只读聚合）---------- */
.todo-group { margin-bottom: 14px; border: 1px solid var(--border, rgba(127,127,127,.25)); border-radius: 10px; overflow: hidden; }
.todo-group-head { display: flex; align-items: center; gap: 8px; padding: 8px 12px; font-size: 13px; font-weight: 600; background: var(--panel-2, rgba(127,127,127,.08)); }
.todo-cnt { background: var(--accent, #3b82f6); color: #fff; border-radius: 8px; padding: 0 7px; font-size: 11.5px; line-height: 17px; }
.todo-item { display: flex; align-items: center; gap: 8px; padding: 7px 12px; border-top: 1px solid var(--border, rgba(127,127,127,.12)); font-size: 12.5px; }
.todo-item:hover { background: var(--panel-2, rgba(127,127,127,.06)); }
.todo-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.todo-tag { border-radius: 4px; padding: 0 6px; font-size: 11px; line-height: 17px; white-space: nowrap; }
.todo-tag.st-待处理 { background: rgba(239,68,68,.14); color: #dc2626; }
.todo-tag.st-处理中 { background: rgba(59,130,246,.14); color: #2563eb; }
.todo-tag.st-待确认 { background: rgba(245,158,11,.16); color: #b45309; }
.todo-tag.st-已解决 { background: rgba(34,197,94,.14); color: #16a34a; }
.todo-tag.st-已关闭 { background: rgba(127,127,127,.14); color: #6b7280; }
.todo-stage { color: var(--muted, #888); font-size: 11.5px; white-space: nowrap; }
.todo-role { border: 1px solid var(--border, rgba(127,127,127,.35)); border-radius: 4px; padding: 0 5px; font-size: 11px; color: var(--muted, #888); white-space: nowrap; }
.todo-time { color: var(--muted, #999); font-size: 11px; white-space: nowrap; }
/* 首页待办的「展开剩余 N 条 / 收起」（2026-10-09 折叠改造）
   展开条 = 整行虚线上边、与 .todo-item 同层级；组头里的「收起」= 右侧小胶囊。 */
.todo-more {
  display: block; width: 100%; text-align: center; padding: 7px 12px;
  border: none; border-top: 1px dashed var(--border); background: transparent;
  color: var(--accent); font-size: 12.5px; cursor: pointer;
}
.todo-more:hover { background: var(--panel-2); }
.todo-more.in-head {
  display: inline-block; width: auto; margin-left: auto; padding: 2px 9px;
  border: 1px solid var(--border); border-radius: var(--rad-chip);
  font-size: 11.5px; color: var(--muted);
}
.todo-more.in-head:hover { border-color: var(--accent); color: var(--accent); background: transparent; }

/* ---------- 首页 / 工作台（2026-10-09 重构 #view-home）----------
   布局（参考哈澜工作台）：欢迎条 → 核心指标 → 运营工作台 → 采购工作台 → 选品源。
   所有数字都复用各看板既有接口 —— 首页只承担「聚合入口 + 一眼看懂」，
   点任意卡片 = 直达那个视图的**同一份数据**，不存在第二套口径。 */
.home-hero {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  padding: 18px 20px; margin-bottom: var(--sp-4);
  background: linear-gradient(120deg, var(--panel-2), var(--panel));
  border: var(--card-line); border-left: 3px solid var(--accent);
  border-radius: var(--rad-card);
}
.home-hello { margin: 0 0 6px; font-size: 20px; font-weight: 600; }
.home-hello-sub { margin: 0; font-size: var(--fs-meta); color: var(--muted); }
.home-hero-actions { display: flex; align-items: center; gap: var(--sp-2); flex: 0 0 auto; }
/* 可见范围标签（管理员/采购 = 全站数据；运营/组长 = 当前范围 + 所属小组/团队）
   用户口径：「这个相当于是管理员的总览页面……如果是运营登录，可以显示自己的……这些」
   ⇒ 把「你现在看到的是谁的数据」摆在明面上，免得看错口径。 */
.home-scope-tag {
  display: inline-flex; align-items: center; white-space: nowrap;
  padding: 4px 10px; border: var(--card-line); border-radius: var(--rad-chip);
  background: var(--panel-2); color: var(--muted); font-size: var(--fs-mini);
}

/* ② 昨日经营（口径：昨天 09:00 ~ 今天 09:00，一个完整营业日） */
.home-metrics {
  display: grid; grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--sp-3);
}
/* 口径说明行（用户要求「需要加以说明」）：紧贴指标卡下方，弱化但不能看不见 */
.home-note { margin: 10px 2px 0; font-size: var(--fs-mini); color: var(--muted); line-height: 1.65; }
.home-metric {
  text-align: left; padding: 14px 16px; cursor: pointer; font: inherit; color: var(--text);
  background: var(--panel); border: var(--card-line); border-radius: var(--rad-card);
  transition: border-color var(--anim-dur-1) var(--anim-ease), transform var(--anim-dur-1) var(--anim-ease);
}
.home-metric:hover { border-color: var(--accent); transform: translateY(-1px); }
.hm-k { font-size: var(--fs-mini); color: var(--muted); }
.hm-v { font-size: 19px; font-weight: 600; margin: 6px 0 3px; font-variant-numeric: tabular-nums; }
.hm-v.pos { color: var(--success); }
.hm-v.neg { color: var(--danger); }
.hm-s { font-size: var(--fs-mini); color: var(--muted); }

/* 区块头（运营工作台 / 采购工作台 / 选品源） */
.home-sec { margin-bottom: var(--sp-5); }
.home-sec-head { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.home-sec-title { font-size: var(--fs-sec); font-weight: 600; }
.home-sec-sub { font-size: var(--fs-mini); color: var(--muted); }
.home-sec-more {
  margin-left: auto; background: none; border: none; color: var(--accent);
  font-size: var(--fs-meta); cursor: pointer; padding: 2px 6px; border-radius: 6px;
}
.home-sec-more:hover { background: var(--panel-2); }

/* 卡片网格（每张卡 = 看板里一个 TAB / 视图） */
.home-tiles {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: var(--sp-3);
}
.home-tile {
  display: flex; flex-direction: column; gap: 3px;
  text-align: left; padding: 13px 15px; cursor: pointer; font: inherit; color: var(--text);
  background: var(--panel); border: var(--card-line); border-radius: var(--rad-card);
  transition: border-color var(--anim-dur-1) var(--anim-ease), transform var(--anim-dur-1) var(--anim-ease);
}
.home-tile:hover { border-color: var(--accent); transform: translateY(-1px); }
.home-tile.hot { border-left: 3px solid var(--warn); }
.home-tile.pos .ht-value { color: var(--success); }
.home-tile.neg .ht-value { color: var(--danger); }
.ht-label { font-size: var(--fs-meta); font-weight: 600; }
.ht-value { font-size: 21px; font-weight: 600; line-height: 1.25; font-variant-numeric: tabular-nums; }
.ht-sub { font-size: var(--fs-mini); color: var(--muted); }

/* 采购报表（仅管理员渲染；非管理员整块为空）。
   2026-10-09 夜：由「一行 hpr-item 文字」改为**与其他板块同款的卡片网格**（.home-tiles），
   口径同步改为「今天」—— 用户口径「那个地方也是需要和小的一样，都做成那种卡片」。 */
.home-report { margin-top: var(--sp-4); }
.hpr-head {
  display: flex; align-items: baseline; gap: var(--sp-2);
  font-size: var(--fs-meta); font-weight: 600; margin-bottom: 8px;
}
.hpr-head .muted { font-weight: 400; font-size: var(--fs-mini); }
.hpr-row {
  display: flex; flex-wrap: wrap; gap: 10px 24px;
  padding: 12px 16px; background: var(--panel-2);
  border: var(--card-line); border-radius: var(--rad-card);
}
/* ⚠️ 以下 .hpr-item 三条已成为**死代码**（报表改用 .home-tiles 卡片后无人再用），
   与旧 .todo-* 一样**保留不删** —— 万一要退回文字版直接可用，且删了也无收益。 */
.hpr-item { display: flex; flex-direction: column; gap: 2px; }
.hpr-item em { font-style: normal; font-size: var(--fs-mini); color: var(--muted); }
.hpr-item b { font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; }

@media (max-width: 1280px) { .home-metrics { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 720px) {
  .home-hero { flex-direction: column; align-items: flex-start; }
  .home-hero-actions { width: 100%; flex-wrap: wrap; }
  .home-hero-actions .btn { flex: 1; }
  .home-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .home-tiles { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
  /* 窄屏区块头：标题别被副标题挤断（「运营工作台」曾折成两行半） */
  .home-sec-head { flex-wrap: wrap; }
  .home-sec-title { white-space: nowrap; }
}

/* ★ F7.4 平台壳：规划中预留位（disabled 灰置 + 不可点） */
#navLeft .nav-group.plat-group .plat-disabled {
  opacity: 0.45;
  cursor: not-allowed;
  filter: grayscale(0.6);
}
#navLeft .nav-group.plat-group .plat-disabled:hover {
  background: transparent;
}

/* ★ F3.5.1 上品链导航骨架（2026-10-12）：**尚未实现的功能位统一置灰**（与平台壳「规划中」同视觉）。
   规则写在通用 `.nav-group` 下（不是 .plat-group），供普通业务组复用；
   置灰位无 data-tab ⇒ 不参与视图切换，点击只 toast 提示。转正时删掉 nav-soon 即可。 */
#navLeft .nav-group .nav-soon {
  opacity: 0.45;
  cursor: not-allowed;
  filter: grayscale(0.6);
}
/* 置灰位不做 hover 高亮，但保留 title 提示可读 */
#navLeft .nav-group .nav-soon:hover {
  background: transparent;
}

/* ---------- 在线商品（F3.5.2 / M3 上品链 P1；2026-10-16 改聚合列版式 —— 对齐毛子ERP参考）----------
   列 = 商品信息 / 类目佣金 / 店铺 / 状态 / 价格 / 库存 / 重量 / 操作（货源信息不做）。
   单行省略仍用于简单列；聚合列（商品信息/佣金/价格/状态）多行展示、不裁剪。
   窄屏由 .p-tablewrap 横向滚动。 */
#onlineTable { table-layout: fixed; min-width: 1240px; }
#onlineTable tbody td {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  vertical-align: middle; font-size: 12.5px; padding-top: 12px; padding-bottom: 12px;
}
#onlineTable tbody td.on-info, #onlineTable tbody td.on-commbox,
#onlineTable tbody td.on-pricecell, #onlineTable tbody td.on-stcell {
  white-space: normal; overflow: visible; text-overflow: clip;
}
#onlineTable .on-info-box { display: flex; gap: 9px; align-items: flex-start; }
#onlineTable .on-info-txt { min-width: 0; }
#onlineTable .on-name {
  font-size: 12px; line-height: 1.4;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#onlineTable .on-meta {
  margin-top: 2px; font-size: 11px; color: var(--muted); line-height: 1.45;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 货号 / SKU 行 = 文本 + 小复制按钮（flex 包裹，长值省略、按钮不被裁掉） */
#onlineTable .on-meta-flex { display: flex; align-items: center; gap: 2px; }
#onlineTable .on-meta-flex .onm-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#onlineTable .on-copy {
  flex: none; border: 0; background: transparent; color: var(--muted);
  cursor: pointer; padding: 1px 3px; border-radius: 4px; line-height: 0;
}
#onlineTable .on-copy:hover { color: var(--accent); background: var(--panel-2); }
#onlineTable .on-cat { color: var(--accent); opacity: .85; }
/* 缩略图高度 = 右侧四行文字（名称 16.8 + 3×15.95 + 3×2 ≈ 70px），宽度同高裁方 */
#onlineTable .on-thumb {
  width: 70px; height: 70px; object-fit: cover; border-radius: 6px;
  background: var(--panel-2); display: block; flex: none;
}
#onlineTable .on-commbox { font-size: 11px; color: var(--muted); line-height: 1.6; }
#onlineTable td.on-pricecell, #onlineTable td.on-stock { cursor: pointer; }
#onlineTable td.on-pricecell:hover, #onlineTable td.on-stock:hover { background: var(--panel-2); }
#onlineTable .on-p-main { font-weight: 700; }
#onlineTable .onp-sub { font-size: 11px; color: var(--muted); line-height: 1.5; }
#onlineTable td.on-stock { text-align: center; }
#onlineTable td.on-stock .on-st-n { font-weight: 700; }
#onlineTable td.on-stock .on-st-hint { display: block; font-size: 10px; color: var(--muted); }
#onlineTable .on-stcell { line-height: 1.5; }
#onlineTable .on-errline {
  margin-top: 2px; font-size: 11px; line-height: 1.35; color: var(--danger);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
#onlineTable td.on-weight { font-size: 12px; }
/* ⚠️ 别把 display:flex 直接放 <td>（td 会脱离表格单元格布局 → 整列错位，2026-10-17 实测踩过）——
   内层 div 承担 flex，td 保持 table-cell */
#onlineTable .on-ops { text-align: center; }
#onlineTable .on-ops-box { display: inline-flex; flex-direction: column; gap: 4px; width: 100%; }
#onlineTable .on-ops-box .btn { padding: 3px 8px; font-size: 11.5px; }

/* ---------- 在线商品 · 行勾选（批量操作入口在工具条按钮，2026-10-17 移除浮动吸附条）---------- */
#onlineTable td.on-pick, #onlineTable th.on-pickth { text-align: center; padding-left: 0; padding-right: 0; }
#onlineTable .onPick { width: 15px; height: 15px; cursor: pointer; accent-color: var(--accent); }
.on-batchpanel {
  position: fixed; z-index: 130;                 /* 位置由 JS 按锚点按钮计算（吸附其正下方） */
  display: grid; grid-template-columns: repeat(3, minmax(104px, 1fr)); gap: 6px;
  padding: 10px; background: var(--panel); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: 0 14px 34px rgba(0, 0, 0, .35);
}
.on-batchpanel[hidden] { display: none; }
.on-batchpanel .btn { padding: 9px 10px; font-size: 12.5px; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 7px; justify-content: flex-start; text-align: left; }
.on-batchpanel .btn.soon { opacity: .55; }
/* 面板图标 = 左侧导航同款线稿（16px 规格缩到 15px，stroke 1.8） */
.on-batchpanel .nav-ico-svg {
  width: 15px; height: 15px; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ---------- 批量操作大弹窗（2026-10-17 · 批量改价 / 批量修改库存，对齐毛子ERP参考）----------
   ⚠️ z-index 必须低于 .ui-modal(300)：弹窗内 fx 统设等会再开 uiPromptMulti 小弹窗，
      大弹窗压在下面才能让嵌套小弹窗可见。 */
.b-dlg { position: fixed; inset: 0; z-index: 290; display: flex; }
.b-dlg[hidden] { display: none; }
.b-dlg-mask { position: absolute; inset: 0; background: rgba(0, 0, 0, .45); }
.b-dlg-box {
  position: relative; margin: 24px auto; width: min(1220px, calc(100vw - 44px));
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
  display: flex; flex-direction: column; min-height: 0; max-height: calc(100vh - 48px);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .45);
}
.b-dlg-head { display: flex; align-items: center; gap: 10px; padding: 11px 14px; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.b-dlg-title { font-weight: 600; font-size: 14px; white-space: nowrap; }
.b-dlg-x { border: 0; background: transparent; color: var(--muted); cursor: pointer; padding: 6px; border-radius: 8px; display: inline-flex; }
.b-dlg-x:hover { background: var(--panel-2); color: inherit; }
.b-dlg-set { display: inline-flex; align-items: center; gap: 8px; margin-left: 14px; flex-wrap: wrap; }
.b-dlg-set[hidden] { display: none; }
.b-setlabel { font-size: 12.5px; color: var(--muted); }
.b-dlg-body { overflow: auto; padding: 8px 14px 14px; flex: 1; min-height: 120px; }
.b-dlg-foot { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-top: 1px solid var(--border); }
.b-dlg-note { font-size: 12px; color: var(--muted); }
.b-whsync { padding: 5px 12px; font-size: 12.5px; }
.b-setapply { padding: 5px 14px; font-size: 12.5px; }
.b-setwh { max-width: 210px; }
.b-setqty { width: 104px; }

.b-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.b-table th {
  position: sticky; top: 0; z-index: 1; background: var(--panel);
  font-size: 12px; color: var(--muted); font-weight: 500; text-align: left;
  padding: 8px; border-bottom: 1px solid var(--border); white-space: nowrap;
}
.b-table td { padding: 6px 8px; font-size: 12.5px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.b-table tbody tr:hover td { background: var(--panel-2); }
.b-infobox { display: flex; gap: 8px; align-items: flex-start; }
.b-thumb { width: 38px; height: 38px; object-fit: cover; border-radius: 6px; background: var(--panel-2); display: block; flex: none; }
.b-name { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; line-height: 1.35; }
.b-sub { margin-top: 2px; font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.b-num, .b-sel {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 12.5px;
  color: inherit; background: transparent; border: 1px solid transparent;
  border-radius: 6px; padding: 5px 7px;
}
.b-num:hover, .b-sel:hover { border-color: var(--border); }
.b-num:focus, .b-sel:focus { outline: none; border-color: var(--accent); background: var(--panel-2); }
.b-num::placeholder { color: var(--muted); opacity: .65; }
/* 改动过的格高亮（提交只针对有改动的行 → 所见即所提交） */
.b-num.b-changed, .b-sel.b-changed { color: var(--accent); font-weight: 600; border-color: var(--accent); }
.b-qtycell { white-space: nowrap; }
.b-qtycell .b-num { width: 84px; display: inline-block; vertical-align: middle; }
.b-qtycell .muted { margin-left: 4px; }
.b-fx {
  margin-left: 4px; border: 1px solid var(--border); background: var(--panel-2);
  color: var(--muted); font-size: 10px; line-height: 1; padding: 2px 5px;
  border-radius: 5px; cursor: pointer; vertical-align: 1px;
}
.b-fx:hover { color: var(--accent); border-color: var(--accent); }
.b-del { border: 0; background: transparent; color: #e5484d; cursor: pointer; font-size: 12.5px; padding: 4px 6px; }
.b-del:hover { text-decoration: underline; }

/* ---------- 在线商品 · 缩略图编辑悬浮图标（2026-10-17 · 正中悬浮「编辑图片」）---------- */
#onlineTable .on-thumbwrap { position: relative; width: 70px; height: 70px; flex: none; }
#onlineTable .on-thumbwrap .on-thumb { width: 70px; height: 70px; }
#onlineTable .on-imgedit {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 28px; height: 28px; border-radius: 8px; border: 0;
  background: rgba(0, 0, 0, .58); color: #fff; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity .15s; padding: 0;
}
#onlineTable .on-thumbwrap:hover .on-imgedit { opacity: 1; }
#onlineTable .on-imgedit:hover { background: var(--accent); }
#onlineTable .on-thumb-none { display: block; border: 1px dashed var(--border); border-radius: 6px; background: var(--panel-2); }

/* ---------- 商品编辑（2026-10-17 · 图片编辑 + 编辑大弹窗/新页，对齐毛子ERP）----------
   ⚠️ z-index：295（高于 b-dlg 290，低于 .ui-modal 300 —— 内部「添加图片」等会再开小弹窗）；
   .page 模式 = 全屏（z-index 305），用于「新页打开」。 */
/* ---------- 商品编辑 · 视图内置整页（W-17 · 2026-10-18 用户口径，对齐毛子 ERP）----------
   结构 = 页头（返回 + 标题）+ 左表单 + 右侧锚点导航 + 底部固定操作条。
   为什么不用弹层：全屏弹层会把来源页整页盖住，用户丢失上下文（毛子用整页视图）。
   锚点/底栏都用 sticky：页面本身由 body 滚动，sticky 才跟得住。 */
.ed-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.ed-head .ui-title { font-size: 16px; margin: 0; }
.ed-wrap { display: grid; grid-template-columns: minmax(0, 1fr) 108px; gap: 26px; align-items: start; }
.ed-main { min-width: 0; max-width: 940px; }
.ed-main .pe-sec { margin-bottom: 26px; scroll-margin-top: 12px; }
.ed-main .pe-sec > h4 { font-size: 14px; }
.ed-anchor {
  position: sticky; top: 16px; display: flex; flex-direction: column; gap: 2px;
  padding-left: 10px; border-left: 1px solid var(--border); font-size: 12.5px;
}
.ed-anchor a {
  display: block; padding: 5px 8px; border-radius: 6px; color: var(--muted);
  cursor: pointer; text-decoration: none; white-space: nowrap;
}
.ed-anchor a:hover { color: var(--text); background: rgba(127, 119, 221, .10); }
.ed-anchor a.active { color: var(--accent); background: rgba(127, 119, 221, .14); font-weight: 600; }
.ed-foot {
  position: sticky; bottom: 0; z-index: 6; display: flex; align-items: center; gap: 10px;
  margin-top: 18px; padding: 10px 14px; background: var(--panel);
  border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 -6px 20px rgba(0, 0, 0, .28);
}
@media (max-width: 980px) {
  .ed-wrap { grid-template-columns: minmax(0, 1fr); }
  .ed-anchor { display: none; }   /* 窄屏没地方放锚点，靠页内顺序阅读 */
}

.pe-dlg { position: fixed; inset: 0; z-index: 295; display: flex; }
.pe-dlg[hidden] { display: none; }
.pe-mask { position: absolute; inset: 0; background: rgba(0, 0, 0, .45); }
.pe-box {
  position: relative; margin: 22px auto; width: min(1080px, calc(100vw - 40px));
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
  display: flex; flex-direction: column; min-height: 0; max-height: calc(100vh - 44px);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .45);
}
.pe-dlg.page { z-index: 305; }
.pe-dlg.page .pe-mask { display: none; }
.pe-dlg.page .pe-box { margin: 0; width: 100%; max-width: none; max-height: none; height: 100vh; border: 0; border-radius: 0; }
.pe-head { display: flex; align-items: center; gap: 10px; padding: 11px 14px; border-bottom: 1px solid var(--border); }
.pe-title { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pe-x { border: 0; background: transparent; color: var(--muted); cursor: pointer; padding: 6px; border-radius: 8px; display: inline-flex; }
.pe-x:hover { background: var(--panel-2); color: inherit; }
.pe-tabs { display: flex; gap: 4px; padding: 8px 14px 0; }
.pe-tabs[hidden] { display: none; }
.pe-tab { border: 1px solid transparent; background: transparent; color: var(--muted); padding: 7px 16px; border-radius: 8px 8px 0 0; cursor: pointer; font-size: 13px; }
.pe-tab.active { background: var(--panel-2); color: inherit; border-color: var(--border); }
.pe-body { overflow: auto; padding: 12px 14px; flex: 1; min-height: 140px; }
.pe-foot { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-top: 1px solid var(--border); }
.pe-note { font-size: 12px; color: var(--muted); }
.pe-toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; position: relative; }
.pe-check, .pe-check-all { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--muted); cursor: pointer; }
.pe-check input, .pe-check-all input { accent-color: var(--accent); width: 14px; height: 14px; cursor: pointer; }
.pe-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
@media (max-width: 1000px) { .pe-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.pe-card { border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: var(--panel-2); position: relative; }
.pe-card-imgwrap { position: relative; aspect-ratio: 3 / 4; background: var(--panel); }
.pe-card-img { width: 100%; height: 100%; object-fit: contain; display: block; }
.pe-card-main { position: absolute; left: 6px; top: 6px; font-size: 11px; background: var(--accent); color: #fff; padding: 2px 7px; border-radius: 6px; }
.pe-card-bar { display: flex; align-items: center; gap: 6px; padding: 6px 8px; font-size: 11.5px; }
.pe-dim { font-size: 11px; }
.pe-ope { border: 1px solid var(--border); background: transparent; color: inherit; font-size: 11.5px; padding: 3px 10px; border-radius: 6px; cursor: pointer; }
.pe-ope:hover { border-color: var(--accent); color: var(--accent); }
.pe-cardops {
  position: absolute; right: 6px; bottom: 36px; z-index: 2;
  display: flex; flex-direction: column; min-width: 104px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .4); overflow: hidden;
}
.pe-cardops[hidden] { display: none; }
.pe-cardops button { border: 0; background: transparent; color: inherit; text-align: left; padding: 7px 14px; font-size: 12px; cursor: pointer; }
.pe-cardops button:hover { background: var(--panel-2); }
.pe-cardops button:disabled { opacity: .4; cursor: default; }
.pe-cardops button.danger, .pe-batchmenu button.danger { color: #e5484d; }
.pe-batchmenu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 3;
  display: flex; flex-direction: column; min-width: 132px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .4); overflow: hidden;
}
.pe-batchmenu[hidden] { display: none; }
.pe-batchmenu button { border: 0; background: transparent; color: inherit; text-align: left; padding: 8px 14px; font-size: 12.5px; cursor: pointer; }
.pe-batchmenu button:hover { background: var(--panel-2); }
.pe-batchmenu button:disabled { opacity: .4; cursor: default; }
/* ---------- 商品基本属性编辑（页内新页 · 2026-10-17）---------- */
.pe-sec { margin-bottom: 20px; }
.pe-sec h4 { margin: 0 0 10px; font-size: 14px; font-weight: 600; padding-bottom: 6px; border-bottom: 1px solid var(--border); }
.pe-fgrid { display: grid; grid-template-columns: 128px minmax(0, 1fr); gap: 9px 12px; align-items: center; max-width: 780px; }
.pe-fgrid > label { font-size: 12.5px; color: var(--muted); }
.pe-fgrid .b-num { border-color: var(--border); }
.pe-ro { font-size: 12.5px; word-break: break-all; color: inherit; }
.pe-dims { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.pe-dims .b-num { width: 92px; border-color: var(--border); }
.pe-ta {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 12.5px; color: inherit;
  background: transparent; border: 1px solid var(--border); border-radius: 6px;
  padding: 6px 8px; resize: vertical; min-height: 52px;
}
.pe-ta:hover { border-color: var(--accent); }
.pe-ta:focus { outline: none; border-color: var(--accent); background: var(--panel-2); }

/* ---------- 类目属性（schema 驱动 · 2026-10-18）----------
   按 Ozon description-category/attribute 渲染：必填红星 / 类型徽标 / 分组折叠 /
   字典 chips + 搜索浮层。缺失必填的行用左侧黄条标出（一眼看到「这行为什么空着」）。 */
.pe-attr-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 12.5px; margin-bottom: 8px; }
.pe-attr-head .btn.xs { padding: 2px 9px; font-size: 12px; }
.pe-attr-src { margin-left: auto; font-size: 11.5px; }
.pe-attr-grp { border: 1px solid var(--border); border-radius: 8px; margin-bottom: 8px; background: var(--panel-2); }
.pe-attr-grp > summary { cursor: pointer; user-select: none; padding: 7px 12px;
  font-size: 12.5px; font-weight: 600; color: var(--muted); list-style: none; }
.pe-attr-grp > summary::before { content: "▸"; margin-right: 6px; font-size: 10px; }
.pe-attr-grp[open] > summary::before { content: "▾"; }
.pe-attr-grp > summary:hover { color: var(--accent); }
.pe-attr-grp > .pe-attr-row:last-child { margin-bottom: 6px; }
.pe-attr-row { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 10px;
  align-items: start; padding: 5px 12px; border-radius: 6px; }
.pe-attr-row:hover { background: rgba(127, 119, 221, .06); }
.pe-attr-l { font-size: 12.5px; color: var(--muted); line-height: 1.5;
  word-break: break-all; cursor: help; padding-top: 5px; }
.pe-attr-req, .pe-req { color: var(--danger); font-weight: 700; margin-left: 2px; }
.pe-attr-dict { display: inline-block; margin-left: 4px; padding: 0 4px; font-size: 10px;
  border: 1px solid var(--border); border-radius: 4px; color: var(--muted); vertical-align: 1px; }
/* 编辑页行内提示（标题格式 / 型号合并 / 标签规则，2026-10-18 毛子口径对齐） */
.pe-hint { font-size: 11.5px; color: var(--muted); line-height: 1.6; margin-top: 3px; }
.pe-cw { min-width: 0; }
.pe-cw .b-num { width: 100%; box-sizing: border-box; }
.pe-attr-type { display: inline-block; margin-left: 4px; font-size: 10px; color: var(--muted); }
.pe-attr-c { min-width: 0; }
.pe-attr-miss { box-shadow: inset 3px 0 0 var(--warn); background: rgba(239, 159, 39, .07); }
.pe-attr-ro .pe-attr-c { font-size: 12.5px; padding-top: 4px; }
.pe-attr-ro-note { font-size: 11.5px; color: var(--muted); cursor: help;
  border-bottom: 1px dashed var(--border); }
.pe-attr-ta { min-height: 44px; }
/* 字典 chips + 搜索浮层 */
.pe-dict { position: relative; }
.pe-chips { display: flex; flex-wrap: wrap; gap: 5px; align-items: center;
  border: 1px solid var(--border); border-radius: 6px; padding: 3px 6px; background: var(--panel); }
.pe-chips:focus-within { border-color: var(--accent); }
.pe-chip { display: inline-flex; align-items: center; gap: 4px; padding: 1px 4px 1px 7px;
  background: rgba(127, 119, 221, .16); border: 1px solid rgba(127, 119, 221, .35);
  border-radius: 999px; font-size: 12px; max-width: 100%; }
.pe-chip-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 320px; }
.pe-chip-x { border: 0; background: transparent; color: var(--muted); cursor: pointer;
  font-size: 13px; line-height: 1; padding: 0 2px; border-radius: 50%; }
.pe-chip-x:hover { color: var(--danger); }
.pe-dict-in { flex: 1; min-width: 130px; border: 0; outline: none; background: transparent;
  font: inherit; font-size: 12.5px; color: inherit; padding: 3px 2px; }
.pe-dict-in::placeholder { color: var(--muted); opacity: .7; }
.pe-dict-pop { position: absolute; z-index: 20; left: 0; right: 0; top: calc(100% + 3px);
  max-height: 260px; overflow: auto; background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, .22); padding: 4px; }
.pe-dict-pop[hidden] { display: none; }
.pe-dict-opt { display: block; width: 100%; text-align: left; border: 0; background: transparent;
  font: inherit; font-size: 12.5px; color: inherit; padding: 6px 8px; border-radius: 6px; cursor: pointer; }
.pe-dict-opt:hover:not(:disabled) { background: rgba(127, 119, 221, .14); }
.pe-dict-opt:disabled { opacity: .45; cursor: not-allowed; }
.pe-dict-none { padding: 8px 10px; font-size: 12.5px; }

/* ---------- 品牌单框（W-17 二修 · 2026-10-18）----------
   用户口径：「品牌直接内置到框里边，不要再选择一次」—— 一个输入框，值就在框里，
   聚焦/输入出下拉候选，选中即写入同一个框（旧版是 搜索框 + chips + 按钮 + 旁边再显示一次）。 */
.pe-brand { position: relative; max-width: 420px; }
.pe-brand .pe-brand-in { width: 100%; box-sizing: border-box; border-color: var(--border); }
.pe-brand .pe-brand-in:focus { outline: none; border-color: var(--accent); background: var(--panel-2); }

/* ---------- 「填写更多属性」折叠（非必填默认收起）----------
   用户口径：默认只保留必填项；入口按钮放在**「产品属性」标题同一行**（2026-10-18 二修）。 */
.pe-more-cap { margin: 14px 0 6px; font-size: 12px; color: var(--muted); }
.pe-h4-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pe-h4-btn { margin-left: auto; display: inline-flex; }
.pe-more-btn {
  cursor: pointer; border: 1px solid transparent; border-radius: 999px;
  padding: 4px 12px; font-size: 12px; font-weight: 600; font-family: inherit;
  color: #fff; background: var(--accent); line-height: 1.6;
}
.pe-more-btn::before { content: "＋ "; font-weight: 700; }
.pe-more-btn[data-open="1"] { background: transparent; color: var(--accent); border-color: var(--accent); }
.pe-more-btn[data-open="1"]::before { content: "－ "; }
.pe-more-btn:hover { filter: brightness(1.08); }
.pe-attr-more { margin-top: 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--panel-2); padding-top: 6px; }
.pe-attr-more[hidden] { display: none; }
.pe-attr-more > .pe-attr-grp { margin: 0 8px 8px; }
.pe-src-link { font-size: 12.5px; word-break: break-all; color: var(--accent); }

/* 上架时间列（W-22）：定长数字 + 不换行，两行"日期/时间"在列表里对齐才扫得动 */
.on-uptime { font-size: 12px; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.on-group-parent .on-uptime { color: var(--fg); }

/* ---------- 在线商品 · 变体组父行（W-20 · 默认折叠）---------- */
.on-group-parent > td { background: var(--panel-2); border-top: 1px solid var(--border); }
.on-gbadge {
  display: inline-block; margin-right: 6px; padding: 0 6px; border-radius: 999px;
  font-size: 10.5px; font-weight: 600; color: #fff; background: var(--accent); vertical-align: 1px;
}
.on-gname { font-weight: 600; }
.on-warn-t { color: var(--warn); font-size: 11.5px; }
.on-gstock { font-weight: 600; }
.on-group-child > td:first-child { border-left: 2px solid var(--accent); }
/* 子行不再给「编辑」（2026-10-18 用户口径）：点哪个变体进的都是**同一张带整组的编辑页**，
   子行再放一个编辑按钮纯属冗余 —— 编辑入口统一收到父行。子行的价格/库存格仍可点（行内改价/改库存）。 */
.on-group-child .onEdit { display: none; }

/* ---------- 变体设置 · 毛子 14 列小表（W-23）----------
   横向宽表：宽度不够时 .pe-var-wrap 里横向滚动，不压扁列（压扁后数字看不清）。 */
.pe-var-14 { table-layout: fixed; min-width: 924px; }
.pe-var-14 th, .pe-var-14 td { padding: 5px 4px; overflow: hidden; }
.pe-var-14 .pe-vi { width: 100%; }
.pe-var-14 th { white-space: nowrap; }
.pe-vi {
  width: 100%; box-sizing: border-box; padding: 3px 5px; font-size: 12px; font-family: inherit;
  color: var(--fg); background: var(--panel); border: 1px solid transparent; border-radius: 5px;
  font-variant-numeric: tabular-nums;
}
.pe-vi:hover { border-color: var(--border); }
.pe-vi:focus { outline: none; border-color: var(--accent); background: var(--panel-2); }
.pe-vi::-webkit-outer-spin-button, .pe-vi::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.pe-vi[type="number"] { -moz-appearance: textfield; }
.pe-var-ro { color: var(--fg); font-size: 12px; white-space: nowrap; }
.pe-var-has { color: var(--accent); font-size: 12px; cursor: help; }
.pe-var-tbl tr.pe-var-dirty > td { background: rgba(255, 176, 32, .10); }
.pe-var-ops { display: flex; gap: 4px; }
.pe-var-op {
  cursor: pointer; font-family: inherit; font-size: 11.5px; padding: 2px 7px; border-radius: 5px;
  border: 1px solid var(--border); background: transparent; color: var(--fg);
}
.pe-var-op:hover { border-color: var(--accent); color: var(--accent); }
.pe-var-op.danger:hover { border-color: var(--danger, #e05b5b); color: var(--danger, #e05b5b); }
/* 「同首行」↓：表头小圆按钮 */
.pe-fill {
  cursor: pointer; font-family: inherit; font-size: 11px; line-height: 1; padding: 2px 5px;
  margin-left: 3px; border-radius: 999px; border: 1px solid var(--border);
  background: transparent; color: var(--muted); vertical-align: 1px;
}
.pe-fill:hover { color: #fff; background: var(--accent); border-color: var(--accent); }
/* 「未保存改动」条：贴在表格上方 */
.pe-var-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 8px;
  padding: 7px 10px; border-radius: 8px; font-size: 12.5px;
  background: rgba(255, 176, 32, .12); border: 1px solid rgba(255, 176, 32, .45);
}
.pe-var-bar[hidden] { display: none; }
.pe-var-pic { cursor: pointer; }
.pe-var-pic:hover { outline: 2px solid var(--accent); }

/* ---------- 变体设置（W-19 · 只读版）----------
   同一张卡片下的变体横向小表：序号 / 图片 / 货号 / 颜色 / 售价 / 划线价 / 库存 / 状态 / 操作。
   只读原因：model_id 数据尚未统一拉取；写操作（改价/改库存/同首行填充）下一轮接。 */
.pe-var-head { font-size: 12.5px; margin-bottom: 8px; }
.pe-var-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: 8px; }
.pe-var-tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.pe-var-tbl th, .pe-var-tbl td {
  padding: 6px 8px; border-bottom: 1px solid var(--border); text-align: left; vertical-align: middle;
  white-space: nowrap;
}
.pe-var-tbl thead th { background: var(--panel-2); font-weight: 600; font-size: 12px; color: var(--muted); }
.pe-var-tbl tbody tr:last-child td { border-bottom: 0; }
.pe-var-tbl tbody tr:hover { background: rgba(127, 119, 221, .06); }
.pe-var-self { background: rgba(127, 119, 221, .10); }
.pe-var-img { width: 36px; height: 36px; object-fit: cover; border-radius: 6px; background: var(--panel-2); }
.pe-var-num { text-align: right; font-variant-numeric: tabular-nums; }
.pe-var-tag {
  font-size: 10.5px; padding: 0 5px; margin-left: 4px; border-radius: 999px;
  background: var(--accent); color: #fff;
}

/* ---------- 页面说明折叠（2026-10-16：长提示收进 details，默认收起）---------- */
.page-help { margin: 6px 0 10px; }
.page-help > summary {
  cursor: pointer; user-select: none; font-size: 12.5px; color: var(--muted);
  list-style: none; display: inline-flex; align-items: center; gap: 4px;
}
.page-help > summary::before { content: "ⓘ"; font-size: 13px; }
.page-help > summary:hover { color: var(--accent); }
.page-help-body {
  margin-top: 6px; padding: 10px 12px; font-size: 12.5px; color: var(--muted);
  background: var(--panel-2); border: 1px solid var(--border); border-radius: 8px;
  line-height: 1.8;
}
/* 档位徽标：颜色按语义分档（销售中=绿 / 准备出售=主色 / 待修改=黄 / 错误=红 / 已下架·已归档=灰） */
#onlineTable .on-tier {
  display: inline-block; padding: 1px 7px; border-radius: 999px;
  font-size: 11px; font-weight: 600; white-space: nowrap;
}
#onlineTable .on-tier-selling  { background: rgba(29,158,117,.18);  color: var(--success); }
#onlineTable .on-tier-ready    { background: rgba(127,119,221,.20); color: var(--accent); }
#onlineTable .on-tier-warning  { background: rgba(239,159,39,.18);  color: var(--warn); }
#onlineTable .on-tier-error    { background: rgba(226,75,74,.18);   color: var(--danger); }
#onlineTable .on-tier-paused   { background: var(--panel-2);        color: var(--muted); }
#onlineTable .on-tier-archived { background: rgba(120,120,140,.20); color: var(--muted); }
/* 「未同步」是**技术隔离桶**，不是第 8 档业务状态 ⇒ 虚线描边、不填色，视觉上一眼区分 */
#onlineTable .on-tier-unsynced {
  background: transparent; border: 1px dashed var(--border); color: var(--muted); font-weight: 500;
}
#onlineTable .on-st { margin-left: 6px; font-size: 11px; }
#onlineTable .on-err { color: var(--danger); font-weight: 600; }
#onlineTable .on-errbox { font-size: 11.5px; }
/* 「未同步」tab 弱化：同样是为了让它跟 7 个业务档区分开 */
.ui-tab.on-tab-tech { opacity: .7; font-weight: 400; }
/* ★ F7.4.1 顶栏套餐 chip：品牌名旁小徽标，可点击弹套餐状态 */
#brandPlanChip {
  display: inline-block;
  margin-left: 9px;
  padding: 2px 9px;
  font-size: 11px;
  font-weight: 600;
  color: var(--text);
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  vertical-align: 3px;
  white-space: nowrap;
  line-height: 1.5;
  max-width: 150px;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* F7.4.1 左模式竖栏窄（214px）：chip 与版本角标换到第二行，不再挤占/遮挡 */
body.nav-left-mode #brandPlanChip { margin-left: 0; }
#brandPlanChip:hover { border-color: var(--brand-grad-a); color: var(--brand-grad-a); }

/* ★ F7.4.1 激活成功结果卡：大 ✓ + 大字标题 + 套餐摘要 + 主按钮（不再是小字提示） */
.code-success-card { max-width: 340px; }
.code-ok-ico {
  width: 52px; height: 52px; margin: 2px auto 10px;
  display: flex; align-items: center; justify-content: center;
  font-size: 30px; font-weight: 800; color: #fff;
  background: linear-gradient(135deg, #2ea97c, #12886A);
  border-radius: 50%;
}
.code-ok-title { font-size: 21px; font-weight: 700; text-align: center; color: var(--success); }
.code-ok-sub { font-size: 12px; text-align: center; color: var(--text2); margin: 6px 0 12px; }
.code-ok-plan {
  text-align: center; padding: 10px 0; margin-bottom: 10px;
  border: 1px dashed var(--brand-grad-a); border-radius: 8px; background: var(--bg2);
}
.code-ok-plan b { font-size: 17px; color: var(--brand-grad-a); }
.code-ok-exp { font-size: 12px; color: var(--text2); margin-top: 2px; }
.code-ok-feats {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin-bottom: 14px;
  text-align: center; font-size: 12px; color: var(--text2);
}
.code-ok-feats b { display: block; font-size: 14px; color: var(--text); margin-top: 1px; }
.code-ok-go {
  width: 100%; padding: 9px 0; font-size: 14px;
  background: linear-gradient(135deg, #2ea97c, #12886A); color: #fff;
}
.code-ok-go:hover { filter: brightness(1.08); }

/* ★ F7.4.1 套餐状态弹窗（planMask）
   F7.15+ 修（用户报障 2026-10-12：开通会员弹窗**同时出现纵向 + 横向**滚动条）：
   根因 = 面板宽度还是「单档状态卡」时代的 max-width:460px（F7.4.1），而 F7.15 已把
   **全部 5 档价格网格**塞进同一弹窗 ⇒ 5 列被压到 ~70px/列，.pc-card 内容（30px 大字价 +
   全宽按钮 + 权益列表）撑破容器 → 横向溢出滚动；卡片被挤高 → 又触发 .price-body 的纵向滚动。
   而 .price-grid 的响应式断点（1100 / 780 / 520）是按**视口**写的 —— 弹窗入口在 1920 视口下
   永远命中不到 ⇒ 这类「弹窗内网格」必须改按**容器**自适应。
   修法：① 面板放宽到能横排 5 档（min() 兜住窄屏，48px = .price-mask 的 24px×2 内边距）；
        ② 网格 auto-fit 按容器降列，窄了自动 3/2 列、不再溢出；
        ③ body 兜一层 overflow-x，杜绝任何横向滚动条。 */
.plan-panel { max-width: min(1120px, calc(100vw - 48px)); }
.plan-panel .price-grid { grid-template-columns: repeat(auto-fit, minmax(var(--plan-card-min), 1fr)); }
.plan-panel .price-body { overflow-x: hidden; }
.plan-hero { text-align: center; padding: 18px 0 6px; }
.plan-hero-name b { font-size: 24px; }
.plan-hero-st {
  display: inline-block; margin-left: 8px; padding: 1px 8px;
  font-size: 11px; color: var(--success);
  border: 1px solid var(--success); border-radius: 999px; vertical-align: 4px;
}
.plan-hero-exp { font-size: 13px; color: var(--text2); margin-top: 8px; }
.plan-days { font-size: 20px; color: var(--brand-grad-a); }
.plan-days.over { color: var(--danger); }
.plan-quotas {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px;
  margin: 14px 0; text-align: center;
}
.plan-actions { display: flex; gap: 10px; justify-content: center; padding: 4px 0 14px; }
.plan-buy { background: linear-gradient(135deg, #2ea97c, #12886A); color: #fff; }

/* ★ F7.4.1 价格弹窗激活成功横幅 */
.price-banner {
  margin: 0 20px 12px; padding: 8px 12px;
  font-size: 12px; color: var(--success);
  background: rgba(46, 169, 124, 0.10);
  border: 1px solid rgba(46, 169, 124, 0.35); border-radius: 6px;
  text-align: center;
}
.price-mask .pc-btn:disabled {
  opacity: 0.55; cursor: not-allowed;
}
/* ★ F7.6 计费横幅（黄=宽限/超限，红=只读） */
.billing-banner {
  padding: 8px 16px;
  font-size: 13px;
  display: flex; align-items: center; gap: 12px;
  border-bottom: 1px solid var(--border);
}
body.nav-left-mode .billing-banner { margin-left: 214px; }
.billing-banner .bill-btn { padding: 2px 12px; font-size: 12px; margin-left: auto; flex: 0 0 auto; }
.billing-banner.bill-grace { background: rgba(224,168,58,.14); color: #d49a2a; }
.billing-banner.bill-over  { background: rgba(224,168,58,.10); color: #c98d1f; }
.billing-banner.bill-susp  { background: rgba(211,84,0,.14); color: #d35400; }
.billing-banner b { color: inherit; }
/* F7.6 套餐弹窗状态段 */
.plan-warn {
  margin: 10px 0 4px; padding: 8px 10px;
  font-size: 12px; text-align: center;
  border: 1px solid rgba(224,168,58,.45); border-radius: 6px;
  color: #c98d1f; background: rgba(224,168,58,.08);
}
/* ★ F7.4 平台壳组件层补充（2026-10-11 收敛 · 只引用 Layer 1 变量，禁止魔数）：
   平台壳是 2026-10-07 全站换装之后新建的视图，当时未纳入设计系统；
   本轮把 view-platform 全部收敛回 Layer 2 拼装，以下为 Layer 2 派生组件：
   · .plat-grid2/3 = .ui-grid 的 2/3 列变体（弹窗表单用，6 列默认太窄）
   · .plat-rowbtn   = 列表行内小按钮（--ctl-h-xs 26px + --fs-mini 11px，替代 magic px）
   · .plat-table    = .rep-table 的平台左对齐变体（rep-table 默认数值右对齐）
   · .plat-mini     = 徽标/小注（--fs-mini + muted）
   · .plat-w{48,64,88,120} = 数字/短输入框定宽（宽属于布局量，用类而非 inline px） */
.plat-grid2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.plat-grid3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.plat-rowbtn { height: var(--ctl-h-xs); padding: 0 10px; font-size: var(--fs-mini); line-height: 1; }
.plat-table th, .plat-table td { text-align: left; }
.plat-table td, .plat-table th { white-space: nowrap; }
.plat-table { margin-bottom: var(--sp-3); }
.plat-mini { font-size: var(--fs-mini); color: var(--muted); }
.plat-w48 { width: 48px; }
.plat-w64 { width: 64px; }
.plat-w88 { width: 88px; }
.plat-w120 { width: 120px; }
.plat-w180 { width: 180px; }
/* ★ F7.4 平台壳 · 子页面板组件（2026-10-11 收敛） */
.plat-title { font-size: var(--fs-sec); font-weight: 600; }
.plat-search { flex: 1; min-width: 120px; max-width: 240px; }
.plat-scroll { max-height: 70vh; overflow: auto; }
.plat-w240 { width: 240px; }
/* ★ F7.11 续：导航就绪门控 —— 登录身份定夺完（CUR_USER 就绪 + applyRoleUI/applyViewMode 壳显隐
   完成）之前，导航**一律隐藏**。原因：业务组与平台组（plat-group）**共存于同一份 DOM**，
   隔离是运行时 display 切换行为；首帧 / me 未返回期间全部按钮按 HTML 默认显示 ⇒ 登录闪屏会
   把平台导航与租户导航同时暴露。visibility 而非 display：保留布局（左模式 header 高度不塌）、
   且门控期间不拦截任何点击。 */
body:not(.ui-ready) .tabs,
body:not(.ui-ready) #navLeft,
body:not(.ui-ready) #navTop { visibility: hidden; }
/* ★ F7.11 续：引导加载屏（用户提议「游戏式缓加载」）—— 登录/刷新后任何瞬间第一眼只看到加载屏，
   身份（me）+ 壳显隐定夺完成（body.ui-ready）才关闭；纯 HTML/CSS 首帧即生效，z-index 高于登录页。 */
.boot-mask {
  position: fixed; inset: 0; z-index: 10000;
  display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(1100px 620px at 16% 10%, rgba(127, 119, 221, .16), transparent 62%),
    radial-gradient(900px 520px at 88% 92%, rgba(15, 110, 86, .14), transparent 60%),
    var(--bg);
}
.boot-mask.hide { display: none; }
.boot-inner { text-align: center; }
.boot-logo svg {
  width: 52px; height: 52px;
  stroke: var(--accent); fill: none;
  stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
}
.boot-logo circle { fill: var(--accent); stroke: none; }
.boot-name { margin-top: 14px; font-size: var(--fs-page); letter-spacing: 2px; color: var(--text); }
.boot-loading {
  margin-top: 12px; display: flex; align-items: center; justify-content: center; gap: 8px;
  font-size: var(--fs-meta); color: var(--muted);
}
.boot-spin {
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid var(--border); border-top-color: var(--accent);
  animation: bootSpin .8s linear infinite;
}
@keyframes bootSpin { to { transform: rotate(360deg); } }

/* ---- F7.16 选品源「上传建档」预览弹层（2026-10-12）----
   比通用 .ui-modal 宽：要放「前 20 行差异表」；body 默认 pre-wrap 会把表格挤散，这里复位。 */
.p-import-box { width: min(880px, 94vw); }
.p-import-box .ui-modal-body { white-space: normal; }
.p-import-tbl { width: 100%; border-collapse: collapse; font-size: 12px; }
.p-import-tbl th, .p-import-tbl td {
  border-bottom: 1px solid var(--border); padding: 4px 6px;
  text-align: left; vertical-align: top;
}
.p-import-tbl th { background: var(--panel-2); }
.p-import-err { max-height: 140px; overflow-y: auto; margin-top: 4px; }

/* ===== 重量核查（系统重量 vs 兴远过机实重 → 利润双算）===== */
.wc-panel { min-height: 200px; }
.wc-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 14px; }
.wc-cards .metric { background: var(--panel, #fff); border: 1px solid var(--line, #e3e6ea); border-radius: 10px; padding: 12px; }
.wc-cards .metric .k { color: var(--mut, #6b7280); font-size: 12px; }
.wc-cards .metric .v { font-size: 18px; font-weight: 500; margin-top: 4px; }
.wc-warn-row td { background: #fdf3f3; }
.wc-tblwrap { max-height: 480px; overflow: auto; }
.wc-pager { margin-top: 10px; }
.wc-pager select { width: auto; }

/* ===== 重量核查 · 主题适配（深浅两套）===== */
.wc-cards .metric { background: var(--panel); border: 1px solid var(--border); border-radius: var(--rad-card, 10px); }
.wc-cards .metric .k { color: var(--muted); }
.wc-warn-row td { background: rgba(226, 75, 74, .08); }

/* ===== 重量核查 · 表头排序（参考 巴士推送-待推送单）===== */
#wcOrdersTable thead th.th-sort { cursor: pointer; user-select: none; white-space: nowrap; }
#wcOrdersTable thead th.th-sort:hover { color: var(--accent); }
#wcOrdersTable thead th.th-sort::after { content: " ⇅"; opacity: .28; font-size: 11px; }
#wcOrdersTable thead th.th-sort.sort-asc::after { content: " ▲"; opacity: 1; color: var(--accent); }
#wcOrdersTable thead th.th-sort.sort-desc::after { content: " ▼"; opacity: 1; color: var(--accent); }

/* ===== 数据备注（历史月份数据缺口说明 · 2026-10-19）=====
   用于「数字看起来不对，但不是 Bug」的解释性提示：配置驱动（app_config notes.data），
   不写死在页面里 —— 补录/重导后改配置即可，不必发版。
   2026-10-19：默认折叠（用户反馈「显示太大」），收起时只占一行。 */
.data-note { margin: 0 0 12px; padding: 7px 12px; border: 1px solid var(--border);
  border-left: 3px solid #e6a23c; border-radius: 8px; background: rgba(230, 162, 60, .07); }
.data-note.open { padding: 9px 12px 11px; }
.data-note-toggle { display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 2px 0; margin: 0; background: none; border: 0; cursor: pointer;
  font: inherit; color: inherit; text-align: left; line-height: 1.4; }
.data-note-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.dn-caret { flex: 0 0 auto; width: 10px; font-size: 11px; color: #e6a23c; }
.dn-label { flex: 0 0 auto; font-size: 13px; font-weight: 600; }
.dn-count { flex: 0 0 auto; padding: 0 6px; border: 1px solid var(--border); border-radius: 9px;
  font-size: 11.5px; line-height: 17px; color: var(--muted); }
.dn-hint { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-size: 12.5px; color: var(--muted); }
.dn-act { flex: 0 0 auto; margin-left: auto; font-size: 12px; color: #e6a23c; }
.data-note-toggle:hover .dn-act { text-decoration: underline; }
.data-note-body { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--border); }
.data-note-item + .data-note-item { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--border); }
.data-note-item b { display: block; font-size: 13px; margin-bottom: 4px; }
.data-note-item ul { margin: 0; padding-left: 18px; }
.data-note-item li { font-size: 12.5px; line-height: 1.75; color: var(--muted); }
.data-note-item.info { opacity: .92; }
.data-note-item.info b { font-weight: 500; }

/* ===== 重量口径开关（二态左右切换 · 2026-10-19）=====
   为什么用左右滑动而不是下拉：这是**全局计算口径**，切了之后全站运费/利润都变，
   运营需要一眼看出"现在是哪一档"，下拉框容易看漏。左右两档 + 高亮当前档 + 右侧状态文字。 */
.wswitch-wrap { margin-top: 4px; padding: 10px 12px; border: 1px solid var(--border);
  border-radius: 8px; background: var(--panel-2); max-width: 520px; }
.wswitch-title { font-size: 13px; font-weight: 600; margin-bottom: 8px; }
.wswitch-sub { font-weight: 400; font-size: 12px; color: var(--muted); margin-left: 6px; }
.wswitch { display: flex; align-items: center; gap: 10px; }
.wswitch .ws-opt { font-size: 12.5px; color: var(--muted); transition: color .15s; cursor: default; }
.wswitch .ws-opt.on { color: var(--text); font-weight: 600; }
.wswitch .ws-rail { position: relative; width: 46px; height: 24px; flex: 0 0 auto;
  border: 0; padding: 0; border-radius: 12px; background: var(--border); cursor: pointer;
  transition: background .18s ease; }
.wswitch .ws-rail i { position: absolute; top: 3px; left: 3px; width: 18px; height: 18px;
  border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.25);
  transition: transform .18s ease; }
.wswitch .ws-rail[data-v="1"] { background: #e6a23c; }
.wswitch .ws-rail[data-v="1"] i { transform: translateX(22px); }
.wswitch .ws-rail:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.wswitch .ws-state { margin-left: auto; font-size: 12px; color: var(--muted); }

/* 选品源「实重(g)」只读列（2026-10-19）：与采集重量偏差 >20% 标橙 + 显示百分比 */
#productsTable td.p-wa-warn { color: #e6a23c; font-variant-numeric: tabular-nums; }
#productsTable td.p-wa-warn em { font-style: normal; font-size: 11px; margin-left: 2px; opacity: .85; }

/* ===== 重量口径横幅（2026-10-19）=====
   用户口径：「需要在受影响的页面加一个横条，说明现在是处于什么视图之下」。
   只在「实重档 + 当前页运费/利润真的按实重算」时出现，用 accent 紫与「数据备注」(橙)、
   计费横幅(黄) 区分；右侧带一键切回，运营不必去设置页找开关。 */
.weight-banner {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 12px; padding: 8px 14px;
  font-size: 12.5px; line-height: 1.6;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--muted);
  border-radius: 8px;
}
/* 两态：采集档=中性灰（默认态，低调）；实重档=accent 紫（非默认态，醒目） */
.weight-banner.wb-actual {
  background: rgba(127, 119, 221, .12);
  border-color: rgba(127, 119, 221, .32);
  border-left-color: var(--accent);
}
.weight-banner .wb-dot { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%;
  background: var(--muted); }
.weight-banner.wb-actual .wb-dot { background: var(--accent);
  box-shadow: 0 0 0 3px rgba(127, 119, 221, .18); }
.weight-banner b { flex: 0 0 auto; font-size: 13px; white-space: nowrap; }
.weight-banner .wb-txt { min-width: 0; color: var(--muted); }
.weight-banner .wb-btn { margin-left: auto; flex: 0 0 auto; padding: 3px 12px;
  font-size: 12px; border: 1px solid var(--border); border-radius: 6px;
  background: var(--panel); color: var(--text); cursor: pointer; }
.weight-banner .wb-btn:hover { border-color: var(--accent); color: var(--accent); }
.weight-banner .wb-btn:disabled { opacity: .5; cursor: default; }

/* ===== 运营看板·口径说明（2026-10-19 P0）=====
   用户口径：「营收/利润和财务报表对不上，看不出哪个是真的」。
   默认折叠，展开是一张四行对照表（指标 / 本页口径 / 说明）+ 一条实测差值提示。 */
.ops-caliber { margin: 0 0 12px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--panel-2); }
.ops-caliber .oc-head { display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 8px 12px; background: none; border: 0; cursor: pointer; font: inherit;
  color: inherit; text-align: left; }
.ops-caliber .oc-caret { flex: 0 0 auto; width: 10px; font-size: 11px; color: var(--muted); }
.ops-caliber .oc-head b { flex: 0 0 auto; font-size: 13px; }
.ops-caliber .oc-hint { min-width: 0; color: var(--muted); font-size: 12.5px; }
.ops-caliber .oc-act { flex: 0 0 auto; margin-left: auto; font-size: 12px; color: var(--accent); }
.ops-caliber .oc-head:hover .oc-act { text-decoration: underline; }
.ops-caliber .oc-body { padding: 0 12px 12px; }
.oc-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.oc-table th, .oc-table td { padding: 5px 8px; border-bottom: 1px solid var(--border);
  text-align: left; vertical-align: top; }
.oc-table th { color: var(--muted); font-weight: 500; font-size: 12px; }
.oc-table td:first-child { white-space: nowrap; font-weight: 600; }
.oc-table td:nth-child(2) { white-space: nowrap; color: var(--text); }
.oc-table td:nth-child(3) { color: var(--muted); }
.oc-note { margin-top: 8px; padding: 8px 10px; font-size: 12px; line-height: 1.7;
  color: var(--muted); border-left: 3px solid #e6a23c;
  background: rgba(230, 162, 60, .07); border-radius: 6px; }

/* 概览加载态（2026-10-19）：单运营 + 整月首次要 4~7 秒，页面毫秒级无变化会被当成「切换没反应」 */
#opsKpis.is-loading { opacity: .45; transition: opacity .15s ease; pointer-events: none; }

/* ================= 预报中转页（2026-10-21） =================
   用户口径：「不能直接进行预报，要进到一个独立的页面进行编辑中转之后才能预报」。
   参考巴士「草稿箱→转预报」页：顶部账单条 + 每单一块（服务/国际订单/商品/打包来源/操作）。
   布局：5 列固定比例，窄屏自动换行；整页全屏（不是小弹窗，要横向摊开核对）。
   ⚠️ z-index：295（**必须低于 .ui-modal 300** —— 本页内的「预报确认」「面单同步结果」等
      都走 uiConfirm/uiAlert，压在下面会看不见、点不到。2026-10-21 事故：原写 320，
      结果「移出本批」的确认框被本页整块盖住，用户完全无法操作）。 */
.fc-dlg { position: fixed; inset: 0; z-index: 295; display: flex; }
.fc-dlg[hidden] { display: none; }
.fc-mask { position: absolute; inset: 0; background: rgba(0,0,0,.5); }
.fc-box {
  position: relative; margin: 0 auto; width: 100%; max-width: 1560px;
  background: var(--panel); border: 1px solid var(--border);
  display: flex; flex-direction: column; min-height: 0; height: 100vh;
}
.fc-head { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--border); }
.fc-head b { font-size: 14px; font-weight: 600; }
.fc-sub { font-size: 12px; color: var(--muted); }
.fc-sub b { color: var(--danger, #e24b4a); font-weight: 600; }
.fc-x { border: none; background: transparent; color: var(--muted); cursor: pointer; padding: 2px 4px; }
.fc-x:hover { color: var(--text); }
.fc-bill {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
  padding: 8px 14px; border-bottom: 1px solid var(--border); background: var(--panel-2);
  font-size: 12px; color: var(--text);
}
.fc-bill b { font-weight: 600; }
.fc-dot { color: var(--border); }
.fc-acc { padding: 1px 8px; border: 1px solid var(--border); border-radius: 10px; }
.fc-acc.short { border-color: var(--danger, #e24b4a); color: var(--danger, #e24b4a); }
.fc-warn { color: #b45309; }
/* 预报结果条（2026-10-21）：替代 uiAlert —— 有失败时留在页里列原因，
   不再弹对话窗（用户口径：确认弹窗和结果弹窗都不需要）。 */
.fc-result { padding: 8px 14px; border-bottom: 1px solid var(--border); font-size: 12px; line-height: 1.6; }
.fc-result[hidden] { display: none; }
.fc-result.bad { background: rgba(226,75,74,.08); color: #b42318; }
.fc-result ul { margin: 4px 0 0; padding-left: 18px; }
.fc-result li { margin: 1px 0; overflow-wrap: anywhere; }
.fc-result .fc-more { color: var(--muted); }
.fc-result .fc-odev { margin-top: 4px; color: var(--muted); }
.fc-body { flex: 1; min-height: 0; overflow-y: auto; padding: 10px 14px 4px; }
.fc-empty { padding: 40px 0; text-align: center; color: var(--muted); font-size: 13px; }
.fc-ord { border: 1px solid var(--border); border-radius: 10px; margin-bottom: 10px; overflow: hidden; }
.fc-oh {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px;
  padding: 7px 10px; background: var(--panel-2); border-bottom: 1px solid var(--border);
  font-size: 12px; color: var(--muted);
}
.fc-oh b { color: var(--text); font-weight: 600; }
.fc-oh .fc-pay { margin-left: auto; color: var(--text); }
.fc-oh .fc-pay.self { color: var(--muted); }
/* 列宽规划（2026-10-21 用户口径：「前边三列宽度一样，操作列是前边三列的三分之一或者一半」）：
   ① 服务 / ② 国际订单·货件编号 / ③ 商品信息 —— 各 1 份（**等宽**）
   ④ 打包来源 1.25 份（要放采购单号 + 快递单号两个输入框，给宽一点）
   ⑤ 操作 0.5 份（= 前三列的**一半**）
   用 fr 不用固定 px：整页 max-width 1560，屏幕窄时按比例一起缩，不会把某一列挤没。
   ⚠️ 表头与各单必须共用**同一个变量** —— 分两处写死必然改一处漏一处，表头就和内容错位了。 */
.fc-dlg { --fc-cols: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.25fr) minmax(0, 0.5fr); }
.fc-cols { display: grid; grid-template-columns: var(--fc-cols); gap: 0; }
/* ★ 2026-10-21（用户口径：「要有上边的表头」+「表头根据首行向下批量填充」）：
   表头**只出一份**、放在滚动区**外**（#fcHead），行内不再重复列名（对齐巴士"转预报"参考图2）。
   ⚠️ grid-template-columns 必须与 `.fc-cols` **逐项一致**，否则表头与各单的列错位（那就白做了）；
      左右 margin 与 `.fc-body` 的 padding 对齐（14px），观感才是同一张表。
   ⚠️ `[hidden]` 必须显式补 `display:none` —— 本规则把 display 设成 grid 会盖掉 hidden 属性的默认值。 */
.fc-thead {
  display: grid; grid-template-columns: var(--fc-cols); gap: 0;
  margin: 10px 14px 0; background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; font-size: 11.5px; color: var(--muted);
}
.fc-thead[hidden] { display: none; }
.fc-th { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: 5px 10px; border-right: 1px solid var(--border); }
.fc-th:last-child { border-right: none; }
/* 批量填充按钮（主 = 该列的默认填充口径 / alt = 不常用的次要口径，如采购单号） */
.fc-fill { padding: 0 7px; font-size: 11px; line-height: 17px; border-radius: 9px; cursor: pointer;
  border: 1px solid var(--primary, #3884e8); background: transparent; color: var(--primary, #3884e8); }
.fc-fill:hover { background: var(--primary, #3884e8); color: #fff; }
.fc-fill.alt { border-color: var(--border); color: var(--muted); }
.fc-fill.alt:hover { background: var(--panel-2); color: var(--text); border-color: var(--muted); }
.fc-ro { font-size: 10.5px; opacity: .75; }
/* 未选服务等级的提醒（服务默认不填充 · 2026-10-21） */
.fc-need { display: inline-block; margin-bottom: 4px; padding: 0 6px; border-radius: 4px;
  background: rgba(226,75,74,.12); color: #b42318; font-size: 10.5px; line-height: 16px; }
.fc-ord.fc-nopick { border-color: rgba(226,75,74,.55); }
.fc-col { padding: 8px 10px; border-right: 1px solid var(--border); font-size: 12px; min-width: 0; }
.fc-col:last-child { border-right: none; }
.fc-c { font-size: 11px; color: var(--muted); margin-bottom: 4px; }
.fc-radio { display: flex; align-items: flex-start; gap: 6px; padding: 2px 0; line-height: 1.4; cursor: pointer; }
.fc-radio input { margin: 2px 0 0; }
.fc-radio span { flex: 1; }
.fc-radio i { font-style: normal; color: var(--muted); }
.fc-kv { display: flex; gap: 6px; padding: 1px 0; }
.fc-kv .k { color: var(--muted); min-width: 52px; }
.fc-kv .v { flex: 1; overflow-wrap: anywhere; }
.fc-item { display: flex; gap: 8px; padding-bottom: 6px; }
.fc-item img, .fc-noimg {
  width: 46px; height: 46px; object-fit: cover; border-radius: 6px;
  border: 1px solid var(--border); flex: none; background: var(--panel-2); cursor: zoom-in;
}
.fc-iline { font-size: 11.5px; line-height: 1.55; overflow-wrap: anywhere; }
/* 打包要求 / 备注（2026-10-21 用户口径：「这两个太大了，把他们缩短放到图片+信息这一列内部，
   不要放整个下边」）——
   原 `.fc-extra` 是横跨整行的一整条（每条单都多吃一行高度，15 单就多出一屏）；
   现在塞进「商品信息」列内、图下两个 2 行高的小框：宽度够读、高度只占两行。
   ⚠️ `.fc-extra` 样式**已删除**（无使用者）；恢复横排只需把这段的 display 改回 flex。 */
.fc-mini { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; padding-top: 6px;
  border-top: 1px dashed var(--border); }
.fc-mini label { display: flex; flex-direction: column; gap: 2px;
  font-size: 10.5px; color: var(--muted); }
.fc-mini textarea {
  width: 100%; height: 30px; min-height: 30px; resize: vertical; box-sizing: border-box;
  font-size: 11.5px; line-height: 1.35; padding: 3px 6px;
  border: 1px solid var(--border); border-radius: 5px;
  background: var(--panel); color: var(--text); font-family: inherit;
}
.fc-mini textarea:focus { outline: none; border-color: var(--primary, #3884e8); }
/* 预报校验不通过的行（2026-10-21 用户口径「不让预报并跳转到需要修改的行」）：
   红框 + 行头右侧挂「待补：…」标签（说明缺什么），并自动滚到第一条。
   ⚠️ 标签**不要** margin-left:auto —— .fc-oh 里 .fc-pay 已经吃了 auto，再加一个会把付款方顶到中间。 */
.fc-ord.fc-invalid { border-color: var(--danger, #e24b4a); box-shadow: 0 0 0 2px rgba(226,75,74,.13); }
.fc-badtag { padding: 0 7px; border-radius: 9px; font-size: 10.5px; line-height: 16px;
  background: rgba(226,75,74,.12); color: #b42318; white-space: nowrap; }
.fc-ops button { width: 100%; }
.fc-foot {
  display: flex; align-items: center; gap: 8px; padding: 10px 14px;
  border-top: 1px solid var(--border); background: var(--panel-2);
}
.fc-tip { font-size: 12px; color: var(--muted); }
.fc-tip.bad { color: var(--danger, #e24b4a); }
/* 顶部提示条（被跳过的单 / 超 100 截断）：与 #fcTip（随选择变化的拦截原因）**分开**，
   各占一块，避免互相覆盖（2026-10-21） */
.fc-note { font-size: 12px; color: #b45309; }
@media (max-width: 1100px) {
  .fc-cols { grid-template-columns: 1fr 1fr; }
  /* 窄屏表头跟着变两列（否则表头 5 列 vs 内容 2 列，彻底错位） */
  .fc-thead { grid-template-columns: 1fr 1fr; }
  .fc-col { border-bottom: 1px solid var(--border); }
}

/* ===== 草稿箱：采购单号 / 快递单号核对行（2026-10-21） =====
   打单页那两行是按 SKU 分行、高度对齐商品大图的（min-height 148px）；
   草稿箱是订单级核对，只要「看得清、缺的标红、假单号有标签」，用 lite 版压扁。 */
.pk-trk-row.pk-trk-lite { min-height: 0; flex-direction: row; align-items: center;
  gap: 6px; padding: 5px 8px; flex-wrap: wrap; }
.pk-trk-lite .pk-lbl { min-width: 56px; flex: 0 0 auto; }
.pk-trk-lite .pk-lbl-v { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-width: 0; }
.pk-absent { color: #e24b4a; font-weight: 600; }
.pk-fake-tag { display: inline-block; padding: 0 5px; border-radius: 4px;
  background: rgba(217,164,65,.16); color: #b57611; font-size: 11px; line-height: 16px; }
.pk-trk-fake { color: #b57611; }
.pk-multi { color: #b57611; }

/* 中转页：采购单号 / 快递单号可编辑（2026-10-21）
   草稿箱要核对采购单号，且库存流可填假单号占位 ⇒ 来源列从「只读列表」变成「平台只读 + 两个输入框」。 */
.fc-fld { display: flex; align-items: center; gap: 6px; padding: 2px 0; }
.fc-fld .k { color: var(--muted); min-width: 52px; flex: 0 0 auto; }
.fc-in {
  flex: 1; min-width: 0; font-size: 12px; padding: 3px 6px;
  border: 1px solid var(--border); border-radius: 5px;
  background: var(--panel); color: var(--text); font-family: monospace;
}
.fc-in:focus { outline: none; border-color: var(--primary, #3884e8); }
.fc-in-fake { border-color: rgba(217,164,65,.6); background: rgba(217,164,65,.08); }
.fc-fake-note { color: #b57611; font-size: 11px; }
.fc-stock-note { color: var(--muted); font-size: 11px; }

/* W-42 P1：履约方式徽标（OGL 直发 / 自建仓 / 未知）—— 订单总表店铺列后缀 */
.ff-badge { display:inline-block; margin-left:6px; font-size:11px; line-height:16px;
  padding:0 6px; border-radius:9px; white-space:nowrap; vertical-align:middle;
  border:1px solid rgba(148,163,184,.45); color:inherit; opacity:.95; }
.ff-badge.ff-ogl  { border-color:rgba(56,189,248,.55); background:rgba(56,189,248,.10); }
.ff-badge.ff-self { border-color:rgba(148,163,184,.35); background:rgba(148,163,184,.08); }
.ff-badge.ff-unk  { border-color:rgba(250,204,21,.60); background:rgba(250,204,21,.12); }

/* W-42（2026-10-21）：运营看板 KPI 下的履约方式分布条（OGL 直发 / 自建仓） */
.ops-substat.ff-chip i { font-style:normal; opacity:.72; margin-left:6px; font-size:11px; }
.ops-substat.ff-chip.is-ogl { border-color:rgba(56,189,248,.55); background:rgba(56,189,248,.10); }

/* W-42（2026-10-21）：详细订单「仓库标识」两套并行 —— 副行（另一套口径） */
.wh-sub { font-size:11px; line-height:14px; margin-top:1px; opacity:.62;
  max-width:132px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* W-42（2026-10-21）：采购卡片「混合」徽标 —— 一张卡（同采购链接）同时含两条轨的订单 */
.ff-badge.ff-mix { border-color:rgba(168,85,247,.55); background:rgba(168,85,247,.10); }
