/* app.css —— 全站唯一样式文件（2026-09-15 由 9 个 CSS 合并） 【为什么合并】本系统靠手工上传部署，文件越多越容易漏传 / 传错层次。 合并为 1 个文件后：只需上传 1 个文件、只需 1 个 <link>。 */

/* 公共基础规范（公共 CSS 基础层）v1 · 2026-09-07 所有页面（主系统 / 收款单据 / 产品价格 / 强泰价格）统一引用本文件。 控件标准值只在这里定义一次，各页面规则通过 var() 引用。 */
/* 全站标准字体链（系统字体栈 System Font Stack） 写法遵循行业惯例… */
:root {
  --ctl-h: 34px;
  --ctl-fs: 15px;
  --ctl-radius: 4px;
  --ctl-border: #ddd;
  --modal-top: min(11vh, 80px);

  --ctl-pad-sm: 0 12px;
  --ink: #1f2733;
  --fs-body: 15px;
  --fs-table: 14px;
  --th-pad: 10px 14px;   /* 列表表头统一内边距（合同/产品/强泰/收款四页一致） */
  --fs-label: 14px;   /* 表单标签字号 */
  --fs-section: 16px; /* 表单分组标题字号（必须 ≥ --fs-body：标题不能比它引导的内容小） */
  --fs-total: 16px;   /* 合计行标签（合同 / 收款两处表单必须同值） */
  --fs-amount: 18px;  /* 合计金额数字 */
  --fs-toast: 13px;   /* 右下角提示条字号 */
  --fs-caption: 13px; /* 说明性小字（表单下方的提示、附注） */
  --lh-heading: 1.3;   /* 标题行高（正文用 body 的 1.6，标题要更紧） */
  --space-label: 8px;       /* 表单标签与控件的间距（8px 网格 × 1） */
  --space-row: 8px;         /* 同一分组内紧邻行的间距（8px 网格 × 1） */
  --space-form: 16px;       /* 表单字段间距（8px 网格 × 2） */
  --space-form-group: 24px; /* 表单分组间距（8px 网格 × 3） */
  --radius-card: 8px;   /* 卡片 / 表格容器圆角 */
  --radius-modal: 10px; /* 弹窗圆角 */
  /* 搜索框统一宽度（合同列表 / 产品价格 / 强泰价格 / 收款单据 / 开票）。
     300 是**量出来的**：开票那条最长占位符文字 272px + 左右内距与边框 26px = 298px ✓
     （原来 260 会把开票的占位符切掉 ✗；合同列表当时靠一句内联 width:300px 侥幸躲过 ✗ 已删）。 */
  --search-w: 300px;
  --op-gap: 8px;        /* 操作列按钮统一间隙（合同 / 产品 / 强泰 / 收款四页一致） */
  --sidebar-w: 230px;   /* 左侧导航栏宽度（.sidebar 用它；合同预览弹窗也用它来避开导航栏） */

  /* ===== 色板（全站唯一来源，改配色只改这一块）===== */
  /* 品牌色 */
  --brand: #2563eb;        /* 主蓝：主按钮 / 链接 / 聚焦 / 选中 */
  --brand-dark: #1d4ed8;   /* 主蓝（深）：hover */
  --brand-soft: #eff6ff;   /* 主蓝（浅底）：聚焦底 / 选中底 / 编辑中 */
  /* 功能色 */
  --danger: #dc2626;       /* 危险：删除 / 负数 / 必填 */
  --danger-border: #fca5a5;/* 危险按钮边框 */
  --danger-soft: #fef2f2;  /* 危险底：删除行 hover */
  --success: #16a34a;      /* 成功提示 */
  /* 文字色（由深到浅） */
  --ink: #1f2733;          /* 主文字 / 表头文字 */
  --ink-2: #334155;        /* 表格正文 */
  --ink-soft: #64748b;     /* 次要说明文字 */
  --ink-faint: #94a3b8;    /* 占位符 / 空状态 / 极淡说明 */
  --ink-label: #475569;    /* 表单标签 */
  /* 线条色 */
  --line: #e6eaf0;         /* 卡片边框 / 分割线 */
  --line-soft: #eef2f7;    /* 更淡的分割线 */
  --line-table: #e2e8f0;   /* 表格线 */
  /* 底色 */
  --surface-hover: #f1f5f9;/* hover 底 / 表头底 */
  --surface-alt: #f8fafc;  /* 斑马纹 / 次级底 */
  --row-hover: #e0f2fe;    /* 表格行 hover 底色（全站统一） */
  --bg: #f4f6fa;           /* 页面底色 */
  --panel: #ffffff;        /* 卡片 / 面板底色 */
  --canvas: #e9edf3;       /* 弹窗画布底色（预览纸外 / 编辑表单外 / 收据详情） */
  --mask: rgba(15,23,42,.45);  /* 弹窗遮罩（全站各弹窗共用，原来抄了 9 份） */

  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
}

/* 表单控件（input / textarea / select / button）浏览器默认字体是 Arial，
   且不会继承 body，必须显式指定，否则页面是雅黑、输入框却是 Arial。
   这是全站公共规则，一次定义四个页面生效。 */
input, textarea, select, button {
  font-family: var(--font-sans);
}

/* 搜索框聚焦态（四页统一） 四个页面搜索框选择器不同：合同列表 .search-input(#q) / 产品价格 #q / 强泰价格 .search / 收款单据 .rc-search，这里一次性全部覆盖。 */
.search-input:focus,
#q:focus,
.search:focus,
.rc-search:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: none;
}

::placeholder {
  color: var(--ink-faint);   /* #94a3b8 统一占位灰，不依赖浏览器默认 #757575 */
  font-size: inherit;        /* 跟随输入框字号 15px */
  opacity: 1;                /* 用颜色本身控制深浅，不再叠透明度 */
}

/* 下拉框（select）全站统一箭头 去掉各浏览器原生黑箭头，统一为品牌蓝「描边空心 V」（与合同列表 .ctl-select 同款：10×6px、#2563eb 描边 1.4、右距 10px、右侧留 28px）。 */
select {
  -webkit-appearance: none !important;
  -moz-appearance: none !important;
  appearance: none !important;
  background: transparent !important;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6'><path d='M1 1.4 L5 4.8 L9 1.4' fill='none' stroke='%232563eb' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/></svg>") !important;
  background-repeat: no-repeat !important;
  background-position: right 10px center !important;
  background-size: 10px 6px !important;
  padding-right: 28px !important;
}

input, textarea, select { color: var(--ink); }

/* —— 按钮 —— */
.btn{display:inline-flex;align-items:center;justify-content:center;font-size:var(--ctl-fs);height:var(--ctl-h);padding:0 16px;box-sizing:border-box;border-radius:var(--ctl-radius);border:1px solid transparent;cursor:pointer;font-weight:500;font-family:inherit}
.btn-primary{background:var(--brand);color:var(--panel)}
/* 【2026-09-22 已合并 ✗→✓】原 `.btn-primary:hover{background:var(--brand-dark)}` ——
   已并入下方**唯一那条**主按钮悬停规则（搜「把"主按钮悬停"合并成」✓ 在第 3003 行附近 ✓）。
   ⚠ 以后改主按钮悬停，去那一条 ✓ 不要在这里写 ✗。 */
.btn-ghost{background:var(--panel);color:var(--ink-label);border-color:var(--ctl-border)}
/* 开票汇总弹窗工具栏的「复制为图片」：裸 .btn 在弹窗里没边框（基础 .btn 是 transparent 边框 ✗）
   → 补一条边框，与旁边的「关闭」（.btn-ghost）常态一致 ✓ */
.inv-mask .inv-modal .toolbar .btn:not(.btn-primary){border-color:var(--ctl-border)}@media (hover: hover) {

/* 【2026-09-23 用户要求·新建合同里那两个 ⚙「管理规格型号选项 / 管理单位选项」】 它们的悬停原来是"只变浅灰底" ✗ → 用户要求跟工具栏那排一致 = **白底 + 蓝框 + 蓝字** ✓。 */
.btn.btn-ghost:hover{background:var(--panel);border-color:var(--brand);color:var(--brand)}
}
.btn-danger{background:var(--panel);color:var(--danger);border-color:var(--danger-border)}

/* ⚠ 必须写成 `.btn.btn-soft`（两个类）✓ —— 只用 `.btn-soft` 无效 ✗： 本文件后面（第 ~469 行）还有一条基础 `.btn{background:var(--panel); */
.btn.btn-soft{background:var(--brand-soft);color:var(--brand);border-color:#bfdbfe}@media (hover: hover) {

.btn.btn-soft:hover{background:#dbeafe;border-color:#93c5fd;color:var(--brand-dark)}
}
.btn.btn-soft:active{background:#dbeafe}

/* —— 行内操作链接 —— */
.link{color:var(--brand);cursor:pointer;font-size:14px;white-space:nowrap;margin-right:var(--op-gap);vertical-align:middle}
.link:last-child{margin-right:0}

/* —— 空状态（全站唯一实现 ✓）—— 历史名字 .rc-empty / .list-empty 共用同一套 ✓；
   容器内的小空态（抬头库 / 调价历史弹窗）留白小一号 ✓ */
.empty,
.rc-empty,
.list-empty,
.invp-empty,
.hist-empty,
.price-app .hist-empty { text-align: center; color: var(--ink-faint); font-size: 14px; }
.empty,
.rc-empty,
.list-empty { padding: 40px 0; }
/* 表格内空态：`.data td` 的内边距特异性更高，会把它压成 9px ⇒ 这里提一级 ✓ */
table.data td.empty { padding: 40px 0; }
.invp-empty { padding: 26px 14px; }
.hist-empty,
.price-app .hist-empty { padding: 20px; }

/* —— 弹窗遮罩 —— */
.mask{position:fixed;inset:0;background:var(--mask);display:none;align-items:flex-start;justify-content:center;padding:var(--modal-top) 0;z-index:50;overflow:auto}
.mask.show{display:flex}

:is(.mask, .pwd-mask, .spec-manage-mask, .rc-modal-mask) > .modal{background:var(--panel);border-radius:var(--radius-modal);width:560px;max-width:94vw;max-height:85vh;overflow:hidden;display:flex;flex-direction:column;box-shadow:0 12px 40px rgba(0,0,0,.2)}
:is(.mask, .pwd-mask, .spec-manage-mask, .rc-modal-mask) > .modal h3{margin:0;padding:14px 18px;font-size:15px;border-bottom:1px solid var(--line-soft);flex:0 0 auto}
:is(.mask, .pwd-mask, .spec-manage-mask, .rc-modal-mask) > .modal .body{padding:16px 18px;overflow:auto;flex:1 1 auto}
:is(.mask, .pwd-mask, .spec-manage-mask, .rc-modal-mask) > .modal .foot{padding:12px 18px;border-top:1px solid var(--line-soft);display:flex;gap:10px;justify-content:flex-end;flex:0 0 auto}
:is(.mask, .pwd-mask, .spec-manage-mask, .rc-modal-mask) > .modal.modal-xs{width:360px}
:is(.mask, .pwd-mask, .spec-manage-mask, .rc-modal-mask) > .modal.modal-sm{width:480px}
:is(.mask, .pwd-mask, .spec-manage-mask, .rc-modal-mask) > .modal.modal-md{width:720px}
:is(.mask, .pwd-mask, .spec-manage-mask, .rc-modal-mask) > .modal.modal-lg{width:1280px}

/* —— 表单字段 —— */

.field input,.field select{width:100%}
.row2{display:flex;gap:12px}
.row2 .field{flex:1}
.err{color:var(--danger);font-size:12px;min-height:16px;margin-top:4px}

.pager{flex:0 0 auto;display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:14px;color:var(--ink-soft);font-size:var(--ctl-fs);font-family:var(--font-sans)}
.pager b{color:var(--ink);font-weight:500}
.pager-sp{flex:1}

.pg-btn{display:inline-flex;align-items:center;justify-content:center;text-align:center;background:var(--panel);border:1px solid var(--ctl-border);border-radius:var(--ctl-radius);padding:0 14px;height:var(--ctl-h);font-size:var(--ctl-fs);font-weight:500;color:var(--ink-label);cursor:pointer;font-family:var(--font-sans);box-sizing:border-box;flex:0 0 auto;white-space:nowrap}@media (hover: hover) {

.pg-btn:hover:not(:disabled){background:var(--surface-hover)}
}
.pg-btn:disabled{opacity:.5;cursor:default}

.toast{position:fixed;top:18px;left:50%;transform:translate(-50%,-8px);z-index:200000;background:var(--ink);color:var(--panel);padding:12px 18px;border-radius:var(--radius-card);box-shadow:0 8px 30px rgba(0,0,0,.2);font-size:var(--fs-toast);opacity:0;transition:all .25s;pointer-events:none;max-width:360px}
.toast.show{opacity:1;transform:translate(-50%,0)}
.toast.err{background:var(--danger)}
.toast.ok{background:var(--success)}

.toast.warn{background:#b45309}

.pwd-mask{position:fixed;inset:0;background:var(--mask);z-index:9999;display:flex;align-items:flex-start;justify-content:center;padding-top:var(--modal-top);overflow:auto}   /* 弹窗略偏上（约 11vh 处）而不是几何正中：视觉重心更舒服，主流设计系统都是这么做的 ✓
   overflow:auto ⇒ 说明文字多、弹窗比视口还高时能滚动，不会把底部按钮裁掉 ✓ */
.pwd-desc{font-size:13px;color:var(--ink-soft);margin:0 0 12px;white-space:pre-wrap}
.pwd-input{width:100%;box-sizing:border-box;height:var(--ctl-h);padding:0 12px;font-size:var(--ctl-fs);border:1px solid var(--ctl-border);border-radius:var(--ctl-radius);background:var(--panel);color:var(--ink);outline:none;font-family:var(--font-sans)}
.pwd-input:focus{border-color:var(--brand)}

.pwd-err{color:var(--danger);font-size:12px;min-height:16px}
/* 【2026-09-26 用户要求·取消按钮统一】「确定 / 取消」改用全站标准 .btn 体系 ✓ （原来用本组件专属 .pwd-ok / .pwd-cancel ✗ —— 其中「取消」的悬停只变浅灰… */
.pwd-mask > .modal .foot .btn{flex:1}

:root {
  /* 公共色板 / 字号 / 圆角统一定义在 base.css（本文件之前加载），这里不再重复定义， 避免同名变量把公共值覆盖回旧色（历史坑：这里曾定义 --primary:var(--brand)… */
  /* --bg / --panel 已上提到 base.css（页面底色 / 卡片底色，全站通用） */
  --accent: #0fb39a; /* 青绿强调色（目前用于：开票汇总「复制为图片」按钮，移动端醒目 ✓） */
  --shadow: 0 1px 3px rgba(20, 30, 50, .06), 0 6px 24px rgba(20, 30, 50, .06);
  /* 旧命名别名，指向 base.css 公共色板，方便老代码不动即可统一（勿在此改值） */
  --primary: var(--brand);
  --primary-dark: var(--brand-dark);
  --primary-soft: var(--brand-soft);
}
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font-sans);
  background: var(--bg);
  color: var(--ink);
  font-size: var(--fs-body);
  line-height: 1.6;
}

/* layout */
.app { display: flex; min-height: 100vh; min-height: 100dvh; }
.sidebar {
  width: var(--sidebar-w); flex-shrink: 0;   /* 宽度见 :root 的 --sidebar-w */
  background: #0f1b33;
  color: #cdd6e6;
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; height: 100dvh;

  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
.sidebar .brand {
  /* 74px 定高 + 水平/垂直居中 —— 别改回内边距撑高（一改字号就偏）✓ */
  background: #1c2c50;   /* 与侧栏对比度 1.25:1（行业"一档"；低于 1.15 就看不出来了）✓ */
  height: 74px;
  display: flex; align-items: center; justify-content: center;
  gap: 10px;
  padding: 0 20px;
  font-size: 18px; font-weight: 700; color: var(--panel);
  letter-spacing: .5px;
}
.sidebar .brand .brand-mark { display: flex; flex: 0 0 auto; }
.sidebar .brand .brand-mark svg { width: 28px; height: 28px; display: block; }

.nav { padding: 12px 0; flex: 1; }
.nav a {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 20px; margin: 0; border-radius: 0;
  border-left: 3px solid transparent;   /* 左侧指示条位（参考对账管理页，2026-09-15 加） */
  color: #cdd6e6; text-decoration: none; cursor: pointer; font-size: 14px;
  transition: background .15s, color .15s, border-color .15s;
}@media (hover: hover) {

.nav a:hover { background: rgba(255,255,255,.06); color:var(--panel); }
}

.nav a.active { background: var(--brand-dark); color: var(--panel); border-left-color: #60a5fa; }
/* 【预留·二级菜单规格】将来加子菜单时按这套加，不用重新算（现在不生效）： 父级（含当前页，展开/收起）：浅底 + 左侧 3px 亮条… */
/* 侧栏导航图标：线性 SVG（18px，颜色跟随文字 currentColor）。
   未选中时略淡(0.78)、hover/选中时满色 —— 这是"现代后台"导航的常见处理，
   视觉上把注意力留给当前页，而不是一排一样重的图标。 */
.nav a .ico { width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; opacity: .78; transition: opacity .15s; }
.nav a .ico svg { width: 18px; height: 18px; display: block; }
.nav a:hover .ico, .nav a.active .ico { opacity: 1; }
.hamburger svg { width: 22px; height: 22px; display: block; }
.nav-sep { height: 1px; background: rgba(255,255,255,.08); margin: 8px 0; }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.topbar {
  height: 60px; background: var(--panel); border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 26px; position: sticky; top: 0; z-index: 5;
}
.topbar h1 { font-size: 20px; margin: 0; font-weight: 650; }
.topbar .sub { color: var(--ink-soft); font-size: 13px; }
.topbar .topbar-logout {
  display: inline-flex; align-items: center; height: 32px; padding: 0 14px;
  border: 1px solid var(--line); border-radius: 8px;
  color: var(--ink-soft); font-size: 13px; text-decoration: none;
  background: var(--panel); transition: border-color .15s, color .15s;
}@media (hover: hover) {

.topbar .topbar-logout:hover { border-color: var(--primary); color: var(--primary); }
}
.content { padding: 26px; max-width: 1400px; width: 100%; margin: 0 auto; }

/* 产品图册：iframe 填满内容区 */
.content.catalog-frame { padding: 0; max-width: none; height: calc(100vh - 61px); height: calc(100dvh - 61px); position: relative; background: #f4f6f6; }

.content.reconcile-frame { padding: 0; max-width: none; height: calc(100vh - 61px); height: calc(100dvh - 61px); position: relative; background: #f4f6f6; }
.content.reconcile-frame iframe { width: 100%; height: 100%; border: 0; display: block; background: #f5f6f8; }
.content.catalog-frame iframe { width: 100%; height: 100%; border: 0; display: block; background: #f5f6f8; position: relative; z-index: 1; color-scheme: light; }

/* 电子签章：原生视图，填满内容区（顶栏由工作台统一提供） */
.content.seal-view { padding: 0; max-width: none; height: calc(100vh - 61px); height: calc(100dvh - 61px); width: 100%; position: relative; }

/* cards */
.card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius-card); box-shadow: var(--shadow); padding: 20px;
}
.card + .card { margin-top: 18px; }
.card h2 { font-size: 18px; margin: 0 0 16px; font-weight: 650; }

.contract-items-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 16px; }
.contract-items-head h2 { margin: 0; }
.contract-items-head .spacer { flex: 1; }
/* 窄屏用的短文案（桌面显示 .ci-long 完整文案，手机切到 .ci-short 短文案 —— 见下面媒体查询） */
.contract-items-head .ci-short { display: none; }

@media (max-width: 1080px) {

  .contract-items-head { gap: 6px; margin: 0 0 12px; }
  .contract-items-head h2 { font-size: 16px; white-space: nowrap; }
  .contract-items-head a.btn { font-size: 14px; padding: 6px 8px; line-height: 1.25; white-space: nowrap; }

  .contract-items-head .ci-long { display: none; }
  .contract-items-head .ci-short { display: inline; }
}
.row { display: flex; gap: 16px; flex-wrap: wrap; }
.grid-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px,1fr)); gap: 16px; }

.stat {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-card);
  padding: 18px 20px; box-shadow: var(--shadow);
}
.stat .label { color: var(--ink-soft); font-size: 13px; }
.stat .value { font-size: 26px; font-weight: 700; margin-top: 6px; }
.stat .value.small { font-size: 20px; }
.stat.clickable { cursor: pointer; transition: background .15s, border-color .15s; }@media (hover: hover) {

.stat.clickable:hover { background: #f4f7fb; border-color: #c5cdd8; }
}

/* 【2026-09-23 用户反馈·"弹窗的按钮点一下会闪一下的颜色"】 实测查证 ✓… */
html { -webkit-tap-highlight-color: transparent; }
@media (hover: none) {
  /* 【2026-09-23 用户反馈·"可以了，但手感确实发死"✓ 说得对 ✓】上一版四处不够 ✓ 逐条抠… */
  .btn:active,
  .rc-btn:active,
  .pg-btn:active, .dp-btn:active, .dp-day:active, .cf-chip:active,
  .col-funnel:active, .r-fab:active {
    transition-duration: 0s;
    background: #e2e8f0;
    transform: scale(.97);
  }
  .dp-lnk:active, .cf-btn:active, .ric:active, .thumb:active,
  .invp-item:active, .inv-drop-item:active,
  .pic-drop:active, .seal-drop:active, .rc-sum:active, .ltoggle:active {
    transition-duration: 0s;
    background: #e2e8f0;
  }

  .btn-primary:active, .btn-export-primary:active, .rc-btn-primary:active { transition-duration: 0s; background: var(--brand-dark); }
  .btn-danger:active, .rc-btn-danger:active { transition-duration: 0s; background: var(--danger-soft); }
  .link:active, .rc-link:active, .op-link:active { transition-duration: 0s; opacity: .55; }
}
/* buttons */

.btn {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  border: 1px solid var(--ctl-border); background: var(--panel); color: var(--ink);
  height: var(--ctl-h); padding: 0 15px; box-sizing: border-box;
  border-radius: var(--ctl-radius); font-size: var(--ctl-fs); font-weight: 500;
  font-family: var(--font-sans);
  transition: all .15s; text-decoration: none; line-height: 1;
}@media (hover: hover) {

.btn:hover { border-color: #c7cfdb; background: var(--surface-hover); }
}

.mask .btn:not(.btn-primary):not(.btn-danger):not(.btn-soft):not(.btn-export-primary):not(.btn-ghost),
.inv-mask .btn:not(.btn-primary):not(.btn-danger):not(.btn-soft):not(.btn-export-primary):not(.btn-ghost),
.spec-manage-mask .btn:not(.btn-primary):not(.btn-danger):not(.btn-soft):not(.btn-export-primary):not(.btn-ghost),
.rc-modal-mask .btn:not(.btn-primary):not(.btn-danger):not(.btn-soft):not(.btn-export-primary):not(.btn-ghost),
.pwd-mask .btn:not(.btn-primary):not(.btn-danger):not(.btn-soft):not(.btn-export-primary):not(.btn-ghost) {
  color: var(--ink-label);
}
.btn.btn-primary{ background: var(--brand); border-color: var(--brand); color: var(--panel); font-weight: 500; border-radius: 4px; height: 34px; padding: 0 16px; box-sizing: border-box; }

/* 工具栏按钮字号统一：与搜索框 / 下拉框同一标准（值来自 base.css --ctl-fs） */
.list-toolbar .btn { font-size: var(--ctl-fs); }
/* 批量删除：红色文字 */
.list-toolbar .btn.btn-danger{ color: var(--danger) !important; border-color: var(--danger-border) !important; font-weight: 500; background:var(--panel) !important; }@media (hover: hover) {

.list-toolbar .btn.btn-danger:hover{ background: var(--danger-soft) !important; }
}
/* 「批量导入」：原来靠 [style*="0fb39a"] 去**匹配标签上的内联颜色** ✗
   （等于在样式表里"猜"内联写了什么 ✗ 内联一改这里就静默失效 ✗）→ 已改成正式类名 .btn-import-ghost ✓
   观感不变（深色字 + 灰边 ✓，就是上面那句青绿被覆盖后的结果 ✓）。 */
.list-toolbar .batch-bar > .btn.btn-import-ghost { color: var(--ink) !important; border-color: #e2e2e2 !important; }
/* 批量栏其余按钮（批量改状态 / 批量导出）文字统一成深色 ——
   上面那条 .list-toolbar .btn 给的是 --ink-label（灰蓝 #475569），在这一排里会显得跟别人不是一个色 */
.list-toolbar .batch-bar > .btn:not(.btn-danger):not(.btn-primary) { color: var(--ink); }

/* 批量改状态按钮壳（灰框同全部状态）；select 本体字号/颜色/高度在下方「下拉框统一基类」 */
.list-toolbar .batch-bar > div.btn {
  height: var(--ctl-h); box-sizing: border-box; padding: 0; display: inline-flex; align-items: center;
  border: 1px solid var(--ctl-border); border-radius: var(--ctl-radius); background: var(--panel);
}
.list-toolbar .batch-bar > div.btn > select {
  padding: 0 24px 0 10px !important;
  background: transparent !important; border: none !important;
  outline: none;   /* 原来写在内联 ✗ → 收进来 ✓ */
  /* base.css 统一 appearance:none 后本 select 的原生箭头被去掉，这里补同款 V 形（同移动端写法） */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6'><path d='M1 1.4 L5 4.8 L9 1.4' fill='none' stroke='%232563eb' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/></svg>") !important;
  background-repeat: no-repeat !important;
  background-position: right 6px center !important;
  background-size: 10px 6px !important;
  cursor: pointer;
}

.btn.btn-sm{ height: var(--ctl-h); padding: 0 14px; font-size: var(--ctl-fs); border-radius: var(--ctl-radius); }

/* 按钮「处理中」：变淡 + 点不动（图标与文字位置都不变，不跳动 ✓）。
   ⚠ 配合 Util.btnBusy() 用 ✓ —— <a class="btn"> 没有 disabled 属性，只有这条 pointer-events 能拦住它 ✓。 */
.btn.is-busy, .rc-btn.is-busy { opacity: .65; pointer-events: none; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

/* table */
/* 使用 border-collapse: separate 而非 collapse，避免 Chrome/Edge 在缩放/高分屏下
   出现 position:sticky 表头被下方数据行穿透的渲染 bug（边框线仍然保留） */
table.data {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
}
table.data th,
table.data td {
  border: 1px solid var(--line-table);
  border-width: 0 1px 1px 0;
}
table.data td:first-child,
table.data th:first-child {
  border-left-width: 1px;
}
table.data th {
  text-align: left; padding: var(--th-pad);
  background: var(--surface-hover);
  border-top-width: 1px;
  border-bottom: 1px solid var(--line-table);
  font-weight: 600; color: var(--ink);

  font-size: var(--fs-table); white-space: nowrap; transition: background .15s, color .15s;
  position: sticky; top: 0; z-index: 3;
  backface-visibility: hidden;
}
table.data td {
  text-align: left; padding: 9px 12px; font-size: var(--fs-table);   /* 【2026-09-20】写死 14px → 变量（值相同 ✓） */
  background: var(--panel);
  /* 给 td 建立独立层叠上下文并置于 z-index:1，确保 sticky 表头在滚动时始终覆盖数据行 */
  position: relative; z-index: 1;
}
table.data thead th { cursor: default; }
table.data th.sort-col { cursor: pointer; user-select: none; }@media (hover: hover) {

table.data th.sort-col:hover { background: var(--row-hover); color: var(--brand-dark); }
}
table.data th.sort-col.sort-active { color: var(--brand-dark); }
table.data th.sort-col .sort-arrow { margin-left: 2px; font-size: 10px; opacity: .5; transition: opacity .15s, color .15s; }
table.data th.sort-col.sort-active .sort-arrow { opacity: 1; color: var(--brand-dark); }
table.data tr { cursor: pointer; }@media (hover: hover) {

table.data tr:hover td { background: var(--row-hover); }
}
table.data tr.hover-row td { background: var(--row-hover); }
table.data tr.selected-row td { background: #eef6ff; }@media (hover: hover) {

table.data tr.selected-row:hover td { background: #e0efff; }
}
table.data tr.selected-row.hover-row td { background: #e0efff; }
/* 合同列表表格统一微软雅黑（覆盖全局宋体），与新建合同页/工具栏一致，仅改字体不动布局 */
.list-scroll table.data, .list-scroll table.data th, .list-scroll table.data td, .list-scroll table.data * {
  font-family: var(--font-sans);
}
/* 合同编号列强制不换行（微软雅黑比宋体宽，140px 放不下会分行） */

.list-scroll table.data .col-no { white-space: nowrap; }
/* 合同列表数字/金额列右对齐（行业标准：数字按位对齐，一眼比大小）+ 等宽数字纵向严丝合缝 */
.list-scroll table.data th.col-num,
.list-scroll table.data td.col-num { text-align: right; font-variant-numeric: tabular-nums; }

.content.list-page {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 61px); height: calc(100dvh - 61px); /* topbar 60px + 1px border */
  overflow: hidden;
  padding: 8px;
  max-width: none;
}
.content.list-page .card { padding: 12px; }
/* 【2026-09-21 用户反馈·"这两个高度不一样"】装着**页脚**的那张卡片，底部不要再垫一层 ✗： 页脚（.pager）自己已经有 12px 下留白 ✓（上 12 / 下 12 对称 ✓）… */
.content.list-page .card:has(#pager) { padding-bottom: 0; }
/* 【2026-09-21 用户要求·"要，改成完全一样"】合同列表 / 劲羽开票 对齐收款单据 ============ 收款单据那套（用户指定的基准）= 卡片内**表格贴边** ✓、页脚外壳左右缩进 16px ✓、卡片外灰边 12px ✓。 */
@media (min-width: 1081px) {
  .content.list-page { padding: 12px; }
  .content.list-page .list-table-card { padding: 0; }
  .content.list-page .list-table-card .list-meta { padding: 12px 16px 0; }

  .content.list-page .list-table-card #pager {
    padding-left: 16px; padding-right: 16px;
  }
}
/* 【2026-09-21 实测·桌面端补 12px】多宽度核对报出： 间距③ 工具栏卡内边距：合同 25px ✓ vs 我那三页 13px ✗（差 12px） 原因 ✓：合同那页的"卡"自己带 20px 内边距 ✓； */

.content.list-page .card + .card,
.invoice-app .card + .card { margin-top: 12px !important; }                       /* 合同 ✓ 开票 ✓ */
.content:is(.price-host, .qtprice-host, .receipt-host) .rc-card-toolbar { margin-bottom: 12px !important; }
.content:is(.price-host, .qtprice-host, .receipt-host) .rc-card-body { margin-top: 0 !important; }
@media (min-width: 1081px) {

  .content:is(.price-host, .qtprice-host, .receipt-host) .rc-card-toolbar { padding: 12px; }
  .content:is(.price-host, .qtprice-host, .receipt-host) .rc-card-toolbar .rc-toolbar { padding: 0; }

  .content:is(.price-host, .qtprice-host, .receipt-host) .rc-card-toolbar { margin-bottom: 12px; }
  .content:is(.price-host, .qtprice-host, .receipt-host) .rc-card-body { margin-top: 0; }

  .invoice-app .card.inv-toolbar { padding: 12px !important; }
}
.content.list-page .list-filter-card { flex: 0 0 auto; }
.content.list-page .list-table-card {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.content.list-page .list-table-card .list-meta { flex: 0 0 auto; }
/* #listBox 是 .list-scroll 的父容器，必须也是 flex 容器，.list-scroll 的 flex:1 才会生效 */
.content.list-page .list-table-card #listBox {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.content.list-page .list-table-card #listBox .list-scroll {
  flex: 1;
  min-height: 0;
  overflow: auto;
  scrollbar-gutter: stable;
  position: relative; /* 建立独立层叠上下文，配合 sticky 表头正确裁剪 */
}
.content.list-page .list-table-card #pager { flex: 0 0 auto; }

.list-scroll table.data { table-layout: fixed; }
/* 手机/平板端卡片视图：桌面端默认隐藏，≤1080px 时由下方媒体查询显示。电脑端布局完全不受影响 */
.list-cards { display: none; }
.batch-bar { display:flex; gap:10px; align-items:center; }
/* 列表页：筛选卡片内「左筛选 / 右操作」分区 */
.list-toolbar {
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  font-family: var(--font-sans);
}
/* 工具栏下拉框统一基类：全部状态 / 批量改状态 共用。改字号、颜色、高度只改这里一处（值来自 base.css 公共变量） */
.list-toolbar > select#statusFilter,
.list-toolbar .batch-bar div.btn select {
  font-size: var(--ctl-fs) !important;
  color: var(--ink) !important;
}
/*  ⚠ 高度**必须按层级分开写** ✗→✓（2026-09-22 根因修复 ✓）—— */
.list-toolbar > select#statusFilter { height: var(--ctl-h) !important; }
.list-toolbar .batch-bar div.btn select { height: 100% !important; }
/* 全部状态：自身带边框，差异部分单独写 */
.list-toolbar > select#statusFilter {
  /* 全局那条「裸 select 满宽」会把它拉长 ✗ —— 原来靠标签上的内联 width:auto 顶着 ✗，现在收进这里 ✓ */
  width: auto !important;
  padding: 2px 28px 2px 12px !important;
  line-height: 1 !important;
  border-radius: var(--ctl-radius) !important; box-sizing: border-box !important;
  border: 1px solid var(--ctl-border) !important; background: var(--panel);
}
/* 列表页：表格卡片顶部信息条（共 N 个合同 / 已选 M 条） */
.list-meta { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:12px; font-size:13px; color:var(--ink-soft); flex-wrap:wrap; }
.meta-left { display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
.meta-stats { display:flex; align-items:center; gap:10px; }
.meta-actions { display:flex; align-items:center; gap:8px; }
.list-meta b { color:var(--ink); font-weight:600; }
.list-meta .meta-sel { color:var(--danger); }
/* 批量导入弹窗的正文（原来写在那段手画弹窗的内联里 ✗ → 收进母本弹窗后用这条管 ✓） */
#importMsg { font-size: 13.5px; color: var(--ink-soft); line-height: 1.8; }
/* 列表页：导出按钮（T3 扁平极简，与工具栏统一） */
.btn.btn-export { display:inline-flex; align-items:center; gap:7px; padding:0 14px; border-radius:4px; height:34px; box-sizing:border-box; font-size:15px; font-weight:500; letter-spacing:0; }
/* 覆盖 btn-sm 的小尺寸，与新建合同按钮等高 */
.btn.btn-export.btn-sm { padding:0 14px !important; font-size:15px !important; height:34px !important; }
.btn-export-primary { background:var(--brand); border-color:var(--brand); color:var(--panel); }@media (hover: hover) {

.btn-export-primary:hover { background:var(--brand-dark); border-color:var(--brand-dark); }
}

.btn-export-secondary,
.content:is(.receipt-host, .price-host, .qtprice-host) .rc-card-body > .rc-batch-bar .rc-btn:not(.rc-btn-danger) {
  background: var(--panel); border-color: var(--brand); color: var(--brand);
}
/* 【2026-09-23 用户反馈·"手机上点「取消选择」后一直保持蓝底白字，不回到蓝字白底"】 根因… */
@media (hover: hover) {
  .btn-export-secondary:hover,
  .content:is(.receipt-host, .price-host, .qtprice-host) .rc-card-body > .rc-batch-bar .rc-btn:not(.rc-btn-danger):hover {
    background: var(--brand); border-color: var(--brand); color: var(--panel);
  }
}
.btn-export-secondary svg { fill:var(--brand); }

.btn > svg, .rc-btn > svg { width: 16px; height: 16px; flex: 0 0 auto; display: block; }
.btn:has(> svg), .rc-btn:has(> svg) { display: inline-flex; align-items: center; gap: 6px; }
/* 列表页：操作列链接（统一蓝 + 删除加粗） */
.op-link { color:var(--primary); cursor:pointer; text-decoration:none; margin-right:var(--op-gap); font-size:14px; vertical-align:middle; }

th.col-withfunnel { position: relative; }

.col-funnel { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; color: var(--ink-faint); cursor: pointer; border-radius: 5px; z-index: 2; transition: background .12s, color .12s; }@media (hover: hover) {

.col-funnel:hover { color: var(--brand); background: var(--brand-soft); box-shadow: inset 0 0 0 1px rgba(37,99,235,.28); }
}
.col-funnel:active { background: #dbeafe; }
.col-funnel.on { color: var(--brand); background: var(--brand-soft); }@media (hover: hover) {

.col-funnel.on:hover { background: #dbeafe; }
}
.col-funnel svg { width: 17px; height: 17px; }
.col-filter-pop { position: fixed; z-index: 100000; width: 240px; padding: 10px; background: #fff; border: none; border-radius: 0; box-shadow: 0 8px 28px rgba(15,23,42,.16), 0 2px 8px rgba(15,23,42,.08); font-family: var(--font-sans); font-size: 13px; box-sizing: border-box; }
.col-filter-pop .cf-title { font-size: 12px; color: var(--ink-faint); margin-bottom: 6px; }
.col-filter-pop input { width: 100%; height: 30px; padding: 0 10px; border: 1px solid var(--ctl-border); border-radius: var(--ctl-radius); font-size: 13px; box-sizing: border-box; outline: none; font-family: inherit; }
.col-filter-pop input:focus { border-color: var(--brand); }
.col-filter-pop .cf-row { display: flex; gap: 8px; margin-top: 8px; }
.col-filter-pop .cf-btn { flex: 1; height: 28px; border: 1px solid var(--ctl-border); background: #fff; border-radius: var(--ctl-radius); cursor: pointer; font-size: 13px; color: var(--ink); font-family: inherit; }@media (hover: hover) {

.col-filter-pop .cf-btn:hover { background: var(--surface-hover); }
}
.col-filter-pop .cf-btn.pri { background: var(--brand); border-color: var(--brand); color: #fff; }@media (hover: hover) {

.col-filter-pop .cf-btn.pri:hover { opacity: .92; }
}
/* 合同列表页：操作列收窄到 140px 时收紧链接间距（仅本页生效，其它列表页不受影响） */
.content.list-page table.data .op-link { margin-right:var(--op-gap); }

.content.list-page table.data th.col-ops,
.content.list-page table.data td.col-ops { padding-left:6px; padding-right:6px; text-align:left; }
/* 子行（多产品合同第二行起）行首格子是「产品名称」td，不带 rowspan 属性。
   全局 td:first-child 的 border-left 会画在需方 rowspan 格右边线旁，叠成重复双线——这里归零。 */
.content.list-page table.data td:first-child:not([rowspan]) { border-left-width: 0; }
/* 列宽自由拖拽：表格宽度 = 各列宽度之和，不再强制填满容器（table.data 的 width:100% 在此页取消）。
   这样拖某条竖线时，右侧所有列保持原宽、整体平移（资源管理器模式）；
   收窄 → 表格变窄右侧留白；加宽 → 超出屏宽时 .list-scroll 出横向滚动条。 */
/* 【2026-09-21 已还原·重要】用户明确要求：**合同列表这一块保持原来的样子** ✓ （原话："我要的是我合同列表原来的那一个……这一块表头不用动… */
/* 【2026-09-21 用户需求·最终版】用户原话（截图指出）： "这里不要离开，应该是铺满的才对。 */
.content.list-page table.data { width: 100%; min-width: max-content; }

/* 列宽拖拽手柄：贴在表头每列右缘（最后一列除外），默认隐形，悬停显示灰色小竖条。
   th 本身是 position:sticky（定位元素），手柄 absolute 相对 th 定位。 */
.content.list-page table.data thead th .col-resizer { position:absolute; top:0; right:-3px; width:7px; height:100%; cursor:col-resize; z-index:5; }
/* 最后一列手柄不向右突出（right:-3px 会伸到表格外，铺满时多出 1px 横向滚动） */
.content.list-page table.data thead th:last-child .col-resizer { right:0; }
.content.list-page table.data thead th .col-resizer::after { content:''; position:absolute; top:25%; height:50%; right:3px; width:2px; border-radius:1px; background:transparent; }@media (hover: hover) {

.content.list-page table.data thead th .col-resizer:hover::after { background:var(--ink-faint); }
}
body.col-resizing, body.col-resizing * { cursor:col-resize !important; user-select:none !important; }
.op-link:last-child { margin-right:0; }@media (hover: hover) {

.op-link:hover { color:var(--primary-dark); }
}
.op-link.op-primary { color:var(--primary); }@media (hover: hover) {

.op-link.op-primary:hover { color:var(--primary-dark); }
}
.op-link.op-danger { color:var(--danger); font-weight:500; }@media (hover: hover) {

.op-link.op-danger:hover { color:var(--danger); }
}

.search-input, .rc-search, .price-app #q, .qtprice-app .search { width: var(--search-w); max-width: 60vw; height: var(--ctl-h); box-sizing: border-box; font-size: var(--ctl-fs); border-radius: var(--ctl-radius); padding: 0 12px; border: 1px solid var(--ctl-border); }
.search-input { min-width: var(--search-w); outline: none; background: var(--panel); }

.search-input:focus { border-color: var(--brand); }

/* form */
.field { margin-bottom: var(--space-form); }
.field label { display: block; font-size: var(--fs-label); color: var(--ink-label); margin-bottom: var(--space-label); font-weight: 500; }
.field .req { color: var(--danger); margin-left: 2px; }
/* 【2026-09-16 修正·重要】不要在本规则里加 `input:not([type])`！ */
input[type=text], input[type=number], input[type=date], .field input, select {
  width: 100%; border: 1px solid var(--ctl-border); border-radius: var(--ctl-radius);

  padding: 0 12px; height: var(--ctl-h); box-sizing: border-box;
  font-size: var(--ctl-fs) !important;
  font-family: var(--font-sans);
  outline: none; background:var(--panel); color: var(--ink);
}

.dp-input::-webkit-calendar-picker-indicator { pointer-events: none; }
.dp-input { cursor: pointer; }

/* 复选框大小 / 勾选列宽度：全站唯一定义处（JS 侧用 Util.ckColWidth() 读 --ck-col） */
:root { --ck-size: 16px; --ck-col: 42px; }
@media (max-width: 1080px) { :root { --ck-size: 20px; } }
input[type="checkbox"] { width: var(--ck-size); height: var(--ck-size); }

/* 四个列表页的勾选列（合同列表 / 开票 / 强泰 / 收款）：宽度取 --ck-col、居中、左右内边距 8px，且不给拖拽手柄 */
.content.list-page table.data thead th:first-child,
.content.list-page table.data tbody td:first-child[rowspan],
.rc-table th.rc-col-sel, .rc-table td.rc-col-sel,
.inv-table-card thead th.chk, .inv-table-card tbody td.chk,
.qtprice-app .rc-table th.col-check, .qtprice-app .rc-table td.col-check {
  width: var(--ck-col); text-align: center; padding-left: 8px; padding-right: 8px;
}
.content.list-page table.data thead th:first-child input[type=checkbox],
.content.list-page table.data tbody td:first-child[rowspan] input[type=checkbox],
.rc-table th.rc-col-sel input, .rc-table td.rc-col-sel input,
.inv-table-card thead th.chk input, .inv-table-card tbody td.chk input,
.qtprice-app .rc-table th.col-check input[type=checkbox], .qtprice-app .rc-table td.col-check input[type=checkbox] {
  width: var(--ck-size); height: var(--ck-size); margin: 0; vertical-align: middle; cursor: pointer;
}

/* 【2026-09-16 修复·移动端】手机点 <input type="date"> 任意位置都会弹系统原生日历，
   此时自绘浮层不再出现（util.js 的 openDatePicker 已在移动端 return）——
   这里把日历图标的 pointer-events 还原，否则用户点那个小图标完全没反应。 */
@media (max-width: 1080px) {
  .dp-input::-webkit-calendar-picker-indicator { pointer-events: auto; }

  .op-link, .rc-link { display: inline-flex; align-items: center; min-height: 34px; padding: 5px 6px; }
  .cc-check { min-height: 34px; }   /* 「选择」这个 label 才是勾选框最好点的地方 */
  /* 【2026-09-16 移动端修复·模板设置页撑破屏幕】 模板设置页「开户与转账信息」的 4 个输入框（开户行/对公账号/公司名称/账号备注） 带**内联** min-width:300px（app.… */
  .form-grid input { min-width: 0 !important; }
}
/* 自绘下拉浮层（桌面端）：原生 <select> 的选项列表由操作系统绘制、改不了，故自绘。见 util.js 的 enhanceSelect()。 */
.sd-opt { padding: 8px 12px; color: var(--ink); cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border-radius: 0; }
.sd-pop { position: fixed; z-index: 100000; min-width: 120px; max-width: min(420px, 92vw); max-height: 320px; overflow-y: auto; padding: 6px 0; background: #fff; border: none; border-radius: 0; box-shadow: 0 8px 28px rgba(15,23,42,.16), 0 2px 8px rgba(15,23,42,.08); font-family: var(--font-sans); font-size: var(--ctl-fs); user-select: none; box-sizing: border-box; }
/* 高亮 = 深灰底白字（浅蓝在白底上看不出指针停在哪）；当前选中项只加粗、不画色块；面板与选项圆角全为 0。 */
.sd-opt { padding: 7px 14px; color: var(--ink); cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sd-opt.sd-hl { background: #475569; color: #fff; font-weight: 600; }
.sd-opt.sd-on { background: transparent; font-weight: normal; }
.sd-opt.sd-on.sd-hl { background: #475569; color: #fff; }
.sd-opt.sd-dis { color: var(--ink-faint); cursor: default; }
.sd-opt.sd-dis.sd-hl { background: transparent; color: var(--ink-faint); }
/* 浮起来的"进场"感：90ms 淡入 + 轻微上移（原生下拉是硬闪出来的，这一步是唯一的观感增强） */
@keyframes sdIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.sd-pop { animation: sdIn .09s ease-out; }
@media (prefers-reduced-motion: reduce) { .sd-pop { animation: none; } }

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; }@media (hover: hover) {

::-webkit-scrollbar-thumb:hover { background: #94a3b8; }
}
::-webkit-scrollbar-corner { background: transparent; }
/* 用**标准属性**兜底并覆盖全站每个元素（Chrome/Edge 121+ 与 Firefox 都认）。 */
html, body, body * { scrollbar-width: thin; scrollbar-color: #cbd5e1 transparent; }
/* 【2026-09-21 撤销记录·重要】上一版我在这里加过一段"滚动条平时隐形、悬停才浮现"的规则 ✗ —— 那是我**理解反了用户的意思** ✗… */
.dp-pop { position: fixed; z-index: 100000; width: 264px; padding: 12px; background: #fff; border: none; border-radius: 10px; box-shadow: 0 8px 28px rgba(15,23,42,.16), 0 2px 8px rgba(15,23,42,.08); font-family: var(--font-sans); font-size: 13px; user-select: none; box-sizing: border-box; }
.dp-head { display: flex; align-items: center; gap: 2px; margin-bottom: 8px; }
.dp-title { flex: 1; text-align: center; font-weight: 600; font-size: 14px; color: var(--ink); }
.dp-btn { width: 24px; height: 26px; display: inline-flex; align-items: center; justify-content: center; border-radius: 6px; cursor: pointer; color: var(--ink-soft); font-size: 15px; line-height: 1; }@media (hover: hover) {

.dp-btn:hover { background: var(--surface-hover); color: var(--brand); }
}
.dp-week { display: grid; grid-template-columns: repeat(7, 1fr); margin-bottom: 2px; }
.dp-week span { text-align: center; padding: 4px 0; font-size: 11.5px; color: var(--ink-faint); }
.dp-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.dp-day { text-align: center; padding: 6px 0; border-radius: 6px; cursor: pointer; color: var(--ink); }@media (hover: hover) {

.dp-day:hover { background: var(--surface-hover); }
}
.dp-blank { cursor: default; }@media (hover: hover) {

.dp-blank:hover { background: transparent; }
}
.dp-today { box-shadow: inset 0 0 0 1px var(--brand); color: var(--brand); }
.dp-sel, .dp-sel:hover { background: var(--brand); color: #fff; box-shadow: none; }
.dp-foot { display: flex; justify-content: space-between; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line-soft); }
.dp-lnk { cursor: pointer; font-size: 12.5px; color: var(--brand); padding: 2px 8px; border-radius: 6px; }@media (hover: hover) {

.dp-lnk:hover { background: var(--surface-hover); }
}
.dp-clear { color: var(--danger); }
/* textarea 是多行控件，不能套用控件标准高度，只统一边框 / 圆角 / 字号 */
textarea {
  width: 100%; border: 1px solid var(--ctl-border); border-radius: var(--ctl-radius);
  padding: 8px 12px; font-size: var(--ctl-fs) !important;
  font-family: var(--font-sans);
  outline: none; background:var(--panel); color: var(--ink);

  resize: vertical; min-height: 70px;
}
/* 数字输入框：关掉上下小箭头。那箭头是浏览器原生控件（不在 DOM 里，没有节点可删），
   只能让它别绘制 —— 效果等同于删除。全站只此一条规则。 */
/* 不写标准属性 appearance:textfield —— 部分浏览器会因此放开非数字输入（能打进中文）。 */
input[type=number] { -moz-appearance: textfield; }
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }

input:focus, textarea:focus, select:focus { outline: none; border-color: var(--brand); }
.btn:focus, .rc-btn:focus, .pg-btn:focus,
.btn:focus-visible, .rc-btn:focus-visible, .pg-btn:focus-visible { outline: none; }
/* 统一下拉框：去掉原生黑箭头，改用品牌蓝描边箭头（与工具栏下拉框一致）。
   高度 / 边框 / 圆角 / 字号继承上方 input/select 统一规则。 */

.ctl-select option, select#status option { background: #fff; color: var(--ink); }
.ctl-select option:hover, select#status option:hover,
.ctl-select option:checked, select#status option:checked { background: #eef5ff; color: #1677ff; font-weight: 600; }

.ctl-select, select#status {
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6'><path d='M1 1.4 L5 4.8 L9 1.4' fill='none' stroke='%232563eb' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat; background-position: right 10px center; background-size: 10px 6px;
  padding-right: 28px;
}
.form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 18px; }
.form-grid .full { grid-column: 1 / -1; }

.form-grid .form-row-3 { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 18px; }

.settings-form { display: flex; flex-direction: column; gap: var(--space-form); }
.settings-form > h2 { margin-bottom: 0; }
.settings-form .field { margin-bottom: 0; }
.settings-form .form-grid { row-gap: var(--space-form); }
.settings-form .field-title { padding-top: calc(var(--space-form-group) - var(--space-form)); }
.field-title > label { font-size: var(--fs-section); font-weight: 600; line-height: var(--lh-heading); color: var(--brand); border-left: 3px solid var(--brand); padding-left: var(--space-label); }
.term-row { display: flex; align-items: center; gap: var(--space-label); margin-bottom: var(--space-row); }
.term-idx { color: var(--ink-faint); }
.form-note { color: var(--ink-soft); font-size: var(--fs-caption); margin-top: calc(var(--space-label) - var(--space-form)); }
.label-hint { margin-left: var(--space-label); font-weight: 400; font-size: var(--fs-caption); color: var(--ink-faint); }
.seal-row { display: flex; flex-wrap: wrap; gap: var(--space-form); }
.settings-actions { margin-top: var(--space-form); }
/* 模板设置页「供方信息 / 开户信息」输入框的 min-width：原来 7 处全写在标签上 ✗
   （手机端还得靠一条 .form-grid input{min-width:0 !important} 去压它们 ✗ —— 那条仍在上面 @media 里 ✓ 继续生效 ✓）。 */
.settings-form #seller { min-width: 280px; }
.settings-form #contractTitle { min-width: 300px; }
.settings-form #contractNoPrefix { min-width: 160px; }
.settings-form #bankName,
.settings-form #bankAccount,
.settings-form #accountOwner,
.settings-form #accountNote { min-width: 300px; }

/* items table (注: 货物清单表格的字体/字号统一在下方 221 行起的专用块中定义) */
.items-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius-card); }
table.items { width: 100%; border-collapse: collapse; min-width: 920px; }
table.items .col-idx { width: 42px; text-align: center; color: var(--ink-soft); }
table.items .col-amount { text-align: center; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* 【2026-10-13 用户要求】「＋ 添加一行」与「含税运总价 / 人民币大写」放**同一行**（添加一行靠左、合计靠右 ✓）。 */
.items-bottom-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 12px; flex-wrap: wrap; }
.items-totals { display: flex; align-items: baseline; gap: 30px; flex-wrap: wrap; }
.items-totals .t { font-size: var(--fs-total); }
.items-totals .t b { font-size: var(--fs-amount); color: var(--primary-dark); }
/* 「保存 / 取消」条：由 openModal 搬到弹窗底部固定成操作栏（见 .pv-modal > .pv-foot）——
   收款 / 开票弹窗页脚本来就有（.rc-modal-foot、.invoice-app .modal .foot 的 border-top），合同表单补齐。
   这里只管按钮排布：单行、靠右（合计已移到上面一行 ✓） */
.totals-bar {
  display: flex; justify-content: flex-end; gap: 30px; align-items: center;
  margin-top: 12px; padding-top: 12px; flex-wrap: wrap;
  border-top: 1px solid var(--line-table);
}
.totals-bar .tb-actions { display: flex; gap: 12px; align-items: center; }

/* 实物图单元格 */
table.items .col-pic { width: 116px; }
.pic-cell { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.pic-drop {
  width: 104px; height: 64px; border: 1px dashed #c2cad8; border-radius: 8px;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  cursor: pointer; background: var(--surface-alt); transition: all .15s; outline: none;
}@media (hover: hover) {

.pic-drop:hover { border-color: var(--primary); background: var(--brand-soft); }
}
.pic-drop.active { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary-soft); }
.pic-drop.drag { border-color: var(--accent); background: #eafffb; }
.pic-drop.uploading { opacity: .6; }
.pic-drop .ph { font-size: 11px; color: var(--ink-soft); text-align: center; line-height: 1.3; }

.ph-lost { color: var(--danger) !important; font-size: 11px; font-weight: 600; }
.pic-drop.lost, .rc-pic-drop.lost { border-style: solid; border-color: var(--danger) !important; background: #fff5f5; }
.pic-drop img { display: block; max-width: 100%; max-height: 100%; object-fit: contain; }
.pic-act { display: flex; gap: 8px; font-size: 12px; }
.link.sm { font-size: 12px; }
.link.danger { color: var(--danger); }

/* 电子章上传 */
.seal-box { min-width: 160px; flex: 1; }
.seal-title { font-size: var(--fs-caption); font-weight: 600; margin-bottom: var(--space-row); }
.seal-acts { display: flex; gap: var(--space-row); margin-top: var(--space-label); font-size: var(--fs-caption); }
.seal-drop {
  width: 150px; height: 150px; border: 2px dashed #c2cad8; border-radius: 10px;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  cursor: pointer; background: var(--surface-alt); transition: all .15s; outline: none;
}@media (hover: hover) {

.seal-drop:hover { border-color: var(--primary); background: var(--brand-soft); }
}
.seal-drop.has { border-style: solid; border-color: var(--accent); }
.seal-drop.uploading { opacity: .6; }
.seal-drop .ph { font-size: 12px; color: var(--ink-soft); text-align: center; line-height: 1.5; }
.seal-drop img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* 签章区印章（预览/打印） */
/* 【2026-09-26】位置：章与落款三行文字垂直居中（略偏上 7px）；文字浮在章之上（章 z1 / 文字 z2），不加描边。
   注意：导出「复制为图片」用的是另一套尺度（字号 17px/行高1.6），坐标在 contract.js 的 __capturing 里，改这里要同步改那边。 */
.sign .seal-col { position: relative; }
.seal-img {
  position: absolute; width: 150px; height: 150px;
  object-fit: contain; opacity: .88; z-index: 1;
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}
.seal-img.buyer-seal {
  top: 2px; left: 4px;
}
.seal-img.seller-seal {
  top: 2px; left: 4px;
}

/* badge */
.badge { display:inline-block; padding: 3px 10px; border-radius: 20px; font-size: 12px; font-weight: 600; }

.badge.status-draft     { background: #8a94a622; color: #8a94a6; }
.badge.status-pending   { background: #e6a23c22; color: #e6a23c; }
.badge.status-signed    { background: #2f9e6b22; color: #2f9e6b; }
.badge.status-cancelled { background: #c0392b22; color: #c0392b; }

.badge.status-issued    { background: #2f9e6b22; color: #2f9e6b; }
.badge.status-void      { background: #c0392b22; color: #c0392b; }
.badge:not([class*="status-"]) { background: var(--ink-soft); color: var(--panel); }
.link { color: var(--primary); cursor: pointer; text-decoration: none; }@media (hover: hover) {

.link:hover { text-decoration: underline; }
}

/* ====== contract preview (A4) ====== */
.preview-shell { background: var(--canvas); padding: 24px; }
.doc {
  background: var(--panel); width: 794px; max-width: 100%; margin: 0 auto;
  padding: 36px 36px 46px; color: #1a1a1a; font-size: 15px; line-height: 1.8;
  font-family: var(--font-sans);
  box-shadow: 0 4px 30px rgba(0,0,0,.12);
}
/* 手机/平板端合同内容：宽度自适应，可横向滑动查看完整A4 */

   /* 改这个断点的样式前，先把 5 处都搜出来看一遍，避免只改了一处。 ── */
@media (max-width: 1080px) {
  .doc {
    width: 100%;
    padding: 20px 16px 28px;
    font-size: 14px;
    box-shadow: 0 2px 12px rgba(0,0,0,.08);
  }
  /* 合同内容区包裹层：允许横向滚动 */
  .preview-shell {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding: 10px 4px;
  }
  /* 表格最小宽度保证不压缩变形 */
  .doc table.goods { min-width: 600px; }
}
   /* 改这个断点的样式前，先把 2 处都搜出来看一遍，避免只改了一处。 ── */
@media (max-width: 480px) {
  .doc { padding: 16px 12px 24px; font-size: 13px; }
  .doc h1.title { font-size: 20px; letter-spacing: 4px; margin-bottom: 18px; }
  .doc table.goods { min-width: 540px; font-size: 12px; }
  .doc table.goods th, .doc table.goods td { padding: 4px 2px; }
}
.doc h1.title { text-align: center; font-size: 26px; letter-spacing: 4px; margin: 0 0 18px; font-weight: 700; }
/* 【2026-10-16 用户反馈·段间距不统一】用户圈出「供方↔兹有…」「公司名称↔3、合同条款」两处空白，
   说"跟需方和供方之间的间隙不一样"，要求**全部**对齐到「需方/供方」那一档（.parties 的 gap:4px）。
   下面几条 margin 一起收窄 ⇒ 全文各段之间的**视觉**间隙都 ≈16.8px ✓。
   注意：字号不同、元素类型不同（文字↔文字 / 表格↔文字），需要的 margin 数值各不相同，别强行写成同一个数 ✗ */
.doc .parties { display: flex; flex-direction: column; gap: 4px; margin-bottom: 4px; }
.doc .parties .p { font-size: 16px; font-weight: 700; }
/* 4px：原先是写在 contract.js 的内联 style 里（margin:8px 0 4px）✗ → 挪进 CSS 统一管理 ✓，数值同步收窄到同一档 */
.doc .section-title { font-size: 16px; margin: 4px 0; }
/* 上 4px（与 .parties 的 margin-bottom 折叠）= 与「需方/供方」同一档 ⇒ 视觉 4+6.4+6.4 ≈ 16.8px ✓（原来是 16/18，明显偏大 ✗） */
.doc .intro { margin: 4px 0; text-indent: 0; font-size: 16px; }
/* 【2026-10-16 用户反馈·打印出来"内容不居中、右边空一大片"】这张表原来**没有 width**（只有 max-width）
   → 表格只按内容撑开（实测：A4 页宽下只有 703px，而它兄弟元素都是满宽 1394/688 ✗）→ 右边留一大片空白 ✗。
   补 width:100% → 各列按内容比例铺满页宽 ⇒ 左右留白相等、看着才是居中的 ✓
   （与开票汇总单的表格 `.inv-modal table.goods{width:100%}` 写法对齐 ✓） */
/* 下方 11px（不是 6px）：表格后面接的是文字，表格本身没有行高留白 ⇒ 要给大一点才能和"文字↔文字"那档视觉一致（11+5.5 ≈ 16.5px ✓） */
.doc table.goods { border-collapse: collapse; width: 100%; margin: 8px 0 11px; font-size: 14px; max-width: 100%; table-layout: auto; }
.doc table.goods th, .doc table.goods td { border: 1px solid #333; padding: 4px 3px; text-align: center; vertical-align: middle; }
.doc table.goods th { font-weight: 600; white-space: nowrap; }
.doc table.goods td .pic { width: 100px; height: 100px; object-fit: contain; cursor: pointer; display: block; margin: 0 auto; }
/* 实物图单元格去掉内边距，消除图片周围空白 */
.doc table.goods td:has(> .pic) { padding: 2px 1px; }

/* 新建/编辑页表格：单元格居中，输入框居中 */
table.items { border-collapse: collapse; width: 100%; font-size: 15px; font-family: var(--font-sans); }
table.items th, table.items td { border: 1px solid #ccc; padding: 5px 4px; text-align: center; vertical-align: middle; }
table.items th { background: var(--surface-hover); white-space: nowrap; font-size: 15px; color: var(--ink); font-weight: 600; }
table.items th.col-idx { color: var(--ink); }
table.items td input, table.items td select, table.items td textarea { text-align: center; font-family: var(--font-sans); font-size: 15px !important; box-sizing: border-box; border: none !important; outline: none !important; background: transparent; min-height: 36px; padding: 4px 6px; width: 100%; }
/* 聚焦：无任何边框/高亮（纯净无边框） */
table.items td input:focus, table.items td select:focus { outline: none !important; border-color: transparent !important; box-shadow: none !important; background: transparent !important; }
table.items td.col-amount { font-size: 15px; font-family: var(--font-sans); }
table.items td input[data-f="spec"] { border: none !important; outline: none !important; background: transparent; box-shadow: none !important; text-align: center !important; padding: 0 !important; width: 100% !important; }
/* 【本轮·行业标准】明细表格子里的"宽度/居中"原来全写在标签上 ✗ （cell-spec 一条串了 9 个属性 ✗、cell-note 又另一种写法 ✗）—— 上面 1092 那条其实已覆盖其余全部属性 ✓，只有下面这几个宽度是真正需要搬过来的 ✓。 */
table.items td input[data-f="unit"] { width: 80px; }
table.items td input[data-f="price"] { width: 80px; }
table.items td input[data-f="amount"] { width: 100px; }
table.items td.cell-unit { white-space: nowrap; }
table.items td.cell-act > div { display: inline-flex; gap: 12px; align-items: center; }
/* 明细表 / 手机端卡片的「删除」链接统一红字（原来两边各写一个内联颜色 ✗） */
.link-del { color: #e5484d; }
/* 产品名称：padding留白让文字视觉居中 */
table.items td.cell-name { vertical-align: middle; text-align: center !important; padding: 4px 6px; }
table.items td.cell-name textarea[data-f="name"] { width: 100%; padding: 12px 6px 4px 6px; line-height: 1.25; text-align: center !important; border: none; outline: none; background: transparent; resize: none; overflow-y: hidden; font-family: var(--font-sans); font-size: 15px !important; word-break: break-word; box-sizing: border-box; min-height: 36px !important; height: 36px !important; }
/* 备注：td 2px + flex 容器让 textarea 真正垂直居中，四周统一 2px */
table.items td:has(textarea[data-f="note"]) { padding: 2px !important; }
.note-cell-wrap { display: flex; align-items: center; justify-content: center; height: 100%; min-height: 36px; }
table.items td textarea[data-f="note"] { width: 100%; padding: 8px 0 !important; line-height: 1.15 !important; text-align: center !important; border: none; outline: none; background: transparent; resize: none; overflow-y: hidden; font-family: var(--font-sans); font-size: 15px !important; word-break: break-word; box-sizing: border-box; min-height: 36px !important; }
table.items td input[data-f="spec"]:focus { border: none !important; outline: none !important; box-shadow: none !important; }
table.items td.col-idx { cursor: pointer; position: relative; user-select: none; transition: background 0.15s; border-radius: 3px; }@media (hover: hover) {

table.items td.col-idx:hover { background: #e8f4fd; color: #1677ff !important; font-weight: 600; }
}@media (hover: hover) {

table.items td.col-idx:hover .idx-num { display: none !important; }
}@media (hover: hover) {

table.items td.col-idx:hover .idx-copy { display: inline !important; }
}
/* 6px（原 20px）：.section 是"文字块"，上下各带半个行距留白 ⇒ 6+5.5+5.5 ≈ 17px，与「需方/供方」同一档 ✓ */
.doc .section { margin-top: 6px; }
.doc .section .st { font-weight: 700; font-size: 16px; margin-bottom: 6px; }
.doc .terms li { margin: 4px 0; }
.doc .sign { display: flex; justify-content: space-between; margin-top: 34px; }
.doc .sign .col { width: 44%; }
.doc .sign .col:last-child { margin-left: auto; }
.doc .sign .line { margin: 22px 0 6px; position: relative; z-index: 2; }
.doc .sign .label { color: #333; }

.pv-mask { position: fixed; inset: 0 0 0 var(--sidebar-w); z-index: 9000; background: var(--mask);
  display: flex; padding: 24px; overflow-y: auto; }
.pv-modal { flex: 1; min-width: 0; background: var(--panel); border-radius: 12px;
  display: flex; flex-direction: column; overflow: hidden;
  box-shadow: 0 20px 60px rgba(0,0,0,.28); }

.pv-head { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 16px; border-bottom: 1px solid var(--line); flex: 0 0 auto; }
.pv-title { font-size: 15px; font-weight: 700; color: var(--ink); flex: 0 0 auto; white-space: nowrap; }
.pv-x { background: none; border: none; color: var(--ink-soft); font-size: 22px; line-height: 1;
  cursor: pointer; padding: 2px 10px; border-radius: 6px; flex: 0 0 auto; }
.pv-x:hover { background: var(--surface-alt); color: var(--ink); }
/* 工具栏那一行：固定在标题栏下面，合同上下滚动时它不动 ✓ */
.pv-bar { display: flex; justify-content: center; padding: 8px 16px;
  border-bottom: 1px solid var(--line); background: var(--panel); flex: 0 0 auto; }
/* 这条工具栏要压掉手机端那条 `.preview-toolbar{flex-direction:column!important}`（竖排铺满会撑成一列 ✗），
   用 .pv-bar 前缀（优先级更高）+ !important 改回横向换行 ✓ —— 两处都带 !important，靠优先级定胜负 */
.pv-bar .preview-toolbar { margin-bottom: 0 !important; gap: 6px !important; flex-direction: row !important;
  flex-wrap: wrap !important; align-items: center !important; justify-content: center !important; }
.pv-bar .preview-toolbar .btn { width: auto !important; padding: 7px 11px !important; font-size: 13px !important; }
.pv-body { overflow-y: auto; -webkit-overflow-scrolling: touch; flex: 1 1 auto; background: var(--canvas); }
.pv-body .preview-shell { padding: 20px 16px; }
/* 编辑表单弹窗主体：底色不另设（沿用 .pv-body 画布，与预览同一片灰），只加一层限宽居中容器 */
.form-modal-inner { padding: 20px 20px 28px; max-width: 1400px; width: 100%; margin: 0 auto; }
/* 【2026-10-13 用户反馈】新建/编辑合同弹窗：明细行一多，「保存合同」被滚出视野 ✗ （新增开票弹窗底部有固定 .foot，合同弹窗没有 ✗）。 */
.pv-modal > .pv-foot {
  flex: 0 0 auto; margin-top: 0;
  padding: 12px 20px; border-top: 1px solid var(--line);
  background: var(--panel);
}
@media (max-width: 820px) {
  /* 手机/平板：弹窗占满整屏（导航此时是抽屉，不用避开），A4 仍可横向滑动查看 */
  .pv-mask { inset: 0; padding: 0; }
  .pv-modal { border-radius: 0; }
  .pv-head { padding: 6px 12px; }
  .pv-bar { padding: 8px 12px; }
  .pv-body .preview-shell { padding: 8px 4px; }
  .form-modal-inner { padding: 12px 12px 24px; }
}

.preview-toolbar { display:flex; gap:8px; justify-content:center; margin-bottom: 16px; flex-wrap: wrap; }
.preview-toolbar .btn { font-size: 13px; padding: 8px 12px; }

/* 手机端货物清单卡片列表（桌面端隐藏，仅手机端显示） */
.rc-item-list { display: none; }

/* ====== 新建/编辑页 货物清单 手机/平板端折叠展开（方案C，≤1080px 生效，宽屏桌面不动） ====== */

   /* 改这个断点的样式前，先把 5 处都搜出来看一遍，避免只改了一处。 ── */
@media (max-width: 1080px) {
  .items-wrap { overflow-x: hidden; border: none; background: transparent; padding: 0; }
  /* 隐藏原始表格，用 JS 生成的卡片列表替代 */
  table.items { display: none !important; }
  /* 卡片列表容器 */
  .rc-item-list { display: flex; flex-direction: column; gap: 10px; }
  /* 每行 = 一张可折叠卡片 */
  .rc-item {
    border: 1px solid #e0e4ea; border-radius: 10px;
    background: var(--panel); overflow: hidden;
  }
  /* 展开时允许溢出（规格型号下拉框需要超出 .rc-item 边界显示） */
  .rc-item.rc-open { overflow: visible; }
  /* ── 摘要栏（始终可见）── */
  .rc-sum {
    display: flex; align-items: center; gap: 10px;
    padding: 12px 14px; cursor: pointer;
    user-select: none; -webkit-tap-highlight-color: transparent;
  }
  .rc-sum .s-idx {
    width: 26px; height: 26px; border-radius: 50%;
    background: var(--brand-soft); color: var(--brand-dark); font-weight: 700; font-size: 13px;
    display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  }
  .rc-sum .s-name {
    flex: 1; font-size: 15px; font-weight: 600; color: var(--ink);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
  }
  .rc-sum .s-amt {
    font-weight: 700; color: var(--brand-dark); font-size: 15px; flex-shrink: 0;
    margin-right: 2px;
  }
  .rc-sum .s-arrow {
    color: var(--ink-faint); font-size: 18px; flex-shrink: 0;
    transition: transform .2s;
  }

  /* ── 展开区（默认隐藏）── */
  .rc-detail { display: none; }
  .rc-item.rc-open .rc-detail { display: block; }
  .rc-item.rc-open { box-shadow: 0 2px 8px rgba(0,0,0,.06); }
  .rc-item.rc-open .rc-sum .s-arrow { transform: rotate(90deg); }
  .rc-item.rc-open .rc-sum { border-bottom: 1px solid #eef1f5; }

  .rc-fld-lab { font-size: 12.5px; color: var(--ink-label); font-weight: 600; }
  /* 整行字段：产品名称 / 备注 / 实物图 */
  .rc-full { border-bottom: 1px solid #f5f6f7; padding: 8px 14px; display: flex; flex-direction: column; gap: 3px; }
  /* 三列行：规格型号 / 单位 / 数量 */
  .rc-row3 { display: grid; grid-template-columns: 1.65fr 0.9fr 1fr; border-bottom: 1px solid #f5f6f7; }
  .rc-row3 .rc-fld { padding: 8px 10px; display: flex; flex-direction: column; gap: 3px; border-right: 1px solid #f5f6f7; position: relative; }
  .rc-row3 .rc-fld:last-child { border-right: none; }
  /* 两列行：含税单价 / 含税总价 */
  .rc-row2 { display: grid; grid-template-columns: 1fr 1fr; border-bottom: 1px solid #f5f6f7; }
  .rc-row2 .rc-fld { padding: 8px 14px; display: flex; flex-direction: column; gap: 3px; border-right: 1px solid #f5f6f7; position: relative; }
  .rc-row2 .rc-fld:last-child { border-right: none; }
  /* 操作行 */
  .rc-acts { display: flex; justify-content: flex-end; gap: 16px; padding: 10px 14px; border-top: 1px solid #eef1f5; }

  /* 输入框统一样式 */
  .rc-fld input, .rc-fld textarea, .rc-full input, .rc-full textarea {
    border: 1px solid #d8dee8; border-radius: 8px;
    background: var(--panel); padding: 8px 10px; min-height: 38px;
    width: 100%; font-size: 15px; font-family: inherit; box-sizing: border-box;
  }
  .rc-full textarea { resize: none; overflow-y:hidden; line-height:1.3; }
  /* 手机端卡片：规格型号 / 单位 两个输入框居中（原来各写一句内联 text-align ✗） */
  .rc-detail .rc-row3 .rc-fld input { text-align: center; }
  /* 实物图占位 */
  .rc-pic-drop { width:100%; height:60px; border:1px dashed #c2cad8; border-radius:8px; display:flex; align-items:center; justify-content:center; background:var(--surface-alt); overflow:hidden; }
  .rc-pic-drop .ph { font-size:12px; color:var(--ink-soft); text-align:center; line-height:1.3; }
  /* 实物图预览：约束在框内（不约束会被手机原图几千px宽撑爆整卡） */
  .rc-pic-drop img { display:block; max-width:100%; max-height:100%; object-fit:contain; }
}

/* print */
   /* 改这个断点的样式前，先把 3 处都搜出来看一遍，避免只改了一处。 ── */
@media print {
  body { background: var(--panel); margin: 0; -webkit-print-color-adjust: exact; print-color-adjust: exact; }

  body.printing > *:not(#printHost) { display: none !important; }
  .no-print { display: none !important; }
  .preview-shell { padding: 0; background: var(--panel); overflow-x: hidden !important; }
  .doc {
    box-shadow: none;
    width: 100%;
    box-sizing: border-box;
    /* 【2026-10-16 修复·打印留白被反超】这里原来只有 `padding: 14mm` ✗ ——
       A4 竖向打印视口正好 794px ≤ 820px ⇒ 命中文件末尾那条 `@media (max-width:820px) .doc{padding:18px}`，
       而它排在本打印块**之后**、优先级相同 ⇒ 打印时它赢 ✗，实际只留 18px（≈4.8mm），
       已贴到多数激光打印机 4~5mm 的不可打印区（边上竖线有被裁的风险 ✗）。
       补 !important ⇒ 打印留白恒定 14mm（≈52.9px），A4 版心 210−14×2 = 182mm = 688px，左右对称 ✓，
       观感与屏幕预览（36px≈9.5mm）同一档，更稳妥。 */
    padding: 14mm !important;
    font-size: 11pt;
    line-height: 1.75;
    font-family: "Arial", "SimHei", "DengXian", "Microsoft YaHei", sans-serif;
  }
  .doc h1.title { font-size: 20pt; letter-spacing: 4px; }
  .doc table.goods { font-size: 11pt; }
  .doc table.goods th { font-size: 11pt; font-weight: 600; }
  .doc .section-title { font-size: 12pt; }
  @page { size: A4; margin: 0; }
  /* 清单页批量打印：内容直接渲染进 #printHost ✓（不进预览页、不弹新标签 ✓） */
  body.printing #printHost { position: static !important; left: auto !important; top: auto !important; width: auto !important; display: block !important; opacity: 1 !important; background: var(--panel); }
  body.printing #printHost .no-print,
  body.printing #printHost .preview-toolbar,
  body.printing #printHost .pic-lightbox { display: none !important; }
}

/* #printHost：平时隐藏；打印准备态时变成"完全透明覆盖层"。 实心原因（别改 ✗）：图片必须在**视口内**被浏览器真实光栅化，离屏容器的图不会被光栅化 → 打印出来是空白 ✗（清单页批量打印当年就踩过这个坑 ✓）。 */
#printHost { display: none; }
body.printing #printHost {
  display: block;
  position: fixed; inset: 0;
  left: 0; top: 0; right: 0; bottom: 0;
  width: auto; background: var(--panel);
  overflow: auto;
  opacity: 0;
  z-index: 99999;
  pointer-events: none;
}
/* 准备态也隐藏工具栏/无打印元素，避免闪现预览界面 */
body.printing #printHost .preview-toolbar,
body.printing #printHost .no-print,
body.printing #printHost .pic-lightbox { display: none; }

/* 规格型号自定义下拉（替代 datalist，下拉文字可居中/改字体） */
/* 注意：position / left / top / width 均由 JS openSpec() 动态设置（absolute 挂 .rc-fld 内，CSS 已设 position:relative） */
.spec-combo {
  background: var(--panel); border: 1px solid var(--line); border-radius: 9px;
  box-shadow: 0 6px 24px rgba(20,30,50,.12);
  max-height: 240px; overflow-y: auto;
  font-family: var(--font-sans);
  font-size: 16px;
}
.spec-combo-item { padding: 9px 14px; text-align: center; cursor: pointer; color: var(--ink); white-space: nowrap; }
.spec-combo-item:hover, .spec-combo-item.active { background: #eef5ff; color: #1677ff; font-weight: 600; }

/* 管理材质选项弹窗 */
.spec-manage-mask { position: fixed; inset: 0; background: var(--mask); z-index: 9500; display: flex; align-items: flex-start; justify-content: center; padding: var(--modal-top) 0; overflow: auto; }
.spec-manage-mask .sm-sub { font-size: 12px; color: #888; font-weight: 400; }
.spec-manage-mask .sm-list { padding: 0; }
.spec-manage-mask .sm-row { display: flex; gap: 10px; align-items: center; margin-bottom: 10px; }
.spec-manage-mask .sm-input { flex: 1; border: 1px solid var(--line); border-radius: 8px; padding: 9px 12px; font-size: 15px; font-family: inherit; outline: none; }
.spec-manage-mask .sm-input:focus { border-color: var(--brand); }

/* ===================== 手机/平板端适配 ===================== */
/* 汉堡按钮与遮罩默认隐藏（桌面端不显示） */
.hamburger { display: none; }
.nav-overlay { display: none; }

@media (max-width: 820px) {
  /* 侧边栏改为可滑出的抽屉 */
  .app { display: block; }
  .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 60;

    width: 58vw; max-width: 228px;
    transform: translateX(-100%); transition: transform .25s ease;
    box-shadow: 0 0 40px rgba(0,0,0,.35);

    padding-bottom: max(10px, env(safe-area-inset-bottom));
  }
  .sidebar.open { transform: translateX(0); }
  .nav-overlay.show {
    display: block; position: fixed; inset: 0; z-index: 55;
    background: rgba(0,0,0,.45);
  }
  /* 顶栏显示汉堡按钮，缩小高度 */
  .hamburger {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; font-size: 22px; line-height: 1;
    border: none; background: transparent; color: var(--ink); cursor: pointer;
    margin-right: 6px; flex-shrink: 0;
  }
  .topbar { height: 54px; padding: 0 12px; position: relative; justify-content: center; }
  .topbar .hamburger { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); margin-right: 0; }
  .topbar > div:nth-of-type(1) { text-align: center; width: 100%; padding: 0 46px; box-sizing: border-box; }
  .topbar > div:nth-of-type(2) { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); }
  .topbar h1 { font-size: 17px; }
  .topbar .sub { font-size: 12px; }
  /* 内容区：顶栏此时是 54px（上面已改），图册 iframe 的高度基准跟着它走。
     （.content 的 padding 不在这里重复定义 —— 下方 1080 块会给到，820 是同属生效范围。） */
  .content.catalog-frame { height: calc(100vh - 54px); height: calc(100dvh - 54px); }
}

   /* 改这个断点的样式前，先把 5 处都搜出来看一遍，避免只改了一处。 ── */
@media (max-width: 1080px) {
  /* 内容区 */
  .content { padding: 14px; }

  /* 表单单列、行竖排；合同编号 / 需方 仍占满整行（保持原样） */
  .form-grid { grid-template-columns: 1fr 1fr; }
  /* 【2026-09-16 修复·重要】这里必须用 `>` 限定"直接子元素"！ */
  .form-grid > .field:nth-child(1),
  .form-grid > .field:nth-child(2) { grid-column: 1 / -1; }

  /* 【2026-09-23 用户反馈·第三轮 —— "弄好了日期… */
  .form-grid .form-row-3 { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 10px; }
  .form-grid .form-row-3 .field { min-width: 0; }
  .form-grid .form-row-3 .field:nth-child(1) { flex: 1 1 calc(9.5 * var(--ctl-fs)); }   /* 签订日期：体面最小 ≈ 9.5 字宽 ✓ */
  .form-grid .form-row-3 .field:nth-child(2),
  .form-grid .form-row-3 .field:nth-child(3) { flex: 1 1 calc(4.7 * var(--ctl-fs)); }   /* 印章 / 状态 ≈ 4.7 字宽 ✓ */
  .form-grid .form-row-3 input,
  .form-grid .form-row-3 select { width: 100%; box-sizing: border-box; min-width: 0; }
  /* 【2026-09-23 用户反馈·"输入框两边的留白跟合同列表不一致，我要他们一致"】 实测（390px 档，同一探针 ✓）… */
  .content:has(.form-grid) .card { padding-left: 8px; padding-right: 8px; }
  /* 【2026-09-23 用户反馈·"卡片边可以了，但白卡本身没跟合同列表对齐"】 实测（360 / 390 / 430 三档 ✓ 探针量的是**白卡的左右边界**）… */
  .content:has(.form-grid) { padding-left: 8px; padding-right: 8px; }

  .form-grid .field:nth-child(1) input { width: 100%; box-sizing: border-box; }
  .form-grid .field.field-buyer { position: relative; }
  .form-grid .field.field-buyer > label { min-height: 30px; padding-right: 120px; box-sizing: border-box; display: flex; align-items: center; }
  .form-grid .field.field-buyer > .buyer-row { display: flex !important; flex-direction: column !important; }
  .form-grid .field.field-buyer > .buyer-row > input#buyer {
    width: 100% !important; box-sizing: border-box; order: 2; margin-top: 6px;

    flex: 0 0 auto !important;
    height: var(--ctl-h);
  }
  .form-grid .field.field-buyer > .buyer-row > button { position: absolute; top: 0; right: 0; height: 30px; font-size: 13px; padding: 0 12px; }
  .form-grid .field.field-buyer > .buyer-row > button:first-of-type { right: 62px; }
  .row { flex-direction: column; align-items: stretch; }
  .grid-stats { grid-template-columns: 1fr 1fr; gap: 12px; }

  /* 卡片内宽表格可横向滚动，避免撑破屏幕 */
  .card { padding: 16px; overflow-x: auto; }
  table.data { width: 100%; }

  /* 手机端合同列表：操作列竖排（间距适中，防误点） */
  .list-page table.data td:last-child {
    display: flex;
    flex-direction: column;
    gap: 7px;
    align-items: flex-start;
    min-width: 52px;
    padding: 4px 0;
  }
  .list-page table.data td:last-child .link {
    font-size: 13px;
    margin-left: 0 !important;
    white-space: nowrap;
    padding: 3px 0;
    line-height: 1.5;
  }

  /* 手机/平板端合同列表：隐藏宽表格，改为卡片「整页滚动」（电脑端不变，仅 ≤1080px 生效） */
  .list-scroll-table { display: none; }
  /* 解除桌面端「整页不滚、仅内容区内部滚」的约束，手机端整页可上下滑动看完全部合同 */
  .content.list-page {
    height: auto !important;
    min-height: 0 !important;
    overflow: visible !important;
    display: block !important;
  }
  .content.list-page .list-filter-card { flex: none !important; }
  .content.list-page .list-table-card {
    flex: none !important;
    min-height: 0 !important;
    display: block !important;
    height: auto !important;
  }
  .content.list-page .list-table-card #listBox {
    flex: none !important;
    min-height: 0 !important;
    display: block !important;
    height: auto !important;
    overflow: visible !important;
  }
  /* 列表卡片在手机端减少左右内边距，让合同卡片更宽、更舒展 */
  .content.list-page .list-table-card { padding: 16px 8px !important; }
  /* 搜索框卡片与列表卡片左右留白保持一致（手机端） */
  .content.list-page .list-filter-card { padding: 16px 8px !important; }
  /* 手机端批量操作区：批量改状态 / 批量删除 / 批量导入 三按钮并成一行（电脑端不变） */
  .list-toolbar .batch-bar {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    align-items: stretch !important;
    gap: 8px;
    width: 100%;
  }
  .list-toolbar .batch-bar > .btn,
  .list-toolbar .batch-bar > div.btn {
    flex: 1 1 0 !important;
    min-width: 0 !important;
    /* 【2026-10-13 用户反馈·移动端边框 bug】原来这里强制蓝色 ✗ → 一排里出现
       「改状态=蓝 / 删除=红 / 导入=灰 / 导出=蓝」四种边框，观感混乱 ✗。
       按全站标准统一成**灰框**（与桌面端、与「批量导入」一致 ✓）：
       只有「批量删除」保留红框（见下方单独那条 ✓）。 */
    border-color: var(--ctl-border) !important;
    height: 34px !important;
    padding: 0 4px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    text-align: center !important;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    box-sizing: border-box;
  }
  /* 「批量删除」保持红框：上面那条会把批量栏**每个**按钮的边框统一成灰色（含 btn-danger ✗），
     这里按红框令牌单独修正回来（选择器多一个类 → 优先级更高 ✓，与桌面端 .btn-danger 一致 ✓） */
  .list-toolbar .batch-bar > .btn.btn-danger { border-color: var(--danger-border) !important; }
  .list-toolbar .batch-bar div.btn select {
    width: 100%;
    height: 100% !important;
    text-align: center;
    text-align-last: center;
    /* 深色字，与桌面端一致（原来是蓝字 ✗ —— 边框改灰后蓝字更不协调 ✗） */
    color: var(--ink) !important;
    padding: 0 14px 0 3px !important;
    font-size: var(--ctl-fs) !important; /* 与同排「批量删除 / 批量导入」一致（原来是 13.5px，比它们小一号 ✗） */
    line-height: 1 !important;
    border: none !important;
    background: transparent !important;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6'><path d='M1 1.4 L5 4.8 L9 1.4' fill='none' stroke='%232563eb' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/></svg>") !important;
    background-repeat: no-repeat !important;
    background-position: right 2px center !important;
    background-size: 10px 6px !important;
    -webkit-appearance: none !important;
    -moz-appearance: none !important;
    appearance: none !important;
  }
  .list-toolbar .search-input {
    width: 100% !important;
    flex: 1 1 100% !important;
    min-width: 0 !important;      /* 解除桌面 min-width:var(--search-w) 的地板 */
    max-width: none !important;   /* 解除桌面 max-width:60vw 的天花板 */
    box-sizing: border-box !important;
  }
  .list-toolbar #statusFilter, .list-toolbar > a.btn.btn-primary{
    flex: 1 1 45% !important;
    min-width: 0 !important;
    box-sizing: border-box !important;
  }
  .list-toolbar > a.btn.btn-primary{
    justify-content: center !important;
    text-align: center !important;
  }
  /* 手机端：列表底部「取消选择 / 打印导出PDF / 开票汇总」三按钮——强制横排一行占满整行，
     压缩内边距与图标间距腾出空间，配合 nowrap 保证任何浏览器下文字都单行、不被裁 */
  .list-meta { width: 100% !important; }
  .meta-actions { width: 100% !important; flex-wrap: nowrap !important; }
  .meta-actions a.btn-export.btn-sm {
    flex: 1 1 auto !important;
    white-space: nowrap !important;
    padding: 0 6px !important;
    gap: 4px !important;
    justify-content: center !important;
  }
  .list-cards {
    display: block !important;
    flex: none !important;
    min-height: 0 !important;
    height: auto !important;
    overflow: visible !important;
    -webkit-overflow-scrolling: auto;
    padding: 10px 0 20px;
  }
  .content.list-page .list-table-card #pager { flex: none !important; margin-top: 6px; }
  .contract-card {
    background: var(--panel); border: 1px solid var(--line-table); border-radius: 12px;
    padding: 12px 14px; margin-bottom: 12px; box-shadow: 0 1px 3px rgba(15,23,42,.06);
  }
  /* 【2026-10-13 移动端一致性体检】原来写死了外来的蓝 #1a73e8（Google 蓝）✗ —— 不是本系统的
     主蓝 --brand #2563eb ⇒ 选中卡片时边框与全站其它蓝色不同色 ✗。改用令牌：边=主蓝、光环=主蓝浅底 ✓ */
  .contract-card.selected-row { border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-soft); }
  .cc-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
  .cc-check { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ink-label); cursor: pointer; }

  .cc-check input { width: 20px; height: 20px; }
  /* 需方名称：原来写死 #0f172a（另一个黑）✗ → 改用全站主文字令牌 --ink ✓ */
  .cc-buyer { font-size: 17px; font-weight: 700; color: var(--ink); line-height: 1.4; margin-bottom: 8px; word-break: break-word; }
  .cc-line { display: flex; justify-content: space-between; font-size: 14px; padding: 4px 0; border-top: 1px dashed var(--line-soft); }
  .cc-k { color: var(--ink-faint); flex-shrink: 0; }
  .cc-v { color: var(--ink-2); font-weight: 500; text-align: right; margin-left: 12px; font-family: var(--font-sans); }
  .cc-prods {
    margin-top: 8px;
    font-size: 14px;
  }
  .cc-prods .cc-k { display: block; margin-bottom: 4px; color: var(--ink-faint); }
  .cc-prod { color: var(--ink-2); font-weight: 500; padding: 2px 0; line-height: 1.5; word-break: break-word; font-family: var(--font-sans); }
  .cc-prod-empty { color: var(--ink-faint); }
  .cc-ops { display: flex; gap: 16px; margin-top: 10px; border-top: 1px solid var(--line-soft); padding-top: 10px; }
  .cc-ops .op-link { font-size: 14px; }

  .cards-filter { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; flex-wrap: wrap; }
  .cards-filter-tip { font-size: 13px; color: var(--ink-faint); }

  .cf-chip {
    display: inline-flex; align-items: center; gap: 6px;
    height: var(--ctl-h); padding: 0 12px; box-sizing: border-box;
    border: 1px solid var(--ctl-border); background: var(--panel);
    border-radius: var(--ctl-radius);
    font-size: var(--ctl-fs); font-weight: 500; line-height: 1;
    font-family: var(--font-sans); color: var(--ink);
    cursor: pointer; max-width: 100%; transition: all .15s;
  }
  .cf-chip:active { background: var(--surface-hover); border-color: #c7cfdb; }
  .cf-chip .cf-chip-k { color: var(--ink-soft); font-weight: 400; }
  .cf-chip .cf-chip-v { color: var(--brand); font-weight: 600; max-width: 96px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .cf-chip svg { width: 15px; height: 15px; color: var(--ink-faint); flex: none; }
  /* 正在筛选 → 整个框变蓝（与桌面"漏斗变蓝"同一语义，手机上看不到小图标，靠整块颜色提示） */
  .cf-chip.on { border-color: var(--brand); background: var(--brand-soft); color: var(--brand); }
  .cf-chip.on .cf-chip-k { color: var(--brand); }
  .cf-chip.on svg { color: var(--brand); }
  /* 筛选面板在手机上按手指点：输入框 30→38、按钮 28→36、字号各提一档（桌面端不受影响） */
  .col-filter-pop input { height: 38px; font-size: 15px; }
  .col-filter-pop .cf-row .cf-btn { height: 36px; font-size: 14px; }
  /* 【2026-09-23 用户要求·手机端筛选面板改成"标准弹窗" ✓ 用户原话："是不是弹窗比较好一点？ */
  .cf-modal-mask {
    position: fixed; inset: 0; z-index: 100000;
    background: var(--mask);
    display: flex; align-items: flex-start; justify-content: center;
    padding: 8vh 16px 16px;
    overflow: auto;
  }
  .col-filter-pop.cf-modal {
    position: static; width: 100%; max-width: 420px; margin: 0;
    border: 1px solid var(--line); border-radius: 12px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, .18);
  }
  .col-filter-pop.cf-modal .cf-title { font-size: 13px; margin-bottom: 8px; }
  /* ⚠ 必须带 !important：上面那条全站规则 `input[type=text]… { font-size: var(--ctl-fs) !important }`
     （15px）会压掉普通声明 ✓ 实测不写它就只剩 15px ✗；
     而 15px < 16px → iOS / 部分安卓聚焦时会把**整页放大** ✗（用户以前截图里页面被放大就是这个 ✓）。 */
  .col-filter-pop.cf-modal input { height: 40px; font-size: 16px !important; }
  .col-filter-pop.cf-modal .cf-row .cf-btn { height: 40px; font-size: 14.5px; }

  /* 【2026-09-19 用户要求·按实测建议全站修复】手机上把**所有**输入框字号提到 16px。 */
  :root { --ctl-fs: 16px; }
  /* 第 ② 步（兜底）：个别地方字号是**写死的数字**、没用变量（如 .seal-app input{13px}、 明细表 input{15px}）→ 用 !important 一起提到 16px。 */
  input, textarea, select { font-size: 16px !important; }

  /* 移动端：规格型号下拉框适配——缩小字体 + 加大每行点按区域，方便手指操作 */
  .spec-combo { font-size: 15px; }
  .spec-combo-item { padding: 13px 14px; min-height: 46px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; }

  /* 手机端合同预览：工具栏竖排（每行一个按钮，方便点击）—— 仅屏幕生效，打印时隐藏 */
  @media screen {
    .btn { padding: 11px 16px; font-size: 15px; }
    .btn.btn-sm{ padding: 9px 13px; }
    .preview-toolbar {
      display: flex !important;
      flex-direction: column !important;
      flex-wrap: nowrap !important;
      align-items: stretch !important;
      justify-content: stretch !important;
      gap: 8px !important;
    }
    .preview-toolbar .btn {
      width: 100% !important;
      justify-content: center !important;
      padding: 12px 16px !important;
      font-size: 14.5px !important;
      box-sizing: border-box !important;
    }
    /* 复制为图片按钮醒目（青绿强调 —— 用户 2026-10-13 确认保留观感 ✓）
       【体检】原来这里写死 #0fb39a ✗ → 改用已有令牌 var(--accent) ✓（同色，不改观感 ✓） */
    #btn-copy-img {
      background: var(--accent) !important;
      color: var(--panel) !important;
      border-color: var(--accent) !important;
      font-weight: 600 !important;
    }
  }
  .doc { padding: 18px; }
}

   /* 改这个断点的样式前，先把 2 处都搜出来看一遍，避免只改了一处。 ── */
@media (max-width: 480px) {
  .grid-stats { grid-template-columns: 1fr; }
  .topbar h1 { font-size: 16px; }
}

/* ===== 实物图点击放大灯箱（仅在屏幕显示，不参与打印）===== */
   /* 改这个断点的样式前，先把 1 处都搜出来看一遍，避免只改了一处。 ── */
@media screen {
  .pic-lightbox {
    position: fixed; inset: 0; z-index: 9999;
    display: none; align-items: center; justify-content: center;
    padding: 20px; box-sizing: border-box;
    background: rgba(0,0,0,0.85);
  }
  .pic-lightbox.open { display: flex; }
  .pic-lightbox img.pic-lb-img {
    max-width: 94%; max-height: 90%;
    object-fit: contain; background: var(--panel);
    box-shadow: 0 10px 50px rgba(0,0,0,0.5);
  }
  .pic-lightbox .pic-lb-tip {
    position: absolute; top: 14px; left: 0; right: 0;
    text-align: center; color: var(--panel); font-size: 13px; opacity: 0.85;
    pointer-events: none;
  }
  .pic-lightbox .pic-lb-close {
    position: absolute; top: 12px; right: 14px;
    width: 40px; height: 40px; border-radius: 50%;
    background: rgba(255,255,255,0.2); color: var(--panel); border: none;
    font-size: 20px; line-height: 1; cursor: pointer;
  }
}

.inv-mask{position:fixed;inset:0;background:rgba(15,23,42,.5);z-index:9999;display:flex}
.inv-modal{margin:24px;flex:1;min-width:0;background:var(--panel);border-radius:10px;box-shadow:0 20px 60px rgba(0,0,0,.35);display:flex;flex-direction:column;overflow:hidden;color:#1e293b;font-size:14px;line-height:1.5;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Microsoft YaHei",sans-serif;color-scheme:light}
.inv-modal *{box-sizing:border-box}
.inv-modal .inv-head{display:flex;align-items:center;gap:10px;padding:12px 18px;background:var(--panel);border-bottom:1px solid var(--line-table);flex:0 0 auto}
.inv-modal .inv-head .ttl{font-size:15px;font-weight:600;margin-right:auto}
.inv-modal .inv-head .sub{color:var(--ink-soft);font-size:12px}
.inv-modal .toolbar{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:8px;padding:8px 16px;background:var(--panel);border-bottom:1px solid var(--line-table);flex:0 0 auto}
/* 内容区铺浅灰底（与原独立页 body 底色一致），白色汇总单浮在上面有层次 */
.inv-modal .stage{flex:1;overflow:auto;padding:28px 24px;display:flex;flex-direction:column;align-items:center;gap:24px;background:var(--surface-hover)}
.inv-modal .loading{padding:60px;text-align:center;color:var(--ink-soft)}
.inv-modal .sheet{width:min(1200px,100%);background:var(--panel);padding:38px 48px;border:1px solid var(--line-table);box-shadow:0 2px 8px rgba(15,23,42,.05)}
.inv-modal .sheet h1.title{text-align:center;font-size:22px;margin:0 0 22px;letter-spacing:4px;font-weight:700}
.inv-modal .head-info{margin-bottom:16px;font-size:15px;line-height:2;letter-spacing:1px}
.inv-modal .head-info .label{font-weight:600}
.inv-modal .head-info .v{font-weight:600}
.inv-modal .sec-cap{font-weight:600;margin:16px 0 6px;font-size:14.5px}
.inv-modal .edit-tip{font-size:12px;color:var(--ink-soft);margin:2px 0 8px}
.inv-modal .edit-tip b{color:var(--brand);font-weight:600}
.inv-modal table.goods{width:100%;border-collapse:collapse;table-layout:fixed}
.inv-modal table.goods thead th{background:var(--surface-hover);color:#1e293b;font-weight:600;font-size:14px;padding:10px 8px;border:1px solid #cbd5e1;text-align:center}
.inv-modal table.goods tbody td{padding:10px 8px;border:1px solid #cbd5e1;vertical-align:middle;word-break:break-word;overflow-wrap:anywhere;text-align:center;color:#1e293b;font-weight:600}
.inv-modal table.goods td.t-name{text-align:left}
.inv-modal table.goods td.tr{text-align:right}
.inv-modal table.goods td.editable{cursor:text}@media (hover: hover) {

.inv-modal table.goods td.editable:hover{background:var(--surface-alt)}
}
.inv-modal table.goods td.editing{background:var(--brand-soft);box-shadow:inset 0 0 0 1px #93c5fd;outline:none}
.inv-modal .del-btn{font-size:12px;padding:3px 9px;border:1px solid #cbd5e1;background:var(--panel);color:var(--danger);border-radius:var(--ctl-radius);cursor:pointer}@media (hover: hover) {

.inv-modal .del-btn:hover{background:var(--danger-soft);border-color:var(--danger-border)}
}
.inv-modal .total-row td{border:1px solid #cbd5e1;padding:10px 8px;font-weight:600;background:var(--surface-alt)}
.inv-modal .total-row .amt{color:var(--brand);font-weight:700}
.inv-modal .meta-row{display:flex;justify-content:space-between;font-size:12px;color:var(--ink-soft);margin-top:14px;padding-top:8px;border-top:1px dashed var(--line-table)}
/* 平板/手机：弹窗边距与表格内边距收紧（沿用主系统 1080px 断点） */
   /* 改这个断点的样式前，先把 5 处都搜出来看一遍，避免只改了一处。 ── */
@media (max-width: 1080px) {
  .inv-modal{margin:10px}
  .inv-modal .sheet{padding:20px 14px}
  .inv-modal .stage{padding:16px 12px;gap:14px}
}
/* 打印：只打印弹窗里的汇总单（display 方案：body 直接子元素里除弹窗外全部隐藏） */
   /* 改这个断点的样式前，先把 3 处都搜出来看一遍，避免只改了一处。 ── */
@media print {

  #printHost .inv-mask{position:static;background:none;display:block}
  #printHost .inv-modal{margin:0;border-radius:0;box-shadow:none;overflow:visible;display:block;height:auto}
  #printHost .inv-modal .stage{overflow:visible;display:block;padding:0;background:none}
  #printHost .inv-modal .inv-head,#printHost .inv-modal .toolbar,#printHost .edit-tip,#printHost .del-btn{display:none !important}
  #printHost td.editing,#printHost td.editable:hover{background:transparent !important;box-shadow:none !important}
  #printHost .sheet{border:none;box-shadow:none;padding:16mm 14mm;width:auto;max-width:794px}
  #printHost .sheet + .sheet{page-break-before:always}
}

/* 视图宿主：主系统 .content 默认 padding:26px + max-width:1400px 居中，
   这里归零并放开限宽（与 catalog-frame / seal-view / price-host 同款做法） */
.content.receipt-host { padding: 0; max-width: none; }

/* 原 `html, body {...}` 收敛到视图宿主 .rc-app-wrap —— 独立页时代它给整页定基调，
   合并后若仍写 html/body 会污染主系统全部页面 */
.rc-app-wrap {
  margin: 0; padding: 0;
  font-family: var(--font-sans);
  color: var(--ink); background: var(--bg);
  font-size: var(--fs-body);
}

/* 工具栏（列表/表单/详情共用顶部条） */
.rc-toolbar {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; background: var(--panel); border-bottom: 1px solid var(--line-table);
  position: sticky; top: 0; z-index: 5;
}
.rc-toolbar h2 { margin: 0; font-size: 18px; font-weight: 600; }
.rc-toolbar .spacer { flex: 1; }
/* 【2026-09-21 第 1 批·按钮统一】============ 这里原来有一套**与全站 .btn 各写一份**的按钮定义 ✗（收款模块 2026-09-12 迁入时自带 ✓ 历史见上方注释）→ 今天用户对比后："做的合同列表按钮一样啊。 */

.rc-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 0 16px; height: var(--ctl-h); box-sizing: border-box;
  border-radius: var(--ctl-radius); border: 1px solid var(--ctl-border);
  background: var(--panel); color: var(--ink-label);
  cursor: pointer; font-size: var(--ctl-fs); font-weight: 500; font-family: inherit;
  text-decoration: none; line-height: 1;
  transition: all .15s;   /* 【本次补】与 .btn 一致 ✓ 悬停不再"硬切" ✗ */
}

@media (hover: hover) {
  .rc-btn:hover { background: var(--surface-hover); border-color: #c7cfdb; }
}
/* 主按钮：与 .btn.btn-primary 一字不差 ✓ */
.rc-btn-primary { background: var(--brand); border-color: var(--brand); color: var(--panel); font-weight: 500; border-radius: 4px; height: 34px; box-sizing: border-box; }

.btn.btn-danger, .rc-btn-danger { background: var(--panel); border-color: var(--danger-border); color: var(--danger); }
/* 带图标的按钮（详情页工具栏：返回列表 / 编辑 / 打印·PDF / 复制为图片）
   图标的尺寸与间距已统一到 style.css 的「图标按钮」规则（16px）；
   这里只给"带图标的按钮"多一点左右内边距，视觉上更舒展。 */
.rc-btn-icon { padding: 0 16px; }
/* 【2026-09-22 方案 B·第 2 组·补齐悬停 ✗→✓】母本 `.btn.btn-danger:hover`（文件靠前那处 ✓）
   与它**合成一条** ✓ —— 以后"红按钮悬停变浅红底"也只写一处 ✓，两页同时变 ✓。
   （这一步必须先做 ✓：下面要删掉母本那份影子规则 ✓，否则母本的悬停会一起丢掉 ✗。） */
/* 【2026-09-23 同上】危险按钮的悬停（浅红底 ✓）也只给有鼠标的设备 ✓ ——
   否则手机上点一下「批量删除」，红底会一直粘着不褪 ✗（同一个毛病 ✓）。 */
@media (hover: hover) {
  .btn.btn-danger:hover, .rc-btn-danger:hover { background: var(--danger-soft); }
}

.rc-form-actions { display: flex; gap: 10px; align-items: center; margin-top: 12px; }
.rc-actions-spacer { flex: 1; }

/* 内容容器 */
.rc-page { padding: 16px; }
.rc-page.hidden, .hidden { display: none !important; }

/* 列表表格 */
.rc-table { width: 100%; border-collapse: collapse; background: var(--panel); }
.rc-table th, .rc-table td {
  border: 1px solid var(--line-table); padding: 9px 12px; text-align: left; font-size: var(--fs-table);
}
.rc-table th { background: var(--surface-hover); color: var(--ink); font-weight: 600; padding: var(--th-pad); text-align: left; }

   /* 改这个断点的样式前，先把 1 处都搜出来看一遍，避免只改了一处。 ── */
@media (hover: hover) and (pointer: fine) {
  .rc-table tbody tr:hover td { background: var(--row-hover); }
}
/* 已勾选的行（JS 同步 class）：勾/取消即时变色，与悬停同一浅蓝 */
.rc-table tbody tr.rc-row-sel td { background: var(--row-hover); }
.rc-amount { font-variant-numeric: tabular-nums; }
.rc-table td.col-amt, .rc-table th.col-amt { text-align: right; }
.qtprice-app .rc-table td.price,
.qtprice-app .rc-table th[data-sort="price"] { text-align: right; }
.rc-link { color: var(--brand); cursor: pointer; text-decoration: none; margin-right: var(--op-gap); vertical-align: middle; }
.rc-link:last-child { margin-right: 0; }@media (hover: hover) {

.rc-link:hover { text-decoration: underline; }
}
/* 【2026-09-21 用户要求·"收款单据也沿用过来"】列宽拖拽手柄的样式 ✓ （观感与合同列表的 .col-resizer、强泰价格的 .resizer 一致 ✓：平时隐形… */
.rc-resizer { position: absolute; top: 0; right: -3px; width: 7px; height: 100%; cursor: col-resize; z-index: 6; }
.rc-resizer::after { content: ''; position: absolute; top: 25%; height: 50%; right: 3px; width: 2px; border-radius: 1px; background: transparent; }@media (hover: hover) {

.rc-resizer:hover::after { background: var(--brand); }
}

/* 【2026-09-20 用户要求·照抄合同列表 / 强泰价格页】整页不滚、卡内滚、表头吸顶、工具栏与页脚固定。 */
.content.receipt-host:has(.rc-list-card) {
  display: flex; flex-direction: column;
  height: calc(100vh - 61px); height: calc(100dvh - 61px);   /* topbar 60px + 1px 边框 */
  overflow: hidden; padding: 0; max-width: none;
}
.content.receipt-host:has(.rc-list-card) .rc-app-wrap { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.content.receipt-host:has(.rc-list-card) .rc-app-wrap > #app { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.rc-list-card {
  flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden;
  margin: 12px; background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius-card); box-shadow: 0 1px 3px rgba(15, 23, 42, .06);
}
.rc-list-card .rc-toolbar { flex: 0 0 auto; position: static; }   /* 固定在卡片顶部，不随内容滚走 ✓ */
.rc-list-card .rc-list-wrap {
  flex: 1; min-height: 0; overflow: auto; scrollbar-gutter: stable; overflow-anchor: none;
  padding: 0; position: relative;    /* 独立层叠上下文，配合 sticky 表头正确裁剪 */
}
.rc-list-card .rc-table thead th { border-top-width: 1px; position: sticky; top: 0; z-index: 3; backface-visibility: hidden; }   /* 表头吸顶 ✓ */
/* 【2026-09-20 用户反馈·修复】粘性表头被下面滚过来的数据行**穿透** ✗ —— 这是 Chrome/Edge 的老毛病（缩放/高分屏下尤其明显）… */
.rc-list-card .rc-table { border-collapse: separate; border-spacing: 0; }
.rc-list-card .rc-table th, .rc-list-card .rc-table td { border-width: 0 1px 1px 0; }
.rc-list-card .rc-table th:first-child, .rc-list-card .rc-table td:first-child { border-left-width: 1px; }
.rc-list-card .rc-table tbody td { position: relative; z-index: 1; background: var(--panel); }
/* 勾选态 / 悬停底色必须在上面这条**之后**重新声明，否则会被 td 的不透明底色压掉 ✗ */
.rc-list-card .rc-table tbody tr.rc-row-sel td { background: var(--row-hover); }
@media (hover: hover) and (pointer: fine) {
  .rc-list-card .rc-table tbody tr:hover td { background: var(--row-hover); }
}
/* 表头排序（与合同列表同一套观感：可点、悬停变色、箭头提示） */
.rc-list-card .rc-table th.rc-sortable { cursor: pointer; user-select: none; white-space: nowrap; }@media (hover: hover) {

.rc-list-card .rc-table th.rc-sortable:hover { background: var(--row-hover); color: var(--brand-dark); }
}
.rc-list-card .rc-table th.rc-sortable.rc-sort-active { color: var(--brand-dark); }
.rc-list-card .rc-table th .sort-arrow { margin-left: 2px; font-size: 10px; opacity: .45; }
.rc-list-card .rc-table th.rc-sort-active .sort-arrow { opacity: 1; color: var(--brand-dark); }

#rcPager { flex: 0 0 auto; padding: 0 16px; background: var(--panel); }/* 2026-09-23：原有 border-top: 0 已被文件末尾那条覆盖，删除。 */

/* 【2026-09-21 用户要求·产品价格 / 强泰价格 按收款单据来】 ============ 用户原话："你让产品价格强泰价格，这两个页面… */
.content.price-host:has(.rc-list-card),
.content.qtprice-host:has(.rc-list-card) {
  display: flex; flex-direction: column;
  height: calc(100vh - 61px); height: calc(100dvh - 61px);
  overflow: hidden; padding: 0; max-width: none;
}
.content.price-host:has(.rc-list-card) .price-app,
.content.qtprice-host:has(.rc-list-card) .qtprice-app { padding: 0; }
/* ③ 页脚外壳：与收款 #rcPager 一样只留左右 16px 缩进 ✓
      （分隔线与上下 12px 留白交给统一后的 .pager ✓ → 5 个列表页页脚高度都是 59px ✓） */
.rc-pager-box { flex: 0 0 auto; padding: 0 16px; background: var(--panel); }

/* ⑤【2026-09-21 用户要求·拆成两个独立模块】产品价格原来是**一整块** ✗ —— 用户圈图对比合同列表（**两张独立的卡**：① 工具栏卡 ② 列表卡 ✓ 中间有灰缝 ✓）后要求拆开 ✓。 */
.rc-card-toolbar { flex: 0 0 auto; }
.rc-card-body { flex: 1 1 auto; min-height: 0; }

.content:is(.price-host, .qtprice-host, .receipt-host) .rc-card-toolbar { margin-bottom: 18px; }
.content:is(.price-host, .qtprice-host, .receipt-host) .rc-card-body { margin-top: 0; }

/* 【2026-09-21 实测·桌面端补 12px】多宽度核对报出： 间距③ 工具栏卡内边距：合同 25px ✓ vs 我那三页 13px ✗（差 12px） 原因 ✓… */
/* ⚠【2026-09-21 踩坑记录】上面这条"桌面端(>1080)给工具栏卡铺 24px"的规则… */
/* 工具栏里若还有小字信息（预留，当前无人用 ✓）——保持灰字不换行 ✓ */
.rc-toolbar .rc-info { color: var(--ink-soft); font-size: var(--ctl-fs); white-space: nowrap; }
/* ⑦【2026-09-21 用户反馈·按钮要跟合同列表同款】 用户原话："还有你这个按钮也是。做的合同列表按钮一样啊。你不是用了全栈统一样式了吗？"✓ —— 说得对 ✓。 */

.list-toolbar .btn:not(.btn-primary),
.rc-detail-bar .rc-btn:not(.rc-btn-primary),
.content:is(.price-host, .qtprice-host, .receipt-host) .rc-toolbar .rc-btn:not(.rc-btn-primary) {
  height: 34px; padding: 0 12px; box-sizing: border-box;
  border: 1px solid #e2e2e2; border-radius: 4px;
  background: transparent; color: var(--ink-label);
  font-size: var(--ctl-fs); font-weight: 500;
}
/* 上面第二条加了 :not(.rc-btn-primary)：这条是"工具栏次要按钮"的灰底灰框样式，
   必须排除主按钮（＋新增产品 / ＋新建收款单据），否则会把主按钮也变成灰底蓝字。
   排除后，主按钮的常态与悬停都只由 .rc-btn-primary 那套基础规则管，一处定义。 */

@media (hover: hover) {
.list-toolbar .btn:not(.btn-primary):hover {
  background: var(--surface-hover); border-color: #ccc;
}
}
/* 工具栏"功能 / 次要"按钮与筛选下拉的**悬停**统一在这里（蓝边 + 蓝字 + 白底）。
   加新控件：只往下面选择器里加一行；主按钮的悬停不归这里（见"主按钮悬停"那条）。 */

@media (hover: hover) {
.list-toolbar .btn:not(.btn-primary):not(.btn-danger):hover,
.list-toolbar .btn.btn-import-ghost:hover,
.list-toolbar .btn.btn-import-ghost:focus-visible,
.content:is(.price-host, .qtprice-host, .receipt-host) .rc-toolbar .rc-btn:not(.rc-btn-primary):hover,
.rc-detail-bar .rc-btn:not(.rc-btn-primary):hover,

.preview-toolbar .btn:not(.btn-primary):hover,
.health-app .btn:not(.btn-primary):not(.btn-soft):not(.btn-danger):hover,
.inv-toolbar .btn.btn-ghost:hover,

.inv-mask .inv-modal .toolbar .btn:not(.btn-primary):hover,

.inv-toolbar select:hover,
.list-toolbar > select#statusFilter:hover,
.list-toolbar .batch-bar > div.btn:hover,
.content:is(.price-host, .qtprice-host, .receipt-host) .rc-toolbar select:hover,

.invoice-app #inv_batchbar .inv-batch-shell:hover {
/*  ⚠⚠ 【2026-09-22 用户截图·"上下没有线了" ✗ 我造成的 ✓ 已修】—— */
  color: var(--brand) !important;
  border-color: var(--brand) !important;

  background-color: var(--panel) !important;
}
}@media (hover: hover) {

/* 【2026-09-23 用户要求·"这两个下拉框跟全部状态那样做"✓ 真实含义 ✓】 ⚠ 先纠正我上一轮的误解 ✗：用户要的是**桌面端鼠标悬停时变蓝框蓝字** ✓ （原话"要悬浮那个… */
.form-grid .form-row-3 select:hover,
.form-grid .form-row-3 input[type="date"]:hover {
  background: var(--panel);
  border-color: var(--brand);
  color: var(--brand);
}

.list-toolbar .batch-bar > div.btn select:hover,
.invoice-app #inv_batchbar .inv-batch-shell:hover select,
.invoice-app #inv_batchbar .inv-batch-shell select:hover {
  color: var(--brand) !important;
}
}
/* 壳内元素的高度一律写 100%（跟着壳走），不要照抄 --ctl-h ——
   否则会比壳的内容区高 2px，一旦有底色就会盖住外壳的上下边框。参见"下拉统一基类"里按层级分开的那两条。 */

.content:is(.price-host, .qtprice-host, .receipt-host) .rc-card-toolbar .rc-toolbar { border-bottom: 0; }
@media (max-width: 1080px) { .rc-list-card { margin: 10px; } }
/* 【2026-09-21 承上】窄屏（≤820px）时"整页不滚、卡内滚"要放开 ✗ —— 手机上屏幕矮，固定高度反而更难用； */
@media (max-width: 1080px) {
  .content.price-host:has(.rc-list-card),
  .content.qtprice-host:has(.rc-list-card) { height: auto; overflow: visible; }

  .content.price-host:has(.rc-list-card) .price-app { padding: 8px 0 40px; }
  .content.qtprice-host:has(.rc-list-card) .qtprice-app { padding: 8px 0 40px; }
  .rc-list-card { flex: none; }
  .price-app .rc-list-wrap { display: none; }

  .content.qtprice-host .rc-list-card .rc-list-wrap { display: none; }
  .rc-pager-box { padding: 0 4px; }

  #rcPager { padding: 0 4px; }

  .content.receipt-host:has(.rc-list-card) { height: auto; overflow: visible; padding: 8px 0 0; }
  /* ↑ 追问的 8px：两个价格页是 .price-app / .qtprice-app 给的 8px 顶部留白 ✓，
     收款的宿主本来 padding:0 ✗ → 卡片会贴着内容区顶边（实测 0px ✗，比合同列表少 8px ✗）→ 补上 ✓。
     （这条只对"列表视图"生效 ✓：表单页没有 .rc-list-card ✓ 不受影响 ✓。） */
  .rc-list-card .rc-list-wrap { overflow: visible; }
  /* ② 工具栏里若还有小字 → 窄屏时**自成一行、靠右** ✓（不挤在"下拉"与"按钮"中间 ✗） */
  .rc-toolbar .rc-info { flex: 1 1 100%; order: 9; text-align: right; }

  /* 【2026-09-21 用户要求·产品价格工具栏照「合同列表」排】 ============ 用户原话："你这个应该跟合同列表来设计才对的" ✓（并红框圈出工具栏 ✗）。 */
  .price-app .rc-toolbar { display: flex; flex-wrap: wrap; gap: 8px; }
  .price-app .rc-toolbar #q { flex: 1 1 100% !important; width: 100% !important; max-width: none !important; box-sizing: border-box; }
  .price-app .rc-toolbar #cat,
  .price-app .rc-toolbar #mat,
  .price-app .rc-toolbar #btnImport,
  .price-app .rc-toolbar #btnAdd {
    flex: 1 1 45% !important; min-width: 0 !important; width: auto !important;
    height: 34px !important; box-sizing: border-box;
  }
  .price-app .rc-toolbar #btnImport {
    border: 1px solid #e2e2e2 !important; color: var(--ink) !important; background: var(--panel) !important;
  }
  .price-app .rc-toolbar #btnAdd {
    display: inline-flex !important; align-items: center !important; justify-content: center !important;
  }

  .qtprice-app .rc-toolbar #search {
    flex: 1 1 100% !important; width: 100% !important; max-width: none !important; box-sizing: border-box;
  }
  .qtprice-app .rc-toolbar #btnAdd,
  .qtprice-app .rc-toolbar #btnAdjust {
    flex: 1 1 45% !important; min-width: 0 !important; width: auto !important;
    height: 34px !important; box-sizing: border-box;
  }
  .qtprice-app .rc-toolbar #btnAdd {
    display: inline-flex !important; align-items: center !important; justify-content: center !important;
  }
  /* 【2026-09-21 用户要求·宽度逐项抄合同列表】============ 实测（窄屏同屏对比 ✓ 数字来自页面自己量的 ✓）： 合同列表：卡宽 466px、左右**外边距 8px**… */
  .content:is(.price-host, .qtprice-host, .receipt-host) .rc-list-card { margin: 0 8px; }
  /* 模块①（工具栏卡）：卡内 16px/8px = 合同列表的 .list-filter-card ✓
     → 卡内的 .rc-toolbar 自己的 padding 归零 ✓ 免得内外叠加成 10+16 = 26px ✗（那正是"上面空太多"✗） */

  .content:is(.price-host, .qtprice-host, .receipt-host) .rc-card-toolbar { padding: 16px 8px; margin-bottom: 12px; }

  /* ⚠ 这条**不能**再写 margin-bottom ✗ —— 卡缝已由上面 `.invoice-app .card + .card { margin-top:12px }`
     负责 ✓，两边都写就会**叠成 24px** ✗（尺子当场抓到：合同 12px vs 开票 24px ✗ 已去掉 ✓）。 */
  .invoice-app .card.inv-toolbar { padding: 16px 8px !important; }
  .content:is(.price-host, .qtprice-host, .receipt-host) .rc-card-toolbar .rc-toolbar { padding: 0; }
  /* 模块②（列表卡）：卡内 16px/8px = 合同列表的 .list-table-card ✓（产品卡片借此自动内缩 8px ✓） */
  .content:is(.price-host, .qtprice-host, .receipt-host) .rc-card-body { padding: 16px 8px; margin-top: 0; }
  .content:is(.price-host, .qtprice-host) .rc-card-body .cards { gap: 12px; }

  .content:is(.price-host, .qtprice-host) .rc-card-body .cards > .card { margin: 0; }
}

/* 表单 */
.rc-form-wrap { max-width: 920px; margin: 0 auto; background: var(--panel); padding: 20px; border-radius: var(--radius-card); }
.rc-form-row { display: flex; gap: 16px; margin-bottom: 14px; flex-wrap: wrap; }
.rc-field { display: flex; flex-direction: column; gap: 4px; }
.rc-field label { font-size: var(--fs-label); color: var(--ink-soft); }
/* input / select 走控件标准（34px / 15px / 圆角4 / 边框 var(--ctl-border)）。
   注意：原先只写了 input 没写 select，导致表单下拉框掉回浏览器默认样式，这里补上。 */
.rc-field input, .rc-field select {
  padding: 0 12px; height: var(--ctl-h); box-sizing: border-box;
  border: 1px solid var(--ctl-border); border-radius: var(--ctl-radius); font-size: var(--ctl-fs);
}
/* textarea 是多行控件，不套标准高度 */
.rc-field textarea {
  padding: 8px 10px; border: 1px solid var(--ctl-border); border-radius: var(--ctl-radius); font-size: var(--ctl-fs);
}
.rc-field input:focus, .rc-field select:focus, .rc-field textarea:focus { outline: none; border-color: var(--brand); }

.rc-items-table { width: 100%; border-collapse: collapse; margin: 8px 0 12px; table-layout: fixed; }
.rc-items-table th, .rc-items-table td { border: 1px solid var(--line-table); padding: 6px; }

/* 补外观：明细表里有几个 input **没写 type 属性**（商品名称/单位/备注），
   它们匹配不到全局的 input[type=text]，会露出浏览器默认外观（2px 粗边框 + 13.33px 小字）。
   这些属性必须写在本作用域里（不能加到全局规则，否则会带 width:100% 把搜索框拉长）。 */

.rc-items-table input, .rc-items-table select, .rc-items-table textarea {
  width: 100%; height: var(--ctl-h); padding: var(--ctl-pad-sm);
  border: 1px solid var(--ctl-border); border-radius: var(--ctl-radius);
  font-size: var(--ctl-fs); background: var(--panel); color: var(--ink);
  box-sizing: border-box; outline: none; font-family: inherit;
}
.rc-items-table input[data-k="unit"],
.rc-items-table input[data-k="qty"],
.rc-items-table input[data-k="price"],
.rc-items-table input[data-k="amount"] { text-align: center; }

.rc-items-table input:focus { outline: none; border-color: var(--brand); }
.rc-items-table th { background: var(--surface-alt); font-size: 13px; }
/* 「操作」列内容居中（与开票一致）；只作用于明细表，列表页那组链接不受影响。 */
.rc-items-table td.col-ops { text-align: center; }
.rc-totals { text-align: right; font-size: var(--fs-total); padding: 10px 0; }
.rc-totals b { color: var(--danger); font-size: var(--fs-amount); }

/* ============ 红框收款收据 ============ */
.receipt-doc {
  width: 794px; margin: 16px auto; background: var(--panel);
  /* 外边框去掉——只保留内部表格的红色框线；底部留出足够空间放印章 */
  border: none; padding: 14px 20px 90px; color: #c40000;
  font-family: var(--font-sans);
}
/* 卖方电子印章：以「收款人」落款为锚点绝对定位，内容高度变化时自动跟随。
   尺寸 150×150 = 与合同预览的 .seal-img 一致；放大后锚点按"章中心不动"同步让位（top/right 各 10px）。 */
.rc-seal {
  position: absolute;
  top: -80px;
  right: 105px;
  width: 150px; height: 150px;
  object-fit: contain;
  opacity: .9;
  transform: rotate(-8deg);
  pointer-events: none;          /* 不拦截点击/复制 */
  z-index: 1;                    /* 章沉底：合计行/收款人行文字浮于章上 */
}
.receipt-title {
  text-align: center; font-size: 28px; font-weight: 700; letter-spacing: 12px;
  margin: 4px 0 14px; padding-bottom: 8px; border-bottom: 2px solid #e40000;
  color: #c40000;
}
.receipt-head { display: flex; justify-content: space-between; font-size: 15px; margin-bottom: 8px; color: #c40000; align-items: baseline; }
.receipt-head .rc-line { display: inline-flex; align-items: baseline; gap: 4px; }
.receipt-head .rc-underline { min-width: 240px; border-bottom: 1px solid #e40000; display: inline-block; color: #000; padding: 0 4px; }
.receipt-head .rc-date { color: #000; }

.rc-table-red {
  width: 100%;
  border-collapse: collapse;            /* 相邻 1px 边框自动合并 → 贯穿整列的连续竖线 */
  border: 2px solid #c40000;
  color: #c40000;
  table-layout: fixed;                  /* 按 CSS 宽度严格分配列宽，不受内容挤压 */
}
/* 6 大列（含"金额"列）的固定宽度分配 —— 避免商品名称把单位/数量挤成竖排 */

.rc-table-red col-group { display: table-column-group; }
.rc-table-red th.col-name,  .rc-table-red td.col-name  { width: 168px; }   /* 商品名称 */
.rc-table-red th.col-unit, .rc-table-red td.col-unit { width: 45px; }    /* 单位 */
.rc-table-red th.col-qty,  .rc-table-red td.col-qty  { width: 45px; }    /* 数量 */
.rc-table-red th.col-price,.rc-table-red td.col-price{ width: 80px; }    /* 单价 */
.rc-table-red th.col-amt,  .rc-table-red td.col-amt  { width: 176px; }   /* "金 额"合并列（8 子格） */
.rc-table-red th.col-remark,.rc-table-red td.col-remark{ width: 120px; }  /* 备注 */
/* 所有单元格：1px 红色边框 → 形成连续红网线 */
.rc-table-red th, .rc-table-red td {
  border: 1px solid #e40000;
  padding: 4px 2px;
  text-align: center;
  vertical-align: middle;
  font-size: 13px;
  background: var(--panel);
  height: 26px;
}
/* 表头 = 红字 */
.rc-table-red th {
  color: #c40000;
  font-weight: 700;
}
/* 数据 = 黑字 */
.rc-table-red td {
  color: #000;
}
/* 商品名称 / 备注列：左对齐 + 自动换行 */
.rc-table-red .col-name {
  text-align: left;
  padding: 4px 8px;
  white-space: normal;
  word-break: break-all;
}
/* "金 额"合并单元格：横跨 8 子格 */
.rc-amount-head {
  font-size: 14px;
  letter-spacing: 6px;
  padding: 6px 0;
}
/* 8 个金额子格：固定窄列宽（数字小），数字垂直居中 */
.rc-table-red .rc-digit-head,
.rc-table-red .rc-digit-cell {
  width: 22px;
  min-width: 22px;
  padding: 0;
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  height: 22px;
  line-height: 22px;
}
.rc-table-red .rc-digit-cell {
  font-weight: 400;
}

/* 合计行：标签红，实际金额黑（严格按模板）；浮于印章之上（章 z1） */
.receipt-summary { display: flex; justify-content: space-between; align-items: baseline; margin-top: 12px; font-size: 15px; gap: 16px; position: relative; z-index: 3; }
.receipt-summary .rc-label { color: #c40000; font-weight: 700; }
.receipt-summary .rc-value { color: #000; font-weight: 700; }
.receipt-summary .rc-big-amount { color: #000; font-weight: 700; font-size: 16px; }
.receipt-foot { display: flex; justify-content: space-between; margin-top: 28px; font-size: 14px; position: relative; z-index: 3; }
.receipt-foot .rc-label { color: #c40000; font-weight: 700; }
.receipt-foot .rc-underline { min-width: 140px; border-bottom: 1px solid #e40000; display: inline-block; color: #000; padding: 0 4px; }
.receipt-foot .rc-payee-wrap { position: relative; display: inline-block; z-index: 3; }

/* 印章层级（v9 落地）：章沉底 z1，合计行/收款人行浮上 z3；
   章区域文字加 2px 四向实心白描边，把字从朱红章面上"抠"出来
   （blur 型 1px 晕会被渲染精度稀释，实测无效，必须用实心描边） */
.receipt-summary .rc-label,
.receipt-summary .rc-value,
.receipt-summary .rc-big-amount,
.receipt-foot .rc-payee-wrap,
.receipt-foot .rc-label {
  text-shadow:
    -2px -2px 0 var(--panel), 2px -2px 0 var(--panel), -2px 2px 0 var(--panel), 2px 2px 0 var(--panel),
    -2.5px 0 0 var(--panel), 2.5px 0 0 var(--panel), 0 -2.5px 0 var(--panel), 0 2.5px 0 var(--panel);
}

/* 复制为图片 loading 遮罩 */
.rc-loading {
  position: fixed; inset: 0; background: rgba(0,0,0,.35); color: var(--panel);
  display: flex; align-items: center; justify-content: center; font-size: 16px; z-index: 50;
}

/* 批量选择 + 批量栏 */

/* 点整行即可勾选该单 → 整行给"可点"的手型提示（行内链接处为链接手型，不受影响） */
.rc-table tbody tr { cursor: pointer; }

.rc-batch-bar { display: none; align-items: center; gap: 8px; width: 100%; flex-wrap: wrap; }
.rc-batch-bar.rc-batch-show { display: flex; margin-left: 0; }

/* ⚠ 取值直接照抄 .list-meta 那条（716 行）：**13px + var(--ink-soft)** ✓ —— 我上一版写成 var(--ink-faint) ✗（实测与基准差一档 ✗ 尺子当场报出来了 ✓）； 字号再补 ! */
.rc-batch-bar .rc-batch-count { font-size: 13px !important; color: var(--ink-soft); }
.rc-batch-bar .rc-batch-num { color: var(--danger); font-weight: 600; }
/* 批量行的按钮：蓝边 = 合同列表那一行（实测 基准边框 rgb(37,99,235)=--brand ✓ vs 我们灰 ✗）。
   危险按钮（批量删除）保持红边 ✓ 不动 ✓（与合同列表工具栏里的「批量删除」同款 ✓）。 */
/* ⚠ 选择器跟着"批量行搬家"一起改 ✓ —— 我上一版写的还是 `.rc-card-toolbar >` ✗，
   而那一行后来已搬进**列表卡**（.rc-card-body ✓）→ 这条规则**跟丢了** ✗
   → 实测（用户截图 ✓）：「取消选择」还是灰边 ✗。这次连同**字色**一起对齐合同 ✓（蓝边 + 蓝字 ✓）。 */

.content:is(.receipt-host, .price-host, .qtprice-host) .rc-card-body > .rc-batch-bar .rc-btn { font-size: 15px; }
/* 【2026-09-22 用户反馈·"鼠标放上去没反应" ✗→✓】 【2026-09-23 副本已删除 ✗→✓】这里原先又写了一份**一模一样的悬停规则** ✗（当年"照抄"留下的 ✓）， 取值与第 790 行那份**逐字相同** ✗。 */

/* 桌面端：它现在是卡片里独立一行 ✓ → 左右内边距跟工具栏对齐（12px 16px ✓）；
   窄屏（≤1080）卡片自己有 16px/8px 内边距 ✓ → 下面把它归零 ✓ 免得叠加 ✗。 */

.content:is(.receipt-host, .price-host, .qtprice-host) .rc-card-body > .rc-batch-bar { padding: 12px 16px 0; margin-bottom: 12px; }

.content:is(.receipt-host, .price-host, .qtprice-host) .rc-card-body > .rc-batch-bar { display: flex; }
.content:is(.receipt-host, .price-host, .qtprice-host) .rc-card-body > .rc-batch-bar.rc-batch-show { display: flex; }

.content.price-host .rc-card-body > .rc-batch-bar .rc-info {
  margin-left: auto; align-self: center;
  color: var(--ink-soft); font-size: var(--ctl-fs); white-space: nowrap;
}

/* ============ 收款印章：开单选章 + 印章管理弹窗 ============ */
.rc-seal-pick { display: flex; align-items: center; gap: 8px; }
.rc-seal-pick select {
  flex: 1; min-width: 0; max-width: 320px; height: var(--ctl-h);
  padding: 0 12px; border: 1px solid var(--ctl-border); border-radius: var(--ctl-radius);
  font-size: var(--ctl-fs); background: var(--panel); color: var(--ink);
}
.rc-seal-pick select:focus { outline: none; border-color: var(--brand); }

.rc-link-danger { color: var(--danger); }

.rc-modal-mask {
  position: fixed; inset: 0; background: var(--mask);
  display: flex; align-items: flex-start; justify-content: center;
  z-index: 60; padding: var(--modal-top) 0; overflow: auto;
}
.rc-detail-mask {
  position: fixed; inset: 0 0 0 var(--sidebar-w); z-index: 60;
  background: var(--mask); display: flex; padding: 24px; overflow-y: auto;
}
.rc-detail-modal {
  flex: 1; min-width: 0; background: var(--panel); border-radius: 12px;
  display: flex; flex-direction: column; overflow: hidden;
  box-shadow: 0 20px 60px rgba(0,0,0,.28);
}
.rc-detail-head { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 16px; border-bottom: 1px solid var(--line); flex: 0 0 auto; }
.rc-detail-head h3 { margin: 0; font-size: 15px; font-weight: 700; color: var(--ink); }
.rc-detail-x { background: none; border: none; color: var(--ink-soft); font-size: 22px; line-height: 1;
  cursor: pointer; padding: 2px 10px; border-radius: 6px; }
.rc-detail-x:hover { background: var(--surface-alt); color: var(--ink); }
/* 工具栏那一行：固定在标题栏下面（与合同预览的 .pv-bar 同一个位置 ✓） */
.rc-detail-bar { display: flex; justify-content: center; gap: 8px; padding: 8px 16px;
  border-bottom: 1px solid var(--line); background: var(--panel); flex: 0 0 auto; }
.rc-detail-body { flex: 1 1 auto; overflow: auto; background: var(--canvas); }
@media (max-width: 820px) {
  .rc-detail-mask { inset: 0; padding: 0; }
  .rc-detail-modal { border-radius: 0; }
  /* 手机上三个按钮可能放不下 → 允许整行换行；文字一律不折行 ✓
     （尺寸与字号**不再单独写**：交给上面那条统一规则管 ✓ 否则又和主系统不一样 ✗） */
  .rc-detail-bar { flex-wrap: wrap; }
  .rc-detail-bar .rc-btn { white-space: nowrap; }
}

@media (min-width: 1081px) {

  .rc-form-mask { align-items: flex-start; padding-top: var(--modal-top); padding-left: 31px; }
  /* 【2026-09-19 用户要求·与开票明细同宽】宽度 860 → **1280**（= 开票「新增/编辑」弹窗的宽度）。 */
  .rc-form-mask > .modal { max-height: calc(100vh - var(--modal-top) - 20px); }
}
.rc-modal-mask .rc-form-wrap { max-width: none; margin: 0; padding: 0; background: transparent; }
.rc-modal-mask .rc-form-row { margin-bottom: 10px; }
.rc-modal-mask .rc-form-row .rc-field { flex: 1 1 220px; min-width: 0; }
.rc-modal-mask .rc-field input, .rc-modal-mask .rc-field select { width: 100%; }
/* 【2026-09-18 用户反馈 → 最终方案】印章字段与「填票人 / 收款人」同行（各占 1/3）， 用户要求"三个一行、搞满" → 下拉框跟着列宽铺满该列，不再单独限宽。 */
.rc-modal-mask .rc-seal-pick select { max-width: none; }
.rc-modal-mask .rc-items-table { margin: 6px 0 4px; }
.rc-modal-mask .rc-form-actions { margin-top: 6px; }
.rc-modal-mask .foot .rc-totals,
.rc-modal-mask .rc-form-actions .rc-totals { padding: 0; }
.rc-form-mask .body { padding: 8px 16px; }
.rc-modal-tip { font-size: 12px; color: var(--ink-faint); }
.rc-seal-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 0; border-bottom: 1px solid var(--line-soft);
}
.rc-seal-row:last-child { border-bottom: none; }
.rc-seal-row.is-default .rc-seal-name { color: var(--brand); }
.rc-seal-thumb { width: 48px; height: 48px; object-fit: contain; flex-shrink: 0; background: var(--panel); }
.rc-seal-thumb.is-none { border: 1px dashed var(--ctl-border); border-radius: 6px; background: var(--surface-alt); }
.rc-seal-meta { flex: 1; min-width: 0; }
.rc-seal-name { font-size: 14px; color: var(--ink); word-break: break-all; }
.rc-seal-tag { display: inline-block; margin-top: 4px; font-size: 12px; color: var(--brand); }
.rc-seal-ops { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.rc-seal-ops .rc-link { font-size: 13px; white-space: nowrap; }
/* 删除时该行先变灰再消失，让用户看得见「真的删掉了」 */
.rc-seal-row { transition: opacity .18s ease, background .18s ease; }
.rc-seal-row.is-removing { opacity: .3; background: var(--surface-hover); }

/* 【2026-09-16 清理·第1批】原「安全验证弹窗」的 .rc-confirm-* 样式（11 条）已删除。 */
.pwd-err { color: var(--danger); font-size: 12.5px; min-height: 18px; margin-top: 6px; }

/* ============ 手机端图片灯箱（复制为图片后全屏预览） ============ */
.rc-img-overlay {
  position: fixed; inset: 0; z-index: 9999;
  background: rgba(0,0,0,.72);
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  padding-top: 20px; overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.rc-img-tip {
  background: var(--panel); color: #1a4a7a; padding: 12px 20px; border-radius: 10px;
  font-size: 14px; line-height: 1.6; text-align: center; margin-bottom: 14px; max-width: 88%;
}
.rc-img-tip-sub { color: #888; font-size: 12px; }
.rc-img-close {
  color: var(--panel); background: rgba(0,0,0,.5); border: none; font-size: 15px;
  padding: 8px 22px; border-radius: 20px; margin-top: 16px; cursor: pointer;
}
.rc-img-photo {
  max-width: 95%; height: auto; border-radius: 4px; box-shadow: 0 8px 40px rgba(0,0,0,.45);
  background: var(--panel); touch-action: manipulation; -webkit-user-select: none; user-select: none;
}

/* ============ 打印：只留收据 ============ */
   /* 改这个断点的样式前，先把 3 处都搜出来看一遍，避免只改了一处。 ── */
@media print {

  html, body, .content.receipt-host, .rc-app-wrap { background: var(--panel); }

  /* 打印模式沿用屏幕模式的 794px 居中容器，避免收据贴边、印章视觉飘移 */
  .receipt-doc { width: 794px; margin: 0 auto; box-shadow: none; padding: 10px 16px 90px; }
  /* 打印预览视口 ≈794px，会触发 ≤820 的 .rc-seal 缩小规则 → 这里覆盖回屏幕值，保证打印=屏幕一致 */
  .rc-seal {
    width: 150px !important;
    height: 150px !important;
    top: -80px !important;
    right: 105px !important;
    bottom: auto !important;
    left: auto !important;
    transform: rotate(-8deg) !important;
  }
  .no-print { display: none !important; }
}

/* 手机端（含微信浏览器）：表单商品表格 → 卡片式 + 收据本体自适应 + 印章缩小 */
   /* 改这个断点的样式前，先把 3 处都搜出来看一遍，避免只改了一处。 ── */
@media (max-width: 820px) {
  /* 表单容器限制宽度，大屏/平板上不会无限拉宽 */
  .rc-form-wrap { max-width: 540px; }

  /* 商品表格 → 卡片流 */
  .rc-items-table { display: block; border: none; width: 100%; counter-reset: rc-item; }
  .rc-items-table thead { display: none; }
  .rc-items-table tbody { display: block; }
  /* 每行 = 一张卡片 */
  .rc-items-table tr {
    display: block; border: 1px solid var(--line-table); border-radius: 8px;
    margin-bottom: 10px; padding: 10px 12px; background: var(--panel); position: relative;
    max-width: 520px; margin-left: auto; margin-right: auto;
    counter-increment: rc-item;
  }

  /* 商品名称：整行 + 序号标签 "商品名称 X" */

  .rc-items-table td.col-name { display: block; border: none; padding: 0 36px 8px 0; }

  .rc-items-table td.col-name::before {
    content: "商品名称 " counter(rc-item);
    display: block;
    font-size: 13px; color: var(--brand); font-weight: 700;
    line-height: 1.3;
    padding-left: 8px; border-left: 3px solid var(--brand);
    margin-bottom: 6px;
  }
  .rc-items-table td.col-name input { font-size: var(--ctl-fs); font-weight: 600; border: 1px solid var(--line-table); border-radius: var(--ctl-radius); padding: 0 12px; width: 100%; }

  /* 单位/数量/单价/金额：一行 4 个并排 */
  .rc-items-table td.col-unit,
  .rc-items-table td.col-qty,
  .rc-items-table td.col-price,
  .rc-items-table td.col-amt {
    display: inline-block; width: 23%; border: none; padding: 0; vertical-align: top; margin-right: 2.6%;
  }
  .rc-items-table td.col-amt { margin-right: 0; }
  .rc-items-table td.col-unit::before  { content: "单位"; }
  .rc-items-table td.col-qty::before   { content: "数量"; }
  .rc-items-table td.col-price::before { content: "单价"; }
  .rc-items-table td.col-amt::before   { content: "金额"; }
  .rc-items-table td.col-unit::before,
  .rc-items-table td.col-qty::before,
  .rc-items-table td.col-price::before,
  .rc-items-table td.col-amt::before {
    display: block; font-size: 11px; color: var(--ink-faint); margin-bottom: 2px;
  }
  .rc-items-table td.col-unit input,
  .rc-items-table td.col-qty input,
  .rc-items-table td.col-price input {
    width: 100%; border: 1px solid var(--line-table); border-radius: 4px; padding: 8px 4px; font-size: 14px; text-align: center;
  }
  .rc-items-table td.col-amt input {
    width: 100%; border: 1px solid var(--danger-border); border-radius: 4px; padding: 8px 4px; font-size: 14px; text-align: center; font-weight: 700; color: var(--danger); background: var(--danger-soft);
  }

  /* 备注：整行 */
  .rc-items-table td.col-remark { display: block; border: none; padding: 8px 0 0; }
  .rc-items-table td.col-remark::before { content: "备注"; display: block; font-size: 11px; color: var(--ink-faint); margin-bottom: 2px; }
  .rc-items-table td.col-remark input { width: 100%; border: 1px solid var(--line-table); border-radius: 4px; padding: 8px; font-size: 14px; }

  /* 删除按钮：右上角 */
  .rc-items-table td.col-ops { display: block; position: absolute; top: 10px; right: 10px; border: none; padding: 0; }
  .rc-items-table td.col-ops a { color: var(--danger); font-size: 12px; padding: 3px 8px; border: 1px solid var(--danger-border); border-radius: 4px; background: var(--danger-soft); text-decoration: none; }

  /* 工具栏适配 */
  .rc-toolbar { flex-wrap: wrap; gap: 6px; padding: 10px 12px; }
  .rc-toolbar h2 { font-size: 16px; }

  /* 列表页表格 → 卡片式（参考合同列表 .contract-card 风格，适配所有手机尺寸）*/
  .rc-page { padding: 10px 12px; }

  /* 工具栏：与合同列表保持一致——搜索框独占一行拉满，「新建收款单据」+「印章管理」并排等分满宽 */
  .rc-toolbar .rc-search {
    width: 100% !important;
    flex: 1 1 100% !important;
    max-width: none !important; /* 解除桌面 max-width:60vw 天花板（375px 视口下=225px，卡死搜索框占不满） */
    box-sizing: border-box !important;
  }
  .rc-toolbar #rcNew,
  .rc-toolbar #rcSealMgr {
    flex: 1 1 0 !important;
    min-width: 0 !important;
    box-sizing: border-box !important;
    justify-content: center !important;
    white-space: nowrap !important; /* 按钮文字禁止换行（防「新建收款单据」挤成三行被裁） */
  }
  /* 工具栏三控件统一高度 34px（与合同列表一致）：上下内边距归零，由 height 精确控制 */
  .rc-toolbar .rc-search,
  .rc-toolbar #rcNew,
  .rc-toolbar #rcSealMgr {
    height: 34px !important;
    box-sizing: border-box !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
  }

  .rc-toolbar .rc-search,
  .rc-toolbar #rcNew,
  .rc-toolbar #rcSealMgr {
    font-size: var(--ctl-fs) !important;
  }
  /* 隐藏桌面表头，表格变块级容器 */
  .content.receipt-host .rc-table { display: block; border: none; background: transparent; }
  .content.receipt-host .rc-table thead { display: none; }
  .content.receipt-host .rc-table tbody { display: block; }
  /* 每行 = 一张卡片 */
  .content.receipt-host .rc-table tr {
    display: block;
    background: var(--panel);
    border: 1px solid var(--line-table);
    border-radius: 12px;
    padding: 12px 14px;
    margin-bottom: 12px;
    box-shadow: 0 1px 3px rgba(15,23,42,.06);
    max-width: 520px;
    margin-left: auto;
    margin-right: auto;
  }
  .content.receipt-host .rc-table td {
    display: block;
    border: none;
    padding: 0;
    text-align: left;
    font-size: 14px;
  }

  /* 【2026-10-13 移动端一致性体检】原来写死外来蓝 #1a73e8（Google 蓝）✗ → 改用系统令牌 ✓ */
  .content.receipt-host .rc-table tbody tr.rc-row-sel {
    border-color: var(--brand);
    box-shadow: 0 0 0 2px var(--brand-soft);
  }
  .content.receipt-host .rc-table tbody tr.rc-row-sel td { background: var(--panel); }
  .content.receipt-host .rc-table tbody tr:hover td { background: var(--panel); }
  /* 复选框列（首列）：手机端内联在卡片顶部 */
  .content.receipt-host .rc-table td.rc-col-sel { display: inline-flex; align-items: center; margin: 0 8px 6px 0; padding: 0; border: none; vertical-align: middle; }

  /* 单据编号：灰色小字 */
  .content.receipt-host .rc-table td.col-no { font-size: 12px; color: var(--ink-faint); margin-bottom: 4px; }
  /* 客户名称：大字加粗 */
  .content.receipt-host .rc-table td.col-customer { font-size: 17px; font-weight: 700; color: var(--ink); line-height: 1.4; margin-bottom: 8px; word-break: break-word; }
  /* 收款日期 + 金额 一行（日期左、金额右）*/
  .content.receipt-host .rc-table td.col-date,
  .content.receipt-host .rc-table td.col-amt { display: inline-block; font-size: 14px; }
  .content.receipt-host .rc-table td.col-date { color: var(--ink-soft); }
  .content.receipt-host .rc-table td.col-amt { float: right; color: var(--danger); font-weight: 700; font-size: 18px; }
  /* 操作：底部链接 */
  .content.receipt-host .rc-table td.col-ops {
    display: flex; gap: 16px; margin-top: 10px; padding-top: 10px;
    border-top: 1px solid var(--line-soft);
  }
  .content.receipt-host .rc-table td.col-ops .rc-link { font-size: 14px; }
  /* 批量栏：手机端占满整行 */
  /* 选中状态下的批量栏：屏幕窄时允许换到第二行 */
  .rc-batch-bar.rc-batch-show { flex-wrap: wrap; margin-left: 0; }

  /* 窄屏：列表卡自带 16px/8px 内边距 ✓ → 这行只留"与表头之间的 12px" ✓（同合同 .list-meta ✓） */
  .content:is(.receipt-host, .price-host, .qtprice-host) .rc-card-body > .rc-batch-bar { padding: 0; }

  /* 印章管理弹窗：窄屏下操作按钮换到第二行，避免挤成一团 */
  .rc-seal-row { flex-wrap: wrap; }
  .rc-seal-ops { width: 100%; justify-content: flex-end; padding-left: 60px; }
  .rc-seal-pick select { max-width: none; }

  .rc-modal-mask .rc-seal-pick select { max-width: none; }

  /* 表单页整体 */
  .rc-form-wrap { padding: 14px 12px; max-width: 100%; }
  .rc-form-row { gap: 10px; margin-bottom: 10px; }

  /* 【2026-09-18 用户要求】手机端：填票人 + 收款人【同一行】（各 45%）； 收款印章（.rc-field-seal）独占整行 —— 它里面是"下拉框 + ＋新章"，压窄会挤。 */
  .rc-modal-mask .rc-form-row .rc-field { flex: 1 1 45%; }
  .rc-modal-mask .rc-form-row .rc-field.rc-field-seal { flex: 1 1 100%; }

  /* 填票人 + 收款人：手机端保持并排一行（不换行） */
  .rc-form-row .rc-field { flex: 1 1 45%; min-width: 0; }

  /* 收据本体（详情/打印页） */
  .receipt-doc { width: 100%; padding: 10px 12px 70px; margin: 10px auto; }
  .rc-seal { width: 104px; height: 104px; right: -12px; bottom: -25px; }
}

/* 劲羽开票 · 视图样式（2026-09-14 新增） 迁移检查清单（沿用 qtprice.css 的踩坑总结）… */

.content.invoice-host { padding: 0; max-width: none; }
.invoice-app {
  height: calc(100vh - 61px); height: calc(100dvh - 61px); display: flex; flex-direction: column;
  /* 页面底色/边距照合同列表 .content.list-page：8px 浅灰(--bg)外框 + 白色卡片。
     此前写成 --panel(纯白) 且无卡片 → 整页全白，灰/白层次全丢。 */
  padding: 8px; overflow: hidden; color: var(--ink);
  font-family: var(--font-sans); font-size: var(--fs-body); line-height: 1.5;
  background: var(--bg); color-scheme: light;
}
:where(.invoice-app *) { box-sizing: border-box; margin: 0; padding: 0; }

/* 白卡片：直接复用主系统 .card 的底色/边框/圆角/阴影（合同列表就是 .card），
   内边距收到 12px（= .content.list-page .card 的值）；
   两张卡片之间的 18px 间距来自 style.css 的 .card + .card，不用另写 */
.invoice-app .card { padding: 12px; }

.invoice-app .card:has(.pager) { padding-bottom: 0; }
/* 【2026-09-21 用户要求·"要，改成完全一样"】劲羽开票也对齐收款单据 ✓（与合同列表同一处理 ✓）： ① 卡片外灰边 8px → 12px ✓（本节原来的注释写"照合同列表… */
@media (min-width: 1081px) {
  .invoice-app { padding: 12px; }
  .invoice-app .card.inv-table-card { padding: 0; }
  .invoice-app .card.inv-table-card .list-meta { padding: 12px 16px 0; }
  /* ⚠️ 这里必须用 **margin**（外边距）而不是 padding ✗ —— 实测教训： 开票的页脚元素**本身就是**那层 .pager（id=#inv_pager，见 util.js 的说明… */
  .invoice-app .card.inv-table-card #inv_pager { margin-left: 16px; margin-right: 16px; }
}

/* 公共样式还原 */
.invoice-app .btn { padding: 0 16px; }

.invoice-app .btn-primary, .price-app .btn-primary, .qtprice-app .btn-primary { background: var(--brand); color: var(--panel); border-color: var(--brand); }

/* 主按钮（.btn-primary / .rc-btn-primary，含三个视图作用域）的**悬停**统一在这里：底色与边框一起变深蓝。
   同名但独立、未纳入的：.btn-export-primary（打印导出）/ .seal-app .btn.pri（印章页）/ .pwd-ok（密码弹窗）。 */

@media (hover: hover) {
.btn-primary:hover,
.btn.btn-primary:hover,
.rc-btn-primary:hover,
.invoice-app .btn-primary:hover,
.price-app .btn-primary:hover,
.qtprice-app .btn-primary:hover { background: var(--brand-dark); border-color: var(--brand-dark); }
}   /* ← 结束「主按钮悬停只给有鼠标的设备」那个 @media (hover: hover)（2026-09-23 ✓） */

/* 【2026-09-20 全站统一】.btn-ghost 定为**全站唯一外观**：白底 + 边框 + 灰字。 */
.btn.btn-ghost {
  background: var(--panel); color: var(--ink-label); border-color: var(--ctl-border);
}

.btn.btn-lite {
  height: 34px; padding: 0 12px; box-sizing: border-box;
  border: 1px solid #e2e2e2; border-radius: 4px;
  background: transparent; color: var(--ink-label);
  font-size: var(--ctl-fs); font-weight: 500;
}
@media (hover: hover) {
  .btn.btn-lite:hover {
    background-color: var(--panel);
    border-color: var(--brand);
    color: var(--brand);
  }
}

.invoice-app .field { margin-bottom: 12px; }
.invoice-app .muted { color: var(--ink-faint); }

/* 工具栏：作为一张白卡片(.card inv-toolbar)的内容，下间距交给 .card + .card 的 18px */
.inv-toolbar { flex: 0 0 auto; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* 搜索框用全站统一类 .search-input（style.css:309 已定义边框/圆角/高度/宽度），
   这里只处理对齐，避免出现"浏览器默认输入框"的观感 */
.inv-toolbar .search-input { flex: 0 0 auto; }
.invoice-app select { width: auto; }
.inv-toolbar select#inv_statusFilter { height: var(--ctl-h); padding: 0 12px; border: 1px solid var(--ctl-border); border-radius: var(--ctl-radius); background: var(--panel); color: var(--ink); font-size: var(--ctl-fs); outline: none; }

/* 「列设置」下拉面板：勾选要显示的表头列 */
.inv-colset-wrap { position: relative; display: inline-flex; }
.inv-colset {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 45;
  width: 330px; max-height: 62vh; overflow: auto;
  background: var(--panel); border: 1px solid var(--line-table); border-radius: var(--radius-card);
  box-shadow: 0 10px 26px rgba(15, 23, 42, .16); padding: 10px 12px;
}
.inv-colset-hd { font-size: 12.5px; color: var(--ink-soft); margin-bottom: 8px; }
.inv-colset-list { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 12px; }
.inv-colset-item { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ink); cursor: pointer; user-select: none; }
.inv-colset-item input { width: var(--ck-size); height: var(--ck-size); margin: 0; cursor: pointer; flex: 0 0 auto; }
.inv-colset-item span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inv-colset-ft { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line-soft); font-size: 13px; }

/* 批量操作行：与合同列表 .list-meta 保持一致 —— 全部为白底描边按钮，只有「批量删除」用红字（btn-danger）； 状态下拉照抄合同列表「批量改状态」：灰框 + 深色字（此前写成了蓝框蓝字，观感不对）。 */
/* 「批量改状态」= 按钮壳 + 内部 select（照合同列表母本 style.css .list-toolbar .batch-bar > div.btn 的观感：
   灰框、与相邻按钮等高、内部 select 透明无边框）。
   母本那条规则的作用域是 .list-toolbar .batch-bar，不覆盖本模块的 .list-meta，所以这里补同样的一份。 */
#inv_batchbar .inv-batch-shell {
  display: inline-flex; align-items: center; height: 34px; box-sizing: border-box;
  background: var(--panel); border: 1px solid var(--ctl-border); border-radius: var(--ctl-radius);
}

#inv_batchbar .inv-batch-shell .inv-batch-status {
  height: 100%; padding: 0 28px 0 12px; border: none; background: transparent;
  color: var(--ink); font-size: var(--ctl-fs); outline: none; font-family: inherit; cursor: pointer;
}

/* 批量操作行：白卡片内部第一行（= 合同列表 .card > .list-meta）。
   卡片本身已是白底，这里不再自己铺白/画分割线；行间距用 .list-meta 自带的 margin-bottom:12px */
#inv_batchbar { flex: 0 0 auto; }

/* 表格-card：白卡来自 .card；卡内三块 = 批量行 + 表体滚动层 + 分页，都是 flex 子项。
   表体单独一层滚动 → 横向滚动条只作用在表格上、表头 sticky 正确吸附 */
.inv-table-card { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; position: relative; }
.inv-table-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; scrollbar-gutter: stable; }
.inv-table-card table { width: 100%; min-width: 2570px; border-collapse: separate; border-spacing: 0; table-layout: fixed; font-size: var(--fs-table); }
.inv-table-card thead th { position: sticky; top: 0; z-index: 3; background: var(--surface-hover); color: var(--ink); text-align: left; font-weight: 600; font-size: var(--fs-table); padding: var(--th-pad); border-right: 1px solid var(--line-table); border-bottom: 1px solid var(--line-table); border-top: 1px solid var(--line-table); white-space: nowrap; }

.inv-table-card thead th:first-child,
.inv-table-card tbody td:first-child { border-left: 1px solid var(--line-table); }
.inv-table-card thead th.num { text-align: right; }
.inv-table-card tbody td { padding: 9px 12px; border-right: 1px solid var(--line-table); border-bottom: 1px solid var(--line-table); vertical-align: middle; color: var(--ink); word-break: break-word; overflow-wrap: anywhere; background: var(--panel); line-height: 1.6; }
.inv-table-card tbody td.num { text-align: right; font-variant-numeric: tabular-nums; }
.inv-table-card tbody td.nm { font-weight: 500; }

@media (hover: hover) {

.inv-table-card tbody tr:hover td { background: var(--row-hover); }
}
/* 点整行即可勾选该行 → 整行给"可点"的手型提示（行内已无操作链接，整行都可点） */
.inv-table-card tbody tr { cursor: pointer; }
/* 同一张票的多行一起高亮（由 JS 按 data-id 加 .inv-tr-hl；多明细时整张票一起变色） */
.inv-table-card tbody tr.inv-tr-hl td { background: var(--row-hover); }

/* 明细子表（新增/编辑弹窗里，一张票可加多条明细） 【2026-09-15】加完整网格线：原来 th/td 只有下边线，看起来"没有边框"； 现在单元格四边都有线，与列表页表格同款观感。 */

.inv-items { border: none; border-radius: 0; overflow: hidden; margin-bottom: 12px; }
.inv-items-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.inv-items-table th { background: var(--surface-hover); font-size: 12.5px; font-weight: 600; color: var(--ink); padding: 7px 8px; border: 1px solid var(--line-table); text-align: left; white-space: nowrap; }
.inv-items-table td { padding: 5px 6px; border: 1px solid var(--line-table); vertical-align: middle; }

.health-app { max-width: 1080px; }
.health-head { border-radius: var(--ctl-radius); padding: 16px 18px; margin-bottom: 14px; border: 1px solid var(--ctl-border); background: var(--panel); }
.health-head.is-ok { border-color: #b7ebc6; background: #f2fdf5; }
.health-head.is-warn { border-color: #ffe0a3; background: #fffaf0; }
.health-head.is-bad { border-color: #f5b5b5; background: #fff5f5; }
.health-verdict { font-size: 17px; font-weight: 700; color: var(--ink); }
.health-time { margin-top: 4px; font-size: 12.5px; color: var(--ink-soft); }
.health-actions { margin-top: 12px; display: flex; gap: 8px; flex-wrap: wrap; }
.health-list { margin: 10px 0 0; padding-left: 20px; font-size: 13.5px; line-height: 1.9; }
.health-list.bad li { color: var(--danger); }
.health-list.warn li { color: #b26a00; }
.health-card { margin-bottom: 12px; padding: 14px 16px; }
.health-card-hd { display: flex; align-items: baseline; gap: 10px; padding-bottom: 8px; border-bottom: 1px solid var(--line); margin-bottom: 6px; }
.health-note { font-size: 12.5px; color: var(--ink-soft); }
.health-row { display: flex; gap: 12px; padding: 6px 0; border-bottom: 1px dashed var(--line); font-size: 13.5px; }
.health-row:last-child { border-bottom: none; }
.health-k { flex: 0 0 150px; color: var(--ink-soft); }
.health-v { flex: 1 1 auto; color: var(--ink); word-break: break-all; }
.health-sub { color: var(--ink-soft); font-size: 12.5px; }
.health-tag { display: inline-block; padding: 1px 8px; border-radius: 10px; font-size: 12.5px; font-weight: 600; }
.health-tag.ok { background: #e8f8ec; color: #1a7f37; }
.health-tag.warn { background: #fff4e0; color: #b26a00; }
.health-tag.bad { background: #ffecec; color: #c0392b; }
.health-pre { margin: 4px 0 0; padding: 10px 12px; background: var(--surface-alt, #f7f8fa); border: 1px solid var(--line); border-radius: var(--ctl-radius); font-size: 12.5px; line-height: 1.7; white-space: pre-wrap; word-break: break-all; max-height: 220px; overflow: auto; }
.health-empty { padding: 6px 0; color: var(--ink-soft); font-size: 13px; }
.health-app code { font-family: Consolas, Monaco, monospace; font-size: 12.5px; background: var(--surface-alt, #f7f8fa); padding: 1px 5px; border-radius: 3px; }

/* 【2026-10-22 新增】系统体检 ⑧ 登录与设备：在线设备 / 登录记录 */
.sess-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin: 2px 0 10px; font-size: 13.5px; }
.sess-table { border: 1px solid var(--line); border-radius: var(--ctl-radius); overflow: hidden; }
.sess-tr { display: flex; gap: 10px; padding: 8px 10px; font-size: 13px; border-bottom: 1px solid var(--line); align-items: center; }
.sess-tr:last-child { border-bottom: none; }
.sess-tr.hd { background: var(--surface-alt, #f7f8fa); color: var(--ink-soft); font-size: 12.5px; }
.sess-tr.sess-off { opacity: .62; }
.sess-td { min-width: 0; word-break: break-all; }
.sess-td.w-ua { flex: 1 1 130px; }
.sess-td.w-ip { flex: 0 0 140px; }
.sess-td.w-time { flex: 0 0 112px; }
.sess-td.w-op { flex: 0 0 82px; text-align: right; }
.sess-td a { color: var(--brand); text-decoration: none; }
.sess-td a:hover { text-decoration: underline; }
.sess-me { margin-left: 5px; font-size: 11.5px; color: var(--brand); border: 1px solid currentColor; border-radius: 8px; padding: 0 5px; }
.sess-more { margin-top: 10px; }
.sess-more > summary { cursor: pointer; font-size: 13px; color: var(--ink-soft); padding: 2px 0; }
.sess-more[open] > summary { margin-bottom: 8px; }
@media (max-width: 720px) {
  .sess-tr { flex-wrap: wrap; }
  .sess-tr.hd { display: none; }
  .sess-td.w-ip, .sess-td.w-time { flex: 1 1 40%; }
  .sess-td.w-op { flex: 1 1 100%; text-align: left; }
}

.health-detail { margin-top: 10px; border-top: 1px solid var(--line); padding-top: 10px; }
.health-detail-hd { font-size: 12.5px; color: var(--ink-soft); margin-bottom: 6px; }
.health-detail-row { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px; padding: 4px 0; font-size: 12.5px; border-bottom: 1px dashed var(--line); }
.health-detail-row:last-child { border-bottom: none; }
.health-arrow { color: var(--ink-soft); }
.health-used { display: inline-block; padding: 1px 7px; margin-right: 4px; border-radius: 10px; background: var(--surface-hover); color: var(--ink); }

/* 同收款明细表：项目名称/规格型号/单位这几个 input 也没写 type，补上完整外观 */

.inv-items-table input, .inv-items-table select, .inv-items-table textarea {
  width: 100%; height: var(--ctl-h); padding: var(--ctl-pad-sm);
  border: 1px solid var(--ctl-border); border-radius: var(--ctl-radius);
  font-size: var(--ctl-fs); background: var(--panel); color: var(--ink);
  box-sizing: border-box; outline: none; font-family: inherit;
}
.inv-items-table input:focus { border-color: var(--brand); }
.inv-item-del { text-align: center; }
.inv-items-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 10px; background: var(--surface-alt); flex-wrap: wrap; border-left: 1px solid var(--line-table); border-right: 1px solid var(--line-table); border-bottom: 1px solid var(--line-table); }
.inv-items-total { font-size: 13px; color: var(--ink-soft); }
.inv-items-total b { color: var(--brand); font-size: 15px; }

/* 分页 */
.invoice-app .pager { flex: 0 0 auto; display: flex; align-items: center; gap: 10px; margin-top: 14px; color: var(--ink-soft); font-size: var(--ctl-fs); flex-wrap: wrap; }
.invoice-app .pager b { color: var(--ink); font-weight: 500; }
.inv-pager-total { flex: 1 1 auto; text-align: center; color: var(--ink-soft); font-size: var(--ctl-fs); }
.inv-pager-total b { color: var(--ink); font-weight: 600; }

/* 弹窗位置：全站统一走 --modal-top（见 :root）—— 略偏上而非几何正中。
   遮罩用 overflow:auto：弹窗比视口高时可以直接滚，不会出现"顶部被切掉、滚不上去"。 */
.invoice-app .mask { position: fixed; inset: 0; background: var(--mask); display: none; justify-content: center; overflow: auto; padding: var(--modal-top) 0; z-index: 50; }
/* ⑦ 必须补 .mask.show，否则被本文件的 .mask{display:none} 压死 */
.invoice-app .mask.show { display: flex; }
.invoice-app .modal { background: var(--panel); border-radius: var(--radius-modal); width: 480px; max-width: 94vw; box-shadow: 0 12px 40px rgba(0, 0, 0, .2); overflow: hidden; }
/* 新增/编辑开票弹窗：字段多（17 列 + 多条明细），加宽到 1280px
   （max-width:94vw 在 .modal 上，小屏自动收窄不溢出）；
   表单改 3 列 + 主体加高到 84vh —— 目标是整屏放下、不出现右侧竖向滚动条 */
.invoice-app .modal.inv-modal-wide { width: 1280px; }
/* 【2026-09-19 用户要求·与收款单据统一】开票「新增/编辑」弹窗（#maskEdit）桌面端位置… */
@media (min-width: 1081px) {
  .invoice-app #maskEdit { align-items: flex-start; padding-top: var(--modal-top); padding-left: 15px; }

  .invoice-app #maskEdit .modal.inv-modal-wide { max-height: calc(100vh - var(--modal-top) - 20px); }
  .invoice-app #maskEdit .modal.inv-modal-wide .body { max-height: none; flex: 1 1 auto; min-height: 0; overflow: auto; }
}
.invoice-app .modal.inv-modal-wide .body { max-height: 84vh; }
/* 宽弹窗里表单 4 列（购买方 7 个字段 → 2 行、发票信息 5 个 → 2 行），
   并整体收紧间距：目标是整屏放下、右侧不出现竖向滚动条 */
.inv-modal-wide .inv-grid { grid-template-columns: repeat(4, 1fr); }
.inv-modal-wide .inv-grid-5 { grid-template-columns: repeat(5, 1fr); }   /* 发票信息一组 5 项 → 一行 */
.inv-modal-wide .field { margin-bottom: 6px; }
.inv-modal-wide .inv-group { margin: 6px 0 3px; }
.inv-modal-wide .body { padding: 10px 16px; max-height: 84vh; }
.inv-modal-wide .inv-items { margin-bottom: 4px; }
/* 【2026-09-19 用户要求·与收款单据统一】开票明细区上下留白原来比收款紧一档 （表头 5px 8px、单元格只有 2px 6px ✗）→ 用户直观看两个弹窗"上下边距不一样" ✗，要求跟收款一致。 */
.inv-modal-wide .inv-items-table th { padding: 6px; font-size: 13px; background: var(--surface-alt); text-align: center; }
.inv-modal-wide .inv-items-table td { padding: 6px; }

.inv-modal-wide .inv-items-foot { padding: 5px 10px; }
.inv-modal-wide .err { min-height: 14px; margin-top: 4px; }
.inv-modal-wide h3 { padding: 12px 18px; }
.inv-modal-wide .foot { padding: 10px 18px; }
/* 标题栏 / 内容区 / 底部栏 与收款单据逐项对齐（标题 16px、内边距 14×16 / 8×16 / 12×16，分隔线 --line-table） */
/* 标题/页脚对齐公共标准（.mask > .modal）：字号 15px、内边距 18px、分隔线 --line-soft。
   .body 的内边距不动 —— 它同时管着 1280px 的开票大表单，改大会撑高、挤出席竖向滚动条。 */
.invoice-app .modal h3 { margin: 0; padding: 14px 18px; font-size: 15px; font-weight: 600; line-height: 1.5; border-bottom: 1px solid var(--line-soft); }
.invoice-app .modal .body { padding: 8px 16px; max-height: 72vh; overflow: auto; }
.invoice-app .modal .foot { padding: 12px 18px; border-top: 1px solid var(--line-soft); display: flex; gap: 10px; justify-content: flex-end; }
.invoice-app .err { color: var(--danger); font-size: 12.5px; min-height: 18px; margin-top: 8px; }

/* 表单栅格 */
.inv-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 16px; }
.inv-group { margin: 14px 0 8px; font-size: 13px; font-weight: 600; color: var(--brand); border-left: 3px solid var(--brand); padding-left: 8px; }
.inv-group:first-child { margin-top: 0; }

.invoice-app .field label { display: block; font-size: 14px; font-weight: 400; color: var(--ink-soft); margin-bottom: 0; }
.invoice-app .field input, .invoice-app .field select, .invoice-app .field textarea {
  width: 100%; font-size: var(--ctl-fs); padding: 8px 10px; border: 1px solid var(--ctl-border);
  border-radius: var(--ctl-radius); background: var(--panel); color: var(--ink); outline: none; font-family: inherit;
}
/* 输入框/下拉框统一高度 = 全站控件标准 --ctl-h(34px)。
   之前弹窗里是 39px、明细表被我压到 24px → 一页里三种高度，观感不一致。
   textarea 不设高度（保持多行自适应）。 */
.invoice-app .field input, .invoice-app .field select { height: var(--ctl-h); box-sizing: border-box; padding: 0 12px; }
.invoice-app .field input:focus, .invoice-app .field select:focus, .invoice-app .field textarea:focus { border-color: var(--brand); }
.invoice-app .field textarea { resize: vertical; }

/* 抬头库输入行 */
.inv-party-row { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 16px; align-items: start; margin-bottom: 6px; }
.inv-party-row > .btn { justify-self: start; }
.inv-party-input-wrap { position: relative; flex: 1 1 auto; }
.inv-party-input-wrap input { width: 100%; height: var(--ctl-h); box-sizing: border-box; padding: 0 12px; font-size: var(--ctl-fs); border: 1px solid var(--ctl-border); border-radius: var(--ctl-radius); outline: none; font-family: inherit; }
.inv-party-input-wrap input:focus { border-color: var(--brand); }
.inv-party-drop { position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 60; background: var(--panel); border: 1px solid var(--line-table); border-radius: var(--ctl-radius); box-shadow: 0 10px 26px rgba(15, 23, 42, .16); max-height: 260px; overflow: auto; }
.inv-drop-item { padding: 8px 12px; cursor: pointer; border-bottom: 1px solid var(--line-soft); }
.inv-drop-item:last-child { border-bottom: none; }@media (hover: hover) {

.inv-drop-item:hover { background: var(--surface-hover); }
}
.inv-drop-item .it-name { font-size: 13.5px; color: var(--ink); }
.inv-drop-item .it-sub { font-size: 12px; color: var(--ink-faint); margin-top: 2px; }
.inv-drop-empty { padding: 10px 12px; font-size: 12.5px; color: var(--ink-faint); }

/* 提示 / 导入结果 / 统计表 */
.inv-hint { font-size: 12.5px; color: var(--ink-soft); line-height: 1.7; margin-bottom: 10px; }
.invoice-app textarea { width: 100%; font-size: var(--ctl-fs); padding: 9px 10px; border: 1px solid var(--ctl-border); border-radius: var(--ctl-radius); font-family: inherit; resize: vertical; outline: none; }
.invoice-app textarea:focus { border-color: var(--brand); }
.inv-import-result { margin-top: 10px; font-size: 13px; color: var(--ink); min-height: 18px; }
.inv-stat-cards { display: flex; gap: 14px; margin-bottom: 14px; }
.inv-stat { flex: 1 1 0; border: 1px solid var(--line-table); border-radius: var(--radius-card); padding: 14px 16px; background: var(--surface-alt); }
.inv-stat .lb { font-size: 12.5px; color: var(--ink-soft); }
.inv-stat .vl { font-size: 22px; font-weight: 600; color: var(--ink); margin-top: 4px; }
.inv-modal-wide h4 { margin: 14px 0 8px; font-size: 13.5px; color: var(--ink); }
.inv-mini { width: 100%; border-collapse: collapse; font-size: 13px; }
.inv-mini th, .inv-mini td { border: 1px solid var(--line-table); padding: 6px 10px; text-align: left; }
.inv-mini th { background: var(--surface-hover); font-weight: 600; }
.inv-mini td.muted { color: var(--ink-faint); }

.invoice-app .mask.mask-top { z-index: 70; }   /* 抬头编辑弹窗要盖在抬头列表弹窗之上 */
.invp-bar { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
.invp-bar .search-input { flex: 1 1 auto; min-width: 240px; }
.invp-count { font-size: 12.5px; color: var(--ink-faint); white-space: nowrap; }
.invp-batch { position: sticky; top: 0; z-index: 2; display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: var(--panel); border-bottom: 1px solid var(--line-soft); flex-wrap: wrap; }
.invp-selall { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ink-soft); cursor: pointer; user-select: none; white-space: nowrap; }
.invp-selall input { width: 15px; height: 15px; cursor: pointer; }
.invp-selinfo { font-size: 12.5px; color: var(--ink-faint); white-space: nowrap; }
.invp-spacer { flex: 1 1 auto; }
.invp-chk { flex: 0 0 auto; display: flex; align-items: flex-start; padding-top: 3px; }
.invp-chk input { width: var(--ck-size); height: var(--ck-size); cursor: pointer; }
.invp-list { border: 1px solid var(--line-table); border-radius: var(--radius-card); max-height: 58vh; overflow: auto; }
.invp-item { display: flex; align-items: flex-start; gap: 12px; padding: 10px 12px; border-bottom: 1px solid var(--line-soft); }
.invp-item:last-child { border-bottom: none; }@media (hover: hover) {

.invp-item:hover { background: var(--surface-hover); }
}
.invp-item.is-dup { background: #fffbf2; }
.invp-item.is-sel { background: var(--row-hover); }
.invp-main { flex: 1 1 auto; min-width: 0; }
.invp-name { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13.5px; font-weight: 500; color: var(--ink); }
.invp-sub { margin-top: 3px; font-size: 12.5px; color: var(--ink-faint); word-break: break-all; }
.invp-dup { padding: 1px 8px; border-radius: 999px; font-size: 11.5px; font-weight: 400; background: #fff5e6; color: #b7791f; border: 1px solid #f0d9a8; }
.invp-ops { flex: 0 0 auto; display: flex; gap: 8px; }
/* 中等宽度弹窗（粘贴识别抬头 / 抬头编辑共用）。
   【注意】必须写全 .invoice-app .modal 前缀：基础规则是 .invoice-app .modal{width:480px}
   （2 个类），只写 .inv-modal-md（1 个类）会被它压掉 → 宽度不生效（已踩过一次）。 */
.invoice-app .modal.inv-modal-md { width: 720px; }
/* 文件选择框：不要套用 .field input 的 34px 高度/0 padding（原生 file 控件会被压变形） */
.invoice-app .field input[type=file] { width: auto; height: auto; padding: 0; }


/* 【2026-10-08】文件选择：原生 <input type=file> 的按钮由操作系统画死、全站每个浏览器长得都不一样，
   这里把它藏起来，改用统一的 .btn 按钮 + 文件名文本（导入 / 导入模板等处共用这套） */
.file-pick{display:flex;align-items:center;gap:10px;min-height:var(--ctl-h)}
.file-pick-input{position:absolute;width:1px;height:1px;padding:0;margin:0;opacity:0;pointer-events:none}
.file-pick-btn{flex:none}
.file-pick-name{font-size:var(--ctl-fs);color:var(--ink-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.file-pick-name.has{color:var(--ink)}

/* 手机端：栅格改单列，工具栏搜索独占一行 */
   /* 改这个断点的样式前，先把 3 处都搜出来看一遍，避免只改了一处。 ── */
@media (max-width: 820px) {
  .invoice-app { height: auto; overflow: visible; padding: 8px 8px 40px; }

  .inv-toolbar { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
  .inv-toolbar .search-input { grid-column: 1 / -1; width: 100% !important; min-width: 0 !important; max-width: none !important; }
  .inv-toolbar #inv_statusFilter { grid-column: 1 / -1; width: 100%; }
  .inv-toolbar .btn { width: 100%; justify-content: center; }
  .inv-toolbar .inv-colset-wrap { width: 100%; }

  .invoice-app .card.inv-toolbar { position: relative; overflow: visible; }
  /* ⚠ 关键一条 ✗→✓（第一版我漏了它 ✗ 探针当场量出"面板只有 54px"✗）… */
  .inv-toolbar .inv-colset-wrap { position: static; }
  .inv-toolbar .inv-colset {
    position: absolute; left: 8px; right: 8px; width: auto;
    top: calc(100% + 8px); margin-top: 0; max-height: 50vh; z-index: 999;
  }
  .inv-grid { grid-template-columns: 1fr; }
  .inv-party-row { grid-template-columns: 1fr; }
  .inv-party-row > .btn { justify-self: start; }
  .inv-stat-cards { flex-wrap: wrap; }
}

   /* 改这个断点的样式前，先把 5 处都搜出来看一遍，避免只改了一处。 ── */
@media (max-width: 1080px) {
  .invoice-app #inv_batchbar { align-items: flex-start; }
  .invoice-app #inv_batchbar .meta-left { width: 100%; flex-direction: column; align-items: flex-start; gap: 8px; }
  .invoice-app #inv_batchbar .meta-actions { width: 100%; flex-wrap: wrap !important; gap: 8px; }
  .invoice-app #inv_batchbar .meta-actions .btn,
  .invoice-app #inv_batchbar .inv-batch-shell { flex: 0 0 auto !important; white-space: nowrap; }
}

/* 产品价格 · 视图样式（2026-09-12 由 /price/index.html 独立页迁入主系统） 移植原则：原 <style> 逐条 1:1 移植，全部收敛在 .price-app 作用域下… */

.content.price-host{padding:0;max-width:none}

.price-app{height:calc(100vh - 61px);height:calc(100dvh - 61px);display:flex;flex-direction:column;padding:16px 20px;overflow:hidden;color:var(--ink);font-family:var(--font-sans);font-size:var(--fs-body);line-height:1.5;background:var(--bg);color-scheme:light}
/* 【2026-09-12 迁移修复】重置必须用 :where() 包成"零优先级"。 原因：原独立页里这条是裸 `*{margin:0;padding:0}`（优先级 0）； */
:where(.price-app *){box-sizing:border-box;margin:0;padding:0}

.price-app .btn{padding:0 16px}

.price-app .field{margin-bottom:12px}
.price-app .card{margin:0}                                       /* 主系统 .card 带 margin-bottom:18px，会撑开手机端卡片 */

/* 标题行 */
.price-app h1{margin:0;font-size:20px;font-weight:650;color:var(--ink);letter-spacing:0;display:inline-block;min-height:30px}
.price-app h1 .ver{font-size:20px;font-weight:650;color:var(--ink);letter-spacing:0}
.price-app .sub{font-size:12px;color:var(--ink-faint);margin-top:2px}

/* 工具栏 + 输入控件（原页是元素级选择器，必须加作用域） */
.price-app .toolbar{flex:0 0 auto;display:flex;align-items:center;gap:10px;margin-top:14px;margin-bottom:14px;flex-wrap:wrap;justify-content:flex-start}
.price-app input,.price-app select{font-size:var(--ctl-fs);height:var(--ctl-h);padding:0 12px;box-sizing:border-box;border:1px solid var(--ctl-border);border-radius:var(--ctl-radius);background:var(--panel);color:var(--ink);outline:none;font-family:inherit}
.price-app input:focus,.price-app select:focus{outline:none;border-color:var(--brand)}

/* 【2026-09-12 迁移修复】搜索框聚焦必须单独写 #q:focus： #q 规则是 ID 级优先级(1,1,0)，会压死低一级的 input:focus(0,2,1)， 导致"点搜索框边框不变色"。 */
.price-app #q:focus{outline:none;border-color:var(--brand)}
.price-app .spacer{flex:1}

.price-app table{width:100%;min-width:960px;border-collapse:separate;border-spacing:0;table-layout:fixed;font-size:var(--fs-table)}
.price-app thead{background:var(--surface-hover)}
.price-app thead th{position:sticky;top:0;z-index:3;background:var(--surface-hover);color:var(--ink);text-align:left;font-weight:600;font-size:var(--fs-table);padding:var(--th-pad);border-right:1px solid var(--line-table);border-bottom:1px solid var(--line-table);white-space:nowrap}
.price-app tbody td{padding:9px 12px;border-right:1px solid var(--line-table);border-bottom:1px solid var(--line-table);vertical-align:middle;color:var(--ink);word-break:break-word;overflow-wrap:anywhere;position:relative;z-index:1;background:var(--panel)}
.price-app tbody td:last-child{vertical-align:middle}@media (hover: hover) {

.price-app tbody tr:hover td{background:var(--row-hover)}
}
.price-app .num{text-align:right;font-variant-numeric:tabular-nums;font-weight:500;color:var(--ink);cursor:default}
.price-app td.remark,.price-app td.remark2{cursor:pointer;color:var(--ink-faint)}
.price-app td.remark.has,.price-app td.remark2.has{color:var(--ink-2)}
.price-app td.remark.editing,.price-app td.remark2.editing{outline:2px solid var(--brand);outline-offset:-2px;background:var(--brand-soft);border-radius:var(--ctl-radius);color:var(--ink);cursor:text}
/* 单重/克、箱数/公斤：与备注同一套"点击即可编辑"的观感 */
.price-app td.cell-edit{cursor:pointer;color:var(--ink-faint)}
.price-app td.cell-edit.has{color:var(--ink-2)}
.price-app td.cell-edit.editing{outline:2px solid var(--brand);outline-offset:-2px;background:var(--brand-soft);border-radius:var(--ctl-radius);color:var(--ink);cursor:text}
.price-app td.remark,.price-app td.remark2,.price-app td.cell-edit,.price-app .card .c-remark{white-space:pre-wrap}
/* 产品价格手机卡片里的勾选框（窄屏没有表头全选，逐张勾 ✓） */
.price-app .card .c-sel{width:16px;height:16px;margin:0 8px 6px 0;vertical-align:middle;cursor:pointer}
.price-app .link.dim{color:var(--danger)}@media (hover: hover) {

.price-app .link.dim:hover{color:var(--danger);text-decoration:underline}
}
/* .pager / .pg-btn 在 components.css（全站统一），本文件不重复定义 */
.price-app .cards{display:none}

.qtprice-app .cards{display:none}

/* 【2026-09-24】强泰价格复选框列 + 勾选高亮（颜色照抄合同列表）；
   ⚠ 必须带 .qtprice-app 前缀：收款单据 / 开票也用 .rc-table，不带会给它们凭空加高亮 ✗ */

.qtprice-app .rc-table tr.selected-row td { background: #eef6ff; }
@media (hover: hover) {
  .qtprice-app .rc-table tr.selected-row:hover td { background: #e0efff; }
}
.qtprice-app .card.selected-row { background: #eef6ff; }
.qtprice-app .card .c-top .card-check { flex: 0 0 auto; margin: 4px 2px 0 0; }
.qtprice-app .card .c-top .card-check + div { flex: 1 1 auto; min-width: 0; }

/* 弹窗（新增/编辑、调价历史、导入）—— 样式走公共层 .mask > .modal，这里只留本页私有布局 */
.price-app .card{background:var(--panel);border:1px solid var(--line-table);border-radius:var(--radius-card);padding:12px}
.price-app .row3{display:flex;gap:12px}
.price-app .row3 .field{flex:1}
.price-app .hist-item{display:flex;gap:12px;align-items:baseline;padding:9px 0;border-bottom:1px dashed var(--line-soft);font-size:var(--fs-body);flex-wrap:wrap}
.price-app .hist-item:last-child{border-bottom:none}
.price-app .hist-item > span{flex:0 0 auto}
.price-app .hist-item .h-time{color:var(--ink-soft);font-size:13px;white-space:nowrap}
.price-app .hist-item .h-src{color:var(--ink-faint);font-size:13px;white-space:nowrap}
.price-app .hist-item .h-chg{color:var(--ink);font-variant-numeric:tabular-nums}
/* 多选看历史时，每条前面多一列型号（区分是哪个产品的记录 ✓） */
.price-app .hist-item .h-model{color:var(--brand);font-weight:600;white-space:nowrap;min-width:76px}

.price-app select{width:auto}

/* 手机端（≤820px，与原独立页断点一致；≤1080 时主系统外壳已是抽屉布局） */
   /* 改这个断点的样式前，先把 1 处都搜出来看一遍，避免只改了一处。 ── */
@media (max-width:1080px){   /* 【2026-09-21 第 4 批】820 → 1080：与合同列表同一个断点 ✓ */
  .price-app{height:auto;overflow:visible;padding:12px 10px 40px}
  .price-app .cards{display:flex;flex-direction:column;gap:10px}
  .price-app #q{width:100%;max-width:none}
  .price-app .toolbar select{flex:1;min-width:0}
  /* font-size 还原：主系统 ≤1080 块有 .btn{font-size:15px}，原独立页的手机端按钮
     沿用 components.css 的 var(--ctl-fs)，这里显式写回，保持与原版一致 */
  .price-app .toolbar .btn{padding:7px 12px;font-size:var(--ctl-fs)}
  /* overflow:visible 还原：主系统 ≤1080 块给 .card 加了 overflow-x:auto，原页卡片没有 */
  .price-app .card{background:var(--panel);border:1px solid var(--line-table);border-radius:var(--radius-card);padding:12px 14px;overflow:visible}
  .price-app .card .c-top{display:flex;justify-content:space-between;gap:8px;align-items:flex-start}

  /* 【2026-10-13 体检】外来黑 #0f172a ✗ → 主文字令牌 var(--ink) ✓ */
  .price-app .card .c-name{font-weight:700;color:var(--ink);font-size:17px;line-height:1.4;word-break:break-word}
  .price-app .card .c-model{color:var(--ink-2);font-size:14px;margin-top:2px}
  .price-app .card .c-meta{display:flex;gap:6px;margin-top:8px;flex-wrap:wrap}
  .price-app .tag{font-size:11px;padding:2px 8px;border-radius:999px;background:var(--surface-hover);color:var(--ink-label)}
  /* 属性标签（材质 / 表面处理）：手机端卡片里靠它区分产品 → 浅蓝底蓝字。
     用 --brand-soft / --brand-dark（全站唯一色板，与 .rc-sum .s-idx 序号圆标同款），
     不新造颜色；也不做"实心蓝"——那在全站代表"可点"，而这些标签是只读资料。 */
  .price-app .tag-attr{background:var(--brand-soft);color:var(--brand-dark)}
  .price-app .card .c-price{display:flex;justify-content:space-between;margin-top:10px;padding-top:9px;border-top:1px dashed var(--line-soft);font-size:14px;color:var(--ink-soft);gap:4px;flex-wrap:wrap}
  .price-app .card .c-price span{flex:1;min-width:0}
  .price-app .card .c-price b{color:var(--ink);font-variant-numeric:tabular-nums;font-weight:600}

  .qtprice-app .cards{display:flex;flex-direction:column;gap:12px}
  .qtprice-app .card{background:var(--panel);border:1px solid var(--line-table);border-radius:var(--radius-card);padding:12px 14px;overflow:visible}
  .qtprice-app .card .c-top{display:flex;justify-content:space-between;gap:8px;align-items:flex-start}
  /* 【2026-10-13 体检】外来黑 #0f172a ✗ → 主文字令牌 var(--ink) ✓ */
  .qtprice-app .card .c-name{font-weight:700;color:var(--ink);font-size:17px;line-height:1.4;word-break:break-word}
  .qtprice-app .card .c-model{color:var(--ink-2);font-size:14px;margin-top:2px}
  .qtprice-app .card .c-price-big{color:var(--danger);font-weight:700;font-size:17px;font-variant-numeric:tabular-nums;white-space:nowrap}
  .qtprice-app .card .c-price{margin-top:8px;font-size:14px;color:var(--ink-soft)}
  .qtprice-app .card .c-price b{color:var(--ink);font-weight:600}
  .qtprice-app .card .c-remark{margin-top:8px;font-size:14px;color:var(--ink-2)}
  .qtprice-app .card .c-foot{display:flex;gap:16px;margin-top:10px;padding-top:10px;border-top:1px solid var(--line-soft)}
  .qtprice-app .card .c-foot .rc-link{font-size:14px}   /* 与合同卡片的 .cc-ops .op-link = 14px 对齐 ✓ */
  /* 【2026-09-21 第 2 批·卡片统一】============ 四套卡片容器（合同 .contract-card ✓ 收款"表格→卡片"的 tr ✓ 产品价格 .card ✓ 强泰 .card… */
  .contract-card,
  .content.receipt-host .rc-table tr,
  .price-app .card,
  .qtprice-app .card {
    padding: 12px 14px; border-radius: 12px; border: 1px solid var(--line-table);
    background: var(--panel); box-shadow: 0 1px 3px rgba(15, 23, 42, .06);
  }
  /* 收款转换出来的卡片：卡片之间 12px（= 合同卡片 .contract-card 的 margin-bottom ✓）。
     只有它需要 margin ✓ —— 另外三套的容器自带 gap:12px ✓ 再写一遍就叠成 24px ✗。 */
  .content.receipt-host .rc-table tr { margin-bottom: 12px; }
  .price-app .card .c-remark{margin-top:8px;font-size:14px;color:var(--ink-faint);border-top:1px dashed var(--line-soft);padding-top:7px;min-height:18px;cursor:pointer}
  .price-app .card .c-remark.has{color:var(--ink-2)}
  .price-app .card .c-remark:not(.has):not(.editing){display:none}
  /* 操作行 = 合同的 .cc-ops ✓（14px 链接 + 上横线 + 上下各 10px ✓）
     ⚠ 产品价格原来**连那条上横线都没有** ✗（用户："而且你这个还没有横线的"✓ 已补 ✓） */
  .price-app .card .c-foot{display:flex;gap:16px;margin-top:10px;padding-top:10px;border-top:1px solid var(--line-soft)}
  .price-app .card .c-foot .rc-link{font-size:14px}
  .price-app .pager{flex-wrap:wrap}
  .price-app .toolbar{position:relative;flex-direction:column;align-items:stretch;gap:8px;margin-top:8px}
  .price-app .toolbar .spacer{display:none}
  .price-app .toolbar input,.price-app .toolbar select{padding:0 12px;font-size:14px}
}

/* 强泰价格 · 视图样式（2026-09-12 由 /qtprice/index.html 独立页迁入主系统） 移植原则：原 <style> 逐条 1:1 移植，全部收敛在 .qtprice-app 作用域下。 */

/* 宿主容器（① ②） */
.content.qtprice-host{padding:0;max-width:none}

.qtprice-app{height:calc(100vh - 61px);height:calc(100dvh - 61px);display:flex;flex-direction:column;padding:16px 20px;overflow:hidden;color:var(--ink);font-family:var(--font-sans);font-size:var(--fs-body);line-height:1.5;background:var(--bg);color-scheme:light}
/* ③ 零优先级重置：匹配范围不变，但不会覆盖 components.css 的 .link/.field 等类样式 */
:where(.qtprice-app *){box-sizing:border-box;margin:0;padding:0}

/* ⑤⑥ 主系统 style.css 会盖掉的公共样式，按原独立页观感显式还原 */
.qtprice-app .btn{padding:0 16px}

.qtprice-app .field{margin-bottom:12px}

/* 工具栏 */
.qtprice-app .toolbar{flex:0 0 auto;display:flex;align-items:center;gap:10px;margin-bottom:14px;flex-wrap:wrap;justify-content:flex-start}
.qtprice-app .toolbar .sub{color:var(--ink-soft);font-size:12px}
.qtprice-app input,.qtprice-app select{font-size:var(--ctl-fs);height:var(--ctl-h);padding:0 12px;box-sizing:border-box;border:1px solid var(--ctl-border);border-radius:var(--ctl-radius);background:var(--panel);color:var(--ink);outline:none;font-family:inherit}
.qtprice-app select{width:auto}                    /* ④ 还原主系统裸 select{width:100%} 的覆盖 */
.qtprice-app input:focus,.qtprice-app select:focus{outline:none;border-color:var(--brand)}

.qtprice-app input[type="checkbox"] { height: var(--ck-size); width: var(--ck-size); padding: 0; }
/* 调价弹窗的筛选框 / 产品下拉（原来写在标签上 ✗ → 收进这里 ✓；下拉必须显式满宽 ——
   上面那条 .qtprice-app select{width:auto} 会把它压成 auto ✗） */
.qtprice-app .adj-search { margin-bottom: 6px; }
.qtprice-app #adj_product { width: 100%; }
/* 产品价格同款兜底（本页目前没有复选框，防止以后加的时候又被 .price-app input 的输入框样式拉大 ✗） */
.price-app input[type="checkbox"] { height: var(--ck-size); width: var(--ck-size); padding: 0; }

.qtprice-app table{width:100%;min-width:760px;border-collapse:separate;border-spacing:0;table-layout:fixed;font-size:var(--fs-table)}
.qtprice-app thead th{position:sticky;top:0;z-index:3;backface-visibility:hidden;background:var(--surface-hover);color:var(--ink);text-align:left;font-weight:600;font-size:var(--fs-table);padding:var(--th-pad);border-right:1px solid var(--line-table);border-bottom:1px solid var(--line-table);white-space:nowrap}
.qtprice-app thead th.sortable{cursor:pointer;user-select:none}@media (hover: hover) {

.qtprice-app thead th.sortable:hover{background:var(--line-table)}
}
.qtprice-app thead th .arrow{font-size:11px;color:var(--brand);margin-left:3px}
.qtprice-app thead th .resizer{position:absolute;top:0;right:0;width:6px;height:100%;cursor:col-resize;user-select:none;z-index:3}@media (hover: hover) {

.qtprice-app thead th .resizer:hover{background:rgba(37,99,235,.25)}
}
.qtprice-app tbody td{padding:9px 12px;border-right:1px solid var(--line-table);border-bottom:1px solid var(--line-table);vertical-align:middle;font-weight:400;color:var(--ink);word-break:break-word;overflow-wrap:anywhere;position:relative;z-index:1;background:var(--panel)}
.qtprice-app tbody td:last-child{vertical-align:middle}@media (hover: hover) {

.qtprice-app tbody tr:hover td{background:var(--row-hover)}
}
.qtprice-app .name,.qtprice-app .mat,.qtprice-app .price{font-weight:400;color:var(--ink)}
.qtprice-app .muted{color:var(--ink-faint);font-size:13px}

/* 展开的价格历史 */
.qtprice-app .hist-row td{background:var(--surface-alt);padding:0}
.qtprice-app .hist-box{border-left:3px solid var(--brand);margin:6px 12px 10px;padding:8px 12px;background:var(--panel);border-radius:6px}
.qtprice-app .hist-box .h-title{font-size:12px;color:var(--ink-soft);margin-bottom:6px}
.qtprice-app .hist-item{display:flex;gap:14px;padding:3px 0;font-size:12px;border-bottom:1px dashed var(--line-soft)}
.qtprice-app .hist-item:last-child{border-bottom:none}

/* 分页页脚（.pager-sp 用公共层 components.css 的定义） */
.qtprice-app .pager{flex:0 0 auto;display:flex;align-items:center;gap:10px;margin-top:14px;color:var(--ink-soft);font-size:var(--ctl-fs);flex-wrap:wrap}
.qtprice-app .pager b{color:var(--ink);font-weight:500}

/* 弹窗 */
.qtprice-app .mask{position:fixed;inset:0;background:var(--mask);display:none;align-items:flex-start;justify-content:center;padding:var(--modal-top) 0;z-index:50}
/* ⑦ 必须补 .mask.show：本文件的 .mask{display:none}（0,2,0）会与公共层
   .mask.show{display:flex}（0,2,0）打平、靠加载顺序反超 → 不补则弹窗永远不显示 */
.qtprice-app .mask.show{display:flex}
/* 弹窗样式走公共层 .mask > .modal（本页弹窗不再单写一份） */

/* 手机端（≤820px）：与原独立页一致 —— 搜索框独占一行拉满，两个按钮并排等分 */
   /* 改这个断点的样式前，先把 3 处都搜出来看一遍，避免只改了一处。 ── */
@media (max-width: 1080px) {   /* 【2026-09-21 第 4 批】820 → 1080：与合同列表同一个断点 ✓ */
  .qtprice-app{height:auto;overflow:visible;padding:12px 10px 40px}
  .qtprice-app .toolbar .search{
    width:100% !important;
    flex:1 1 100% !important;
    max-width:none !important;
    box-sizing:border-box !important;
  }
  .qtprice-app .toolbar #btnAdd,
  .qtprice-app .toolbar #btnAdjust{
    flex:1 1 45% !important;
    min-width:0 !important;
    box-sizing:border-box !important;
    white-space:nowrap !important;
  }
  /* 按钮字号还原（主系统 ≤1080 块有 .btn{font-size:15px}） */
  .qtprice-app .toolbar .btn{font-size:var(--ctl-fs)}
}

/* ══════════════════════════════════════════════════════════════
   电子签章 · 样式（已收敛到 .seal-app 作用域，避免与工作台 style.css 冲突）
   ══════════════════════════════════════════════════════════════ */
*{box-sizing:border-box}
.seal-app{

  --bg:#f4f5f7; --card:var(--panel); --line:#e3e6ea; --ink:#1c2024; --muted:#6b7280;
  --brand-weak:var(--brand-soft);  --warn:#b7791f;
  --shadow:0 1px 3px rgba(16,24,40,.06),0 1px 2px rgba(16,24,40,.04);
  display:flex;flex-direction:column;height:100%;min-height:640px;
  background:var(--bg);color:var(--ink);
  font:14px/1.5 "Microsoft YaHei","PingFang SC","Hiragino Sans GB",system-ui,sans-serif;
}
.seal-app button{font-family:inherit;font-size:15px;cursor:pointer}
.seal-app input,.seal-app select{font-family:inherit;font-size:13px}
.seal-app .hide{display:none !important}

/* ── 顶部信息条（含 L1 徽标 + 效力说明；工作台顶栏已显示「电子签章」标题，故不再重复 H1） ── */
.seal-app .top{display:flex;align-items:center;gap:12px;padding:10px 16px;background:var(--panel);border-bottom:1px solid var(--line);flex:0 0 auto}
.seal-app .top .lg{margin-left:auto;display:flex;gap:8px;align-items:center}
.seal-app .badge{font-size:11px;padding:3px 9px;border-radius:20px;border:1px solid;white-space:nowrap}
.seal-app .badge.warn{color:var(--warn);border-color:#f0d9a8;background:#fdf8ec}
.seal-app .badge.gray{color:var(--muted);border-color:var(--line);background:#fafbfc}

/* ── 三栏 ── */
.seal-app .cols{flex:1;display:grid;grid-template-columns:auto 1fr 292px;min-height:0}
.seal-app .panel{background:var(--panel);overflow-y:auto;padding:14px}
.seal-app .panel.r{border-left:1px solid var(--line)}

/* 左侧 Acrobat 风格窄栏：46px 常驻，面板从右侧滑出/滑回 */
.seal-app .lside{display:flex;min-width:0;overflow:hidden;background:var(--panel);border-right:1px solid var(--line)}
.seal-app .lrail{flex:0 0 46px;position:relative;display:flex;flex-direction:column;align-items:center;
       gap:6px;padding:12px 0 10px;border-right:1px solid var(--line);
       cursor:pointer;user-select:none;transition:background .15s ease}@media (hover: hover) {

.seal-app .lrail:hover{background:#f6f8fb}
}
.seal-app .lrail:active{background:var(--line-soft)}
.seal-app .lrail .ric{width:32px;height:32px;border:0;border-radius:7px;background:none;cursor:pointer;
            font-size:14px;color:#5b6675;line-height:1;user-select:none}@media (hover: hover) {

.seal-app .lrail .ric:hover{background:var(--line-soft);color:var(--brand)}
}
.seal-app .panel.l{flex:0 0 286px;width:286px;overflow-y:auto;overflow-x:hidden;
         transition:margin-left .22s ease,opacity .18s ease}
.seal-app .cols.l-collapse .panel.l{margin-left:-286px;opacity:0;pointer-events:none}

/* 栏中央的小三角（Acrobat 同款位置） */
.seal-app .ltoggle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
         width:22px;height:38px;padding:0;margin:0;border:0;border-radius:6px;
         background:none;color:var(--muted);font-size:11px;line-height:1;
         cursor:pointer;user-select:none}@media (hover: hover) {

.seal-app .ltoggle:hover{color:var(--brand);background:var(--line-soft)}
}
.seal-app .stage{overflow:auto;background:var(--bg);padding:16px;display:flex;gap:14px;align-items:flex-start}

.seal-app h3{margin:0 0 10px;font-size:12px;font-weight:700;color:var(--muted);letter-spacing:1.5px}
.seal-app .sec{margin-bottom:18px;padding-bottom:16px;border-bottom:1px dashed var(--line)}
.seal-app .sec:last-child{border:0;margin-bottom:0;padding-bottom:0}
.seal-app .row{display:flex;align-items:center;gap:8px;margin-bottom:9px}
/* 行内修饰（把模板里散落的 gap/margin/小字内联收回来 ✓）：窄间距 / 顶部间距 / 次要小字 */
.seal-app .row.tight{gap:6px}
.seal-app .mt10{margin-top:10px}
.seal-app .mt8{margin-top:8px}
.seal-app .dim{font-size:11px;color:var(--muted)}
.seal-app .row>label{flex:0 0 58px;font-size:12px;color:var(--muted)}
.seal-app .row input[type=text],.seal-app .row input[type=number],.seal-app .row select{flex:1;min-width:0;padding:0 12px;height:var(--ctl-h);font-size:var(--ctl-fs);box-sizing:border-box;border:1px solid var(--ctl-border);border-radius:var(--ctl-radius);outline:none;background:var(--panel)}
.seal-app .row input:focus,.seal-app .row select:focus{border-color:var(--brand)}
.seal-app .row input[type=color]{flex:0 0 42px;padding:1px;height:28px;border:1px solid var(--line);border-radius:5px;background:var(--panel)}
.seal-app .rng{display:flex;align-items:center;gap:8px;margin-bottom:9px}
.seal-app .rng>label{flex:0 0 58px;font-size:12px;color:var(--muted)}
.seal-app .rng input[type=range]{flex:1;min-width:0;accent-color:var(--brand)}
.seal-app .rng .v{flex:0 0 48px;text-align:right;font-size:12px;color:var(--ink);font-variant-numeric:tabular-nums}

.seal-app .seg{display:flex;border:1px solid var(--line);border-radius:6px;overflow:hidden;margin-bottom:10px}
.seal-app .seg button{flex:1;padding:6px 4px;border:0;background:var(--panel);color:var(--muted);font-size:12px}
.seal-app .seg button+button{border-left:1px solid var(--line)}
.seal-app .seg button.on{background:var(--brand);color:var(--panel);font-weight:600}

.seal-app .btn{padding:0 14px;height:var(--ctl-h);display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--ctl-border);background:var(--panel);border-radius:var(--ctl-radius);color:var(--ink);font-weight:500}@media (hover: hover) {

.seal-app .btn:hover{border-color:#c7cfdb;background:var(--surface-hover)}
}
.seal-app .btn.pri{background:var(--brand);border-color:var(--brand);color:var(--panel);font-weight:500}@media (hover: hover) {

.seal-app .btn.pri:hover{background:var(--brand-dark)}
}
.seal-app .btn.btn-sm{padding:0 14px;height:var(--ctl-h);font-size:var(--ctl-fs);display:inline-flex;align-items:center;justify-content:center;white-space:nowrap}
.seal-app .row .btn{flex:1 1 0;min-width:0;white-space:nowrap}
.seal-app .btn.wide{width:100%;margin-top:6px}
.seal-app .btn:disabled{opacity:.45;cursor:not-allowed}

.seal-app .sealbox{background:repeating-conic-gradient(#fafafa 0 25%,#f2f3f5 0 50%) 0 0/16px 16px;
  border:1px solid var(--line);border-radius:8px;display:grid;place-items:center;padding:10px;margin-bottom:10px}
.seal-app .sealbox canvas{max-width:100%;height:auto;display:block}
.seal-app #sealFile{width:100%;font-size:12px;margin-bottom:8px}

/* ── 舞台 ── */
.seal-app .drop{flex:1;min-height:430px;border:2px dashed #cdd2d9;border-radius:12px;display:grid;place-items:center;
  background:var(--panel);color:var(--muted);text-align:center;cursor:pointer;padding:24px}@media (hover: hover) {

.seal-app .drop:hover{border-color:var(--brand);background:var(--brand-weak)}
}
.seal-app .drop b{display:block;font-size:15px;color:var(--ink);margin-bottom:6px}
.seal-app .drop .sub{font-size:12px}

.seal-app .thumbs{flex:0 0 150px;display:flex;flex-direction:column;gap:10px;overflow-y:auto;padding-right:2px;max-height:calc(100vh - 130px);max-height:calc(100dvh - 130px)}
.seal-app .thumb{position:relative;border:2px solid transparent;border-radius:5px;overflow:hidden;background:var(--panel);
  box-shadow:var(--shadow);cursor:pointer;flex:0 0 auto}
.seal-app .thumb.on{border-color:var(--brand)}
.seal-app .thumb canvas{display:block;width:100%;height:auto}
.seal-app .thumb .no{position:absolute;left:0;top:0;background:rgba(0,0,0,.55);color:var(--panel);font-size:10px;padding:1px 5px;border-bottom-right-radius:4px}

.seal-app .pagewrap{position:relative;background:var(--panel);box-shadow:var(--shadow);border-radius:4px;overflow:hidden;align-self:flex-start}
.seal-app .pagewrap canvas{display:block}
.seal-app .pagewrap .ov{position:absolute;left:0;top:0;cursor:move;touch-action:none}
.seal-app .pagewrap .hint{position:absolute;left:50%;top:8px;transform:translateX(-50%);background:rgba(28,32,36,.72);
  color:var(--panel);font-size:11px;padding:3px 10px;border-radius:20px;pointer-events:none;white-space:nowrap}

.seal-app .mask{position:fixed;inset:0;background:rgba(255,255,255,.84);display:none;place-items:center;z-index:110}
.seal-app .mask.show{display:grid}
.seal-app .mbox{font-size:14px;color:var(--ink);background:var(--panel);padding:14px 26px;border-radius:10px;box-shadow:var(--shadow)}

.seal-app .note{font-size:11px;color:var(--muted);line-height:1.7;background:#fafbfc;border-left:3px solid var(--line);padding:7px 9px;border-radius:0 4px 4px 0;margin-top:8px}
.seal-app .chk{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--muted);margin-top:9px;cursor:pointer}
.seal-app .grid9{display:grid;grid-template-columns:repeat(3,1fr);gap:4px;margin-bottom:9px}
.seal-app .grid9 button{padding:7px 0;border:1px solid var(--line);background:var(--panel);border-radius:5px;font-size:11px;color:var(--muted)}
.seal-app .grid9 button.on{background:var(--brand);border-color:var(--brand);color:var(--panel)}

/* ── 弹窗 ── */
.seal-app .modal{position:fixed;inset:0;background:rgba(20,24,28,.5);display:none;place-items:center;z-index:130;padding:20px}
.seal-app .modal.show{display:grid}
.seal-app .mcard{background:var(--panel);border-radius:12px;max-width:640px;width:100%;padding:22px 24px;max-height:86vh;overflow:auto}
.seal-app .mcard h2{margin:0 0 14px;font-size:16px}

.seal-app .mcard table{width:100%;border-collapse:collapse;font-size:var(--fs-table)}
.seal-app .mcard th,.seal-app .mcard td{border:1px solid var(--line);padding:7px 9px;text-align:left;vertical-align:top;line-height:1.65}
.seal-app .mcard th{background:var(--surface-hover);font-weight:700}
.seal-app .mcard td.hl{font-weight:700;white-space:nowrap}
.seal-app .mcard .p{font-size:12.5px;line-height:1.8;color:#374151}
.seal-app .mcard code{background:#f3f4f6;padding:1px 5px;border-radius:3px;font-size:12px}

   /* 改这个断点的样式前，先把 1 处都搜出来看一遍，避免只改了一处。 ── */
@media(max-width:1100px){
  /* —— 整体纵向三段：顶 L 条 / 中舞台 / 底 R 抽屉 —— */
  .seal-app{height:100%;min-height:0}
  .seal-app .cols{
    grid-template-columns:1fr;
    grid-template-rows:auto 1fr auto;
    min-height:0;
  }
  .seal-app .top{padding:8px 10px;font-size:12px;gap:8px}
  .seal-app .top .lg{gap:6px}
  .seal-app .top .badge{font-size:10px;padding:2px 6px}

  /* —— 左 L 改成顶部横条 —— */
  .seal-app .lside{
    flex-direction:column;
    border-right:0;
    border-bottom:1px solid var(--line);
    background:var(--panel);
  }
  .seal-app .lrail{
    flex:0 0 44px;
    flex-direction:row;
    align-items:center;
    justify-content:flex-start;
    gap:6px;
    padding:0 10px;
    border-right:0;
    border-bottom:0;
    cursor:default;
  }
  .seal-app .lrail:hover{background:transparent}
  .seal-app .lrail .ric{
    width:36px;height:32px;
    font-size:13px;
    border:1px solid var(--line);
    background:var(--panel);
    border-radius:6px;
  }
  .seal-app .lrail .ric.on{background:var(--brand);color:var(--panel);border-color:var(--brand)}
  .seal-app .ltoggle{
    position:static;
    transform:none;
    margin-left:auto;
    width:34px;height:32px;
    border:1px solid var(--line);
    background:var(--panel);
    border-radius:6px;
  }

  /* —— 左 L 面板改为 overlay 抽屉（从顶部下拉）—— ⚠️ .lside 必须 position:relative… */
  /* ⚠️ 必须 overflow:visible —— 原版 .lside 的 overflow:hidden（L30）会把 absolute 的 面板整块裁掉… */
  .seal-app .lside{position:relative;z-index:30;overflow:visible}
  .seal-app .panel.l{
    position:absolute !important;
    left:0;right:0;
    top:100%;                     /* = 顶栏自身高度，自适应不写死 44px */
    z-index:20;
    width:100%;
    flex:0 0 auto;
    max-height:60vh;
    border-bottom:1px solid var(--line);
    box-shadow:0 6px 18px rgba(0,0,0,.12);
    background:var(--panel);
    margin-left:0 !important;     /* 覆盖桌面端 .cols.l-collapse .panel.l{margin-left:-286px} */
    opacity:1 !important;
    pointer-events:auto !important;
  }
  .seal-app .cols.l-collapse .panel.l{display:none}

  /* —— 中间舞台 —— */
  .seal-app .stage{
    flex-direction:column;
    padding:10px;
    gap:10px;
    min-height:0;
    overflow:auto;
  }
  .seal-app .thumbs{
    flex:0 0 auto;
    flex-direction:row;
    max-height:none;
    overflow-x:auto;
    overflow-y:hidden;
    width:100%;
    padding:2px;
  }
  .seal-app .thumb{flex:0 0 78px}
  .seal-app .pagewrap{max-width:100%;align-self:stretch}
  .seal-app .pagewrap canvas{max-width:100%;height:auto;display:block}
  .seal-app .pagewrap .hint{font-size:10px;padding:2px 8px}

  /* —— 右 R 抽屉：默认收起，点 FAB 展开 —— */
  .seal-app .panel.r{
    border-left:0;
    border-top:1px solid var(--line);
    max-height:60vh;
    flex:0 0 auto;
    overflow-y:auto;
    transition:max-height .22s ease;
  }
  .seal-app .panel.r:not(.r-open){max-height:0;border-top:0;overflow:hidden;padding:0 14px}
  .seal-app .panel.r.r-open{padding:14px;border-top:1px solid var(--line)}
  /* —— 右 R 触发按钮（FAB）—— */
  .seal-app .r-fab{
    display:flex;align-items:center;justify-content:center;
    position:fixed;right:14px;bottom:14px;
    width:48px;height:48px;
    background:var(--brand);color:var(--panel);
    border-radius:50%;border:0;

    box-shadow:0 4px 12px rgba(37,99,235,.4);
    font-size:20px;cursor:pointer;z-index:30;
  }
  .seal-app .r-fab:hover{background:var(--brand-dark)}
  .seal-app .r-fab-close{display:none}
  .seal-app .panel.r.r-open ~ .r-fab .r-fab-open{display:none}
  .seal-app .panel.r.r-open ~ .r-fab .r-fab-close{display:block}

  /* —— 印章预览自适应 —— */
  .seal-app .sealbox{padding:6px}
  .seal-app .sealbox canvas{width:100% !important;height:auto !important}

  /* —— 段落、控件紧凑，但按钮保证触控高度（≥32px） —— */
  .seal-app h3{font-size:11px;margin-bottom:6px}
  .seal-app .sec{margin-bottom:12px;padding-bottom:10px}
  .seal-app .row,.seal-app .rng{margin-bottom:6px}
  /* 触控最小高度：普通按钮 36px / 小按钮 32px / 分段 36px / 九宫格 38px */
  .seal-app .btn{min-height:36px;padding:6px 12px;font-size:13px}
  .seal-app .btn.btn-sm{min-height:32px;padding:5px 10px;font-size:12px}
  /* 印章库操作三按钮（重命名/设为默认/删除）：强制横排一行，防旧版HTML竖排结构/大字体换行 */
  .seal-app .row{flex-direction:row;flex-wrap:nowrap}
  .seal-app .row .btn{flex:1 1 0;min-width:0;white-space:nowrap}
  .seal-app .seg button{min-height:36px;padding:6px 2px;font-size:12px}
  .seal-app .grid9 button{min-height:38px;padding:6px 0;font-size:11px}
  /* 输入框同样保证触控高度 */
  .seal-app .row input[type=text],.seal-app .row input[type=number],
  .seal-app .row select{height:var(--ctl-h);padding:0 12px;font-size:var(--ctl-fs)}
  .seal-app .row input[type=color]{height:34px}

  /* —— 帮助弹窗留出顶部空间 —— */
  .seal-app .mcard{padding:16px 18px;max-height:80vh}
}

/* 桌面端隐藏 FAB */
   /* 改这个断点的样式前，先把 1 处都搜出来看一遍，避免只改了一处。 ── */
@media(min-width:1101px){
  .seal-app .r-fab{display:none}
}

@media (max-width: 1080px) {
  .rc-modal-mask, .pwd-mask, .spec-manage-mask, .inv-mask, .invoice-app .mask {
    padding-bottom: var(--kb, 0px);
    box-sizing: border-box;
  }
  .rc-modal-mask > .modal, .pwd-mask > .modal, .spec-manage-mask > .modal,
  .inv-mask > .inv-modal, .invoice-app .mask > .modal {
    max-height: calc(100dvh - var(--kb, 0px) - var(--modal-top) - 28px);
  }
}

/* 【2026-09-20 用户反馈·重做】列表页脚：**按收款单据那套"设计"** ✓ ── 第一版做错在哪（用户原话… */
.pager,
.invoice-app .pager,
.qtprice-app .pager,
.price-app .pager {
  /* 【2026-09-20 用户反馈·第三次·这次理解对了】线的位置： 用户原话："我意思那条线，在表单哪里" ✓ —— 那条线要**紧贴在表格（表单）的下沿** ✓… */
  margin-top: 0;                             /* ★ 紧贴表格下沿（关键就是这一行） */

  padding: 12px 0;                           /* ★ 上下各 12px → 页脚高度全站一致 ✓（水平方向保持原样 0 ✓） */
  background: var(--panel);                  /* 与卡片同底色 → 读作"页脚区"✓ */
  }

  .rc-pager-box,
  #rcPager,
  .content.list-page .list-table-card #pager {
  border-top: 1px solid var(--line-table);
  }
  /* 内层 .pager 不再画线（免出现两条线）。 */
  .rc-pager-box > .pager,
  #rcPager > .pager,
  #rcPager .pager,
  .content.list-page .list-table-card #pager .pager {
  border-top: 0;
  }

  @media (min-width: 1081px) {
  .invoice-app .card.inv-table-card #inv_pager {
  margin-left: 0; margin-right: 0;
  padding-left: 16px; padding-right: 16px;
  }
  }

  .invoice-app .card.inv-table-card #inv_pager {
    border-top: 1px solid var(--line-table);
  }
  /* 2026-09-23 修复：产品价格工具栏刷新时闪动 —— 分类/材质两个下拉原来没有宽度， 候选值是接口回来后才填的（price.js loadMeta）→ 下拉变宽 15/25px… */
  .price-app .rc-toolbar #cat,
  .price-app .rc-toolbar #mat {
    width: 132px; min-width: 132px;
  }
