:root {
  --bg: #f4f6fa;
  --surface: #ffffff;
  --surface-2: #fafbfd;
  --border: #e4e8f0;
  --border-strong: #d3d9e4;
  --border-heavy: #a9b2c1; /* 加粗分隔线（结算表三大合计行的下边框） */
  --text: #1c2430;
  --text-2: #5a6577;
  --muted: #8a93a4;
  --primary: #1a6cf0;
  --primary-weak: #eaf1fe;
  --success: #12a150;
  --success-weak: #e7f7ee;
  --warn: #d97706;
  --warn-weak: #fef4e6;
  --danger: #d92d20;
  --danger-weak: #fdeceb;
  --purple: #7c3aed;
  --purple-weak: #f3edfe;
  --teal: #0d9488;
  --teal-weak: #e6f6f4;
  --radius: 10px;
  --shadow: 0 1px 2px rgba(16, 24, 40, 0.04), 0 4px 14px rgba(16, 24, 40, 0.05);
  --shadow-lg: 0 12px 36px rgba(16, 24, 40, 0.16);
  --sidebar-w: 216px;
}

* { box-sizing: border-box; }
/* hidden 属性必须真的隐藏：作者样式里的 display（如 .btn{display:inline-flex}）会盖过 UA 的
   [hidden]{display:none}——2026-09-28「取消选择」按钮在未选中时就渲染出来了，就是踩了这个。 */
[hidden] { display: none !important; }
html, body { margin: 0; padding: 0; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--primary); text-decoration: none; }
h1, h2, h3, h4 { margin: 0; font-weight: 600; }

/* ============ 登录页 ============ */
.login-wrap {
  min-height: 100vh;
  display: flex;
  /* 纵向排：登录卡在上、ICP 页脚在下（2026-10-28） */
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: linear-gradient(150deg, #eef3fd 0%, #f7f9fc 45%, #f1f5fb 100%);
  padding: 24px;
}
.login-card {
  width: 100%;
  max-width: 400px;
  background: var(--surface);
  border-radius: 16px;
  box-shadow: var(--shadow-lg);
  padding: 32px 30px 26px;
}
.login-brand { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 6px; }
.login-brand .logo { width: 34px; height: 34px; object-fit: contain; flex: 0 0 auto; }
.login-brand .dot {
  width: 34px; height: 34px; border-radius: 9px;
  background: linear-gradient(135deg, #1a6cf0, #4d8ff5);
  color: #fff; display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 15px; letter-spacing: -.5px;
}
.login-brand h1 { font-size: 18px; }
.login-sub { color: var(--muted); font-size: 13px; margin-bottom: 22px; }
.entry-tabs { display: flex; background: var(--surface-2); border: 1px solid var(--border); border-radius: 9px; padding: 3px; margin-bottom: 20px; }
.entry-tabs button {
  flex: 1; border: 0; background: transparent; padding: 8px 0; border-radius: 7px;
  font-size: 13.5px; color: var(--text-2); cursor: pointer; font-family: inherit; transition: all .15s;
}
.entry-tabs button.on { background: var(--surface); color: var(--primary); font-weight: 600; box-shadow: 0 1px 3px rgba(16,24,40,.1); }

/* ============ 付款管理顶部三个入口（2026-09-28 改版） ============ */
/* 原来是挤在 480px 里的 entry-tabs 分段控件：看着像标签不像按钮、三个还贴在一起。
   现在每个入口是一张**按钮卡片**（图标 + 标题 + 一句说明 + 待办数字徽标），用 gap 拉开距离；
   数字为 0 时徽标转灰，不再抢眼，但仍然显示（用户要求「按钮上显示各自的待办数字」）。 */
.pay-tabs { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 18px; }
.pay-tab {
  flex: 1 1 230px; min-width: 210px;
  display: flex; align-items: center; gap: 12px; text-align: left;
  padding: 13px 16px; border: 1px solid var(--border-strong); border-radius: 12px;
  background: var(--surface); color: var(--text); font: inherit; font-size: 13.5px;
  cursor: pointer; transition: all .15s; box-shadow: var(--shadow);
}
.pay-tab:hover { border-color: var(--primary); color: var(--text); }
.pay-tab.on { border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-weak); }
.pay-tab .pt-ico {
  flex: 0 0 auto; width: 36px; height: 36px; border-radius: 10px; background: var(--surface-2);
  display: flex; align-items: center; justify-content: center; font-size: 17px;
}
.pay-tab.on .pt-ico { background: var(--primary-weak); }
.pay-tab .pt-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.pay-tab .pt-label { font-weight: 600; line-height: 1.5; }
.pay-tab.on .pt-label { color: var(--primary); }
.pay-tab .pt-sub { font-size: 11.5px; color: var(--muted); line-height: 1.5; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pay-tab .pt-count {
  flex: 0 0 auto; min-width: 24px; height: 22px; padding: 0 7px; border-radius: 11px;
  background: var(--danger); color: #fff; font-size: 12px; font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center;
}
.pay-tab .pt-count.zero { background: #eef1f6; color: var(--muted); }

/* ============ 表单 ============ */
.field { margin-bottom: 14px; }
.field label { display: block; font-size: 12.5px; color: var(--text-2); margin-bottom: 6px; font-weight: 500; }
.field label .req { color: var(--danger); margin-left: 2px; }
/* 联系人 1 必填：小标题上的红星（2026-10-22），与字段 label 里那颗同一个色 */
.contact-block h4 .req { color: var(--danger); margin-left: 2px; }
input[type=text], input[type=password], input[type=number], input[type=date], input[type=email], select, textarea {
  width: 100%; padding: 9px 11px; border: 1px solid var(--border-strong); border-radius: 8px;
  font-size: 13.5px; font-family: inherit; color: var(--text); background: #fff; transition: border-color .15s, box-shadow .15s;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(26,108,240,.12); }
/* 校验没过时聚焦的输入框标红（2026-10-22 联系人必填）；一输入就撤掉（views.registry.js）。
   ⚠️ 必须写在 :focus 之后并带上 :focus —— 出错时会主动 focus 到那个框，
   否则蓝框会把红框盖掉，用户看不出是哪个字段的问题。 */
input.inp-err, select.inp-err,
input.inp-err:focus, select.inp-err:focus { border-color: var(--danger); box-shadow: 0 0 0 3px rgba(224,49,49,.14); }
textarea { resize: vertical; min-height: 62px; }
input:disabled, select:disabled { background: #f3f5f9; color: var(--muted); }

/* ============ 按钮 ============ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 15px; border-radius: 8px; border: 1px solid var(--border-strong);
  background: #fff; color: var(--text); font-size: 13.5px; font-family: inherit;
  cursor: pointer; transition: all .15s; white-space: nowrap;
}
.btn:hover { border-color: var(--primary); color: var(--primary); }
.btn-primary { background: var(--primary); border-color: var(--primary); color: #fff; }
.btn-primary:hover { background: #1559cc; border-color: #1559cc; color: #fff; }
.btn-success { background: var(--success); border-color: var(--success); color: #fff; }
.btn-success:hover { background: #0e8a43; color: #fff; }
.btn-danger { background: #fff; border-color: #f0b4b0; color: var(--danger); }
.btn-danger:hover { background: var(--danger-weak); border-color: var(--danger); color: var(--danger); }
.btn-danger-solid { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn-danger-solid:hover { background: #c8322b; border-color: #c8322b; color: #fff; }
.btn-ghost { border-color: transparent; background: transparent; color: var(--text-2); }
.btn-ghost:hover { background: var(--primary-weak); color: var(--primary); border-color: transparent; }
.btn-sm { padding: 5px 10px; font-size: 12.5px; border-radius: 7px; }
.btn-block { width: 100%; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

/* ============ 站点页脚 / ICP 备案（2026-10-28） ============
   工信部要求：已备案站点每页底部都要能看到备案号，且必须链到 https://beian.miit.gov.cn/。
   app.html（后台，在 .main 底部 —— .content 是 flex:1，短页面时页脚也被顶到视口底）
   与 login.html（登录页 = 站点首页）各有一份；登录页那份不要上边框和底色，融进渐变背景。 */
.site-foot {
  flex: 0 0 auto;
  border-top: 1px solid var(--border);
  background: var(--surface);
  color: var(--muted);
  font-size: 12px;
  line-height: 1.7;
  padding: 10px 22px;
  text-align: center;
}
/* 两段各自不折行：窄屏（390）下若整行放不下，就让「备案号」整体掉到第二行，
   绝不能把「沪ICP备2026056165号」从中间劈开（数字被折断就看不清了）。 */
.site-foot span, .site-foot a { white-space: nowrap; }
.site-foot span + a { margin-left: 10px; }
.site-foot a { color: var(--muted); }
.site-foot a:hover { color: var(--primary); text-decoration: underline; }
.site-foot-login { border-top: 0; background: transparent; padding: 16px 22px 0; }

/* ============ 布局 ============ */
.layout { display: flex; min-height: 100vh; }
.sidebar {
  width: var(--sidebar-w); flex: 0 0 var(--sidebar-w); background: #fff;
  border-right: 1px solid var(--border); display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
}
.side-brand { padding: 18px 18px 14px; border-bottom: 1px solid var(--border); display: flex; gap: 10px; align-items: center; }
.side-brand .dot {
  width: 30px; height: 30px; border-radius: 8px; background: linear-gradient(135deg, #1a6cf0, #4d8ff5);
  color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 13px;
}
.side-brand .logo { width: 30px; height: 30px; object-fit: contain; flex: 0 0 auto; }
.side-brand b { font-size: 14.5px; display: block; line-height: 1.25; }
.side-brand span { font-size: 11.5px; color: var(--muted); }
.nav { padding: 10px 10px 24px; overflow-y: auto; flex: 1; }
.nav-group { font-size: 11px; color: var(--muted); padding: 14px 10px 6px; letter-spacing: .5px; }
.nav a {
  display: flex; align-items: center; gap: 9px; padding: 8px 10px; border-radius: 8px;
  color: var(--text-2); font-size: 13.5px; margin-bottom: 2px; transition: all .12s;
}
.nav a:hover { background: var(--surface-2); color: var(--text); }
.nav a.on { background: var(--primary-weak); color: var(--primary); font-weight: 600; }
.nav a .ico { width: 16px; text-align: center; font-size: 14px; }
.nav a .badge { margin-left: auto; background: var(--danger); color: #fff; font-size: 10.5px; padding: 1px 6px; border-radius: 9px; font-weight: 600; }
/* ---------- 二级菜单（2026-10-23 用户要求） ----------
   客户费用不再和「客户 / 供应商 / 货代 / 其他服务商」并列，改成挂在「客户」下面：
   默认只显示 4 个一级项；点「客户」或进到客户费用页时，客户费用才展开显示。
   ⚠️ 选择器要带 `a`（.nav a.nav-sub）：`.nav a` 特异性 (0,1,1) 会压过单纯 `.nav-sub`。 */
.nav a.nav-parent { user-select: none; }
.nav a.nav-parent.open { color: var(--text); }
.nav a.nav-parent.open.on { color: var(--primary); }
.nav a.nav-sub {
  display: none; margin-left: 17px; padding-left: 12px;
  border-left: 2px solid var(--border); border-radius: 0 8px 8px 0;
  font-size: 13px; color: var(--text-2);
}
.nav a.nav-sub.open { display: flex; }
.nav a.nav-sub.on { background: var(--primary-weak); color: var(--primary); font-weight: 600; border-left-color: var(--primary); }
.side-foot { border-top: 1px solid var(--border); padding: 12px 14px; font-size: 12.5px; color: var(--text-2); }
.side-foot .who { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.avatar { width: 28px; height: 28px; border-radius: 50%; background: var(--primary-weak); color: var(--primary); display: flex; align-items: center; justify-content: center; font-size: 12.5px; font-weight: 600; }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.topbar {
  height: 56px; background: #fff; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; padding: 0 22px; gap: 14px; position: sticky; top: 0; z-index: 20;
}
.topbar h2 { font-size: 16px; }
.topbar .crumb { color: var(--muted); font-size: 12.5px; }
.topbar .spacer { flex: 1; }
.content { padding: 22px; flex: 1; }
/* 手机端的汉堡按钮（2026-10-23）：桌面端不显示，见文件末尾 820px 断点里再打开。
   放顶栏最左，抽屉由 core.js#initMobileNav 控制。 */
.nav-toggle {
  display: none; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: 0 0 auto; padding: 0;
  border: 1px solid var(--border-strong); border-radius: 8px; background: #fff;
  color: var(--text-2); font-size: 17px; line-height: 1; cursor: pointer;
}
.nav-toggle:hover { border-color: var(--primary); color: var(--primary); }

/* ============ 卡片 / 网格 ============ */
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); }
.card + .card { margin-top: 16px; }
/* 网格里的并排卡片由 gap 管间距：若沿用「相邻卡片上外边距」，grid 拉伸高度会被这 16px 吃掉，
   导致第二张卡比第一张矮 16px（工作台「收款概览 / 近期订单」曾如此）。 */
.grid > .card + .card { margin-top: 0; }
.card-head { padding: 14px 18px; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.card-head h3 { font-size: 14.5px; }
.card-head .spacer { flex: 1; }
/* 卡片表头可点跳转（2026-10-24）：工作台「收款概览 → 收款看板」「近期订单 → 全部订单」
   两个右上角按钮已删，入口收敛到表头本身 —— 整条表头可点，标题后挂 › 箭头提示可点。 */
.card-head.linkable { cursor: pointer; user-select: none; }
.card-head.linkable:hover > h3 { text-decoration: underline; }
.ttl-arrow { color: var(--muted); font-size: 15px; line-height: 1; margin-left: -4px; transition: transform .12s, color .12s; }
.card-head.linkable:hover > .ttl-arrow { color: var(--acc-text); transform: translateX(3px); }
/* 收款概览被截断时的补充文案（「共 N 笔 · 显示最近 8 笔，点表头看全部」）——
   用主题色跟前面的灰色计数区分开：这句是指路用的，不是附注。 */
.card-head .hint .ov-more { color: var(--acc-text); opacity: .8; }
.card-body { padding: 18px; }
.card-body.tight { padding: 0; }

.grid { display: grid; gap: 14px; }
.grid-1 { grid-template-columns: 1fr; } /* 单卡独占一行（如跟单员工作台只剩「订单总数」/「近期订单」时） */
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.grid-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 1100px) { .grid-4 { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 820px) {
  .layout { flex-direction: column; }
  .sidebar { width: 100%; flex: none; height: auto; position: static; }
  .grid-4, .grid-3, .grid-2, .grid-5, .grid-6 { grid-template-columns: 1fr; }
}

.stat { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px 18px; box-shadow: var(--shadow); }
.stat .label { font-size: 12.5px; color: var(--text-2); margin-bottom: 6px; }
.stat .value { font-size: 23px; font-weight: 650; letter-spacing: -.4px; }
.stat .sub { font-size: 12px; color: var(--muted); margin-top: 4px; }
.stat.accent .value { color: var(--primary); }
.stat.warn .value { color: var(--warn); }
.stat.success .value { color: var(--success); }
.stat.danger .value { color: var(--danger); }
/* 合同总金额卡：拆成「执行中订单 / 已完成订单」两行金额 */
.stat .split { margin-top: 2px; }
.stat .split .row-line { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding: 5px 0; }
.stat .split .row-line + .row-line { border-top: 1px dashed var(--border); }
.stat .split .k { font-size: 12.5px; color: var(--text-2); white-space: nowrap; }
.stat .split .v { font-size: 17px; font-weight: 650; letter-spacing: -.3px; }

/* 工作台底部并排的「收款概览 / 近期订单」：两张卡**各自按内容定高**，行数不同就高度不同
   （用户 2026-09-30：两边行数本来就不同，不必等高）。
   grid 默认 align-items:stretch 会把矮的那张拉伸到和高的一样高，在表格下面留出一块空白，
   所以这里显式写成 start —— 别删，删了又会变回强制等高。
   行高仍统一 40px：近期订单行里有状态标签，行高本就比收款概览高一点，统一后单卡内视觉更整齐。 */
.dash-pair { align-items: start; }
.dash-pair table.tbl.compact td { height: 40px; }
/* 收款概览（.ov-tbl）7 列挤在半宽卡片里 —— 2026-10-24 用户拍板「不折行，改成横滑」：
   ① 整表 nowrap：原先「备注」「付款人」会折成两行，8 行卡片被撑到 693px（旁边近期订单才 544px），
      两卡视觉差一大截；nowrap 后行高回到 40px，卡片高度与近期订单基本齐平。
   ② 备注是自由文本，无限 nowrap 会把它撑到上千像素 —— 单列用 span 截断 + 省略号，全文挂 title。
   ③ min-width 兜底 + .table-wrap 的 overflow-x:auto 横滑（与收款看板 .rcp-tbl 同一套做法）。
   ⚠️ 别改成卡片内纵向滚动：企微 WebView 里是嵌套滚动条，要滚两次，滚轮还会被卡片「吃掉」。 */
table.tbl.ov-tbl { min-width: 700px; }
table.tbl.ov-tbl th,
table.tbl.ov-tbl td { padding-left: 10px; padding-right: 10px; white-space: nowrap; }
table.tbl.ov-tbl td.ov-memo > span { display: block; max-width: 190px; overflow: hidden; text-overflow: ellipsis; }
/* 近期订单（.ord-tbl）：同轮（2026-10-24）用户要求「内容在一行显示不下时不要折行，显示不下的用省略号」——
   目的就是让**两张卡行数相同时高度一样**（都回到 40px/行），而不是靠横向滚动去够右边的内容。
   ⚠️ 必须用 `table-layout: fixed`：自动布局下列宽由内容的 min-content 决定，而 nowrap 的长订单号
      （演示库里的 `VERIFY-RLOCK-B-1790913376536`）min-content 就有两百多像素，会把整表撑出容器；
      写在 td 上的 max-width 在自动布局里只是参考值，拦不住。fixed 下宽度由 th 的百分比定，
      超出部分交给 `overflow:hidden + text-overflow:ellipsis` 变成省略号。
   ⚠️ 每个 th / td 都要带 ord-* 宽度类 —— 没指定宽度的列会被均分剩余空间，长订单号就压不住了。
   ⚠️ 4 列版（订单号/客户/金额/状态）与跟单员 5 列版（+业务员/预计交货日期）共用这一套百分比：
      加总不足 100% 时浏览器会按比例把余量摊回去，两版都够用。 */
table.tbl.ord-tbl { table-layout: fixed; min-width: 460px; }
table.tbl.ord-tbl th,
table.tbl.ord-tbl td { padding-left: 10px; padding-right: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tbl.ord-tbl .ord-no { width: 24%; }
table.tbl.ord-tbl .ord-cust { width: 22%; }
table.tbl.ord-tbl .ord-sales { width: 16%; }
table.tbl.ord-tbl .ord-due { width: 18%; }
table.tbl.ord-tbl .ord-amt { width: 18%; }
table.tbl.ord-tbl .ord-st { width: 18%; }

/* ============ 表格 ============ */
.table-wrap { overflow-x: auto; }
table.tbl { width: 100%; border-collapse: collapse; font-size: 13.5px; }
table.tbl th {
  text-align: left; padding: 10px 14px; background: var(--surface-2); color: var(--text-2);
  font-weight: 600; font-size: 12.5px; border-bottom: 1px solid var(--border); white-space: nowrap;
}
table.tbl td { padding: 11px 14px; border-bottom: 1px solid var(--border); vertical-align: middle; }
table.tbl tbody tr:hover { background: #fbfcfe; }
table.tbl tbody tr:last-child td { border-bottom: 0; }
table.tbl td.num, table.tbl th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.tbl td.actions { white-space: nowrap; text-align: right; }
/* 收款看板（.rcp-tbl）：13 列横向很挤，三件事：
   ① 编号 / 订单号 / 币种 / 分配笔数 不换行 —— 否则「RC0001」「SO-2026-0001」「13」会被折成两行；
   ② 左右内边距由 14px 收到 10px，省出约 88px（11 列 × 8px），让「付款人」这类文字列少折行；
   ③ 整表设 min-width：容器装不下就由 .table-wrap 的 overflow-x:auto 横向滚动。
   ⚠️ ③ 是 2026-10-23 加「收款编号」列时补的 —— 不设 min-width，浏览器会按最小内容宽度硬挤，
      于是「附言」被压成一字一行、「分配笔数」竖排成「分/配/笔/数」，比横向滚动难看得多。 */
table.tbl.rcp-tbl { min-width: 1180px; }
table.tbl.rcp-tbl th,
table.tbl.rcp-tbl td { padding-left: 10px; padding-right: 10px; }
table.tbl.rcp-tbl td.rcp-nodate,
table.tbl.rcp-tbl td.rcp-od,
table.tbl.rcp-tbl td.rcp-cur,
table.tbl.rcp-tbl th.rcp-cnt { white-space: nowrap; }
/* 附言：允许折行，但不许压成竖条 */
table.tbl.rcp-tbl th.rcp-memo,
table.tbl.rcp-tbl td.rcp-memo { min-width: 110px; }
/* 收款看板「订单号」列（2026-09-30 用户要求）：一笔款拆到多个订单时**竖排**，
   每行 = 订单号链接 + 该单分到的金额。竖排是为了让金额跟订单号对齐成两列 ——
   原来用「·」并排，多单时会拉成一长条，既看不出哪个单分了多少，也会把「操作」列挤出去。 */
.rcp-orders { display: flex; flex-direction: column; gap: 2px; }
.rcp-orders .rcp-o { display: flex; align-items: baseline; gap: 8px; }
.rcp-orders .rcp-o a { display: inline-block; white-space: nowrap; }
.rcp-orders .rcp-oamt { margin-left: auto; color: var(--text-2); font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* 费用认领列表（.claim-tbl）：11 列，且「订单号」列可能同时显示多个订单号（一笔费用拆到多单）。
   规则：① 每个订单号**自身**不折行（inline-block + nowrap）—— 否则「SO-2026-0001」会在连字符处断成两行；
        ② 单元格**不加** nowrap —— 多个订单号之间允许折行，这样列宽不会把「操作」列挤出可视区。
   （对比收款看板 .rcp-tbl 的 td.rcp-od：那里一格只放订单号链接、列很窄，整格 nowrap 更划算。） */
table.tbl.claim-tbl th,
table.tbl.claim-tbl td { padding-left: 10px; padding-right: 10px; }
table.tbl.claim-tbl td.claim-od a { display: inline-block; white-space: nowrap; }
table.tbl.compact td, table.tbl.compact th { padding: 8px 12px; }
/* 客户费用列表 —— 与收款看板 .rcp-tbl 同一套处理：
   ① 编号 / 登记人 / 币种 / 状态 不换行 —— 否则「CF20261023-002」在连字符处断成两行、
      「系统管理员」压成「系统管理/员」；
   ② 左右内边距 14 → 10，列多时省宽度；
   ③ min-width 兜底 + .table-wrap 横向滚动。
   ⚠️ 不设 min-width 时浏览器按最小内容宽度硬挤，「其他」会竖排成「其/他」—— 比横向滚动难看。
   2026-10-23：去掉「类型」「发生日期」两列（13 → 11 列），min-width 1180 → 1020。 */
table.tbl.cf-tbl { min-width: 1020px; }
table.tbl.cf-tbl th,
table.tbl.cf-tbl td { padding-left: 10px; padding-right: 10px; }
table.tbl.cf-tbl td.cf-no,
table.tbl.cf-tbl td.cf-user,
table.tbl.cf-tbl td.cf-cur,
table.tbl.cf-tbl td.cf-tag { white-space: nowrap; }
/* 事由 / 我方垫付：给列一个下限宽度，别让「展位搭建代垫（演示）」折成三行、
   「2026-10-23」在连字符处断成两行。 */
table.tbl.cf-tbl td.cf-title { min-width: 132px; }
table.tbl.cf-tbl td.cf-pay { min-width: 96px; }
table.tbl.cf-tbl .cf-nowrap { white-space: nowrap; }
/* 客户费用附件（2026-10-23 用户要求：备注里能传附件）—— 复用全局 .drop / .file-list，
   这里只补三件小事：列表上间距、空态不画边框、上传中把按钮压住防重复点。 */
.cf-files { margin-top: 8px; }
.cf-files li.empty-li { border: none; background: transparent; padding: 0; margin: 0; }
.cf-drop.busy { opacity: .55; pointer-events: none; }
.cf-files .cf-file-x { padding: 0 8px; line-height: 1.6; }
/* 事由下面的「📎 N 个附件」提示 */
.cf-att { color: var(--text-2); }
/* 展开明细里的附件行 */
.cf-att-box { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.cf-att-link { font-size: 12.5px; }
.mono { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace; font-size: 12.5px; }

/* ============ 标签 ============ */
.tag { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 20px; font-size: 12px; font-weight: 500; line-height: 1.6; white-space: nowrap; }
.tag-blue { background: var(--primary-weak); color: var(--primary); }
.tag-green { background: var(--success-weak); color: var(--success); }
.tag-orange { background: var(--warn-weak); color: var(--warn); }
.tag-red { background: var(--danger-weak); color: var(--danger); }
.tag-purple { background: var(--purple-weak); color: var(--purple); }
.tag-teal { background: var(--teal-weak); color: var(--teal); }
.tag-gray { background: #eef1f6; color: var(--text-2); }

/* 筛选栏里的复选框（「含停用」，2026-10-09） */
.chk-inline { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-2); cursor: pointer; user-select: none; white-space: nowrap; }
.chk-inline input { margin: 0; cursor: pointer; }

/* 停用行：整行压暗，与「已停用」灰标签呼应；⚠️ 操作列要留清晰（「启用」按钮得看得见） */
tr.row-off > td { opacity: 0.55; }
tr.row-off > td.actions { opacity: 1; }

/* ============ 员工管理：部门分组表（2026-10-23 部门表 + 员工表合并） ============
   ① .grp-row 是分组头（部门 / 公司管理 / 未设部门），整行可点开合，所以 td 不留内边距，
      由 .grp-inner 撑开，点击热区才覆盖整行；
   ② 子行（.emp-row）首列留 30px 缩进，视觉上挂在部门下面；
   ③ 分组行的鼠标悬停要单独写 —— 基础样式是 tr:hover 变色，而这里 td 自带背景色会盖掉它。 */
table.tbl.org-tbl tr.grp-row > td { padding: 0; background: var(--surface-2); }
table.tbl.org-tbl tr.grp-row:hover > td { background: #f2f6fd; }
.grp-inner { display: flex; align-items: center; gap: 10px; padding: 10px 14px; cursor: pointer; user-select: none; }
.grp-arrow { width: 12px; flex: 0 0 12px; color: var(--muted); font-size: 11px; line-height: 1; }
.grp-count { font-size: 12.5px; color: var(--text-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.grp-meta { font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.grp-actions { margin-left: auto; display: flex; gap: 6px; flex: 0 0 auto; }
table.tbl.org-tbl tr.emp-row > td:first-child { padding-left: 30px; }
table.tbl.org-tbl tr.emp-empty > td { color: var(--muted); font-size: 12.5px; padding-left: 30px; background: #fcfdff; }

/* ============ 工具条 ============ */
.toolbar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 16px; }
.toolbar select, .toolbar input[type="date"] { min-width: 132px; }
.toolbar .search { flex: 0 1 auto; }
.toolbar .spacer { flex: 1; }
.toolbar .settle-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; justify-content: center; }
/* 日期区间「起 ~ 至 ~」包成一个**不可拆的小组**（费用认领 / 收款看板筛选条，2026-10-24）：
   .toolbar 是 flex-wrap，裸放两个 date + 一个「至」时，1296px 企微窗口下会把「至」单独留在
   上一行行尾（读起来像「至」后面没了）。包成 inline-flex 且 nowrap 后，换行时整组一起下移。
   ⚠️ 宽度写在这里而不是行内 style：行内 max-width 在手机断点下压不住（特异性最高），
      390px 下两个日期就摊不开整行。 */
.toolbar .df-range { display: inline-flex; gap: 6px; align-items: center; flex: 0 0 auto; white-space: nowrap; }
.toolbar .df-range input[type="date"] { width: 132px; min-width: 0; flex: 0 0 auto; }
/* 全局 .hint 带 margin-top:4px（那是给表单下面的说明行用的），在这里会把「至」顶偏，清掉 */
.toolbar .df-range .hint { flex: 0 0 auto; margin-top: 0; }
/* 筛选条下拉的定宽（费用认领 / 收款看板，2026-10-24）。
   ⚠️ 定宽写在 CSS 里、别写行内 style：行内 max-width 特异性最高，手机断点压不住，
      390px 下「全部币种」只剩「全部币」+ 一个压在字上的箭头（实测截图）。
   min-width:0 是为了压掉 `.toolbar select` 的 min-width:132px，否则币种框想窄也窄不下来。 */
.toolbar .f-st { flex: 0 0 auto; width: 140px; min-width: 0; }
.toolbar .f-cur { flex: 0 0 auto; width: 100px; min-width: 0; }
.toolbar .f-acc { flex: 0 0 auto; width: 148px; min-width: 0; }
.toolbar .f-who { flex: 0 0 auto; width: 148px; min-width: 0; }
/* 「重置 + 导出 Excel」包成一个**不可拆的小组**（订单管理 / 收款看板 / 付款管理 / 费用认领，2026-10-24）。
   用户口径：导出按钮必须在「重置」右边。但 .toolbar 是 flex-wrap，窄窗口（企微 1296）下两个按钮会
   被拆到两行 —— 从 DOM 看仍是「重置的下一个兄弟节点」，从屏幕看却各占一行，等于没满足要求。
   包成 inline-flex + nowrap 后：换行时整组一起下移，两个按钮永远同一行、左右相邻。 */
.toolbar .act-group { display: inline-flex; gap: 10px; align-items: center; flex: 0 0 auto; white-space: nowrap; }
.search { position: relative; }
.search input { padding-left: 30px; min-width: 210px; }
.search::before { content: "🔍"; position: absolute; left: 9px; top: 50%; transform: translateY(-50%); font-size: 12px; opacity: .5; }

/* ============ 弹窗 ============ */
.modal-mask {
  position: fixed; inset: 0; background: rgba(18, 24, 38, .45); z-index: 100;
  display: flex; align-items: flex-start; justify-content: center; padding: 40px 16px; overflow-y: auto;
  animation: fade .16s ease;
}
.modal {
  background: #fff; border-radius: 14px; width: 100%; max-width: 720px;
  box-shadow: var(--shadow-lg); animation: pop .18s ease; margin: auto 0;
}
.modal.wide { max-width: 940px; }
.modal.narrow { max-width: 460px; }
/* 采购合同弹窗（2026-10-26）：明细表 6 列 + 二～八条 + 一般条款 9 条，比普通 wide 弹窗再宽再高一档，
   否则 68vh 里滚半天才看得到条款。只影响这一类弹窗，别的弹窗尺寸不动。 */
.modal.pcd-modal { max-width: 1000px; }
.modal.pcd-modal .modal-body { max-height: 80vh; }
.modal-head { padding: 16px 20px; border-bottom: 1px solid var(--border); display: flex; align-items: center; }
.modal-head h3 { font-size: 15px; }
.modal-head .x { margin-left: auto; cursor: pointer; color: var(--muted); font-size: 20px; line-height: 1; padding: 0 4px; border: 0; background: none; }
.modal-head .x:hover { color: var(--danger); }
.modal-body { padding: 20px; max-height: 68vh; overflow-y: auto; }
.modal-foot { padding: 14px 20px; border-top: 1px solid var(--border); display: flex; gap: 10px; justify-content: flex-end; }
@keyframes fade { from { opacity: 0 } to { opacity: 1 } }
@keyframes pop { from { opacity: 0; transform: translateY(8px) scale(.99) } to { opacity: 1; transform: none } }

/* ============ 分组表单 ============ */
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 0 16px; }
.form-grid .full { grid-column: 1 / -1; }
/* 单据表头「客户名称」= 下拉 + 「＋ 新建客户」（2026-10-21） */
.cust-pick { display: flex; gap: 8px; align-items: stretch; }
.cust-pick select { min-width: 0; }
.cust-pick .btn { white-space: nowrap; }

/* 国家/地区 = 中英文可搜索组合框（2026-10-21）：249 个国家/地区，原生下拉找起来太慢 */
.ctry { position: relative; }
.ctry-box { position: relative; }
.ctry-box .ctry-q { padding-right: 30px; }
.ctry-arrow { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); font-size: 13px; line-height: 1; color: var(--text-2); pointer-events: none; }
.ctry-pop {
  position: absolute; left: 0; top: calc(100% + 4px); z-index: 60;
  min-width: 100%; width: max-content; max-width: min(560px, calc(100vw - 48px));
  background: #fff; border: 1px solid var(--border-strong); border-radius: 9px;
  box-shadow: 0 10px 26px rgba(16, 24, 40, .16); max-height: 252px; overflow-y: auto;
}
.ctry-list { padding: 4px; }
.ctry-item { display: flex; align-items: center; gap: 8px; padding: 6px 9px; border-radius: 7px; font-size: 13px; cursor: pointer; }
.ctry-item .cn { white-space: nowrap; color: var(--text); }
.ctry-item .en { flex: 1; min-width: 0; color: var(--muted); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ctry-item .code { font-size: 11.5px; color: var(--muted); letter-spacing: .04em; }
.ctry-item:hover, .ctry-item.on { background: var(--primary-weak); }
.ctry-item.sel .cn { color: var(--primary); font-weight: 600; }
.ctry-item.sel .code { color: var(--primary); }
.ctry-item b { color: var(--primary); font-weight: 600; background: rgba(26, 108, 240, .12); border-radius: 3px; }
.ctry-empty { padding: 12px 10px; text-align: center; font-size: 12.5px; color: var(--muted); }
.ctry-foot {
  position: sticky; bottom: 0; padding: 5px 10px 6px; border-top: 1px solid var(--border);
  background: #fff; font-size: 11.5px; color: var(--muted);
}
/* 「✕ 清空」：列表筛选器要有「回到全部国家/地区」的出路（选了就露出来，没选就藏起来） */
.ctry-clear {
  position: absolute; right: 26px; top: 50%; transform: translateY(-50%);
  border: 0; background: none; color: var(--muted); font-size: 12px; line-height: 1;
  padding: 3px 5px; border-radius: 4px; cursor: pointer;
}
.ctry-clear:hover { background: var(--primary-weak); color: var(--text); }
.ctry.has-clear .ctry-box .ctry-q { padding-right: 52px; }
/* 列表顶部工具栏里当筛选用：宽度对齐原来那个 200px 的原生下拉，
   别再宽 —— 宽 32px 就会在 PC 企微那种 ~1100px 窗口里把工具栏挤成两行（2026-10-21 实测） */
.toolbar .ctry { width: 200px; flex: 0 0 auto; }
/* 汇率页的币种搜索框（2026-10-23）：与国家选择器共用 .ctry-* 样式，只补宽度。
   弹层位置由 JS 设成 position:fixed（表格容器 overflow-x:auto 会把 absolute 弹层裁掉），
   所以这里的 z-index 要压过表格/卡片。 */
.curpick { min-width: 170px; }
.curpick .ctry-q { width: 100%; min-width: 150px; }
/* ⚠️ min-width:0 不能省：.ctry-pop 原本是 min-width:100%（相对 .curpick），
   换成 position:fixed 后百分比改成相对**视口**，弹层会被撑成整屏宽（2026-10-23 实测 1296px）。 */
.curpick .ctry-pop { min-width: 0; z-index: 80; }
@media (max-width: 700px) { .form-grid { grid-template-columns: 1fr; } }
.form-sep { border: none; border-top: 1px dashed var(--border); margin: 16px 0 4px; }
.form-sep-label { font-size: 12px; color: var(--muted); font-weight: 600; letter-spacing: .03em; margin: 0 0 10px; }
.section-title {
  font-size: 12.5px; font-weight: 600; color: var(--primary); background: var(--primary-weak);
  padding: 5px 10px; border-radius: 6px; margin: 18px 0 12px; display: inline-block;
}
.section-title:first-child { margin-top: 0; }
.contact-block { border: 1px solid var(--border); border-radius: 9px; padding: 12px 14px 2px; margin-bottom: 12px; background: var(--surface-2); }
.contact-block h4 { font-size: 12.5px; color: var(--text-2); margin-bottom: 8px; }
.bank-row { display: grid; grid-template-columns: repeat(3, 1fr) auto; gap: 8px; margin-bottom: 8px; align-items: center; }
.bank-row input { font-size: 13px; }

/* ============ 提示 ============ */
.toast-wrap { position: fixed; top: 16px; left: 50%; transform: translateX(-50%); z-index: 300; display: flex; flex-direction: column; gap: 8px; align-items: center; }
.toast {
  background: #1c2430; color: #fff; padding: 10px 18px; border-radius: 9px; font-size: 13.5px;
  box-shadow: var(--shadow-lg); animation: pop .18s ease; max-width: 90vw;
}
.toast.ok { background: #0f8a45; }
.toast.err { background: #c62a1e; }

/* 后端服务加载的不是最新代码时，页面顶部挂一条提示（2026-09-28 增，见 core.js#OS.staleBanner） */
.stale-banner {
  position: relative; z-index: 200;
  background: var(--warn-weak); color: #7a4708; border-bottom: 1px solid #f2cfa0;
  padding: 9px 16px; font-size: 13px; line-height: 1.5;
}
.empty { padding: 40px 20px; text-align: center; color: var(--muted); font-size: 13.5px; }
.empty .big { font-size: 30px; display: block; margin-bottom: 8px; opacity: .35; }
.loading { padding: 36px; text-align: center; color: var(--muted); }

.hint { font-size: 12px; color: var(--muted); margin-top: 4px; }
/* 商品表单里的「同品名已有商品 / 编号已被占用」提示（2026-10-09）：橙色警示，和后端 400 一个口径 */
.hint.dup-warn { color: #b25e00; font-weight: 600; }
.row-actions { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
/* 已认领费用卡的操作列：三个按钮（查看分配 / 修改分配 / 取消认领）竖排对齐（2026-10-01 用户要求） */
table.tbl td.actions .vactions { display: flex; flex-direction: column; gap: 4px; align-items: stretch; }

/* 批量操作条（付款管理「已通过 · 待登记付款」的合并登记入口，2026-09-28 用户反馈后新增）
   常驻在表格上方、通栏浅蓝底：之前放在标题栏右侧是个灰色小按钮，和「N 笔」标签长得像，
   用户根本找不到「统一上传凭证的地方」，只会去点每行的蓝色单笔按钮。 */
.bulk-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 14px; background: var(--primary-weak); border-bottom: 1px solid var(--border);
}
.bulk-bar.is-active { background: #dfeafe; }
.bulk-bar .bulk-tip { font-size: 12.5px; color: var(--text-2); }
.bulk-bar .bulk-sum { font-size: 12.5px; color: var(--text); }
.bulk-bar .bulk-sum b { color: var(--primary); }
.bulk-bar .spacer { flex: 1; }
.divider { height: 1px; background: var(--border); margin: 14px 0; }
.kv { display: grid; grid-template-columns: 96px 1fr; gap: 6px 12px; font-size: 13.5px; }
.kv dt { color: var(--text-2); }
.kv dd { margin: 0; word-break: break-all; }
.file-list { list-style: none; padding: 0; margin: 0; }
.file-list li { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border: 1px solid var(--border); border-radius: 8px; margin-bottom: 6px; font-size: 13px; background: #fff; }
.file-list li .nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-list li .sz { color: var(--muted); font-size: 12px; }
.file-list li .up-by { color: var(--muted); font-size: 12px; margin-left: 2px; }
.drop {
  border: 1.5px dashed var(--border-strong); border-radius: 9px; padding: 14px; text-align: center;
  color: var(--text-2); font-size: 13px; cursor: pointer; background: var(--surface-2); transition: all .15s;
}
.drop:hover { border-color: var(--primary); color: var(--primary); background: var(--primary-weak); }
.alloc-line { display: grid; grid-template-columns: 1fr 130px auto; gap: 8px; margin-bottom: 8px; align-items: center; }
/* 管理员调整分配（2026-10-23）：多一列「认领人」下拉 —— 订单列被压缩，金额 / 认领人固定宽 */
/* 四列：订单（吃掉剩余宽）/ 金额 / 认领人 / 删。金额与认领人给固定窄宽，把宽度留给订单号 ——
   1296 宽企微窗口里弹窗 720，订单列能拿到 ~380px，够显示「单号 · 客户简称」。 */
.alloc-line.alloc-admin { grid-template-columns: minmax(140px, 1fr) 96px 132px auto; }
.alloc-line.alloc-admin select[data-alloc-owner] { min-width: 0; }
/* 管理员「取消认领」选人弹窗里的单选项（一人一行，整行可点） */
.ru-line { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px; margin-bottom: 8px; cursor: pointer; font-size: 13.5px; }
.ru-line:hover { border-color: var(--primary); background: var(--primary-weak); }
.ru-line input[type=radio] { width: 16px; height: 16px; flex: 0 0 auto; }
@media (max-width: 820px) {
  .alloc-line { grid-template-columns: 1fr 110px auto; }
  /* 手机上四列放不下 → 订单号独占一行，金额 / 认领人 / 删挤在第二行 */
  .alloc-line.alloc-admin { grid-template-columns: 1fr 1fr auto; }
  .alloc-line.alloc-admin select[data-alloc-order] { grid-column: 1 / -1; }
}
/* 冻结行（落在锁定订单上的分配额，结算终态）：只读、不可删，视觉上一眼看出动不了 */
.alloc-frozen input[readonly] { background: #f3f5f9; color: var(--muted); cursor: not-allowed; }
.alloc-frozen select[disabled] { background: #f3f5f9; color: var(--muted); cursor: not-allowed; }
.sum-line { display: flex; justify-content: space-between; font-size: 13px; color: var(--text-2); padding: 8px 0; border-top: 1px dashed var(--border); }
.sum-line b { color: var(--text); font-size: 14px; }
/* 认领收款弹窗（2026-09-30 用户要求）：
   ① 未分配金额紧挨在「已分配」右边，红色 —— 合计小于实收时才出现；
   ② 分配清单竖排，一行 = 订单号 + 金额（一笔款分给多个订单时一眼看清各单分了多少）；
   ③ 合计超实收时的报错行（同时禁用「保存分配」）。 */
.alloc-remain { margin-left: 8px; color: var(--danger); font-weight: 600; font-variant-numeric: tabular-nums; }
.alloc-view { display: flex; flex-direction: column; gap: 4px; margin: 10px 0 0; padding-top: 8px; border-top: 1px dashed var(--border); }
.alloc-view:empty { display: none; margin: 0; padding: 0; border: 0; }
.alloc-view .av-title { color: var(--muted); font-size: 12px; }
.alloc-vrow { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 13px; }
.alloc-vrow b { font-variant-numeric: tabular-nums; }
.alloc-err { min-height: 18px; color: var(--danger); font-size: 12.5px; }
.timeline { border-left: 2px solid var(--border); padding-left: 14px; }
.timeline .step { position: relative; padding-bottom: 14px; font-size: 13px; }
.timeline .step::before { content: ""; position: absolute; left: -20px; top: 6px; width: 8px; height: 8px; border-radius: 50%; background: var(--border-strong); }
.timeline .step.done::before { background: var(--success); }
.timeline .step.reject::before { background: var(--danger); }
.timeline .step.wait::before { background: var(--warn); }
.timeline .step .t { color: var(--muted); font-size: 12px; }
.pager { display: flex; align-items: center; gap: 10px; justify-content: flex-end; padding: 12px 18px; color: var(--text-2); font-size: 13px; }
.locked-field {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--surface-2);
  font-size: 13.5px; color: var(--text);
}
.locked-field .mono { font-weight: 600; }
.locked-field .hint { margin-top: 0; flex: 1; text-align: right; }

/* 商品表单「每箱数量 = 1」→ 外箱那几格自动取独立包装（2026-10-24）：
   浅灰底只是提示「这一格是带出来的」，不是禁用 —— 仍可手改（有衬垫时外箱确实会更大）。 */
input.pf-mirror { background: var(--surface-2); }

/* ============ 可折叠卡片（客户合同 / 收款记录 / 已认领费用，2026-10-22） ============ */
/* 与「附件」「结算表」同一套交互：默认折叠，点卡片头展开、再点折叠。
   ⚠️ 折叠是**隐藏 .card-body**（不清 DOM）：展开 / 折叠不重渲染 → 不闪、不跳滚动，
      页面内查找（脚本 / 打印 / 导出）也照旧能拿到内容。 */
.card.card-fold > .card-head { cursor: pointer; }
.card.card-fold.folded > .card-body { display: none; }
/* 折叠时卡片头不留底部边框（不然像切掉一半的卡片） */
.card.card-fold.folded > .card-head { border-bottom: 0; }
.collapse-caret { color: var(--text-2); font-size: 14px; line-height: 1; flex: 0 0 auto; margin-left: -2px; }
.card-head:hover > .collapse-caret { color: var(--acc-text); }

/* ============ 记录行（一条一行，点击展开/折叠） ============ */
.rec-meta { font-size: 12px; color: var(--muted); }
.card-sub { font-size: 12px; color: var(--muted); font-weight: 400; letter-spacing: .2px; }
#attach-card .card-head { cursor: pointer; }
#attach-card .card-head h3 { cursor: pointer; }
.rec-list { display: flex; flex-direction: column; }
.rec-item { border-bottom: 1px solid var(--border); }
.rec-item:last-child { border-bottom: 0; }
.rec-head {
  display: flex; align-items: center; gap: 10px; padding: 11px 18px;
  font-size: 13.5px; cursor: pointer; transition: background .12s;
}
.rec-head:hover { background: #fbfcfe; }
.rec-caret { color: var(--muted); font-size: 11px; line-height: 1; flex: 0 0 auto; transition: transform .15s; }
.rec-item.open .rec-caret { transform: rotate(90deg); }
.rec-item.open .rec-head { background: var(--surface-2); }
.rec-payee { color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 32%; }
.rec-date { color: var(--muted); font-size: 12.5px; margin-left: auto; white-space: nowrap; }
.rec-amt { font-weight: 650; font-variant-numeric: tabular-nums; white-space: nowrap; }
.rec-body { display: none; padding: 12px 18px 16px 40px; background: var(--surface-2); border-top: 1px dashed var(--border); }
.rec-item.open .rec-body { display: block; }
.rec-body .section-title { margin: 14px 0 10px; }
.rec-body .section-title:first-child { margin-top: 0; }
.rec-body .file-list li { background: #fff; }

/* ============ 成本测算表 ============ */
.seg { display: inline-flex; gap: 0; border: 1px solid var(--border-strong); border-radius: 8px; overflow: hidden; background: #fff; }
.seg .btn { border: 0; border-radius: 0; height: 28px; padding: 0 10px; font-size: 12.5px; color: var(--text-2); background: transparent; }
.seg .btn + .btn { border-left: 1px solid var(--border); }
.seg .btn.on { background: var(--primary-weak); color: var(--primary); font-weight: 600; }

table.cost-tbl th { font-size: 12.5px; }
table.cost-tbl tbody tr:hover { background: transparent; }
table.cost-tbl td { padding: 8px 14px; }
table.cost-tbl td:first-child { white-space: nowrap; }
table.cost-tbl .cost-note { color: var(--text-2); font-size: 12.5px; }
.cost-grp td {
  background: var(--surface-2); color: var(--text-2); font-weight: 600; font-size: 12.5px;
  letter-spacing: .03em; padding: 6px 14px;
}
.cost-sub td { color: var(--text-2); font-size: 12.5px; background: #fff; }
.cost-sub td:first-child { padding-left: 30px; }
.cost-neg { color: var(--danger); }
.cost-pos { color: var(--success); }
.cost-subtotal td { font-weight: 600; border-top: 1px dashed var(--border); }
/* 成本按付款批次分类的小标题（货款 / 运杂费 / 其他费用）与最终成本合计 */
table.cost-tbl tr.cost-cat td { background: #f3f5f8; color: var(--ink); font-weight: 700; padding: 6px 14px; font-size: 12.5px; }
/* ★ 三大合计行：收入合计 / 成本合计 / 退税合计（页面卡片，2026-09-30 用户要求）
   文字蓝色加粗；上边框 = 普通灰细线 1px，下边框 = 加粗灰粗线 2px；「计算说明」列仍用常规灰字、不加粗 */
table.cost-tbl tr.cost-sum td {
  background: #fff; color: var(--primary); font-weight: 700;
  border-top: 1px solid var(--border);
  border-bottom: 2px solid var(--border-heavy);
}
table.cost-tbl tr.cost-sum td:first-child { letter-spacing: .02em; }
table.cost-tbl tr.cost-sum td.cost-note { color: var(--text-2); font-weight: 400; }
.cost-empty { color: var(--muted); font-size: 12.5px; padding: 16px 14px !important; }
/* 自动测算行：系统按订单数据算出，无需手填 */
table.cost-tbl tr.cost-auto td { background: var(--primary-weak); }
table.cost-tbl tr.cost-auto:hover td { background: var(--primary-weak); }
table.cost-tbl tr.cost-auto td .tag { margin-left: 6px; }
table.cost-tbl tfoot td { border-top: 1px solid var(--border-strong); }
table.cost-tbl tfoot tr:first-child td { border-top: 2px solid var(--border-strong); }
.cost-result td { font-size: 14.5px; padding: 10px 14px !important; }
.cost-result td:first-child { font-weight: 600; }
.cost-result td b { font-size: 15.5px; }

/* ============ 关联方列表（供应商 / 货代 / 其他服务商：一行一条，点击展开） ============ */
.pty-labels, .pty-head {
  display: grid; grid-template-columns: 18px 110px minmax(120px, 1fr) 170px 170px;
  align-items: center; gap: 10px;
}
.pty-labels {
  padding: 8px 18px; font-size: 12px; color: var(--muted);
  background: var(--surface-2); border-bottom: 1px solid var(--border);
}
.pty-head { cursor: pointer; }
.pty-code { font-size: 12.5px; color: var(--text-2); }
.pty-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.pty-amt { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; font-weight: 650; }
.pty-amt .hint { font-weight: 400; }
.pty-amt .tag { font-weight: 500; }
/* 展开区里的商品明细表格、付款行缩进一点，避免和上层行混淆 */
.rec-body .section-title + .table-wrap table.tbl td,
.rec-body .section-title + .table-wrap table.tbl th { padding: 7px 10px; }
.rec-body .rec-list .rec-head { padding: 9px 12px; font-size: 13px; }
.rec-body .rec-list .rec-item { border: 1px solid var(--border); border-radius: 8px; margin-bottom: 6px; }
.rec-body .rec-list .rec-item:last-child { margin-bottom: 0; }
.rec-body .rec-list .rec-item.open .rec-head { border-radius: 8px 8px 0 0; }
.rec-body .rec-list .rec-body { padding: 10px 12px 12px 30px; }

/* ============ 板块色块：卡片左缘色条 + 标题栏底色，相邻板块颜色不同 ============ */
/* 用 #view .card（不限层级）：有些页面把卡片装在 #pay-body 之类的容器里，用 > 子选择器会漏掉 */
#view .card {
  --acc: #1a6cf0; --acc-weak: #eaf1fe; --acc-text: #14489c; --acc-bar: rgba(26,108,240,.28);
  border-left: 4px solid var(--acc);
}
#view .card > .card-head { background: var(--acc-weak); }
#view .card > .card-head h3 { color: var(--acc-text); }

/* 未指定语义色的页面（工作台 / 列表 / 付款 / 收款 / 备案 / 系统管理）按出现顺序循环取色 */
#view .card:nth-of-type(5n+2) { --acc:#0d9488; --acc-weak:#e3f4f1; --acc-text:#0a6c64; --acc-bar:rgba(13,148,136,.28); }
#view .card:nth-of-type(5n+3) { --acc:#d97706; --acc-weak:#fdf1e0; --acc-text:#a25604; --acc-bar:rgba(217,119,6,.28); }
#view .card:nth-of-type(5n+4) { --acc:#7c3aed; --acc-weak:#f1eafc; --acc-text:#5c28bd; --acc-bar:rgba(124,58,237,.24); }
#view .card:nth-of-type(5n+5) { --acc:#db2777; --acc-weak:#fce8f0; --acc-text:#ad1a5d; --acc-bar:rgba(219,39,119,.24); }

/* 订单详情页的语义色（固定：同一类板块在任何订单里颜色一致） */
#view .card.sec-blue   { --acc:#1a6cf0; --acc-weak:#eaf1fe; --acc-text:#14489c; --acc-bar:rgba(26,108,240,.28); }
#view .card.sec-green  { --acc:#12a150; --acc-weak:#e7f7ee; --acc-text:#0b7a3c; --acc-bar:rgba(18,161,80,.28); }
#view .card.sec-orange { --acc:#d97706; --acc-weak:#fdf1e0; --acc-text:#a25604; --acc-bar:rgba(217,119,6,.28); }
#view .card.sec-teal   { --acc:#0d9488; --acc-weak:#e3f4f1; --acc-text:#0a6c64; --acc-bar:rgba(13,148,136,.28); }
#view .card.sec-purple { --acc:#7c3aed; --acc-weak:#f1eafc; --acc-text:#5c28bd; --acc-bar:rgba(124,58,237,.24); }
#view .card.sec-pink   { --acc:#db2777; --acc-weak:#fce8f0; --acc-text:#ad1a5d; --acc-bar:rgba(219,39,119,.24); }
#view .card.sec-slate  { --acc:#64748b; --acc-weak:#eef2f6; --acc-text:#41506b; --acc-bar:rgba(100,116,139,.28); }
/* 结算卡片：用琥珀色（与「待财务核对 / 审批流」语义一致），区别于其它板块 */
#view .card.sec-amber  { --acc:#d97706; --acc-weak:#fef4e6; --acc-text:#9a5b00; --acc-bar:rgba(217,119,6,.26); }
.settle-row { display:flex; align-items:baseline; gap:10px; padding:6px 0; border-bottom:1px dashed var(--border); font-size:13px; }
.settle-row:last-child { border-bottom:0; }
.settle-label { width:92px; flex:none; color:var(--text-2); }
.settle-who { font-weight:600; }
.settle-when { color:var(--text-2); margin-left:auto; }
.settle-extra { flex-basis:100%; color:var(--text-2); margin-top:2px; }
.settle-reject { margin-top:8px; padding:8px 10px; border-radius:var(--radius); background:var(--danger-weak); color:var(--danger); font-size:13px; }
/* 「未闭环事项」提示（2026-09-30）：订单上还有待审核付款 / 待认领费用时，
   工具栏的结算按钮与状态弹窗里的「已完成 / 已结算」会被禁掉，用这一行就地说明原因。 */
.settle-block { display:inline-flex; align-items:center; gap:6px; padding:6px 10px; border-radius:var(--radius);
  background:var(--warn-weak); color:var(--warn); font-size:12.5px; line-height:1.5; max-width:420px; }
/* 报价单的品牌色（与下载的 PDF / Excel 里的 MAINBON 棕一致，2026-09-28）。
   不指定的话会落进上面的 5n 循环配色（报价明细卡头会变成橙色），和单据的棕色调性对不上。 */
#view .card.sec-brand  { --acc:#6B4226; --acc-weak:#f6efe7; --acc-text:#5a351d; --acc-bar:rgba(107,66,38,.28); }

/* 板块内的分区小标题跟随所属板块配色（弹窗表单里的 section-title 不受影响） */
#view .card .section-title { background: var(--acc-weak); color: var(--acc-text); }

/* ============ 行间色块：折叠行隔行着色 + 行首色条（与所在板块同色），避免看串行 ============ */
.rec-list > .rec-item { border-left: 3px solid var(--acc-bar, rgba(26,108,240,.28)); }
.rec-list > .rec-item:nth-child(even) { background: #eef3fb; }
.rec-list > .rec-item:nth-child(even) .rec-head:hover { background: #e6eefa; }

/* 展开区里的子行（付款记录行）白底卡片式，同样隔行着色 */
.rec-body .rec-list .rec-item { background: #fff; }
.rec-body .rec-list .rec-item:nth-child(even) { background: #f1f5fb; }

/* 表格隔行着色（成本测算表除外——它有自己的分组底色） */
table.tbl:not(.cost-tbl) tbody tr:nth-child(even) td { background: #eef3fb; }
table.tbl:not(.cost-tbl) tbody tr:hover td { background: #e3ecfa; }

/* ============ 订单管理列表：整行点击打开详情 ============ */
table.tbl.ord-tbl tbody tr.ord-row { cursor: pointer; }
/* 行尾的「›」只在悬停时淡入，作为「可点开」的提示（不是按钮） */
table.tbl.ord-tbl tbody tr.ord-row > td:last-child { position: relative; padding-right: 24px; }
table.tbl.ord-tbl tbody tr.ord-row > td:last-child::after {
  content: '›';
  position: absolute; right: 10px; top: 50%;
  transform: translateY(-50%);
  font-size: 17px; line-height: 1; color: var(--muted);
  opacity: 0; transition: opacity .15s, right .15s;
}
table.tbl.ord-tbl tbody tr.ord-row:hover > td:last-child::after { opacity: .8; right: 8px; }
table.tbl.ord-tbl tbody tr.ord-row:hover td a { text-decoration: underline; }

/* ============ 备案台账：整行点击展开详情 ============ */
table.tbl.reg-tbl tbody tr.reg-row { cursor: pointer; }
table.tbl.reg-tbl tbody tr.reg-row .reg-caret { display: inline-block; margin-right: 5px; transition: transform .15s; }
table.tbl.reg-tbl tbody tr.reg-row.open .reg-caret { transform: rotate(90deg); }
table.tbl.reg-tbl tbody tr.reg-detail { display: none; }
table.tbl.reg-tbl tbody tr.reg-detail.open { display: table-row; }
table.tbl.reg-tbl tbody tr.reg-detail > td {
  background: var(--surface-2);
  padding: 14px 18px 16px 38px;
  box-shadow: inset 3px 0 0 var(--acc-bar, rgba(26,108,240,.28));
}
table.tbl.reg-tbl tbody tr.reg-detail:hover td { background: var(--surface-2); }
/* 详情行插在数据行后面，tbody 的 nth-child 会被打乱（数据行=奇数位、详情行=偶数位）：
   先撤销通用斑马纹，再只给数据行隔行着色（数据行位于 1、3、5…位，取 4n+3 即每两条着色一条） */
table.tbl.reg-tbl tbody tr:nth-child(even) td { background: transparent; }
table.tbl.reg-tbl tbody tr.reg-row:nth-of-type(4n+3) td { background: #eef3fb; }
table.tbl.reg-tbl tbody tr.reg-row:hover td,
table.tbl.reg-tbl tbody tr.reg-row.open td { background: #e3ecfa; }
/* 展开区「关联情况」（2026-10-11）：条数 + 具体订单号（可点跳订单详情）+ 状态标签。
   ⚠️ .kv dd 有 word-break: break-all —— 会把 PO20261001-001 从中间断开，这里必须归正。 */
.reg-usage-dd { word-break: normal; }
.reg-usage-head { margin-bottom: 4px; }
.reg-ords { display: flex; flex-wrap: wrap; gap: 5px 12px; word-break: normal; }
.reg-ord-item { display: inline-flex; align-items: center; gap: 5px; }
.reg-ord { color: var(--primary); text-decoration: none; }
.reg-ord:hover { text-decoration: underline; }
.reg-ord-more { font-size: 12.5px; }
/* 详情区：联系人 / 收款账户卡片自适应两列排布 */
.reg-kv { margin-bottom: 4px; }
.reg-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 12px; }
.reg-cards .contact-block { margin-bottom: 0; height: fit-content; }
@media (max-width: 820px) { .reg-cards { grid-template-columns: 1fr; } }

/* ---------- 联系人照片 / 名片（2026-10-22 用户要求） ----------
   原话：「增加上传联系人照片功能，并在列表展开的时候显示联系人和照片。就像带照片的名片类似的效果。
          照片可以是非必填。」
   三处样式：① 列表行「主要联系人」前的小头像；② 展开区 / 详情弹窗里的名片卡；③ 表单里的上传位。
   没照片时一律画姓名首字（.reg-avatar / .biz-photo / .cp-initials），所以「非必填」不会让版面塌。 */
.reg-contact { display: inline-flex; align-items: center; gap: 7px; min-width: 0; }
.reg-avatar {
  width: 22px; height: 22px; flex: 0 0 auto; border-radius: 6px; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--primary-weak); color: var(--primary);
  font-size: 11px; font-weight: 600;
}
.reg-avatar.has-photo { background: #e9edf4; }
.reg-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.reg-contact-txt { min-width: 0; }

.reg-cards .biz-card { padding: 13px 14px 11px; }
.biz-top { display: flex; gap: 12px; align-items: flex-start; }
.biz-photo {
  width: 60px; height: 60px; flex: 0 0 auto; border-radius: 10px; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #eef4ff, #dde8fa); color: var(--primary);
  font-size: 22px; font-weight: 600; border: 0; padding: 0; cursor: default;
  font-family: inherit;
}
.biz-photo.has-photo { cursor: zoom-in; background: #e9edf4; box-shadow: 0 0 0 1px var(--border); }
.biz-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.biz-main { flex: 1; min-width: 0; }
.biz-name-row { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 3px; }
.biz-name { font-size: 15.5px; font-weight: 600; color: var(--text); }
.biz-title {
  font-size: 12px; color: var(--text-2); background: var(--surface);
  border: 1px solid var(--border); border-radius: 999px; padding: 0 8px;
}
.biz-line { display: flex; gap: 8px; font-size: 13px; line-height: 1.85; }
.biz-k { flex: 0 0 30px; color: var(--muted); }
.biz-v { color: var(--text); word-break: break-all; }
a.biz-v { color: var(--primary); text-decoration: none; }
a.biz-v:hover { text-decoration: underline; }
.biz-foot {
  display: flex; align-items: center; gap: 8px; margin-top: 10px; padding-top: 8px;
  border-top: 1px dashed var(--border); font-size: 12px; color: var(--muted);
}
.biz-tag { color: var(--primary); background: var(--primary-weak); border-radius: 999px; padding: 0 7px; }
.photo-view img { max-width: 100%; max-height: 68vh; border-radius: 10px; display: block; margin: 0 auto; }

/* 备案表单里的照片位（可选）：方框 + 上传 / 移除 */
.cp-row { display: flex; gap: 12px; align-items: center; margin-bottom: 10px; }
.cp-photo {
  width: 72px; height: 72px; flex: 0 0 auto; border-radius: 10px; overflow: hidden;
  border: 1px dashed var(--border-strong); background: var(--surface);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  transition: border-color .15s, background .15s;
}
.cp-photo:hover { border-color: var(--primary); background: var(--primary-weak); }
.cp-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cp-photo.uploading { opacity: .5; }
.cp-initials { font-size: 22px; font-weight: 600; color: var(--muted); }
.cp-btns { display: flex; gap: 8px; margin-bottom: 3px; }
.cp-tools .hint { line-height: 1.4; }
/* 供应商展开区最末的「产品列表」（2026-10-09）：只有 4 列，跟着展开区的紧凑节奏走，
   不与主清单抢视觉；空态（该供应商暂无产品）用普通 hint 即可。 */
table.tbl.sup-prod-tbl { min-width: 0; width: 100%; }
table.tbl.sup-prod-tbl th,
table.tbl.sup-prod-tbl td { padding: 7px 10px; }
table.tbl.sup-prod-tbl th .th-u { font-weight: 400; color: var(--muted); font-size: 11px; }
table.tbl.sup-prod-tbl td.mono b { font-variant-numeric: tabular-nums; }
.sup-prod-empty { margin: 0; }
/* 产品行**再展开一层**商品详情（2026-10-09 用户要求：点开行看完整信息，再点里面的「编辑」）。
   与外层 reg-tbl 同一套做法（箭头旋转 + 详情行默认隐藏 + 斑马纹按 4n+3 重排，
   因为详情行会把 nth-child 打乱）。只读角色没有 sup-prod-row，自然也没有手型光标。 */
table.tbl.sup-prod-tbl tbody tr.sup-prod-row { cursor: pointer; }
table.tbl.sup-prod-tbl tbody tr.sup-prod-row .sup-prod-caret { display: inline-block; margin-right: 5px; transition: transform .15s; }
table.tbl.sup-prod-tbl tbody tr.sup-prod-row.open .sup-prod-caret { transform: rotate(90deg); }
table.tbl.sup-prod-tbl tbody tr.sup-prod-detail { display: none; }
table.tbl.sup-prod-tbl tbody tr.sup-prod-detail.open { display: table-row; }
table.tbl.sup-prod-tbl tbody tr:nth-child(even) td { background: transparent; }
table.tbl.sup-prod-tbl tbody tr.sup-prod-row:nth-of-type(4n+3) td { background: #eef3fb; }
table.tbl.sup-prod-tbl tbody tr.sup-prod-row:hover td,
table.tbl.sup-prod-tbl tbody tr.sup-prod-row.open td { background: #e3ecfa; }
table.tbl.sup-prod-tbl tbody tr.sup-prod-detail > td { background: var(--surface-2); padding: 12px 14px 14px 26px; box-shadow: inset 3px 0 0 var(--acc-bar, rgba(26,108,240,.28)); }
table.tbl.sup-prod-tbl tbody tr.sup-prod-detail:hover td { background: var(--surface-2); }

/* 客户联系方式隐藏标记（仅管理员/归属业务员可见） */
/* 订单详情页「添加商品」里的商品库选择行（下拉 + 新建按钮） */
.pick-row { display: flex; gap: 8px; align-items: center; }
.pick-row select { flex: 1; min-width: 0; }

/* ---------- 商品维护（商品库，2026-09-28）----------
   清单有 17 列（用户要求把品名/净毛重/内外包装尺寸与体积/每箱数量/退税率/供应商全列出来），
   所以用 compact 的内边距 + 尺寸列 nowrap，超出宽度交给 .table-wrap 横向滚动。 */
table.tbl.prod-tbl th,
table.tbl.prod-tbl td { padding-left: 10px; padding-right: 10px; }
table.tbl.prod-tbl th .th-u { font-weight: 400; color: var(--muted); font-size: 11px; }
table.tbl.prod-tbl td.prod-dim { white-space: nowrap; font-variant-numeric: tabular-nums; }
table.tbl.prod-tbl td.prod-pic { width: 52px; }
.prod-thumb { width: 44px; height: 44px; object-fit: cover; border-radius: 6px; border: 1px solid var(--border); display: block; background: #fff; }
.prod-noimg { display: inline-flex; width: 44px; height: 44px; align-items: center; justify-content: center; border: 1px dashed var(--border-strong); border-radius: 6px; color: var(--muted); font-size: 18px; }
/* 行内展开详情：左图右字段 */
.prod-detail-wrap { display: grid; grid-template-columns: 190px 1fr; gap: 18px; align-items: start; }
.prod-big { width: 190px; height: 190px; object-fit: cover; border-radius: 10px; border: 1px solid var(--border); background: #fff; display: block; }
.prod-noimg-big { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; font-size: 34px; color: var(--muted); border-style: dashed; }
.prod-detail-fields { min-width: 0; }
.prod-detail-fields .section-title { margin-top: 0; }
.prod-detail-fields .section-title + .kv { margin-bottom: 10px; }
/* 表单里的图片位 */
.prod-img-row { display: flex; gap: 14px; align-items: flex-start; }
.prod-img-preview { width: 120px; height: 120px; flex: 0 0 auto; border: 1px dashed var(--border-strong); border-radius: 9px; display: flex; align-items: center; justify-content: center; overflow: hidden; background: var(--surface-2); }
.prod-img-preview img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 820px) { .prod-detail-wrap { grid-template-columns: 1fr; } }

.muted { color: var(--muted); font-size: 12px; }

/* ---------- 报价单（工具 → 报价单，2026-09-28）----------
   详情页 = 「表头卡（Logo + MAINBON GROUP + 报价单信息）」+「明细表（13 列 + 操作）」。
   明细表列多，用 .table-wrap 横向滚动；输入列窄内边距 + 数字右对齐，让一行能看全。 */
.q-readonly { margin-bottom: 14px; padding: 10px 14px; border-radius: var(--radius); background: var(--warn-weak); border: 1px solid #f3ddb4; color: #8a5a00; font-size: 13px; }

/* 表头卡：与下载的 PDF 同一套品牌视觉（左侧色条 + Logo + 公司名 + 单据名） */
.q-doc { padding: 0; overflow: hidden; }
.q-doc-band {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 18px;
  background: linear-gradient(90deg, #6B4226 0%, #8a5a37 55%, #a97a52 100%);
  color: #fff;
}
.q-doc-logo { width: 46px; height: 46px; object-fit: contain; background: #fff; border-radius: 8px; padding: 4px; flex: 0 0 auto; }
.q-doc-co { display: flex; flex-direction: column; line-height: 1.35; }
.q-doc-co b { font-size: 22px; letter-spacing: .06em; }
.q-doc-co span { font-size: 12px; opacity: .85; letter-spacing: .04em; }
.q-doc-title { margin-left: auto; text-align: right; display: flex; flex-direction: column; line-height: 1.3; }
.q-doc-title b { font-size: 22px; letter-spacing: .28em; }
.q-doc-title span { font-size: 11.5px; opacity: .8; letter-spacing: .3em; }

/* 清单：整行可点开 */
table.tbl.q-list-tbl tbody tr.q-list-row { cursor: pointer; }
table.tbl.q-list-tbl th, table.tbl.q-list-tbl td { padding-left: 10px; padding-right: 10px; }

/* 明细表 */
/* 13 列 + 操作，比内容区还宽 —— 给一个 min-width 让 .table-wrap 横向滚动，
   而不是把「品名」压成「Bamboo Tra」这种半截字（2026-09-28 视觉核对发现的）。 */
table.tbl.q-tbl { min-width: 1180px; }
table.tbl.q-tbl th, table.tbl.q-tbl td { padding-left: 7px; padding-right: 7px; }
table.tbl.q-tbl th { white-space: nowrap; }
table.tbl.q-tbl th.q-th-in { text-align: right; }
table.tbl.q-tbl th.actions { text-align: right; }
table.tbl.q-tbl th .th-u { font-weight: 400; color: var(--muted); font-size: 10.5px; }
table.tbl.q-tbl td { padding-top: 6px; padding-bottom: 6px; }
table.tbl.q-tbl input[type="number"],
table.tbl.q-tbl input[type="text"] { width: 100%; min-width: 54px; padding: 5px 7px; font-size: 13px; border: 1px solid var(--border); border-radius: 6px; background: #fff; }
table.tbl.q-tbl input[data-k="product_code"] { min-width: 92px; }
table.tbl.q-tbl input[data-k="item_name"] { min-width: 168px; }
table.tbl.q-tbl input[type="number"] { text-align: right; font-variant-numeric: tabular-nums; }
table.tbl.q-tbl input:focus { outline: 0; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-weak); }
table.tbl.q-tbl td.q-calc { color: var(--text); font-weight: 600; background: var(--surface-2); }
table.tbl.q-tbl td.q-dims { white-space: nowrap; }
table.tbl.q-tbl td.q-dims .q-d { width: 50px; min-width: 0; padding-left: 5px; padding-right: 5px; }
table.tbl.q-tbl td.q-dims .q-x { color: var(--muted); margin: 0 1px; font-size: 11px; }
/* 合计行：上双线 + 浅色底，一眼看出「这是全部商品的总和」 */
table.tbl.q-tbl tfoot tr.q-total td {
  background: #F0EAE1; font-weight: 700; color: #3A2A1A;
  border-top: 2px solid #6B4226; border-bottom: 0; white-space: nowrap;
}
table.tbl.q-tbl tfoot tr.q-total td:first-child { letter-spacing: .1em; }
table.tbl.q-tbl tbody tr:nth-child(even) td { background: #faf7f3; }
table.tbl.q-tbl tbody tr:hover td { background: #f2ece5; }
table.tbl.q-tbl td.actions { width: 44px; }

/* ---------- 装箱单（工具 → 装箱单，2026-09-29）----------
   与报价单共用上面那套 .q-* 视觉（同一品牌语言）；差别只在列数：
   11 列（没有单价 / 总金额，也没有有效期），所以最小宽度调窄一点，宽屏下不用白滚。 */
table.tbl.q-tbl.pl-tbl { min-width: 1020px; }
table.tbl.q-list-tbl.pl-list-tbl th, table.tbl.q-list-tbl.pl-list-tbl td { padding-left: 10px; padding-right: 10px; }

/* 商品选择弹窗 */
.pp-toolbar { display: flex; gap: 10px; align-items: center; margin-bottom: 12px; flex-wrap: wrap; }.pp-toolbar .spacer { flex: 1; }
table.tbl.pp-tbl th, table.tbl.pp-tbl td { padding-left: 9px; padding-right: 9px; }
table.tbl.pp-tbl tbody tr.pp-row { cursor: pointer; }
table.tbl.pp-tbl th.pp-ck, table.tbl.pp-tbl td.pp-ck { width: 34px; text-align: center; }
table.tbl.pp-tbl td.pp-ck input { width: 15px; height: 15px; }

/* ============ 结算管理（业务协同 → 结算管理，2026-09-30）============
   顶部筛选 + 顶部求和卡 + 一条条「按实际发生」成本测算表（点击展开/折叠）。
   行卡片复用 .card，但 #st-list 用 flex 间距，撤销 .card+.card 的 16px 上外边距避免叠加。 */
.filters { display: flex; flex-wrap: wrap; gap: 14px 18px; align-items: flex-end; }
.filters label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--text-2); }
.filters input, .filters select { min-width: 150px; }

/* 顶部求和卡：浅蓝底（明显区别于白卡），左缘色条 */
.st-summary { background: var(--primary-weak); border-left: 4px solid var(--primary); }
.st-summary .sum-row { padding: 14px 16px; }

/* ★ 顶部求和行与下面每一单共用同一条 grid 模板，保证「总收入 / 总货款 / …」同名列上下严格对齐。
   列：勾选 20 · 箭头 14 · 订单号/客户 1.4fr · 状态 88 · **8 个指标** · 下载按钮 128
   ⚠️ 改指标个数（现在 8 个）必须同步改这里的 repeat 次数，否则求和行与明细行会错位。 */
.st-grid {
  display: grid;
  grid-template-columns: 20px 14px minmax(150px, 1.4fr) 88px repeat(8, minmax(72px, 1fr)) 128px;
  gap: 12px 14px;
  align-items: center;
}
/* 指标的容器本身不占格子，让 8 个 .st-m 各自成为一格（与求和行的 8 个 .sum-cell 一一对齐） */
.st-metrics { display: contents; }
/* 窄屏：按钮换行到下一行，指标挤一挤仍能对齐 */
@media (max-width: 1320px) {
  .st-grid { grid-template-columns: 20px 14px minmax(140px, 1.2fr) 88px repeat(8, minmax(64px, 1fr)); }
  .st-acts, .sum-tail { grid-column: 1 / -1; }
  .st-acts { justify-self: start; }
}
.sum-cell { display: flex; flex-direction: column; gap: 3px; }
.sum-label { font-size: 12px; color: var(--text-2); }
/* 字号与下面每行的 .st-mv 一致（13.5px）：同一列上下用同一个字号才谈得上「对齐」，
   也避免合计金额（比单行大）因字号过大而在列里折行。 */
/* 字号由 fitAmounts() 动态降档（13.5 → 9.5）；最小档仍放不下才省略号截断（不让它溢出压到相邻列） */
.sum-val { font-size: 13.5px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sum-val.sum-count { color: var(--primary); }
.sum-val.pos { color: var(--success); }
.sum-val.neg { color: var(--danger); }

#st-list { display: flex; flex-direction: column; gap: 10px; }
#st-list > .card { margin-top: 0; }
.st-row { border-left: 4px solid var(--acc-bar, rgba(26,108,240,.28)); }
/* display / 列宽统一走 .st-grid（不在这里设 display，否则会盖掉 grid） */
.st-row .st-head { padding: 12px 16px; cursor: pointer; }
.st-row .st-head:hover { background: var(--surface-2); }
.st-caret { flex: none; width: 14px; text-align: center; color: var(--muted); font-size: 12px; transition: transform .15s; }
.st-idblock { display: flex; flex-direction: column; gap: 2px; min-width: 140px; }
.st-no { font-size: 14px; font-weight: 700; color: var(--text); }
.st-cust { font-size: 12px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 200px; }
/* display:contents —— 8 个 .st-m 直接成为 .st-grid 的列（与求和行对齐）；窄屏下由媒体查询改回 flex 换行 */
.st-metrics { display: contents; }
.st-m { display: flex; flex-direction: column; gap: 2px; min-width: 62px; }
.st-ml { font-size: 11px; color: var(--muted); white-space: nowrap; }
.st-mv { font-size: 13.5px; font-weight: 650; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-mv.pos { color: var(--success); }
.st-mv.neg { color: var(--danger); }
.st-acts { display: flex; gap: 8px; flex: none; justify-self: end; }
.st-acts .btn { min-width: 56px; text-align: center; }
.st-detail { padding: 0 16px 16px; border-top: 1px dashed var(--border); }
.cost-dl-title { font-size: 13px; font-weight: 600; color: var(--acc-text, var(--primary)); margin: 12px 0 8px; }

/* 筛选行内的按钮组（订单状态后面）+ 已选提示 */
.filters .btn-group { display: flex; gap: 8px; align-items: center; align-self: flex-end; }
.filters .st-selinfo { align-self: flex-end; font-size: 12px; color: var(--text-2); white-space: nowrap; }
.filters .st-selinfo b { color: var(--primary); font-variant-numeric: tabular-nums; }

/* ★ 「全选」不在筛选行里，而在**求和行的最左边**（2026-09-30 用户要求）。
   grid-column: span 2 —— 占「勾选列 + 箭头列」（箭头列在求和行是空的），
   复选框用 justify-self/ justify-content: flex-start ⇒ 与下面每一行的勾选框**左缘同一条线**。 */
.sum-row .sum-ck { grid-column: span 2; display: flex; align-items: center; gap: 6px; justify-self: start; cursor: pointer; font-size: 12px; color: var(--text-2); white-space: nowrap; }
.sum-row .sum-ck input { width: 16px; height: 16px; cursor: pointer; } /* 与 .st-ck 的勾选框同尺寸 */

/* 每行最左的勾选框（与求和行的「全选」同列、同左缘：都用 flex-start，别改回 center） */
.st-row .st-head .st-ck { flex: none; display: flex; align-items: center; justify-content: flex-start; width: 20px; }
.st-row .st-head .st-ck input { width: 16px; height: 16px; cursor: pointer; }
.st-row.st-selected { box-shadow: 0 0 0 2px var(--primary-weak) inset, var(--shadow); }
/* 极窄屏：放弃「同名列对齐」，指标整块换行铺开（对齐在宽屏才有意义） */
@media (max-width: 900px) {
  .st-grid { grid-template-columns: 20px 14px minmax(120px, 1fr) 88px; }
  .st-metrics { display: flex; flex-wrap: wrap; gap: 8px 20px; grid-column: 1 / -1; }
  .st-acts, .sum-tail { grid-column: 1 / -1; }
  .st-summary .sum-row { grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); }
}

/* ============ 统计页（概览 → 统计，2026-10-09） ============ */
/* 分组行：整行可点（展开 / 折叠）；最左一格的 ▸/▾ 是展开指示 */
table.tbl tr.sg-row { cursor: pointer; }
table.tbl tr.sg-row:hover { background: var(--primary-weak); }
table.tbl td.sg-exp, table.tbl th.sg-exp { width: 28px; padding-left: 14px; padding-right: 2px; color: var(--muted); user-select: none; }
/* 展开出来的明细块：浅底、内嵌一层小表格，与外层分组行区分开 */
table.tbl tr.sg-detail > td { background: var(--surface-2); padding: 10px 14px 14px; }
table.tbl tr.sg-detail table.tbl.compact { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
/* 统计页汇总卡与下面两张卡之间的间距（.grid-3 自身没有外边距） */
#sg-summary { margin: 16px 0; }
#sg-list .card { margin-bottom: 0; }
#sg-note { margin-top: 10px; }

/* ============================================================================
   外销单据（PI / 商业发票 / 装箱单）—— 2026-10-25
   「生成文件」区在「外销明细」卡片底部：上面三个按钮，下面已生成的文件行。
   文件行是**横排**而不是表格：一单一型最多三份，用表格反而空旷，
   横排还能把「下载 PDF / Excel」两颗按钮放在同一行右侧，一眼看得见。
   ============================================================================ */
.doc-area { border-top: 1px dashed var(--border); padding-top: 10px; margin-top: 4px; }
.doc-btns { display: flex; flex-wrap: wrap; gap: 8px; }
.doc-list { margin-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.doc-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--surface);
}
.doc-row:hover { background: var(--surface-2); }
.doc-row .doc-ico { font-size: 18px; flex: 0 0 auto; }
.doc-row .doc-main { flex: 1 1 auto; min-width: 0; }
.doc-row .doc-name { font-size: 13px; font-weight: 600; }
.doc-row .doc-meta { font-size: 12px; color: var(--muted); margin-top: 2px; }
.doc-row .doc-ops { flex: 0 0 auto; display: flex; flex-wrap: nowrap; gap: 6px; }
/* 单据弹窗里的两列表单（条款 / shipping details / 银行字段都用它） */
.doc-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 12px; }
@media (max-width: 700px) { .doc-form { grid-template-columns: 1fr; } }

/* ============================================================================
   桌面（企微窗口）密度 —— 2026-10-20 用户要求「适配电脑端企微为主」
   ----------------------------------------------------------------------------
   背景：交付形态是企微工作台。PC 企微打开自建应用是**一个应用窗口**，最大化后
   可视高度只有 ~640–900px（1920 屏 ≈1856×900；1366 屏 ≈1296×640），宽度也在
   1296–1856 之间。原来这套尺寸是按「全屏浏览器、高度 1000+」调的，结果在企微里：
   顶部两张指标卡 + 筛选行吃掉约 300px，一屏只剩 3–4 行数据 —— 用户的原话是
   「内容比较多，窗口最大化才看得多」，所以这里只做**密度**，不动结构、不动字号档位。
   ⚠️ 全部包在 min-width:1200 里：手机/窄屏那几档（≤900 / ≤820）保持原样，别一起改。
   实测依据：scripts/ui-shots.js（1856×900 / 1440×800 / 1296×640 三档截图 + 量尺寸）。
   ============================================================================ */
@media (min-width: 1200px) {
  .content { padding: 14px 18px; }          /* 22 → 14：上下各省 8px */
  .card-head { padding: 10px 14px; }
  .card-body { padding: 14px; }
  .grid { gap: 12px; }
  .card + .card { margin-top: 12px; }
  .stat { padding: 12px 14px; }             /* 指标卡：16/18 → 12/14 */
  .stat .value { font-size: 21px; }
  table.tbl th { padding: 8px 12px; }
  table.tbl td { padding: 8px 12px; }       /* 行高约 42 → 36 */
  table.tbl.rcp-tbl th,
  table.tbl.rcp-tbl td { padding-left: 8px; padding-right: 8px; }
  .filters { gap: 9px 12px; }
  .filters input, .filters select { min-width: 132px; }  /* 150 → 132，一排能多塞一个 */
}

/* 结算管理：8 个指标在 1200–1400 这段（=1366 屏的企微窗口）会被挤到
   「¥1,421,846…」——fitAmounts() 已经降到 9.5px 仍放不下，只剩省略号。
   根因是列间距 14px × 11 + 订单号块最小 140px 太占地方。这里把间距收到 8px、
   订单号块收到 118px，让每列多出约 14px，金额就能以 11–12px 完整显示。 */
@media (min-width: 1200px) and (max-width: 1400px) {
  .st-grid { gap: 10px 8px; grid-template-columns: 20px 14px minmax(118px, 1.2fr) 84px repeat(8, minmax(72px, 1fr)); }
}

/* 横向滚动时把「操作」列钉在右边 —— 2026-10-20（适配电脑端企微）
   收款看板 13 列 / 费用认领 11 列，在企微窗口（1296–1856 宽）里必然要横向滚动：
   原来一滚按钮就滑出可视区，发一笔款得先把表拖到最右，滚回去又不知道是哪一行。
   .table-wrap 是 overflow-x:auto 的滚动容器，所以 sticky + right:0 在**水平方向**生效。
   ⚠️ 必须给 td 补背景色，否则横向掠过的单元格会从按钮底下透出来；
      表头那格用 surface-2（和别的 th 一致），行 hover 时同步换色。 */
@media (min-width: 1200px) {
  table.tbl th.actions,
  table.tbl td.actions {
    position: sticky; right: 0; z-index: 2;
    background: #fff;
    box-shadow: -10px 0 10px -10px rgba(0, 0, 0, .18);
  }
  table.tbl th.actions { background: var(--surface-2); }
  table.tbl tbody tr:hover td.actions { background: #fbfcfe; }
}

/* 弹窗表单密度 —— 2026-10-21（「添加商品」加币种/汇率后）
   PC 企微窗口高度常只有 640–700px，`.modal-body` 的 68vh ≈ 440–476px；
   加了「币种」下拉与（外币时的）「汇率」以后，出口退税率/备注会被裁在视口外，
   用户以为字段没了。这里把 modal-body 上限抬到 74vh、表单行距 14 → 8px，
   五行的弹窗正好收进一屏（手机几档不动，仍走上面的默认值）。 */
@media (min-width: 1200px) {
  .modal-body { max-height: 74vh; }
  .form-grid .field { margin-bottom: 8px; }
}

/* ============ 图片裁剪器（2026-10-22 用户要求：上传前先裁） ============
   用在两处：备案联系人照片（固定 1:1）、商品主图（1:1 / 4:3 / 3:4 / 自由）。
   结构：左边画布区（底图 + 可拖动裁剪框）+ 右边预览 / 尺寸 / 比例 / 旋转。
   框外用一圈 9999px 的 box-shadow 压暗（不用另做四块遮罩 div，改框尺寸时不会露缝）。 */
.crop-modal { max-width: 880px; }
.crop-modal .modal-body { max-height: none; overflow: visible; }
.crop-wrap { display: flex; gap: 16px; align-items: flex-start; }
.crop-stage {
  position: relative; flex: 1 1 auto; min-width: 320px; height: 360px;
  background: #eef1f6;
  border: 1px solid var(--border); border-radius: 8px;
  overflow: hidden; touch-action: none; user-select: none;
}
.crop-stage canvas { display: block; }
.crop-box {
  position: absolute; box-sizing: border-box; cursor: move;
  border: 1px solid rgba(255, 255, 255, .95);
  box-shadow: 0 0 0 9999px rgba(15, 23, 42, .45);
}
/* 三分线：裁人像 / 商品构图时有个参照 */
.crop-box::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(255,255,255,.35) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.35) 1px, transparent 1px);
  background-size: 100% 33.33%, 33.33% 100%;
}
.crop-h {
  position: absolute; width: 14px; height: 14px; background: #fff;
  border: 1px solid var(--primary); border-radius: 2px;
}
.crop-h.nw { left: -7px; top: -7px; cursor: nwse-resize; }
.crop-h.ne { right: -7px; top: -7px; cursor: nesw-resize; }
.crop-h.sw { left: -7px; bottom: -7px; cursor: nesw-resize; }
.crop-h.se { right: -7px; bottom: -7px; cursor: nwse-resize; }
.crop-side { flex: 0 0 136px; width: 136px; }
.crop-prev-wrap {
  width: 112px; height: 112px; background: #eef1f6;
  border: 1px solid var(--border); border-radius: 8px; overflow: hidden;
}
.crop-prev-wrap canvas { display: block; width: 112px; height: 112px; }
/* 比例按钮排两列（1:1 | 4:3 / 3:4 | 自由）—— 用 flex 会在窄栏里把「自由」挤到第三行 */
.crop-aspects { display: grid; grid-template-columns: repeat(2, 1fr); gap: 4px; margin: 8px 0; }
.crop-mini-acts { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 6px; }
@media (max-width: 820px) {
  .crop-wrap { flex-direction: column; }
  .crop-side { flex: 1 1 auto; width: 100%; }
  .crop-stage { min-width: 0; height: 300px; }
}

/* ============ 员工头像（2026-10-22 用户要求） ============
   三处用到：员工列表「姓名左边」一列、员工表单头像位、左下角登录者。
   约定：有图放图、没图画姓名首字 —— 所以有没有头像版面都不会塌。 */
.u-av-cell { width: 38px; min-width: 38px; padding-right: 0 !important; text-align: center; }
.u-avatar {
  width: 26px; height: 26px; flex: 0 0 auto; border-radius: 50%; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--primary-weak); color: var(--primary);
  font-size: 11px; font-weight: 600; letter-spacing: .2px;
}
.u-avatar.has-photo { background: #e9edf4; }
.u-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 左下角那个 28px 圆形头像：换成 <img> 之后要撑满且不变形 */
.avatar.has-photo { overflow: hidden; background: #e9edf4; }
.avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 员工表单头像位：比联系人那张（72px）稍小一点，因为员工信息本身少两行 */
.u-av-row .cp-photo { width: 64px; height: 64px; border-radius: 50%; }
.u-av-row .cp-initials { font-size: 20px; }
/* 有照片时把虚线框收掉（否则圆形头像下面会露出一小段虚线弧） */
.cp-photo.has-photo { border-color: transparent; }

/* ============ 客户费用（2026-10-22 用户要求） ============
   两处用到：客户费用列表页、收款认领弹窗里的「抵扣客户费用」区块。
   列表页顶部是筛选条（搜索 / 客户 / 只看未收回 + 右侧合计），下面是常规表格。 */
/* 客户费用筛选条：2026-10-23 用户要求**移出卡片、放到卡片上方**，跟客户 / 供应商 / 货代 / 其他服务商
   页面共用同一套 `.toolbar`（搜索 + 筛选 + spacer + 右侧统计）。卡片里只剩说明 + 表格。
   ⚠️ 全局 `input[type=text] { width:100% }` 特异性是 (0,1,1)：搜索框靠 `.toolbar .search`（0,2,0）压住；
      客户下拉要限宽就写成 `.toolbar select#cf-cust-filter`（带 id，压得住），别写裸 `#cf-cust-filter`
      之外的低特异性选择器 —— 否则下拉会被撑成整行，筛选条散成多行。 */
.toolbar select#cf-cust-filter { flex: 0 1 230px; width: auto; min-width: 160px; max-width: 230px; }
/* 汇总条在 toolbar 右侧（spacer 之后）：多币种时允许在块内换行，别 nowrap 撑破工具栏。
   ⚠️ flex-base 必须写死一个**小宽度**（340px）：`.toolbar` 是 flex-wrap，换行是按 base 宽度判的，
      不是按收缩后的宽度 —— 只写 `flex:0 1 auto` 时汇总的 base 就是整段文案宽（多币种能到 550+），
      1296 窄窗口下会被整块挤到第二行（实测筛选条 72px 两行）。写成 340px 后它在右侧块内换成两行。 */
.cf-sum { font-size: 12.5px; text-align: right; flex: 0 1 340px; min-width: 0; max-width: 340px; }
.cf-sum b { color: var(--warn); }
/* 页面说明条（2026-10-23 用户要求）：在筛选条下面、卡片上面，**不在卡片里**。
   `.toolbar` 自带 margin-bottom:16px，这里用负上边距把它往筛选条下面拉近一点，
   再留 12px 给卡片 —— 读起来是「页头说明」，不是卡片的第一行。 */
.cf-note { margin: -6px 0 12px; line-height: 1.5; }
/* 展开的明细行：浅底，与主行区分开 */
.cf-detail-row > td { background: #f7f9fc; padding: 10px 14px !important; }
.cf-detail-row .cf-sub { margin: 0; }
.cf-row.on > td { background: var(--primary-weak); }
/* 整行可点展开（2026-10-23 用户要求）：给出手型 + hover 底色，否则没人知道这行能点。
   ⚠️ 行内的编辑 / 删除按钮必须 stopPropagation（见 views.customerfees.js#bindRows），
      否则点删除会先展开一行，删完还停在展开态。 */
tr.cf-row { cursor: pointer; }
tr.cf-row:hover > td { background: #f2f6fd; }
tr.cf-row.on:hover > td { background: var(--primary-weak); }
/* 行首的展开指示箭头：收起 ▸ / 展开 ▾ */
.cf-caret { display: inline-block; width: 12px; color: var(--muted); font-size: 10px; margin-right: 2px; }
.cf-caret.open { color: var(--primary); }
/* 明细里的收款编号（RC0001）：可点开那笔收款的分配明细，做成链接色 + 虚点下划线才看得出能点 */
.cf-rcp-link { color: var(--primary); text-decoration: none; border-bottom: 1px dashed currentColor; }
.cf-rcp-link:hover { text-decoration: none; border-bottom-style: solid; }
/* 收款看板里的收款编号列（第一列）：同上，是「查看分配明细」的入口 */
.rcp-no { color: var(--primary); text-decoration: none; border-bottom: 1px dashed currentColor; white-space: nowrap; }
.rcp-no:hover { border-bottom-style: solid; }

/* 收款认领弹窗：「抵扣客户费用」区块 */
.fee-alloc-wrap { margin: 12px 0 2px; padding-top: 10px; border-top: 1px dashed var(--border); }
.fee-line { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 6px; }
.fee-line select { flex: 1 1 260px; min-width: 180px; }
.fee-line input[type=number] { width: 112px; }
.fee-unit { font-size: 12px; color: var(--muted); min-width: 36px; }
.fee-line-hint { flex: 1 1 100%; font-size: 12px; color: var(--muted); padding-left: 2px; margin-top: -2px; }
/* 收款列表里费用抵扣那几行：字色区分，免得看成订单号 */
.rcp-ofee .mono { color: var(--primary); }
.rcp-ofx { font-style: normal; font-size: 11px; color: var(--muted); margin-left: 4px; }

/* ============ 分享弹窗（2026-10-23：附件 / 单据转给企微、微信）============
 * 2026-10-23 晚改版（用户要求）：弹窗里**不再出现链接 / 二维码 / 在浏览器打开**，
 * 只留「系统分享 / 转发给企微好友 / 分享到微信」三条直接发给对方的路 ——
 * 链接一旦摆在输入框里，人就会去粘微信，机密文件就流出来了。
 * 顶端那行深红加粗的机密提示是硬要求（.shr-conf），别删、别改浅。
 */
.share-box { display: flex; flex-direction: column; gap: 10px; }
.share-box .shr-conf {
  text-align: center; font-size: 13.5px; font-weight: 800; letter-spacing: .3px;
  color: #a8170c; background: var(--danger-weak); border: 1px solid #f3c9c4;
  border-radius: 8px; padding: 9px 10px; line-height: 1.5;
}
.share-box .shr-name { font-size: 14px; font-weight: 600; color: var(--text); word-break: break-all; }
.share-box .shr-lab { font-size: 12px; color: var(--muted); margin-top: 2px; }
.share-box .shr-kinds,
.share-box .shr-days { display: flex; gap: 6px; flex-wrap: wrap; }
.share-box .shr-acts { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
.share-box .shr-acts .btn { flex: 1 1 auto; min-width: 140px; padding: 9px 12px; font-size: 13px; }
.share-box .shr-tip { font-size: 12px; line-height: 1.7; color: var(--muted); }
.share-box .shr-tip .err { color: var(--danger, #b0402f); }
.share-box .shr-foot { display: flex; align-items: center; gap: 10px; border-top: 1px dashed var(--border); padding-top: 10px; }
.share-box .shr-foot .hint { flex: 1; font-size: 12px; }

/* ============ 驳回意见提示条（2026-10-24）============
 * 编辑「被驳回」的付款申请时挂在表单最上面：谁驳回的、因为什么、改完会重新走到哪一步。
 * 用左边框 + 淡红底，跟「错误信息」区分开 —— 这是历史意见，不是当前报错。 */
.reject-note {
  border: 1px solid var(--border);
  border-left: 3px solid var(--danger, #d92d20);
  /* ⚠️ 不用 color-mix()：企微内置浏览器版本偏老，不支持会整块没底色 */
  background: rgba(217, 45, 32, 0.06);
  border-radius: 6px;
  padding: 10px 12px;
  margin-bottom: 14px;
  font-size: 13px;
  line-height: 1.7;
  color: var(--text);
}
.reject-note b { color: var(--danger, #d92d20); }

/* ============ 手机端企微适配（2026-10-23 用户要求）============
 * 目标：电脑端企微（主内容区常 800–900px）与**手机端企微**都能用。
 * 断点用 820px：比这窄就是手机 / 竖屏平板。
 *
 * ⚠️ 这里**不把宽表改成卡片式**。理由：同一张表在电脑端是横向阅读习惯（对齐列比对齐键值对快得多），
 *    改卡片式会让两端看到的信息结构不一样，且要维护两套渲染。手机上靠 `.table-wrap` 横滑解决，
 *    首列 sticky 由 ≥1200 那套负责，互不干扰。
 * ⚠️ 抽屉的开关状态在 core.js#initMobileNav，遮罩点一下 / 点任意菜单项 / 路由变化都会关。
 */
@media (max-width: 820px) {
  /* --- 侧栏 → 抽屉 --- */
  .sidebar {
    position: fixed; left: 0; top: 0; bottom: 0; height: 100vh; height: 100dvh;
    width: 276px; flex: none; z-index: 120;
    transform: translateX(-100%); transition: transform .22s ease;
  }
  .sidebar.open { transform: none; box-shadow: 12px 0 34px rgba(16, 24, 40, .2); }
  .nav-mask {
    display: none; position: fixed; inset: 0; background: rgba(18, 24, 38, .45); z-index: 110;
    animation: fade .16s ease;
  }
  .nav-mask.on { display: block; }
  .nav-toggle { display: inline-flex; }

  /* --- 顶栏：汉堡 + 标题，按钮多时换行而不是被裁掉 --- */
  .topbar { height: auto; min-height: 52px; padding: 7px 12px; gap: 8px; flex-wrap: wrap; }
  .topbar h2 { font-size: 15px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .topbar .crumb { display: none; }
  .topbar #top-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-left: auto; }
  .content { padding: 12px; }

  /* --- 触摸目标：按钮不小于 30px，主按钮 36px --- */
  .btn { min-height: 36px; }
  .btn-sm { min-height: 30px; padding: 6px 10px; }
  /* iOS / 企微 WebView：输入框字号 <16px 时聚焦会把整页放大，用户得手动缩回去 */
  input[type=text], input[type=password], input[type=number], input[type=date],
  input[type=email], input[type=tel], select, textarea { font-size: 16px; }
  .toolbar .search input { min-width: 0; }
  .toolbar .search { flex: 1 1 100%; }
  .toolbar select, .toolbar input[type=date] { flex: 1 1 auto; min-width: 0; }
  /* 手机端反过来：日期区间整组独占一行，两个 date 等分（132px 定宽在 390px 下摊不开整行） */
  .toolbar .df-range { flex: 1 1 100%; }
  .toolbar .df-range input[type=date] { width: auto; flex: 1 1 0; }
  /* 手机端：定宽改成等分（两个一行），字才不会被截掉 */
  .toolbar .f-st, .toolbar .f-cur, .toolbar .f-acc, .toolbar .f-who { width: auto; flex: 1 1 40%; min-width: 0; }
  .toolbar .spacer { display: none; }
  .toolbar .settle-actions { width: 100%; justify-content: flex-start; }

  /* --- 弹窗：改成底部抽屉（贴着键盘 / 拇指），高度吃满，内容自己滚 --- */
  .modal-mask { padding: 0; align-items: flex-end; }
  .modal, .modal.wide, .modal.narrow, .modal.pcd-modal {
    max-width: none; width: 100%; margin: 0; border-radius: 16px 16px 0 0;
    max-height: 92vh; max-height: 92dvh; display: flex; flex-direction: column;
  }
  .modal-head { padding: 12px 14px; flex: 0 0 auto; }
  /* ⚠️ 采购合同弹窗（.pcd-modal .modal-body）特异性高于 .modal-body，必须一起列进来，
     否则手机上会留着 80vh 定高、不跟着抽屉撑满 */
  .modal-body, .modal.pcd-modal .modal-body { padding: 14px; max-height: none; flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch; }
  .modal-foot { padding: 10px 14px; flex: 0 0 auto; }
  .modal-foot .btn { flex: 1 1 auto; }

  /* --- 表格：横滑（没有 .table-wrap 的老表格，让卡片体自己成为滚动容器兜底） --- */
  .card-body.tight { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  table.tbl th, table.tbl td { padding: 9px 10px; }
  table.tbl { font-size: 13px; }
  /* 🔴 表格里的操作按钮**不许换行堆叠**（2026-10-23 实测的坑）：
     .row-actions 全局是 flex-wrap:wrap，手机上操作列被压到 90px 时四个按钮叠成四行，
     行高从 44px 涨到 124px，同一行其它列同时被挤成「无/锡/动/力/电/池/厂」的竖条。
     改成 nowrap + 按钮不收缩 → 操作列按内容变宽、表格整体变宽，交给 .table-wrap 横滑。 */
  table.tbl .row-actions { flex-wrap: nowrap; }
  table.tbl .row-actions .btn { flex: 0 0 auto; }
  /* 宽表在手机上给足最小宽度：列宽按内容排，不要被压成竖条。
     （rcp-tbl 1180 / cf-tbl 1020 / q-tbl 1180 / pl-tbl 1020 在各自区块里已经设过，别重复设） */
  table.tbl.claim-tbl { min-width: 1120px; }
  /* 单据号 / 费用事由在手机上不许折行：
     「PR20261021-001」断成两行、「多人认领演示-拼柜运费」被压成两列竖条，都是列宽不够时浏览器硬挤的。
     ⚠️ 费用事由必须靠内层 span 的 min-width 撑列 —— 直接写在 td 上 Chrome 不认（实测无效）。 */
  table.tbl td.mono, table.tbl td.mono a { white-space: nowrap; }
  table.tbl.claim-tbl th.claim-title { width: 160px; }
  table.tbl.claim-tbl .claim-title-in { display: inline-block; min-width: 150px; }
  table.tbl.pay-tbl { min-width: 1080px; }
  table.tbl.org-tbl { min-width: 940px; }
  table.tbl.ord-tbl { min-width: 1000px; }
  table.tbl.reg-tbl { min-width: 900px; }
  table.tbl.cost-tbl { min-width: 900px; }

  /* --- 分享弹窗的三个按钮：手机上竖排、每个都够大 --- */
  .share-box .shr-acts { flex-direction: column; }
  .share-box .shr-acts .btn { width: 100%; min-width: 0; min-height: 42px; }
  .share-box .shr-conf { font-size: 13px; }

  .toast-wrap { top: 10px; left: 8px; right: 8px; transform: none; }
  .toast { max-width: none; width: 100%; }
}
