/* ============================================================
   山鹊协同系统 · 极简皮肤 v2（minimal）
   必须在 styles.css 之后加载（替代 styles-polish.css）

   设计原则（极简）：
   ① 单一强调色：只用「鲜茶绿」一处强调（v15 提亮），其余全部退成中性灰阶
   ② 不用阴影做层次，只用 1px 发丝线 + 留白
   ③ 圆角统一（卡片 10 / 控件 8 / 标签 6），去掉装饰性渐变
   ④ 数字统一等宽（tabular-nums），金额一眼对齐
   ⑤ 保留全部可用性修正：字号下限、触控目标、对比度、导航展开
   ============================================================ */

:root {
  /* v78：只保留浅色模式 —— 强制浏览器把原生控件（下拉框 / 滚动条 / 日期选择器 / 表单）
     也按浅色渲染。老板手机开了系统深色，不声明的话这些控件会变黑。
     写在 CSS 里而不是只靠 <meta>：实测本项目 Edge/Chrome 154 下
     <meta name="color-scheme" content="light only"> 的 computed 仍是 normal（没生效），
     CSS 声明能确实生效。两行是渐进增强：老浏览器只认第一行 light。 */
  color-scheme: light;
  color-scheme: light only;

  --mini: 12px;              /* 手机端小字字号，宽屏手机版会放大到 13px */
  /* --- 中性灰阶 v23：改成「微冷中性」，与石墨·钴蓝统一 ---
     旧值是绿色方案留下的：--ink/--muted 带绿调（H156/H158）、--canvas/--line 偏暖（H60），
     冷色主色配暖绿灰会互相打架、整体发脏。 */
  --canvas: #f5f5f7;           /* H240 S11% L96% 微冷白 */
  --surface: #ffffff;
  --surface-soft: #fafafb;
  --ink: #1c1f22;              /* 近黑（微冷中性）主要文字 · 白卡 16.56:1 ✅ */
  --muted: #666b71;            /* 次要文字 · 白卡 5.38:1 ✅ */
  --line: #e3e4e8;             /* 发丝线 */
  --line-soft: #f0f1f3;

  /* --- 强调色 v70「松墨 · 翡翠」：主色深墨绿 + 高饱和绿点缀 ---
     v25→v70：主色由中性「石墨」#24282b 换成深墨绿「松墨」#1c3a2e（H156 S35% L17%），
     点缀色 --accent-bright / --accent-on / --accent-tile / --nav-icon-bright 全部保持不变。 */
  --accent: #1c3a2e;            /* 主色·松墨 H156 S35% L17%：按钮 / 强调文字 / 正数 · 白字 12.40:1 ✅ */
  --accent-deep: #132a20;       /* 主色加深 H154 S38% L12%：按下态 / 浅底上的文字 · 白卡 15.22:1 ✅ · 绿瓷砖底 12.86:1 ✅ */
  --accent-bright: #00a85f;     /* 点缀·翡翠 H154 S100% L33%：高饱和，只做小面积（品牌块/圆点/当前页/完成态）· 压白 3.10:1 ✅ */
  --accent-on: #04241a;         /* 点缀底上的文字。这个绿是中明度，必须用深字：5.32:1 ✅（白字仅 3.10 ✗）*/
  --nav-bar-bg: #1c3a2e;       /* 底栏专用底色：浅色下等于主色，深色下不跟 --accent 一起被提亮 · 白字 12.40:1 ✅ */
  --nav-icon-bright: #34d07e;   /* 浅色下抽屉图标专用：比 --accent-bright(#00a85f) 亮一档，压深底才有 3.0+ 对比 */
  --accent-soft: #e9efeb;       /* 主色浅底（微绿调 H140 S16% L93%）：选中行 / 表头 · 主色压其上 10.63:1 ✅ · --muted 压其上 4.61:1 ✅ */
  --accent-tile: #d5f3e2;       /* 点缀浅底（绿调）：完成标签 / 列表图标 · 14.77:1 ✅ */

  /* --- 兼容旧变量名：base 层 styles.css 仍在用 --green*，指向当前方案的强调色 --- */
  --green: var(--accent);
  --green-deep: var(--accent-deep);
  --green-bright: var(--accent-bright);
  --green-bright-ink: var(--accent-on);
  --green-soft: var(--accent-soft);
  --green-tile: var(--accent-tile);

  /* --- 辅助色（仅用于状态，面积很小） --- */
  --gold: #8a6a3a;             /* 暖砂：进行中 */
  --gold-ink: #7a5a2c;         /* 6.32:1 ✅ */
  --gold-soft: #f5f2ec;
  --red: #a3453e;
  --red-ink: #9c4038;          /* 6.55:1 ✅ */
  --red-soft: #faf1f0;

  --shadow: none;
  --radius-card: 10px;
  --radius-control: 8px;
  --radius-pill: 6px;

  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 24px;
}

body { background: var(--canvas); color: var(--ink); line-height: 1.65; }
/* v78：深色模式停用后，原来那条 ::placeholder 规则随深色块一起失效了，浏览器退回默认
   #757575 —— 在 --canvas 上只有 4.23:1。浅色是唯一模式，这里补一条全局的。
   （登录页输入框那条在 1650 附近，单独再修一次，因为它还多带一层 opacity） */
input::placeholder, textarea::placeholder { color: var(--muted); }
p { line-height: 1.7; }
h1 { font-size: 26px; font-weight: 680; letter-spacing: -.01em; }
h2 { font-size: 21px; font-weight: 660; }
h3 { font-size: 15px; font-weight: 650; }

/* 所有数字对齐 */
.stat-value, .account-balance, .sale-amount, .flow-value,
.money-positive, .money-negative, .wh-weight, .wh-date,
table td, table th { font-variant-numeric: tabular-nums; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* ============================================================
   一、侧栏：深色块面 → 浅色纸面，靠发丝线分区
   ============================================================ */
.sidebar {
  background: var(--surface);
  border-right: 1px solid var(--line);
  color: var(--ink);
  padding: 22px 14px 16px;
  width: 232px;
}
.brand-lockup { border-bottom: 1px solid var(--line); padding: 0 8px 20px; }
.brand-mark { background: var(--accent-bright); color: var(--accent-on); border-radius: 9px; width: 34px; height: 34px; font-size: 16px; }
.brand-name { font-size: 16px; font-weight: 700; letter-spacing: .02em; color: var(--ink); }
.brand-subtitle { color: var(--muted); opacity: 1; font-size: 10px; }
.nav-list { gap: 4px; padding-top: 18px; }
.nav-item {
  color: var(--muted);
  border-radius: var(--radius-control);
  padding: 10px 12px;
  font-size: 13.5px;
  box-shadow: none;
}
.nav-item:hover { background: var(--surface-soft); color: var(--ink); }
.nav-item.active {
  background: var(--accent-soft);
  color: var(--ink);
  font-weight: 650;
  box-shadow: inset 2px 0 var(--accent);
}
/* v78：--muted 再乘 .8 只剩 3.54:1，侧栏图标看不清。深色模式已停用，浅色是唯一模式，不再淡化。 */
.nav-icon { opacity: 1; font-size: 15px; }
.sidebar-bottom { gap: 6px; }
.storage-card { background: var(--surface-soft); border: 1px solid var(--line); border-radius: var(--radius-card); }
.storage-card span { color: var(--muted); opacity: 1; }
.storage-dot { background: var(--accent-bright); box-shadow: 0 0 0 3px var(--accent-soft); }
.sidebar-link { color: var(--muted); font-size: 12px; }
.sidebar-link:hover { color: var(--ink); }
.sidebar-link.danger:hover { color: var(--red-ink); }
.main-content { margin-left: 232px; width: calc(100% - 232px); padding: 30px 40px 60px; }

/* ============================================================
   二、按钮：主按钮近黑，次按钮描边，去掉立体感
   ============================================================ */
.primary-button, .secondary-button, .ghost-button {
  border-radius: var(--radius-control);
  font-size: 13px;
  font-weight: 650;
  box-shadow: none;
  transition: background .18s, border-color .18s, color .18s;
}
.primary-button { background: var(--accent); color: #fff; }
.primary-button:hover { background: var(--accent-deep); transform: none; }
.secondary-button { background: var(--surface-soft); color: var(--ink); border: 1px solid var(--line); }
.secondary-button:hover { background: var(--line-soft); }
.ghost-button { background: var(--surface); border: 1px solid var(--line); color: var(--muted); font-weight: 600; }
.ghost-button:hover { color: var(--ink); border-color: var(--line); background: var(--surface-soft); }

.icon-button { background: var(--surface); border: 1px solid var(--line); color: var(--ink); border-radius: var(--radius-control); height: 36px; }
.icon-button:hover { border-color: var(--ink); }
.avatar { background: var(--ink); color: #fff; }
.voice-button { background: var(--surface); color: var(--ink); border: 1px solid var(--line); }
.mini-button { background: var(--surface); border: 1px solid var(--line); color: var(--ink); border-radius: var(--radius-control); padding: 6px 10px; font-weight: 600; }
.mini-button:hover { border-color: var(--accent); color: var(--accent); }
.text-button { color: var(--accent); font-weight: 650; }
/* 红色只给「风险」：该收没收、该付没付、删除类操作 */
.danger-text, .money-negative { color: var(--red-ink); }
.money-positive { color: var(--accent); }
/* 只是「方向」为负（付多于收）不算风险，用中性色，靠 − 号表达 */
.money-neutral { color: var(--ink); font-weight: 650; }
.invoice-contract-button { background: var(--gold-soft); color: var(--gold-ink); }
.invoice-contract-button:hover { background: #efe9dd; }
.close-button { background: var(--surface-soft); color: var(--muted); border-radius: var(--radius-control); }
.remove-row { background: var(--red-soft); color: var(--red-ink); }

/* ============================================================
   三、卡片 / 面板：白底 + 发丝线，无阴影
   ============================================================ */
.panel, .stat-card, .account-card, .warehouse-card,
.contact-stat-card, .stock-card, .source-choice, .workflow-task {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: none;
}
.panel-header { padding: 18px 20px 12px; }
.panel-header p { color: var(--muted); font-size: 12px; }
.eyebrow { color: var(--muted); font-size: 10px; letter-spacing: .12em; font-weight: 700; }

.stat-card { min-height: 118px; padding: 16px 18px; }
.stat-label { color: var(--muted); font-size: 12px; font-weight: 600; }
.stat-value { font-size: 24px; font-weight: 700; letter-spacing: -.02em; margin: 12px 0 8px; }
.stat-meta { color: var(--muted); font-size: 11px; }
/* 头号指标卡（v18）：白底 + 3px 翠绿左标 —— 点缀只留一条线，不再满铺亮块 */
.stat-card.accent-card { background: var(--surface); color: var(--ink); border-color: var(--line); border-left: 3px solid var(--accent-bright); }
.accent-card .stat-label { color: var(--muted); }
.accent-card .stat-meta { color: var(--muted); }
.accent-card .stat-value { color: var(--ink); }
.stat-card.profit-card { background: var(--surface); border-color: var(--line); }

/* 中和 styles.css 里的绿/奶油硬编码底色 */
th, .item-editor tfoot td { background: var(--surface-soft); color: var(--muted); }
.settlement-card, .catalog-row, .allocation-row, .detail-stat,
.item-editor input, .form-field input, .form-field select, .form-field textarea,
.receipt-type, .stock-numbers div { background: var(--surface); }
.warehouse-card, .stock-card .stock-numbers div { background: var(--surface); }
.expense-summary-card { background: var(--surface); border-color: var(--line); }
.packing-selection-notice, .warehouse-selection-bar, .proxy-return-fields,
.invoice-recognition-status, .company-modal-brand, .voice-shell, .parse-item {
  background: var(--surface-soft); border-color: var(--line); box-shadow: none;
}
.company-profile-strip { background: var(--surface); border-color: var(--line); box-shadow: none; background-image: none; }
.company-profile-logo, .company-modal-logo { background: var(--surface-soft); }
/* inv147：A4 预览 —— 纸是白的，容器用浅灰托出纸张边界；排版统一由 styles.css 的 A4 规则负责，
   这里不再覆盖字号 / 间距，否则屏幕版式和打印出来对不上。 */
.contract-preview { background: #e7eae4; }

.invoice-recognition-status.ready { background: var(--accent-tile); color: var(--accent-deep); }
.invoice-recognition-status.pending { background: var(--gold-soft); color: var(--gold-ink); }
.invoice-contract-upload { background: var(--surface); border: 1px dashed var(--line); color: var(--muted); }
.upload-button { background: var(--surface); border: 1px dashed var(--line); color: var(--muted); }
.upload-button:hover { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }

.sku-label { color: var(--gold-ink); }
.supplier-math { color: var(--ink); font-weight: 650; }
.supplier-link-row em { color: var(--gold-ink); font-style: normal; }
.unit-toggle-button { color: var(--muted); }
.unit-toggle-button.active { color: var(--ink); font-weight: 650; }
.status-pill { border-radius: var(--radius-pill); padding: 4px 8px; font-size: 11px; font-weight: 650; }
.status-pill.progress { background: var(--gold-soft); color: var(--gold-ink); }
.status-pill.completed { background: var(--accent-tile); color: var(--accent-deep); }
.sale-icon { background: var(--accent-tile); color: var(--accent-deep); border-radius: var(--radius-control); }
.flow-bullet.in { background: var(--accent-tile); color: var(--accent-deep); }
/* 流出是方向不是风险：中性灰，靠 ↑ 与 − 号表达 */
.flow-bullet.out { background: var(--surface-soft); color: var(--muted); border: 1px solid var(--line); }
.flow-value.in { color: var(--ink); }
.flow-value.out { color: var(--muted); }
/* 趋势箭头：base 层写死 #91d4a2（浅绿），非绿方案下必须覆盖。
   上涨是正面信号 → 主色；不再用绿。 */
.trend { color: var(--muted); }
.trend.up { color: var(--accent); }
.trend.down { color: var(--red-ink); }
.timeline-dot { background: var(--surface-soft); color: var(--muted); border-radius: var(--radius-control); }
.workflow-track span { background: var(--surface); border: 1px solid var(--line); color: var(--muted); }
.workflow-track li.done span { background: var(--accent-tile); border-color: #a5e2c3; color: var(--accent-deep); }
.workflow-track li.done::after { background: var(--line); }
.workflow-track li.current span { background: var(--gold-soft); border-color: var(--gold); color: var(--gold-ink); box-shadow: none; }
.workflow-task strong { color: var(--red-ink); }

/* 悬停：只换边框色，不做位移 */
.warehouse-card:hover, .stock-card:hover { border-color: var(--accent-bright); background: var(--surface); transform: none; }
.source-card.selected { border-color: var(--accent-bright); background: var(--accent-tile); }
tbody tr:hover { background: var(--surface-soft); }
.sale-row:hover { background: var(--surface-soft); border-radius: var(--radius-control); }
td.money-negative { font-weight: 600; background: var(--red-soft); border-radius: var(--radius-control); }

/* 表单 */
.form-field label { color: var(--muted); font-size: 12px; font-weight: 600; }
.form-field input, .form-field select, .form-field textarea { border: 1px solid var(--line); border-radius: var(--radius-control); }
.form-field input:focus, .form-field select:focus, .form-field textarea:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.search-box { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-control); }
select { border: 1px solid var(--line); border-radius: var(--radius-control); background: var(--surface); }
.record-button { background: var(--ink); }
.record-button.recording { background: var(--red); }
.pulse { background: var(--accent-bright); }

/* 弹窗 */
.modal-backdrop { background: rgba(31,36,34,.34); }
.modal { border-radius: 12px; border: 1px solid var(--line); box-shadow: 0 24px 60px rgba(31,36,34,.14); }
.modal-head p { color: var(--muted); }
.form-foot .hint { color: var(--muted); }

/* ============================================================
   四、表格：去掉斑马底与粗内边距，只留发丝线
   ============================================================ */
th {
  font-size: 11px; font-weight: 650; color: var(--muted);
  padding: 11px 14px; border-bottom: 1px solid var(--line); background: var(--surface-soft);
}
td { padding: 12px 14px; border-bottom: 1px solid var(--line-soft); font-size: 13px; }
.table-primary { font-weight: 650; }
.table-secondary { color: var(--muted); font-size: 11px; }
.table-wrap { background-color: var(--surface); }
.empty-state { color: var(--muted); }

/* ============================================================
   五、账户区 + 登录（跟随浅色极简）
   ============================================================ */
.account-chip {
  background: var(--surface-soft); border: 1px solid var(--line);
  border-radius: var(--radius-card); color: var(--ink); padding: 9px 11px;
}
.account-chip:hover { background: var(--line-soft); border-color: var(--line); }
/* --- v43 账户头像：单圈 + 登录态用颜色区分（B+D）---
   ① 去掉「灰圆套绿圆」的甜甜圈双圈：容器不再画圆，只剩头像这一颗。
   ② 已登录 = 翡翠实心圆 + 内白环 + 浅绿外环；未登录 = 中性灰圆 + 淡灰环，
      一眼就能看出「还没登录」，不会和已登录混淆。
   ③ 环一律用 box-shadow 画，不用 border —— border 会把圆撑大、破坏 44×44 触控区。
   ④ 文字改成两字（见 app.js 的 avatarText），字号必须跟着收，否则两字挤爆圆。
   v86：这条原来只有宽高 + 配色，既没 display、没居中，连 border-radius 都没有 ——
       字是靠行内盒的默认位置摆的。放两字时填满圆看不出来，改成单姓后一眼就看出偏左上。
       这里补成「flex 居中 + 正圆」，横竖都居中；line-height 收成 1 免得行高把字往下顶。 */
.account-chip-avatar {
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; overflow: hidden;
  line-height: 1; text-align: center; flex: 0 0 auto;
  background: var(--accent-soft); color: var(--muted);
  box-shadow: 0 0 0 1.5px var(--line);
  font-size: 12px; font-weight: 650; letter-spacing: -0.2px;
}
/* .is-signed-in 打在 [data-account-btn] 上（含 .mobile-avatar-btn，它不是 .account-chip），
   所以这里只认 .is-signed-in，不能写 .account-chip.is-signed-in，否则手机首页那颗不生效。 */
.is-signed-in .account-chip-avatar {
  background: var(--accent-bright); color: var(--accent-on);
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 5px var(--accent-tile);
}
/* 手机底栏那颗（base 里是 36px，容器 54px）跟着统一到 38px/13px，别出现第三种样式 */
.mobile-account-chip .account-chip-avatar { width: 38px; height: 38px; font-size: 13px; }
/* 「我的账户」弹窗里那颗不在 [data-account-btn] 里，拿不到 .is-signed-in，
   会被上面的「未登录灰圆」误伤；这个弹窗只在已登录时才会打开，所以直接按已登录配色给。
   颜色全用变量，深色块里不用再复制一份。 */
/* v48：这颗放大到 56px 并显示**完整姓名**（最多 6 字），所以要能折行、字号按字数自适应。
   小圆（32/38px）照样只放两字，别一起改 —— 两字在小圆里才清楚。 */
.account-menu-head .account-chip-avatar {
  background: var(--accent-bright); color: var(--accent-on);
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 5px var(--accent-tile);
  flex: 0 0 56px; width: 56px; height: 56px; border-radius: 50%;
  padding: 5px; box-sizing: border-box;
  text-align: center; line-height: 1.12;
  word-break: break-all; letter-spacing: -0.3px;
}
.account-menu-head .account-chip-avatar.av-len-2 { font-size: 21px; letter-spacing: 0; }
.account-menu-head .account-chip-avatar.av-len-4 { font-size: 15px; }
.account-menu-head .account-chip-avatar.av-len-6 { font-size: 12.5px; }
.account-chip-text strong { font-size: 13px; font-weight: 620; }
.account-chip-text span { color: var(--muted); opacity: 1; font-size: 11px; }
.auth-tabs { background: var(--surface-soft); border-radius: var(--radius-card); padding: 3px; }
.auth-tab { color: var(--muted); border-radius: var(--radius-control); font-size: 13px; }
.auth-tab.active { background: var(--surface); color: var(--ink); font-weight: 650; box-shadow: 0 1px 3px rgba(31,36,34,.08); }
.auth-remember, .auth-register p { color: var(--muted); }
.auth-gate-head h3 { font-weight: 650; }
.auth-gate-head p { color: var(--muted); }
.account-menu-head { background: var(--surface-soft); border-radius: var(--radius-card); }
.account-menu-rows > div { border: 1px solid var(--line); border-radius: var(--radius-card); }
.account-menu-rows span { color: var(--muted); }

/* ============================================================
   六、采购仓：两行列表（供应商 / 重量 / 状态 · 品名 / 剩余 / 未付）
   ============================================================ */
.warehouse-card-list { gap: 0; padding: 0; }
.warehouse-summary {
  display: flex; flex-wrap: wrap; gap: 4px 16px;
  padding: 9px 13px; border-bottom: 1px solid var(--line);
  background: var(--surface-soft); font-size: 11.5px; color: var(--muted);
}
.warehouse-summary b { color: var(--ink); font-weight: 650; margin-left: 3px; }
/* v78：去掉 .85 淡化 —— 只剩 3.79:1。--muted 本身就是次要色，不必再压。 */
.warehouse-summary-hint { color: var(--muted); opacity: 1; }
.warehouse-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  column-gap: 8px; align-items: center;
  padding: 10px 13px; margin: 0;
  border: 0; border-bottom: 1px solid var(--line-soft); border-radius: 0;
  background: transparent; cursor: pointer;
}
.warehouse-row:last-child { border-bottom: 0; }
.warehouse-row:hover, .warehouse-row:active { background: var(--surface-soft); }
.warehouse-row .wh-line1 { grid-column: 2; grid-row: 1; display: flex; align-items: center; gap: 8px; min-width: 0; }
.warehouse-row .wh-line2 { grid-column: 2; grid-row: 2; display: flex; align-items: center; gap: 8px; min-width: 0; margin-top: 2px; }
/* v94：批次列表补日期，字号整体放大一档 */
.warehouse-row .wh-date { flex: 0 0 auto; font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.warehouse-row .wh-supplier { flex: 0 1 auto; max-width: 34%; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14.5px; font-weight: 600; }
.warehouse-row .wh-weight { flex: 0 0 auto; font-size: 14.5px; font-weight: 650; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* 剩余量做成重量后面的灰色小字（不再单独占一个标签，一行标签数控制在 2 个以内） */
.warehouse-row .wh-remain { font-style: normal; font-weight: 500; color: var(--muted); }
/* v94：品名从灰色小字提成主信息，字号放大、颜色用主墨色 */
.warehouse-row .wh-products { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14.5px; font-weight: 650; color: var(--ink); }
.warehouse-row .wh-price { flex: 0 0 auto; font-size: 13.5px; font-weight: 600; color: var(--accent-deep); font-variant-numeric: tabular-nums; white-space: nowrap; }
.warehouse-row .wh-amount { flex: 0 0 auto; font-size: 13.5px; font-weight: 650; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* v97：第二行末位改「未付金额」——欠款红、结清绿 */
.warehouse-row .wh-amount.is-debt { color: var(--red-ink); }
.warehouse-row .wh-amount.is-clear { color: var(--accent-deep); }
/* v78：原来用 --line（发丝线色）画箭头只有 1.27:1，等于看不见。换 --muted（5.38:1）。 */
.warehouse-row .wh-chevron { flex: 0 0 auto; color: var(--muted); font-size: 16px; }
.warehouse-row .status-pill { flex: 0 0 auto; padding: 3px 6px; font-size: 10.5px; white-space: nowrap; }
/* 两个状态标签：流转=绿/砂，结算=砂/绿 */
.warehouse-row .wh-pill-settle.completed { background: var(--accent-tile); color: var(--accent-deep); }
.warehouse-row .wh-pill-settle.progress { background: var(--gold-soft); color: var(--gold-ink); }

/* 详情页：三类状态并排 */
.status-triple { display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 8px; }
.status-triple > div {
  display: flex; flex-direction: column; align-items: flex-start; gap: 5px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius-control);
  background: var(--surface-soft);
}
.status-triple > div > span:first-child { font-size: 11.5px; color: var(--muted); }
.status-triple small { font-size: 11px; color: var(--muted); line-height: 1.5; }

/* 等级小标签 */
.grade-tag {
  display: inline-block; margin-left: 6px; padding: 1px 5px;
  border: 1px solid var(--line); border-radius: 5px;
  background: var(--surface-soft); color: var(--muted);
  font-size: 10.5px; font-weight: 600; white-space: nowrap;
}
/* 销售明细卡片：品名 + 等级并排 */
.item-name-grid { display: grid; grid-template-columns: minmax(0, 1fr) 96px; gap: 8px; }

/* 合作状态标签：比普通状态更轻 */
.coop-pill { padding: 2px 6px; font-size: 10.5px; font-weight: 600; white-space: nowrap; }

/* 包装卡片：加入出成率 / 规格件数后，数字块改为自适应换行 */
.stock-numbers { grid-template-columns: repeat(auto-fit, minmax(78px, 1fr)); }
.stock-numbers em { display: block; margin-top: 2px; }

/* 资金流水号：小号等宽，不与金额抢视线 */
.payment-no { font-size: 11.5px; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.warehouse-row .warehouse-batch-check-wrap {
  grid-column: 1; grid-row: 1 / span 2; align-self: center;
  display: inline-flex; align-items: center;
  padding: 0; margin: 0; background: none; border: none;
}
.warehouse-row .warehouse-batch-check-wrap span { display: none; }
.warehouse-row .warehouse-batch-check { width: 16px; height: 16px; margin: 0; accent-color: var(--accent-bright); }

/* ============================================================
   六·补 表格合计行（tfoot）
   ============================================================ */
tfoot td {
  background: var(--surface-soft); border-top: 1px solid var(--line);
  padding: 10px 14px; font-size: 12px; font-weight: 600; color: var(--muted);
}
tfoot .tf-label { color: var(--ink); font-weight: 650; }
tfoot .tf-total { white-space: nowrap; }
tfoot .tf-total .table-secondary { color: var(--muted); font-weight: 500; }

/* ============================================================
   七、移动端：白底底栏 + 字号下限 + 触控目标 + 导航展开
   ============================================================ */
/* 手机优先：≤720px 一律手机版；触屏设备放宽到 1000px（折叠屏展开、横屏、平板竖屏也走手机版） */
.mobile-dashboard-header { display: none; }

@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  body { font-size: 15px; }
  /* 手机版必须显式复位：否则被上面的桌面侧栏宽度（232px）覆盖，正文会被挤窄 */
  .main-content { width: 100%; margin-left: 0; max-width: none; padding: 14px 12px calc(92px + env(safe-area-inset-bottom)); }
  .topbar { margin-bottom: 16px; align-items: center; }
  .topbar .eyebrow { display: none; }
  .topbar h1 { font-size: 20px; }

  /* 字号下限 11px（中文可读性） */
  .stat-label, .stat-meta, .account-kind, .account-name, .account-flow,
  .sale-sub, .flow-desc, .table-secondary, .status-pill,
  .company-profile-copy small, .company-info-list span,
  .source-choice small, .source-summary small, .source-quantity,
  .stock-numbers small, .stock-numbers em, .stock-card p,
  .detail-stat span, .timeline-copy span, .receipt-name,
  .registration-row span, .registration-row small,
  .ledger-account-card span, .supplier-link-row span,
  .supplier-submission-row span, .supplier-submission-row small,
  .contact-stat-card small, .parse-label, .invoice-attachment, .field-hint,
  .packing-card-meta, .available-sales-card small,
  .supplier-batch-money-grid span, .supplier-batch-money-grid small,
  .supplier-invoice-parse-hint, .supplier-verify-summary span,
  .supplier-verify-table td small, .supplier-verify-hint, .supplier-verify-error,
  .supplier-verify-foot, .form-foot .hint, .voice-hint, .invoice-recognition-status,
  .invoice-contract-note, .invoice-contract-file, .shipment-summary span,
  .file-status, .warehouse-batch-check-wrap { font-size: var(--mini); }

  /* 底栏：白底 + 发丝线（位置、宽度、方向都要复位，否则仍是左侧竖栏） */
  .sidebar {
    position: fixed;
    inset: auto 0 0 0;
    width: 100%;
    height: calc(68px + env(safe-area-inset-bottom));
    z-index: 4;
    flex-direction: row;
    align-items: center;
    background: var(--surface);
    border-top: 1px solid var(--line);
    border-right: 0;
    padding: 6px 8px env(safe-area-inset-bottom);
  }
  .nav-item { color: var(--muted); }
  /* 底栏当前项：亮绿药丸 + 深绿字（6.9:1），一眼看出在哪个页 */
  .nav-item.active { box-shadow: none; background: var(--accent-tile); color: var(--accent-deep); font-weight: 700; }
  .sidebar.nav-expanded > .nav-list .nav-item.active { background: var(--accent-tile); color: var(--accent-deep); }

  /* 收起态：一行 */
  .sidebar:not(.nav-expanded) > .nav-list { display: flex !important; grid-template-columns: none !important; gap: 3px; overflow: hidden; }
  .sidebar:not(.nav-expanded) > .nav-list .nav-item { font-size: 12px; padding: 8px 6px; min-width: 0; min-height: 54px; }

  /* 展开态：2 列网格，一次看全 */
  .sidebar.nav-expanded > .nav-list {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 8px; padding: 12px;
    max-height: min(520px, calc(100vh - 120px));
    overflow: visible;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    box-shadow: 0 12px 40px rgba(31,36,34,.12);
  }
  .sidebar.nav-expanded > .nav-list .nav-item {
    font-size: 13px; min-height: 52px; padding: 10px 12px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    background: var(--surface-soft);
  }
  .mobile-nav-toggle {
    font-size: var(--mini); min-height: 54px; min-width: 66px;
    border: 1px solid var(--line) !important;
    background: var(--surface-soft) !important;
    color: var(--ink) !important;
    border-radius: var(--radius-control);
  }

  /* 触控目标 ≥ 40px */
  .remove-row { min-height: 40px; width: 40px; }
  .close-button { width: 40px; height: 40px; }
  .mini-button { min-height: 40px; padding: 9px 11px; }
  .upload-button { min-height: 44px; }
  .receipt-type { min-height: 44px; }
  .voice-button, .primary-button, .secondary-button, .ghost-button { min-height: 42px; }

  /* 手机优先：整体再收紧一档，内容区留更多宽度 */
  .main-content { padding: 12px 10px calc(92px + env(safe-area-inset-bottom)); }
  .panel { border-radius: 12px; }
  .panel-header { padding: 13px 12px 9px; }
  .panel-header h3 { font-size: 13.5px; }
  .panel-header p { font-size: var(--mini); margin-top: 4px; }
  .section-toolbar > div:first-child p { font-size: 12px; line-height: 1.5; }
  .empty-state { padding: 22px 12px; font-size: 12px; }
  .filter-row { margin-bottom: 10px; }
  .search-box { height: 40px; }

  /* 紧凑排版 */
  .stat-grid { gap: 8px; margin-bottom: 14px; }
  .stat-card { padding: 12px; min-height: 92px; }
  .stat-value { font-size: 19px; margin: 9px 0 6px; }
  .panel-header { padding: 14px 14px 10px; }
  .sales-list, .flow-list { padding: 0 8px 8px; }
  .sale-row, .flow-row { gap: 8px; padding: 11px 10px; }
  .welcome-row, .dashboard-company-head { gap: 12px; margin-bottom: 16px; }
  .welcome-row p, .dashboard-company-head p { margin-top: 4px; }
  .section-toolbar { gap: 10px; margin-bottom: 14px; }
  .account-card { padding: 11px 12px; }
  .detail-summary { gap: 8px; }
  .detail-stat { padding: 9px 11px; }
  .form-grid, .parse-grid { gap: 10px 12px; }
  .form-foot { gap: 10px; margin-top: 16px; }
  .modal { padding: 16px 14px calc(24px + env(safe-area-inset-bottom)); }
  .modal-actions button { min-height: 46px; }

  /* ===== 表格：手机端改为「行卡片」，信息按重要性重排 ===== */
  #customersView table, #suppliersView table, #salesView table, #cashflowView table {
    display: block; width: 100%; min-width: 0; table-layout: auto;
  }
  #customersView thead, #suppliersView thead, #salesView thead, #cashflowView thead { display: none; }
  #customersView tbody, #suppliersView tbody, #salesView tbody, #cashflowView tbody { display: block; }
  #customersView tbody tr, #suppliersView tbody tr, #salesView tbody tr, #cashflowView tbody tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 3px 10px;
    padding: 11px 13px;
    border-bottom: 1px solid var(--line-soft);
  }
  #customersView tbody tr:last-child, #suppliersView tbody tr:last-child,
  #salesView tbody tr:last-child, #cashflowView tbody tr:last-child { border-bottom: 0; }
  #customersView tbody td, #suppliersView tbody td, #salesView tbody td, #cashflowView tbody td {
    display: block; padding: 0; border: 0; text-align: left; min-width: 0;
  }
  /* 行内文字不撑破卡片 */
  #customersView .table-primary, #suppliersView .table-primary, #salesView .table-primary {
    display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .table-secondary { display: block; font-size: var(--mini); }
  /* 名称列：名称 + 合作状态同行，账期信息另起一行，避免三行堆叠 */
  #customersView tbody td:nth-child(1), #suppliersView tbody td:nth-child(1) {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 6px;
  }
  #customersView tbody td:nth-child(1) .table-primary,
  #suppliersView tbody td:nth-child(1) .table-primary { flex: 1 1 55%; }
  #customersView tbody td:nth-child(1) .table-secondary,
  #suppliersView tbody td:nth-child(1) .table-secondary { flex: 1 1 100%; }

  /* --- 客户：客户名 / 待收款；次行 销售额 / 已收款；末行 联系方式 / 最近交易；操作 --- */
  #customersView tbody td:nth-child(1) { grid-column: 1; grid-row: 1; }
  #customersView tbody td:nth-child(9) { grid-column: 2; grid-row: 1; text-align: right; font-weight: 650; white-space: nowrap; }
  #customersView tbody td:nth-child(7) { grid-column: 1; grid-row: 2; font-size: var(--mini); color: var(--muted); white-space: nowrap; }
  #customersView tbody td:nth-child(8) { grid-column: 2; grid-row: 2; text-align: right; font-size: var(--mini); color: var(--muted); white-space: nowrap; }
  #customersView tbody td:nth-child(3) { grid-column: 1; grid-row: 3; font-size: var(--mini); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #customersView tbody td:nth-child(10) { grid-column: 2; grid-row: 3; text-align: right; font-size: var(--mini); color: var(--muted); white-space: nowrap; }
  #customersView tbody td:nth-child(11) { grid-column: 1 / -1; grid-row: 4; justify-self: end; }
  #customersView tbody td:nth-child(2), #customersView tbody td:nth-child(4),
  #customersView tbody td:nth-child(5), #customersView tbody td:nth-child(6) { display: none; }

  /* --- 供应商：供应商 / 未结；次行 累计采购 / 采购额；末行 联系方式 / 最近采购；操作 --- */
  #suppliersView tbody td:nth-child(1) { grid-column: 1; grid-row: 1; }
  #suppliersView tbody td:nth-child(8) { grid-column: 2; grid-row: 1; text-align: right; font-weight: 650; white-space: nowrap; }
  #suppliersView tbody td:nth-child(5) { grid-column: 1; grid-row: 2; font-size: var(--mini); color: var(--muted); white-space: nowrap; }
  #suppliersView tbody td:nth-child(6) { grid-column: 2; grid-row: 2; text-align: right; font-size: var(--mini); color: var(--muted); white-space: nowrap; }
  #suppliersView tbody td:nth-child(3) { grid-column: 1; grid-row: 3; font-size: var(--mini); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #suppliersView tbody td:nth-child(9) { grid-column: 2; grid-row: 3; text-align: right; font-size: var(--mini); color: var(--muted); white-space: nowrap; }
  #suppliersView tbody td:nth-child(10) { grid-column: 1 / -1; grid-row: 4; justify-self: end; }
  #suppliersView tbody td:nth-child(2), #suppliersView tbody td:nth-child(4),
  #suppliersView tbody td:nth-child(7) { display: none; }

  /* --- 销售单：客户 / 状态，次行 批次+金额，末行 日期 · 已收待收 --- */
  #salesView tbody td:nth-child(3) { grid-column: 1; grid-row: 1; font-weight: 650; }
  #salesView tbody td:nth-child(6) { grid-column: 2; grid-row: 1; text-align: right; }
  #salesView tbody td:nth-child(2) { grid-column: 1 / -1; grid-row: 2; }
  #salesView tbody td:nth-child(2) .sales-amount-line { color: var(--ink); font-weight: 650; }
  #salesView tbody td:nth-child(1) { grid-column: 1; grid-row: 3; font-size: var(--mini); color: var(--muted); }
  #salesView tbody td:nth-child(1) .date-stack { display: inline; }
  #salesView tbody td:nth-child(1) .date-stack strong,
  #salesView tbody td:nth-child(1) .date-stack span { display: inline; font-size: var(--mini); }
  #salesView tbody td:nth-child(4) { grid-column: 2; grid-row: 3; text-align: right; font-size: var(--mini); white-space: nowrap; }
  #salesView tbody td:nth-child(5) { display: none; }
  /* v3.10：附件打包列 —— 手机上独占一行、靠右，两个按钮自动换行 */
  #salesView tbody td:nth-child(7) { grid-column: 1 / -1; grid-row: 4; justify-self: end; }
  #salesView tbody td:nth-child(7) .mini-button { min-height: 32px; }

  /* --- 资金流水：对方 / 金额；次行 日期 · 流水号 · 余额；末行 用途 · 经手人 --- */
  #cashflowView tbody tr { grid-template-columns: minmax(0, 1fr) auto auto; }
  #cashflowView tbody td:nth-child(4) { grid-column: 1; grid-row: 1; font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #cashflowView tbody td:nth-child(8) { grid-column: 2 / span 2; grid-row: 1; text-align: right; font-weight: 700; white-space: nowrap; }
  #cashflowView tbody td:nth-child(2) { grid-column: 1; grid-row: 2; font-size: var(--mini); color: var(--muted); white-space: nowrap; }
  #cashflowView tbody td:nth-child(1) { grid-column: 2; grid-row: 2; font-size: var(--mini); color: var(--muted); white-space: nowrap; }
  #cashflowView tbody td:nth-child(9) { grid-column: 3; grid-row: 2; text-align: right; font-size: var(--mini); color: var(--muted); white-space: nowrap; }
  #cashflowView tbody td:nth-child(6) { grid-column: 1 / span 2; grid-row: 3; font-size: var(--mini); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #cashflowView tbody td:nth-child(7) { grid-column: 3; grid-row: 3; text-align: right; font-size: var(--mini); color: var(--muted); white-space: nowrap; max-width: 7em; overflow: hidden; text-overflow: ellipsis; }
  #cashflowView tbody td:nth-child(3), #cashflowView tbody td:nth-child(5) { display: none; }
  #cashflowView tbody td:nth-child(6) .table-secondary { display: inline-block; margin-left: 6px; }

  .contact-actions { flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
  .contact-actions .text-button { min-height: 34px; padding: 6px 8px; }

  /* 合计行在手机上横向铺开 */
  #customersView tfoot, #suppliersView tfoot, #salesView tfoot, #cashflowView tfoot { display: block; }
  #customersView tfoot tr, #suppliersView tfoot tr, #salesView tfoot tr, #cashflowView tfoot tr {
    display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px 12px;
    padding: 9px 13px; background: var(--surface-soft);
    border-top: 1px solid var(--line); font-size: var(--mini);
  }
  #salesView tfoot td:nth-child(3) { display: none; }
  #customersView tfoot td, #suppliersView tfoot td, #salesView tfoot td, #cashflowView tfoot td {
    display: block; padding: 0; border: 0; background: transparent;
  }
  #customersView tfoot td:empty, #suppliersView tfoot td:empty,
  #salesView tfoot td:empty, #cashflowView tfoot td:empty { display: none; }
  #customersView tfoot .tf-total .table-secondary, #suppliersView tfoot .tf-total .table-secondary,
  #salesView tfoot .tf-total .table-secondary, #cashflowView tfoot .tf-total .table-secondary { color: var(--muted); }

  th { padding: 10px 12px; }
  td { padding: 11px 12px; }

  /* 流程条横滑 */
  .workflow-track { display: flex; grid-template-columns: none; overflow-x: auto; gap: 6px; padding: 4px 2px 8px; scrollbar-width: none; }
  .workflow-track::-webkit-scrollbar { display: none; }
  .workflow-track li { flex: 0 0 auto; min-width: 62px; font-size: var(--mini); }
  .workflow-track li::after { display: none; }
}

/* v3.10：手动切成手机版（html.force-mobile）时视口仍是宽屏，媒体查询不命中，补一份副本 */
html.force-mobile #salesView tbody td:nth-child(7) { grid-column: 1 / -1; grid-row: 4; justify-self: end; }
html.force-mobile #salesView tbody td:nth-child(7) .mini-button { min-height: 32px; }

@media (min-width: 1200px) {
  .stat-grid, .contact-stat-grid, .detail-summary { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* 采购明细：加入「等级」后，桌面列宽重新分配（共 9 列） */
.purchase-item-editor th:nth-child(1) { width: 15%; }
.purchase-item-editor th:nth-child(2) { width: 8%; }
.purchase-item-editor th:nth-child(3) { width: 10%; }
.purchase-item-editor th:nth-child(4) { width: 8%; }
.purchase-item-editor th:nth-child(5) { width: 9%; }
.purchase-item-editor th:nth-child(6) { width: 11%; }
.purchase-item-editor th:nth-child(7) { width: 9%; }
.purchase-item-editor th:nth-child(8) { width: 11%; }
.purchase-item-editor th:nth-child(9) { width: 28px; }
@media (min-width: 1200px) {
  /* v55：采购明细 9 列要 820px 才排得开，而 .modal 只有 680px，
     原来第 9 列（删除键）被挤到弹窗外，要横滑才看得到。
     给「新建采购入库」这颗弹窗单独加宽到 920px，表格就不用横滑了。 */
  .modal.modal-purchase-wide { width: min(920px, 100%); }
  .purchase-item-editor { min-width: 820px; }
  /* v130：客户对账批次明细 12 列（发货/扣重/结算重量、原单价/扣价/结算单价/结算金额），
     680px 装不下，跟采购 / 销售弹窗一样单独加宽；列多了横向滚动兜底 */
  .modal.modal-reconcile-wide { width: min(1080px, 100%); }
}

@media (max-width: 1199.98px) {
  /* 手机端备用栅格：品名整行 → 等级/件数/单件重量/尾件 → 单价(跨两格)/重量/金额；
     行列全部写死，避免自动排位错位。真正的手机排版以第二十七段为准（v67 重做）。
     列顺序跟 app.js 里 <td> 的顺序一致：件数（第 3 格）在单件重量（第 4 格）前面。 */
  .purchase-item-editor tbody tr { padding-right: 46px; }   /* 给右上角删除键留够空位，避免压住品名 */
  .purchase-item-editor tbody td:nth-child(1) { grid-column: 1 / -1; grid-row: 1; }
  .purchase-item-editor tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
  .purchase-item-editor tbody td:nth-child(3) { grid-column: 2; grid-row: 2; }   /* 件数 */
  .purchase-item-editor tbody td:nth-child(4) { grid-column: 3; grid-row: 2; }   /* 单件重量 */
  .purchase-item-editor tbody td:nth-child(5) { grid-column: 4; grid-row: 2; }
  .purchase-item-editor tbody td:nth-child(6) { grid-column: 1 / span 2; grid-row: 3; }
  .purchase-item-editor tbody td:nth-child(7) { grid-column: 3; grid-row: 3; }
  .purchase-item-editor tbody td:nth-child(8) { grid-column: 4; grid-row: 3; position: static; }
  .purchase-item-editor tbody td:nth-child(9) { position: absolute; top: 8px; right: 0; }
}

@media (max-width: 640px) {
  .warehouse-row { gap: 8px; padding: 10px 12px; }
  .warehouse-summary-hint { flex-basis: 100%; }

  /* v96：手机端采购仓行重新排版。
     原 wh-line1 一行硬塞 6 个元素（日期/供应商/品名/仓位/流转状态/箭头），
     供应商和品名被 ellipsis 截断，关键文字显示不全。
     改成多行：第 1 行供应商+状态+箭头，第 2 行品名（完整），第 3 行日期+仓位；
     第二行（算式·单价·金额）允许算式换行、完整显示。 */
  .warehouse-row .wh-line1 {
    flex-wrap: wrap;
    row-gap: 5px;
    column-gap: 8px;
  }
  .warehouse-row .wh-supplier {
    order: 1;
    flex: 1 1 auto;
    max-width: none;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    line-height: 1.3;
  }
  .warehouse-row .wh-pill-flow { order: 2; }
  .warehouse-row .wh-chevron { order: 3; }
  .warehouse-row .wh-products {
    order: 4;
    flex: 1 1 100%;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    line-height: 1.4;
  }
  .warehouse-row .wh-date { order: 5; }
  .warehouse-row .wh-location {
    order: 6;
    max-width: none;
    white-space: normal;
    overflow: visible;
  }
  .warehouse-row .wh-line2 {
    gap: 6px;
    flex-wrap: wrap;
    row-gap: 3px;
  }
  .warehouse-row .wh-expr {
    flex: 1 1 auto;
    min-width: 0;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    line-height: 1.35;
  }
}

/* ============================================================
   七·补 大屏触屏（721~1000px，含折叠屏展开 / 手机横屏）：
   基础样式只在 ≤720px 才把侧栏变底栏，这里补齐，避免出现"半桌面版"
   ============================================================ */
@media (min-width: 721px) and (max-width: 1180px) and (pointer: coarse), (min-width: 721px) and (max-width: 1180px) and (any-pointer: coarse), (min-width: 721px) and (max-width: 1180px) and (hover: none) {
  .sidebar {
    width: 100%;
    height: calc(68px + env(safe-area-inset-bottom));
    inset: auto 0 0;
    z-index: 4;
    padding: 6px 8px env(safe-area-inset-bottom);
    flex-direction: row;
    align-items: center;
    background: var(--surface);
    border-top: 1px solid var(--line);
    border-right: 0;
  }
  .brand-lockup, .sidebar-bottom { display: none; }
  .nav-list { width: 100%; display: flex; overflow-x: auto; gap: 3px; padding: 0; }
  .nav-item {
    flex: 0 0 auto;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    min-height: 54px;
    padding: 8px 7px;
    font-size: 12px;
    line-height: 1.15;
  }
  .nav-item span:last-child { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .mobile-nav-toggle {
    display: flex; flex: 0 0 66px; min-height: 54px;
    align-items: center; justify-content: center; flex-direction: column; gap: 2px;
    border: 1px solid var(--line) !important;
    background: var(--surface-soft) !important;
    color: var(--ink) !important;
    border-radius: var(--radius-control);
    padding: 6px 4px; font-size: 11px;
  }
  .main-content { width: 100%; margin-left: 0; padding: 14px 12px calc(92px + env(safe-area-inset-bottom)); }
  .content-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   八、防溢出：任何文字都不顶出方框
   ① 长文本容器允许换行（含长串数字/编码）
   ② 单行文本一律省略号
   ③ 弹性/栅格子项 min-width:0（否则 nowrap 会撑破父级）
   ④ 大号数字用 clamp 自适应，窄屏自动缩小
   ============================================================ */

/* ① 允许换行 */
.stat-card, .account-card, .contact-stat-card, .detail-stat, .stock-card,
.panel, .modal, .warehouse-card, .source-card, .settlement-card,
.workflow-task, .empty-state, .next-step, .calculation-note,
.ledger-account-card, .registration-row, .supplier-submission-row,
td, th, .table-primary, .table-secondary, .linked-record, .sale-item-card {
  overflow-wrap: anywhere;
}
.modal-head h3, .panel-title, .detail-section h4, .form-section-title strong { overflow-wrap: anywhere; }

/* ② 单行文本省略号 */
.stat-value, .stat-meta, .account-balance, .account-name, .account-kind,
.detail-stat strong, .contact-stat-card strong, .contact-stat-card small,
.stock-card h3, .stock-numbers strong, .stock-numbers small,
.sale-amount, .sale-title, .flow-value, .flow-party, .timeline-amount,
.wh-date, .wh-supplier, .wh-products, .wh-weight,
.status-pill, .sku-label, .source-summary b,
.supplier-batch-price, .supplier-batch-total, .supplier-batch-date strong,
.item-editor output, .flow-desc, .sale-sub, .timeline-copy strong {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.stat-meta, .flow-desc, .sale-sub, .contact-stat-card small, .stock-numbers small {
  white-space: normal;                 /* 说明性文字允许折行，不截断语义 */
  overflow-wrap: anywhere;
  overflow: visible;
}
.account-chip-text strong, .account-chip-text span {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.brand-name, .brand-subtitle, .nav-item span:last-child {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.primary-button, .secondary-button, .ghost-button, .icon-button, .mini-button {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis;
}

/* ③ 子项最小宽度归零（栅格/弹性不撑破） */
.stat-card, .account-card, .contact-stat-card, .detail-stat,
.panel-header > div, .welcome-row > div, .dashboard-company-head > div, .section-toolbar > div,
.topbar > div, .modal-head > div, .account-chip-text,
.sale-main, .stock-card-top, .settlement-detail-head > div,
.form-field, .contact-actions { min-width: 0; }
.account-strip { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.topbar { flex-wrap: wrap; gap: 10px 14px; }
.top-actions { flex-wrap: wrap; justify-content: flex-end; min-width: 0; }
.contact-actions { flex-wrap: wrap; gap: 6px; white-space: normal; }

/* ④ 大号数字自适应 + 保证是块级（否则省略号不生效） */
.stat-value, .account-balance, .contact-stat-card strong,
.detail-stat strong, .stock-card h3 {
  display: block; width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.stat-value { font-size: clamp(14px, 3.8vw, 24px); letter-spacing: -.02em; }
.account-balance { font-size: clamp(14px, 3.6vw, 19px); }
.contact-stat-card strong { font-size: clamp(15px, 3.8vw, 19px); }
.detail-stat strong { font-size: clamp(13px, 3.2vw, 15px); }
.stock-card h3 { font-size: clamp(14px, 3.6vw, 15px); }
.modal-head h3 { font-size: clamp(17px, 4.4vw, 20px); }
.stat-label { white-space: normal; overflow-wrap: anywhere; }

/* ⑤ 按钮：工具栏/卡片头里的按钮不再被截字，允许折行居中 */
.toolbar-actions button, .panel-header-actions button, .panel-header > button,
.company-profile-actions button, .section-toolbar button {
  white-space: normal;
  height: auto;
  min-height: 42px;
  line-height: 1.25;
  overflow: visible;
  text-overflow: clip;
  text-align: center;
  padding: 8px 10px;
}
.toolbar-actions { flex-wrap: wrap; }
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  .toolbar-actions { display: flex; flex-wrap: wrap; gap: 8px; width: 100%; }
  .toolbar-actions button { flex: 1 1 auto; min-width: 45%; }
  /* 只有一个按钮时占满一行 */
  .section-toolbar > button.primary-button { width: 100%; }
}

/* ⑥ 金额与列表行：金额不折行，标题省略号 */
.sale-amount, .flow-value, .timeline-amount { white-space: nowrap; }
.sale-amount small { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sale-row { grid-template-columns: minmax(0, 1fr) auto; }
.sale-main { min-width: 0; }
.sale-title, .sale-sub { display: block; width: 100%; }
.td-numeric, td.money-negative, td.money-positive { white-space: nowrap; }

/* ⑦ 其余小卡片：允许折行，不竖排 */
.workflow-task { white-space: normal; }
.account-flow { flex-wrap: wrap; }
.account-flow span { white-space: nowrap; }
.contact-stat-card small, .stock-numbers small { line-height: 1.4; }

/* 表格：表头/单元格允许换行，但金额列保持单行 */
th { white-space: normal; }
td { white-space: normal; }
.supplier-verify-table th, .supplier-verify-table td { white-space: normal; }
#customersView .contact-table td:nth-child(8),
#customersView .contact-table td:nth-child(9),
#suppliersView .contact-table td:nth-child(6),
#cashflowView table td:last-child,
td.align-right { white-space: nowrap; }
.contact-actions { flex-wrap: nowrap; gap: 8px; }
/* v128：客户列表整行可点 → 打开该客户的销售批次对账 */
tr.row-link { cursor: pointer; }
tr.row-link:hover { background: var(--accent-soft); }
tr.row-link:hover .table-primary { color: var(--accent-deep); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.customer-reconcile-hint { margin: 0 0 10px; font-size: var(--mini); color: var(--muted); }

/* 采购仓行：保证不横向溢出 */
.warehouse-row { min-width: 0; overflow: hidden; }
.warehouse-row .wh-weight, .warehouse-row .wh-date { flex: 0 0 auto; }

/* ============================================================
   八·补 手机端字号整体放大一档
   背景：之前为防溢出把字号压到 11~14px，手机上偏小、看着费劲。
   这里统一抬一档；防溢出的手段（省略号 / 金额不换行 / 允许折行）全部保留。
   必须放在防溢出规则之后，否则会被 clamp() 覆盖回去。
   ============================================================ */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  body { font-size: 16px; }
  .topbar h1 { font-size: 22px; }

  /* 首页统计卡 */
  .stat-label { font-size: 12.5px; }
  .stat-value { font-size: clamp(22px, 5.6vw, 26px); }
  .stat-meta { font-size: 12px; }
  .contact-stat-card strong { font-size: clamp(17px, 4.6vw, 20px); }
  /* 7 张卡：前 4 张两列大卡；后 3 张（在库重量 / 库存金额 / 毛利率）并成一行三张，
     否则最后一张会孤零零占半行，页面整体节奏被拉散 */
  .stat-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .stat-grid .stat-card { grid-column: span 3; }
  .stat-grid .stat-card:nth-child(n+5) {
    grid-column: span 2; padding: 12px; min-height: 0;
  }
  .stat-grid .stat-card:nth-child(n+5) .stat-value { font-size: 18px; margin: 8px 0 5px; }
  .stat-grid .stat-card:nth-child(n+5) .stat-meta { font-size: var(--mini); }

  /* 列表行（最近销售 / 最近流水） */
  .sale-title, .flow-party { font-size: 14.5px; }
  .sale-amount, .flow-value { font-size: 15.5px; }
  .sale-sub, .flow-desc, .table-secondary { font-size: 12.5px; }
  .sale-amount small { font-size: 12px; }

  /* 采购仓行 */
  .warehouse-row .wh-supplier, .warehouse-row .wh-weight { font-size: 15.5px; }
  .warehouse-row .wh-products { font-size: 14.5px; }
  .warehouse-row .wh-price { font-size: 14px; }
  .warehouse-row .wh-date { font-size: 13px; }
  .warehouse-summary { font-size: 12.5px; }
  .warehouse-row .status-pill { font-size: var(--mini); padding: 3px 7px; }

  /* 状态标签 */
  .status-pill { font-size: var(--mini); padding: 4px 8px; }

  /* 表格 */
  th { font-size: 12px; }
  td { font-size: 14px; padding: 12px 12px; }

  /* 卡片 */
  .panel-header h2, .panel-header h3 { font-size: 15px; }
  .stock-card h3 { font-size: clamp(16px, 4.4vw, 18px); }
  .stock-card .packing-card-meta, .stock-card p, .stock-numbers small, .stock-numbers em { font-size: 12.5px; }
  .detail-stat strong { font-size: clamp(15px, 4vw, 17px); }

  /* 底栏与按钮 */
  /* 底栏：要压过 .sidebar:not(.nav-expanded) > .nav-list .nav-item 这条更高优先级的规则 */
  .sidebar .nav-item,
  .sidebar:not(.nav-expanded) > .nav-list .nav-item,
  .sidebar.nav-expanded > .nav-list .nav-item { font-size: 13px; }
  .nav-icon { font-size: 16px; }
  .primary-button, .secondary-button, .ghost-button, .mini-button { font-size: 14px; }
  .toolbar-actions button, .panel-header-actions button,
  .company-profile-actions button, .section-toolbar button { min-height: 46px; }

  /* 表单：16px 可避免 iOS 聚焦时自动放大；密集明细表单独降一档 */
  input, select, textarea { font-size: 16px; }
  .item-editor input, .item-editor select { font-size: 15px; }
  .field-hint, .form-foot .hint, .hint { font-size: 12.5px; }
}

/* ============================================================
   八·补三 触控目标一律 ≥44×44（人机指南），不改文字视觉大小
   —— 放在最后，压过上面那些 34/36/38/42px 的规则
   ============================================================ */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  button, .text-button, .mini-button, .secondary-button, .ghost-button,
  .primary-button, .icon-button, .invoice-contract-button,
  .unit-preference-button, .unit-toggle-button, .upload-button,
  .supplier-invoice-upload-button, .remove-row, .close-button { min-height: 44px; }

  /* 行内文字按钮：视觉仍是文字，触控区撑到 44×44 居中 */
  .text-button {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 44px; padding: 0 6px; border-radius: var(--radius-control);
  }
  .contact-actions { gap: 4px; }
  .contact-actions .text-button { min-height: 44px; padding: 0 10px; }

  /* 卡片头 / 工具栏里的按钮：选择器优先级更高，必须同权重再写一遍才压得住 */
  .toolbar-actions button, .panel-header-actions button, .panel-header > button,
  .company-profile-actions button, .section-toolbar button { min-height: 44px; }

  /* 头像：正方形 44×44 */
  .avatar { width: 44px; height: 44px; min-width: 44px; }
  /* 图标按钮：#exportBtn 里是「⇩ 导出」，强制 44px 方形会把「导出」两个字裁掉。
     高度锁 44、宽度按内容走，并放开上面那条 text-overflow: ellipsis 的裁剪。 */
  .icon-button { width: auto; min-width: 44px; height: 44px; padding: 0 12px; overflow: visible; text-overflow: clip; }

  /* 表单控件 */
  input, select, textarea,
  .form-field input, .form-field select, .form-field textarea,
  .item-editor input, .item-editor select { min-height: 44px; }

  /* 行首勾选框：本体 20px，靠外层 label 撑出 44px 热区 */
  .warehouse-row .warehouse-batch-check-wrap { min-width: 44px; min-height: 44px; justify-content: center; margin: -10px 0; }
  .warehouse-row .warehouse-batch-check { width: 20px; height: 20px; }
}

/* ------------------------------------------------------------
   八·补三·兜底 同一套触控规则也绑到 JS 兜底类 html.force-mobile 上。
   场景：安卓浏览器按「桌面版网站」渲染 → 视口按 980px 算 → 上面那条媒体查询
   （≤720px 或 ≤1180px 且粗指针）全不命中，但布局已经切到手机版，
   此时触控目标若不撑到 44px，用户就要用手指去点 34~42px 的小按钮。
   ------------------------------------------------------------ */
html.force-mobile button, html.force-mobile .text-button, html.force-mobile .mini-button,
html.force-mobile .secondary-button, html.force-mobile .ghost-button, html.force-mobile .primary-button,
html.force-mobile .icon-button, html.force-mobile .invoice-contract-button,
html.force-mobile .unit-preference-button, html.force-mobile .unit-toggle-button,
html.force-mobile .upload-button, html.force-mobile .supplier-invoice-upload-button,
html.force-mobile .remove-row, html.force-mobile .close-button { min-height: 44px; }

html.force-mobile .text-button {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; padding: 0 6px; border-radius: var(--radius-control);
}
html.force-mobile .contact-actions { gap: 4px; }
html.force-mobile .contact-actions .text-button { min-height: 44px; padding: 0 10px; }

html.force-mobile .toolbar-actions button, html.force-mobile .panel-header-actions button,
html.force-mobile .panel-header > button, html.force-mobile .company-profile-actions button,
html.force-mobile .section-toolbar button { min-height: 44px; }

html.force-mobile .avatar { width: 44px; height: 44px; min-width: 44px; }
html.force-mobile .icon-button { width: auto; min-width: 44px; height: 44px; padding: 0 12px; overflow: visible; text-overflow: clip; }

html.force-mobile input, html.force-mobile select, html.force-mobile textarea,
html.force-mobile .form-field input, html.force-mobile .form-field select, html.force-mobile .form-field textarea,
html.force-mobile .item-editor input, html.force-mobile .item-editor select { min-height: 44px; }

html.force-mobile .warehouse-row .warehouse-batch-check-wrap { min-width: 44px; min-height: 44px; justify-content: center; margin: -10px 0; }
html.force-mobile .warehouse-row .warehouse-batch-check { width: 20px; height: 20px; }

/* v96：采购仓行手机排版（多行、文字不截断）在 JS 兜底「电脑手动切手机版」下同样生效 */
html.force-mobile .warehouse-row .wh-line1 { flex-wrap: wrap; row-gap: 5px; column-gap: 8px; }
html.force-mobile .warehouse-row .wh-supplier {
  order: 1; flex: 1 1 auto; max-width: none;
  white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.3;
}
html.force-mobile .warehouse-row .wh-pill-flow { order: 2; }
html.force-mobile .warehouse-row .wh-chevron { order: 3; }
html.force-mobile .warehouse-row .wh-products {
  order: 4; flex: 1 1 100%;
  white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.4;
}
html.force-mobile .warehouse-row .wh-date { order: 5; }
html.force-mobile .warehouse-row .wh-location {
  order: 6; max-width: none; white-space: normal; overflow: visible;
}
html.force-mobile .warehouse-row .wh-line2 { gap: 6px; flex-wrap: wrap; row-gap: 3px; }
html.force-mobile .warehouse-row .wh-expr {
  flex: 1 1 auto; min-width: 0;
  white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.35;
}

/* ============================================================
   v103：销售发票登记行 · 补开票日期/税率两列后重新排布
   v3.13.2：上传发票按钮紧跟「开票方式」后面
   桌面：类型/上传发票/删除 → 开票主体/金额/号码 → 日期/税率 → 附件
   手机：类型/上传发票/删除 → 开票主体(全宽) → 金额/日期/税率 → 号码 → 附件
   ============================================================ */
.invoice-row .type { grid-column: 1; grid-row: 1; }
.invoice-row .upload-button { grid-column: 2 / 4; grid-row: 1; }
.invoice-row .remove-row { grid-column: 4; grid-row: 1; }
.invoice-row .issuer { grid-column: 1; grid-row: 2; }
.invoice-row .amount { grid-column: 2; grid-row: 2; }
.invoice-row .number { grid-column: 3; grid-row: 2; }
.invoice-row .date { grid-column: 1; grid-row: 3; }
.invoice-row .tax-rate { grid-column: 2; grid-row: 3; }
.invoice-row .invoice-attachment { grid-column: 1 / 4; grid-row: 4; }
/* v3.11.1：登记发票重排 —— 行编号徽标（绝对定位不进 grid，不动上面 grid-row）+ 「添加发票」按钮挪到发票行下方 */
.invoice-row { position: relative; }
.invoice-row .inv-index { position: absolute; top: -9px; left: -8px; z-index: 1; min-width: 22px; height: 20px; padding: 0 7px; border-radius: 10px; background: #2f7d5d; color: #fff; font-size: 10.5px; font-weight: 700; line-height: 20px; text-align: center; box-shadow: 0 1px 4px rgba(15, 60, 40, .25); pointer-events: none; }
.invoice-add-bar { display: flex; justify-content: center; margin: 2px 0 10px; }
.invoice-add-bar .mini-button { min-width: 220px; border: 1px dashed #2f7d5d; color: #2f7d5d; background: #f4faf6; }

@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  .invoice-row .upload-button { grid-column: 2 / 4; grid-row: 1; }
  .invoice-row .issuer { grid-column: 1 / 4; grid-row: 2; }
  .invoice-row .amount { grid-column: 1; grid-row: 3; }
  .invoice-row .date { grid-column: 2; grid-row: 3; }
  .invoice-row .tax-rate { grid-column: 3; grid-row: 3; }
  .invoice-row .number { grid-column: 1 / 4; grid-row: 4; }
  .invoice-row .invoice-attachment { grid-column: 1 / 4; grid-row: 5; }
}
html.force-mobile .invoice-row .upload-button { grid-column: 2 / 4; grid-row: 1; }
html.force-mobile .invoice-row .issuer { grid-column: 1 / 4; grid-row: 2; }
html.force-mobile .invoice-row .amount { grid-column: 1; grid-row: 3; }
html.force-mobile .invoice-row .date { grid-column: 2; grid-row: 3; }
html.force-mobile .invoice-row .tax-rate { grid-column: 3; grid-row: 3; }
html.force-mobile .invoice-row .number { grid-column: 1 / 4; grid-row: 4; }
html.force-mobile .invoice-row .invoice-attachment { grid-column: 1 / 4; grid-row: 5; }

/* ============================================================
   八·补四 补回被丢弃的 styles-polish.css 里的孤儿样式
   （该文件已不再加载，但 .toast / .mobile-account-chip / .auth-* 只在它里面定义过）
   ============================================================ */

/* 提示条：浮在底部居中，默认无样式会导致提示以纯文字挤在页面末尾 */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(84px + env(safe-area-inset-bottom));
  transform: translate(-50%, 12px);
  z-index: 60;
  max-width: min(92vw, 420px);
  padding: 11px 16px;
  border-radius: var(--radius-card);
  background: var(--ink);
  color: var(--surface);
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.5;
  text-align: center;
  box-shadow: 0 10px 30px rgba(20, 26, 32, .22);
  opacity: 0;
  transition: opacity .22s ease, transform .22s cubic-bezier(.22,.61,.36,1);
  pointer-events: none;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast.error { background: var(--red-ink); }

/* 手机底栏里的账户入口：桌面隐藏，手机显示成圆形头像 */
.mobile-account-chip { display: none; }

/* 登录页（整屏拦截）头部 */
.auth-gate-head { display: grid; justify-items: center; gap: 8px; text-align: center; padding: 8px 0 4px; }
.auth-gate-head .brand-mark { width: 54px; height: 54px; }
.auth-gate-head h3 { margin: 4px 0 0; font-size: 18px; }
.auth-gate-head p { margin: 0; font-size: 12.5px; color: var(--muted); }

/* 记住登录状态 + 忘记密码 一行 */
.auth-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin: 4px 0 10px; }
.auth-remember { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--muted); }
.auth-remember input { width: 18px; height: 18px; accent-color: var(--accent-bright); }

/* 账户菜单里的信息行 */
.account-menu-rows { display: grid; gap: 1px; margin: 4px 0 14px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius-card); overflow: hidden; }
.account-menu-rows > div { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 11px 13px; background: var(--surface); }
.account-menu-rows span { font-size: 12.5px; color: var(--muted); flex: 0 0 auto; }
.account-menu-rows strong { font-size: 13px; text-align: right; overflow-wrap: anywhere; }
.account-menu-head { display: flex; align-items: center; gap: 11px; padding: 12px 13px; margin: 4px 0 0; background: var(--surface-soft); border: 1px solid var(--line); border-radius: var(--radius-card); }
.account-menu-head strong { display: block; font-size: 14px; }
.account-menu-head span { font-size: 12px; color: var(--muted); }

/* 页头账户按钮：直接显示登录人和身份 */
.topbar-account { display: inline-flex; align-items: center; gap: 9px; padding: 6px 12px 6px 6px; }
.topbar-account .account-chip-text { display: grid; text-align: left; line-height: 1.25; }
.topbar-account .account-chip-text strong { font-size: 13px; font-weight: 650; }
.topbar-account .account-chip-text span { font-size: 11.5px; color: var(--muted); }

/* 登录页版本号 */
.auth-version { margin: 10px 0 0; text-align: center; font-size: 11.5px; color: var(--muted); letter-spacing: .02em; }
.sidebar-version { font-size: 10.5px; color: var(--muted); text-align: center; padding: 2px 0 0; letter-spacing: .02em; }

/* ============================================================
   十、兜底：强制手机版
   部分手机浏览器按「桌面版网站」渲染，视口宽度按 980px 算，
   媒体查询判断不出是手机 —— 由 JS 打上 .force-mobile 把骨架拉回来
   ============================================================ */
html.force-mobile .sidebar {
  position: fixed;
  inset: auto 0 0 0;
  width: 100%;
  height: calc(68px + env(safe-area-inset-bottom));
  z-index: 4;
  flex-direction: row;
  align-items: center;
  /* v45：底栏用与页面形成对比的深色，跟电脑版侧栏同色系 */
  background: var(--nav-bar-bg); color: rgba(255,255,255,.92);
  border-top: 0; border-right: 0;
  box-shadow: 0 -1px 0 rgba(255,255,255,.10);
  padding: 6px 8px env(safe-area-inset-bottom);
}
html.force-mobile .main-content { margin-left: 0; width: 100%; max-width: none; padding: 14px 12px calc(92px + env(safe-area-inset-bottom)); }
html.force-mobile .brand-lockup,
html.force-mobile .sidebar-bottom,
html.force-mobile .storage-card,
html.force-mobile .mobile-nav-toggle { display: none; }
html.force-mobile .sidebar .nav-list {
  width: 100%;
  display: flex !important;
  grid-template-columns: none !important;
  gap: 3px;
  overflow-x: auto;
  padding: 0;
}
html.force-mobile .nav-item {
  flex: 0 0 auto;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-height: 54px;
  padding: 8px 7px;
  font-size: 12px;
  line-height: 1.15;
  color: rgba(255,255,255,.64);
}
html.force-mobile .nav-item span:last-child { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
html.force-mobile .nav-item.active { box-shadow: none; background: rgba(255,255,255,.16); color: #fff; font-weight: 700; }
html.force-mobile .mobile-account-chip {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  min-width: 54px;
  min-height: 54px;
  background: rgba(255,255,255,.10);
  border: 1px solid rgba(255,255,255,.14);
  border-radius: var(--radius-control);
  color: #fff;
}
html.force-mobile .content-grid { grid-template-columns: 1fr; }
html.force-mobile .topbar { flex-wrap: wrap; gap: 10px 14px; }
html.force-mobile .topbar h1 { font-size: 22px; }
html.force-mobile .topbar-account { display: none; }

/* ============================================================
   十一、交互动效（统一节奏：入场 220ms、按压 120ms）
   只做位移/淡化/缩放，不做发光渐变；并尊重系统「减弱动态效果」
   ============================================================ */
@keyframes sqRise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes sqFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes sqPopIn { from { opacity: 0; transform: scale(.975) translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes sqSheet { from { opacity: 0; transform: translateY(14px) scale(.99); } to { opacity: 1; transform: none; } }

/* 页面切换：顶层区块依次浮现（比每张卡片都动要稳，不会在搜索时闪） */
.view.active-view > * { animation: sqRise .24s cubic-bezier(.22,.61,.36,1) both; }
.view.active-view > *:nth-child(2) { animation-delay: .03s; }
.view.active-view > *:nth-child(3) { animation-delay: .06s; }
.view.active-view > *:nth-child(4) { animation-delay: .09s; }
.view.active-view > *:nth-child(n+5) { animation-delay: .12s; }

/* 弹窗与遮罩 */
.modal-backdrop { animation: sqFadeIn .18s ease both; }
.modal { animation: sqPopIn .26s cubic-bezier(.22,.61,.36,1) both; }
.modal-foot, .modal-actions { animation: sqRise .28s cubic-bezier(.22,.61,.36,1) both; animation-delay: .04s; }

/* 底栏展开的导航面板 */
.sidebar.nav-expanded > .nav-list { animation: sqSheet .22s cubic-bezier(.22,.61,.36,1) both; }

/* 按压反馈：可点元素统一缩一下 */
button, .nav-item, .account-chip, .source-card, .source-choice,
.warehouse-row, .warehouse-card, .sale-row, .stock-card, .contact-stat-card, .flow-row {
  transition: transform .12s ease, background-color .18s ease, border-color .18s ease,
              color .18s ease, box-shadow .18s ease;
}
button:active:not(:disabled),
.nav-item:active,
.account-chip:active,
.source-card:active,
.source-choice:active { transform: scale(.97); }
.warehouse-row:active,
.warehouse-card:active,
.sale-row:active,
.stock-card:active { transform: scale(.985); }

/* 表单聚焦、状态标签换色也要平顺 */
input, select, textarea { transition: border-color .18s ease, box-shadow .18s ease, background-color .18s ease; }
.status-pill, .coop-pill, .grade-tag { transition: background-color .2s ease, color .2s ease, border-color .2s ease; }
.storage-dot { transition: box-shadow .2s ease, background-color .2s ease; }
.flow-bullet { transition: background-color .2s ease, color .2s ease; }

/* 尊重系统设置 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ------------------------------------------------------------
   十二、移动端点击与选中反馈（干掉安卓默认的那一下蓝）
   安卓 Chrome 点击任何元素都会先闪一个**淡蓝色矩形**高亮（-webkit-tap-highlight-color
   默认就是蓝调），和翡翠绿主题打架；长按选中文字的默认选区也是蓝色。
   全部关掉 / 换色 —— 按压反馈本来就够：按钮有 scale(.97)、列表行有底色变化。
   ------------------------------------------------------------ */
html { -webkit-tap-highlight-color: transparent; }

/* 按钮类：禁掉长按选中，并去掉双击缩放造成的 300ms 点击延迟 */
button, a, .nav-item, .text-button, .mini-button, .secondary-button, .ghost-button,
.primary-button, .icon-button, .account-chip, .remove-row, .close-button,
.unit-preference-button, .unit-toggle-button, .upload-button,
.invoice-contract-button, .supplier-invoice-upload-button {
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
  touch-action: manipulation;
}

/* 可点列表行 / 卡片：同样去掉蓝闪，但**保留文字可选中**（还能复制供应商名、金额） */
.warehouse-row, .warehouse-card, .sale-row, .stock-card, .contact-stat-card,
.flow-row, .source-card, .source-choice, .packing-card, .settlement-card {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* 文字选区换成主题浅绿（浏览器默认是蓝的） */
::selection { background: var(--accent-tile); color: var(--accent-deep); }
::-moz-selection { background: var(--accent-tile); color: var(--accent-deep); }

/* ============================================================
   九、深色模式（中性深灰，非绿调）
   ============================================================ */
/* v78：老板决定不保留深色模式，整块停用（内容保留，恢复时把 and (min-width: 999999px) 删掉即可） */
@media (prefers-color-scheme: dark) and (min-width: 999999px) {
  :root {
    --canvas: #16181a;
    --surface: #1e2124;
    --surface-soft: #26292d;
    --ink: #e8eaec;
    --muted: #a2a9ad;
    --line: rgba(255,255,255,.12);
    --line-soft: rgba(255,255,255,.07);
    --accent: #a9c8b7;          /* 深色下的主色：松墨提亮成「茶青」H147 S22% L72%，提亮但不刺眼 · 压 --surface 8.96:1 ✅ · 压 --canvas 9.86:1 ✅ */
    --accent-deep: #c8ded1;      /* 更浅一档 H145 S25% L83%：按下态 / 绿瓷砖底上的文字 · 压 tile 实色 7.61:1 ✅ */
    --accent-bright: #34d07e;   /* 深色下的点缀：翡翠绿提亮版，同样只做小面积 */
    --accent-on: #04241a;
    --nav-bar-bg: #0a1410;       /* 深色下底栏要压得住页面（--canvas #16181a），不能用被提亮的 --accent · 极深墨绿 H156 S33% L6%，亮度 0.0060 < canvas 0.0090，白字 18.74:1 ✅ */
    --nav-icon-bright: #34d07e;   /* 浅色下抽屉图标专用：比 --accent-bright(#00a85f) 亮一档，压深底才有 3.0+ 对比 */
    --accent-soft: rgba(169,200,183,.14);  /* 跟随新 --accent 的 RGB，透明度维持 .14 */
    --accent-tile: rgba(52,208,126,.2);
    --gold: #d3b483;
    --gold-ink: #d9bd8c;
    --gold-soft: rgba(211,180,131,.14);
    --red: #e08a83;
    --red-ink: #ea9a93;
    --red-soft: rgba(224,138,131,.13);
  }
  .sidebar { background: var(--surface); border-right-color: var(--line); }
  .nav-item:hover, .sidebar.nav-expanded > .nav-list .nav-item { background: var(--surface-soft); }
  .primary-button { background: var(--accent); color: #16181a; }
  .primary-button:hover { background: var(--accent-deep); }
  /* 深色下亮绿小色块换回半透明绿底 + 亮绿字（深字会看不见） */
  .status-pill.completed, .invoice-recognition-status.ready, .sale-icon, .flow-bullet.in,
  .warehouse-row .wh-pill-stock.completed, .warehouse-row .wh-pill-settle.completed,
  .workflow-track li.done span { background: var(--accent-soft); color: var(--accent); }
  /* v77：结算差异「多收」行 + 「有扣减」小字标签 —— 这两个类漏在上面那条深色覆盖之外，
     深色下 --accent-on(#04241a) 压 --accent-tile（叠 surface 合成 #224436）只有 1.53:1，深字看不见。
     只改文字色（换 --accent-deep #c8ded1 → 7.60:1），背景 --accent-tile 不动：浅色下 13.95:1 本来是对的。
     注意必须带 html 前缀：原规则在 2211 / 2233 行，特异性相同但位置更靠后，
     不加前缀的话深色下会被它压回去（v69 就是这么漏掉的）。 */
  html .settlement-diff-row.is-more span, html .settlement-diff-row.is-more strong,
  html .settlement-stat-note.is-more { color: var(--accent-deep); }
  /* v77：勾选框选中态文字 —— 容器背景是 --surface 不是 --accent-tile，
     深色下 --accent-on(#04241a) 压 --surface(#1e2124) 只有 1.02:1，勾中后文字看不见。
     同样要带 html 前缀：原规则在 2103 行，位置比深色块更靠后。 */
  html .closed-filter-toggle input[type="checkbox"]:checked + span { color: var(--accent-deep); }
  .accent-card { background: var(--surface); border-color: var(--line); border-left: 3px solid var(--accent-bright); color: var(--ink); }
  .brand-mark { background: var(--accent-bright); color: #16181a; }
  /* v43：深色下头像同样按登录态分色，不再一律跟着 brand-mark 变绿，
     否则「未登录」和「已登录」在深色里分不出来。内环用 var(--surface)，深色下不会是白环。 */
  .account-chip-avatar { background: var(--surface-soft); color: var(--muted); box-shadow: 0 0 0 1.5px var(--line); }
  .is-signed-in .account-chip-avatar {
    background: var(--accent-bright); color: var(--accent-on);
    box-shadow: 0 0 0 2px var(--surface), 0 0 0 5px var(--accent-tile);
  }
  .modal { background: var(--surface); }
  .modal-backdrop { background: rgba(0,0,0,.55); }
  input, select, textarea { background: var(--surface-soft); color: var(--ink); border-color: var(--line); }
  input::placeholder, textarea::placeholder { color: var(--muted); }
  .contract-paper { background: #fff; color: #222; }
}

/* ============================================================
   十三、手机版真重做 v27
   ------------------------------------------------------------
   v26 之前手机版只是「电脑版缩窄」：字号调小、间距收紧、侧栏挪到底部，
   内容结构一模一样（7 张小指标卡 + 10 列表格横滑）。用户反馈「手机版和
   电脑版区别不大」，这一段改成真正的手机版：

   ① 底栏：4 个主页签一点就切（此前要点两下：先弹菜单再选），
      次要页（包装 / 客户 / 供应商 / 账号）收进「更多」抽屉
   ② 首页：销售额做成跨两列的大数，待收款 + 待结供应商款两张中等卡，
      利润 / 库存 / 毛利率收进「更多指标」折叠区
   ③ 四个表格（销售 / 客户 / 供应商 / 资金流水）在手机上变成竖排卡片，
      不再横滑。靠 .card-on-mobile 标记，不动 app.js 的渲染逻辑
   ============================================================ */

/* 电脑端：折叠区摊平。
   v36 起不再摊进外层网格（display:contents），改成「一行一条」的列表：
   左边指标名 + 小字说明，右边数值对齐。四张小卡排一排跟上面三张大卡分不清层次。 */
.stat-more {
  display: grid; grid-column: 1 / -1;
  grid-template-columns: 1fr; gap: 8px;
}
.stat-more > summary { display: none; }
.stat-more > .stat-card {
  display: grid; grid-template-columns: 1fr auto;
  align-items: center; gap: 2px 16px;
  min-height: 56px; padding: 10px 18px;
  text-align: left;
}
.stat-more > .stat-card > .stat-label { grid-area: 1 / 1; margin: 0; font-size: 13px; }
.stat-more > .stat-card > .stat-meta  { grid-area: 2 / 1; margin: 0; font-size: 11px; }
.stat-more > .stat-card > .stat-value { grid-area: 1 / 2 / span 2 / 3; margin: 0; font-size: 20px; text-align: right; }

@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {

  /* ---------- ① 底栏：主页签 + 更多 ---------- */
  /* 收起态只显示 4 个主页签；次要页 hide，点「更多」才在抽屉里出现 */
  .sidebar:not(.nav-expanded) > .nav-list .nav-item[data-nav-tier="secondary"] { display: none !important; }
  .sidebar:not(.nav-expanded) > .nav-list .nav-item[data-nav-tier="primary"] { display: flex !important; flex: 1 1 0; min-width: 0; justify-content: center; }
  .sidebar:not(.nav-expanded) > .nav-list { gap: 2px; }
  /* 「更多」按钮排到最后（DOM 里它在 nav-list 前面） */
  .mobile-nav-toggle { order: 9; flex: 0 0 62px; min-width: 62px; }

  /* ---------- ② 首页 ---------- */
  /* 欢迎语和公司资料条在手机上占半屏，收掉；流程条是说明文字，也收掉，把空间让给关键数字 */
  #dashboardView .welcome-row, #dashboardView .dashboard-company-head { display: none; }
  #dashboardView .company-profile-strip { display: none; }
  #dashboardView #workflowGuide { display: none; }
  #dashboardView .stat-grid { gap: 10px; margin-bottom: 12px; }

  /* v32：手机版首页顶部简化标题栏（经营概览 + + + 更多） */
  body[data-current-view="dashboard"] .topbar { display: none; }
  .mobile-dashboard-header { display: none; }
  body[data-current-view="dashboard"] .mobile-dashboard-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 16px;
    gap: 8px; /* v71：右上两个按钮补了文字，间距收紧给标题让位，别让「经营概览」折行 */
  }
  .mobile-dashboard-header h2 {
    font-size: 22px;
    font-weight: 700;
    margin: 0;
    letter-spacing: -.01em;
  }
  .mobile-dashboard-actions {
    display: flex;
    align-items: center;
    gap: 6px; /* v71：按钮带文字后收紧 */
  }
  .mobile-quick-add {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 0;
    background: var(--accent-bright);
    color: #fff;
    font-size: 26px;
    line-height: 1;
    display: grid;
    place-items: center;
    padding: 0;
    box-shadow: none;
  }
  .mobile-quick-add:active { transform: scale(.95); background: var(--accent-bright); filter: brightness(1.05); }
  .mobile-more-top {
    height: 44px;
    padding: 0 14px;
    border-radius: 22px;
    border: 1px solid var(--line);
    background: var(--surface);
    color: var(--muted);
    font-size: 14px;
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 4px;
  }
  .mobile-more-top span { font-size: 15px; line-height: 1; }

  /* 待收款 / 待结供应商款：中等卡 */
  #dashboardView .stat-grid > .stat-card { min-height: 90px; padding: 13px 14px; border-radius: 11px; }
  #dashboardView .stat-grid > .stat-card .stat-value { font-size: clamp(15px, 4.6vw, 19px); margin: 9px 0 5px; }

  /* 销售总额：跨两列的大数，石墨底白字，一眼看到 */
  #dashboardView .stat-grid > .accent-card {
    grid-column: 1 / -1; min-height: 0; padding: 16px 18px;
    background: var(--accent); color: #fff; border-color: var(--accent); border-left: 0;
  }
  #dashboardView .stat-grid > .accent-card .stat-label { font-size: 12px; color: rgba(255,255,255,.72); }
  #dashboardView .stat-grid > .accent-card .stat-meta { color: rgba(255,255,255,.72); }
  #dashboardView .stat-grid > .accent-card .stat-value { font-size: clamp(22px, 7vw, 30px); margin: 8px 0 5px; color: #fff; }
  /* v78：hero 卡底色是 --accent，而 .trend.up 也是 --accent → 绿箭头压绿底 1.00:1 完全看不见。
     这里跟着卡片里的其它文字一起用浅色。 */
  #dashboardView .stat-grid > .accent-card .trend.up { color: rgba(255,255,255,.92); }

  /* 利润 / 库存 / 毛利率：收进折叠区，展开后一行一条（v36）
     —— 之前是 2 列小卡，手机上每张卡都要「标签一行 + 数字一行 + 说明一行」，
        四张卡堆成一坨还看不齐。改成一行一条：左边指标名，右边数值。 */
  #dashboardView .stat-more {
    display: grid; grid-column: 1 / -1;
    grid-template-columns: 1fr; gap: 8px;
  }
  /* v37：不再折叠 —— 一行一条之后只占四行，还要多点一次才看得到，不划算。
     折叠条整个撤掉，指标直接铺在下面。（用户手动开合过仍然尊重，见 app.js） */
  #dashboardView .stat-more > summary { display: none; }
  #dashboardView .stat-more > summary::-webkit-details-marker { display: none; }
  #dashboardView .stat-more > .stat-card {
    display: grid; grid-template-columns: 1fr auto;
    align-items: center; gap: 2px 12px;
    min-height: 58px; padding: 11px 16px; border-radius: 12px;
  }
  #dashboardView .stat-more > .stat-card > .stat-label { grid-area: 1 / 1; margin: 0; font-size: 13.5px; }
  #dashboardView .stat-more > .stat-card > .stat-meta  { grid-area: 2 / 1; margin: 0; font-size: 11px; }
  #dashboardView .stat-more > .stat-card > .stat-value { grid-area: 1 / 2 / span 2 / 3; margin: 0; font-size: 19px; text-align: right; }

  /* 待办：2x2 卡片，标签在上数字在下（数据来自 workflow.js 的待签收/待开票/待付款/待结款计数） */
  #dashboardView .workflow-tasks { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-bottom: 16px; }
  #dashboardView .workflow-tasks::before {
    content: '今天要办的事'; grid-column: 1 / -1;
    font-size: 13px; font-weight: 700; color: var(--ink); margin-bottom: 4px;
  }
  #dashboardView .workflow-task {
    display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
    min-height: 76px; padding: 14px 16px; gap: 4px;
    background: var(--surface-soft); border: 1px solid var(--line); border-radius: 12px;
    font-size: 12px; color: var(--muted);
  }
  #dashboardView .workflow-task span { font-size: 12px; color: var(--muted); }
  #dashboardView .workflow-task strong { font-size: 22px; color: var(--ink); font-weight: 700; }

  /* ---------- ③ 列表：把已有的「行卡片」做成一眼看得出来的卡片 ----------
     注意：四个列表的手机排版早就不是表格了（上面第 471 行起已经改成行卡片：
     按重要性重排、次要列在手机上隐藏）。但一直是「白底 + 一条发丝分隔线」，
     所以看着仍然像张表。这里只补外观，不动里面的排布规则，避免打架。 */
  #customersView tbody tr, #suppliersView tbody tr, #salesView tbody tr, #cashflowView tbody tr {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 12px 14px;
    margin: 0 0 10px;
    gap: 5px 10px;
  }
  #customersView tbody tr:last-child, #suppliersView tbody tr:last-child,
  #salesView tbody tr:last-child, #cashflowView tbody tr:last-child { border-bottom: 1px solid var(--line); }
  #customersView tbody tr:active, #suppliersView tbody tr:active,
  #salesView tbody tr:active, #cashflowView tbody tr:active { background: var(--surface-soft); }

  /* 合计行也做成一条卡片，跟数据行区分开 */
  #customersView tfoot tr, #suppliersView tfoot tr, #salesView tfoot tr, #cashflowView tfoot tr {
    border: 1px dashed var(--line);
    border-radius: 12px;
    margin-bottom: 4px;
  }
  /* 操作按钮在卡片里做成实心小按钮，触控目标 44px */
  .contact-actions .text-button { min-height: 44px; padding: 0 14px; border: 1px solid var(--line); border-radius: 9px; }
}

/* 深色模式：石墨 hero 卡换成深色面 + 绿边，别糊成一片 */
/* v78：老板决定不保留深色模式，整块停用（内容保留，恢复时把 and (min-width: 999999px) 删掉即可） */
@media (prefers-color-scheme: dark) and (min-width: 999999px) {
  #dashboardView .stat-grid > .accent-card { background: var(--accent); color: #16181a; border-color: var(--accent); }
  #dashboardView .stat-grid > .accent-card .stat-label,
  #dashboardView .stat-grid > .accent-card .stat-meta { color: rgba(22,24,26,.72); }
  #dashboardView .stat-grid > .accent-card .stat-value { color: #16181a; }
}

/* ============================================================
   十四、宽屏手机版 v29（721px ~ 1199px，以及任何更宽的触屏设备）
   ------------------------------------------------------------
   问题：断点改成 1200 之后（v79），1366 / 1440 已回到电脑版；但 721~1199 的平板/小笔记本仍走手机版，而手机版 CSS
   是按 390~440 的手机写的——放到 1400 宽的屏幕上，字和卡片全显得很小。
   这一档在手机版内部再分一层：屏幕越宽，字号 / 间距 / 列数跟着放大。
   小字统一用 --mini（手机 12px，这里 13px），不用逐个改 11px。
   ============================================================ */
@media (min-width: 721px) and (max-width: 1199.98px), (min-width: 721px) and (pointer: coarse), (min-width: 721px) and (hover: none) {
  :root { --mini: 13px; }
  body { font-size: 16px; }
  .main-content { padding: 20px 24px calc(96px + env(safe-area-inset-bottom)); }
  .topbar { margin-bottom: 20px; }
  .topbar h1 { font-size: 27px; }

  /* 首页指标：3 列，卡片和字号都放大 */
  #dashboardView .stat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-bottom: 16px; }
  /* 关掉窄屏手机版的 6 列/span 规则，否则在 3~4 列布局里卡片会乱跨列 */
  #dashboardView .stat-grid > .stat-card { grid-column: auto; min-height: 124px; padding: 18px 20px; border-radius: 14px; }
  #dashboardView .stat-grid > .stat-card:nth-child(n+5) { grid-column: auto; padding: 18px 20px; min-height: 124px; }
  #dashboardView .stat-grid > .stat-card .stat-value { font-size: clamp(20px, 3.6vw, 26px); margin: 12px 0 7px; }
  /* hero 卡同时带 stat-card 和 accent-card 两个类，必须写在 stat-card 之后才不会被盖掉 */
  #dashboardView .stat-grid > .accent-card { grid-column: 1 / -1; padding: 22px 26px; }
  #dashboardView .stat-grid > .accent-card .stat-label { font-size: 14px; }
  #dashboardView .stat-grid > .accent-card .stat-value { font-size: clamp(28px, 5.5vw, 40px); margin: 10px 0 6px; }
  #dashboardView .stat-label { font-size: 14px; }
  #dashboardView .stat-meta { font-size: 13px; }

  #dashboardView .stat-more { gap: 14px; }
  #dashboardView .stat-more > summary { min-height: 52px; padding: 0 18px; border-radius: 12px; font-size: 14px; }
  /* v36：宽屏手机版仍然一行一条，只是条更高、字更大 */
  #dashboardView .stat-more > .stat-card { min-height: 68px; padding: 14px 20px; border-radius: 14px; }
  #dashboardView .stat-more > .stat-card > .stat-label { font-size: 15px; }
  #dashboardView .stat-more > .stat-card > .stat-meta { font-size: 12px; }
  #dashboardView .stat-more > .stat-card > .stat-value { font-size: 23px; }

  /* 待办：一行 4 个 */
  #dashboardView .workflow-tasks { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-bottom: 20px; }
  #dashboardView .workflow-tasks::before { font-size: 15px; margin-bottom: 6px; }
  #dashboardView .workflow-task {
    display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
    min-height: 86px; padding: 18px 20px; gap: 6px;
    background: var(--surface-soft); border: 1px solid var(--line); border-radius: 14px;
    font-size: 14px; color: var(--muted);
  }
  #dashboardView .workflow-task span { font-size: 14px; color: var(--muted); }
  #dashboardView .workflow-task strong { font-size: 26px; color: var(--ink); font-weight: 700; }

  /* 列表卡片：内边距、圆角、正文都放大 */
  #customersView tbody tr, #suppliersView tbody tr, #salesView tbody tr, #cashflowView tbody tr {
    padding: 16px 20px; border-radius: 14px; margin-bottom: 12px; gap: 8px 14px;
  }
  #customersView tbody td, #suppliersView tbody td, #salesView tbody td, #cashflowView tbody td { font-size: 15px; }
  #customersView tbody td:nth-child(1) .table-primary, #suppliersView tbody td:nth-child(1) .table-primary,
  #salesView tbody td:nth-child(3) { font-size: 17px; }
  #customersView tbody td:nth-child(9), #suppliersView tbody td:nth-child(8) { font-size: 17px; }
  #cashflowView tbody td:nth-child(4) { font-size: 17px; }
  #cashflowView tbody td:nth-child(8) { font-size: 18px; }
  #customersView tfoot tr, #suppliersView tfoot tr, #salesView tfoot tr, #cashflowView tfoot tr { padding: 13px 18px; font-size: 13.5px; }

  /* 底栏页签：跟屏幕一起变大 */
  .sidebar { height: calc(80px + env(safe-area-inset-bottom)); }
  .sidebar:not(.nav-expanded) > .nav-list .nav-item[data-nav-tier="primary"] { font-size: 14px; min-height: 60px; }
  .sidebar.nav-expanded > .nav-list .nav-item { font-size: 15px; min-height: 60px; }
  .nav-icon { font-size: 20px; }
  .mobile-nav-toggle { flex: 0 0 80px; min-width: 80px; font-size: 13px; min-height: 60px; }

  /* 按钮 / 输入框跟着放大，鼠标点也更好点 */
  .secondary-button, .primary-button, .ghost-button, .mini-button, .text-button { font-size: 15px; min-height: 48px; }
  input, select, textarea { font-size: 15px; min-height: 48px; }
  .search-box { height: 48px; }
  .filter-row select { height: 48px; }
  .panel-header { padding: 20px 18px 12px; }
  .panel-header h3 { font-size: 17px; }
}

/* ============================================================
   十四·补 兜底：html.force-mobile 也要能驱动布局
   ------------------------------------------------------------
   v30：JS 只要认出 UA 是手机就给 <html> 加 force-mobile（不再要求媒体查询没命中）。
   但媒体查询里的规则不会跟着这个类走，所以这里把「手机版骨架」再写一遍：
   侧栏变底栏、正文占满宽、底栏只留主页签。
   作用：不管视口怎么变、缓存怎么混，手机都不会掉回电脑版。
   ============================================================ */
html.force-mobile .sidebar {
  position: fixed; inset: auto 0 0 0;
  width: 100%; height: calc(68px + env(safe-area-inset-bottom));
  flex-direction: row; align-items: center; z-index: 4;
  /* v45：底栏用与页面形成对比的深色，跟电脑版侧栏同色系 */
  background: var(--nav-bar-bg); color: rgba(255,255,255,.92);
  border-top: 0; border-right: 0;
  box-shadow: 0 -1px 0 rgba(255,255,255,.10);
  padding: 6px 8px env(safe-area-inset-bottom);
}
html.force-mobile .brand-lockup,
html.force-mobile .sidebar-bottom { display: none; }
html.force-mobile .main-content {
  width: 100%; margin-left: 0; max-width: none;
  padding: 14px 12px calc(92px + env(safe-area-inset-bottom));
}
html.force-mobile .nav-list { width: 100%; display: flex; gap: 3px; overflow: hidden; padding: 0; }
html.force-mobile .nav-item[data-nav-tier="secondary"] { display: none !important; }
html.force-mobile .nav-item[data-nav-tier="primary"] { display: flex !important; flex: 1 1 0; min-width: 0; justify-content: center; }
html.force-mobile .mobile-nav-toggle { display: flex; order: 9; flex: 0 0 70px; min-width: 70px; }
html.force-mobile .sidebar.nav-expanded > .nav-list { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
html.force-mobile .sidebar.nav-expanded > .nav-list .nav-item { display: flex !important; }

/* 「更多」按钮做得像按钮，别跟页签混在一起 */
.mobile-nav-toggle {
  flex: 0 0 70px; min-width: 70px;
  border: 1px solid var(--line) !important;
  background: var(--surface-soft) !important;
  color: var(--ink) !important;
  font-size: 12px; border-radius: 10px;
}
/* ============================================================
   十五、未登录闸门 v31
   ------------------------------------------------------------
   未登录时 <html> 带 .auth-locked：侧栏 / 底栏 / 顶栏 / 内容区全部不显示，
   只剩一张全屏登录页。之前登录弹窗背后业务数据全都看得见，等于没锁。
   ============================================================ */
html.auth-locked { background: var(--canvas); }
html.auth-locked .app-shell,
html.auth-locked .mobile-nav-scrim { display: none !important; }
/* 登录页：铺满整屏的画布色，卡片居中 */
html.auth-locked .modal-backdrop {
  background: var(--canvas);
  padding: 24px 16px;
  align-items: center;
  z-index: 20;
}
html.auth-locked .modal-backdrop[hidden] { display: none; }
html.auth-locked .modal {
  width: min(430px, 100%);
  max-height: calc(100vh - 48px);
  margin: 0 auto;
  padding: 26px 24px;
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 10px 40px rgba(31,36,34,.10);
}
/* 登录闸门不能取消 */
html.auth-locked .modal .form-foot .ghost-button[data-close] { display: none; }
html.auth-locked .modal > .modal-head > .close-button { display: none; }

/* ============================================================
   十六、登录页重做 v33
   ------------------------------------------------------------
   原来的登录页：logo 偏小、文案带 demo 味（"仅本机保存、仅用于演示"）、
   演示按钮占了主按钮的位置、层级拉不开，看着像测试页面。
   改成正经企业 SaaS 的样子：品牌区 → 表单 → 主按钮 → 弱化辅助信息。
   ============================================================ */
/* v35：整张卡收紧一档 —— 原来 padding 28/24 + 品牌区 150px，一屏装不下要滚动 */
html.auth-locked .modal-backdrop { padding: 16px 12px; align-items: center; }
/* v38：注册表单比登录表单长，装不下时让它在卡内滚动，别顶出屏幕 */
html.auth-locked .modal { padding: 20px 18px 18px; border-radius: 16px; max-height: calc(100vh - 32px); overflow-y: auto; }

/* ---- 品牌区：logo 在左、文字两行在右（竖排时要占 150px，太长） ---- */
html.auth-locked .auth-gate-head {
  display: flex; align-items: center; gap: 12px;
  text-align: left;
  margin: 0 0 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
}
html.auth-locked .auth-gate-head .brand-mark {
  flex: 0 0 50px; width: 50px; height: 50px; margin: 0;
  display: grid; place-items: center; border-radius: 14px;
  background: var(--accent);
}
html.auth-locked .auth-gate-head .brand-mark img { width: 30px; height: 30px; }
html.auth-locked .auth-gate-head .auth-brand-text { min-width: 0; }
html.auth-locked .auth-gate-head h3 {
  margin: 0; font-size: 19px; font-weight: 700;
  letter-spacing: .04em; color: var(--ink);
}
/* 系统名 + 公司全称并成一行，不再各占一行 */
html.auth-locked .auth-gate-head .auth-brand-sub {
  margin: 3px 0 0; font-size: 11px; line-height: 1.45;
  font-weight: 500; color: var(--muted); letter-spacing: .01em;
}
html.auth-locked .auth-gate-head .auth-brand-org { display: none; }

/* ---- 页签：胶囊分段控件，选中项实心底 ---- */
html.auth-locked .auth-tabs {
  display: flex; gap: 4px; padding: 3px; margin: 0 0 12px;
  background: var(--surface-soft);
  border: 1px solid var(--line);
  border-radius: 12px;
}
html.auth-locked .auth-tab {
  flex: 1 1 0; min-width: 0; min-height: 44px; padding: 0 8px;
  border: 0; border-radius: 9px; background: transparent;
  font-family: inherit; font-size: 13px; font-weight: 600;
  letter-spacing: .16em; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: background .18s, color .18s;
}
html.auth-locked .auth-tab.active {
  background: var(--accent); color: #fff; font-weight: 650;
  box-shadow: none;
}

/* ---- 表单：label 在上、输入框 50px 高、聚焦主色描边 ---- */
.auth-form { display: block; }
.auth-label {
  display: block; margin-bottom: 10px;
  font-size: 12.5px; font-weight: 600; color: var(--muted);
}
.auth-label input {
  display: block; width: 100%; margin-top: 6px;
  padding: 0 13px; height: 46px;
  font-size: 16px; color: var(--ink);   /* 保持 16px：小于 16 手机浏览器聚焦时会自动放大整页 */
  background: var(--surface);
  border: 1px solid var(--line); border-radius: 10px;
}
/* v78：去掉 .65 淡化 —— 只剩 2.67:1。登录页是所有人进系统的第一个画面。 */
.auth-label input::placeholder { color: var(--muted); opacity: 1; font-size: 15px; }
.auth-label input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
  outline: none;
}
/* 「记住登录 / 忘记密码」一行 */
.auth-form .auth-row { margin: 10px 0 13px; }
.auth-form .auth-row .text-button { font-size: 12.5px; }

/* ---- 主按钮：通栏、够高、按下有反馈 ---- */
.auth-submit {
  display: block; width: 100%; height: 48px;
  font-size: 15.5px; font-weight: 700; letter-spacing: .22em;
  border-radius: 10px;
}
/* ---- 辅助信息：演示入口 + 提示，统一弱化到底部 ---- */
.auth-foot-note {
  margin-top: 12px; padding-top: 10px;
  border-top: 1px solid var(--line); text-align: center;
}
.auth-foot-note .text-button { font-size: 12.5px; color: var(--accent); }
.auth-foot-note p {
  margin: 4px 0 0; font-size: 10.5px; line-height: 1.5;
  color: var(--muted); opacity: 1;   /* v78：去掉 .8 淡化，只剩 3.54:1 */
}
/* 版本号：从卡片里挪到最底，再弱化 */
html.auth-locked .auth-version {
  margin: 9px 0 0; font-size: 10px; letter-spacing: .04em;
  color: var(--muted); opacity: 1;   /* v78：去掉 .6 淡化，只剩 2.44:1，版本号要看得清 */
}
/* 账号菜单里主动打开登录（非闸门）时，也保持同样的精致排版 */
#modalContent .auth-label input,
#modalContent .auth-submit { font-family: inherit; }


/* 更宽的手机版（≥1180）：指标改 4 列，大数再放大一档 */
@media (min-width: 1180px) and (max-width: 1199.98px), (min-width: 1180px) and (pointer: coarse), (min-width: 1180px) and (hover: none) {
  #dashboardView .stat-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
  #dashboardView .stat-grid > .stat-card { grid-column: auto; min-height: 130px; }
  #dashboardView .stat-grid > .stat-card:nth-child(n+5) { grid-column: auto; padding: 18px 20px; min-height: 130px; }
  #dashboardView .stat-grid > .stat-card .stat-value { font-size: clamp(22px, 3.2vw, 28px); }
  #dashboardView .stat-grid > .accent-card { grid-column: 1 / -1; }
  #dashboardView .stat-grid > .accent-card .stat-value { font-size: clamp(32px, 4.8vw, 46px); }   /* 同上：必须排在 stat-card 之后 */
  /* v36：超宽屏手机版也是一行一条（不再摊成 4 列小卡） */
  #dashboardView .stat-more { grid-template-columns: 1fr; }
  #dashboardView .stat-more > .stat-card > .stat-value { font-size: 25px; }
  .main-content { padding: 24px 32px calc(100px + env(safe-area-inset-bottom)); }
}

/* ============================================================
   十七、底栏重做 v33
   ------------------------------------------------------------
   v33：原来 5 个按钮（4 主页签 + 更多）信息太散，选中态不够跳。
   v34：改成「底部只留当前板块，点它展开全部板块」——
        收起态整条就是一个当前板块，右侧标「☰ 全部板块」提示可点；
        点开后抽屉里列出 8 个板块，点一个即切换。
        这样底部永远只有一个明确的入口，不会认不出该点哪。
   ============================================================ */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  /* 整条压成一条 60px 的导航条。
     v45：底栏改用跟页面对比的深色（浅色页面配深底栏），白字 —— 之前只有
     html.force-mobile 有这套配色，普通窄屏设备（<1200 走手机版）会掉回白色底栏，
     白条贴白底几乎看不见。 */
  .sidebar {
    height: calc(62px + env(safe-area-inset-bottom));
    background: var(--nav-bar-bg); color: rgba(255, 255, 255, .92);
    border-top: 0;
    box-shadow: 0 -1px 0 rgba(255, 255, 255, .10);
    padding: 0 0 env(safe-area-inset-bottom);
  }
  html .sidebar .nav-item { color: rgba(255, 255, 255, .64); }
  html .sidebar .nav-item.active { background: rgba(255, 255, 255, .16); color: #fff; }
  html .sidebar .mobile-account-chip { background: rgba(255, 255, 255, .10); border-color: rgba(255, 255, 255, .14); color: #fff; }
  .sidebar:not(.nav-expanded) > .nav-list { padding: 0; gap: 0; }

  /* 收起态：除了当前板块，其余全部隐藏
     —— 选择器必须带 [data-nav-tier] 并加 html 前缀，才压得住 v27 那条
        .sidebar:not(.nav-expanded) > .nav-list .nav-item[data-nav-tier="primary"] { display:flex } */
  html .sidebar:not(.nav-expanded) > .nav-list .nav-item[data-nav-tier] { display: none !important; }

  /* 当前板块：占满整条，左边图标+名字，右边「☰ 全部板块」 */
  html .sidebar:not(.nav-expanded) > .nav-list .nav-item.active {
    display: flex !important;
    flex: 1 1 auto; width: 100%;
    flex-direction: row; align-items: center; justify-content: flex-start; gap: 10px;
    min-height: 60px; padding: 0 20px;
    background: var(--nav-bar-bg); color: #fff;
    border-radius: 0; box-shadow: none;
    font-size: 16px; font-weight: 700;
  }
  html .sidebar:not(.nav-expanded) > .nav-list .nav-item.active .nav-icon {
    font-size: 21px; color: var(--accent-bright);
  }

  /* 按下给点反馈，让人知道整条都能点 */
  html .sidebar:not(.nav-expanded) > .nav-list .nav-item.active:active { background: rgba(255, 255, 255, .08); }

  /* 原来那个独立的「全部」按钮撤掉：当前板块这条本身就是入口 */
  .sidebar .mobile-nav-toggle { display: none !important; }

  /* 抽屉标题：写清楚「点一个进入」，别让人以为要点两次 */
  
}

/* 同套规则绑到 html.force-mobile（手机浏览器请求「桌面版网站」时不掉回去） */
html.force-mobile .sidebar {
  height: calc(62px + env(safe-area-inset-bottom));
  box-shadow: 0 -1px 0 var(--line);
  padding: 0 0 env(safe-area-inset-bottom);
}
html.force-mobile .nav-list { gap: 0; padding: 0; }
/* 只在收起态隐藏其余板块，展开态（抽屉）要照常显示全部 */
html.force-mobile .sidebar:not(.nav-expanded) .nav-item { display: none !important; }
html.force-mobile .sidebar:not(.nav-expanded) .nav-item.active {
  display: flex !important;
  flex: 1 1 auto; width: 100%;
  flex-direction: row; align-items: center; justify-content: flex-start; gap: 10px;
  min-height: 60px; padding: 0 20px;
  background: var(--nav-bar-bg); color: #fff;
  border-radius: 0; box-shadow: none;
  font-size: 16px; font-weight: 700;
}
html.force-mobile .sidebar:not(.nav-expanded) .nav-item.active .nav-icon { font-size: 21px; color: var(--accent-bright); }
html.force-mobile .mobile-nav-toggle { display: none !important; }

/* v33：手机底栏隐藏头像入口，别把仅有的一条导航挤乱 */
html.force-mobile .mobile-account-chip { display: none !important; }

/* 宽屏手机版（≥721）：当前板块条再高一点 */
@media (min-width: 721px) and (max-width: 1199.98px), (min-width: 721px) and (pointer: coarse), (min-width: 721px) and (hover: none) {
  html .sidebar:not(.nav-expanded) > .nav-list .nav-item.active { min-height: 70px; font-size: 18px; padding: 0 28px; }
  html .sidebar:not(.nav-expanded) > .nav-list .nav-item.active .nav-icon { font-size: 24px; }
  html .sidebar:not(.nav-expanded) > .nav-list .nav-item.active::after { font-size: 15px; }
  .sidebar { height: calc(72px + env(safe-area-inset-bottom)); }
}

/* 深色模式：当前板块条用深色面，文字用浅色 */
/* v78：老板决定不保留深色模式，整块停用（内容保留，恢复时把 and (min-width: 999999px) 删掉即可） */
@media (prefers-color-scheme: dark) and (min-width: 999999px) {
  html .sidebar:not(.nav-expanded) > .nav-list .nav-item.active,
  html.force-mobile .sidebar:not(.nav-expanded) .nav-item.active {
    background: var(--nav-bar-bg); color: #fff;
  }
  html .sidebar:not(.nav-expanded) > .nav-list .nav-item.active .nav-icon,
  html.force-mobile .sidebar:not(.nav-expanded) .nav-item.active .nav-icon {
    color: var(--accent-bright);
  }
}

/* ============================================================
   十八、抽屉修正 v35
   ------------------------------------------------------------
   1) 致命 bug：遮罩 .mobile-nav-scrim 的 z-index 是 8，而底栏 .sidebar 只有 4
      —— 抽屉展开后遮罩压在它上面，8 个板块看得见却点不到，
      点下去只触发「收起抽屉」，页面纹丝不动。
      （之前的核验脚本用 JS 的 el.click() 直接调方法，绕过了命中测试，所以一直没测出来。）
      修法：遮罩降到 3，底栏(4) 重新回到遮罩之上；弹窗遮罩(10 / 登录页 20)仍在底栏之上。
   2) v50：抽屉配色跟底栏统一成深色（--nav-bar-bg）+ 白字，选中项更亮一档 + 左侧翡翠条。
      （原来是白卡片配深底栏，展开像两层皮，不在一起。）
   ============================================================ */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  html .mobile-nav-scrim { z-index: 3; }

  html .sidebar.nav-expanded > .nav-list { color: #fff;
    bottom: calc(62px + env(safe-area-inset-bottom) + 8px);
    padding: 12px; gap: 8px;
    max-height: min(62vh, 520px);
    overflow-y: auto;
    background: var(--nav-bar-bg);
    border: 1px solid rgba(255,255,255,.12);
    border-radius: 16px;
    box-shadow: 0 16px 44px rgba(20,24,22,.32);
  }
  html .sidebar.nav-expanded > .nav-list .nav-item {
    min-height: 52px; padding: 10px 12px;
    background: rgba(255,255,255,.06);
    border: 1px solid rgba(255,255,255,.10);
    border-radius: 12px;
    color: rgba(255,255,255,.90); font-size: 13.5px; font-weight: 600;
  }
  html .sidebar.nav-expanded > .nav-list .nav-item .nav-icon { color: var(--nav-icon-bright); opacity: 1; }
  /* 选中项：更亮一档的白底 + 左侧 3px 翡翠条 */
  html .sidebar.nav-expanded > .nav-list .nav-item.active {
    background: rgba(255,255,255,.16);
    border-color: rgba(255,255,255,.22);
    color: #fff;
    box-shadow: inset 3px 0 0 var(--accent-bright);
  }
  html .sidebar.nav-expanded > .nav-list .nav-item.active .nav-icon { color: var(--nav-icon-bright); opacity: 1; }

}
/* 同套规则绑到 html.force-mobile */
html.force-mobile .mobile-nav-scrim { z-index: 3; }
html.force-mobile .sidebar.nav-expanded > .nav-list { color: #fff;
  bottom: calc(62px + env(safe-area-inset-bottom) + 8px);
  padding: 12px; gap: 8px;
  max-height: min(62vh, 520px);
  overflow-y: auto;
  background: var(--nav-bar-bg);
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 16px;
  box-shadow: 0 16px 44px rgba(20,24,22,.32);
}
html.force-mobile .sidebar.nav-expanded > .nav-list .nav-item {
  min-height: 52px; padding: 10px 12px;
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.10);
  border-radius: 12px;
  color: rgba(255,255,255,.90); font-size: 13.5px; font-weight: 600;
}
html.force-mobile .sidebar.nav-expanded > .nav-list .nav-item .nav-icon { color: var(--nav-icon-bright); opacity: 1; }
html.force-mobile .sidebar.nav-expanded > .nav-list .nav-item.active {
  background: rgba(255,255,255,.16);
  border-color: rgba(255,255,255,.22);
  color: #fff;
  box-shadow: inset 3px 0 0 var(--accent-bright);
}
html.force-mobile .sidebar.nav-expanded > .nav-list .nav-item.active .nav-icon { color: var(--nav-icon-bright); opacity: 1; }
/* 宽屏手机版底栏是 72px，抽屉跟着抬高 */
@media (min-width: 721px) and (max-width: 1199.98px), (min-width: 721px) and (pointer: coarse), (min-width: 721px) and (hover: none) {
  html .sidebar.nav-expanded > .nav-list,
  html.force-mobile .sidebar.nav-expanded > .nav-list { bottom: calc(72px + env(safe-area-inset-bottom) + 8px); }
}

/* ============================================================
   十九、账户入口 + 返回按钮 v36
   ------------------------------------------------------------
   底栏改成「只留当前板块」之后，手机上的账户菜单彻底没有入口了
   （首页顶栏是简版、其余页的顶栏账号卡又被隐藏）。
   ============================================================ */

/* 电脑版：首页简版顶栏不出现头像（顶栏本来就有完整账号卡） */
.mobile-avatar-btn { display: none; }

@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  /* 首页：标题左边一个圆形头像，点它进「我的账户」
     v43：按钮本身不再画灰圆（原来「灰圆套绿圆」＝甜甜圈双圈），只留里面这一颗头像。
     宽高写死 44px（只写 min-height 会被别处 44px 规则拉成椭圆），触控区达标。 */
  .mobile-avatar-btn {
    display: inline-flex; align-items: center; justify-content: center;
    flex: 0 0 44px; width: 44px; height: 44px; padding: 0; margin-right: 2px;
    border: 0; border-radius: 50%;
    background: transparent; color: var(--ink);
  }
  /* (0,2,0) 高于基础层 .account-chip-avatar (0,1,0)，手机端要显式覆盖尺寸 */
  .mobile-avatar-btn .account-chip-avatar { width: 38px; height: 38px; font-size: 13px; }

  /* 其余页：顶栏账号卡只留圆头像，姓名/角色两行文字收掉，省位置 */
  .topbar-account { padding: 3px; gap: 0; }
  .topbar-account .account-chip-text { display: none; }

  /* 弹窗：左上角「‹ 返回」，右上角那个 × 在手机上认不出是返回，藏掉 */
  .modal-back-button {
    display: inline-flex; align-items: center; gap: 2px;
    flex: 0 0 auto; order: -1;
    min-height: 44px; padding: 0 12px 0 8px;
    border: 0; border-radius: var(--radius-control);
    background: var(--surface-soft); color: var(--ink);
    font-family: inherit; font-size: 14px; font-weight: 600;
  }
  .modal-back-button span { font-size: 21px; line-height: 1; }
  .modal-head > .modal-back-button + div { flex: 1 1 auto; min-width: 0; }
  .modal-head > .close-button { display: none; }
}
/* 同套规则绑到 html.force-mobile */
html.force-mobile .mobile-avatar-btn {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 44px; width: 44px; height: 44px; padding: 0; margin-right: 2px;
  border: 0; border-radius: 50%;
  background: transparent; color: var(--ink);
}
html.force-mobile .mobile-avatar-btn .account-chip-avatar { width: 38px; height: 38px; font-size: 13px; }
html.force-mobile .topbar-account { display: inline-flex; padding: 3px; gap: 0; }
html.force-mobile .topbar-account .account-chip-text { display: none; }
html.force-mobile .modal-back-button {
  display: inline-flex; align-items: center; gap: 2px;
  flex: 0 0 auto; order: -1;
  min-height: 44px; padding: 0 12px 0 8px;
  border: 0; border-radius: var(--radius-control);
  background: var(--surface-soft); color: var(--ink);
  font-family: inherit; font-size: 14px; font-weight: 600;
}
html.force-mobile .modal-back-button span { font-size: 21px; line-height: 1; }
html.force-mobile .modal-head > .modal-back-button + div { flex: 1 1 auto; min-width: 0; }
html.force-mobile .modal-head > .close-button { display: none; }

/* 深色模式：这两个入口跟随深色面 */
/* v78：老板决定不保留深色模式，整块停用（内容保留，恢复时把 and (min-width: 999999px) 删掉即可） */
@media (prefers-color-scheme: dark) and (min-width: 999999px) {
  /* v43：头像按钮本身透明（圆由里面那颗头像画），返回按钮仍是面块 */
  .mobile-avatar-btn { background: transparent; color: var(--ink); }
  .modal-back-button { background: var(--surface-soft); color: var(--ink); }
}

/* ============================================================
   二十、注册表单排版 v38
   ------------------------------------------------------------
   原来登录页里点「注册账号」只有一句话 + 一个跳转按钮，
   跳过去还是白屏（登录闸门没解除）。现在表单直接做在登录弹窗里，
   样式跟登录表单对齐：单列、输入框 46px、提交按钮通栏。
   ============================================================ */
/* 带 display 的类（.form-grid 是 display:grid）会盖掉 [hidden] 自带的 display:none，
   结果「该隐藏的区块」照常显示（供应商收款账户就是这么露出来的）。统一压回去。 */
[hidden] { display: none !important; }
.auth-register-form .form-grid { grid-template-columns: 1fr; gap: 10px; }
.auth-register-form .form-field { margin: 0; }
.auth-register-form .form-field label {
  display: block; margin-bottom: 6px;
  font-size: 12.5px; font-weight: 600; color: var(--muted);
}
.auth-register-form .form-field input,
.auth-register-form .form-field select {
  width: 100%; height: 46px; padding: 0 13px;
  font-size: 16px; color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line); border-radius: 10px;
}
.auth-register-form .form-field input:focus,
.auth-register-form .form-field select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
  outline: none;
}
.auth-register-tip {
  margin: 0 0 12px; font-size: 12px; line-height: 1.6;
  color: var(--muted);
}
/* 供应商收款账户那一段：跟主表单分开一点 */
.auth-register-form #registrationSupplierFields {
  margin-top: 4px; padding-top: 10px;
  border-top: 1px dashed var(--line);
}
.auth-register-form .form-hint { font-size: 11px; color: var(--muted); }
.auth-register-form .auth-submit { margin-top: 14px; }

/* ============================================================
   二十一、装车板块 + 手机端细节 v42
   ------------------------------------------------------------
   1) 装车板块分两块：待装车（来自销售单）/ 装车记录
   2) 手机端禁止左右滑动返回（浏览器边缘手势），只能点顶部「‹ 返回」
   3) 手机端采购明细：品名和等级并排一行
   ============================================================ */
.packing-board { display: grid; gap: 20px; }
.packing-block { display: grid; gap: 12px; }
.packing-block-head {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding-bottom: 8px; border-bottom: 1px solid var(--line);
}
.packing-block-head strong { font-size: 14px; color: var(--ink); }
.packing-block-head span { font-size: 11.5px; color: var(--muted); }
/* 待装车卡片：虚线框跟「已建装车单」区分开 */
.pending-truck-card { border-style: dashed; border-color: var(--accent-bright); }
.pending-truck-card .stock-numbers { grid-template-columns: repeat(3, 1fr); }
.truck-card-cta {
  display: block; margin-top: 12px; padding-top: 10px;
  border-top: 1px dashed var(--line);
  color: var(--accent); font-size: 12.5px; font-weight: 700;
}

/* 手机端禁止左右滑动返回：浏览器从屏幕边缘往里滑 = 后退手势，一滑就把系统划走 */
html, body { overscroll-behavior-x: none; }

/* 手机端：采购明细里「品名」和「等级」并排一行（原来是内联，窄屏会被挤到下一行） */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  .source-summary > div > strong {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  }
  .source-summary > div > strong .grade-tag { margin-left: 0; }
  .detail-items td > .grade-tag { display: inline-block; margin-left: 6px; }
}
html.force-mobile .source-summary > div > strong {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
}
html.force-mobile .source-summary > div > strong .grade-tag { margin-left: 0; }
html.force-mobile .detail-items td > .grade-tag { display: inline-block; margin-left: 6px; }

/* ============================================================
   二十二、精制加工 · 多品种产出
   ------------------------------------------------------------
   一次精制可能分出 7-8 个品种：弹窗里一行一个品种（品名 / SKU / 产出重量），
   保存后每个品种各自成为一个可销售的成品批次；列表按「加工单」分组展示，
   卡片里品种超过 4 个时改成可滚动，避免一张卡撑满屏幕。
   手机端规则照惯例写两份：媒体查询版 + html.force-mobile 版。
   ============================================================ */
#processingOutputRows { display: grid; gap: 8px; }
.processing-output-row {
  display: grid;
  grid-template-columns: minmax(160px, 1fr) 152px 136px 40px;
  gap: 8px 10px; align-items: end;
}
.processing-cell { display: grid; gap: 3px; min-width: 0; }
.processing-cell > small { font-size: 11px; color: var(--muted); }
.processing-cell input { width: 100%; }
.processing-output-row .processing-row-remove {
  display: flex; align-items: center; justify-content: center;
  width: 40px; min-height: 40px; padding: 0; font-size: 16px;
}
.processing-row-remove[hidden] { display: none; }
#addProcessingRow { justify-self: start; margin-top: 10px; }

/* 加工单卡片里的品种区：跟上面的数字块之间拉一条虚线 */
.processing-order-card { text-align: left; }
.processing-order-card .processing-variety-list {
  margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--line);
}
.processing-variety-list { display: grid; gap: 6px; }
.processing-variety-list.scrollable { max-height: 196px; overflow-y: auto; padding-right: 2px; }
.processing-variety-row {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 10px;
  width: 100%; padding: 8px 10px; cursor: pointer;
  text-align: left; font: inherit; color: var(--ink);
  border: 1px solid var(--line-soft); border-radius: var(--radius-control);
  background: var(--surface-soft);
}
.processing-variety-row:hover, .processing-variety-row:focus-visible {
  background: var(--accent-soft); border-color: var(--line);
}
.processing-variety-row:active { transform: scale(.99); }
.processing-variety-row strong { grid-column: 1; grid-row: 1; font-size: 13px; }
.processing-variety-row em {
  grid-column: 2; grid-row: 1; justify-self: end;
  font-style: normal; font-size: 12px; color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.processing-variety-row .sku-label { grid-column: 1 / -1; font-size: 11px; }
.processing-variety-row span:not(.sku-label) { grid-column: 1 / -1; font-size: 11.5px; color: var(--muted); }

/* 手机端：品名独占一行，产出重量和删除并排，SKU 收在最后一行 */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  .processing-output-row { grid-template-columns: 1fr auto; gap: 8px; }
  .processing-output-row .name-cell { grid-column: 1 / -1; grid-row: 1; }
  .processing-output-row .weight-cell { grid-column: 1; grid-row: 2; }
  .processing-output-row .processing-row-remove { grid-column: 2; grid-row: 2; width: 44px; min-height: 44px; }
  .processing-output-row .sku-cell { grid-column: 1 / -1; grid-row: 3; }
  .processing-variety-row { min-height: 44px; }
}
html.force-mobile .processing-output-row { grid-template-columns: 1fr auto; gap: 8px; }
html.force-mobile .processing-output-row .name-cell { grid-column: 1 / -1; grid-row: 1; }
html.force-mobile .processing-output-row .weight-cell { grid-column: 1; grid-row: 2; }
html.force-mobile .processing-output-row .processing-row-remove { grid-column: 2; grid-row: 2; width: 44px; min-height: 44px; }
html.force-mobile .processing-output-row .sku-cell { grid-column: 1 / -1; grid-row: 3; }
html.force-mobile .processing-variety-row { min-height: 44px; }

/* ============================================================
   二十三、已结清隐藏开关
   「已经结清闭环的单子就不显示了。」采购仓库 / 装车 / 精制加工 / 销售清单
   四个列表顶部各放一个复选框，默认关闭（隐藏已结清），打开即放出结清单据。
   视觉上刻意做小做淡：它是辅助控件，不能抢主按钮的重量。
   配色只用现有变量，不新增硬编码色值。
   ============================================================ */
.closed-filter-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 8px;
  padding: 4px 10px 4px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--muted);
  font-size: 12px;
  line-height: 1.4;
  cursor: pointer;
  user-select: none;
}
.closed-filter-toggle input[type="checkbox"] {
  width: 13px;
  height: 13px;
  margin: 0;
  accent-color: var(--accent-bright);
  cursor: pointer;
}
.closed-filter-toggle span { color: var(--muted); font-size: 12px; }
.closed-filter-toggle:hover { border-color: var(--accent); }
.closed-filter-toggle:hover span { color: var(--ink); }
.closed-filter-toggle input[type="checkbox"]:checked + span { color: var(--accent-on); }
.closed-filter-toggle input[type="checkbox"]:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 1px; }

/* 手机端：复选框要够大才好点 */
@media (max-width: 1199.98px) {
  .closed-filter-toggle { min-height: 36px; padding: 6px 12px 6px 10px; font-size: 13px; gap: 8px; }
  .closed-filter-toggle span { font-size: 13px; }
  .closed-filter-toggle input[type="checkbox"] { width: 16px; height: 16px; }
}
html.force-mobile .closed-filter-toggle { min-height: 36px; padding: 6px 12px 6px 10px; font-size: 13px; gap: 8px; }
html.force-mobile .closed-filter-toggle span { font-size: 13px; }
html.force-mobile .closed-filter-toggle input[type="checkbox"] { width: 16px; height: 16px; }

/* ============================================================
   二十四、精制加工 · 编辑入口 v47
   三个入口各放一个「编辑」按钮：加工单卡片右上角 / 加工单明细弹窗底部 /
   成品批次详情底部。定位是次要操作 —— 小号、描边、低对比，
   不能抢「新建加工单 / 保存 / 准备发货」这类主按钮的视觉重量。
   配色只用现有变量，不新增硬编码色值。手机端规则照惯例写两份。
   ============================================================ */
.processing-edit-button {
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 650;
  border-radius: var(--radius-pill);
  white-space: nowrap;
}
.processing-edit-button:hover { border-color: var(--accent); color: var(--accent-on); }

/* 卡片右上角：单号左、状态紧跟、编辑贴右边。
   stock-card-top 是 space-between，给状态胶囊 margin-right:auto 吃掉剩余空间，
   编辑按钮才能稳稳靠右，而不是三等分飘在中间。 */
.processing-order-card .stock-card-top { gap: 8px; flex-wrap: wrap; }
.processing-order-card .stock-card-top .status-pill { margin-right: auto; }

/* 编辑模式下来料装车单是只读的，视觉上要看得出来锁住了 */
#processingTruck:disabled { background: var(--surface-soft); color: var(--muted); cursor: not-allowed; }

/* 手机端：点得到才有用 */
@media (max-width: 1199.98px) {
  .processing-edit-button { min-height: 36px; padding: 8px 14px; font-size: 13px; }
  .processing-order-card .stock-card-top { gap: 10px; }
}
html.force-mobile .processing-edit-button { min-height: 36px; padding: 8px 14px; font-size: 13px; }
html.force-mobile .processing-order-card .stock-card-top { gap: 10px; }

/* ============================================================
   二十五、签收结算 · 扣重扣价 v48
   客户签收时的实收结算区：做成一张浅底记账卡片，数字全部右对齐、
   等宽数字对齐小数点，一眼能核账。差额一行要给足视觉重量 ——
   少收（亏损方向）走 --red-*，多收走点缀绿底 --accent-tile + 深字
   （--accent-bright 压白只有 3.1:1，小字不能用）。
   配色全部用现有变量，不新增硬编码色值；手机端规则照惯例写两份。
   ============================================================ */
.settlement-block {
  background: var(--surface-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 14px 15px;
}
/* 标题行右那句提示要贴着标题，不能被 .form-hint 的默认 margin 顶歪 */
.settlement-block .form-section-title { margin-bottom: 12px; gap: 8px; }
.settlement-block .form-section-title .form-hint { margin: 0; }

.settlement-sub {
  margin: 2px 0 10px;
  color: var(--accent);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .02em;
}

.settlement-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.settlement-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.settlement-grid .form-field { min-width: 0; }
.settlement-grid .form-field input { text-align: right; font-variant-numeric: tabular-nums; }
.settlement-readonly { background: var(--accent-soft); color: var(--muted); cursor: default; }
.settlement-readonly:focus { border-color: var(--line); box-shadow: none; }

.settlement-result {
  margin: 10px 0 0;
  padding: 9px 11px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--muted);
  font-size: var(--mini);
  line-height: 1.6;
  font-variant-numeric: tabular-nums;
}

.settlement-note-field { margin-top: 12px; }

/* v96 逐批结算：每个销售明细一张卡片，各自填扣重 / 扣价 */
.receipt-item-list { display: grid; gap: 10px; }
.receipt-item-row {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--surface);
  padding: 11px 12px;
}
.receipt-item-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.receipt-item-head .ri-product { font-size: 14px; font-weight: 650; color: var(--ink); }
.receipt-item-head .ri-sku { font-size: 11px; color: var(--muted); }
.receipt-item-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
.receipt-item-grid .form-field { min-width: 0; }
.receipt-item-grid .form-field input { text-align: right; font-variant-numeric: tabular-nums; }
.receipt-item-row .ri-result {
  margin: 10px 0 0;
  padding: 7px 10px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-control);
  background: var(--surface-soft);
  color: var(--muted);
  font-size: var(--mini);
  line-height: 1.6;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.receipt-item-row .ri-result b { color: var(--ink); }

.settlement-total {
  margin-top: 12px;
  padding-top: 11px;
  border-top: 1px solid var(--line);
  display: grid;
  gap: 8px;
}
.settlement-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; min-width: 0; }
.settlement-row span { color: var(--muted); font-size: 11px; white-space: nowrap; }
.settlement-row strong { font-size: 14px; overflow-wrap: anywhere; text-align: right; font-variant-numeric: tabular-nums; }
.settlement-diff-row { padding: 8px 10px; border-radius: var(--radius-control); background: var(--accent-soft); }
.settlement-diff-row span { font-weight: 700; }
.settlement-diff-row.is-less { background: var(--red-soft); }
.settlement-diff-row.is-less span, .settlement-diff-row.is-less strong { color: var(--red-ink); }
.settlement-diff-row.is-more { background: var(--accent-tile); }
.settlement-diff-row.is-more span, .settlement-diff-row.is-more strong { color: var(--accent-on); }

/* 销售单详情里的结算明细 */
.settlement-detail { margin-top: 10px; display: grid; gap: 7px; }
.settlement-detail .settlement-detail-line { margin: 0; color: var(--muted); font-size: 11px; line-height: 1.65; overflow-wrap: anywhere; }
.settlement-detail .settlement-detail-line b { color: var(--ink); font-variant-numeric: tabular-nums; }
.settlement-detail .settlement-row { padding-top: 6px; border-top: 1px dashed var(--line); }
.settlement-detail .settlement-diff-row { border-top: 0; padding-top: 8px; }

/* 顶部「销售金额」下面的小字：有扣减才出现，做成一枚能一眼看见的标签 */
.settlement-stat-note {
  display: block;
  margin-top: 5px;
  padding: 3px 6px;
  border-radius: var(--radius-pill);
  font-size: 10px;
  line-height: 1.45;
  color: var(--muted);
  background: var(--surface);
  overflow-wrap: anywhere;
}
.settlement-stat-note.is-less { color: var(--red-ink); background: var(--red-soft); }
.settlement-stat-note.is-more { color: var(--accent-on); background: var(--accent-tile); }

/* 手机端：四个输入框挤一行会太窄，改成两列；触控目标按项目惯例拉到 44px */
@media (max-width: 1199.98px) {
  .settlement-block { padding: 12px 13px; }
  .settlement-grid, .settlement-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .receipt-item-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }
  .settlement-block input { min-height: 44px; }
  .settlement-row strong { font-size: 15px; }
  .settlement-stat-note { font-size: 11px; }
}
html.force-mobile .settlement-block { padding: 12px 13px; }
html.force-mobile .settlement-grid,
html.force-mobile .settlement-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
html.force-mobile .receipt-item-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }
html.force-mobile .settlement-block input { min-height: 44px; }
html.force-mobile .settlement-row strong { font-size: 15px; }
html.force-mobile .settlement-stat-note { font-size: 11px; }
/* ==================== 二十六、附件图片预览 ====================
   图片原图存 IndexedDB，state 里只有 attachId；这里只负责缩略图和全屏预览层的观感。
   层级：底栏 4 < 弹窗遮罩 10 < **预览浮层 30** < 整屏登录页 20（登录页仍在其上） < toast 60 */
.attach-item { display: inline-flex; align-items: center; gap: 8px; max-width: 100%; }
.attach-item.is-legacy { flex-wrap: wrap; gap: 4px; color: var(--muted); }
.attach-item.is-image { cursor: pointer; min-height: 44px; padding: 2px 6px 2px 2px; border-radius: var(--radius-control); -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
.attach-item.is-image:active { background: var(--accent-soft); }
.attach-thumb { flex: none; width: 44px; height: 44px; border-radius: var(--radius-control); overflow: hidden; border: 1px solid var(--line); background: var(--surface-soft); display: inline-flex; align-items: center; justify-content: center; font-size: 10px; color: var(--muted); }
.attach-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.attach-pdf-badge { font-weight: 600; font-size: 10px; letter-spacing: .5px; color: #b03a2e; }
.attach-thumb[data-state='loading']::after { content: ''; width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--line); border-top-color: var(--muted); }
.attach-name { font-size: var(--mini); color: var(--ink); overflow-wrap: anywhere; }
.attach-note { font-size: var(--mini); color: var(--muted); }
.attach-item.is-legacy .attach-name { color: var(--muted); }
.attach-inline { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.receipt-detail-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 4px 0; }
.receipt-detail-type { font-size: var(--mini); color: var(--muted); flex: none; }
.portal-attach, .supplier-verify-file { display: block; margin-top: 6px; }

.image-preview-layer { position: fixed; inset: 0; z-index: 30; background: var(--accent-deep); display: flex; flex-direction: column; }
.image-preview-bar { flex: none; display: flex; align-items: center; gap: 12px; padding: 8px 12px; background: var(--accent-deep); border-bottom: 1px solid var(--line); }
.image-preview-name { flex: 1 1 auto; min-width: 0; font-size: var(--mini); color: var(--surface); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.image-preview-close { flex: none; width: 44px; height: 44px; border: 0; border-radius: var(--radius-control); background: var(--accent-soft); color: var(--ink); font-size: 20px; line-height: 1; cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation; user-select: none; }
.image-preview-close:active { transform: scale(.97); background: var(--line); }
/* v127：预览层右上角「下载」按钮 */
.image-preview-download { flex: none; height: 44px; padding: 0 14px; display: inline-flex; align-items: center; gap: 4px; border: 0; border-radius: var(--radius-control); background: var(--accent-soft); color: var(--ink); font-size: var(--mini); font-family: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation; user-select: none; }
.image-preview-download:active { transform: scale(.97); background: var(--line); }
.image-preview-dl-icon { font-size: 16px; line-height: 1; }
.image-preview-stage { flex: 1 1 auto; min-height: 0; display: flex; align-items: center; justify-content: center; padding: 12px; }
.image-preview-img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; border-radius: var(--radius-control); background: var(--surface); }
/* v126：PDF 预览 —— 页面内渲染成图，可上下滚动，不跳窗不下载 */
.image-preview-layer.is-pdf .image-preview-stage { flex-direction: column; align-items: center; justify-content: flex-start; overflow: auto; -webkit-overflow-scrolling: touch; padding: 10px; }
.pdf-page-canvas { width: 100%; max-width: 900px; height: auto; display: block; margin: 0 auto 10px; background: #fff; border-radius: 4px; box-shadow: 0 1px 4px rgba(0, 0, 0, .25); }
.pdf-page-canvas:last-child { margin-bottom: 0; }
.pdf-loading { color: var(--surface); font-size: var(--mini); padding: 24px 0; text-align: center; }
.image-preview-frame { flex: 1 1 auto; width: 100%; height: 100%; border: 0; background: var(--surface); }

/* 手机端：关闭按钮热区按项目惯例拉到 44px，文件名允许折行 */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  .attach-item.is-image { min-height: 48px; }
  .attach-name { font-size: var(--mini); }
  .image-preview-bar { padding: 6px 10px; }
  .image-preview-name { white-space: normal; overflow-wrap: anywhere; font-size: 13px; }
  .image-preview-stage { padding: 8px; }
}
html.force-mobile .attach-item.is-image { min-height: 48px; }
html.force-mobile .attach-name { font-size: var(--mini); }
html.force-mobile .image-preview-bar { padding: 6px 10px; }
html.force-mobile .image-preview-name { white-space: normal; overflow-wrap: anywhere; font-size: 13px; }
html.force-mobile .image-preview-stage { padding: 8px; }

@media (prefers-reduced-motion: reduce) {
  .image-preview-close:active { transform: none; }
}

/* ============================================================
   二十七、采购明细 · 手机版品名与等级同行
   老板反馈：手机上「品名」自己占一整行太占地方，要和「等级」并排。
   做法：手机端把明细表改成 10 列细网格 ——
     第 1 行：品名 6 格 + 等级 2 格 + 删除键 2 格
     第 2 行：件数 3 + 单件重量 3 + 尾件 4
     第 3 行：采购单价 3 + 重量 3 + 金额 4
   ------------------------------------------------------------
   v67 重做（老板原话：「排版布局重新做下，必要表格边框不要重叠」）：
   1) 手机端 tr / td 已被改成 display:grid，border-collapse 根本不生效 ——
      每个输入框的 1px 边框都是各自独立的一条线。base 层 styles.css 给 tr 写的
      padding 是「10px 32px 10px 0」，左内边距为 0，行首输入框的左边框离
      .item-table-wrap 的外框线只差 1px，看上去像焊在一起（红线：不能改 base）。
      这里在皮肤层把左右内边距都补成 12px，每条线都留出呼吸。
   2) 删除键原来是 position:absolute; right:0，圆形钮右缘正好压在外框内边线上。
      改成占第 1 行最后两格的普通网格单元（不再绝对定位），纵向贴底对齐，
      跟品名 / 等级的输入框同一条基线，也不会再压线。
   3) 第 2、3 行的竖（列间）缝统一落在 3|4 与 6|7 两处，不再各自为政。
   4) 重量 / 金额是 <output>，原来裸奔（无边框、11px），跟 15px 的输入框基线不齐。
      这里给它和输入框同一套边框、同一字号（15px）、同一高度（44px）。
   其它字段仍是三个一行，不改成两列（手机上两个数字框太挤）。
   只作用于 .purchase-item-editor（新建/编辑采购入库弹窗的明细表），
   销售明细等其它 .item-editor 表格不受影响。
   ============================================================ */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  .purchase-item-editor tbody tr {
    grid-template-columns: repeat(10, minmax(0, 1fr));
    gap: 8px 5px;
    padding: 10px 12px 12px;          /* 左右都留边：输入框边框不再贴着外框线 */
  }
  .purchase-item-editor tbody td:nth-child(1) { grid-column: 1 / span 6; grid-row: 1; }   /* 品名 */
  .purchase-item-editor tbody td:nth-child(2) { grid-column: 7 / span 2; grid-row: 1; }   /* 等级 */
  .purchase-item-editor tbody td:nth-child(3) { grid-column: 1 / span 3; grid-row: 2; }   /* 件数 */
  .purchase-item-editor tbody td:nth-child(4) { grid-column: 4 / span 3; grid-row: 2; }   /* 单件重量 */
  .purchase-item-editor tbody td:nth-child(5) { grid-column: 7 / span 4; grid-row: 2; }   /* 尾件 */
  .purchase-item-editor tbody td:nth-child(6) { grid-column: 1 / span 3; grid-row: 3; }   /* 采购单价 */
  .purchase-item-editor tbody td:nth-child(7) { grid-column: 4 / span 3; grid-row: 3; }   /* 重量 */
  .purchase-item-editor tbody td:nth-child(8) { grid-column: 7 / span 4; grid-row: 3; position: static; }  /* 金额 */
  /* 删除键：第 1 行最后两格、贴底对齐；::before 是空标签会顶高一行，直接去掉 */
  .purchase-item-editor tbody td:nth-child(9) { grid-column: 9 / span 2; grid-row: 1; position: static; align-content: end; justify-items: center; padding: 0; }
  .purchase-item-editor tbody td:nth-child(9)::before { display: none; }

  /* 所有字段：标签压成小字贴在各自框正上方，同一条水平线、等高。
     text-align:left 是必要的：电脑版列宽那段给第 7/8 列（重量/金额）写了 text-align:right，
     会被 ::before 标签继承，导致标签跑到框的右边去。 */
  .purchase-item-editor tbody td { align-content: start; }
  .purchase-item-editor tbody td::before { font-size: 10px; line-height: 1.1; white-space: nowrap; text-align: left; }
  .purchase-item-editor tbody td > input { min-height: 44px; font-size: 15px; }

  /* 重量 / 金额：跟输入框同一套边框、同一字号、同一高度，数字右对齐 */
  .purchase-item-editor tbody td > output {
    display: flex; align-items: center; justify-content: flex-end;
    min-height: 44px; padding: 7px 8px;
    border: 1px solid var(--line); border-radius: 6px;
    background: var(--surface-soft);
    font-size: 15px; font-weight: 700; white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis;
  }

  /* 窄屏（360px）不横向溢出 */
  .purchase-item-editor tbody td > input,
  .purchase-item-editor tbody td > output { min-width: 0; max-width: 100%; }
}

/* 电脑上手动切手机版（html.force-mobile）不命中上面的媒体查询，同步一份 */
html.force-mobile .purchase-item-editor tbody tr {
  grid-template-columns: repeat(10, minmax(0, 1fr));
  gap: 8px 5px;
  padding: 10px 12px 12px;
}
html.force-mobile .purchase-item-editor tbody td:nth-child(1) { grid-column: 1 / span 6; grid-row: 1; }
html.force-mobile .purchase-item-editor tbody td:nth-child(2) { grid-column: 7 / span 2; grid-row: 1; }
html.force-mobile .purchase-item-editor tbody td:nth-child(3) { grid-column: 1 / span 3; grid-row: 2; }
html.force-mobile .purchase-item-editor tbody td:nth-child(4) { grid-column: 4 / span 3; grid-row: 2; }
html.force-mobile .purchase-item-editor tbody td:nth-child(5) { grid-column: 7 / span 4; grid-row: 2; }
html.force-mobile .purchase-item-editor tbody td:nth-child(6) { grid-column: 1 / span 3; grid-row: 3; }
html.force-mobile .purchase-item-editor tbody td:nth-child(7) { grid-column: 4 / span 3; grid-row: 3; }
html.force-mobile .purchase-item-editor tbody td:nth-child(8) { grid-column: 7 / span 4; grid-row: 3; position: static; }
/* 删除键不再 absolute（同二十七的说明）：宽屏 + force-mobile 时表格仍是普通 <table>，
   grid-column 不生效，删除键就老老实实待在最后一格，不会甩到表格右上角。 */
html.force-mobile .purchase-item-editor tbody td:nth-child(9) { grid-column: 9 / span 2; grid-row: 1; position: static; align-content: end; justify-items: center; padding: 0; }
html.force-mobile .purchase-item-editor tbody td:nth-child(9)::before { display: none; }
html.force-mobile .purchase-item-editor tbody td { align-content: start; }
html.force-mobile .purchase-item-editor tbody td::before { font-size: 10px; line-height: 1.1; white-space: nowrap; text-align: left; }
html.force-mobile .purchase-item-editor tbody td > input { min-height: 44px; font-size: 15px; }
html.force-mobile .purchase-item-editor tbody td > output {
  display: flex; align-items: center; justify-content: flex-end;
  min-height: 44px; padding: 7px 8px;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--surface-soft);
  font-size: 15px; font-weight: 700; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
html.force-mobile .purchase-item-editor tbody td > input,
html.force-mobile .purchase-item-editor tbody td > output { min-width: 0; max-width: 100%; }

/* ============================================================
   二十八、底栏五板块 / 管理中心 / 返回按钮 v53
   ------------------------------------------------------------
   1) 底栏（含抽屉）只列 5 个板块：概览 / 采购仓库 / 精制加工 / 销售清单 / 管理中心。
      资金流水、客户管理、供应商管理、账号与授权降为 secondary —— 抽屉里不再出现，
      只在电脑版侧栏和「管理中心」页里进得去。
   2) 抽屉里不列当前所在板块（.is-current-board 由 app.js 打在对应的 primary 按钮上）。
      5 个藏 1 个 = 剩 4 个，用 flex-wrap 排 2 列，最后一个不会甩出空洞。
   3) 每个页面左上角一个「← 返回」（.back-button），回上一个看过的页面。
   配色只用现有变量；层级链不变：遮罩 3 < 底栏 4 < 弹窗 10 < 登录页 20 < 预览 30 < toast 60。
   ============================================================ */

/* ---------- ① 返回按钮 ---------- */
.back-button {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto; order: -1;
  min-height: 44px; padding: 0 14px;          /* 触控目标 ≥44px */
  border: 1px solid var(--line); border-radius: var(--radius-control);
  background: var(--surface-soft); color: var(--ink);
  font-family: inherit; font-size: 14px; font-weight: 600;
  cursor: pointer;
}
.back-button:hover { background: var(--accent-tile); color: var(--accent-deep); }
/* hidden 要压得住上面的 display:inline-flex，否则按钮一直杵在那儿 */
.back-button[hidden] { display: none !important; }
.topbar > .back-button + div { flex: 1 1 auto; min-width: 0; }

/* ---------- ② 管理中心：4 张卡片复用 .stat-card（改成 button 后复位字体/对齐） ---------- */
button.stat-card {
  display: block; width: 100%; min-height: 44px;
  font-family: inherit; font-size: inherit; text-align: left;
  color: var(--ink); cursor: pointer;
}
button.stat-card:hover { border-color: var(--accent-bright); background: var(--accent-tile); }
button.stat-card:hover .stat-label,
button.stat-card:hover .stat-meta { color: var(--accent-deep); }
.management-grid { gap: 15px; }

/* ---------- ③ 手机版 ---------- */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {

  /* 首页顶栏被隐藏（body[data-current-view="dashboard"] .topbar{display:none}），
     返回按钮跟着进简版标题栏，排在最左、头像之前 */
  .mobile-dashboard-header > .back-button {
    flex: 0 0 auto; min-height: 44px; padding: 0 12px; margin-right: 2px;
    font-size: 15px;
  }
  .mobile-dashboard-header > h2 { flex: 1 1 auto; min-width: 0; }

  /* 管理中心：手机上一律 2 列，别被 6 列 / span 规则拆乱 */
  .management-grid {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 12px;
  }
  .management-grid > .stat-card { grid-column: auto !important; min-height: 96px; padding: 14px; }

  /* 抽屉：只列 5 个 primary，且不列当前所在板块 */
  html .sidebar.nav-expanded > .nav-list { display: flex !important; flex-wrap: wrap; }
  html .sidebar.nav-expanded > .nav-list .nav-item { flex: 1 1 calc(50% - 4px); max-width: 100%; }  /* gap 8px */
  html .sidebar.nav-expanded > .nav-list .nav-item[data-nav-tier="secondary"] { display: none !important; }
  html .sidebar.nav-expanded > .nav-list .nav-item.is-current-board { display: none !important; }
}
/* 同套规则绑到 html.force-mobile */
html.force-mobile .mobile-dashboard-header > .back-button {
  flex: 0 0 auto; min-height: 44px; padding: 0 12px; margin-right: 2px;
  font-size: 15px;
}
html.force-mobile .mobile-dashboard-header > h2 { flex: 1 1 auto; min-width: 0; }
html.force-mobile .management-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  gap: 12px;
}
html.force-mobile .management-grid > .stat-card { grid-column: auto !important; min-height: 96px; padding: 14px; }
html.force-mobile .sidebar.nav-expanded > .nav-list { display: flex !important; flex-wrap: wrap; }
html.force-mobile .sidebar.nav-expanded > .nav-list .nav-item { flex: 1 1 calc(50% - 4px); max-width: 100%; }
html.force-mobile .sidebar.nav-expanded > .nav-list .nav-item[data-nav-tier="secondary"] { display: none !important; }
html.force-mobile .sidebar.nav-expanded > .nav-list .nav-item.is-current-board { display: none !important; }

/* ============================================================
   二十九、装车并入采购仓库 / 采购明细表格 v54
   ------------------------------------------------------------
   1) 采购明细表格重新分配列宽：品名最宽（主信息），等级和单件重量中等，
      件数 / 尾件 / 单价收窄，重量和金额右对齐、不被长数字挤歪，
      删除键只留一条窄列。
   2) 删除键改成贴在行最右侧的「×」小圆钮，不再占一整格；
      明细只剩一行时整格隐藏（不能把最后一行也删掉）—— 由
      app.js 的 syncPurchaseItemRemoveButtons 打 hidden 属性。
   3) 采购仓库里新增「已装车 / 在途」区块（#warehousePackingBoard）。
   4) 工具栏里的「显示已结清」开关（#warehouseClosedSlot）排版。
   配色只用现有变量；断点统一 1200；触控目标 ≥ 44px。
   ============================================================ */

/* ---------- ① 采购明细 · 电脑版列宽（9 列，合计 100%） ---------- */
.purchase-item-editor th:nth-child(1) { width: 22%; }   /* 品名：最宽 */
.purchase-item-editor th:nth-child(2) { width: 11%; }   /* 等级 */
.purchase-item-editor th:nth-child(3) { width: 8%; }    /* 件数 */
.purchase-item-editor th:nth-child(4) { width: 11%; }   /* 单件重量 */
.purchase-item-editor th:nth-child(5) { width: 8%; }    /* 尾件 */
.purchase-item-editor th:nth-child(6) { width: 12%; }   /* 采购单价 */
.purchase-item-editor th:nth-child(7) { width: 9%; }    /* 重量（右对齐） */
.purchase-item-editor th:nth-child(8) { width: 13%; }   /* 金额（右对齐） */
.purchase-item-editor th:nth-child(9) { width: 6%; }    /* 删除：只留一条窄列 */

/* 重量 / 金额右对齐，长数字不挤歪表格 */
.purchase-item-editor th:nth-child(7),
.purchase-item-editor td:nth-child(7),
.purchase-item-editor th:nth-child(8),
.purchase-item-editor td:nth-child(8) { text-align: right; }
.purchase-item-editor td:nth-child(7) output,
.purchase-item-editor td:nth-child(8) output { text-align: right; white-space: nowrap; }

/* ---------- ② 删除键：行内最右侧的「×」小圆钮 ---------- */
.purchase-item-editor td.purchase-item-remove { padding: 0 2px; text-align: center; vertical-align: middle; }
.purchase-item-editor .purchase-item-remove-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; min-height: 28px; padding: 0;
  border: 1px solid var(--line); border-radius: 50%;
  background: var(--surface-soft); color: var(--red-ink);
  font-size: 15px; line-height: 1; cursor: pointer;
}
.purchase-item-editor .purchase-item-remove-btn:hover { border-color: var(--accent-bright); background: var(--accent-tile); }
/* 只剩一行时整格藏掉（手机端 td 被改成 grid，[hidden] 压不住 display，需要 !important） */
.purchase-item-editor td.purchase-item-remove[hidden] { display: none !important; }

/* ---------- ③ 采购仓库 · 已装车 / 在途 ---------- */
.warehouse-packing-block { margin-top: 15px; padding-top: 13px; border-top: 1px solid var(--line); }
.warehouse-packing-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 11px; }
.warehouse-packing-head strong { font-size: 14px; color: var(--ink); }
.warehouse-packing-head span { font-size: 12px; color: var(--muted); }
.warehouse-packing-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 10px; }
.warehouse-packing-card {
  display: grid; gap: 6px; width: 100%;
  padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-control);
  background: var(--surface); color: var(--ink);
  font-family: inherit; font-size: 13px; text-align: left; cursor: pointer;
}
.warehouse-packing-card:hover { border-color: var(--accent-bright); background: var(--accent-tile); }
.warehouse-packing-card:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.wpc-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.warehouse-packing-card h4 { margin: 0; font-size: 14px; color: var(--ink); }
.wpc-meta { margin: 0; font-size: 12px; color: var(--muted); }
.wpc-numbers { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; padding: 8px 0; border-top: 1px dashed var(--line); border-bottom: 1px dashed var(--line); }
.wpc-numbers small { display: block; font-size: 11px; color: var(--muted); }
.wpc-numbers strong { font-size: 14px; color: var(--ink); }
.wpc-sources { display: grid; gap: 5px; }
.wpc-sources-label { font-size: 11px; color: var(--muted); }
.wpc-source { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; font-size: 12px; color: var(--ink); }
.wpc-source span { color: var(--muted); white-space: nowrap; }
.wpc-cta { font-size: 12px; font-weight: 600; color: var(--accent); }

/* ---------- ④ 工具栏里的「显示已结清」开关 ---------- */
.toolbar-closed-slot { display: inline-flex; align-items: center; flex: 0 0 auto; }
#warehouseView .toolbar-actions { flex-wrap: wrap; align-items: center; }

/* ---------- ⑤ 手机版（两份：媒体查询 + html.force-mobile） ---------- */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  /* v67：行盒内边距、删除键定位、output 边框统一由第二十七段负责，这里只保留
     第三行的列宽分配（采购单价 3 / 重量 3 / 金额 4）—— 跟第二行的竖缝落在同一列，
     金额是最长的数字，给它 4 格。 */
  .purchase-item-editor tbody td:nth-child(6) { grid-column: 1 / span 3; grid-row: 3; }  /* 采购单价 */
  .purchase-item-editor tbody td:nth-child(7) { grid-column: 4 / span 3; grid-row: 3; }  /* 重量 */
  .purchase-item-editor tbody td:nth-child(8) { grid-column: 7 / span 4; grid-row: 3; position: static; }  /* 金额 */

  /* 删除键：44px 触控目标（定位在第二十七段，这里只管大小） */
  .purchase-item-editor .purchase-item-remove-btn { width: 44px; height: 44px; min-height: 44px; font-size: 19px; }

  /* 已装车 / 在途 */
  .warehouse-packing-grid { grid-template-columns: repeat(1, minmax(0, 1fr)); }
  .warehouse-packing-card { min-height: 44px; padding: 13px; }

  /* 工具栏：「显示已结清」独占一行更好点 */
  #warehouseView .toolbar-actions { width: 100%; }
  .toolbar-closed-slot { flex: 1 1 100%; }
  .toolbar-closed-slot .closed-filter-toggle { width: 100%; min-height: 44px; justify-content: center; }
}

html.force-mobile .purchase-item-editor tbody td:nth-child(6) { grid-column: 1 / span 3; grid-row: 3; }
html.force-mobile .purchase-item-editor tbody td:nth-child(7) { grid-column: 4 / span 3; grid-row: 3; }
html.force-mobile .purchase-item-editor tbody td:nth-child(8) { grid-column: 7 / span 4; grid-row: 3; position: static; }
/* 同二十七的取舍：宽屏 + force-mobile 时表格仍是普通 <table>，
   这里不写 td:nth-child(9) 的 absolute，窄屏由上面那条媒体查询负责。 */
html.force-mobile .purchase-item-editor .purchase-item-remove-btn { width: 44px; height: 44px; min-height: 44px; font-size: 19px; }
html.force-mobile .warehouse-packing-grid { grid-template-columns: repeat(1, minmax(0, 1fr)); }
html.force-mobile .warehouse-packing-card { min-height: 44px; padding: 13px; }
html.force-mobile #warehouseView .toolbar-actions { width: 100%; }
html.force-mobile .toolbar-closed-slot { flex: 1 1 100%; }
html.force-mobile .toolbar-closed-slot .closed-filter-toggle { width: 100%; min-height: 44px; justify-content: center; }

/* ============================================================
   三十、精制加工 · 待加工批次与装卸费
   ------------------------------------------------------------
   1) 精制加工板块顶部新增「待加工批次货物」：还没精制完的装车单
      一张一卡，点一下直接开加工单弹窗（容器由 workflow.js 动态创建，
      index.html 不动）。
   2) 下面「精制仓 · 待售成品」标题（#processingFinishedHead）。
   3) 加工单卡片上的「可售 X 斤 / 已售完」标记（.processing-available-flag），
      要一眼看到还剩多少能卖。
   配色只用现有变量；断点统一 1200；触控目标 ≥ 44px。
   ============================================================ */

/* ---------- ① 待加工批次货物 ---------- */
.pending-process-block { padding-top: 13px; border-top: 1px solid var(--line); }
.pending-process-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 11px; }
.pending-process-head strong { font-size: 14px; color: var(--ink); }
.pending-process-head span { font-size: 12px; color: var(--muted); }
.pending-process-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 10px; }
.pending-process-card {
  display: grid; gap: 6px; width: 100%;
  padding: 12px; border: 1px solid var(--accent-bright); border-radius: var(--radius-control);
  background: var(--surface); color: var(--ink);
  font-family: inherit; font-size: 13px; text-align: left; cursor: pointer;
}
.pending-process-card:hover { background: var(--accent-tile); }
.pending-process-card:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.pending-process-card:active { transform: scale(.995); }
.pp-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.pending-process-card h4 { margin: 0; font-size: 14px; color: var(--ink); }
.pp-meta { margin: 0; font-size: 12px; color: var(--muted); }
.pp-numbers {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px;
  padding: 8px 0; border-top: 1px dashed var(--line); border-bottom: 1px dashed var(--line);
}
.pp-numbers small { display: block; font-size: 11px; color: var(--muted); }
.pp-numbers strong { font-size: 14px; color: var(--ink); }
.pp-numbers em { font-style: normal; font-size: 11px; color: var(--muted); }
/* 还可投多少是这张卡的主信息：用主色加重（--accent 深/浅两套都跟底色够对比） */
.pp-left { color: var(--accent); font-weight: 700; }
.pp-dest { margin: 0; font-size: 12px; color: var(--muted); }
.pp-cta { font-size: 12px; font-weight: 600; color: var(--accent); }

/* ---------- ② 精制仓 · 待售成品 标题 ---------- */
.processing-block-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  margin: 15px 0 11px; padding-top: 13px; border-top: 1px solid var(--line);
}
.processing-block-head strong { font-size: 14px; color: var(--ink); }
.processing-block-head span { font-size: 12px; color: var(--muted); }

/* ---------- ③ 加工单卡片上的可售标记 ---------- */
.processing-available-flag {
  margin: 4px 0 0; display: inline-block; padding: 3px 9px;
  border: 1px solid var(--accent-bright); border-radius: 999px;
  background: var(--accent-tile); color: var(--accent);
  font-size: 12px; font-weight: 700; line-height: 1.4;
}
.processing-available-flag.sold-out { border-color: var(--line); background: var(--surface-soft); color: var(--muted); }

/* ---------- ④ 手机版（两份：媒体查询 + html.force-mobile） ---------- */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  .pending-process-grid { grid-template-columns: repeat(1, minmax(0, 1fr)); }
  .pending-process-card { min-height: 44px; padding: 13px; }
  .pp-cta { min-height: 44px; display: flex; align-items: center; }
  .processing-block-head { margin-top: 13px; }
  .processing-available-flag { min-height: 26px; font-size: 13px; padding: 4px 11px; }
}

html.force-mobile .pending-process-grid { grid-template-columns: repeat(1, minmax(0, 1fr)); }
html.force-mobile .pending-process-card { min-height: 44px; padding: 13px; }
html.force-mobile .pp-cta { min-height: 44px; display: flex; align-items: center; }
html.force-mobile .processing-block-head { margin-top: 13px; }
html.force-mobile .processing-available-flag { min-height: 26px; font-size: 13px; padding: 4px 11px; }

/* ============================================================
   三十一、采购仓库 · 新建采购入库与供应商填报链接竖排
   ------------------------------------------------------------
   背景：「供应商填报链接」按钮从【管理中心 / 供应商管理】页挪到
   【采购仓库】页，竖排放在「+ 新建采购入库」按钮下面（DOM 里紧跟其后），
   所以给它包一层 .toolbar-primary-stack 竖排容器。
   要点：
   1) 竖排容器内部两个按钮 width: 100%，避免竖排后宽度抖动。
   2) 桌面端：容器作为横向 flex 的一项，和「品名管理」「显示已结清」
      并列；工具栏 align-items: center，高度不齐也不歪。
   3) 手机端：容器 flex-basis: 100% 独占一行，两个按钮上下叠着、都可点满宽。
   配色沿用 .primary-button / .secondary-button 现有样式，不新造颜色。
   断点统一 1200；手机规则写两份（媒体查询 + html.force-mobile）。
   ============================================================ */

/* ---------- ① 竖排容器（桌面端） ---------- */
.toolbar-primary-stack {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  flex: 0 0 auto;
}
.toolbar-primary-stack > button { width: 100%; }
/* 工具栏横向 flex：竖排块变高后，「品名管理」和「显示已结清」居中对齐、不被挤掉。
   这里只覆盖采购仓库这一处工具栏，其它板块保持原样。 */
#warehouseView .toolbar-actions { flex-wrap: wrap; align-items: center; gap: 9px; }

/* ---------- ② 手机版（媒体查询） ---------- */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  /* 竖排块独占一行，两个按钮上下叠着、都可点满宽 */
  .toolbar-primary-stack { flex: 1 1 100%; width: 100%; }
  .toolbar-primary-stack > button {
    width: 100%; min-width: 0; flex: 0 0 auto;
    min-height: 44px;   /* 触控目标 */
  }
  /* 兜底：换行后「品名管理」「显示已结清」仍在同一行内分，不溢出容器 */
  #warehouseView .toolbar-actions { flex-wrap: wrap; align-items: center; gap: 8px; }
}

/* ---------- ③ 手机版（html.force-mobile 前缀，同步一份） ---------- */
html.force-mobile .toolbar-primary-stack { flex: 1 1 100%; width: 100%; }
html.force-mobile .toolbar-primary-stack > button {
  width: 100%; min-width: 0; flex: 0 0 auto;
  min-height: 44px;
}
html.force-mobile #warehouseView .toolbar-actions { flex-wrap: wrap; align-items: center; gap: 8px; }

/* ============================================================
   三十二、精制加工 v57 · 品种行七列 / 单据识别审核区 / 加工单批量添加
   ------------------------------------------------------------
   背景：加工单品种行由 4 列扩到 7 列（品名 / 件数 / 单件重量 / 尾件 /
   产出重量 / SKU / 删除），第二十二段那套 grid（minmax(160px,1fr) 152px
   136px 40px）已经对不上号。这里在文件末尾整段重写 —— 同特异性、写在后面，
   按层叠顺序覆盖旧规则，不去动第二十二段，也不动第三十一段。
   要点：
   1) 桌面用 flex 一行排开；产出重量 = 件数 × 单件重量 ＋ 尾件，是算出来的，
      给它浅底 + 左侧翡翠竖条，让老板一眼看出「这个框不用填」。
   2) 手机换行成两列：品名整行 → 件数/质量 → 尾件/重量 → SKU＋删除键。
   3) 单据识别审核区 .process-doc-* 用 .form-section 同款发丝线卡片；
      合计（#processDocTotal）是跟照片底部对账的关键数字 → 加粗 + 主色。
   4) 加工单弹窗加宽到 980px，7 列才排得开、不出横向滚动条。
   配色全部沿用现有令牌，不新造颜色；断点统一 1200；手机规则写两份
   （媒体查询 + html.force-mobile）；触控目标 ≥ 44px。
   ============================================================ */

/* ---------- ① 品种行：桌面一行排开 ---------- */
.processing-output-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px; }
.processing-output-row .processing-cell { flex: 0 1 auto; min-width: 0; }
.processing-output-row .name-cell    { flex: 1 1 24%; }
.processing-output-row .pieces-cell  { flex: 1 1 11%; }
.processing-output-row .quality-cell { flex: 1 1 12%; }
.processing-output-row .tail-cell    { flex: 1 1 11%; }
.processing-output-row .weight-cell  { flex: 1 1 13%; }
.processing-output-row .sku-cell     { flex: 1 1 13%; }
.processing-output-row .processing-row-remove { flex: 0 0 40px; width: 40px; }
/* 产出重量是算出来的：浅底 + 左侧翡翠竖条，跟前面三个「要填的」框区分开 */
.processing-output-row .weight-cell input,
.process-doc-table .process-doc-weight {
  background: var(--canvas);
  border-left: 3px solid var(--accent-bright);
}
/* 行内公式小字：独占一行 */
.processing-output-row .processing-row-formula {
  flex: 0 0 100%; margin: 1px 0 0;
  font-size: 12px; color: var(--muted);
}

/* ---------- ② 单据识别审核区 ---------- */
.process-doc-review {
  margin: 11px 0 12px; padding: 12px;
  border: 1px solid var(--line); border-radius: var(--radius-card);
  background: var(--surface-soft);
}
.process-doc-head { display: flex; align-items: flex-start; gap: 12px; }
.process-doc-thumb, .process-doc-thumb-empty {
  flex: 0 0 88px; width: 88px; height: 88px;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--canvas); object-fit: cover; cursor: zoom-in;
}
.process-doc-thumb-empty {
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; color: var(--muted); cursor: default;
}
.process-doc-meta { display: grid; gap: 2px; min-width: 0; }
.process-doc-meta strong { font-size: 13px; color: var(--ink); overflow-wrap: anywhere; }
.process-doc-meta small { font-size: 12px; color: var(--muted); }
.process-doc-table { width: 100%; margin: 10px 0 0; border-collapse: collapse; }
.process-doc-table th {
  padding: 4px 6px; text-align: left;
  font-size: 12px; font-weight: 600; color: var(--muted);
  border-bottom: 1px solid var(--line);
}
.process-doc-table td { padding: 4px 6px; vertical-align: top; }
.process-doc-table input { width: 100%; min-width: 0; }
/* 合计：跟照片最下面那行数字对账用的，必须醒目（主色 + 加粗 + 等宽数字） */
#processDocTotal, .process-doc-total {
  padding: 8px 10px;
  background: var(--accent-tile); border-radius: var(--radius-control);
  color: var(--accent); font-size: 13px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.process-doc-actions {
  display: flex; justify-content: flex-end; align-items: center;
  flex-wrap: wrap; gap: 8px; margin-top: 10px;
}

/* ---------- ③ 加工单弹窗加宽（7 列才排得开） ---------- */
@media (min-width: 1200px) {
  .modal.modal-processing-wide { width: min(980px, 100%); }
}

/* ---------- ③b 新建/编辑销售单弹窗加宽（v100） ----------
   销售明细卡片里的「件数 / 单件重量 / 尾件 / 单价」四列在 680px 下挤不下，
   标签（如「单件重量（斤 / 件）」）折行把卡片撑高，整张表单要上下拉。
   加宽到 980px 后四列并排、标签不折行；同时把 max-height 放开到整个视口高度，
   一屏能看完，尽量不产生内部滚动。 */
@media (min-width: 1200px) {
  .modal.modal-sale-wide { width: min(980px, 100%); max-height: calc(100vh - 32px); }
}

/* ---------- ④ 销售明细卡片里新加的那行小字 ---------- */
.item-card-hint {
  margin: 8px 0 0; font-size: 12px; line-height: 1.55;
  color: var(--muted); overflow-wrap: anywhere; word-break: break-word;
}

/* ---------- ④b 深色模式补一条：销售明细卡片的底色 ----------
   base 层 styles.css 把 .sale-item-card 的底色写死成浅色 #fcfdfc，没有深色覆盖。
   深色模式下卡片里的字（--ink 是浅色）压在白底上，对比度只有 1.76 ——
   本次新增的 .item-card-hint 也跟着不可读。这里只在 minimal 层补底色，不动 base 层。 */
/* v78：老板决定不保留深色模式，整块停用（内容保留，恢复时把 and (min-width: 999999px) 删掉即可） */
@media (prefers-color-scheme: dark) and (min-width: 999999px) {
  .sale-item-card { background: var(--surface-soft); }
}

/* ---------- ⑤ 加工单选择弹窗里的条目（沿用 .linked-record 观感） ---------- */
.linked-record.processing-pick-item { grid-template-columns: 1fr; gap: 2px; min-height: 44px; }
.linked-record.processing-pick-item strong { font-size: 13px; }
.linked-record.processing-pick-item span { font-size: 12px; }

/* ---------- ⑥ 手机版（媒体查询） ---------- */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  /* 品种行：品名整行 → 件数/质量 → 尾件/重量 → SKU＋删除键 */
  .processing-output-row .name-cell { flex: 1 1 100%; }
  .processing-output-row .pieces-cell,
  .processing-output-row .quality-cell,
  .processing-output-row .tail-cell,
  .processing-output-row .weight-cell { flex: 1 1 calc(50% - 4px); }
  .processing-output-row .sku-cell { flex: 1 1 calc(100% - 52px); }
  .processing-output-row .processing-row-remove { flex: 0 0 44px; width: 44px; min-height: 44px; }
  .processing-output-row input { min-height: 44px; }
  .processing-output-row .processing-cell > small { font-size: 12px; }
  .processing-output-row .processing-row-formula { font-size: 12px; }

  /* 审核区：缩略图改纵向，表格拆成一行一卡，390px 下不横向滚动 */
  .process-doc-head { flex-direction: column; }
  .process-doc-thumb, .process-doc-thumb-empty { width: 100%; height: 148px; flex: 0 0 auto; }
  /* base 层 styles.css 在手机断点给所有 table 加了 min-width: 680px（给宽表横滑用的），
     这里表格已经拆成一行一卡，必须把它清掉，否则弹窗被撑到 680px 出现横向滚动条。 */
  .process-doc-table, .process-doc-table tbody, .process-doc-table tfoot,
  .process-doc-table tr, .process-doc-table td, .process-doc-table th { display: block; width: auto; min-width: 0; max-width: 100%; }
  .process-doc-table thead { display: none; }
  /* 注意：上面那句 `.process-doc-table tr { display: block }` 是 (0,1,1)，
     只写 .process-doc-row (0,1,0) 会被它压过去、卡片式布局不生效 —— 这里补一个类提权。 */
  .process-doc-table .process-doc-row {
    display: grid; grid-template-columns: calc(50% - 4px) calc(50% - 4px);
    gap: 8px; margin-bottom: 8px; padding: 10px;
    border: 1px solid var(--line); border-radius: var(--radius-control);
    background: var(--surface);
  }
  .process-doc-row td { padding: 0; }
  /* 表头被收起来了，用 ::before 把列名补在框上面 */
  .process-doc-row td::before {
    display: block; margin-bottom: 3px;
    font-size: 11px; color: var(--muted); content: '';
  }
  .process-doc-row td:nth-child(1)::before { content: '品名'; }
  .process-doc-row td:nth-child(2)::before { content: '件数'; }
  .process-doc-row td:nth-child(3)::before { content: '单件重量'; }
  .process-doc-row td:nth-child(4)::before { content: '尾件'; }
  .process-doc-row td:nth-child(5)::before { content: '总重量（自动算）'; }
  .process-doc-row td:nth-child(1) { grid-column: 1 / -1; }
  .process-doc-row td:nth-child(6) { grid-column: 1 / -1; }
  .process-doc-row td:nth-child(6)::before { content: none; display: none; }
  .process-doc-row .process-doc-row-remove { width: 100%; min-height: 44px; }
  .process-doc-row input { min-height: 44px; }
  #processDocTotal, .process-doc-total { margin-top: 2px; font-size: 14px; }
  .process-doc-actions { flex-direction: column; align-items: stretch; }
  .process-doc-actions > button { width: 100%; min-height: 44px; }

  /* 两个并排的小按钮（+ 添加 SKU / + 按加工单批量添加）窄屏要能换行 */
  .form-section-title { flex-wrap: wrap; }
  .mini-button { min-height: 44px; }
}

/* ---------- ⑦ 手机版（html.force-mobile 前缀，同步一份） ---------- */
html.force-mobile .processing-output-row .name-cell { flex: 1 1 100%; }
html.force-mobile .processing-output-row .pieces-cell,
html.force-mobile .processing-output-row .quality-cell,
html.force-mobile .processing-output-row .tail-cell,
html.force-mobile .processing-output-row .weight-cell { flex: 1 1 calc(50% - 4px); }
html.force-mobile .processing-output-row .sku-cell { flex: 1 1 calc(100% - 52px); }
html.force-mobile .processing-output-row .processing-row-remove { flex: 0 0 44px; width: 44px; min-height: 44px; }
html.force-mobile .processing-output-row input { min-height: 44px; }
html.force-mobile .processing-output-row .processing-cell > small { font-size: 12px; }
html.force-mobile .processing-output-row .processing-row-formula { font-size: 12px; }
html.force-mobile .process-doc-head { flex-direction: column; }
html.force-mobile .process-doc-thumb, html.force-mobile .process-doc-thumb-empty { width: 100%; height: 148px; flex: 0 0 auto; }
html.force-mobile .process-doc-table, html.force-mobile .process-doc-table tbody, html.force-mobile .process-doc-table tfoot,
html.force-mobile .process-doc-table tr, html.force-mobile .process-doc-table td, html.force-mobile .process-doc-table th { display: block; width: auto; min-width: 0; max-width: 100%; }
html.force-mobile .process-doc-table thead { display: none; }
html.force-mobile .process-doc-table .process-doc-row {
  display: grid; grid-template-columns: calc(50% - 4px) calc(50% - 4px);
  gap: 8px; margin-bottom: 8px; padding: 10px;
  border: 1px solid var(--line); border-radius: var(--radius-control);
  background: var(--surface);
}
html.force-mobile .process-doc-row td { padding: 0; }
html.force-mobile .process-doc-row td::before {
  display: block; margin-bottom: 3px;
  font-size: 11px; color: var(--muted); content: '';
}
html.force-mobile .process-doc-row td:nth-child(1)::before { content: '品名'; }
html.force-mobile .process-doc-row td:nth-child(2)::before { content: '件数'; }
html.force-mobile .process-doc-row td:nth-child(3)::before { content: '单件重量'; }
html.force-mobile .process-doc-row td:nth-child(4)::before { content: '尾件'; }
html.force-mobile .process-doc-row td:nth-child(5)::before { content: '总重量（自动算）'; }
html.force-mobile .process-doc-row td:nth-child(1) { grid-column: 1 / -1; }
html.force-mobile .process-doc-row td:nth-child(6) { grid-column: 1 / -1; }
html.force-mobile .process-doc-row td:nth-child(6)::before { content: none; display: none; }
html.force-mobile .process-doc-row .process-doc-row-remove { width: 100%; min-height: 44px; }
html.force-mobile .process-doc-row input { min-height: 44px; }
html.force-mobile #processDocTotal, html.force-mobile .process-doc-total { margin-top: 2px; font-size: 14px; }
html.force-mobile .process-doc-actions { flex-direction: column; align-items: stretch; }
html.force-mobile .process-doc-actions > button { width: 100%; min-height: 44px; }
html.force-mobile .form-section-title { flex-wrap: wrap; }
html.force-mobile .mini-button { min-height: 44px; }


/* ============================================================
   三十三、数据备份与恢复 v58
   ------------------------------------------------------------
   系统数据存在浏览器本地、按网址（域名）隔离，换域名 / 换手机 / 清缓存前
   必须先导出备份。新增两个入口：
   ① 登录页「从备份文件恢复数据」（换域名后系统是空的、没账号，
      登录页是唯一能点到的地方，入口放这里才不会死循环）
   ② 管理中心卡片「数据备份与恢复」+ 弹窗（导出 / 恢复 + 打包图片开关）
   配色全部沿用现有令牌，不新造颜色；断点统一 1200；手机规则写两份
   （媒体查询 + html.force-mobile）；触控目标 ≥ 44px。
   ============================================================ */

/* ---------- ① 管理中心卡片 ---------- */
/* 卡片上的「上次备份时间」比别的卡片数字长，字号收一档才不挤 */
.backup-card .backup-card-value { font-size: 18px; letter-spacing: -.01em; }
.backup-card .stat-meta { overflow-wrap: anywhere; }

/* ---------- ② 备份弹窗 ---------- */
.backup-panel { display: grid; gap: 12px; }
.backup-tip {
  margin: 0; padding: 11px 12px;
  border: 1px solid var(--line); border-radius: var(--radius-card);
  border-left: 3px solid var(--accent-bright);
  background: var(--surface-soft);
  font-size: 13px; line-height: 1.7; color: var(--ink);
}
.backup-last { font-size: 13px; color: var(--muted); }
.backup-last strong { color: var(--ink); font-variant-numeric: tabular-nums; }
/* 打包图片开关：整行可点，触控高度按按钮标准给 */
.backup-check {
  display: flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 2px;
  font-size: 13px; color: var(--ink); cursor: pointer;
}
.backup-check input[type='checkbox'] { width: 18px; height: 18px; flex: 0 0 18px; accent-color: var(--accent-bright); }
.backup-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 2px; }
.backup-actions > button { flex: 1 1 auto; min-height: 40px; }

/* ---------- ③ 恢复确认弹窗 ---------- */
.backup-confirm { display: grid; gap: 12px; }
.backup-confirm-warn {
  margin: 0; padding: 11px 12px;
  border: 1px solid var(--line); border-left: 3px solid var(--red);
  border-radius: var(--radius-card);
  background: var(--red-soft); color: var(--red-ink);
  font-size: 13px; line-height: 1.75;
}
.backup-confirm-warn strong { font-variant-numeric: tabular-nums; }
.backup-confirm-warn b { color: var(--red-ink); }
.backup-summary-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px;
}
.backup-summary-item {
  display: grid; gap: 2px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: var(--radius-control);
  background: var(--surface-soft);
}
.backup-summary-item span { font-size: 11px; color: var(--muted); }
.backup-summary-item strong { font-size: 15px; color: var(--ink); font-variant-numeric: tabular-nums; }

/* ---------- ④ 登录页恢复入口 ---------- */
.auth-restore-btn { display: inline-block; margin-top: 6px; }
.auth-foot-note .auth-restore-btn { color: var(--accent); }
/* 登录闸门（未登录全屏登录页）下，取消按钮不能是 data-close（那条规则会把它藏掉），
   这里保证两个按钮都露出来 */
html.auth-locked .modal .form-foot .modal-actions { display: flex; }

/* ---------- ⑤ 手机版 ---------- */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  .backup-card .backup-card-value { font-size: 16px; }
  .backup-tip { font-size: 13px; padding: 10px; }
  .backup-check { min-height: 44px; font-size: 13px; }
  .backup-check input[type='checkbox'] { width: 20px; height: 20px; flex: 0 0 20px; }
  /* 两个按钮竖排铺满，触控高度 ≥44 */
  .backup-actions { flex-direction: column; align-items: stretch; }
  .backup-actions > button { width: 100%; min-height: 44px; }
  .backup-summary-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .backup-summary-item { padding: 9px 10px; }
  /* 登录页恢复入口：整行按钮，别夹在小字里点不到 */
  .auth-restore-btn {
    display: block; width: 100%; margin-top: 10px;
    min-height: 44px; padding: 0 4px;
    text-align: center; font-size: 14px;
  }
}
/* 同套规则绑到 html.force-mobile */
html.force-mobile .backup-card .backup-card-value { font-size: 16px; }
html.force-mobile .backup-tip { font-size: 13px; padding: 10px; }
html.force-mobile .backup-check { min-height: 44px; font-size: 13px; }
html.force-mobile .backup-check input[type='checkbox'] { width: 20px; height: 20px; flex: 0 0 20px; }
html.force-mobile .backup-actions { flex-direction: column; align-items: stretch; }
html.force-mobile .backup-actions > button { width: 100%; min-height: 44px; }
html.force-mobile .backup-summary-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
html.force-mobile .backup-summary-item { padding: 9px 10px; }
html.force-mobile .auth-restore-btn {
  display: block; width: 100%; margin-top: 10px;
  min-height: 44px; padding: 0 4px;
  text-align: center; font-size: 14px;
}

/* ==========================================================================
   三十四、采购仓库 · 显示「件数 × 单件重量 ＋ 尾件 ＝ 重量」(v60 电脑版 / v63 手机版)
   老板要的是：扫一眼就能看出这批货的包装结构，不用点进详情才知道多少件、每件多重。
   v60 只给电脑版（≥1200）；v63 老板主要用手机，手机版也要看到。手机一行放不下，
   所以手机版单独一套：字号小一档（11px）＋ 允许换行 ＋ 最多 2 行截断。
   条数上限由 JS 控制（手机 2 条 / 电脑 3 条），宁可少显示几条，也不让人看半截算式。
   ========================================================================== */
.warehouse-row .wh-expr { display: block; }

/* v95：算式从独立第 3 行并入第 2 行（行2 = 算式 · 单价 · 金额），单行省略号 */
.warehouse-row .wh-expr {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 12.5px; color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   三十五、装车单发货 · 顶部「收货单位」输入框（v62）
   装车单发精制厂没有关联销售单，原来顶部是死的「未关联客户」，老板没法填精制厂名。
   改成：同一块 shipment-summary 里放一个可填的输入框，版式沿用现有 .form-field，不新增配色。
   ========================================================================== */
.shipment-summary-form { align-items: stretch; }
.shipment-summary-form .form-field { flex: 1 1 auto; min-width: 0; }
.shipment-summary-form > span { flex: 0 0 auto; }

/* 电子发货单是白纸黑字的 A4 单据（浅色/深色皮肤下底色都是 #fff），
   但 base 层 styles-polish.css 有条全局 th { color: var(--muted) } —— 深色下 --muted 是浅灰，
   套到白底表头上只有 2.18:1，发货单表头会糊成一片。这里按单据自身的墨色复位，不新造颜色。 */
.shipment-document th { color: #1b3b35; background: #f2f6f1; }

/* ============================================================
   三十四、v64 真 OCR 接入后新增的三块提示
   ------------------------------------------------------------
   ① .process-doc-pending  上传后到拿到结果前的「识别中…」
   ② .process-doc-mismatch 明细合计跟单据合计对不上时的防错提示（老板最需要）
   ③ .process-doc-unparsed 没能自动解析的原文行，让老板照着手工补
   配色全部沿用现有令牌，不新造颜色；断点统一 1200；手机规则写两份
   （媒体查询 + html.force-mobile）；触控目标 ≥ 44px。
   ============================================================ */

/* ---------- ① 识别中 ---------- */
.process-doc-review.process-doc-pending {
  display: grid; gap: 4px; align-content: start;
  padding: 14px 12px;
}
.process-doc-pending strong { font-size: 14px; color: var(--accent); }
.process-doc-pending small { font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }

/* ---------- ② 合计对不上（防错，必须醒目） ---------- */
.process-doc-mismatch {
  margin: 10px 0 0; padding: 10px 12px;
  border: 1px solid var(--red); border-radius: var(--radius-control);
  background: var(--red-soft); color: var(--red-ink);
  font-size: 13px; line-height: 1.6; font-weight: 600;
  overflow-wrap: anywhere;
}

/* ---------- ③ 未能自动解析，请手工补 ---------- */
.process-doc-unparsed {
  margin: 10px 0 0; padding: 10px 12px;
  border: 1px dashed var(--line); border-radius: var(--radius-control);
  background: var(--surface);
}
.process-doc-unparsed > strong {
  display: block; margin-bottom: 6px;
  font-size: 13px; color: var(--ink);
}
.process-doc-unparsed ul { margin: 0; padding-left: 18px; }
.process-doc-unparsed li {
  margin-bottom: 3px;
  font-size: 13px; color: var(--ink);
  overflow-wrap: anywhere; word-break: break-word;
}
.process-doc-unparsed > small { display: block; margin-top: 6px; font-size: 12px; color: var(--muted); }

/* ---------- ④ 手机版（媒体查询） ---------- */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  .process-doc-pending strong { font-size: 15px; }
  .process-doc-pending small { font-size: 13px; }
  .process-doc-mismatch { font-size: 14px; padding: 12px; }
  .process-doc-unparsed { padding: 12px; }
  .process-doc-unparsed > strong { font-size: 14px; }
  .process-doc-unparsed li { font-size: 14px; line-height: 1.65; }
  .process-doc-unparsed > small { font-size: 13px; }
}

/* ---------- ⑤ 手机版（html.force-mobile 前缀，同步一份） ---------- */
html.force-mobile .process-doc-pending strong { font-size: 15px; }
html.force-mobile .process-doc-pending small { font-size: 13px; }
html.force-mobile .process-doc-mismatch { font-size: 14px; padding: 12px; }
html.force-mobile .process-doc-unparsed { padding: 12px; }
html.force-mobile .process-doc-unparsed > strong { font-size: 14px; }
html.force-mobile .process-doc-unparsed li { font-size: 14px; line-height: 1.65; }
html.force-mobile .process-doc-unparsed > small { font-size: 13px; }

/* ============================================================
   三十六、返回按钮挪到手机底栏右端 v65
   ------------------------------------------------------------
   背景：老板主要用手机、单手操作，页面左上角够不着 —— 返回入口挪到屏幕底部
        那条固定导航的最右端，拇指一伸就能按到。
   分工：
     · 手机版（<1200 / pointer:coarse / hover:none，或 html.force-mobile）
       底栏 #backBtnNav 显示；顶栏 #backBtn 和首页简版标题栏 #backBtnMobile
       全部隐藏 —— 同一屏只留一个返回入口，不然老板会点错。
     · 电脑版（≥1200 且非 force-mobile）
       底栏其实是左侧竖排侧栏，没有「底部导航」这回事，返回按钮塞进去反而找不着，
       所以底栏这个 display:none，电脑版继续用顶栏左上角那个。
   逻辑一行没动：三块都带 .back-button 类，app.js 的 refreshBackButton()
       按 viewStack 统一 hidden，栈空时三个一起消失，不放点了没反应的死按钮。
   空间（改前实测 390×844）：底栏收起态只显示「当前板块」一条（flex:1 1 0，占满 390px），
       ☰ 和头像早就是 display:none。返回按钮按 flex:0 0 auto 排到最右（order 12 > ☰ 的 9），
       nav-list 改成 flex:1 1 0 + min-width:0 自动让位，板块条不会被压到 44px 以下。
   配色沿用现有令牌：--accent-tile 浅绿底 + --accent-deep 深绿字（跟已完成标签同一对），
       在深底栏上是一颗浅绿药丸 —— 跟「当前板块」那条平铺深色区分开（动作 vs 导航），
       不新造颜色。触控目标 min-height/min-width 48px（≥44）。
   抽屉展开时 nav-list 变成 position:fixed 浮在底栏上方（浮层底边 774 < 底栏顶边 782），
       返回按钮留在底栏原位，不会被盖住也不会错位。
   ============================================================ */

/* ① 电脑版（默认）：底栏 = 左侧竖排侧栏，不出现返回按钮 */
.sidebar > .nav-back-button { display: none; }

/* ---------- ② 手机版（媒体查询） ---------- */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  /* 顶栏 / 首页简版标题栏那两个返回按钮撤掉，避免一屏两个返回 */
  .topbar > .back-button,
  .mobile-dashboard-header > .back-button { display: none !important; }

  /* 底栏右端的返回按钮 */
  html .sidebar > .nav-back-button {
    display: inline-flex;
    order: 12;                 /* nav-list 是 0、☰ 是 9 → 12 排到最右 */
    flex: 0 0 auto;
    align-self: center;
    min-height: 48px; min-width: 48px;
    /* margin-left:auto：抽屉展开时 nav-list 变 position:fixed 脱离了流，
       返回按钮成了底栏唯一在流元素 —— 没有 auto 它会被吸到最左（从右端跳到左端）。
       加了 auto 后收起态贴右、展开态也贴右，位置不跳。 */
    margin: 0 10px 0 auto;
    padding: 0 14px;
    font-size: 15px; font-weight: 700;
    border: 1px solid transparent;
    border-radius: 12px;
    background: var(--accent-tile);
    color: var(--accent-deep);
  }
  html .sidebar > .nav-back-button:active { background: var(--accent-soft); }

  /* 板块条让位：nav-list 收缩而不是把返回按钮挤出屏幕 */
  html .sidebar > .nav-list { flex: 1 1 0; width: auto; min-width: 0; }
}

/* ---------- ③ 手机版（html.force-mobile 前缀，同步一份） ---------- */
html.force-mobile .topbar > .back-button,
html.force-mobile .mobile-dashboard-header > .back-button { display: none !important; }
html.force-mobile .sidebar > .nav-back-button {
  display: inline-flex;
  order: 12;
  flex: 0 0 auto;
  align-self: center;
  min-height: 48px; min-width: 48px;
  margin: 0 10px 0 auto;   /* 同上：展开态也贴右，不跳位 */
  padding: 0 14px;
  font-size: 15px; font-weight: 700;
  border: 1px solid transparent;
  border-radius: 12px;
  background: var(--accent-tile);
  color: var(--accent-deep);
}
html.force-mobile .sidebar > .nav-back-button:active { background: var(--accent-soft); }
html.force-mobile .sidebar > .nav-list { flex: 1 1 0; width: auto; min-width: 0; }

/* ---------- ④ 抽屉：force-mobile 下也要浮起来（v65 补丁） ----------
   抽屉的 position:fixed / left / right / bottom 只在 styles.css:609 里给过一次，
   而那条规则写在 @media (max-width: 1199.98px) 里 —— 宽屏（≥1200）根本不生效。
   结果：电脑上手动切成手机版后，抽屉以 position:static 塞在 62px 高的底栏里，
   实测 nav-list rect = [0,795]→[1585,943]，直接溢出到视口（900）外面，
   板块看得见名但坐标在屏幕外，点了没反应（elementFromPoint 返回 null）。
   这里给 html.force-mobile 补上定位；bottom / 配色 / 圆角沿用上面十八节已有的值。
   注意：styles.css 是 base 层，按规矩不动它，只在皮肤层补。 */
html.force-mobile .sidebar.nav-expanded > .nav-list {
  position: fixed;
  left: 10px; right: 10px;
  width: auto;
}

/* ---------- ⑤ 抽屉定位：宽屏触屏也要浮起来（v65 补丁②） ----------
   抽屉的 position:fixed / left / right 只在 styles.css:609 给过一次，而那条规则
   写在 @media (max-width: 1199.98px) 里 —— 只覆盖「窄屏」，不覆盖「宽屏但触屏」。
   实测 1600×900 + pointer:coarse（大平板横屏）：nav-list 是 position:static，
   rect = [0,792]→[1600,936]，整个掉到视口（900）外面，板块看得见名却点不到
   （elementFromPoint 返回 null）。这里在皮肤层的同一个断点里补上定位。
   窄屏下 styles.css:609 已经给了同样的值，这里等于重复声明，不会改变现状。
   （宽屏 + 鼠标 + force-mobile 那一路见上面 ④） */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  .sidebar.nav-expanded > .nav-list {
    position: fixed;
    left: 10px; right: 10px;
    width: auto;
  }
}

/* ---------- ⑥ 手机版首页简版标题栏：补 html.force-mobile 副本（v65 补丁③） ----------
   v32 那套「首页顶部简版标题栏（头像 + 经营概览 + 语音 + 更多）」只在媒体查询里写过，
   从来没复制 html.force-mobile 那份（违反本文件「每段手机规则都要同步一份」的约定）。
   后果：电脑上手动切成手机版后，首页还是电脑版那套顶栏 —— topbar 1561×62 照常显示、
   简版标题栏 display:none，里面的圆形头像 #mobileAvatarBtn 也就跟着看不见。
   （注：账户菜单并没真的打不开 —— 顶栏账号卡 #accountAvatarBtn 在 force-mobile 下
     是可见的（:1897 覆盖了 :1086 的 display:none），实测 40×44 能点开菜单、
     菜单里就有「切到电脑版」。所以这条是「手机版首页长得不像手机版」，
     不是「切不回来」。真手机 390 首页本来就是 topbar 隐藏 + 简版标题栏显示，
     补的这整段对真手机是同值重复声明，零影响。）
   隐藏 topbar 是配套动作：否则宽屏下会出现「电脑版顶栏 + 手机版简版标题栏」双标题。 */
html.force-mobile body[data-current-view="dashboard"] .topbar { display: none; }
html.force-mobile .mobile-dashboard-header { display: none; }
html.force-mobile body[data-current-view="dashboard"] .mobile-dashboard-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  gap: 8px; /* v71：同上，按钮带文字后收紧 */
}
html.force-mobile .mobile-dashboard-header h2 {
  font-size: 22px;
  font-weight: 700;
  margin: 0;
  letter-spacing: -.01em;
}
html.force-mobile .mobile-dashboard-actions {
  display: flex;
  align-items: center;
  gap: 6px; /* v71：按钮带文字后收紧 */
}
html.force-mobile .mobile-quick-add {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 0;
  background: var(--accent-bright);
  color: #fff;
  font-size: 26px;
  line-height: 1;
  display: grid;
  place-items: center;
  padding: 0;
  box-shadow: none;
}
html.force-mobile .mobile-quick-add:active { transform: scale(.95); background: var(--accent-bright); filter: brightness(1.05); }
html.force-mobile .mobile-more-top {
  height: 44px;
  padding: 0 14px;
  border-radius: 22px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--muted);
  font-size: 14px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 4px;
}
html.force-mobile .mobile-more-top span { font-size: 15px; line-height: 1; }

/* ---------- ⑦ 手机版首页：收掉欢迎语 / 公司资料条 / 流程条（v65 补丁④） ----------
   这三块在手机上一律收掉（媒体查询版在 :1270-1272），但从来没复制 html.force-mobile 那份。
   后果：电脑上手动切成手机版后，首页顶部还杵着「欢迎语 1561×65 + 公司资料条 1561×90 +
   流程条 1561×58」，合计约 213px，吃掉近四分之一屏 —— 真手机上是全隐藏的。
   收掉之后首页只剩简版标题栏 + 待办/统计，跟真手机一致。
   （#dashboardView .stat-more > summary 两边本来都是隐藏，不用动。） */
html.force-mobile #dashboardView .welcome-row, html.force-mobile #dashboardView .dashboard-company-head { display: none; }
html.force-mobile #dashboardView .company-profile-strip { display: none; }
html.force-mobile #dashboardView #workflowGuide { display: none; }

/* ============================================================
   v68 补丁 ① 深色下写死白底的输入框（F1）
   ------------------------------------------------------------
   base 层 styles.css 里有两条规则给输入框写死了浅底色，并且都配了 var(--ink)：
     styles.css:166  .allocation-row select, .allocation-row input { background:#fff; color:var(--ink) }
     styles.css:666  .settlement-fields input                      { background:#fff; color:var(--ink) }
   特异度都是 (0,1,1)；深色模式只在上面用「元素选择器」覆盖输入框：
     input, select, textarea { background: var(--surface-soft) }        ← (0,0,1)，压不住
   于是白底保留，而 --ink 在深色下已经翻成 #e8eaec（浅灰）→ 变成「浅字 + 白底」，
   实测对比度 1.21:1（WCAG AA 要 ≥4.5），深色系统下数字基本看不见。

   这里只在 prefers-color-scheme: dark 里补同级别选择器 —— 浅色模式一行都不动。
   底色复用上面元素选择器用的 var(--surface-soft)，跟其它输入框观感一致：
   #e8eaec on #26292d = 12.11:1 ✅
   ============================================================ */
/* v78：老板决定不保留深色模式，整块停用（内容保留，恢复时把 and (min-width: 999999px) 删掉即可） */
@media (prefers-color-scheme: dark) and (min-width: 999999px) {
  .settlement-fields input,
  .allocation-row input,
  .allocation-row select {
    background: var(--surface-soft);
    color: var(--ink);
    border-color: var(--line);
  }
}

/* ============================================================
   v68 补丁 ② 手机端采购明细「明细合计」区的空白灰块（F3）
   ------------------------------------------------------------
   base 层 styles.css:687-693 在手机上把采购明细 tfoot 改成 2 列网格，
   而 tfoot 第 2 格 <td></td> 本来就是个占位空单元格（第 6 列「采购单价」），
   .item-editor tfoot td 又给了底色（皮肤层 :172 翻成 var(--surface-soft)）—— 手机上实测是一块
   165×57 的浅灰方块（ rgb(250,250,251) = 浅色下的 --surface-soft ），
   看起来像「有一格忘记填了」。

   皮肤层原来只对 #customersView / #suppliersView / #salesView / #cashflowView
   隐藏 td:empty（本文件 :603），采购弹窗不在名单里 —— 这里补上。
   用 :empty 保证只隐藏真正没有内容（连空白文本节点都没有）的单元格，
   合计重量 / 合计金额两格内容正常，不受影响。

   只在手机端生效：桌面端 tfoot 是普通表格行，列宽由 thead 的 th 写死，
   没必要去动它的单元格。
   ============================================================ */
@media (max-width: 1199.98px) {
  .purchase-item-editor tfoot td:empty { display: none; }
}
html.force-mobile .purchase-item-editor tfoot td:empty { display: none; }

/* ============================================================
   v69 补丁 ① 账号权限勾选框（「设置权限」弹窗）
   ------------------------------------------------------------
   .permission-checks 本体在 base 层 styles.css:663，这里一行都不动，
   只补三样它没有的：分组小标题、「管理员不可改」的禁用态、底部说明小字。
   手机端勾选框放大到 33px 高（checkout 目标），桌面端保持紧凑。
   每写一段手机媒体查询，同时写一份 html.force-mobile 副本 ——
   手动切成手机版时视口仍是宽屏，媒体查询不命中。
   ============================================================ */
.permission-group { margin-top: 14px; }
.permission-group-title { display: block; margin-bottom: 7px; color: var(--muted); font-size: 11px; font-weight: 700; }
.permission-checks label.locked { opacity: .55; cursor: not-allowed; }
.permission-note { margin-top: 12px; color: var(--muted); font-size: 11px; line-height: 1.7; }
@media (max-width: 1199.98px) {
  .permission-group { margin-top: 12px; }
  .permission-checks label { padding: 9px 10px; font-size: var(--mini); }
  .permission-note { font-size: var(--mini); }
}
html.force-mobile .permission-group { margin-top: 12px; }
html.force-mobile .permission-checks label { padding: 9px 10px; font-size: var(--mini); }
html.force-mobile .permission-note { font-size: var(--mini); }

/* ============================================================
   v69 补丁 ② 已开通账号行里的权限小字（F：手机端换行后被挤成一条）
   ------------------------------------------------------------
   .registration-row small 的 base 层字号是 10px（styles.css:663），
   手机上权限名有十几个字时会占 3 行、把右侧按钮顶出屏幕外。
   这里只把小字放宽到 var(--mini) 并允许整行换行，不改 base 层。
   ============================================================ */
@media (max-width: 1199.98px) {
  .registration-row small { font-size: var(--mini); line-height: 1.65; overflow-wrap: anywhere; }
}
html.force-mobile .registration-row small { font-size: var(--mini); line-height: 1.65; overflow-wrap: anywhere; }

/* ============================================================
   v70 补丁 ① 运费三联动区（销售单 / 销售发车 / 装车单）
   ------------------------------------------------------------
   老板原话：「运费应该为多少钱一吨乘以数量等于金额。」
   区块本体用的是 base 层的 .form-section / .form-grid / .calculation-note，
   这里一行都不改，只补三样 base 没有的：只读吨数框的观感、金额框的强调、
   手机上「吨数 + 单价」两列、「金额」独占一行。
   每写一段手机媒体查询，同时写一份 html.force-mobile 副本 ——
   手动切成手机版时视口仍是宽屏，媒体查询不命中。
   ============================================================ */
.freight-section .freight-tons { background: var(--surface-soft); color: var(--muted); cursor: default; }
.freight-section .freight-tons:focus { border-color: var(--line); box-shadow: none; }
.freight-section .freight-amount { font-weight: 700; color: var(--green); }
.freight-section .freight-note { margin-top: 10px; }
@media (max-width: 1199.98px) {
  .freight-section .form-grid { grid-template-columns: 1fr 1fr; }
  .freight-section .freight-amount-field { grid-column: 1 / -1; }
}
html.force-mobile .freight-section .form-grid { grid-template-columns: 1fr 1fr; }
html.force-mobile .freight-section .freight-amount-field { grid-column: 1 / -1; }

/* ============================================================
   v71 补丁 ① 按钮文案变长后的承载（只改本文件，base 层未动）
   ------------------------------------------------------------
   ① 首页右上角「+」补上「语音记一笔」文字：圆形改胶囊，别挤成两行
   ② 语音弹窗录音按钮补「🎤 按住说话」：圆形改胶囊
   ③ 供应商填报页单位切换：状态文案与动作按钮拆开后并排一行
   ============================================================ */
.mobile-quick-add {
  width: auto; height: 44px; padding: 0 12px;
  border-radius: 22px; font-size: 14px; font-weight: 600;
  grid-auto-flow: column; gap: 5px; white-space: nowrap;
  flex: 0 0 auto; padding: 0 10px;
  /* v78：白字压 --accent-bright(#00a85f) 只有 3.10:1。这个绿是中明度，必须用深字
     （项目既有惯例：--accent-on 配 --accent-bright = 5.32:1）。 */
  color: var(--accent-on);
}
.mobile-quick-add .quick-add-plus { font-size: 19px; line-height: 1; }
/* 手动切成手机版时挂的是 html.force-mobile，比上面那条多一个类，必须再写一份 */
html.force-mobile .mobile-quick-add {
  width: auto; height: 44px; padding: 0 12px;
  border-radius: 22px; font-size: 14px; font-weight: 600;
  grid-auto-flow: column; gap: 5px; white-space: nowrap;
  flex: 0 0 auto; padding: 0 10px;
  /* v78：白字压 --accent-bright(#00a85f) 只有 3.10:1。这个绿是中明度，必须用深字
     （项目既有惯例：--accent-on 配 --accent-bright = 5.32:1）。 */
  color: var(--accent-on);
}
html.force-mobile .mobile-quick-add .quick-add-plus { font-size: 19px; line-height: 1; }
/* 「⋯ 全部板块」同样不许折行，并收紧一点内边距，给标题让出空间 */
.mobile-more-top,
html.force-mobile .mobile-more-top { padding: 0 8px; font-size: 13px; white-space: nowrap; flex: 0 0 auto; }
.record-button {
  width: auto; min-width: 54px; height: 54px; padding: 0 20px;
  border-radius: 27px; font-size: 15px; font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
#unitToggleLabel { display: inline-block; white-space: nowrap; margin-right: 6px; }

/* v71 补丁 ② 弹窗底部一排按钮：文案变长后手机上会被截成省略号
   （装车单详情一排 4 个：关闭 / 可以直接卖了 / 登记精制加工 / 安排发货）。
   放不下就让整排换行，按钮保持单行、按内容取宽，不再压成「可以…」。
   base 层的 .modal-actions { flex:1 } 不动，只在手机断点覆盖。 */
@media (max-width: 1199.98px) {
  .modal-actions { flex-wrap: wrap; }
  .modal-actions button { flex: 1 1 auto; min-width: max-content; }
}
html.force-mobile .modal-actions { flex-wrap: wrap; }
html.force-mobile .modal-actions button { flex: 1 1 auto; min-width: max-content; }

/* v71 补丁 ③ 卡片头里的按钮（如「去提交注册资料」）：文案变长后
   在「注册申请」面板头里被挤到只剩 59px 宽、折成 4 行。
   手机上允许按钮换到文字下方一行摆放，按内容取宽、保持单行。 */
@media (max-width: 1199.98px) {
  .panel-header { flex-wrap: wrap; }
  .panel-header > button { flex: 0 1 auto; min-width: max-content; }
}
html.force-mobile .panel-header { flex-wrap: wrap; }
html.force-mobile .panel-header > button { flex: 0 1 auto; min-width: max-content; }

/* ============================================================
   v79 平板档 640~1199px —— 沿用手机版骨架，只收回「明显浪费空间」的限制
   ------------------------------------------------------------
   断点从 1500 下移到 1200（v79）后，640~1199 这一档（平板、竖屏小笔记本、
   手机横屏）套用的是给 390px 写的手机版规则。实测（390/640/768/1024/1199）：
   骨架、卡片网格（768/1024 自动成 2 列）、字号、表格换行在平板上都站得住，
   唯一明显浪费空间的是**弹窗** —— 手机版弹窗是「贴底全宽抽屉」
   （base 层 styles.css「.modal-backdrop{align-items:flex-end;padding:0} /
   .modal{width:100%}」），到 1024 上就被拉成 1024px 宽：上传框横拉近 1000px、
   底部两颗按钮各占半屏，读一屏要横着扫。这里只把它收回成居中对话框。
   其余一条不动；force-mobile 的手机骨架规则也一条不改。
   ============================================================ */
@media (min-width: 640px) and (max-width: 1199.98px) {
  .modal-backdrop { align-items: center; padding: 24px; }
  .modal {
    width: min(680px, 100%);
    max-height: calc(100vh - 48px);
    border-radius: 16px;
    padding: 22px 20px 20px;
  }
  /* 采购明细 9 列要 820px、加工单 7 列要 920px 才排得开（见上面 ≥1200 的规则），
     平板上给它们留出余量，避免退回横滑 */
  .modal.modal-purchase-wide { width: min(920px, 100%); }
  .modal.modal-processing-wide { width: min(980px, 100%); }
  .modal.modal-sale-wide { width: min(980px, 100%); }
  .modal.modal-reconcile-wide { width: min(980px, 100%); }
}

/* ============================================================
   v81 必修 4 / 5：销售详情卡片化 + 管理中心高危操作区
   ------------------------------------------------------------
   768px 平板的销售详情弹窗内容宽约 638px，小于 .detail-items 的 680px
   最小宽度，因此手机骨架（<1200 / 粗指针 / 无 hover）统一改成卡片；
   1200px 以上鼠标桌面不命中，继续保留七列表格。
   ============================================================ */
.management-data-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  margin-top: 20px;
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--surface);
}
.management-data-actions-copy { min-width: 0; }
.management-data-actions-copy h3 { margin: 0 0 5px; font-size: 16px; }
.management-data-actions-copy p { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.6; }
.management-data-actions-buttons { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; }
.management-data-actions-buttons button { min-height: 44px; }
.secondary-button.danger-button {
  color: var(--red-ink);
  border-color: var(--red-ink);
  background: var(--surface);
}
.secondary-button.danger-button:hover { color: var(--red-ink); background: var(--red-soft); border-color: var(--red-ink); }

@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  .management-data-actions { align-items: stretch; flex-direction: column; padding: 16px; }
  .management-data-actions-buttons { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); width: 100%; }

  .detail-section .item-table-wrap:has(.detail-items) { overflow-x: visible; border: 0; border-radius: 0; }
  /* 先把表格拆成块级；td 不写在这组里 —— 后面的 .detail-items tbody td 要把它改成 flex，
     若在这里也写一条同权的 display:block 会按源序赢掉后面那条，卡片排版就废了。 */
  .detail-items,
  .detail-items thead,
  .detail-items tbody,
  .detail-items tr { display: block; }
  .detail-items { width: 100%; min-width: 0; table-layout: auto; }
  .detail-items thead { display: none; }
  .detail-items tbody tr {
    padding: 12px 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    background: var(--surface);
  }
  .detail-items tbody tr + tr { margin-top: 10px; }
  .detail-items tbody td {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 18px;
    min-width: 0;
    padding: 8px 0;
    border: 0;
    border-bottom: 1px solid var(--line-soft);
    text-align: right;
    white-space: normal;
    overflow-wrap: anywhere;
  }
  .detail-items tbody td::before {
    content: attr(data-label);
    flex: 0 0 44%;
    color: var(--muted);
    font-weight: 600;
    text-align: left;
  }
  .detail-items tbody td:first-child {
    display: block;
    margin-bottom: 2px;
    padding: 0 0 10px;
    color: var(--ink);
    font-size: 14px;
    font-weight: 700;
    text-align: left;
  }
  .detail-items tbody td:first-child::before { content: none; }
  .detail-items tbody td:first-child .table-secondary { margin-top: 4px; font-weight: 500; }
  .detail-items tbody td:last-child { border-bottom: 0; font-weight: 750; }
}

html.force-mobile .management-data-actions { align-items: stretch; flex-direction: column; padding: 16px; }
html.force-mobile .management-data-actions-buttons { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); width: 100%; }
html.force-mobile .detail-section .item-table-wrap:has(.detail-items) { overflow-x: visible; border: 0; border-radius: 0; }
html.force-mobile .detail-items,
html.force-mobile .detail-items thead,
html.force-mobile .detail-items tbody,
html.force-mobile .detail-items tr { display: block; }
html.force-mobile .detail-items { width: 100%; min-width: 0; table-layout: auto; }
html.force-mobile .detail-items thead { display: none; }
html.force-mobile .detail-items tbody tr {
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--surface);
}
html.force-mobile .detail-items tbody tr + tr { margin-top: 10px; }
html.force-mobile .detail-items tbody td {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  min-width: 0;
  padding: 8px 0;
  border: 0;
  border-bottom: 1px solid var(--line-soft);
  text-align: right;
  white-space: normal;
  overflow-wrap: anywhere;
}
html.force-mobile .detail-items tbody td::before {
  content: attr(data-label);
  flex: 0 0 44%;
  color: var(--muted);
  font-weight: 600;
  text-align: left;
}
html.force-mobile .detail-items tbody td:first-child {
  display: block;
  margin-bottom: 2px;
  padding: 0 0 10px;
  color: var(--ink);
  font-size: 14px;
  font-weight: 700;
  text-align: left;
}
html.force-mobile .detail-items tbody td:first-child::before { content: none; }
html.force-mobile .detail-items tbody td:first-child .table-secondary { margin-top: 4px; font-weight: 500; }
html.force-mobile .detail-items tbody td:last-child { border-bottom: 0; font-weight: 750; }

/* ============================================================
   v82 · 客户「营业执照」上传行（新增/编辑客户弹窗）
   上传按钮 + 文件名/缩略图 + 删除按钮。控件全是现有类，这里只排一行 Flex，
   窄屏自动换行，保证手机端点得到。
   ============================================================ */
.license-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.license-row .upload-button { flex: 0 0 auto; }
.license-row .receipt-name { flex: 1 1 200px; min-width: 0; }
/* 原生 file input 自己有几百 px 宽，放在 flex 里会把整行撑出屏幕（Flex 的 auto 最小尺寸是按内容算的，
   不像 .receipt-row 那种写死列宽的 grid）。压成 1px 藏起来：点 label 照样能选文件，
   CDP 的 DOM.setFileInputFiles 也照样能塞。 */
.license-row .upload-button input[type='file'] { position: absolute; width: 1px; height: 1px; padding: 0; margin: 0; opacity: 0; pointer-events: none; }

/* ============================================================
   v83 · 销售明细「勾选货物」挑货面板（openProcessingPickerForSale）
   面板里每一行就是一个 checkbox：未精制的毛茶和已精制的成品混在一个列表里，
   靠分区标题和 optgroup 一样的思路让老板看得懂。
   全部用 flex 自适应（不写媒体查询）—— html.force-mobile 直接继承，不用复制一份。
   ============================================================ */
.pick-panel { display: flex; flex-direction: column; gap: 14px; margin: 14px 0; }
.pick-group { display: flex; flex-direction: column; gap: 6px; }
.pick-group-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; padding: 0 2px; }
.pick-group-head strong { font-size: 14px; color: var(--ink); }
.pick-group-head span { font-size: var(--mini); color: var(--muted); }
/* 一条加工单 = 一组品种。组头放「全选本单」，和分区标题拉开一点层级 */
.pick-sub { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-control); background: var(--surface-soft); }
.pick-sub-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 10px; }
.pick-sub-head > span { font-size: var(--mini); font-weight: 700; color: var(--muted); }
.pick-all { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; font-size: var(--mini); color: var(--accent); font-weight: 700; cursor: pointer; }
/* 每一行都能点：checkbox 自己就是 44px 触控目标的锚点，整行包进 label */
.pick-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 10px; min-height: 44px; padding: 8px 10px; border: 1px solid transparent; border-radius: var(--radius-control); background: var(--surface); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.pick-row:hover { background: var(--surface-soft); }
.pick-row input[type='checkbox'] { flex: none; width: 20px; height: 20px; margin: 2px 0 0; accent-color: var(--accent); }
/* 主文案和小字各自独立成列，窄屏时小字整行掉下去，不被 checkbox 挤成竖排 */
.pick-row-main { flex: 1 1 auto; min-width: 0; font-size: 14px; font-weight: 600; color: var(--ink); line-height: 1.4; }
.pick-row-meta { flex: 1 1 100%; font-size: var(--mini); font-weight: 400; color: var(--muted); line-height: 1.5; }
.pick-row input[type='checkbox']:checked ~ .pick-row-main { color: var(--accent); }
.pick-row:has(input[type='checkbox']:checked) { background: var(--accent-soft); border-color: var(--accent); }
/* 底部：已选统计 + 按钮。窄屏自动换行，按钮整行铺开也点得到 */
.pick-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; }
.pick-foot .hint { flex: 1 1 160px; min-width: 0; font-size: var(--mini); font-weight: 700; color: var(--accent); }
.pick-foot .modal-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.pick-foot .modal-actions > * { flex: 1 1 auto; }
#pickAddBtn:disabled { opacity: .45; cursor: not-allowed; }

/* ============================================================
   v84 · 「新建销售清单」弹窗里的「精制板块货物」节
   卡片本体沿用 .source-card / .source-choice / .warehouse-sale-fields 这套老类
   （布局、选中态 .selected 都是现成的），这里只补新类：分组标题和金额行。
   ============================================================ */
#warehouseProcSources { display: flex; flex-direction: column; gap: 4px; }
.warehouse-proc-source { margin-bottom: 4px; }
/* 两类货各有一个分标题；同一张加工单下的 N 个品种再缩进一层，和上面的采购区一眼区分开 */
.proc-source-subhead { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; margin: 10px 0 6px; }
.proc-source-subhead:first-child { margin-top: 0; }
.proc-source-subhead strong { font-size: 13px; color: var(--ink); }
.proc-source-subhead span { font-size: var(--mini); color: var(--muted); line-height: 1.5; }
.proc-source-grouphead { margin: 4px 0 6px; padding-left: 8px; border-left: 2px solid var(--accent-bright); font-size: var(--mini); font-weight: 700; color: var(--muted); }
.proc-source-grouphead + .warehouse-proc-source { margin-left: 10px; }
/* 金额行：和采购卡片里的 .warehouse-sale-calculated 一样跨满整行 */
.warehouse-proc-calculated { grid-column: 1 / -1; color: var(--accent); font-size: 11px; font-weight: 700; }
.warehouse-proc-source input[type='number']:disabled { background: var(--surface-soft); color: var(--muted); }

/* ============================================================
   v85：头像改成「注册人的姓」（单姓 1 字 / 复姓 2 字）
   ------------------------------------------------------------
   原来头像放的是姓名后两字，字号（32px 圆 → 12px、38px 圆 → 13px）
   是按「两个字挤在小圆里」定的。改成单字后会显得又小又空，
   所以给 av-len-1 单独放大字号；复姓两字沿用原来的 av-len-2。
   选择器都带 .av-len-1，特异性比 .mobile-account-chip .account-chip-avatar
   和媒体查询里的 .mobile-avatar-btn .account-chip-avatar 都高，
   不用再给 html.force-mobile 复制一份。
   颜色全用变量，深色块已停用，不用再写深色份。
   ============================================================ */
.account-chip-avatar.av-len-1 { font-size: 15px; letter-spacing: 0; }
.mobile-account-chip .account-chip-avatar.av-len-1,
.mobile-avatar-btn .account-chip-avatar.av-len-1 { font-size: 17px; }
/* 「我的账户」弹窗里那颗 56px 大头像：单姓放大到 28px，圆里才不空 */
.account-menu-head .account-chip-avatar.av-len-1 { font-size: 28px; letter-spacing: 0; line-height: 1; }

/* ============================================================
   v91：侧栏「数据存哪儿」指示点 —— 云端绿 / 本机橙 / 未登录灰
   ------------------------------------------------------------
   .storage-dot 原本默认是绿色（--accent-bright），但未登录时也该有个中性态，
   所以默认改成灰，云端(is-cloud)恢复绿、本机(is-local)换橙。
   文字本体由 app.js refreshStorageCard() 动态写，这里只管点的颜色。
   ============================================================ */
.storage-dot { background: var(--muted); box-shadow: 0 0 0 3px var(--line); }
.storage-dot.is-cloud { background: var(--accent-bright); box-shadow: 0 0 0 3px var(--accent-soft); }
.storage-dot.is-local { background: #e6a23c; box-shadow: 0 0 0 3px rgba(230, 162, 60, .18); }

/* ============================================================
   v98：采购仓库批次列表 · 电脑版拼成单行 + 文字放大
   ------------------------------------------------------------
   老板要「电脑版全部排成一行，文字大点」。原结构是 wh-line1 / wh-line2 两行，
   这里只在 ≥1200px 用 display:contents 拆掉两行容器、让子元素直接参与
   warehouse-row 的 flex 单行排列，再用 order 排成：
   日期 → 供应商 → 品名 → 算式 → 单价 → 未付金额 → 流程状态 → ›
   手机版（≤1199.98px）维持原两行，本块不碰。
   ============================================================ */
@media (min-width: 1200px) {
  /* v102：电脑版从 flex 改成 grid 固定比例列，让「每列纵向对齐、间距统一」。
     列序：勾选 → 日期 → 供应商 → 品名 → 仓位 → 算式 → 单价 → 未付金额 → 状态 → ›。
     每行是独立 grid 容器但宽度一致（100%），fr 比例固定 → 同列在各行对齐。 */
  .warehouse-row {
    display: grid;
    grid-template-columns: 28px minmax(72px,.85fr) minmax(96px,1.1fr) minmax(140px,1.55fr) minmax(76px,.9fr) minmax(140px,1.7fr) minmax(88px,1fr) minmax(88px,1fr) minmax(74px,.85fr) 18px;
    column-gap: 12px;
    align-items: center;
  }
  .warehouse-row .wh-line1, .warehouse-row .wh-line2 { display: contents; }
  /* v102 修正：每个元素都显式钉在 grid-row:1。不写的话 auto-placement 光标会被
     DOM 顺序靠前的状态/箭头列（第 9/10 列）推到行尾，后面的算式/单价/金额列
     会被挤到第二行（实测踩中）。显式定位后与 DOM 顺序无关。 */
  .warehouse-row .warehouse-batch-check-wrap { grid-column: 1; grid-row: 1; padding: 10px; margin: -10px; justify-self: start; }
  .warehouse-row .wh-date { grid-column: 2; grid-row: 1; }
  .warehouse-row .wh-supplier { grid-column: 3; grid-row: 1; max-width: none; }
  .warehouse-row .wh-products { grid-column: 4; grid-row: 1; }
  .warehouse-row .wh-location { grid-column: 5; grid-row: 1; max-width: none; }
  .warehouse-row .wh-expr { grid-column: 6; grid-row: 1; }
  .warehouse-row .wh-price { grid-column: 7; grid-row: 1; }
  .warehouse-row .wh-amount { grid-column: 8; grid-row: 1; }
  .warehouse-row .wh-pill-flow { grid-column: 9; grid-row: 1; justify-self: start; }
  .warehouse-row .wh-chevron { grid-column: 10; grid-row: 1; }
  /* v102：批次列表字体统一 14px（日期/供应商/品名/仓位/算式/单价/金额同号） */
  .warehouse-row .wh-date,
  .warehouse-row .wh-supplier,
  .warehouse-row .wh-products,
  .warehouse-row .wh-location,
  .warehouse-row .wh-expr,
  .warehouse-row .wh-price,
  .warehouse-row .wh-amount { font-size: 14px; }
}

/* ---------- v101：仓位徽章（品名后面的小标签） ---------- */
.warehouse-row .wh-location {
  flex: 0 0 auto; display: inline-flex; align-items: center;
  max-width: 12%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding: 2px 8px; border: 1px solid var(--line); border-radius: 6px;
  background: var(--surface-soft); color: var(--muted);
  font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums;
}
/* v102：电脑版仓位列占满 grid 单元格、字号随批次列表统一到 14px。
   必须放在上面基础样式之后，否则基础里的 max-width:12% / font-size:12px 会反覆盖。 */
@media (min-width: 1200px) {
  .warehouse-row .wh-location { max-width: none; font-size: 14px; }
}

/* ---------- v101：流程状态五种颜色块 ----------
   原来只有 completed/progress 两色，「已入库 / 已装车 / 已售出」全挤金色分不清。
   现在：入库=绿、装车=金、售出=蓝、发货=紫、客户收货=实心绿（终点态最醒目）。
   详情页 status-triple 的流程状态用的是同一个 purchaseFlowClass，一起受益。 */
.status-pill.flow-stocked { color: var(--green); background: var(--green-soft); }
.status-pill.flow-packed { color: #9a6b24; background: var(--gold-soft); }
.status-pill.flow-sold { color: #34618f; background: #e4edf6; }
.status-pill.flow-shipped { color: #655393; background: #ece7f6; }
.status-pill.flow-signed { color: #fff; background: var(--green); }

/* ---------- v102：采购仓库批次筛选栏（品名 / 供应商 / 库位 + 清空） ---------- */
.warehouse-filter-row {
  display: grid; grid-template-columns: 1fr 1fr 1fr auto;
  gap: 8px; align-items: center;
}
.warehouse-filter-row .search-box { max-width: none; }
.warehouse-filter-row .text-button { white-space: nowrap; }
@media (max-width: 1199.98px) {
  .warehouse-filter-row { grid-template-columns: 1fr; }
  .warehouse-filter-row .text-button { justify-self: start; }
}

/* v107：发票登记 · 供应商直开区 —— 显式占位 + 手机版重排。
   .invoice-row 是 4 列 grid（1.2fr 1fr .8fr 28px），全部子元素都显式 grid-row/column 定位；
   本区块若不显式定位，auto-placement 会把它塞进 28px 窄列（手机上文字竖排、整行被撑高）。
   桌面：附件第 4 行 → 本区第 5 行全宽、两个下拉并排；手机/平板：附件第 5 行 → 本区第 6 行全宽、
   下拉单列全宽、触控 ≥44px（媒体查询 + html.force-mobile 两份，按全站惯例）。 */
.inv-supplier-fields {
  grid-column: 1 / -1; grid-row: 5;
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px; align-content: start;
  padding: 10px; border: 1px dashed #e0c992; border-radius: 8px; background: #fffaf1;
}
.inv-supplier-fields label { display: grid; gap: 4px; color: var(--muted); font-size: 10px; }
.inv-supplier-fields .form-hint { grid-column: 1 / -1; margin: 0; font-size: 10px; color: var(--muted); }
.inv-supplier-fields[hidden] { display: none; }
/* 代开回款区同样补显式行位（不改其 3 列布局，只防 auto-placement 事故） */
.proxy-return-fields { grid-row: 5; }
@media (max-width: 1199.98px) {
  .inv-supplier-fields { grid-row: 6; grid-template-columns: 1fr; }
  .inv-supplier-fields select { min-height: 44px; font-size: 15px; }
  .proxy-return-fields { grid-row: 6; }
}
html.force-mobile .inv-supplier-fields { grid-column: 1 / -1; grid-row: 6; grid-template-columns: 1fr; }
html.force-mobile .inv-supplier-fields select { min-height: 44px; font-size: 15px; }
html.force-mobile .proxy-return-fields { grid-row: 6; }

/* ---------- v129：客户对账 —— 批次明细加「单件重量 / 总重量」，并把整份对账导成 Excel ----------
   批次表列数增到 8 列，手机上会被挤扁，改成横向滚动（不硬压列宽）；导出按钮手机版单列、触控 ≥44px。 */
.customer-reconcile-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.customer-reconcile-export { display: flex; flex-wrap: wrap; gap: 8px; margin: 2px 0 14px; }
@media (max-width: 1199.98px) {
  .customer-reconcile-table-wrap .ledger-table { min-width: 940px; }
  .customer-reconcile-export { display: grid; grid-template-columns: 1fr; }
  .customer-reconcile-export button { min-height: 44px; }
}
html.force-mobile .customer-reconcile-table-wrap .ledger-table { min-width: 940px; }
html.force-mobile .customer-reconcile-export { display: grid; grid-template-columns: 1fr; }
html.force-mobile .customer-reconcile-export button { min-height: 44px; }

/* ---------- v130：客户对账 —— 按「实际结算」口径列明扣重 / 扣价 ----------
   批次表加到 12 列（发货重量 / 扣重 / 结算重量 / 原单价 / 扣价 / 结算单价 / 结算金额），
   手机上必然放不下 → 横向滚动，不硬压列宽。扣过重、砍过价的批次整行标红。
   汇总卡从 4 项变 5 项（多「结算扣减」），用 auto-fit 让它自己排，不硬挤一列。 */
.customer-reconcile-summary { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); }
.customer-reconcile-summary .detail-stat small { display: block; margin-top: 4px; color: var(--muted); font-size: 10px; }
.reconcile-deduct { color: var(--red-ink); font-weight: 600; white-space: nowrap; }
.reconcile-deduct-row { background: var(--red-soft); }
.reconcile-cut { display: block; color: var(--red-ink); }
.reconcile-settled { font-weight: 650; white-space: nowrap; }
.customer-reconcile-table-wrap .ledger-table td.reconcile-deduct,
.customer-reconcile-table-wrap .ledger-table .reconcile-deduct { white-space: nowrap; }
@media (max-width: 1199.98px) {
  .customer-reconcile-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
html.force-mobile .customer-reconcile-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* ---------- v134：电脑版弹窗整体放大（后加载覆盖 styles.css，确保生效） ----------
   老板反馈电脑上弹窗仍是手机尺寸（680px / 最高 760px），长表单要上下左右滑。
   电脑版（> 1199.98px）整档放大，高上限改成跟随可视高度；移动/平板不受影响。 */
@media (min-width: 1200px) {
  .modal { width: min(920px, 100%); max-height: min(1000px, calc(100vh - 64px)); padding: 28px; }
  .modal.wide { width: min(1100px, 100%); }
  .modal.modal-purchase-wide   { width: min(1120px, 100%); }
  .modal.modal-processing-wide { width: min(1160px, 100%); }
  .modal.modal-sale-wide       { width: min(1160px, 100%); }
  .modal.modal-reconcile-wide  { width: min(1280px, 100%); }
  .modal.modal-doc-wide        { width: min(1020px, 100%); }
  .modal.modal-purchase-wide .purchase-item-editor { min-width: 980px; }
}

/* v134 续：电脑版 backdrop 允许整体滚动，超长弹窗也不会被裁掉上下两端 */
@media (min-width: 1200px) {
  .modal-backdrop { align-items: center; padding: 32px 24px; overflow: auto; }
  .modal-backdrop > .modal { margin: auto; }
}

/* ============================================================
   inv135：发票链路（① 供应商直开客户 / ② 经山鹊开票）+ 开票进度
   （后加载覆盖 styles.css，双写确保生效）
   ============================================================ */
.invoice-row .inv-supplier-fields { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 7px; padding: 9px; border: 1px dashed #cfe0d6; border-radius: 8px; background: #f6fbf8; }
.invoice-row .inv-supplier-fields label { display: grid; gap: 4px; color: var(--muted); font-size: 10px; }
.invoice-row .inv-supplier-fields .chain-hint { grid-column: 1 / -1; margin: 0; color: var(--muted); font-size: 11px; line-height: 1.55; }
.invoice-row .inv-supplier-fields[hidden], .invoice-row .inv-supplier-fields label[hidden] { display: none; }
.invoice-row .inv-chain { font-size: 11px; }
.invoice-row .inv-supplier-fields .buyer-field { grid-column: 1 / -1; }
.invoice-row .inv-supplier-fields .buyer-field input { font-size: 12px; }
.invoice-row .inv-supplier-fields { grid-row: 5; }
/* inv135：styles-minimal 里把代开回款块写死在 grid-row 5，新块插进去后要整体往后挪一行 */
.invoice-row .proxy-return-fields { grid-row: 6; }
html.force-mobile .invoice-row .inv-supplier-fields { grid-row: 6; }
html.force-mobile .invoice-row .proxy-return-fields { grid-row: 7; }


.invoice-progress { border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; margin-bottom: 14px; background: #fbfdfa; }
.invoice-progress.is-open { border-color: #e8cfa4; background: #fffaf1; }
.invoice-progress.is-full { border-color: #cfe0d6; background: var(--green-soft); }
.invoice-progress.is-over { border-color: #eccac5; background: var(--red-soft); }
.invoice-progress-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.invoice-progress-label { display: block; color: var(--muted); font-size: 11px; }
.invoice-progress-amount { display: block; font-size: 22px; line-height: 1.15; }
.invoice-progress-main small { display: block; margin-top: 4px; color: var(--muted); font-size: 11px; }
.invoice-progress-remain { text-align: right; }
.invoice-progress-remain span { display: block; color: var(--muted); font-size: 11px; }
.invoice-progress-remain strong { display: block; font-size: 18px; }
.invoice-progress.is-open .invoice-progress-remain strong { color: var(--red-ink, #9c4038); }
.invoice-progress.is-over .invoice-progress-remain strong { color: var(--red-ink, #9c4038); }
.invoice-progress.is-full .invoice-progress-remain strong { color: var(--green); }
.invoice-progress-bar { margin-top: 10px; height: 8px; border-radius: 999px; background: rgba(27, 59, 53, .1); overflow: hidden; }
.invoice-progress-bar span { display: block; height: 100%; border-radius: 999px; background: var(--green); transition: width .25s ease; }
.invoice-progress.is-open .invoice-progress-bar span { background: var(--gold); }
.invoice-progress.is-over .invoice-progress-bar span { background: var(--red); }
.invoice-progress-foot { margin-top: 7px; color: var(--muted); font-size: 11px; }

.sales-invoice-line { color: var(--green); }
.sales-invoice-line.is-pending { color: var(--red-ink, #9c4038); }
.invoice-chain-tag { display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px; background: var(--green-soft); color: var(--green); font-size: 10px; white-space: nowrap; }
.row-clickable { cursor: pointer; }
.row-clickable:hover > td { background: #f4f9f5; }
.supplier-reconcile-summary { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); }
.supplier-reconcile-summary .detail-stat small { display: block; margin-top: 4px; color: var(--muted); font-size: 10px; }
/* inv139：媒体条件跟基础字段对齐（原來只看宽度，触摸宽屏平板会漏 → 块重叠）；手机版两列紧凑 */
@media (max-width: 1199.98px), (pointer: coarse), (hover: none) {
  .invoice-row .inv-supplier-fields { grid-template-columns: 1fr 1fr; grid-row: 6; }
  .invoice-row .inv-supplier-fields .inv-return-account-field { grid-column: 1 / -1; }
  .invoice-row .proxy-return-fields { grid-row: 7; grid-template-columns: 1fr 1fr; }
  .invoice-row .proxy-return-fields label:last-child { grid-column: 1 / -1; }
  .invoice-progress-amount { font-size: 19px; }
  .supplier-reconcile-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
html.force-mobile .invoice-row .inv-supplier-fields { grid-template-columns: 1fr 1fr; }
html.force-mobile .invoice-row .inv-supplier-fields .inv-return-account-field { grid-column: 1 / -1; }
html.force-mobile .invoice-row .proxy-return-fields { grid-template-columns: 1fr 1fr; }
html.force-mobile .invoice-row .proxy-return-fields label:last-child { grid-column: 1 / -1; }
html.force-mobile .supplier-reconcile-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* inv136：客户对账「代开/代收回款」—— 提示这笔钱由开票方代收、没有经过山鹊账户 */
.reconcile-proxy { display: block; margin-top: 2px; font-size: 11px; line-height: 1.35; white-space: nowrap; }
.reconcile-proxy-strong { color: #b06a1b; }

/* ---------- inv140：客户对账「开票明细」+ 由发票直接生成合同 ----------
   发票表 7 列（开票日期/销售单、号码、开票主体、链路、金额、凭证、操作），
   手机上跟批次表一样横向滚动；「生成合同」按钮保持不换行、触控够大。 */
.reconcile-invoice-table .status-pill { white-space: nowrap; }
.reconcile-invoice-contract { white-space: nowrap; }
.reconcile-invoice-table .contact-actions { justify-content: flex-start; }
.invoice-contract-source { display: grid; gap: 10px; margin-bottom: 14px; }
.invoice-contract-source .calculation-note { margin: 0; }
.invoice-contract-source-item { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.invoice-contract-file { color: var(--muted); font-size: 12px; line-height: 1.5; }
@media (max-width: 1199.98px) {
  .invoice-contract-source-item .attach-item { min-height: 44px; }
}
html.force-mobile .invoice-contract-source-item .attach-item { min-height: 44px; }
.reconcile-invoice-table .contact-actions { flex-wrap: nowrap; white-space: nowrap; gap: 6px; }
.reconcile-invoice-table td:last-child { min-width: 150px; }
.reconcile-invoice-table td .table-secondary { display: block; max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* inv161：概览「登记发票」—— 候选卡片（与 styles.css 双写） */
.invoice-register-summary { margin-top: 12px; padding: 12px 14px; border-radius: 9px; background: var(--green-soft); color: var(--green); font-size: 13px; line-height: 1.6; }
.invoice-register-buyer-field { margin-top: 12px; }
.invoice-register-matches { margin-top: 14px; display: flex; flex-direction: column; gap: 8px; }
.invoice-register-candidate { display: block; width: 100%; text-align: left; padding: 12px 14px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); cursor: pointer; }
.invoice-register-candidate:active { border-color: var(--green); }
.invoice-register-candidate .cand-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.invoice-register-candidate .cand-head strong { font-size: 14px; color: var(--ink); }
.invoice-register-candidate .cand-meta { margin-top: 4px; font-size: 12px; color: var(--muted); line-height: 1.5; }
.invoice-register-candidate .cand-numbers { margin-top: 8px; display: flex; gap: 14px; flex-wrap: wrap; font-size: 13px; color: var(--ink); }
.invoice-register-candidate .cand-cta { display: inline-block; margin-top: 10px; font-size: 12px; font-weight: 600; color: var(--green); }

/* ---------- inv164：一笔款分到多张票（直开票收款弹窗内的分配区） ---------- */
.receipt-split-box { margin-top: 12px; padding: 12px 13px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); display: grid; gap: 6px; }
.receipt-split-head { display: grid; gap: 4px; }
.receipt-split-head strong { font-size: 12px; color: var(--ink); }
.receipt-split-head small { color: var(--muted); font-size: 10px; line-height: 1.6; }
.receipt-split-head .text-button { margin-left: 6px; }
.receipt-split-row { display: grid; grid-template-columns: minmax(0, 1fr) 118px auto; align-items: center; gap: 8px; padding: 8px 0; border-top: 1px dashed var(--line); }
.receipt-split-info { display: grid; gap: 2px; min-width: 0; }
.receipt-split-info b { font-size: 12px; color: var(--ink); }
.receipt-split-info span { font-size: 10px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.receipt-split-amount { width: 100%; box-sizing: border-box; padding: 6px 8px; border: 1px solid var(--line); border-radius: 7px; background: var(--surface); color: var(--ink); text-align: right; font-size: 12px; }
.receipt-split-sum { font-size: 11px; color: var(--muted); line-height: 1.6; }
.receipt-split-sum b { color: var(--green); }
@media (max-width: 640px) {
  .receipt-split-row { grid-template-columns: minmax(0, 1fr) 96px; }
  .receipt-split-row .receipt-split-fill { grid-column: 1 / -1; justify-self: start; }
}
html.force-mobile .receipt-split-row { grid-template-columns: minmax(0, 1fr) 96px; }
html.force-mobile .receipt-split-row .receipt-split-fill { grid-column: 1 / -1; justify-self: start; }



/* ============ v3.12：登记发票重排 —— 每张发票一张卡片分隔开；字段说明直接写进输入框/下拉；
   「开票方式」与「开票链路」合并成一个下拉（链路存隐藏域），购买方/供货方/超额回款账户去掉外置标签 ============ */
.invoice-row { border: 1px solid #d7e3da; border-radius: 10px; background: #fbfdfc; padding: 14px 12px 10px 16px; box-shadow: 0 1px 2px rgba(20, 60, 40, .06); margin-bottom: 14px; }
.invoice-row .inv-supplier-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 2px; }
.invoice-row .inv-supplier-fields .buyer { grid-column: 1 / -1; }
.invoice-row .inv-supplier-fields .inv-return-account-field[hidden] { display: none; }
html.force-mobile .invoice-row .inv-supplier-fields { grid-template-columns: 1fr; }
html.force-mobile .invoice-row .inv-supplier-fields .inv-return-account-field { grid-column: 1 / -1; }
