/* ============================================================
   报价清单（概算表）· 样式（2026-10-29）
   ------------------------------------------------------------
   设计基准：**1920 × 1080**
     可用宽度 = 1920 - 侧边栏(200) - 内容区 padding(48) ≈ 1670px
     三栏分配：空间树 264 / 明细表 自适应(~1070) / 汇总面板 300

   编辑器三栏：
     左 = 施工空间树（一级/二级）
     中 = 明细表
     右 = 汇总面板（直接费/管理费/税费/合计大写）

   版式参照《山东电建办公楼四楼《概算》.xlsx》：
   · 区域标题行（跨列加粗）
   · 「XX 合计」小计行
   ============================================================ */

/* ---------- 布局（1920 基准）：① 汇总在上（整宽）② 明细在下（两栏）---------- */
/* ★ 2026-10-29 22:55 改三栏：空间树 | 明细表 | 报价器
   —— 用户要求「明细表整体向左挪，右边留部分空间」放报价器 */

/* ★★★ 2026-10-29 23:35 再改：报价器独占**整个右栏**（约占屏幕 1/4）
   —— 用户反馈「计算器占比太小」→ 不能只是第三栏里一个 300px 小面板
   —— 新结构：
        .ql-work
          ├─ .ql-work-main   ← 汇总 + （空间树 | 明细表）
          └─ .ql-col-calc    ← 报价器大栏（右侧）
   —— 右栏宽度用 vw 表达：24vw ≈ 1920 屏幕的 1/4（≈460px）
   —— 窄屏时自动降级成上下堆叠，绝不把明细表挤扁。 */
.ql-work {
  display: grid;
  /* ★ 2026-10-31：右栏计算器放宽（用户：「挤成了一个疙瘩，重新排版，舒朗些，
     屏幕这么宽，最少满屏的 80%」）——
     clamp(380px,25vw,520px) → clamp(440px, 30vw, 600px)，gap 16→20px。
     降级断点从 1400px 放宽到 1200px：1920 宽屏下始终双栏，不掉到上下堆叠。 */
  grid-template-columns: minmax(0, 1fr) clamp(440px, 30vw, 600px);
  gap: 20px;
  align-items: start;
  margin-top: 16px;
}
.ql-work-main {
  min-width: 0;
}
/* 左主区内部：汇总 + 明细两栏 */
.ql-layout {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: 18px;
  align-items: start;
  margin-top: 14px;
}
/* 屏幕不够宽时，报价器挪到下一行（不再挤明细表） */
@media (max-width: 1200px) {
  .ql-work {
    grid-template-columns: minmax(0, 1fr);
  }
  .ql-col-calc {
    grid-column: 1 / -1;
  }
  .ql-layout {
    grid-template-columns: 220px minmax(0, 1fr);
  }
}
.ql-col-tree .card-body { padding: 8px; max-height: calc(100vh - 240px); overflow-y: auto; }
.ql-col-items .card-body { padding: 0; }
/* 左栏跟随滚动（明细表很长时，空间树始终可见）*/
.ql-col-tree { position: sticky; top: 0; }
/* 报价器大栏：占据右侧整列（宽度 ≈ 25vw ≈ 屏幕 1/4），
   高度撑满一屏 → 顶部与「工程费用汇总」齐平、随页面滚动跟随，
   内容超高时栏内自己滚（.ql-col-calc .card-body） */
.ql-col-calc {
  position: sticky;
  top: 8px;
  display: flex;
  flex-direction: column;
  height: calc(100vh - 150px);
  min-height: 480px;
}
.ql-col-calc .card-head { flex: 0 0 auto; }
.ql-col-calc .card-head .btn { margin-left: auto; }
.ql-col-calc .card-head .ql-card-sub { margin-left: 0; }
.ql-col-calc .card-body {
  padding: 14px 16px;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}
/* 收起状态：整栏压扁，别占着一大块空白 */
.ql-col-calc.is-collapsed {
  height: auto;
  min-height: 0;
  max-height: none;
}
.ql-col-calc.is-collapsed .card-body {
  padding: 6px 16px 14px;
}

/* ---------- 顶部使用提示条 ---------- */
/* ⚠️ 2026-10-29 23:35：顶部那条蓝色提示条已被隐藏
   （页面顶上常年占一条，信息密度低）→ 改成页头「📖 报价表操作指南」按钮，
      点开是弹窗版完整说明（.ql-guide-doc）。
      .ql-guide 样式保留在下面（万一别处还在用），但页面已不再渲染它。 */
.ql-guide {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: var(--primary-soft);
  border: 1px solid #BFDBFE;
  border-radius: 10px;
  padding: 11px 15px;
  font-size: 12.5px;
  color: var(--text);
  line-height: 1.7;
  margin-top: 16px;
}
.ql-guide-icon {
  flex-shrink: 0;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 1px;
}
.ql-guide b { color: var(--primary-d); }
.ql-guide kbd {
  display: inline-block;
  background: #fff;
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 4px;
  padding: 0 5px;
  font-size: 11px;
  font-family: inherit;
  color: var(--muted);
}

/* ---------- ① 项目汇总区（对应《概算》表行 13-28）---------- */
/* ⚠️ 用 div + flex 而不是 <table>：
     table-layout:fixed 的两列表格，某些浏览器会把金额列算成 0 宽 → 金额看不见。
     div 布局左右对齐更可控。 */
.ql-sum { margin-top: 16px; }
/* ⚠️ 汇总卡现在在 .ql-work-main 里，外层 .ql-work 已有 16px 间距 → 这里去掉重复的 */
.ql-work-main > .ql-sum { margin-top: 0; }
.ql-sum .card-body { padding: 0; }
.ql-card-sub { font-size: 12px; color: var(--sub); margin-left: 4px; }
.ql-sum-head {
  display: flex; justify-content: space-between; align-items: center;
  background: #FAFAFB; padding: 11px 18px; border-bottom: 1px solid var(--line);
  font-size: 12.5px; font-weight: 600; color: var(--muted);
}
.ql-sum-head .ql-sum-val { width: 220px; text-align: right; }
.ql-sum-body { padding: 4px 0; }
.ql-sum-line {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 9px 18px; font-size: 13.5px; color: var(--text);
  border-bottom: 1px solid var(--line-soft);
}
.ql-sum-name { font-weight: 500; }
/* 金额列：固定宽 + 右对齐（对应 Excel 的 K 列）*/
.ql-sum-val {
  width: 220px; flex-shrink: 0; text-align: right;
  font-variant-numeric: tabular-nums; font-weight: 600; color: var(--text);
}
.ql-sum-line .dim { color: var(--sub); font-style: normal; font-size: 11.5px; }
/* 分隔条 */
.ql-sum-gap { height: 9px; background: #FAFAFB; border-bottom: 1px solid var(--line); }
.ql-sum-strong .ql-sum-val { font-size: 15px; }
/* 合计行 */
.ql-sum-total-line {
  background: var(--primary-soft); border-bottom: none;
  padding-top: 13px; padding-bottom: 13px; font-weight: 700;
}
.ql-sum-total-line .ql-sum-val {
  font-size: 20px; font-weight: 800; color: var(--primary-d); letter-spacing: -.4px;
}
/* 大写金额 */
.ql-sum-capital {
  display: block; font-style: normal; font-size: 11.5px; font-weight: 400;
  color: var(--primary-d); margin-top: 3px; opacity: .85;
}
.ql-sum-empty { text-align: center; color: var(--sub); padding: 26px 18px !important; font-size: 13px; }
.ql-sum-meta {
  text-align: right; font-size: 11.5px; color: var(--sub);
  padding: 9px 18px; border-top: 1px solid var(--line-soft);
}

/* ---------- 左栏：空间树 ---------- */
.ql-space {
  border-radius: 8px;
  padding: 9px 11px;
  margin-bottom: 4px;
  cursor: pointer;
  transition: background .12s;
}
.ql-space:hover { background: var(--primary-soft); }
.ql-space.is-active {
  background: var(--primary-soft);
  box-shadow: inset 3px 0 0 var(--primary);
}
.ql-space-main {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.ql-space-name {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ql-space-amt {
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.ql-space-acts {
  display: flex;
  gap: 10px;
  margin-top: 3px;
  opacity: 0;
  transition: opacity .12s;
}
.ql-space:hover .ql-space-acts,
.ql-space.is-active .ql-space-acts { opacity: 1; }
.ql-space-acts .btn-link { font-size: 11.5px; }
.ql-space-children {
  margin-top: 3px;
  margin-left: 6px;
  padding-left: 10px;
  border-left: 1px dashed var(--line);
}
/* 二级区域名字稍小一点，视觉上从属一级 */
.ql-space-children .ql-space-name { font-size: 12.5px; font-weight: 400; }

/* ---------- 中栏：明细表 ---------- */
.ql-items { width: 100%; border-collapse: collapse; table-layout: fixed; }
.ql-items th {
  background: #FAFAFB;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  text-align: left;
  padding: 11px 12px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
  position: sticky;
  top: 0;
  z-index: 2;
}
.ql-items td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--line-soft);
  font-size: 13px;
  vertical-align: middle;
}
/* 行 hover：长表格里定位当前行更容易 */
.ql-items tbody tr:not(.ql-space-row):not(.ql-subtotal-row):hover td {
  background: #F9FAFB;
}
/* 汇总面板的每个区域行也加 hover */
.ql-sum-row:hover { background: var(--primary-soft); border-radius: 6px; padding-left: 6px; padding-right: 6px; }
/* 数值列右对齐 + 等宽数字 */
.ql-items td.ql-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ql-items td.ql-num-strong { font-weight: 600; }
/* 工艺说明列 */
.ql-items td.ql-note {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.55;
}
/* 区域标题行（对应 Excel 的区域标题行，跨列）*/
.ql-space-row td {
  background: #F7F8FA;
  border-bottom: 1px solid var(--line);
  border-top: 1px solid var(--line);
  padding-top: 13px;
  padding-bottom: 13px;
}
.ql-space-row b { font-size: 13.5px; color: var(--text); letter-spacing: .2px; }
/* 小计行（对应 Excel 的「XX 合计」）*/
.ql-subtotal-row td {
  background: var(--primary-soft);
  border-bottom: 1px solid var(--line);
  padding-top: 11px;
  padding-bottom: 11px;
}
.ql-subtotal-row b { color: var(--primary-d); font-size: 13px; }
.ql-subtotal-row td.ql-num { font-weight: 700; font-size: 13.5px; }

/* ---------- 表格内编辑（造价软件式：表格即编辑器）---------- */
/* 输入框要「像单元格」—— 默认透明无边框，聚焦才显现编辑态 */
.ql-cell-input {
  width: 100%;
  /* ⚠️ 边框不能是 transparent —— 那样用户看着像**不可编辑的纯文本**，
     点了没反应就以为「填不了」（2026-10-29 用户反馈）。
     改成**淡淡的虚线底**：一眼看出「这里能填」，但又不抢内容的视觉。 */
  border: 1px dashed #D6DAE1;
  border-radius: 5px;
  background: #FCFDFE;
  padding: 5px 7px;
  font-family: inherit;
  font-size: 13px;
  color: var(--text);
  transition: border-color .12s, background .12s, box-shadow .12s;
}
.ql-cell-input:hover {
  border-color: var(--primary);
  border-style: solid;
  background: #fff;
}
.ql-cell-input:focus {
  outline: none;
  border-color: var(--primary);
  border-style: solid;
  background: #fff;
  box-shadow: 0 0 0 3px var(--primary-soft);
}
.ql-cell-input::placeholder { color: var(--sub); opacity: .75; }
/* 数字列右对齐 */
.ql-cell-num { text-align: right; font-variant-numeric: tabular-nums; }
/* 区域标题行里的输入框：加粗、字号大一点，像标题 */
.ql-cell-space {
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: .2px;
  padding: 4px 7px;
  /* 标题行用**实线**边框，跟普通单元格区分开 */
  border-style: solid;
  border-color: #E4E7EC;
  background: #fff;
  max-width: 320px;
}
/* 明细行的区域名（缩进显示）*/
.ql-indent {
  padding-left: 10px !important;
  font-size: 11.5px;
  color: var(--sub);
}
/* ---------- 明细表：区域内「新建项目」输入行 ---------- */
/* 这一行紧跟在所属区域标题行下面 → "在哪个区域下加项目"一眼可见 */
.ql-addrow td {
  background: #FCFCFD;
  border-bottom: 1px dashed var(--line);
  padding-top: 7px;
  padding-bottom: 7px;
}
.ql-addrow .ql-cell-add { border-color: #BFDBFE; background: #fff; }
.ql-addrow .ql-cell-add:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-soft); }
.ql-addrow .ql-cell-add::placeholder { color: var(--primary); opacity: .72; }
/* 二级区域在明细里的缩进 */
.ql-indent-dim { padding-left: 22px !important; font-size: 11.5px; color: var(--sub); }
/* 二级区域标题行：缩进 + 标记 */
.ql-cell-sub { margin-left: 22px; }
.ql-space-lv {
  display: inline-block; font-size: 10.5px; font-weight: 600;
  color: var(--muted); background: #EFEFF1; border-radius: 20px;
  padding: 1px 8px; margin-left: 8px; vertical-align: middle;
}

/* 单位列：给 datalist 下拉箭头留位置，值要能完整显示 */
.ql-items td .ql-cell-input[list] {
  padding-right: 18px;   /* 给下拉箭头留位 */
  min-width: 56px;
}

/* ---------- 单位下拉（自绘面板，不用 datalist）---------- */
/* ⚠️ datalist 会按输入内容过滤 → 选了 m² 就再也看不到 个/套
   → 改成自绘菜单：固定列出全部选项，一次看全 */
.ql-unit {
  position: relative;
  display: flex;
  align-items: center;
}
.ql-unit-input {
  padding-right: 20px !important;   /* 给 ▼ 让位 */
  min-width: 46px;
}
.ql-unit-caret {
  position: absolute;
  right: 2px;
  top: 50%;
  transform: translateY(-50%);
  border: none;
  background: transparent;
  color: var(--sub);
  font-size: 11px;
  line-height: 1;
  padding: 3px 4px;
  cursor: pointer;
  border-radius: 4px;
}
.ql-unit-caret:hover { background: var(--line-soft); color: var(--primary); }
.ql-unit.is-open .ql-unit-caret { color: var(--primary); }
/* 菜单：绝对定位浮层，z-index 高于表格 */
.ql-unit-menu {
  position: absolute;
  top: calc(100% + 3px);
  left: 0;
  min-width: 132px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, .16);
  z-index: 40;
  padding: 4px;
  overflow: hidden;
}
.ql-unit-opt {
  display: flex;
  align-items: baseline;
  gap: 7px;
  width: 100%;
  border: none;
  background: transparent;
  text-align: left;
  padding: 6px 9px;
  border-radius: 5px;
  cursor: pointer;
  font-family: inherit;
}
.ql-unit-opt:hover { background: var(--primary-soft); }
.ql-unit-opt.is-cur { background: var(--primary-soft); }
.ql-unit-t {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  min-width: 22px;
}
.ql-unit-opt.is-cur .ql-unit-t { color: var(--primary-d); }
.ql-unit-d {
  font-size: 11px;
  color: var(--sub);
  white-space: nowrap;
}
/* 自定义单位 */
.ql-unit-custom {
  border-top: 1px solid var(--line-soft);
  margin-top: 3px;
  padding: 5px 5px 2px;
}
.ql-unit-custom-inp {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 4px 7px;
  font-size: 12px;
  font-family: inherit;
  background: #fff;
}
.ql-unit-custom-inp:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-soft);
}

/* 保存成功的绿勾反馈（让用户确知"改完存进去了"）*/
.ql-saved-mark {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 13px;
  font-weight: 700;
  color: #16A34A;
  opacity: 0;
  transition: opacity .18s;
  pointer-events: none;
  z-index: 3;
}
.ql-saved-mark.show { opacity: 1; }
.ql-saved-mark.hide { opacity: 0; }
/* 明细行要 relative，勾才能定位在行内 */
.ql-items tbody tr[data-item] { position: relative; }

/* 新建行的单位输入框（默认 m，可下拉选）*/
.ql-cell-new-unit {
  border-color: #BFDBFE !important;
  background: #fff !important;
  font-weight: 600;
}

/* 规格列输入框（现在是可编辑的了）*/
.ql-spec-input {
  font-size: 12px;
  color: var(--muted);
}
.ql-spec-input:focus { color: var(--text); }

/* 序号列（对应 Excel 的 A 列 `1` / `1-1`）*/
.ql-seq {
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* 区域标题行的序号（`1` / `2` …）*/
.ql-space-seq {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
/* 规格列（内径 1350mm / 长边×短边）*/
.ql-spec {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.5;
}
/* 区域标题行里的提示文字 */
.ql-row-hint { padding: 0 12px !important; }
.ql-hint-text {
  font-size: 11.5px;
  color: var(--sub);
  font-style: italic;
}
/* 底部新建行：整行用虚线框提示「这里可以打字」*/
.ql-newrow td {
  background: #FAFAFB;
  border-top: 1px solid var(--line);
  border-bottom: none;
  padding-top: 10px;
  padding-bottom: 10px;
}
.ql-newrow .ql-cell-input {
  background: #fff;
  border-color: #BFDBFE;
}
.ql-newrow .ql-cell-input:focus {
  border-color: var(--primary);
  background: #fff;
}
/* ⚠️ 不能用 ::before 给 input 加「＋」—— input 是 void 元素，伪元素不生效
   → 改用左边框 + placeholder 文案来提示「这里可以打字」*/
.ql-cell-new {
  border-color: #BFDBFE;
  background: #fff;
  font-weight: 500;
}
.ql-cell-new::placeholder { color: var(--primary); opacity: .7; font-weight: 400; }

/* ---------- 右栏：汇总面板 ---------- */
.ql-sum-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 0;
  font-size: 13px;
  color: var(--muted);
}
.ql-sum-row b {
  color: var(--text);
  font-variant-numeric: tabular-nums;
  font-size: 13.5px;
}
.ql-sum-row .dim { color: var(--sub); font-style: normal; font-size: 11.5px; }
.ql-sum-direct {
  border-top: 1px solid var(--line-soft);
  padding-top: 12px;
}
.ql-sum-direct b { font-size: 16px; font-weight: 700; }
.ql-sum-sep {
  height: 1px;
  background: var(--line);
  margin: 12px 0;
}
.ql-sum-total {
  background: var(--primary-soft);
  border: 1px solid #BFDBFE;
  border-radius: 12px;
  padding: 16px 16px 14px;
  text-align: right;
}
.ql-sum-label {
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 5px;
  letter-spacing: 1px;
}
.ql-sum-value {
  font-size: 26px;
  font-weight: 800;
  color: var(--primary-d);
  letter-spacing: -.6px;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
/* 中文大写金额 */
.ql-sum-capital {
  font-size: 12px;
  color: var(--primary-d);
  margin-top: 9px;
  padding-top: 9px;
  border-top: 1px dashed #BFDBFE;
  line-height: 1.6;
  word-break: break-all;
}
.ql-sum-meta {
  text-align: center;
  font-size: 11.5px;
  color: var(--sub);
  margin-top: 12px;
}

/* ============================================================
   表单弹窗（新建/编辑清单、施工项目、空间）
   —— 1920 屏下用更宽的弹窗 + 三列网格
   ============================================================ */
.modal-box.ql-modal { width: min(1080px, 96vw); max-width: calc(100vw - 80px); }
/* 4 列网格：1920 屏下每列 ~290px，字段刚好一行填满不浪费 */
.modal-box.ql-modal .form-grid.ql-form-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px 18px;
}
.modal-box.ql-modal .form-item.full { grid-column: 1 / -1; }
/* 占 2 列：让「费率」这种只有 2 项的分组也能填满一行 */
.modal-box.ql-modal .form-item.ql-span2 { grid-column: span 2; }
.modal-box.ql-modal .form-item label {
  font-size: 14px;
  font-weight: 500;
  color: var(--muted);
  display: block;
}
.modal-box.ql-modal .form-item input,
.modal-box.ql-modal .form-item select,
.modal-box.ql-modal .form-item textarea {
  padding: 9px 11px;
  font-size: 15px;
  border-radius: 7px;
}
.modal-box.ql-modal .form-item .hint {
  font-size: 13px;
  color: var(--sub);
  line-height: 1.5;
}
/* 分组标题：把表头分成几块，看起来不挤 */
.ql-form-sec {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 4px;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: .5px;
}
.ql-form-sec::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line-soft);
}
.ql-form-sec:first-child { margin-top: 0; }

/* ---------- 响应式 ---------- */
@media (max-width: 1600px) {
  .ql-layout { grid-template-columns: 220px minmax(0, 1fr); gap: 12px; }
}
@media (max-width: 1360px) {
  .ql-layout { grid-template-columns: 200px minmax(0, 1fr); }
  .modal-box.ql-modal { width: 980px; }
  .modal-box.ql-modal .form-grid.ql-form-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 1100px) {
  .ql-layout { grid-template-columns: 1fr; }
  .ql-col-tree .card-body { max-height: 260px; }
  /* 汇总面板挪到下面，横向排开 */
}
@media (max-width: 900px) {
  .modal-box.ql-modal { width: calc(100vw - 32px); }
  .modal-box.ql-modal .form-grid.ql-form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
  .modal-box.ql-modal .form-grid.ql-form-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   空白新增行（点「+ 新增施工项目」后插入的那一行）
   ============================================================ */
.ql-blankrow td {
  background: #fffdf3;
}
.ql-blankrow .ql-blank-name {
  border-color: #f0c36d;
  box-shadow: 0 0 0 2px rgba(240, 195, 109, 0.18);
}
.ql-blankrow .ql-blank-cancel {
  color: #b06a00;
}

/* ============================================================
   导出：打印区域（PDF）
   —— 平时隐藏，导出时填充内容再打印
   ============================================================ */
#qlPrintArea {
  display: none;
}

/* ============================================================
   打印预览层（2026-10-29 22:45）
   —— 在应用内先看效果，右上角有 × 关闭按钮 + 「打印」按钮
   —— 浏览器原生打印预览是系统 UI，加不了按钮，所以自己做一层
   —— 注意：这一层只在【屏幕】显示，打印时必须整体隐藏
   ============================================================ */
.ql-pv {
  position: fixed;
  inset: 0;
  z-index: 9000;
  background: #E9EBEE;
  display: flex;
  flex-direction: column;
}
.ql-pv.hidden {
  display: none !important;
}
/* 顶部工具条 */
.ql-pv-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 16px;
  background: #fff;
  border-bottom: 1px solid var(--line);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
}
.ql-pv-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.ql-pv-hint {
  font-size: 12px;
  font-weight: 400;
  color: var(--muted);
}
.ql-pv-acts {
  display: flex;
  align-items: center;
  gap: 10px;
}
.ql-pv-dir {
  width: auto;
  padding: 5px 8px;
}
/* ★ 右上角关闭按钮（叉号）*/
.ql-pv-close {
  width: 30px;
  height: 30px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
  color: var(--muted);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.ql-pv-close:hover {
  background: #FEF2F2;
  border-color: #FCA5A5;
  color: #DC2626;
}
/* 预览主体：居中纸张 */
.ql-pv-body {
  flex: 1 1 auto;
  overflow: auto;
  padding: 20px;
}
.ql-pv-paper {
  width: 100%;
  max-width: 1040px;
  margin: 0 auto;
  background: #fff;
  padding: 14mm 12mm;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.12);
  border-radius: 2px;
  color: #000;
  font-family: "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", "SimSun", serif;
  font-size: 10.5pt;
  line-height: 1.6;
}
/* 窄版（纵向纸）时纸张更窄 */
.ql-pv.narrow .ql-pv-paper {
  max-width: 700px;
}
/* 预览层里也要有打印的表格样式（打印时的样式在 @media print 里，
   屏幕预览时看不到，所以这里把关键样式提出来共用） */
.ql-pv-paper .pr-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 9pt;
  table-layout: fixed;
  border: 0.5pt solid #000;
}
.ql-pv-paper .pr-table th,
.ql-pv-paper .pr-table td {
  border: 0.5pt solid #000;
  padding: 1.2mm 1mm;
  vertical-align: middle;
  word-break: break-word;
  /* ★★ 2026-10-30 12:00 修「PDF 工艺做法文字严重溢出」
     style.css 全局 `th, td { white-space: nowrap }` 会打到打印表 →
     overflow-wrap:anywhere 在 nowrap 下一行都不换 → 长文本单行冲出纸外。
     这里必须显式恢复 normal（打印段同款修复见 @media print）。 */
  white-space: normal;
}
.ql-pv-paper .pr-table th {
  font-weight: 700;
  text-align: center;
  background: #F5F5F5;
}
.ql-pv-paper .pr-table tr.pr-space td {
  font-weight: 700;
  background: #fff;
}
.ql-pv-paper .pr-table tr.pr-space-sub td {
  font-weight: 600;
  font-size: 8.6pt;
  background: #fff;
}
.ql-pv-paper .pr-table tr.pr-space-sub td:nth-child(2) {
  padding-left: 4mm;
}
.ql-pv-paper .pr-table tr.pr-sub td {
  font-weight: 700;
  border-top-width: 0.9pt;
  border-top-style: solid;
  border-top-color: #000;
}
.ql-pv-paper .pr-table tbody td:nth-child(3) {
  text-align: left;
}
.ql-pv-paper .pr-table tbody td:first-child {
  text-align: center;
  color: #333;
  font-size: 8.2pt;
}
.ql-pv-paper .pr-table tbody td:nth-child(8),
.ql-pv-paper .pr-table tbody td:nth-child(9) {
  text-align: left;
  word-break: break-word;
  overflow-wrap: anywhere;
  line-height: 1.4;
}
.ql-pv-paper .pr-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  word-break: keep-all;
  overflow-wrap: break-word;
  padding-left: 1.5mm !important;
}
.ql-pv-paper .pr-sum {
  width: 100%;
  border-collapse: collapse;
  font-size: 10.5pt;
  border: 0.5pt solid #000;
}
.ql-pv-paper .pr-sum th,
.ql-pv-paper .pr-sum td {
  border: 0.5pt solid #000;
  padding: 1.4mm 2.5mm;
  vertical-align: middle;
  white-space: normal; /* 同上：防全局 nowrap 让区域名/大写金额溢出 */
}
.ql-pv-paper .pr-sum th {
  font-weight: 700;
  text-align: center;
  background: #F2F2F2;
}
.ql-pv-paper .pr-sum .lbl {
  text-align: right;
  letter-spacing: 0.5px;
}
.ql-pv-paper .pr-sum .amt {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  white-space: nowrap;
  width: 22%;
}
.ql-pv-paper .pr-sum tr.pr-sum-group td {
  background: #F2F2F2;
  font-weight: 700;
  text-align: left;
  letter-spacing: 1px;
}
/* ★ 汇总分组标题可点击改名（2026-10-30 12:00）：悬停出现虚线下划线提示 */
.ql-pv-paper .pr-sum tr.pr-sum-group td.pr-sum-group-label:hover {
  text-decoration: underline dashed #666;
  text-underline-offset: 3px;
}
.ql-pv-paper .pr-sum tr.pr-sum-group td.pr-sum-group-label[contenteditable="true"] {
  outline: 2px solid #4A78C2;
  outline-offset: -2px;
  background: #FFFDF2;
}
.ql-pv-paper .pr-sum tr.pr-sum-total td {
  font-weight: 700;
  font-size: 11pt;
  padding: 1.8mm 2.5mm;
}
.ql-pv-paper .pr-sum tr.pr-sum-total .cap {
  text-align: right;
  letter-spacing: 1px;
  padding-right: 4mm;
}
.ql-pv-paper .pr-sum tr.pr-sum-sub td.lbl {
  padding-right: 6mm;
  font-weight: 400;
}
.ql-pv-paper .pr-sum tr.pr-sum-sub td.amt {
  font-weight: 400;
}
.ql-pv-paper .pr-doc-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  border-bottom: 0.8pt solid #000;
  padding-bottom: 1.5mm;
  margin-bottom: 1mm;
}
.ql-pv-paper .pr-doc-title {
  font-size: 12pt;
  font-weight: 700;
  letter-spacing: 2px;
}
.ql-pv-paper .pr-doc-meta {
  font-size: 9pt;
  color: #333;
  letter-spacing: 0.5px;
}
.ql-pv-paper .pr-sec {
  position: relative;
  font-size: 13.5pt;
  font-weight: 700;
  color: #000;
  letter-spacing: 1.5px;
  padding-bottom: 1mm;
  margin: 4.5mm 0 2.2mm;
  border-bottom: 0.6pt solid #000;
}
.ql-pv-paper .pr-sec::before {
  content: "";
  position: absolute;
  left: 0;
  bottom: -0.7pt;
  width: 26mm;
  height: 1.8pt;
  background: #000;
}
.ql-pv-paper .pr-info {
  width: 100%;
  border-collapse: collapse;
  font-size: 10.5pt;
}
.ql-pv-paper .pr-info td {
  padding: 0.5mm 0;
  border: none;
  vertical-align: top;
  white-space: normal; /* 防全局 nowrap：工程地址等长值要能换行 */
}
.ql-pv-paper .pr-info .k {
  width: 26mm;
  text-align: right;
  padding-right: 2mm;
  white-space: nowrap;
  letter-spacing: 1px;
}
.ql-pv-paper .pr-info .v {
  width: 44%;
  text-align: left;
  padding-right: 6mm;
}
.ql-pv-paper .pr-info .k2 {
  width: 24mm;
  text-align: right;
  padding-right: 2mm;
  white-space: nowrap;
  letter-spacing: 1px;
}
.ql-pv-paper .pr-info .v2 {
  text-align: left;
}
.ql-pv-paper .pr-remark {
  margin-top: 3mm;
  font-size: 9.5pt;
  line-height: 1.7;
}
.ql-pv-paper .pr-sign {
  margin-top: 9mm;
  display: flex;
  justify-content: space-between;
  gap: 8mm;
  font-size: 10pt;
}
.ql-pv-paper .pr-sign-col {
  flex: 1;
  display: flex;
  align-items: flex-end;
  white-space: nowrap;
}
.ql-pv-paper .pr-sign-line {
  flex: 1;
  border-bottom: 0.6pt solid #000;
  margin-left: 2mm;
  height: 5.5mm;
}
.ql-pv-paper .pr-foot {
  margin-top: 4mm;
  font-size: 8pt;
  color: #666;
  text-align: center;
  letter-spacing: 0.5px;
  border-top: 0.5pt solid #999;
  padding-top: 1.5mm;
}
/* 窄版预览时的字号 */
.ql-pv.narrow .ql-pv-paper .pr-sec { font-size: 11pt; margin: 3mm 0 1.8mm; }
.ql-pv.narrow .ql-pv-paper .pr-sec::before { width: 20mm; height: 1.5pt; }
.ql-pv.narrow .ql-pv-paper .pr-info { font-size: 8.6pt; }
.ql-pv.narrow .ql-pv-paper .pr-info .k { width: 22mm; }
.ql-pv.narrow .ql-pv-paper .pr-info .k2 { width: 21mm; }
.ql-pv.narrow .ql-pv-paper .pr-table { font-size: 7.2pt; }
.ql-pv.narrow .ql-pv-paper .pr-table th { font-size: 7.2pt; }
.ql-pv.narrow .ql-pv-paper .pr-table th,
.ql-pv.narrow .ql-pv-paper .pr-table td { padding: 0.9mm 0.7mm; }
.ql-pv.narrow .ql-pv-paper .pr-sum { font-size: 8.6pt; }
.ql-pv.narrow .ql-pv-paper .pr-sum th,
.ql-pv.narrow .ql-pv-paper .pr-sum td { padding: 1mm 1.6mm; }
.ql-pv.narrow .ql-pv-paper .pr-sum tr.pr-sum-total td { font-size: 9pt; }
.ql-pv.narrow .ql-pv-paper .pr-remark { font-size: 8.2pt; }
.ql-pv.narrow .ql-pv-paper .pr-sign { margin-top: 6mm; font-size: 8.4pt; }
.ql-pv.narrow .ql-pv-paper .pr-foot { font-size: 7pt; }

/* ============================================================
   PDF 打印样式（2026-10-29 22:35 重做 · 黑白工程文档风格）
   —— 参照用户提供的标准报价单样张：
      ① 章节标题：加粗大字 + 贯穿细线 + 左端粗黑短段
      ② 工程概况：键值对齐排版（标签定宽、值紧跟），不是网格表
      ③ 费用汇总：两列「费用项目 | 金额」，标签右对齐
      ④ 全黑白、无色块、无斑马纹 —— 接近 Word 打印稿
   ============================================================ */
@media print {
  /* ★★★ 绝对不能在 @page 里写 size:！
     一旦出现 `size: A4 landscape`，Chrome 会用它覆盖打印对话框的
     「纵向 / 横向」单选 → 用户在对话框里怎么点都没反应。
     这里只写页边距，纸张与方向全部交给打印对话框。 */
  @page {
    margin: 12mm 10mm 10mm;
  }

  html, body {
    background: #fff !important;
    height: auto !important;
    min-height: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    overflow: visible !important;
    color: #000 !important;
    font-family: "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", "SimSun", serif !important;
    font-size: 10.5pt;
    line-height: 1.6;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* 隐藏整个应用界面（#appView 才是真正的容器）*/
  #appView,
  #appView *,
  .page-head,
  .ql-guide,
  .ql-sum,
  .ql-layout,
  /* ★ 2026-10-29 23:35 新增的工作区容器（报价器大栏在这一层里）*/
  .ql-work,
  .toast,
  #mask,
  #modal,
  #confirm,
  .ql-unit-menu,
  .login-wrap,
  .modal,
  header,
  .sidebar,
  .topbar,
  .menu {
    display: none !important;
  }

  /* ★ 预览层必须整体隐藏 —— 否则预览内容会被重复打印一份
     （预览层是 fixed 定位的，里面已经有完整报表） */
  #qlPreview,
  .ql-pv,
  .ql-pv-bar,
  .ql-pv-body,
  .ql-pv-paper {
    display: none !important;
  }

  /* 打印区回到正常文档流（absolute 会撑不开 body 高度 → 分页错乱）*/
  #qlPrintArea {
    display: block !important;
    position: static !important;
    width: 100% !important;
    padding: 0 !important;
    margin: 0 !important;
    background: #fff !important;
    color: #000 !important;
    overflow: visible !important;
    page-break-before: avoid;
  }

  /* ==========================================================
     ① 文档抬头（顶部横线 + 单据名 + 编号日期）
     ========================================================== */
  .pr-doc-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    border-bottom: 0.8pt solid #000;
    padding-bottom: 1.5mm;
    margin-bottom: 1mm;
  }
  .pr-doc-title {
    font-size: 12pt;
    font-weight: 700;
    letter-spacing: 2px;
  }
  .pr-doc-meta {
    font-size: 9pt;
    color: #333;
    letter-spacing: 0.5px;
  }
  .pr-doc-line {
    display: none;
  }

  /* ==========================================================
     ② 章节标题：加粗大字 + 贯穿细线 + 左端粗黑短段
     ========================================================== */
  .pr-sec {
    position: relative;
    font-size: 13.5pt;
    font-weight: 700;
    color: #000;
    letter-spacing: 1.5px;
    padding-bottom: 1mm;
    margin: 4.5mm 0 2.2mm;
    border-bottom: 0.6pt solid #000;
    page-break-after: avoid;
  }
  .pr-sec::before {
    content: "";
    position: absolute;
    left: 0;
    bottom: -0.7pt;
    width: 26mm;
    height: 1.8pt;
    background: #000;
  }
  .pr-sec:first-child {
    margin-top: 3mm;
  }

  /* ==========================================================
     ③ 工程概况：键值对齐（标签定宽、值紧跟）
     ========================================================== */
  .pr-info {
    width: 100%;
    border-collapse: collapse;
    font-size: 10.5pt;
    page-break-inside: avoid;
  }
  .pr-info td {
    padding: 0.5mm 0;
    border: none;
    vertical-align: top;
    white-space: normal; /* 防全局 nowrap：地址等长值要换行 */
  }
  /* 标签：定宽、右对齐、字距拉开（甲　　方：） */
  .pr-info .k {
    width: 26mm;
    text-align: right;
    padding-right: 2mm;
    white-space: nowrap;
    letter-spacing: 1px;
    color: #000;
  }
  /* 值 */
  .pr-info .v {
    width: 44%;
    text-align: left;
    padding-right: 6mm;
    word-break: break-word;
  }
  /* 第二组的标签（电　　话：/ 工程面积：）*/
  .pr-info .k2 {
    width: 24mm;
    text-align: right;
    padding-right: 2mm;
    white-space: nowrap;
    letter-spacing: 1px;
  }
  .pr-info .v2 {
    text-align: left;
    word-break: break-word;
  }
  /* 整行独占的项（乙方地址/工程名称/工程地址）*/
  .pr-info .v-wide {
    width: auto;
    padding-right: 0;
  }

  /* ==========================================================
     ④ 明细表：黑白细线，Word 表格观感
     ========================================================== */
  .pr-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 9pt;
    table-layout: fixed;
    /* ★ 表格自身也画一圈外框 —— collapse 模式下会与单元格边框合并，
       任何一行缺边框都不会让表格「缺边」 */
    border: 0.5pt solid #000;
  }
  .pr-table th,
  .pr-table td {
    border: 0.5pt solid #000;
    padding: 1.2mm 1mm;
    vertical-align: middle;
    word-break: break-word;
    /* ★★ 2026-10-30 12:00 修「PDF 工艺做法文字严重溢出」：
       style.css 全局 `th, td { white-space: nowrap }` 打进打印表 →
       长文本一行不换直接冲出纸外。必须显式恢复 normal。 */
    white-space: normal;
  }
  /* 表头：加粗 + 居中，无底色 */
  .pr-table th {
    font-weight: 700;
    text-align: center;
    color: #000;
    font-size: 9pt;
    letter-spacing: 0.3px;
  }
  /* 区域行：加粗，无色条 */
  .pr-table tr.pr-space td {
    font-weight: 700;
    background: #fff !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .pr-table tr.pr-space td:first-child {
    text-align: center;
  }
  /* 二级区域：缩进 + 常规字重 */
  .pr-table tr.pr-space-sub td {
    font-weight: 600;
    font-size: 8.6pt;
    background: #fff !important;
  }
  .pr-table tr.pr-space-sub td:nth-child(2) {
    padding-left: 4mm;
  }
  /* 小计行：加粗 + 上边框加粗 */
  .pr-table tr.pr-sub td {
    font-weight: 700;
    /* ★★ 千万不能用 `border-top:` 简写！
       简写会把 border-bottom 重置为 0 → 小计行恰好是表格最后一行时，
       整张表就**缺一条下边框**（用户 2026-10-29 反馈「表格不完整，缺少横线」）。
       只改 border-top-width/style/color，保留其它三边的边框。 */
    border-top-width: 0.9pt;
    border-top-style: solid;
    border-top-color: #000;
    background: #fff !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .pr-table tr.pr-sub td.pr-num {
    font-weight: 700;
  }
  /* 数字列 */
  .pr-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    word-break: keep-all;
    overflow-wrap: break-word;
    padding-left: 1.5mm !important;
  }
  .pr-strong {
    font-weight: 700;
  }
  .pr-r {
    text-align: right;
  }
  .pr-center {
    text-align: center;
  }
  /* 项目名称列：左对齐 */
  .pr-table tbody td:nth-child(3) {
    text-align: left;
  }
  /* 序号列 */
  .pr-table tbody td:first-child {
    text-align: center;
    color: #333;
    font-size: 8.2pt;
  }
  /* 规格 / 工艺说明：长句要能换行 */
  .pr-table tbody td:nth-child(8),
  .pr-table tbody td:nth-child(9) {
    text-align: left;
    word-break: break-word;
    overflow-wrap: anywhere;
    line-height: 1.4;
  }
  /* 表头跨页重复 */
  .pr-table thead {
    display: table-header-group;
  }
  .pr-table tr {
    page-break-inside: avoid;
  }

  /* ==========================================================
     ⑤ 工程费用汇总：两列「费用项目 | 金额」，标签右对齐
     ========================================================== */
  .pr-sum {
    width: 100%;
    border-collapse: collapse;
    font-size: 10.5pt;
    page-break-inside: avoid;
    /* 同上：表格自身外框兜底 */
    border: 0.5pt solid #000;
  }
  .pr-sum th,
  .pr-sum td {
    border: 0.5pt solid #000;
    padding: 1.4mm 2.5mm;
    vertical-align: middle;
    white-space: normal; /* 防全局 nowrap：区域名/大写金额要能换行 */
  }
  .pr-sum th {
    font-weight: 700;
    text-align: center;
    background: #F2F2F2 !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
    font-size: 10.5pt;
    letter-spacing: 1px;
  }
  /* 标签列：右对齐 */
  .pr-sum .lbl {
    text-align: right;
    letter-spacing: 0.5px;
  }
  /* 金额列：右对齐 + 加粗 */
  .pr-sum .amt {
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    white-space: nowrap;
    width: 22%;
  }
  /* 分组小标题（各区域金额）*/
  /* 汇总表最后一行必须保留完整下边框 */
  .pr-sum tbody tr:last-child td {
    border-bottom-width: 0.5pt;
    border-bottom-style: solid;
    border-bottom-color: #000;
  }
  .pr-sum tr.pr-sum-group td {
    background: #F2F2F2 !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
    font-weight: 700;
    text-align: left;
    letter-spacing: 1px;
  }
  /* 合计行 */
  .pr-sum tr.pr-sum-total td {
    font-weight: 700;
    font-size: 11pt;
    padding: 1.8mm 2.5mm;
  }
  .pr-sum tr.pr-sum-total .cap {
    /* ★ 样张：大写金额在标签列里**右对齐**（紧贴金额列），不是左对齐 */
    text-align: right;
    letter-spacing: 1px;
    padding-right: 4mm;
  }
  /* 区域小计行（缩进）*/
  .pr-sum tr.pr-sum-sub td.lbl {
    padding-right: 6mm;
    font-weight: 400;
  }
  .pr-sum tr.pr-sum-sub td.amt {
    font-weight: 400;
  }

  /* ==========================================================
     ⑥ 备注 + 签字 + 页脚
     ========================================================== */
  .pr-remark {
    margin-top: 3mm;
    font-size: 9.5pt;
    line-height: 1.7;
    color: #000;
    page-break-inside: avoid;
    text-indent: 0;
  }
  .pr-remark b {
    letter-spacing: 1px;
  }
  .pr-sign {
    margin-top: 9mm;
    display: flex;
    justify-content: space-between;
    gap: 8mm;
    page-break-inside: avoid;
    font-size: 10pt;
  }
  .pr-sign-col {
    flex: 1;
    display: flex;
    align-items: flex-end;
    white-space: nowrap;
  }
  .pr-sign-line {
    flex: 1;
    border-bottom: 0.6pt solid #000;
    margin-left: 2mm;
    height: 5.5mm;
  }
  .pr-foot {
    margin-top: 4mm;
    font-size: 8pt;
    color: #666;
    text-align: center;
    letter-spacing: 0.5px;
    border-top: 0.5pt solid #999;
    padding-top: 1.5mm;
  }

  /* ==========================================================
     ⑦ 窄版（纵向纸）适配
     ========================================================== */
  body.ql-print-narrow .pr-doc-title { font-size: 10pt; letter-spacing: 1px; }
  body.ql-print-narrow .pr-doc-meta { font-size: 8pt; }
  body.ql-print-narrow .pr-sec { font-size: 11pt; margin: 3mm 0 1.8mm; }
  body.ql-print-narrow .pr-sec::before { width: 20mm; height: 1.5pt; }
  body.ql-print-narrow .pr-info { font-size: 8.6pt; }
  body.ql-print-narrow .pr-info .k { width: 22mm; }
  body.ql-print-narrow .pr-info .k2 { width: 21mm; }
  body.ql-print-narrow .pr-table { font-size: 7.2pt; }
  body.ql-print-narrow .pr-table th { font-size: 7.2pt; }
  body.ql-print-narrow .pr-table th,
  body.ql-print-narrow .pr-table td { padding: 0.9mm 0.7mm; }
  body.ql-print-narrow .pr-table tbody td:first-child { font-size: 6.6pt; }
  /* ★★ 2026-10-30 12:00 列宽重排（与 Excel 导出同思路）：
     其它列以「单行放得下」为准、能窄则窄，省下的宽度全部让给工艺做法列。
     内联基准（宽版）：序号4.5 施工空间10 项目名称13 数量5 单位4.5
                       单价9 合计10 规格8.5 工艺做法36 = 100%
     窄版覆盖（合计仍= 100%）：数量 6 / 单价 9.5 / 工艺做法 34
     （旧版窄版各列合计 101% 且工艺做法只有 23% —— 已废弃） */
  body.ql-print-narrow .pr-table th:nth-child(4),
  body.ql-print-narrow .pr-table td:nth-child(4) { width: 6% !important; }
  body.ql-print-narrow .pr-table th:nth-child(6),
  body.ql-print-narrow .pr-table td:nth-child(6) { width: 9.5% !important; }
  body.ql-print-narrow .pr-table th:nth-child(9),
  body.ql-print-narrow .pr-table td:nth-child(9) { width: 34% !important; }
  body.ql-print-narrow .pr-sum { font-size: 8.6pt; }
  body.ql-print-narrow .pr-sum th,
  body.ql-print-narrow .pr-sum td { padding: 1mm 1.6mm; }
  body.ql-print-narrow .pr-sum tr.pr-sum-total td { font-size: 9pt; }
  body.ql-print-narrow .pr-remark { font-size: 8.2pt; }
  body.ql-print-narrow .pr-sign { margin-top: 6mm; font-size: 8.4pt; }
  body.ql-print-narrow .pr-foot { font-size: 7pt; }
}

/* ============================================================
   列表页 · 操作列（导出入口必须一眼能看到，不能被挤出屏幕）
   ============================================================ */
/* ① 操作列按钮之间要有间距 —— .btn-link 默认 padding:0，
      四个链接会挤成一团「编辑导出Excel导出PDF删除」 */
.ql-list-act {
  display: flex;
  align-items: center;
  gap: 12px;
}
/* ② 表格别被 nowrap 撑太宽 → 操作列固定在右侧且不被挤压 */
.ql-list-table {
  table-layout: fixed;
  width: 100%;
  /* ★ 表格最小宽度：不够就横向滚动，而不是把列压扁
     （用户 2026-10-29 反馈：操作列的「编辑/Excel/PDF/删除」被挤到换行、
       整张表挤出一条横向滚动条，主滚动条划不动）
     ★ 各固定列合计 = 74+86+108+116+210 = 594px
       → 最小宽度给 860px → 工程名称列至少还有 266px，够显示项目名+甲方 */
  min-width: 860px;
}
.ql-list-table th,
.ql-list-table td {
  white-space: normal;
  /* ★ 内容不换行时用省略号，避免把行撑高 */
  overflow: hidden;
  text-overflow: ellipsis;
  /* ★ 行高压缩：默认 padding 10px + border-spacing 2px → 行高 60px，
       一屏放不下几行。改成 7px + border-spacing 0 → 行高约 40px */
  padding: 7px 12px;
  line-height: 1.35;
}
/* 表格不要额外间距（table 元素默认 border-spacing: 2px，白白多出 4px） */
.ql-list-table {
  border-spacing: 0;
}
/* 表头紧凑一点 */
.ql-list-table th {
  padding: 9px 12px;
  white-space: nowrap;
}
/* ★ 操作列里的按钮不换行 —— 否则一行里挤成 2-3 行，表格高度暴涨 */
.ql-list-act {
  flex-wrap: nowrap;
  white-space: nowrap;
  /* ★ 操作列不许被压缩 —— 宽度不够时表格横向滚，而不是压按钮 */
  justify-content: flex-end;
}
/* 日期、金额、状态：不换行 */
.ql-list-table td:nth-child(2),
.ql-list-table td:nth-child(3),
.ql-list-table td:nth-child(4),
.ql-list-table td:nth-child(5) {
  white-space: nowrap;
}
/* 工程名称：允许换行（长名字），但最多两行 */
.ql-list-table td:nth-child(1) {
  max-width: 0;
}
.ql-list-table td:nth-child(1) .td-sub {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* ★ 2026-10-29 22:05 重排列宽
   原来：30/8/9/13/13/27  → 状态列只有 9% ≈ 65px，「已定稿」3个字放不下
        → 文字被截成「草稿··」/「已定稿」竖排 → 行高暴涨到 60px
   现在：给「状态」「更新时间」「操作」三个列足够的固定宽度，
        工程名称用剩余空间（自适应，最长） */
.ql-list-table th:nth-child(1) { width: auto; }   /* 工程名称 —— 自适应 */
.ql-list-table th:nth-child(2) { width: 74px; }   /* 场景 */
.ql-list-table th:nth-child(3) { width: 86px; }   /* 状态 —— 要放得下「已定稿」 */
.ql-list-table th:nth-child(4) { width: 108px; }  /* 合计金额 */
.ql-list-table th:nth-child(5) { width: 116px; }  /* 更新时间 —— 要放得下「2026-10-29 20:21」 */
.ql-list-table th:nth-child(6) { width: 210px; }   /* 操作 —— 编辑/Excel/PDF/删除 */
/* ③ 导出按钮做成胶囊样式，跟「编辑/删除」区分开 */
.ql-export-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #F7FAFF;
  color: var(--primary);
  font-size: 12px;
  white-space: nowrap;
  text-decoration: none;
}
.ql-export-btn:hover {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
  text-decoration: none;
}

/* ============================================================
   明细表 · 工艺说明列不能被压扁（2026-10-29 21:20）
   —— table-layout:fixed 下，自适应列会被浏览器压到接近 0
   —— 给「工艺做法及材料说明」列一个 min-width 下限
   ============================================================ */
.ql-items {
  /* ★★ 2026-10-30 00:05 修「回填后明细表变窄、右侧空出一大片」
     ⚠️⚠️ 根因（截图实测 + 算术反推确认）：
        我在 23:55 给表格加了 `min-width: 910px` 想防列被压扁，
        结果 **min-width 会覆盖 width:100%** →
        table-layout:fixed 下表格按 910px 渲染，而容器有 1250px →
        表格右侧空出 ~340px（截图实测：表格内容只到 x=1959，
        卡片白底却到 x=2596，差 632 截图px ≈ 355 CSS px）。
        反推验证：截图缩放比 3418/1920=1.78，表格实测 895 CSS px
                   ≈ min-width 的 910px ✅ 铁证。
     ✅ 正确做法（CSS 规范）：
        · **表格本身不设 min-width** → width:100% 永远撑满容器
        · 「不许被压扁」这件事交给**列的 min-width** 承担
          （第 8/9/10 列已各有 min-width）→ 列有下限，表格仍满宽
        · 容器窄到连列下限都放不下时，.table-wrap overflow-x:auto 横向滚动
          （这才是滚动条该出现的时候） */
  width: 100%;
  /* ❌ 不要再写 min-width —— 它会覆盖 width:100%，让表格不撑满 */
}
/* ★★★★ 2026-10-30 01:50 根治：列宽全部用【百分比】（合计 100%）
   —— 之前给每列写固定 px 的 min-width（40/76/200/…/60，合计 890px），
      在 2560 宽屏（容器 1522px）时实测**表格只画到 924px**（= 列宽和），
      右侧空出 600px（比例 0.607）—— 用户截图实测确认。
      根因是「固定 px 列宽 + width:100%」时，浏览器**不保证**
      把「列宽和 < 容器」的多余空间摊给列，表格可能就停在列宽和。
   —— ✅ 改成百分比后，table-layout:fixed 按【表格宽度】分配，
      表格撑满 → 各列等比放大，**永远不留白**；
      表格被压窄 → 各列一起等比缩小，谁也不塌成 0。
   —— 下面这些 min-width 只作为「极窄容器时的兜底」，
      数值远小于正常值，不会干扰百分比分配。 */
.ql-items td:nth-child(1), .ql-items th:nth-child(1) { min-width: 34px; }
.ql-items td:nth-child(2), .ql-items th:nth-child(2) { min-width: 56px; }
.ql-items td:nth-child(3), .ql-items th:nth-child(3) { min-width: 120px; }
.ql-items td:nth-child(4), .ql-items th:nth-child(4) { min-width: 40px; }
.ql-items td:nth-child(5), .ql-items th:nth-child(5) { min-width: 38px; }
.ql-items td:nth-child(6), .ql-items th:nth-child(6) { min-width: 50px; }
.ql-items td:nth-child(7), .ql-items th:nth-child(7) { min-width: 52px; }
/* 规格列（8）：窄容器时别把输入框压没 */
.ql-items td:nth-child(8),
.ql-items th:nth-child(8) {
  min-width: 72px;
}
/* 工艺说明列（9）：这是用户最在意的列，给足下限 */
.ql-items td:nth-child(9),
.ql-items th:nth-child(9) {
  min-width: 140px;
}
/* 两个输入框自身的最小宽度（父列再窄也白搭）
   —— ⚠️ 2026-10-30 01:55 修正：列宽改百分比后，输入框要**跟着列宽走**
      （width:100%），之前写死的 min-width:120px 会让输入框
      永远只有 120px，列变宽了输入框也不变 → 看着还是"没变宽"。
      所以改成：width:100% + 只保留一个很小的 min-width 兜底。 */
.ql-items td:nth-child(8) .ql-cell-input,
.ql-items td:nth-child(9) .ql-cell-input {
  width: 100%;
  min-width: 0;
}
/* ★ 操作列（2026-10-29 23:55，00:40 定稿，01:50 改百分比）
   —— 给足宽度并**居中**，别让「删」字紧贴卡片右边框
   —— ⚠️ 这里**不能**再写 width: 60px！fixed 布局下
      td/th 的 width 会与 colgroup 的百分比打架（百分比列会被固定宽顶掉） */
.ql-items th:nth-child(10),
.ql-items td:nth-child(10) {
  min-width: 56px;
  text-align: center;
  padding-left: 4px;
  padding-right: 16px;
}
/* 表格整体右侧留一点白，不顶到卡片边框 */
.ql-items th:last-child,
.ql-items td:last-child {
  padding-right: 18px;
}
/* 「删」链接居中一点，别贴边 */
.ql-items td:nth-child(10) .btn-link {
  display: inline-block;
  padding: 0 4px;
}
/* ★ 明细表容器：表格撑满时正好；列下限超出时横向滚动 */
.ql-col-items .table-wrap {
  overflow-x: auto;
}

/* ============================================================
   PDF · 明细表下方的「各施工区域金额」小表（2026-10-29 21:30）
   —— 用户要求：一级区域金额行从明细表里挪到明细表下面
   ============================================================ */
.pr-sub-table {
  margin-top: 4mm;
  width: auto;
  min-width: 60%;
}
.pr-sub-table th {
  background: #EFEFEF !important;
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
  text-align: left;
  padding: 1.8mm 2mm;
  font-size: 9pt;
}
.pr-sub-table td {
  padding: 1.6mm 2mm;
  font-size: 9pt;
  border: 0.4pt solid #666;
}
.pr-sub-table tbody tr:last-child td {
  border-bottom: 0.4pt solid #666;
}

/* ============================================================
   报价器侧栏（2026-10-29 22:55；23:35 扩为右侧大栏）
   —— 右侧独立一栏：选产品 → 填参数 → 算价 → 单价自动回填明细表
   —— 宽度约 24vw（1920 屏 ≈ 460px），内部排版按「大栏」重排：
      标签更宽、字号更大、参数区自动两列。
   ============================================================ */
.ql-calc-hint {
  padding: 22px 8px;
  font-size: 13px;
  line-height: 1.9;
  color: var(--muted);
  text-align: center;
}
.ql-calc-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 11px;
}
.ql-calc-lb {
  flex: 0 0 84px;
  font-size: 13px;
  color: var(--muted);
  text-align: right;
}
.ql-calc-row .input {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 13.5px;
  padding: 8px 10px;
}
.ql-calc-unit {
  font-size: 13px;
  color: var(--muted);
  flex: 0 0 auto;
}
.ql-calc-params {
  margin: 6px 0 12px;
  padding: 12px 14px;
  background: var(--primary-soft);
  border: 1px solid #DBEAFE;
  border-radius: 10px;
  /* 大栏里参数自动分列（放不下就退成单列）
     ⚠️ 用 auto-fit：只有一个参数时（圆形产品只有「内径」）
        空轨道会被折叠 → 那一条自动占满整行，不会孤零零占半格 */
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px 16px;
}
.ql-calc-params:empty {
  display: none;
}
/* 内径那条是「下拉 + 输入」并排 → 必须占满整行 */
.ql-calc-params .q-param-wide {
  grid-column: 1 / -1;
}
.ql-calc-params .q-param {
  gap: 6px;
}
.ql-calc-params .q-param-label {
  font-size: 12.5px;
}
.ql-calc-params input,
.ql-calc-params select {
  font-size: 13.5px;
  padding: 8px 10px;
}
.ql-calc-params .q-param-hint {
  font-size: 11.5px;
  line-height: 1.6;
}
/* ★ 规格自动带入提示（2026-10-30 00:15）*/
.ql-calc-specsrc {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: -4px 0 11px;
  padding: 7px 11px;
  border-radius: 8px;
  background: #ECFDF5;
  border: 1px solid #A7F3D0;
  color: #065F46;
  font-size: 12.5px;
  line-height: 1.5;
}
.ql-calc-specsrc-i {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #10B981;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* 回填目标提示 */
.ql-calc-target {
  margin: 10px 0;
}
.ql-calc-tg {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 11px;
  border: 1px dashed var(--line);
  border-radius: 8px;
  background: #FCFCFD;
  font-size: 13px;
  color: var(--muted);
}
.ql-calc-tg.is-on {
  border-style: solid;
  border-color: #BFDBFE;
  background: var(--primary-soft);
  color: var(--text);
}
.ql-calc-tg-lb {
  flex: 0 0 auto;
  color: var(--muted);
}
.ql-calc-tg-empty {
  color: var(--muted);
}
.ql-calc-tg-x {
  margin-left: auto;
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  color: var(--muted);
  padding: 0 3px;
}
.ql-calc-tg-x:hover {
  color: #DC2626;
}
/* 算价按钮 */
.ql-calc-btn {
  width: 100%;
  justify-content: center;
  margin: 6px 0 12px;
  padding: 11px 14px;
  font-size: 14px;
  font-weight: 600;
}
/* 结果 */
.ql-calc-result {
  border-top: 1px solid var(--line-soft);
  padding-top: 12px;
}
.ql-calc-empty {
  padding: 12px 0;
  font-size: 13px;
  color: var(--muted);
  text-align: center;
}
.ql-calc-hero {
  padding: 14px 16px;
  border-radius: 10px;
  background: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);
  border: 1px solid #BFDBFE;
  margin-bottom: 11px;
}
.ql-calc-hero-lb {
  font-size: 12px;
  color: #64748B;
}
.ql-calc-hero-vl {
  font-size: 26px;
  font-weight: 700;
  color: #1D4ED8;
  letter-spacing: -0.5px;
  margin: 3px 0;
  font-variant-numeric: tabular-nums;
}
.ql-calc-hero-sub {
  font-size: 12.5px;
  color: #64748B;
}
/* 各合作路径比价 */
.ql-calc-paths {
  margin-bottom: 11px;
}
.ql-calc-path {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 11px;
  border: 1px solid var(--line);
  border-radius: 7px;
  font-size: 12.5px;
  margin-bottom: 6px;
  cursor: pointer;
  transition: border-color .12s, background .12s;
}
.ql-calc-path:hover {
  border-color: var(--primary);
  background: var(--primary-soft);
}
.ql-calc-path.is-on {
  border-color: var(--primary);
  background: var(--primary-soft);
  font-weight: 600;
}
.ql-calc-path b {
  font-variant-numeric: tabular-nums;
}
/* 回填成功提示 */
.ql-calc-filled:empty {
  display: none;
}
.ql-calc-ok {
  padding: 10px 12px;
  border-radius: 8px;
  background: #ECFDF5;
  border: 1px solid #A7F3D0;
  color: #065F46;
  font-size: 12.5px;
  line-height: 1.75;
}

/* ============================================================
   「报价表操作指南」弹窗（2026-10-29 23:35）
   —— 取代页面上那条占位的蓝色提示条
   ============================================================ */
.modal-box.ql-guide-modal {
  width: min(1080px, 96vw);
  max-width: calc(100vw - 60px);
}
.modal-box.ql-guide-modal .modal-body {
  padding: 18px 22px;
  max-height: 72vh;
  overflow-y: auto;
}
.ql-guide-doc {
  font-size: 13px;
  color: var(--text);
  line-height: 1.85;
}
.ql-guide-sec {
  padding: 12px 14px;
  margin-bottom: 12px;
  background: #FBFCFE;
  border: 1px solid var(--line-soft);
  border-radius: 10px;
}
.ql-guide-sec:last-of-type { margin-bottom: 0; }
.ql-guide-h {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--primary-d);
  margin-bottom: 6px;
  padding-left: 10px;
  border-left: 3px solid var(--primary);
  line-height: 1.5;
}
.ql-guide-sec ul {
  margin: 0;
  padding-left: 20px;
}
.ql-guide-sec li {
  margin-bottom: 4px;
}
.ql-guide-sec li::marker { color: var(--primary); }
.ql-guide-sec b { color: var(--primary-d); }
.ql-guide-sec kbd {
  display: inline-block;
  background: #fff;
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 4px;
  padding: 0 5px;
  font-size: 11px;
  font-family: inherit;
  color: var(--muted);
}
.ql-guide-tip {
  margin-top: 12px;
  padding: 10px 13px;
  border-radius: 9px;
  background: var(--primary-soft);
  border: 1px solid #BFDBFE;
  color: var(--primary-d);
  font-size: 12.5px;
}
@media (max-width: 760px) {
  .modal-box.ql-guide-modal { width: calc(100vw - 32px); }
}

/* ============================================================
   版本号标记（2026-10-30 01:55）
   —— 显示在页面右下角的小字，一眼看出浏览器跑的是哪一版
   —— 背景：连续两次「改了没生效」，根因是浏览器缓存旧 CSS
   ============================================================ */
.ql-build-mark {
  position: fixed;
  right: 10px;
  bottom: 8px;
  z-index: 5;
  font-size: 10px;
  line-height: 1.4;
  color: #94A3B8;
  background: rgba(255, 255, 255, .82);
  border: 1px solid var(--line-soft);
  border-radius: 5px;
  padding: 1px 6px;
  pointer-events: none;
  user-select: none;
  font-variant-numeric: tabular-nums;
}

/* ============================================================
   工程费用汇总 · 折叠标题栏（2026-10-30 09:50）
   需求：「把上面的汇总页折叠起来，太占屏幕，需要的时候可以打开」
   默认收起成一条标题栏（右侧带合计金额），点标题展开/收起。
   ============================================================ */
.ql-sum-head-bar {
  cursor: pointer;
  user-select: none;
}
.ql-sum-head-bar:hover { background: #F6F9FF; }
.ql-sum-fold-arrow {
  display: inline-block;
  width: 14px;
  color: var(--muted);
  font-size: 12px;
  transition: transform .15s ease;
}
.ql-sum-fold-total {
  margin-left: auto;
  display: flex;
  align-items: baseline;
  gap: 8px;
  color: var(--muted);
  font-size: 12px;
  white-space: nowrap;
}
.ql-sum-fold-total b {
  color: var(--primary);
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}

/* ============================================================
   产品选择弹窗（2026-10-30 10:30）
   需求：
     ① 明细表「项目名称」点进去 → 弹出产品选择菜单：
        产品类型（正圆类~圆角矩形）→ 产品清单 → 标准规格提示
        选标准规格 → 自动填标品单价；选自定义 → 产品名送报价器
     ② 报价器「项目名称」点进去 → 弹出对应产品和规格供选择
   ============================================================ */
.ql-pkr {
  position: fixed;
  z-index: 1300;
  width: 540px;
  max-width: calc(100vw - 20px);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 14px 44px rgba(15, 35, 95, .18);
  font-size: 13px;
  color: var(--ink, #1F2937);
  overflow: hidden;
  animation: qlPkrIn .12s ease;
}
@keyframes qlPkrIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}
.ql-pkr-head {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line-soft);
  background: #FAFBFD;
}
.ql-pkr-head-lb { font-size: 12px; color: var(--muted); margin-right: 2px; }
.ql-pkr-type {
  border: 1px solid var(--line);
  background: #fff;
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 12px;
  cursor: pointer;
  color: var(--ink, #1F2937);
}
.ql-pkr-type:hover { border-color: var(--primary); color: var(--primary); }
.ql-pkr-type.is-on {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.ql-pkr-body { display: flex; min-height: 180px; max-height: 320px; }
.ql-pkr-prods {
  width: 45%;
  overflow: auto;
  border-right: 1px solid var(--line-soft);
  padding: 6px;
}
.ql-pkr-prod {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  padding: 7px 9px;
  border-radius: 8px;
  cursor: pointer;
}
.ql-pkr-prod:hover { background: #F0F4FF; }
.ql-pkr-prod.is-on { background: var(--primary-soft); }
.ql-pkr-prod-nm { font-weight: 600; }
.ql-pkr-prod-pr {
  color: var(--muted);
  font-size: 12px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.ql-pkr-specs { flex: 1; overflow: auto; padding: 10px 12px; }
.ql-pkr-spec-name { font-weight: 700; margin-bottom: 2px; }
.ql-pkr-spec-t { font-size: 12px; color: var(--muted); margin-bottom: 8px; }
.ql-pkr-tiers { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.ql-pkr-tier {
  border: 1px solid var(--line);
  background: #fff;
  border-radius: 8px;
  padding: 5px 11px;
  font-size: 12.5px;
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.ql-pkr-tier:hover { border-color: var(--primary); color: var(--primary); background: #F5F8FF; }
.ql-pkr-tier-note { font-size: 11.5px; color: var(--muted); margin-top: 6px; }
.ql-pkr-custom {
  display: block;
  width: 100%;
  margin-top: 10px;
  border: 1px dashed var(--primary);
  background: var(--primary-soft);
  color: var(--primary-d);
  border-radius: 8px;
  padding: 7px 10px;
  font-size: 12.5px;
  cursor: pointer;
}
.ql-pkr-custom:hover { filter: brightness(.97); }
.ql-pkr-empty { color: var(--muted); padding: 22px 10px; text-align: center; font-size: 12.5px; }
.ql-pkr-hint {
  padding: 6px 10px;
  border-top: 1px solid var(--line-soft);
  background: #FAFBFD;
  color: var(--muted);
  font-size: 11.5px;
}

/* ============================================================
   明细表 · 列宽拖拽（2026-10-30 11:15，仿 Excel）
   th 右缘放一个拖拽把手，按住左右拖调列宽；
   列宽存 localStorage，下次打开沿用。
   ============================================================ */
.ql-items thead th { position: sticky; }
.ql-col-rz {
  position: absolute;
  top: 0;
  /* ⚠️ 必须在 th **内部**右缘（right:0），不能负值溢出到相邻 th ——
     每个 th 都是 position:sticky + z-index:2（独立层叠上下文），
     相邻 th 按 DOM 顺序画在本 th 溢出部分之上 → 溢出的把手
     会被命中测试判给相邻 th，真实鼠标点不到（2026-10-30 实测踩坑） */
  right: 0;
  width: 10px;
  height: 100%;
  cursor: col-resize;
  z-index: 6;
  user-select: none;
}
.ql-col-rz::after {
  content: "";
  position: absolute;
  right: 4px;
  top: 20%;
  width: 2px;
  height: 60%;
  background: transparent;
  border-radius: 2px;
  transition: background .12s ease;
}
.ql-col-rz:hover::after,
body.ql-col-resizing .ql-col-rz::after { background: var(--primary); }
/* 拖动时全局显示竖直调整光标，选中文本会干扰拖拽 → 全局禁选中 */
body.ql-col-resizing { cursor: col-resize; user-select: none; }
body.ql-col-resizing * { cursor: col-resize !important; }

/* ============================================================
   工艺做法 textarea（2026-10-30 11:15）
   ① 一行写全看全：列已加宽到 ~46.5%
   ② 字数超过列宽 → 自动增加行高，不隐藏任何字
   ============================================================ */
.ql-items textarea.ql-note-ta {
  width: 100%;
  min-width: 0;
  resize: none;
  overflow: hidden;
  min-height: 30px;
  line-height: 1.55;
  display: block;
  font-family: inherit;
  font-size: 13px;
  text-align: left;
  white-space: pre-wrap;
  word-break: break-all;
}

/* ============================================================
   操作列（第 10 列）缩窄（2026-10-30 11:15）
   只有一个「删」字 → 3.5% 足够，去掉大 padding
   ============================================================ */
.ql-items th:nth-child(10),
.ql-items td:nth-child(10) {
  min-width: 0;
  padding-left: 0;
  padding-right: 6px;
}
.ql-items th:last-child,
.ql-items td:last-child {
  padding-right: 8px;
}

/* ============================================================
   工艺做法 · 默认模板菜单（2026-10-30 11:15）
   点进「工艺做法及材料说明」弹出 3 套默认做法，点一条填入；
   填完可继续修改，也可完全自定义。
   ============================================================ */
.ql-note-menu {
  position: fixed;
  z-index: 1350;
  width: 460px;
  max-width: calc(100vw - 20px);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 14px 44px rgba(15, 35, 95, .18);
  font-size: 13px;
  overflow: hidden;
  animation: qlPkrIn .12s ease;
}
.ql-note-menu-h {
  padding: 8px 12px;
  border-bottom: 1px solid var(--line-soft);
  background: #FAFBFD;
  font-size: 12px;
  color: var(--muted);
}
.ql-note-menu-i {
  padding: 9px 12px;
  cursor: pointer;
  line-height: 1.55;
  border-bottom: 1px solid var(--line-soft);
}
.ql-note-menu-i:last-of-type { border-bottom: none; }
.ql-note-menu-i:hover { background: #F0F4FF; color: var(--primary-d); }
.ql-note-menu-i::before { content: "▸ "; color: var(--primary); font-weight: 700; }
.ql-note-menu-f {
  padding: 6px 12px;
  border-top: 1px solid var(--line-soft);
  background: #FAFBFD;
  font-size: 11.5px;
  color: var(--muted);
}

/* ============================================================
   列表页 · 批量管理（2026-10-30，与会员管理同款交互）
   ============================================================ */
/* 勾选列：窄、居中、不许被压缩 */
.ql-list-table th.ql-chk,
.ql-list-table td.ql-chk {
  width: 40px;
  min-width: 40px;
  max-width: 40px;
  text-align: center;
  padding: 7px 4px;
  overflow: visible;
}
.ql-list-table td.ql-chk input[type="checkbox"],
.ql-list-table th.ql-chk input[type="checkbox"] {
  width: 15px;
  height: 15px;
  cursor: pointer;
  accent-color: #2563eb;
}
/* 批量工具条：勾选后出现在表格上方 */
.ql-bulk-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 14px;
  margin-bottom: 10px;
  background: #eff6ff;
  border: 1px solid #bfdbfe;
  border-radius: 10px;
  font-size: 13px;
  animation: qlBulkIn 0.15s ease-out;
}
@keyframes qlBulkIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}
.ql-bulk-count {
  font-weight: 600;
  color: #1d4ed8;
  white-space: nowrap;
}
.ql-bulk-bar .btn-link {
  white-space: nowrap;
}
