/* 报价批单识别系统 —— 全局样式
   目标：内部管理系统，紧凑、清晰、信息密度高。 */

/* 设计令牌：色彩、字号、圆角、行高、阴影的唯一来源。
   取值刻意收窄（字号 4 档、圆角 3 档、行高 3 档、语义色四态各一个），界面的一致性靠它保证，
   不要在规则里再写裸色值和裸字号。 */
:root {
  /* 品牌与语义：success/warning/danger/info 全部由品牌绿一侧派生，不用库默认糖果色 */
  --qrs-brand: #2f6f5e;
  --qrs-brand-weak: #e8f1ee;
  --qrs-brand-on-dark: #4fb99a;
  --qrs-ok: #1f7a3d;
  --qrs-warn: #9c6a12;  /* 原 #a9741a 白底只有 4.04:1，12px 提示文字读着发虚 */
  --qrs-danger: #b0453a;
  --qrs-info: #4a6b80;   /* 低饱和蓝灰：留给「说明类」提示盒子；标签那一层另压回中性，见 .el-tag--info */

  /* 灰阶六档：面 / 次级面 / 分隔线 / 主文 / 次文 / 弱文 */
  --qrs-surface: #ffffff;
  --qrs-surface-2: #f7f8fa;
  --qrs-rule: #e3e6ea;
  --qrs-ink: #1f2329;
  --qrs-ink-2: #4a5259;
  --qrs-ink-3: #6b7280;       /* 弱文：12px 小字也要 ≥4.5:1（原 #8a919b 只有 3.18，读起来发糊） */

  /* 布局底色与侧栏（深底单独一档） */
  --qrs-bg: #f5f6f8;
  --qrs-sidebar: #1f2a2e;
  --qrs-sidebar-2: #2b3a3f;
  --qrs-sidebar-ink: #c9d2d5;

  /* 语义浅底：同色约 8%，不再各自调一个近似色 */
  --qrs-ok-bg: #eaf3ec;
  --qrs-warn-bg: #f7f0e4;
  --qrs-danger-bg: #f7ebe9;
  --qrs-info-bg: var(--qrs-surface-2);  /* 同上：整块浅底一律用次级面 */

  /* 尺度 */
  --fs-sm: 12px;      /* 次要说明、表头、标签 */
  --fs-body: 14px;    /* 正文、表格、表单 */
  --fs-title: 16px;   /* 页题、面板标题（配 600） */
  --fs-figure: 21px;  /* 统计数字、图标 */
  --r-sm: 4px;        /* 控件、标签、小容器 */
  --r-md: 6px;        /* 面板、卡片 */
  --r-lg: 10px;       /* 仅登录卡与抽屉 */
  --lh-tight: 1.4;    /* 表格、紧凑列表 */
  --lh-body: 1.6;     /* 正文 */
  --lh-loose: 1.8;    /* 说明段落 */
  --sh-1: 0 1px 2px rgba(31, 42, 46, .06);
  --sh-2: 0 8px 24px rgba(31, 42, 46, .14);

  /* Element Plus 覆写：主色阶、语义四态、文字/边框/圆角/阴影/字号 */
  --el-color-primary: var(--qrs-brand);
  --el-color-primary-light-3: #5d9384;
  --el-color-primary-light-5: #8bb3a8;
  --el-color-primary-light-7: #b9d2cb;
  --el-color-primary-light-8: #d0e1dc;
  --el-color-primary-light-9: var(--qrs-brand-weak);
  --el-color-primary-dark-2: #26594b;
  --el-color-success: var(--qrs-ok);
  --el-color-success-light-3: #62a277;
  --el-color-success-light-5: #8fbc9e;
  --el-color-success-light-7: #bcd7c5;
  --el-color-success-light-8: #d2e4d8;
  --el-color-success-light-9: var(--qrs-ok-bg);
  --el-color-warning: var(--qrs-warn);
  --el-color-warning-light-3: #c39e5f;
  --el-color-warning-light-5: #d4ba8c;
  --el-color-warning-light-7: #e5d5ba;
  --el-color-warning-light-8: #eee3d1;
  --el-color-warning-light-9: var(--qrs-warn-bg);
  --el-color-danger: var(--qrs-danger);
  --el-color-danger-light-3: #c87d75;
  --el-color-danger-light-5: #d8a29c;
  --el-color-danger-light-7: #e7c7c4;
  --el-color-danger-light-8: #efdad8;
  --el-color-danger-light-9: var(--qrs-danger-bg);
  --el-color-info: var(--qrs-info);
  --el-color-info-light-3: #7b8189;
  --el-color-info-light-5: #a9aeb5;
  --el-color-info-light-7: #c9ccd1;
  --el-color-info-light-8: #dcdee2;
  --el-color-info-light-9: #eef3f7;      /* 说明类提示盒子的浅底；批量条 / 当前行另用次级面 */
  --el-color-error: var(--qrs-danger);
  --el-color-error-light-9: var(--qrs-danger-bg);
  --el-text-color-primary: var(--qrs-ink);
  --el-text-color-regular: var(--qrs-ink-2);
  --el-text-color-secondary: var(--qrs-ink-3);
  --el-text-color-placeholder: #9aa1ab;   /* 占位符要浅于弱文，但不能浅到看不清（原同弱文一档） */
  --el-text-color-disabled: #a8aeb8;      /* 禁用态单独一档：不能跟着弱文一起变深，否则像可点 */
  --el-border-color: var(--qrs-rule);
  --el-border-color-light: var(--qrs-rule);
  --el-border-color-lighter: var(--qrs-rule);
  --el-fill-color-light: var(--qrs-surface-2);
  --el-fill-color-blank: var(--qrs-surface);
  --el-bg-color: var(--qrs-surface);
  --el-bg-color-overlay: var(--qrs-surface);
  --el-font-size-base: var(--fs-body);
  --el-border-radius-base: var(--r-sm);
  --el-border-radius-small: var(--r-sm);
  --el-tag-border-radius: var(--r-sm);
  --el-box-shadow: var(--sh-2);
  --el-box-shadow-light: var(--sh-1);
  --el-box-shadow-lighter: var(--sh-1);
}

* { box-sizing: border-box; }

html, body, #app {
  height: 100%;
  margin: 0;
  padding: 0;
}
/* 触摸设备：禁掉系统字体自动放大，减少点击延迟；整页不允许横向溢出 */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
html, body { overflow-x: hidden; }
button, .el-button, .el-menu-item, a { touch-action: manipulation; }

body {
  font-family: "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, sans-serif;
  font-size: var(--fs-body);
  color: var(--qrs-ink);
  background: var(--qrs-bg);
}

/* ------------------------------------------------------------ 启动占位 */
.boot-splash {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--qrs-ink-3);
}
.boot-title { font-size: var(--fs-title); color: var(--qrs-brand); font-weight: 600; }
.boot-tip { font-size: var(--fs-body); }

/* ------------------------------------------------------------ 登录页 */
/* 0.8.35（第 148 轮 C 组）：登录页去「AI 落地页」味——不再用 140° 渐变底、
   居中标题与 380px 卡片，改成纯底色 + 360px 左对齐卡片 + 1px 边框（卡片靠边界，不靠阴影）。 */
.login-wrap {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--qrs-bg);
}
.login-card {
  width: 360px;
  background: var(--qrs-surface);
  border: 1px solid var(--qrs-rule);
  border-radius: var(--r-md);
  padding: 24px 24px 24px;
  box-shadow: var(--sh-1);
}
.login-head { text-align: left; margin-bottom: 24px; }
.login-head h1 { font-size: var(--fs-title); margin: 0 0 6px; color: var(--qrs-ink); }
.login-head p { margin: 0; font-size: var(--fs-sm); color: var(--qrs-ink-3); }
.login-card .el-form-item { margin-bottom: 16px; }
.login-btn { width: 100%; }
.login-hint {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px dashed var(--qrs-rule);
  font-size: var(--fs-sm);
  color: var(--qrs-ink-3);
  line-height: var(--lh-loose);
}
.login-hint b { color: var(--qrs-ink); font-weight: 600; }
.login-hint code {
  background: var(--qrs-surface-2);
  padding: 4px 4px;
  border-radius: var(--r-sm);
  font-family: Consolas, Monaco, monospace;
}
.login-hint .hint-title { color: var(--qrs-warn); }

/* ------------------------------------------------------------ 主框架 */
.app-shell { height: 100%; display: flex; overflow: hidden; }

.app-aside {
  width: 196px;
  flex: 0 0 196px;
  background: var(--qrs-sidebar);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.app-brand {
  height: 54px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 16px;
  color: var(--qrs-surface);
  font-size: var(--fs-body);
  font-weight: 600;
  letter-spacing: .5px;
  border-bottom: 1px solid rgba(255,255,255,.08);
  white-space: nowrap;
}
.app-brand .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--qrs-brand-on-dark); flex: 0 0 8px;
}
.app-menu { flex: 1; border-right: none !important; background: transparent !important; padding: 6px 0; overflow-y: auto; }
.app-menu .el-menu-item { color: var(--qrs-sidebar-ink); height: 42px; line-height: 42px; font-size: var(--fs-body); }
.app-menu .el-menu-item:hover { background: var(--qrs-sidebar-2) !important; color: var(--qrs-surface); }
.app-menu .el-menu-item.is-active { background: var(--qrs-brand) !important; color: var(--qrs-surface); }
.app-menu .el-menu-item .el-icon { width: 18px; }
.app-body { flex: 1; display: flex; flex-direction: column; overflow: hidden; min-width: 0; }

.app-header {
  height: 54px;
  flex: 0 0 54px;
  background: var(--qrs-surface);
  border-bottom: 1px solid var(--qrs-rule);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
}
.app-header .header-left { display: flex; align-items: center; gap: 4px; min-width: 0; }
.app-header .page-title {
  font-size: var(--fs-title); font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 手机端汉堡按钮：桌面不显示（见文件末尾的断点段） */
.mobile-menu-btn { display: none; }
.app-aside-mask { display: none; }
.app-header .user-zone { display: flex; align-items: center; gap: 8px; }
.app-header .user-zone .who { font-size: var(--fs-sm); color: var(--qrs-ink-3); }
.app-header .user-zone .who b { color: var(--qrs-ink); font-size: var(--fs-body); }

.app-main {
  flex: 1;
  overflow: auto;
  padding: 12px 16px 24px;
  /* 预留滚动条槽位：列表条数变化导致滚动条出现/消失时，内容宽度不再变化，
     避免工具栏等元素跟着重排（点击筛选后“跳动”的常见成因）。手机端滚动条是浮层，无影响。 */
  scrollbar-gutter: stable;
}

/* ------------------------------------------------------------ 通用块 */
.panel {
  background: var(--qrs-surface);
  border: 1px solid var(--qrs-rule);
  border-radius: var(--r-md);
  padding: 12px 16px;
  margin-bottom: 12px;
}
.panel-title {
  font-size: var(--fs-title); font-weight: 600; margin: 0 0 12px;
  display: flex; align-items: center; gap: 6px;
}
/* 0.8.33（第 147 轮）：删掉面板标题前那根 3px 绿条——28 处同款装饰是纯装饰，
   层级交给 16px/600 与面板自身间距；面板已有 1px 边框，不再叠一层色块。 */
/* 0.8.6 概览页：标题右侧的操作按钮与说明；嵌入的报价记录列表不再套一层面板边框 */
.panel-title-ops { margin-left: auto; }
/* 0.8.20：标题行有两个以上操作按钮时（账号信息：展开/收起 + 修改个人信息 + 修改密码），
   每多一个 auto 外边距就把剩余空白多分一份，按钮被推到标题行两端；只让第一个吃掉空白 */
.panel-title-ops + .panel-title-ops { margin-left: 0; }
.panel-title-note { font-weight: 400; }

.panel.is-embedded {
  background: transparent; border: 0; border-radius: 0; padding: 0; margin-bottom: 0;
}
.toolbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 12px;
}
.toolbar .spacer { flex: 1; }
/* 「扫描服务器输入目录 / 立即处理识别队列」这两个按钮（0.8.37）：原来贴左、又是默认白底，
   用户反馈「没居中、不明显」。按钮单独一行居中并给底色，原来跟在按钮右边的说明挪到下方。 */
.toolbar.scan-actions { justify-content: center; }
.scan-hint { margin: 0 0 12px; font-size: var(--fs-sm); line-height: 1.7; text-align: center; }

.filter-grid {
  /* 第 4 项：flex 定宽排布，下拉按内容长度收窄，一行放下更多筛选项 */
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
}
.filter-grid .fg-keyword { width: 180px; }
.filter-grid .fg-sm { width: 108px; }
.filter-grid .fg-md { width: 136px; }
.filter-grid .fg-range { width: 200px; }
.filter-grid .el-form-item:not(.fg-keyword):not(.fg-sm):not(.fg-md):not(.fg-range) { flex: 1 1 200px; }
.filter-grid .el-form-item { margin-bottom: 8px; }
.filter-grid .el-form-item__label { font-size: var(--fs-sm); color: var(--qrs-ink-3); }
/* 待复核/筛选/刷新/列设置：桌面端不改变原有排布，手机端并成整行 */
.toolbar-quad { display: contents; }

/* 「待复核」处于筛选状态时的高亮（中等强度：淡主色底 + 主色描边与文字，
   与旁边「新增记录」的实心主色按钮区分开，不抢眼但一眼可辨） */
.toolbar-quad .el-button.is-quad-active {
  background: var(--qrs-brand-weak);                          /* 接近纯白，仅一丝主色 */
  border-color: var(--el-color-primary);
  color: var(--el-color-primary);
  /* 不加粗：字重变化会改变按钮宽度，点击时尺寸跳动（用户反馈很不舒服） */
}
/* 仅 hover 时给一点底色反馈；focus 保持与常态一致（否则点击后残留的 focus 会让底色变重） */
.toolbar-quad .el-button.is-quad-active:hover {
  background: var(--el-color-primary-light-9);
  border-color: var(--el-color-primary);
  color: var(--el-color-primary);
}

/* 有待复核记录时给「待复核」按钮一个提示色（0.7.63 用户反馈）。
   与 is-quad-active（处于「只看待复核」筛选态）是两回事：
     · is-quad-active = 当前**正在看**待复核列表（淡主色）
     · has-todo       = **有**待复核记录待处理（警示红，与顶部待办角标同一色系）
   两者可同时出现，此时以 has-todo 的红色为准（更该被注意到的是「有活要干」）。
   注意：不改字重，避免按钮宽度跳动（is-quad-active 处已说明该约束）。 */
.toolbar-quad .el-button.has-todo {
  border-color: var(--qrs-danger);
  color: var(--qrs-danger);
  background: var(--qrs-danger-bg);
}
.toolbar-quad .el-button.has-todo:hover { background: var(--qrs-danger-bg); border-color: var(--qrs-danger); }
/* 计数改成小红胶囊，醒目但不变宽（用 padding 微调，字号不变） */
.toolbar-quad .quad-count {
  font-style: normal; font-size: var(--fs-sm); line-height: 16px;
  margin-left: 4px; padding: 0 4px; border-radius: var(--r-md);
  background: var(--qrs-danger); color: var(--qrs-surface); font-weight: 600;
}
/* 折叠/手机端沿用同一胶囊样式（原先只定义了字号） */

/* 操作按钮格：与筛选条件同一行，垂直对齐到输入框那一行（顶部留出标签高度） */
.filter-grid .fg-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-top: 24px;
  margin-bottom: 8px;
}

.el-table { font-size: var(--fs-body); }
.el-table th.el-table__cell { background: var(--qrs-surface-2) !important; font-weight: 600; color: var(--qrs-ink-2); }
.el-table .cell { line-height: var(--lh-body); }
/* 0.8.35（第 148 轮 C 组）：等宽体回归本职——只留给 OCR 原文与行内 code。
   数字 / 金额 / 统计值改用正文体 + 齐线数字（tabular-nums），中英文混排下不再忽宽忽窄。 */

.num-cell { font-variant-numeric: tabular-nums; }
.money-cell { font-variant-numeric: tabular-nums; text-align: right; font-weight: 600; }
.mono { font-variant-numeric: tabular-nums; }
.muted { color: var(--qrs-ink-3); }

.summary-bar {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 8px 12px;
  background: var(--qrs-surface-2);
  border: 1px solid var(--qrs-rule);
  border-top: none;
  border-radius: 0 0 var(--r-md) var(--r-md);
  font-size: var(--fs-body);
  color: var(--qrs-ink-3);
}
.summary-bar .fig { color: var(--qrs-ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.summary-bar .fig.money { color: var(--qrs-danger); }

/* 0.7.63：统计条与分页并排一行（原来各占一行，白吃 ~42px）。窄屏自动折回两行。 */
.list-foot {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin-top: 8px;
}
/* summary-bar 必须允许收缩（min-width:0），否则内部 flex 行不肯变窄，
   会把 pager 挤到下一行——用真实浏览器实测发现的（它一度仍占满 1204px）。 */
.list-foot .summary-bar {
  flex: 1 1 auto; min-width: 0; margin: 0; border-radius: var(--r-md);
  /* 统计项不折行、整条允许横向裁切；导出说明在空间不足时让位（见下） */
  flex-wrap: nowrap; overflow: hidden; gap: 16px;
}
.list-foot .summary-bar > span { white-space: nowrap; }
.list-foot .pager { margin-left: auto; margin-top: 0; flex: 0 0 auto; }   /* 清掉独立一行时的上边距 */
/* 导出说明是补充信息：只在确实放得下时显示，宽度不够就收起，
   避免为了它把整条挤成两行（用真实浏览器实测：4 段文案共需 769px）。 */
@media (max-width: 1599px) {
  .list-foot .summary-bar .muted { display: none; }
}
.pager { display: flex; justify-content: flex-end; margin-top: 12px; }

/* 统计卡片 */
.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 12px; }
.stat-card {
  background: var(--qrs-surface); border: 1px solid var(--qrs-rule);
  border-radius: var(--r-md); padding: 12px 12px;
}
.stat-card .label { font-size: var(--fs-sm); color: var(--qrs-ink-3); margin-bottom: 6px; }
.stat-card .value { font-size: var(--fs-figure); font-weight: 600; font-variant-numeric: tabular-nums; }
.stat-card.is-active { border-color: var(--qrs-brand); background: var(--qrs-brand-weak); }

/* 图片预览 */
.img-preview-box {
  display: flex; align-items: center; justify-content: center;
  background: var(--qrs-surface-2); border-radius: var(--r-md); min-height: 320px; max-height: 62vh; overflow: auto;
}
.img-preview-box img { max-width: 100%; display: block; }
.ocr-raw {
  background: var(--qrs-sidebar); color: var(--qrs-sidebar-ink); padding: 12px;
  border-radius: var(--r-md); font-family: Consolas, Monaco, monospace;
  font-size: var(--fs-sm); line-height: var(--lh-body); max-height: 56vh; overflow: auto;
  white-space: pre-wrap; word-break: break-all; margin: 0;
}

/* 表单 */
.form-section-label {
  font-size: var(--fs-sm); font-weight: 600; color: var(--qrs-ink-3);
  margin: 4px 0 8px; padding-bottom: 6px; border-bottom: 1px dashed var(--qrs-rule);
}
.el-form-item__label { font-size: var(--fs-body); }

.dialog-footer { display: flex; justify-content: flex-end; gap: 8px; }

/* 详情描述（账号信息 / 用户管理「查看」右上角同一份）：字段标签走 12px 次要档，取值走 14px 正文档，
   与表头、表单标签同一套口径；此前两者都吃 Element 默认的 14px，整块看着没跟着令牌收口。 */
.detail-desc .el-descriptions__label { width: 96px; color: var(--qrs-ink-3); font-weight: 400; font-size: var(--fs-sm); }
.detail-desc .el-descriptions__content { font-size: var(--fs-body); }

/* 表格内操作按钮紧凑 */
.el-table .el-button.is-link { padding: 0 4px; font-size: var(--fs-body); }

/* 操作列紧凑（0.7.62）：表格「操作」列只放图标按钮，桌面默认左右各 12px 内边距 +
   相邻按钮 12px 间距，白白吃掉近 40px。这里按列收窄（.col-actions 由各表格
   el-table-column 的 class-name 指定），使其「够用即止」。
   注意：不要写成全局 .el-table .cell 覆盖——文字类表格（日志/上传）需要原有疏朗内边距。 */
/* 0.7.63 用真实 Chromium 实测后修正：折行的**真正原因是按钮间距**，不是列宽。
   实测量（12.5px 字体 + Element Plus 12px 内边距）：
     uploads 列宽 218：5 按钮 179 + 4×8 间距 = 219 -> 差 1px 就折行
     users   列宽 242：5 按钮 202 + 4×8 间距 = 242 -> 恰好临界
   gap 收到 4px 后分别只需 203 / 226，全部单行且有余量（8–18px）。
   同时补 white-space: nowrap —— 光有它不够（会截断），必须与缩小 gap 一起用。 */
.el-table .col-actions .cell { padding: 0 4px; white-space: nowrap; }
.el-table .col-actions .el-button + .el-button { margin-left: 4px; }
/* 图标按钮自带 el-tooltip 包裹时，相邻间距由包裹层承担（与按钮规则保持一致） */
.el-table .col-actions > .cell > .el-tooltip + .el-tooltip { margin-left: 4px; }
/* 0.7.82 起操作列有纯图标按钮：tooltip 的触发元素可能是按钮本身（.el-tooltip__trigger 与
   .el-button 同类名），也可能是包裹它的 span（禁用按钮仍要能弹出说明），上面两条相邻选择器
   会漏掉其中一种。这里统一给操作列里「相邻的直接子元素」留 4px 缝，取值与上面一致。 */
.el-table .col-actions .cell > * + * { margin-left: 4px; }
/* 禁用的图标按钮本身不接收指针事件，鼠标落在它上面时把悬停交给包裹层，
   这样「为什么不能点」的 tooltip 仍然能弹出来 */
.el-table .col-actions .el-button.is-disabled { pointer-events: none; }

/* ===================== 识别复核（左图右表单） ===================== */
.review-split { display: flex; gap: 12px; align-items: flex-start; }
.review-left { flex: 1 1 58%; min-width: 0; }
.review-right { flex: 1 1 42%; min-width: 380px; }

.review-left-toolbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px;
}
.review-file-name { max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.review-viewer {
  border: 1px solid var(--qrs-rule); border-radius: var(--r-md); background: var(--qrs-surface-2);
  padding: 8px; max-height: 72vh; overflow: auto;
}
.review-viewer img { display: block; margin: 0 auto; max-width: none; }
.review-pdf { width: 100%; height: 68vh; border: 0; background: var(--qrs-surface); }

/* 字段旁的「来源 + 置信度」标注 */
.review-label { white-space: nowrap; }
.review-meta {
  flex-basis: 100%; display: block; margin-top: 4px;
  font-size: var(--fs-sm); line-height: var(--lh-body); color: var(--qrs-ink-3);
}
.review-meta.is-success { color: var(--qrs-ok); }
.review-meta.is-warning { color: var(--qrs-warn); }
.review-meta.is-danger { color: var(--qrs-danger); font-weight: 600; }
/* 多图记录：字段命中来自其它图，点击可跳转（0.7.55） */
.review-meta.is-jump { cursor: pointer; text-decoration: underline dotted; }
/* 详情抽屉的识别警告区（手写签批提醒等） */
.detail-warnings { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.review-hint {
  margin-top: 4px; padding: 8px 8px; border-radius: var(--r-md);
  background: var(--qrs-danger-bg); color: var(--qrs-danger); font-size: var(--fs-sm); line-height: var(--lh-body);
}
/* 工程名称提示框：项目单位名通常藏在这里 */
.review-source {
  margin-bottom: 12px; padding: 8px 12px; border-radius: var(--r-md);
  background: var(--qrs-info-bg); border-left: 3px solid var(--qrs-info);
}
.review-source-label { font-size: var(--fs-sm); color: var(--qrs-info); margin-right: 8px; }
.review-source-value { font-size: var(--fs-body); font-weight: 600; }
.review-source-tip { margin-top: 4px; font-size: var(--fs-sm); color: var(--qrs-ink-3); line-height: var(--lh-body); }
.review-candidate-tip {
  margin-top: 8px; padding: 8px 8px; border-radius: var(--r-md);
  background: var(--qrs-surface-2); color: var(--qrs-ink-3); font-size: var(--fs-sm); line-height: var(--lh-body);
}

/* ---------------- 记录页：行内编辑 / 批量 / 列设置 ---------------- */
/* 可点开改状态的状态标签 */
.cell-tag-edit { cursor: pointer; }
.cell-tag-edit:hover { filter: brightness(0.94); }
.cell-edit-input .el-input__wrapper { padding-left: 4px; padding-right: 4px; }
/* 当前行（键盘导航） */
.el-table .row-current > td.el-table__cell { background: var(--qrs-info-bg) !important; }

/* 批量操作条 */
.bulk-bar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0 0 8px; padding: 8px 12px; border-radius: var(--r-md);
  background: var(--qrs-info-bg); border: 1px solid var(--qrs-rule);
}
.bulk-bar .spacer { flex: 1; }

/* 列设置弹层 */
.col-setting { display: flex; flex-direction: column; gap: 6px; max-height: 60vh; overflow: auto; }
.col-setting-head { display: flex; gap: 4px; padding-bottom: 6px; border-bottom: 1px dashed var(--qrs-rule); }

/* 字典别名 */
.alias-box { padding: 8px 12px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.alias-add { display: flex; gap: 6px; align-items: center; margin-left: 4px; }
.alias-count { margin-left: 6px; }

/* 记录详情：左图右信息 */
.detail-split { display: flex; gap: 12px; align-items: flex-start; }
.detail-left { flex: 1 1 56%; min-width: 0; }
.detail-right { flex: 1 1 44%; min-width: 340px; }
.detail-left-toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
/* 文件名可长可短：让它可收缩并在超长时省略，否则会把「全屏查看 / 下载 PDF」挤到第二行
   （真实浏览器实测：左栏 637px，文件名独占 261px，子元素合计 633px，仅余 4px）。 */
.detail-left-toolbar .detail-file-name {
  flex: 0 1 auto; min-width: 0; max-width: 34%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.detail-left-toolbar .spacer { flex: 1 1 0%; min-width: 0; }
.detail-viewer {
  border: 1px solid var(--qrs-rule); border-radius: var(--r-md); background: var(--qrs-surface-2);
  padding: 8px; max-height: 74vh; overflow: auto; min-height: 200px;
}
.detail-viewer img { display: block; margin: 0 auto; max-width: none; }

/* PDF 连续滚动视图（0.7.63）：纵向堆叠全部页，随页面滚动连续阅读，
   不再「一页一翻」。页图宽度自适应容器，点任意页可进全屏查看器。 */
.pdf-scroll { display: flex; flex-direction: column; gap: 8px; align-items: center; }
.pdf-page { width: 100%; text-align: center; }
.pdf-page img {
  display: block; width: 100%; height: auto; max-width: 100%;
  margin: 0 auto; border: 1px solid var(--qrs-rule); border-radius: var(--r-sm);
  background: var(--qrs-surface); cursor: zoom-in;
}
.pdf-page-no { font-size: var(--fs-sm); margin-top: 4px; }
.pdf-page-pending {
  min-height: 220px; display: flex; align-items: center; justify-content: center;
  border: 1px dashed var(--qrs-rule); border-radius: var(--r-sm); background: var(--qrs-surface-2);
}
.detail-tabs { padding-top: 4px; }

/* 滚动条 */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-thumb { background: var(--qrs-rule); border-radius: var(--r-sm); }
::-webkit-scrollbar-thumb:hover { background: var(--qrs-ink-3); }
::-webkit-scrollbar-track { background: transparent; }

/* 响应式断点见文件末尾「移动端适配」段（<768 手机 / 768–1199 平板 / ≥1200 桌面） */

/* ============ 第 0.2.1 轮：菜单待办角标 / 施工内容摘要 / 相似度建议 ============ */

/* P6-1：菜单待办角标 */
.menu-badge {
  margin-left: auto;
  min-width: 18px; height: 18px; line-height: 18px;
  padding: 0 4px; border-radius: var(--r-md);
  background: var(--qrs-danger); color: var(--qrs-surface);
  font-size: var(--fs-sm); text-align: center; font-weight: 600;
}

/* P3-7：项目单位名称下的施工内容摘要行 */
.cell-sub {
  font-size: var(--fs-sm); color: var(--qrs-ink-3); line-height: var(--lh-tight);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* P5-1：字典候选的相似度建议 */
.suggest-tip {
  font-size: var(--fs-sm); color: var(--qrs-warn); margin-top: 4px; line-height: var(--lh-tight);
}

/* ============ 第 0.2.2 轮：别名行内 / 操作历史差异 / 版本号 / 紧凑筛选 ============ */

/* 第 6 项：侧边栏底部版本号 */
.app-aside { display: flex; flex-direction: column; }
.app-version {
  margin-top: auto;
  padding: 8px 16px;
  font-size: var(--fs-sm); color: var(--qrs-ink-3);
  font-variant-numeric: tabular-nums;
  user-select: none;
}

/* 第 2 项：正名行内的别名展示与快捷添加 */
.alias-canonical { font-weight: 600; }
.alias-tag { margin-left: 6px; }
.alias-add-btn { margin-left: 4px; padding: 0; }
.alias-add-inline { margin-left: 8px; display: inline-flex; gap: 6px; align-items: center; }

/* 第 5 项：操作历史的字段级差异 */
.log-diffs { margin-top: 6px; display: flex; flex-direction: column; gap: 4px; }
.log-diff {
  display: flex; align-items: center; gap: 8px;
  font-size: var(--fs-body); background: var(--qrs-surface-2);
  border: 1px solid var(--qrs-rule); border-radius: var(--r-sm);
  padding: 4px 8px; width: fit-content; max-width: 100%;
}
.log-field { color: var(--qrs-ink-3); min-width: 72px; }
.log-old { color: var(--qrs-danger); text-decoration: line-through; word-break: break-all; }
.log-arrow { color: var(--qrs-ink-3); }
.log-new { color: var(--qrs-ok); font-weight: 600; word-break: break-all; }

/* ============ 第 0.2.3 轮：记录锁定 ============ */
/* 锁定行的浅色提示 + ID 旁的锁标 */
.row-locked td { background: var(--qrs-surface-2) !important; }
/* 锁定行的标记从「整行铺暖橙」改成首格一条 2px 竖线：一条线 + 状态文字，不用大面积底色 */
.row-locked td:first-child { box-shadow: inset 2px 0 0 var(--qrs-warn); }
.lock-flag { color: var(--qrs-warn); margin-left: 4px; vertical-align: -2px; }

/* ============ 第 0.2.5 轮：待审结算角标 / 详情抽屉空间 ============ */
.settle-badge { margin-right: 12px; }
.settle-badge .el-badge__content { z-index: 2; }
/* 详情抽屉：压缩上下留白，图片区域尽量占满 */
.el-drawer__body { padding: 8px 12px; overflow: hidden; }
.el-drawer__header { margin-bottom: 8px; padding: 12px 16px 0; }
.detail-viewer { max-height: calc(100vh - 150px); }
.detail-tabs { max-height: calc(100vh - 110px); overflow: auto; }

/* ============ 0.4.1：金额并列候选（打印合计 / 备注列核定） ============ */
.amount-options {
  margin-top: 6px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
.amount-options-label { color: var(--qrs-ink-3); font-size: var(--fs-sm); }


/* ============ 0.5.0 阶段 1：手机 / 微信内置浏览器 / 平板 适配基础层 ============ */

/* 高度改用动态视口：微信等移动浏览器里 100% 是「布局视口」高度，
   底部会被浏览器工具栏盖住（表现为最下面的按钮点不到）。 */
@supports (height: 100dvh) {
  html, body, #app { height: 100dvh; }
}

/* ---------- 平板（768–1199px）：保留侧栏（原来 900px 会收成图标条，触摸端易误触） ---------- */
@media (max-width: 1199px) {
  .app-aside { width: 180px; flex-basis: 180px; }
  .app-main { padding: 12px 12px 16px; }

  /* 弹层宽度收口（0.7.61）：页面里写的是固定像素宽（记录详情抽屉 1180px、
     新增/修改对话框 760px、图片查看弹窗 880px…）。原来只在 <768px 覆盖，
     于是 768–1180px 的视口（iPad 竖屏、1024 笔记本、手机横屏）打开详情会横向
     溢出。这里只加 max-width「封顶」——不设 width，小弹窗（440/520px）不会被
     撑大，桌面大屏也保持原宽。Element Plus 用行内 width，max-width 仍能封住。 */
  .el-drawer { max-width: 94vw; }
  .el-dialog { max-width: 94vw; }
  .el-message-box { max-width: 92vw; }
}

/* ---------- 手机（<768px，含微信内置浏览器）：抽屉导航 + 单列布局 ---------- */
@media (max-width: 767px) {
  /* 侧栏改为浮出抽屉，不再常驻占宽 */
  .app-aside {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 3001;
    width: 232px; flex: 0 0 232px;
    transform: translateX(-100%);
    transition: transform .22s ease;
    box-shadow: var(--sh-2);
  }
  .app-aside.is-open { transform: translateX(0); }
  .app-aside-mask {
    display: block; position: fixed; inset: 0; z-index: 3000;
    background: rgba(0, 0, 0, .45);
  }
  .mobile-menu-btn { display: inline-flex; }
  .app-header { padding: 0 8px; }
  .app-header .user-zone { gap: 6px; }
  .app-header .user-zone .who { display: none; }
  .app-main { padding: 10px 10px calc(20px + env(safe-area-inset-bottom)); }
  body { font-size: var(--fs-body); }

  /* 弹窗/抽屉：页面里写的是固定像素宽（420~1180px），手机上会超出屏幕 */
  .el-dialog { width: 92vw !important; max-width: 92vw; margin-top: 4vh !important; }
  .el-dialog__body { padding: 12px 12px; }

  /* 手机端表单统一范式：任何表单加 class="form-stack-mobile" 即可
     —— 标签移到字段上方、字段整行，避免「右标签 96px」把输入框压到只剩几十像素 */
  .form-stack-mobile .el-form-item { display: block; margin-bottom: 12px; }
  .form-stack-mobile .el-form-item__label {
    display: block;
    width: auto !important;
    float: none;
    text-align: left;
    padding: 0 0 4px;
    line-height: var(--lh-tight);
  }
  .form-stack-mobile .el-form-item__content { margin-left: 0 !important; }
  .form-stack-mobile .el-row > .el-col { width: 100%; max-width: 100%; flex: 0 0 100%; }

  /* 新增/修改记录对话框：手机端 96vw + 表单体内部滚动 + 底部按钮等宽 */
  .rec-form-dialog {
    width: 96vw !important; max-width: 96vw;
    margin-top: 2vh !important;
  }
  .rec-form-dialog .el-dialog__body { max-height: 68vh; overflow: auto; }

  /* 手机端所有对话框：底部按钮等宽铺满 + 安全区下边距（记录/用户/字典等共用同一结构） */
  .el-dialog .el-dialog__footer { padding: 10px 12px calc(10px + env(safe-area-inset-bottom)); }
  .el-dialog .el-dialog__footer .dialog-footer { display: flex; gap: 8px; }
  .el-dialog .el-dialog__footer .dialog-footer .el-button { flex: 1; margin-left: 0; }
  .el-drawer { width: 100vw !important; }
  .el-drawer__body { padding: 8px 8px; }
  .el-message-box { width: 88vw !important; max-width: 88vw; }
  .detail-viewer { max-height: 40vh; }
  .detail-tabs { max-height: none; }

  /* 左右分栏 → 上下堆叠（复核页此前 min-width 380px 会把原图挤没） */
  .review-split, .detail-split { flex-direction: column; gap: 8px; }
  .review-left, .review-right, .detail-left, .detail-right {
    flex: none; width: 100%; min-width: 0;
  }
  .review-viewer { max-height: 42vh; }
  .review-pdf { height: 46vh; }

  /* 登录卡片：iPhone SE(375px) 也不溢出 */
  .login-card { width: min(360px, 92vw); padding: 24px 16px 16px; }

  /* 筛选区：手机上每项整行 */
  .filter-grid .el-form-item,
  .filter-grid .fg-keyword,
  .filter-grid .fg-sm,
  .filter-grid .fg-md,
  .filter-grid .fg-range { width: 100%; flex: 1 1 100%; }

  .filter-grid .fg-actions { width: 100%; padding-top: 0; }

  /* 手机端：待复核/筛选/刷新/列设置 并排一行（保留图标）
     靠收紧内边距与间距腾出空间，≤360px 也能放下；万一仍放不下则换行兜底，不裁切 */
  /* 手机端工具栏：新增记录 / 待复核 / 筛选 / 刷新 —— 4 等分同一行，按钮宽度完全一致
     （列设置、导出、导入等在手机端无意义，均已隐藏） */
  .toolbar {
    display: grid;
    gap: 8px;
  }
  /* 列数按实际可见按钮数（cols-N 由模板计算），角色少时按钮等分整行不留空白 */
  .toolbar.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .toolbar.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .toolbar.cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  /* 手机端隐藏统一由 .hide-mobile 承担（导出/列设置/导入等标记该类即可） */
  .hide-mobile { display: none !important; }
  .toolbar-quad { display: contents; }                  /* 三个按钮直接成为网格项 */
  /* 四等分后每格宽度固定，字号按正文 14px 以容纳「待复核 12」这类两位数角标
     （360px 下限屏下两位数角标仍不裁切；390px 及以上余量更大） */
  .toolbar-quad .el-button { width: 100%; padding: 6px 4px; font-size: var(--fs-body); }
  /* 图标略收（12px），缩短图标与文字的间距 */
  .toolbar-quad .el-button .el-icon { font-size: var(--fs-sm); margin-right: 4px; }
  /* 角标数字小一号：360px 下限屏下两位数（如「待复核 99」）也不顶到按钮边框 */
  .toolbar-quad .quad-count { font-style: normal; font-size: var(--fs-sm); margin-left: 4px; }
  .toolbar-wide-mobile { grid-column: 1 / -1; }         /* 施工单位的「新工单」独占一行 */
  /* 手机端不需要占位把右侧内容顶开（导入等已隐藏），否则会占掉一格 */
  .toolbar .spacer { display: none; }
  /* EP 默认给相邻按钮加 12px 左边距，叠加起来会强制换行，这里清零 */
  .toolbar-quad .el-button + .el-button { margin-left: 0; }

  .panel { padding: 8px 12px; }
  .toolbar { gap: 6px; }
  /* 触摸目标：small 按钮在手机上偏小 */
  .el-button--small { min-height: 34px; padding: 6px 12px; }
  .app-menu .el-menu-item { height: 46px; line-height: 46px; font-size: var(--fs-body); }
  .detail-desc .el-descriptions__label { width: 80px; }
  .amount-options .el-button { flex: 1 1 46%; }
}

/* ============ 0.5.0 阶段 2：手机端拍照上传 ============ */
/* 三个按钮并排（拍照 / 相册 / 选文件）：窄屏一行放不下三个，允许换行 */
.mobile-upload-actions { display: none; gap: 8px; margin-bottom: 4px; flex-wrap: wrap; }
.mobile-upload-actions .mu-btn {
  flex: 1 1 30%; min-width: 96px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; padding: 12px 6px;
  border: 1px dashed var(--qrs-rule); border-radius: var(--r-md);
  background: var(--qrs-surface-2); color: var(--qrs-ink); font-size: var(--fs-body);
  min-height: 84px; touch-action: manipulation;
}
.mobile-upload-actions .mu-btn:active { background: var(--qrs-brand-weak); }
.mobile-upload-actions .mu-btn .el-icon { font-size: var(--fs-figure); color: var(--qrs-brand); }
.mobile-upload-actions .mu-btn:disabled { opacity: .6; }
.mobile-upload-actions .mu-btn .mu-note { font-style: normal; font-size: var(--fs-sm); color: var(--qrs-ink-3); }
/* 安卓兜底提示（仅在触摸设备的上传入口下显示） */
.mobile-upload-actions .mu-hint { flex: 1 1 100%; margin: 4px 0 0; font-size: var(--fs-sm); line-height: var(--lh-body); }
.mobile-upload-actions .mu-hint code {
  background: var(--qrs-brand-weak); padding: 4px 4px; border-radius: var(--r-sm);
  font-family: Consolas, Monaco, monospace; font-size: var(--fs-sm);
}
.mobile-upload-actions + .desktop-upload { margin-top: 0; }

@media (max-width: 767px) {
  .mobile-upload-actions { display: flex; }
  .desktop-upload { display: none; }        /* 手机上不显示拖拽区 */
}

/* ============ 0.5.0 阶段 2：单据图片全屏查看 ============ */
.clickable-photo { cursor: zoom-in; }
/* 全屏查看器里的缩放/旋转按钮在手机上要够大 */
@media (max-width: 767px) {
  .el-image-viewer__btn { width: 46px; height: 46px; line-height: 46px; font-size: var(--fs-figure); }
  .el-image-viewer__close { top: max(12px, env(safe-area-inset-top)); }
}

/* ============ 0.5.0 阶段 3：记录列表卡片流 / 筛选抽屉 ============ */
.records-cards { display: none; }
.filter-mask { display: none; }

@media (max-width: 767px) {
  /* 卡片流 */
  .records-cards { display: block; min-height: 120px; }
  .rec-card {
    border: 1px solid var(--qrs-rule); border-radius: var(--r-md);
    padding: 8px 12px; margin-bottom: 8px; background: var(--qrs-surface);
  }
  .rec-card:active { background: var(--qrs-surface-2); }
  .rec-card.is-deleted { opacity: .55; }
  .rec-card-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 6px; }
  .rec-card-no { font-variant-numeric: tabular-nums; font-size: var(--fs-body); font-weight: 600; margin-right: 4px; }
  .rec-card-line { display: flex; align-items: baseline; gap: 6px; font-size: var(--fs-body); line-height: var(--lh-body); }
  .rec-card-line .k { color: var(--qrs-ink-3); flex: 0 0 30px; }
  .rec-card-line .v { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* 施工内容可能较长：允许折两行 */
  .rec-card-line .v.clamp-2 {
    white-space: normal; display: -webkit-box;
    -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
  .rec-card-foot {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    margin-top: 6px; padding-top: 6px; border-top: 1px dashed var(--qrs-rule); font-size: var(--fs-sm);
  }
  .rec-card-foot .money { color: var(--qrs-warn); font-weight: 600; }

  /* 筛选：改成从底部弹出的抽屉 */
  .filter-panel {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 3002;
    margin: 0; border-radius: var(--r-md) var(--r-md) 0 0;
    max-height: 78vh; overflow: auto;
    padding-bottom: calc(14px + env(safe-area-inset-bottom));
    transform: translateY(102%);
    transition: transform .22s ease;
    box-shadow: var(--sh-2);
  }
  .filter-panel.is-open { transform: translateY(0); }
  .filter-mask {
    display: block; position: fixed; inset: 0; z-index: 3001;
    background: rgba(0, 0, 0, .45);
  }

  /* 分页器：手机上省掉总数/每页条数/跳页，只留翻页 */
  .pager .el-pagination { justify-content: center; flex-wrap: wrap; }
  .pager .el-pagination__total,
  .pager .el-pagination__sizes,
  .pager .el-pagination__jump { display: none; }
  .summary-bar { font-size: var(--fs-sm); gap: 8px; }
  /* 手机端：并排会太挤，退回上下两行（与 0.7.63 之前一致） */
  .list-foot { display: block; }
  .list-foot .pager { margin-left: 0; }
  .summary-bar .muted { display: none; }   /* 导出说明手机上省掉 */
}

/* ============ 0.5.0 阶段 4：手机端触摸尺寸 ============ */
@media (max-width: 767px) {
  /* 容器内的缩放控件在手机上没用（改用全屏查看器缩放），收起以减少按钮堆叠 */
  .zoom-ctl { display: none; }
  /* 手指比鼠标粗，输入框/按钮统一撑高到 38–40px */
  .el-button { min-height: 40px; }
  .el-button--small { min-height: 36px; }
  .el-input__wrapper, .el-select__wrapper, .el-textarea__inner { min-height: 38px; }
  .el-radio-button__inner { padding: 8px 12px; }
  .el-checkbox { height: 38px; }
  .el-tabs__item { height: 44px; line-height: 44px; }
  /* 表格已换卡片流，但字典/用户页仍有小表格：把小按钮留出间距 */
  .el-table .el-button + .el-button { margin-left: 6px; }
}

/* ============ 0.5.0 阶段 3：复核队列卡片（手机端） ============ */
.queue-cards { display: none; }
@media (max-width: 767px) {
  .queue-cards { display: block; min-height: 80px; }
  .queue-cards .rec-card.is-active { border-color: var(--qrs-brand); box-shadow: 0 0 0 2px var(--qrs-brand-weak); }
}

/* ============ 0.5.1：手机端记录详情抽屉修复 ============ */
@media (max-width: 767px) {
  /* 原来的 overflow:hidden 让内容比屏幕长时直接被裁掉、又不给滚 —— 详情「显示不完整」的根因 */
  .el-drawer__body { overflow: auto; -webkit-overflow-scrolling: touch; }
  /* 手机上以「改字段」为主，所以表单在上、单据图片在下 */
  .detail-split { flex-direction: column-reverse; gap: 8px; }
  .detail-left, .detail-right { flex: none; width: 100%; min-width: 0; }
  /* 表单区不再限高（交给抽屉主体滚动），图片区不内嵌滚动条（避免双滚动） */
  .detail-tabs { max-height: none; overflow: visible; }
  .detail-viewer { max-height: none; overflow: visible; }
  .detail-viewer img { max-height: 68vh !important; }
  /* 抽屉标题栏固定，关掉/返回随时可点 */
  .el-drawer__header { position: sticky; top: 0; z-index: 2; background: var(--qrs-surface); }
}

/* ============ 0.5.1：手机端详情表单可读性 ============ */
@media (max-width: 767px) {
  /* 详情/复核表单里的两列字段在手机上太挤（施工单位被截断），改成整行单列 */
  .detail-right .el-row > .el-col,
  .review-right .el-row > .el-col { max-width: 100%; flex: 0 0 100%; }
  .el-drawer .el-form-item__label,
  .review-right .el-form-item__label { width: 84px !important; }
  /* 保存/锁定/关闭 粘在底部，滚动时随时可点 */
  .el-drawer .dialog-footer {
    position: sticky; bottom: 0;
    background: var(--qrs-surface); padding: 8px 0 calc(8px + env(safe-area-inset-bottom));
    border-top: 1px solid var(--qrs-rule); margin-top: 8px !important;
  }
}

/* ============ 0.5.2：手机端详情改为「按钮核对批单」 ============ */
.detail-mobile-bar { display: none; }
@media (max-width: 767px) {
  /* 内嵌图片区在手机上占地方、要滚很久 —— 改为「核对批单」按钮点开全屏原图 */
  .detail-left { display: none; }
  .detail-right { position: relative; }
  /* 按钮飘在 tab 行右侧，与「操作历史」同一行，省掉一整行空间 */
  .detail-mobile-bar {
    display: flex; align-items: center; gap: 6px;
    position: absolute; top: -2px; right: 0; z-index: 3;
    background: var(--qrs-surface); padding-left: 8px;
  }
}

/* 全屏看原图：遮罩加深，避免底下的表单透上来干扰核对 */
.el-image-viewer__mask { background: #000; opacity: .92; }

/* ============ 0.5.3：通用手机端卡片容器（图片任务 / 字典 / 用户） ============ */
.mobile-cards { display: none; }
@media (max-width: 767px) {
  .mobile-cards { display: block; min-height: 80px; }
  /* 卡片里的长文件名/长名称允许换行，不撑破卡片 */
  .mobile-cards .rec-card-no { white-space: normal; word-break: break-all; }
  /* 字典卡片的别名行 */
  .dict-aliases { display: flex; flex-wrap: wrap; gap: 4px; margin: 4px 0 4px; }
}

/* ============ 0.5.4：手机端工具条与状态卡紧凑化 ============ */
@media (max-width: 767px) {
  /* 按钮文字不换行（「立即处理识别队列」曾折成两行），下拉收窄让一行放得下 */
  .toolbar .el-button > span { white-space: nowrap; }
  .toolbar .el-select { width: 116px !important; }
  .toolbar .el-switch__label { font-size: var(--fs-sm); }

  /* 状态卡：0.8.11 起是 4 张（加了「施工中项目」），手机上排 2 列——挤一行会让
     「本年度金额（2026）」这类长标签溢出卡片 */
  .stat-row {
    grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px;
  }
  .stat-card { padding: 6px 4px; text-align: center; min-width: 0; }
  .stat-card .label { font-size: var(--fs-sm); margin-bottom: 4px; white-space: nowrap; }
  .stat-card .value { font-size: var(--fs-title); }

  /* 卡片操作按钮更紧凑，尽量一行放下 */
  .mobile-cards .rec-card { padding: 8px 8px; }
  .rec-card-foot { gap: 4px 6px; }
  .rec-card-foot .el-button { min-height: 30px; padding: 4px 6px; font-size: var(--fs-body); }
  .dict-aliases .alias-tag { height: 20px; line-height: 20px; font-size: var(--fs-sm); }
}

/* ============ 0.5.4：手机端细节打磨 ============ */
@media (max-width: 767px) {
  /* 浏览模式下禁用输入框的 placeholder 容易看成真实值，压淡它 */
  .detail-right .el-input.is-disabled .el-input__inner::placeholder,
  .detail-right .el-textarea.is-disabled .el-textarea__inner::placeholder {
    color: var(--qrs-ink-3);
  }
  /* 说明类文字在手机上占地方，缩小一号 */
  .panel .muted { font-size: var(--fs-sm); line-height: var(--lh-body); }
  .el-alert__title { font-size: var(--fs-body); line-height: var(--lh-body); }
  .el-alert { padding: 8px 8px; }
}

/* ============ 0.5.5：任务数紧跟刷新图标（省一行） ============ */
.upload-count { margin-left: auto; white-space: nowrap; }
@media (max-width: 767px) {
  .upload-count {
    margin-left: 4px;
    font-size: var(--fs-sm);
  }
  /* 让「状态 + 来源 + 刷新 + 任务数」稳定排在一行：
     下拉允许收缩（min-width:0），任务数不收缩，间距收紧 */
  .toolbar { gap: 4px; }
  .toolbar .el-select { width: 106px !important; min-width: 0; flex: 0 1 auto; }
  .upload-count { flex: 0 0 auto; }
}


/* ============ 0.5.7：报价记录卡片字号加大 ============ */
@media (max-width: 767px) {
  .records-cards .rec-card-no { font-size: var(--fs-title); }
  .records-cards .rec-card-line { font-size: var(--fs-title); line-height: var(--lh-loose); }
  .records-cards .rec-card-line .k { flex: 0 0 34px; }
  .records-cards .rec-card-foot { font-size: var(--fs-body); }
  .records-cards .rec-card-foot .money { font-size: var(--fs-body); }
  .records-cards .rec-card-head .el-tag { font-size: var(--fs-sm); }
}

/* ============ 0.6.0：角色权限矩阵 / 通用横向滚动表格容器 ============ */
.table-scroll { overflow-x: auto; }

/* ============ 0.6.1：报价单位未认领公司提示条 ============ */
.contractor-notice { margin-bottom: 8px; }
.contractor-notice .notice-text { margin-right: 8px; font-size: var(--fs-body); line-height: var(--lh-body); }
.contractor-notice .el-button { vertical-align: middle; }

/* ============ 0.8.26：概览页「查看他人」的只读提示条 ============ */

/* ============ 0.6.4：个人设置认领面板（公司信息 + 执照自助） ============ */

/* ============ 0.6.5：个人设置左右分栏（认领公司+修改密码 | 营业执照） ============ */
/* ============ 0.6.5：个人设置左右分栏；0.8.6 概览页右栏改为公司资料列（与左栏等高） ============ */
.profile-cols.is-two-col { display: flex; gap: 12px; align-items: stretch; }
/* 0.8.9：两栏与下面「待办项目」之间留出间隔，否则卡片贴着压在一起 */
.profile-cols { margin-bottom: 12px; }
/* 0.8.10：认领公司并入「归属公司」行——标注 + 悬停说明 + 认领入口 */
.claim-mark { color: var(--qrs-brand); }
.claim-help { margin-left: 4px; color: var(--qrs-ink-3); cursor: help; vertical-align: -2px; }
.claim-link { margin-left: 8px; }
/* 0.8.20：未认领时面板正文（原来只有一句话，右栏与左栏等高撑开后就是一大片空白）
   改成认领引导：三条步骤把「为什么认领、认领之后有什么」讲清楚，不新增按钮 */
.claim-guide-title { margin-bottom: 8px; font-size: var(--fs-body); font-weight: 600; color: var(--qrs-brand); }
.claim-guide-steps { margin: 0; padding-left: 16px; font-size: var(--fs-body); line-height: var(--lh-loose); color: var(--qrs-ink-3); }
/* 已认领但执照 / 税号收款还缺的：面板末尾一行标签（入口仍是标题行那个按钮） */
.profile-gaps { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
/* 0.8.20：原来这里还有 .profile-main 的 flex 与 .panel 的 max-width:520px 两条，
   都被下面 .profile-cols.is-two-col 的两条（同属性、更高特异性、更靠后）完全覆盖，已删 */
.profile-cols .profile-main { min-width: 0; }
.profile-cols.is-two-col .profile-main .panel { max-width: none; }
/* 0.8.8：左栏同样纵排，最后一块卡片撑满剩余高度——否则左栏卡片下沿会比右栏营业执照早结束 */
/* 0.8.22：宽屏（≥1720）改为「右栏按执照等比放大到与左栏等高定宽、多出来的宽度给左栏」，
   见文件后面的 @media (min-width: 1720px) 块。这里的 54 / 46 是 900~1719 用的（桌面窄屏、
   横屏 iPad），<900 由上面那条 @media (max-width: 899px) 改成上下单列，<768 手机端沿用同一套声明 */
.profile-cols.is-two-col .profile-main {
  flex: 1 1 54%;
  display: flex; flex-direction: column; gap: 12px;
}
.profile-cols.is-two-col .profile-main > .panel { margin-bottom: 0; }
.profile-cols.is-two-col .profile-main > .panel:last-child { flex: 1 1 auto; }
.profile-cols.is-two-col .profile-side {
  flex: 1 1 46%; min-width: 0;
  display: flex; flex-direction: column; gap: 12px;
}
/* 0.8.9：右栏只让最后一块卡片撑满——两块都撑会在「认领公司」里留出一截空白 */
.profile-cols.is-two-col .profile-side > .panel { margin-bottom: 0; }
.profile-cols.is-two-col .profile-side > .panel:last-child { flex: 1 1 auto; }
/* 0.8.28：非报价单位右栏的「公司资料」说明卡按内容高度——它没有照片那类会被撑开的内容，
   再拉满就又是「被撑开的空框」（0.8.20 删占位面板的同一个理由），故单独退出等高规则 */
.profile-cols.is-two-col .profile-side > .panel.is-placeholder { flex: 0 0 auto; }
/* ---------- 0.8.23：竖屏 iPad / 窄平板（<900）：概览页两栏改上下单列 ----------
   768~899 下 54 / 46 两栏各只有 290~390 宽，账号信息表被挤成一格 60px（实测 768 行高
   147 / 78 / 55，正常 32），440×320 的执照也只能压到 211×124。改成单列后两块卡片都拿到整宽：
   描述表一行一对（见 overview.js 的 descCols）值有 400px 以上，执照回到 440 上限（实测
   438×256.6），统计卡也从一排 1 张变一排 3 张。声明与 <768 手机端那套一致（见文件后面的手机块）。 */
@media (max-width: 899px) {
  .profile-cols.is-two-col { flex-direction: column; }
  .profile-cols.is-two-col .profile-side { flex: 0 0 auto; width: 100%; }
}
.license-preview {
  display: inline-block; max-width: 100%;
  border: 1px solid var(--qrs-rule); border-radius: var(--r-md); background: var(--qrs-surface);
}
/* 0.8.9：照片放到 440×320（等比缩放，不裁切）——执照卡片是右栏唯一会撑满的卡片，
   照片太小会在卡片里留下一截空白。≥1720 的宽屏上限见本文件后面的 @media 块 */
.license-preview .el-image__inner,
.license-preview img { max-width: 440px; max-height: 320px; width: auto; height: auto; }
/* 0.8.18：照片右侧那一列文字按钮（换照 / 撤回待审核 / 状态标签 / 已上传）整体撤掉，
   照片改为点击看大图。没有操作区要留位，照片按上面那一档上限等比显示、不再收缩；
   外层的 .license-media 只为给状态遮罩提供一个贴合照片的定位框（照片多高它就多高）。 */
.license-row { display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
/* .license-media 是悬停提示的锚点，.license-media-inner 是点击看大图的触发器；
   两层都按内容收缩，照片仍按上限等比显示，遮罩挂在内层、正好贴合照片（照片多高它就多高）。 */
/* max-width 用 min(440px, 100%)：440 是照片原有的上限，100% 保证窄栏（手机 390 下面板只有
   362 宽）不会溢出；min-width:0 是为了让 flex 项能真正收缩（否则自动最小尺寸=照片固有宽度 440）。 */
.license-media, .license-media-inner { display: inline-flex; max-width: min(440px, 100%); min-width: 0; }
.license-media-inner { position: relative; }
.license-row .license-preview img,
.license-row .license-preview .el-image__inner { max-width: 100%; }
.license-row .license-empty { flex: 1 1 auto; min-width: 0; }
/* 0.8.18：待审核 / 已驳回不占版面，直接在照片上压一层半透明遮罩 + 居中两行提示 */
.license-mask {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 4px; padding: 0 12px;
  text-align: center; border-radius: var(--r-sm); background: rgba(0, 0, 0, .45);
  color: var(--qrs-surface); pointer-events: none;
}
.license-mask-title { font-size: var(--fs-title); font-weight: 600; }
.license-mask-note { font-size: var(--fs-sm); color: var(--qrs-ink-3); }
/* 0.8.17：字典维护页的审核弹窗预览 */
.license-review-body { display: flex; justify-content: center; }
.license-review-img { max-width: 100%; max-height: 50vh; border: 1px solid var(--qrs-rule); border-radius: var(--r-md); }
/* 0.8.16：税票信息 / 收款信息；0.8.18 标题与「修改」按钮并入面板标题行，这里只剩字段。
   0.8.22：整块从执照卡片搬到左栏「账号信息」卡片（左栏宽，字段不再挤成窄条） */
.billing-block { margin-top: 12px; padding-top: 8px; border-top: 1px dashed var(--qrs-rule); }
/* 标题行里它是第二段说明，压低视觉重量，不与主标题抢 */
.panel-title .billing-title { font-weight: 400; color: var(--qrs-ink-2); }
/* 0.8.16：横向两行（用户指定分组），窗口窄了自动折行；标签不换行、值可长可短。
   0.8.22：≥1720 时这块搬进左栏账号信息卡片、两组排成 3 列网格（见后面的 @media 块） */
.billing-grid { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.billing-line { display: flex; flex-wrap: wrap; gap: 4px 16px; }
.billing-item { display: inline-flex; gap: 6px; align-items: baseline; font-size: var(--fs-body); }
.billing-item .k { color: var(--qrs-ink-3); white-space: nowrap; }
.billing-note { margin-left: 8px; }
.license-pdf-btn { width: 100%; }
.license-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; min-height: 220px; cursor: pointer;
  border: 1px dashed var(--qrs-rule); border-radius: var(--r-md); background: var(--qrs-surface-2);
  color: var(--qrs-ink); touch-action: manipulation;
}
.license-empty:hover { border-color: var(--qrs-ink-3); }
.license-empty .el-icon { font-size: var(--fs-title); color: var(--qrs-ink-3); }
/* ============ 0.8.22：宽屏（≥1720）概览页两栏改版 ============
   用户反馈：1080p 下营业执照右侧空出 294px（0.8.18 撤掉照片右那列按钮后露出来的）。
   这一版把空出来的宽度让给左栏，照片只放大到原来「执照 + 下方税号 / 收款」占的那点高度：
     ① 分栏：右栏定宽 582（照片 548 + 内边距 30 + 边框 2），其余全给左栏（1920 下 1088）——
        右栏不按比例分、也不留富余，宽度正好等于照片，右侧不再空一条；
     ② 照片上限 548×321 ＝ 0.8.21 卡片里「照片 256.6 高 + 下方税号 / 收款块 65 高」，
        卡片自然高度 383 与 0.8.21 的 383.6 持平——照片再往上长就要把页面撑高、把下方待办项目
        面板往下挤，所以到此为止（算式见下）；
     ③ 账号信息表排 3 对（6 格）、税号 / 收款搬进左栏账号信息卡片——两处都按同一阈值切换，
        见 overview.js 的 descCols。
   阈值取 1720 而不是更低：1680 实测「归属公司」那一格只有 279px（内容 268px），排 3 对会把
   「（已认领，营业执照已上传，已通过）」挤到第二行；1720 下该格 320px，留 28px 余量。
   900~1719 保持 0.8.18 以来的 54 / 46 分栏 + 440×320 照片 + 税号 / 收款挂在执照卡片里；
   0.8.23 起 <900（竖屏 iPad / 窄平板）两栏改上下单列（见上面的 @media (max-width: 899px)），
   <1200 的账号信息表每行只排 1 对（见 overview.js 的 descCols）——这一段只有 290~520 宽，
   2 对会把「归属公司」挤到 60~126px 一格。 */
@media (min-width: 1720px) {
  .profile-cols.is-two-col .profile-main { flex: 1 1 auto; }
  /* 右栏用 0 0（不缩不胀）而不是 0 1：左栏的 flex-basis 是内容宽度（auto），跟着表格 / 网格变，
     留 1 会让右栏在跨阈值来回缩放时被挤掉几像素（618 那版实测 1720 下掉到 612.6，照片随之缩水、
     卡片又空出一截）。定死 582 后照片上限才稳定生效 */
  .profile-cols.is-two-col .profile-side { flex: 0 0 582px; }
  /* 照片高 321 = 0.8.21 卡片里「照片 256.6 + 下方税号 / 收款块 65」（即移走税号 / 收款后空出来的
     那段高度，用户指定的上限）→ 宽 = 321 × 640/375 ≈ 548 → media 550（含 .license-preview 的
     1px 边框）。照片在卡片里水平、垂直都居中：左栏（账号信息 222 + 间隔 12 + 金额统计 170 = 404）
     比卡片自然高度 383 高 21px，这 21px 上下均分，不再整块压在照片下面。
     1920 下实测照片 546×319.9（media 550 − 2 层 1px 边框）、照片 + 标题与内边距 383.9（0.8.21 是
     383.6）、右栏 582、左栏 1088，两栏同为 404，照片下方留白 11px。左栏内容高度变了要一起调 */
  .license-preview .el-image__inner,
  .license-preview img { max-width: 548px; max-height: 321px; }
  .license-media, .license-media-inner { max-width: min(550px, 100%); }
  /* 竖版执照到不了 548 宽、照片比卡片窄时居中显示；卡片被等高规则撑高时照片在剩余高度里居中 */
  .license-row { justify-content: center; }
  .license-panel { display: flex; flex-direction: column; }
  .license-panel .license-row { margin: auto 0; }
  /* 六个字段排成 3 列网格，自然形成用户指定的两行（前三个一组、后三个一组），字段按列对齐；
     .billing-line 退成 display:contents，标记里的分组照旧保留 */
  .billing-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px 16px; }
  .billing-line { display: contents; }
}
/* ============ 0.8.19：公司信息弹窗（归属公司/认领 + 执照 + 税号/收款 三块合并） ============ */
/* 三块叠起来会比一屏高，正文区自己滚动，底部「保存 / 提交认领」始终留在视野里 */
/* 0.8.20：el-dialog 默认 margin-bottom 50px，叠加 15vh 上边距后「15vh + 68vh 正文 + 标题/页脚」
   在 900 高的屏上实测约 917px，超出的部分让 overlay 出现整屏滚动条。清掉下边距，正文再按
   视口高兜一层（短窗口下 68vh 本身也会顶出去）。 */
.company-dialog.el-dialog { margin-bottom: 0; }
.company-dialog .el-dialog__body { max-height: min(68vh, calc(100vh - 300px)); overflow: auto; }
.company-sec + .company-sec {
  margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--qrs-rule);
}
/* 0.8.20：弹窗内分节标题与说明文字统一按正文 14px；面板标题另按 16px
   （面板里的 .muted 被手机端规则压到 12px，弹窗不是 .panel 的后代，原本是 14px） */
.company-sec-title { margin-bottom: 8px; font-size: var(--fs-body); font-weight: 600; color: var(--qrs-brand); }
.company-dialog .muted,
.company-dialog .company-ops .muted { font-size: var(--fs-body); }
.company-claim-line { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
/* 弹窗里的执照比面板（440×320）大一档：上限 660×420，等比缩放不裁切。
   min-width:0 + max-width: min(660px, 100%)：窄屏（手机 390 下弹窗 92vw）按容器收缩不溢出。 */
.company-license { display: flex; justify-content: center; }
.company-license-inner {
  position: relative; display: inline-flex; cursor: pointer;
  max-width: min(660px, 100%); min-width: 0;
}
.company-license .license-preview .el-image__inner,
.company-license .license-preview img { max-width: 100%; max-height: 420px; }
.company-license .license-preview { max-width: min(660px, 100%); }
.company-ops { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 12px; margin-top: 8px; }
.company-ops .muted { font-size: var(--fs-sm); }
@media (max-width: 767px) {
  .profile-cols.is-two-col { flex-direction: column; }
  .profile-cols.is-two-col .profile-side { flex: 0 0 auto; width: 100%; }
  /* 0.8.20：竖版执照在手机上按 40vh 限高，否则仍按桌面 420px 封顶、把弹窗撑满整屏。
     注意特异性：上面那条是选择器列表，img 同时命中 .el-image__inner，整条规则按 (0,3,0) 生效，
     所以这里必须带上同一个类选择器（同为 (0,3,0)、同一 @media 内更靠后）才压得住 */
  .company-license .license-preview .el-image__inner,
  .company-license .license-preview img,
  .license-preview img { max-width: 100%; max-height: 40vh; }
}

/* ============ 0.7.18：金额候选右列 + 备注行对齐预结金额 ============ */
.amount-candidate-box {
  display: flex;
  flex-wrap: nowrap;          /* 手签/报价并排，靠右列左缘（紧邻输入框右侧） */
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
  min-height: 32px;           /* 与左侧输入框同高，垂直对齐 */
}
.amount-candidate-box .el-button {
  flex: 0 0 auto;
  padding: 4px 8px;           /* 略收紧内边距，两个按钮并排放得下 */
  font-size: var(--fs-sm);
}
.amount-candidate-box .el-button + .el-button { margin-left: 0; }
@media (max-width: 767px) {
  .amount-candidate-box { flex-wrap: wrap; }
}
/* ============ 表单控件与间距统一（批次 E） ============
   1) 表单内的下拉 / 日期控件默认撑满所在列——需要定宽的照旧写内联 width
      （如 logs/uploads 里的 150px 下拉，内联优先级更高）；
   2) 「最小 ~ 最大」金额区间用 .range-inputs；
   3) 零散间距改用工具类，避免散落内联 style。 */
.el-form-item .el-select,
.el-form-item .el-date-editor { width: 100%; }
.range-inputs { display: flex; gap: 6px; align-items: center; width: 100%; }
/* 间距 / 定宽 / 语义工具类（数值即含义；定宽类用于工具栏里的筛选控件） */
.mt-0 { margin-top: 0; }
.mt-4 { margin-top: 4px; }
.mt-8 { margin-top: 8px; }
.mt-10 { margin-top: 8px; }
.mt-12 { margin-top: 12px; }
.mb-0 { margin-bottom: 0; }
.mb-8 { margin-bottom: 8px; }
.mb-10 { margin-bottom: 8px; }
.mb-12 { margin-bottom: 12px; }
.ml-4 { margin-left: 4px; }
.ml-6 { margin-left: 6px; }
.ml-96 { margin-left: 96px; }
.mr-8 { margin-right: 8px; }
.mx-8 { margin-left: 8px; margin-right: 8px; }
.pl-4 { padding-left: 4px; }
.pb-0 { padding-bottom: 0; }
.lh-18 { line-height: var(--lh-loose); }
.w-130 { width: 130px; }
.w-140 { width: 140px; }
.w-150 { width: 150px; }
.w-160 { width: 160px; }
.w-170 { width: 170px; }
.w-200 { width: 200px; }
.w-340 { width: 340px; }
/* .w-340 用于日志页的日期区间控件：它是 .toolbar（flex）的 flex item，min-width:auto
   取内容最小宽度（约 410px），连内联 width 也压不下去 —— 该声明改造前后都无效、渲染一致。 */
.zoom-pct { min-width: 44px; text-align: center; }
.dialog-footer-left { justify-content: flex-start; margin-top: 12px; }
.cursor-pointer { cursor: pointer; }
.text-danger { color: var(--qrs-danger); }

/* ============ 提示文字统一两级（批次 C） ============
   1) .hint / .hint-warn：12px 字段说明与橙色提醒
   2) .review-meta：11.5px 字段来源标注（带置信度配色），贴输入框 */
.hint { font-size: var(--fs-sm); line-height: var(--lh-body); color: var(--qrs-ink-3); }
.hint-warn { font-size: var(--fs-sm); line-height: var(--lh-body); color: var(--qrs-warn); }
.hint-indent { padding-left: 96px; }        /* 桌面端与输入框左缘对齐 */
/* 分类类标签（角色 / 备份类型 / 别名 / 区域 / 权限）用 Element 自带的说明色（0.8.37 退回）。
   第 147 轮曾把 info 标签整体压成中性灰，实际效果是标签在白底上几乎看不出底色——用户反馈
   「角色的背景底色没恢复」。故撤销这条覆写，恢复浅蓝灰底 + 蓝灰字（#eef3f7 / #4a6b80）。
   随之作废的是「只有状态类才上色」的说法：info 现在既是提示盒子的底色，也是分类标签的底色，
   两者靠文字区分；状态类的语义色（success / warning / danger / primary）不受影响。 */
/* 与未认领提示条同一套取值（.notice-text 在那边是后代选择器，这里要单独写一份） */
.view-only-bar { margin-bottom: 8px; }
.view-only-bar .notice-text { margin-right: 8px; font-size: var(--fs-body); line-height: var(--lh-body); }
.view-only-bar .el-button { vertical-align: middle; }
/* 提示行里的 ⓘ / ⚠：说明搬进 tooltip 后，正文只留一个可悬停的图标（0.7.82 备份页排版瘦身） */
.hint-icon { font-size: var(--fs-body); color: var(--qrs-ink-3); cursor: help; margin: 0 4px; vertical-align: -2px; }
.hint-icon:hover { color: var(--el-color-primary); }

/* 预结算备注：尺寸/颜色取 .hint-warn，这里只管布局 */
.presettle-note {
  padding-left: 92px;         /* 与上方字段输入框左缘对齐 */
  margin-top: -16px;          /* 抵消上一行 el-form-item 的 16px 下边距，紧贴其上 */
  margin-bottom: 16px;        /* 下方留一行空白，与「结算金额」行分开 */
}
@media (max-width: 767px) {
  /* 手机端详情表单标签宽 84px（见下方 .el-drawer .el-form-item__label 覆盖），
     备注行同样缩进到输入框左缘，避免偏左 */
  .presettle-note { padding-left: 84px; }
  /* 手机端标签移到字段上方，说明文字不再需要与输入框对齐的缩进 */
  .hint-indent { padding-left: 0; }
}

/* ============ 0.7.5：详情抽屉铺满视口（图片自适应无滚动条，底部空间利用起来） ============ */
.detail-split { align-items: stretch; min-height: calc(100vh - 200px); }
.detail-left { display: flex; flex-direction: column; }
.detail-viewer {
  flex: 1 1 auto;
  max-height: none;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: auto;
}
.detail-viewer img { margin: 0 auto; }
.detail-viewer .review-pdf { flex: 1 1 auto; height: auto; min-height: 60vh; }
/* ---------- 0.8.23：平板（<1200）详情 / 复核抽屉改上下堆叠 ----------
   抽屉在 ≤1199 被文件顶部那条 `.el-drawer{max-width:94vw}` 封到约 94vw（768 下实测 721.9px），
   里面仍是桌面的「左图 56% + 右表单 44%」，而 `.detail-right` 有 min-width:340px，
   左图区只剩 340px 左右；复核页的 `.review-split` 是同一套版式（手机的 <768 块也是两块一起改）。
   这里改成图片在上、表单在下；手机端另有「表单在上 + 隐藏内嵌图」的一套（见后面
   @media (max-width: 767px) 的两块）。必须写在这组 0.7.5 规则之后，否则压不住它的
   min-height 与 flex 布局。 */
@media (max-width: 1199px) {
  .el-drawer__body { overflow: auto; -webkit-overflow-scrolling: touch; }
  .detail-split, .review-split { flex-direction: column; gap: 12px; min-height: 0; }
  .detail-left, .detail-right, .review-left, .review-right { flex: none; width: 100%; min-width: 0; }
  .detail-viewer { max-height: none; overflow: visible; }
  .detail-viewer img { max-height: 68vh !important; }
  .detail-tabs { max-height: none; overflow: visible; }
}
.detail-viewer .review-pdf { flex: 1 1 auto; height: auto; min-height: 60vh; }

/* PDF 连续滚动（0.7.65 修正）：上面这条全局规则把 .detail-viewer 设为
   `max-height:none` + flex 居中，单个图片没问题（图片自适应一屏），
   但**多页 PDF 纵向堆叠会长到数千像素**，而抽屉主体在桌面端是 `overflow:hidden`
   —— 实测容器高 6333px、抽屉裁掉超出部分，于是「完全滚不动」。
   这里给 PDF 模式一个受限高度并让它自己成为滚动容器。
   同时改为顶对齐：居中会让首屏落在长内容的中段，反而看不到第 1 页。 */
.detail-viewer.is-pdf {
  /* 高度：实测抽屉可用区 top52→bottom890（838px），而预览窗曾被压到 670px、
     下方白空 136px。上一轮我误用 -230px 覆盖了项目原有的 -150px，反而改小 80px
     （用户反馈「显示的面积反而变小了」）。现取 -120px（780px），
     下方留约 26px 余量，避免工具栏在窄屏换行时溢出。 */
  max-height: calc(100vh - 120px);
  min-height: 240px;
  overflow-y: auto;
  overflow-x: hidden;
  align-items: flex-start;
  justify-content: flex-start;
  -webkit-overflow-scrolling: touch;   /* 移动端惯性滚动 */
  /* 底部额外内边距：保证滚到最后一页时页码与页边框完整可见 */
  padding-bottom: 24px;
  scroll-padding-bottom: 24px;
}
/* PDF 模式下页图按容器宽度自适应，高度自然延伸，不再被 flex 居中拉伸 */
.detail-viewer.is-pdf .pdf-page img { width: 100%; height: auto; }
.detail-right { display: flex; flex-direction: column; }

/* 原图查看弹窗：整图完整可见（此前纵向被裁剪） */
.img-preview-box img { max-height: 62vh; width: auto; height: auto; }
@media (max-width: 767px) {
  /* 手机端上下堆叠布局，不需要为铺满视口而拉最小高度 */
  .detail-split { min-height: 0; }
}

/* ============ 0.7.8：手机卡片底部：状态标签 + 日期到日 ============ */
.rec-card-foot .el-tag { flex: 0 0 auto; }
@media (max-width: 767px) {
  /* 手机端：候选按钮盒自适应右列宽度，允许换行 */
  .amount-candidate-box { flex-wrap: wrap; }
}

/* ---- 桌面折叠态（0.7.58）：只留一列 icon，el-menu 自动 tooltip 显示名称 ---- */
.app-aside.is-collapsed { width: 64px; flex: 0 0 64px; }
.app-aside.is-collapsed .app-brand .txt { display: none; }
.app-aside.is-collapsed .app-menu,
.app-aside.is-collapsed .app-menu.el-menu--collapse { width: 64px; }
.app-aside.is-collapsed .menu-badge { position: absolute; top: 6px; right: 6px; margin-left: 0; }
.app-aside-foot {
  display: flex; align-items: center; gap: 6px; padding: 8px 12px;
  color: var(--qrs-ink-3);
}
.app-aside.is-collapsed .app-aside-foot { flex-direction: column; padding: 8px 6px; }
.app-aside.is-collapsed .collapse-btn { width: 100%; }
/* 操作栏里的锁定状态图标（施工方只读展示） */
.lock-state-icon { color: var(--qrs-warn); vertical-align: middle; }

/* 触摸设备上的上传入口：手机与**平板**都用「拍照/相册/选文件」按钮。
   为什么平板也要：768–1199px 原先落到桌面拖拽区，而安卓平板点它唤起的是
   系统文件选择器——拖拽区在触摸屏上没有意义，且用户反馈「只能选图片、选不到 PDF」。
   用 pointer/any-pointer 而不是固定宽度，才能覆盖横屏平板。 */
/* 触屏设备**不限宽度**都用按钮式入口。
   原因（0.7.68 实测）：原来限了 max-width:1199px，于是**平板横屏（1280px 及以上）落到桌面拖拽区**；
   而拖拽区的 accept 混有图片 MIME，安卓见到图片类型就路由到「照片选择器」
   —— 用户在三家浏览器上看到的选择器都只有「相机 / 照片与视频」正是此故。
   拖拽在触摸屏上本来就没有意义，所以直接按指针类型判断，不看宽度。 */
@media (pointer: coarse) {
  .mobile-upload-actions { display: flex; }
  .desktop-upload { display: none; }
}
@media (any-pointer: coarse) {
  .mobile-upload-actions { display: flex; }
  .desktop-upload { display: none; }
}

/* ============ 0.7.70：上传页预览弹窗复用详情预览结构 ============
   uploads 页的 viewer-dialog 里用了与详情抽屉相同的 .detail-viewer / .pdf-scroll，
   但 dialog 没有「抽屉 body overflow:hidden + .detail-split 定高」那层兜底，
   而 0.7.5 的全局规则把 .detail-viewer 设成 max-height:none —— 单图会随原图
   高度把弹窗撑出屏幕。这里按 dialog 场景（top 4vh + 标题栏 + 工具栏）重新限高。 */
.viewer-dialog .el-dialog__body { padding-top: 8px; padding-bottom: 12px; }
/* 0.7.70e：el-dialog 默认 margin-bottom 50px，叠加 top:12px 后 overlay 内容高
   （弹窗 886 + 50）超出视口 → 弹窗最右侧出现整页滚动条。viewer-dialog 已按
   top:12px 定位，底部 margin 必须清零。 */
.viewer-dialog.el-dialog { margin-bottom: 0; }
.viewer-bar {
  display: flex; align-items: center; gap: 8px; margin-bottom: 8px; flex-wrap: wrap;
}
.viewer-bar .spacer { flex: 1 1 0%; min-width: 0; }
/* 0.7.70b：用户要求「竖向 100% 显示，横向按图片比例自适应」——
   容器必须给确定高度（只写 max-height 的话 height:100% 无基准，图片会塌缩），
   图片才有可参照的 100% 高度。0.7.70c：窗口宽度已按首图比例计算（fitDialogWidth），
   横版窗口较宽时容器高会大于「宽 ÷ 比例」，故图片同时保留 max-height 兜底，
   横版由宽决定高、竖版由高决定宽。
   0.7.70d：实测 top4vh 弹窗高 732px、底部空 132px——「上下空余很多」。
   扣高从 280px 收到 150px（header 60 + 工具栏 46 + 间距/边框余量 ≈ 148），
   配合 top:12px 几乎全屏利用竖向空间。 */
.viewer-dialog .detail-viewer {
  height: calc(100vh - 150px);
  min-height: 200px;
  display: flex; align-items: center; justify-content: center;
  overflow: auto;
}
.viewer-dialog .detail-viewer > img {
  max-height: 100%;   /* 横版兜底：窗口宽是限制项时不超高 */
}
/* 多页 PDF 连续滚动：每页竖向定高（略留页码行余量），宽度按页面比例自适应、居中；
   页多时靠容器自身滚动，阅读顺序不变。 */
.viewer-dialog .detail-viewer.is-pdf {
  align-items: flex-start; justify-content: flex-start;
  overflow-y: auto; overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 24px; scroll-padding-bottom: 24px;
}
.viewer-dialog .detail-viewer.is-pdf .pdf-page img {
  height: calc(100vh - 210px);   /* 容器高(100vh-150) - 页码行与页间距，每页图+页码完整落在容器一屏内 */
  width: auto; max-width: 100%;
}

/* ============ 0.8.21：站点信息（标题 / Logo / 浏览器图标）与设置页 ============ */
/* 侧栏品牌区：配了 Logo 就用图片，否则仍是内置圆点（.dot）。
   限高限宽是为了不让一张大图把侧栏顶部撑变形——侧栏收起时也要能看 */
.brand-logo { max-height: 26px; max-width: 132px; margin-right: 8px; object-fit: contain; }
/* 登录页大标题上方的 Logo：宽度自适应、跟标题一起左对齐（0.8.35 起不再居中） */
.login-logo { display: block; max-height: 60px; max-width: 100%; margin: 0 0 8px; object-fit: contain; }

/* 设置页：图片预览与「选择图片 / 移除」一行。
   0.8.36：Element 的 .el-form-item__content 本身是 flex + wrap，这一行不占满整行时，
   紧随其后的 .hint 会被挤到同一行的右侧（实测跑到 left=559，比上面的输入框文字右移 234px）。
   让它固定占满一行，说明文字就回到与输入框同一起点。 */
.brand-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; flex: 0 0 100%; }
.brand-preview {
  max-height: 34px; max-width: 200px; padding: 4px 6px;
  border: 1px solid var(--qrs-rule); border-radius: var(--r-sm); background: var(--qrs-surface);
}
.icon-preview {
  width: 32px; height: 32px; padding: 4px;
  border: 1px solid var(--qrs-rule); border-radius: var(--r-sm); background: var(--qrs-surface);
  object-fit: contain;
}
/* 设置页：识别状态标签一行 */
.settings-tags {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-top: 8px; font-size: var(--fs-body);
}
/* 数据目录 / 数据库文件的绝对路径可能很长，宁可折行也不要横向撑破面板 */
.settings-path { word-break: break-all; }

/* 字典页「一个单位两行」（0.8.21）：名称列第二行放税票/收款摘要 + 修改入口。
   摘要可以省略（完整值在 title 里），但操作与提示不能省略，否则按钮点不到 */
.dict-sub { display: flex; align-items: center; gap: 8px; margin-top: 4px; font-size: var(--fs-sm); line-height: var(--lh-body); }
.dict-sub-text {
  flex: 0 1 auto; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: var(--qrs-ink-3);
}
/* 行内链接按钮：压掉 EP 默认高度与内边距，否则第二行会被撑到 32px */
.dict-sub-op { flex: 0 0 auto; height: auto; padding: 0; font-size: var(--fs-sm); }
.dict-sub .suggest-tip { flex: 0 0 auto; margin-top: 0; }
/* 手机端字典卡片：标签比 .k 默认的 30px 宽时按内容占位，别压到后面的值 */
.rec-card-line .k-wide { flex: 0 0 auto; }

@media (max-width: 767px) {
  /* 手机端：预览图占满一行，按钮换到下一行，避免图片把按钮挤到屏幕外 */
  .brand-row .brand-preview { max-width: 100%; }
  .brand-preview, .icon-preview { order: -1; }
}

/* 360–400px 下限屏：四等分按钮的内边距、图标/角标间距与字号各收一档。
   正文换到 14px 后，实测「待复核 12」这类两位数角标会顶出按钮边框 5px（0.8.32），
   这里把该按钮降到 12px 档并收紧间距，让角标回到框内；≥401px 的三档屏余量足够，不必收。 */
@media (max-width: 400px) {
  .toolbar-quad .el-button { padding: 6px 2px; font-size: var(--fs-sm); }
  .toolbar-quad .el-button .el-icon { margin-right: 2px; }
  .toolbar-quad .quad-count { margin-left: 2px; }
}
