/* ============================================================
   Design Token（2026-09-15 建立）
   ------------------------------------------------------------
   为什么要有这一层：审核实测发现全站散落 17 种字号、10 种卡片内边距、
   17 种圆角、8 套按钮规格且互不对应 —— 根因是视觉值各处硬编码，
   改一处漏一处。这里把它们收拢成唯一真值源，后续统一引用变量。

   ⚠ 当前策略（分两步走）：
     第一步（本次）：只**声明**变量，不改动下面任何既有规则 —— 零视觉变化、零风险。
     第二步（后续批次）：逐块把字面量替换为 var(...)，替换时同步复测。
   例：.lodging-table 已作为第一块试点，改用下面的变量。

   字号梯级设计依据（从 21 种收到 8 级）：
     实测 9 / 9.5 / 10 / 10.5 / 11 / 11.5 / 12 / 12.5 / 13 / 13.5 / 14 / 15 / 16
     / 18 / 19 / 20 / 21 / 22 / 24 共 19 种文本字号（另有 28 / 40 两处纯图标字号）。

    梯级不是拍脑袋定的，是按「逐行清点 + 语义就近靠档」推出来的，两条硬约束：
     ① body 与 input 的基础字号是 14px —— 若归到 13 或 15，全站正文会整体
        缩放 7%，属"为了整齐而破坏版面"。所以保留 --fs-base: 14px。
     ② 11 / 12 / 13 / 14 四档小字各差 1px（可辨识），一举消灭了
        9 / 9.5 / 10 / 10.5 / 11.5 / 12.5 / 13.5 七个冗余档位。
     实际替换后 96% 的处所字号变化 ≤0.5px（视觉零感），最大变化 ±2px 仅 4 处。

   ⚠ --fs-lg 取 16px 是有意为之，不是凑数：
     它既是卡片标题档，也是**输入控件的下限** —— iOS Safari 在输入框字号
     小于 16px 时，聚焦会自动放大整个页面（填报销单每点一格跳一次）。
     所以所有 input / select / textarea 都指向这一档。
   ============================================================ */
:root {
  /* ---------- 字号：8 级 ---------- */
  --fs-xs: 11px;    /* 辅助说明、图例、角标、meta */
  --fs-sm: 12px;    /* 表单 label、次级文本、tag */
  --fs-md: 13px;    /* 表格单元格、紧凑正文 */
  --fs-base: 14px;  /* 正文默认（body） */
  --fs-lg: 16px;    /* 输入控件 / 卡片标题（iOS 输入聚焦不放大阈值） */
  --fs-xl: 18px;    /* 页面标题、区块大标题 */
  --fs-2xl: 20px;   /* 登录页标题、统计大数 */
  --fs-3xl: 24px;   /* 统计卡主数字 */

  /* ---------- 行高：4 档 ---------- */
  --lh-num: 1;      /* 金额、计数等大数字 */
  --lh-tight: 1.2;  /* 标题、单行数字 */
  --lh-body: 1.4;   /* 正文默认 */
  --lh-loose: 1.6;  /* 多行说明、长文本 */

  /* ---------- 圆角：3 档 ---------- */
  --radius-sm: 4px;   /* 小控件：标签、小徽章 */
  --radius-md: 8px;   /* 按钮、卡片、输入框 */
  --radius-lg: 12px;  /* 弹窗、登录框等大容器 */

  /* ---------- 间距：4 档（8 的倍数） ---------- */
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 16px;
  --space-lg: 24px;

  /* ---------- 卡片内边距：2 档 ---------- */
  --card-pad-sm: 12px;  /* 图表卡、紧凑卡 */
  --card-pad-md: 16px;  /* 内容卡、表单卡 */

  /* ---------- 语义色 ---------- */
  /* ★ 2026-10-08 第 83 批 L1 换肤（飞书风 · 拍板方向 A 现代浅色 + 蓝绿双板块色）：
     主色 #1F4E79 → #185FA5（OA 蓝），文本/底色同步提亮；语义红绿不动。
     ⚠️ --c-border / --c-border-strong 不动 —— verify_ncr_toolbar_ui 按 #C8D3E0 实值断言筛选条描边。
     ⚠️ 工厂绿不进 --c-primary —— 板块色由 .sidebar-sec-factory 等作用域类承载，防「一处改了全站跟着变」。 */
  --c-primary: #185FA5;       /* 主色：OA 蓝（板块色·蓝） */
  --c-primary-dark: #0C447C;  /* 主色深：hover */
  --c-primary-soft: #E6F1FB;  /* 主色浅底：导航高亮、选中态 */
  --c-factory: #0F6E56;       /* 工厂板块绿 */
  --c-factory-dark: #085041;  /* 工厂绿深：hover */
  --c-factory-soft: #E1F5EE;  /* 工厂绿浅底 */
  --c-text: #1A1D21;          /* 主文本 */
  --c-text-sub: #5F6470;      /* 次级文本、label */
  --c-muted: #9BA1AB;         /* 弱化文本（第 83 批顺手调亮，还对比度欠账） */
  --c-border: #DCE3EC;        /* 常规描边 */
  --c-border-strong: #C8D3E0; /* 输入框描边（断言按此实值，勿动） */
  --c-bg: #F7F8FA;            /* 页面底色（第 83 批：#F2F5F9 → #F7F8FA） */
  --c-bg-soft: #F8FAFC;       /* 卡片内浅底、条纹 */
  --c-danger: #D9534F;        /* 危险 / 删除 */
  --c-success: #2E9E5B;       /* 成功 / 通过 */
  --c-warning: #E88A00;       /* 警示 / 待处理（⚠ 对比度待 P1 批次处理） */

  /* ---------- 触控 ---------- */
  --tap-min: 44px;  /* 移动端可点元素最小尺寸（iOS HIG / Material 共识值） */
}

* { margin: 0; padding: 0; box-sizing: border-box; }
/* 正文基准行高（P1「行高补齐」）：
   改造前全站 95% 的文字都是浏览器默认 normal（≈1.2），小字号下拥挤、也无法
   形成层级。这里铺一个 1.4 的正文基准；标题与数字由各自规则用
   --lh-tight(1.2) / --lh-num(1) 覆盖回去。 */
body { font-family: 'PingFang SC', 'Microsoft YaHei', 'Segoe UI', Arial, sans-serif; background: #F2F5F9; color: #17233D; font-size: var(--fs-base); line-height: var(--lh-body); }
a { text-decoration: none; color: inherit; }
button { cursor: pointer; font-family: inherit; }
input, select, textarea { font-family: inherit; font-size: var(--fs-lg); }

/* 登录页 */
/* ★ 2026-10-08 第 83 批：登录页浅色化（飞书风）——深蓝大色块 → 浅灰底 + 白卡 + 品牌蓝点缀 */
.login-page { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #EDF2F9 0%, #F7F8FA 100%); padding: 20px; }
.login-box { display: flex; width: 100%; max-width: 820px; background: #fff; border-radius: var(--radius-lg); overflow: hidden; border: 1px solid rgba(0,0,0,.06); box-shadow: 0 8px 24px rgba(0,0,0,0.10); }
.login-brand { flex: 0 0 45%; display: flex; flex-direction: column; }
.login-brand-logo { flex: 1; background: #fff; display: flex; align-items: center; justify-content: center; padding: 30px; }
.login-brand-logo img { max-width: 140px; max-height: 132px; width: auto; height: auto; }
.login-brand-info { flex: 1; display: flex; flex-direction: column; justify-content: center; background: #E6F1FB; padding: 28px; color: #0C447C; }
/* ★ 第 85 批补丁 v3：登录页主名「耀润」字号**翻倍**（20 → 40px）；英文副标题已删除 ⇒ .en 规则一并移除。 */
.login-brand-info h1 { font-size: calc(var(--fs-2xl) * 2); font-weight: 700; }
.login-brand-info p { font-size: var(--fs-sm); color: #5F6470; margin-top: 12px; line-height: var(--lh-loose); }
.login-form { flex: 1; padding: 40px 36px; display: flex; flex-direction: column; justify-content: center; }
.login-form h2 { font-size: var(--fs-2xl); font-weight: 700; margin-bottom: 6px; }
.login-form .sub { font-size: var(--fs-sm); color: #9BA1AB; margin-bottom: 24px; }
.form-group { margin-bottom: 16px; }
.form-group label { display: block; font-size: var(--fs-sm); color: #3D5166; margin-bottom: 6px; }
.form-group label .req { color: #D9534F; }
.form-group input, .form-group select, .form-group textarea {
  width: 100%; height: 44px; box-sizing: border-box; padding: 10px 12px; border: 1px solid #C8D3E0; border-radius: 6px; background: #fff; outline: none; transition: border-color 0.2s;
}
/* 多行文本框豁免固定高度：44px 只约束单行控件（input/select），textarea 按 rows 自适应 */
.form-group textarea { height: auto; min-height: 44px; resize: vertical; }
/* 单选/复选框与紧凑表格输入沿用自身尺寸，不被 44px 单行控件规则误伤 */
.form-group input[type=radio], .form-group input[type=checkbox] { width: auto; height: auto; }
.form-group .liquor-table input, .form-group .liquor-table select,
.form-group .ent-liq-table input, .form-group .ent-liq-table select { height: auto; }
.form-group input:focus, .form-group select:focus, .form-group textarea:focus { border-color: #1F4E79; }
.form-group input.error { border-color: #D9534F; background: #FFF5F5; }
.form-group .error-msg { font-size: var(--fs-xs); color: #D9534F; margin-top: 4px; }
.form-group .readonly { background: #EEF2F7; color: #3D5166; }
.btn { padding: 11px 20px; border-radius: var(--radius-md); font-size: var(--fs-base); font-weight: 600; border: none; transition: all 0.2s; display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
/* ★ 第 83 批：主按钮随 token 走（#185FA5 OA 蓝） */
.btn-primary { background: #185FA5; color: #fff; }
.btn-primary:hover { background: #0C447C; }
.btn-primary:disabled { opacity: 0.6; cursor: not-allowed; }
.btn-success { background: #2E9E5B; color: #fff; }
.btn-success:hover { background: #25804A; }
.btn-danger { background: #fff; color: #D9534F; border: 1px solid #D9534F; }
.btn-danger:hover { background: #FFF5F5; }
.btn-default { background: #fff; color: #5F6470; border: 1px solid #C8D3E0; }
.btn-default:hover { background: #F8FAFC; }
.btn-block { width: 100%; }
.login-forgot { text-align: center; font-size: var(--fs-xs); color: #9BA1AB; margin-top: 14px; }
.login-error { background: #FFF5F5; color: #D9534F; padding: 10px 14px; border-radius: var(--radius-md); font-size: var(--fs-sm); margin-bottom: 16px; display: none; }

/* 主布局 */
.app-layout { min-height: 100vh; display: flex; flex-direction: column; }
/* ★ 第 83 批：顶栏深蓝渐变 → 白底细边（飞书风）；高度 52px 不动（mobile-nav top:48 / 侧栏 sticky top:52 都依赖它） */
.app-header { background: #fff; height: 52px; display: flex; align-items: center; justify-content: space-between; padding: 0 20px; color: #1A1D21; position: sticky; top: 0; z-index: 100; border-bottom: 1px solid #E8EAEE; }
.app-header-left { display: flex; align-items: center; gap: 10px; cursor: pointer; }
.app-header-left img { height: 30px; width: auto; }
/* ★ 第 85 批补丁 v3：品牌字标「耀润」字号**翻倍**（16 → 32px，故写 calc 而非新字号级）；
   英文副标题已从 index.html 删除 ⇒ 原先给副标题的字号规则一并移除（避免留死 CSS）。 */
.app-header-left .title { font-size: calc(var(--fs-lg) * 2); font-weight: 700; letter-spacing: 1px; line-height: var(--lh-tight); }
.app-header-right { display: flex; align-items: center; gap: 18px; }
.header-user { display: flex; align-items: center; gap: 8px; cursor: pointer; position: relative; }
/* ★ 第 83 批：白底下头像从「半透明白」改为浅灰底品牌蓝字 */
.header-user .avatar { width: 28px; height: 28px; border-radius: 50%; background: #EEF2F7; color: #185FA5; display: flex; align-items: center; justify-content: center; font-size: var(--fs-sm); font-weight: 600; }
.header-user .name { font-size: var(--fs-md); }
.header-user .role { font-size: var(--fs-xs); color: #9BA1AB; }
.user-dropdown { position: absolute; top: 100%; right: 0; background: #fff; border-radius: 0 0 var(--radius-md) var(--radius-md); box-shadow: 0 8px 24px rgba(0,0,0,0.12); min-width: 140px; display: none; z-index: 200; }
.user-dropdown.show { display: block; }
.user-dropdown .item { padding: 10px 14px; font-size: var(--fs-md); color: #5F6470; cursor: pointer; border-bottom: 1px solid #EEF2F7; }
.user-dropdown .item:hover { background: #F8FAFC; }
.user-dropdown .item:last-child { color: #D9534F; border-bottom: none; }

.app-body { flex: 1; display: flex; }
/* ★ 2026-10-08 第 83 批：侧栏深蓝渐变 → 白底细边（飞书风），菜单按板块分组（组头 .sidebar-sec-title）。
   板块色：OA 蓝 / 工厂绿（.sidebar-sec-factory 作用域）——绿只在工厂组生效，全站主色仍是蓝。
   ★ 2026-09-15 用户要求：右侧内容区滚动时，左侧菜单栏固定不动（所有角色一致生效，与角色无关）。
   为什么用 sticky 而不是 fixed：本页的滚动容器是**文档**（.app-content 的 overflow-y:auto
   是个「不滚动的滚动容器」—— 见下方 .form-page-host 那段注释），所以 sticky 的参照物就是视口，
   吸得住；且不会破坏表单页底部那条 sticky 工具条（它依赖的正是「文档滚动」这个前提）。
   top: 52px = 顶部固定 header 的高度，否则菜单会被 header 压住一截。
   height + overflow-y:auto：菜单项超过视口高度时侧栏自己滚，不把整页撑高。 */
.app-sidebar { width: 180px; background: #fff; border-right: 1px solid #E8EAEE; padding: 12px 0; flex-shrink: 0;
  position: sticky; top: 52px; height: calc(100vh - 52px); overflow-y: auto; }
/* ★ 第 83 批：菜单按板块分组（app.js renderSidebar 渲染 .sidebar-sec 容器） */
.sidebar-sec { margin-bottom: 4px; }
.sidebar-sec-title { padding: 8px 20px 4px; font-size: var(--fs-xs); color: #9BA1AB; letter-spacing: 1px; font-weight: 600; }
.sidebar-sec-me { margin-top: 8px; border-top: 1px solid #EEF0F3; padding-top: 8px; }
.sidebar-item { padding: 11px 20px; font-size: var(--fs-md); color: #5F6470; cursor: pointer; display: flex; align-items: center; gap: 8px; border-left: 3px solid transparent; transition: all 0.2s; }
.sidebar-item:hover { background: #F2F4F7; color: #1A1D21; }
.sidebar-item.active { background: #E6F1FB; color: #185FA5; font-weight: 600; border-left-color: #185FA5; }
/* 工厂组高亮用板块绿（唯一作用域，别处不受影响） */
.sidebar-sec-factory .sidebar-item.active { background: #E1F5EE; color: #0F6E56; border-left-color: #0F6E56; }

.app-content { flex: 1; padding: 20px; overflow-y: auto; }
.page-title { font-size: var(--fs-xl); font-weight: 700; margin-bottom: 4px; }
/* 标题行（标题 + 右侧导出按钮） */
.page-title-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 4px; }
.page-title-row .page-title { margin-bottom: 0; }
.export-btn { flex-shrink: 0; display: inline-flex; align-items: center; gap: 5px; padding: 7px 14px; font-size: var(--fs-md); font-weight: 600; color: #1B6FB8; background: #fff; border: 1px solid #C7D6E8; border-radius: var(--radius-md); cursor: pointer; transition: all .15s; }
.export-btn:hover { background: #EEF5FC; border-color: #1B6FB8; }
.export-btn:active { transform: translateY(1px); }
.page-sub { font-size: var(--fs-sm); color: #8A94A6; margin-bottom: 18px; }
.page-sub-with-paid { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.page-sub-paid { font-size: var(--fs-md); font-weight: 600; color: #1B7A4A; white-space: nowrap; }

/* 卡片 */
.card { background: #fff; border-radius: var(--radius-md); border: 1px solid #DCE3EC; padding: 16px; margin-bottom: 16px; }
.card-title { font-size: var(--fs-base); font-weight: 600; margin-bottom: 12px; display: flex; justify-content: space-between; align-items: center; }
.card-title .link { font-size: var(--fs-sm); color: #1F4E79; cursor: pointer; font-weight: 400; }

/* 统计卡片 */
/* ── 统计卡配色语义约定（2026-09-15 收口 · UI 审核 P0-4）────────────────────
   颜色只表达「状态类别」，不表达顺序、也不表达金额健康度：
     blue  = 中性 / 总量      总数、人数、年度合计、月份金额
     gold  = 待处理（需关注）  待审批、待财务审批、待打款、在审批中
     green = 已完成            已打款、已通过
     red   = 异常 / 需干预     统计卡上不使用，留给「已驳回」这类标签
     purple= 停用，勿在新卡片上使用
   收口前三处硬伤：① 同一「待打款」同时用 green 与 gold；
   ② 「在审批中」用 red，被业务方读成「出错了」；③ 月份金额用 red/green/purple 编码月份，
   红色最容易被读成「超支」——月份已由 label 文字说明，颜色不该再承担信息。 */
.stats-row { display: flex; gap: 12px; margin-bottom: 18px; flex-wrap: wrap; }
.stat-card { flex: 1 1 140px; min-width: 120px; background: #fff; border-radius: var(--radius-md); padding: 14px 16px; border: 1px solid #DCE3EC; border-left: 3px solid #185FA5; }
.stat-card.gold { border-left-color: #8A6D3B; }
.stat-card.green { border-left-color: #2E9E5B; }
.stat-card.red { border-left-color: #D9534F; }
.stat-card.purple { border-left-color: #7B5EA7; }
.stat-card .label { font-size: var(--fs-sm); color: #8A94A6; }
.stat-card .value { font-size: var(--fs-3xl); font-weight: 700; margin-top: 4px; }
.stat-card.blue .value { color: #185FA5; }
.stat-card.gold .value { color: #8A6D3B; }
.stat-card.green .value { color: #2E9E5B; }
.stat-card.red .value { color: #D9534F; }
.stat-card.purple .value { color: #7B5EA7; }
.stat-card .desc { font-size: var(--fs-xs); color: #8A94A6; margin-top: 2px; }

/* 提醒条 */
.alert-bar { background: #FFF8E6; border-radius: var(--radius-md); padding: 12px 16px; margin-bottom: 18px; border-left: 3px solid #E8B84B; display: flex; justify-content: space-between; align-items: center; }
.alert-bar .text { font-size: var(--fs-md); color: #8A6D2E; }
.alert-bar .text b { font-weight: 600; }
.alert-bar .action { font-size: var(--fs-sm); color: #1F4E79; font-weight: 600; cursor: pointer; white-space: nowrap; margin-left: 12px; }
.alert-bar.red { background: #FFF0F0; border-left-color: #D9534F; }
.alert-bar.red .text { color: #B83A36; }

/* 表格 */
.table-wrap { background: #fff; border-radius: var(--radius-md); border: 1px solid #DCE3EC; overflow-x: auto; overflow-y: hidden; }
/* 单号单元格：等宽 + 禁止换行。
   单号形如 YRBX-陈泰元-20260914-01，内含 '-'，浏览器默认会在每个连字符后折行，
   会把一个单号竖着拆成 4 行、把行高从 ~30px 撑到 ~58px。必须锁成一行。 */
.doc-no { font-family: ui-monospace, Menlo, monospace; font-size: var(--fs-sm); white-space: nowrap; }
table { width: 100%; border-collapse: collapse; }
th { background: #F7F8FA; padding: 10px 14px; font-size: var(--fs-sm); font-weight: 600; color: #5F6470; text-align: left; }
td { padding: 12px 14px; font-size: var(--fs-md); border-bottom: 1px solid #EEF2F7; }
tr:last-child td { border-bottom: none; }
tr:hover td { background: #F8FAFC; }

/* 状态标签 */
.tag { display: inline-block; padding: 3px 8px; border-radius: var(--radius-sm); font-size: var(--fs-xs); font-weight: 600; }
/* 标签配色语义约定（2026-09-15 收口 · UI 审核 P0-4）
   收口前：「待处理」这一个语义用了四种颜色 —— 待审批=绿(#2E9E5B)、
   待总监审批=橙(#E88A00)、待财务审批=蓝(#1F4E79)、待打款=紫(#7B1FA2)。
   同一进度在不同页面呈现不同颜色，业务员没法靠颜色判断「这单走到哪了」。
   收口后只留三类：橙 = 待处理 · 绿 = 已完成 · 红 = 异常。 */
.tag.pending { background: #FFF3E0; color: #E88A00; }
.tag.approved { background: #E3F0E8; color: #1B7A4A; }
.tag.rejected { background: #FFF0F0; color: #D9534F; }
.tag.paid { background: #E3F0E8; color: #1B7A4A; }
.tag.gm-pending { background: #FFF3E0; color: #E88A00; }
.tag.finance-pending { background: #FFF3E0; color: #E88A00; }
.tag.pending-payment { background: #FFF3E0; color: #E88A00; }

/* 表单分组 */
.form-section { margin-bottom: 20px; }
.form-section-title { font-size: var(--fs-sm); font-weight: 600; color: #1F4E79; margin-bottom: 10px; padding-bottom: 6px; border-bottom: 1px solid #EEF2F7; }
.form-row { display: flex; gap: 12px; flex-wrap: wrap; }
.form-row .form-group { flex: 1 1 200px; min-width: 180px; }

/* 客户明细行：一次出差可对应多个「客户 + 事项」（2026-09-14 新增） */
.client-row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; margin-bottom: 10px; }
.client-row .form-group { flex: 1 1 180px; min-width: 140px; margin-bottom: 0; }
.client-row .client-del {
  flex: 0 0 auto; width: 40px; height: 41px; padding: 0; border-radius: var(--radius-md);
  border: 1px solid #E8C9C9; background: #FFF5F5; color: #D9534F; font-size: 18px; line-height: var(--lh-num); cursor: pointer;
  display: flex; align-items: center; justify-content: center; transition: all 0.2s;
}
.client-row .client-del:hover { background: #FFE9E9; border-color: #D9534F; }
.btn-add-client { width: 100%; margin-top: 2px; border: 1px dashed #A8BDD6; background: #F7FAFD; color: #1F4E79; }
.btn-add-client:hover { background: #EAF1F9; border-color: #1F4E79; }
.form-hint { font-size: var(--fs-xs); color: #8A94A6; margin-top: 8px; line-height: var(--lh-loose); }
@media (max-width: 640px) {
  .client-row { gap: 8px; }
  .client-row .form-group { flex: 1 1 100px; min-width: 0; }
  .client-row .client-del { width: 36px; }
}

/* 酒水审批明细表（2026-09-14 新增，对应纸质《酒水审批》表）
   列较多，窄屏用横向滚动兜底，不折行、不换行错位 */
.liquor-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid #DCE3EC; border-radius: var(--radius-md); background: #fff; }
.liquor-table { width: 100%; border-collapse: collapse; min-width: 660px; }
/* 详情页的合并总表多一列「对应客户」，需要更宽的下限 */
.liquor-table.liquor-table-wide { min-width: 800px; }
.liquor-table th { background: #EAF0F7; padding: 8px 10px; font-size: var(--fs-sm); font-weight: 600; color: #3D5166; text-align: left; white-space: nowrap; }
.liquor-table td { padding: 8px 10px; font-size: var(--fs-md); border-bottom: 1px solid #EEF2F7; vertical-align: middle; }
.liquor-table tfoot td { padding: 9px 10px; font-size: var(--fs-md); font-weight: 700; color: #1F4E79; background: #F8FAFC; border-bottom: none; }
.liquor-table input, .liquor-table select {
  width: 100%; padding: 6px 8px; border: 1px solid #DCE3EC; border-radius: var(--radius-md);
  font-size: var(--fs-lg); color: #22334A; background: #fff; box-sizing: border-box;
}
.liquor-table input:focus, .liquor-table select:focus { outline: none; border-color: #1F4E79; box-shadow: 0 0 0 2px rgba(31,78,121,0.08); }
.liquor-table .lq-total, .liquor-table .lq-total-cell { font-weight: 600; color: #1F4E79; white-space: nowrap; }
.liquor-table .liquor-del-cell { width: 44px; text-align: center; }
/* 删除按钮的基础样式挂在 .client-row 作用域下，这里需另写一份 */
.liquor-table .client-del {
  width: 32px; height: 32px; padding: 0; border-radius: var(--radius-md); margin: 0 auto;
  border: 1px solid #E8C9C9; background: #FFF5F5; color: #D9534F; font-size: 16px; line-height: var(--lh-num);
  cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s;
}
.liquor-table .client-del:hover { background: #FFE9E9; border-color: #D9534F; }
.liquor-sum-label { text-align: right; }
/* 公司领导审批栏（出差详情页） */
.liquor-sign { display: flex; align-items: stretch; margin-top: 10px; border: 1px solid #DCE3EC; border-radius: var(--radius-md); overflow: hidden; }
.liquor-sign-label { flex: 0 0 92px; display: flex; align-items: center; justify-content: center; text-align: center; background: #EAF0F7; font-size: var(--fs-sm); font-weight: 600; color: #3D5166; padding: 12px 8px; line-height: var(--lh-loose); }
.liquor-sign-value { flex: 1; padding: 12px; font-size: var(--fs-md); color: #22334A; }
@media (max-width: 640px) {
  .liquor-table { min-width: 560px; }
  .liquor-table th, .liquor-table td { padding: 7px 8px; font-size: var(--fs-sm); }
  .liquor-table input, .liquor-table select { padding: 5px 6px; font-size: var(--fs-lg); }
  .liquor-sign-label { flex: 0 0 76px; font-size: var(--fs-xs); }
}

/* 住宿费 + 伙食补助（2026-09-14 新增；2026-09-15 Token 化 + 新增「发票」列）
   本块改动：①「标准」→「费用」；②每行多一个「发票」上传位（44px = --tap-min）；
   ③所有视觉值改引 Token 变量 —— 这一块是全站第一块试点，其余块后续批次跟进。
   与酒水表同一套表格观感，窄屏横向滚动兜底（手机端另有 .lg-scroll-hint 文字提示）。 */
.lodging-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--c-border); border-radius: var(--radius-md); background: #fff; }
.lodging-table { width: 100%; border-collapse: collapse; min-width: 760px; }
.lodging-table th { background: #EAF0F7; padding: var(--space-sm) 10px; font-size: var(--fs-xs); font-weight: 600; color: var(--c-text-sub); text-align: left; white-space: nowrap; }
.lodging-table td { padding: var(--space-sm) 10px; font-size: var(--fs-md); border-bottom: 1px solid #EEF2F7; vertical-align: middle; }
.lodging-table tfoot td { padding: 9px 10px; font-size: var(--fs-md); font-weight: 700; color: var(--c-primary); background: var(--c-bg-soft); border-bottom: none; }
/* ★ 2026-09-17 第 33 批：补 select —— 第 30 批加「归属客户」列时只写了 input 的样式，
   表格里的下拉裸奔成系统原生样式（截图反馈），与同行地区/费用/天数输入框不一致。 */
.lodging-table input, .lodging-table select {
  width: 100%; padding: 5px 7px; border: 1px solid var(--c-border); border-radius: var(--radius-sm);
  /* 用 --fs-lg(16px) 而非 --fs-md：所有 input 必须 ≥16px，
     iOS Safari 在输入框字号小于 16px 时聚焦会自动放大整页 —— 住宿费表要填 4 个字段，
     每点一格跳一次放大，是业务员投诉最多的体验问题。表格内已相应收窄 padding 抵住行高。 */
  font-size: var(--fs-lg); color: #22334A; background: #fff; box-sizing: border-box;
}
.lodging-table input:focus, .lodging-table select:focus { outline: none; border-color: var(--c-primary); box-shadow: 0 0 0 2px rgba(31,78,121,0.08); }
/* select 浏览器默认渲染比 input 高 2px（同 padding 同字号实测 36 vs 34），显式钉住同高 */
.lodging-table select { height: 34px; }
.lodging-table .lq-total, .lodging-table .lq-total-cell { font-weight: 600; color: var(--c-primary); white-space: nowrap; }
.lodging-table .liquor-del-cell { width: 44px; text-align: center; }
/* 删除按钮的基础样式挂在 .client-row 作用域下，这里需另写一份 */
.lodging-table .client-del {
  width: 32px; height: 32px; padding: 0; border-radius: var(--radius-sm); margin: 0 auto;
  border: 1px solid #E8C9C9; background: #FFF5F5; color: var(--c-danger); font-size: 16px; line-height: var(--lh-num);
  cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s;
}
.lodging-table .client-del:hover { background: #FFE9E9; border-color: var(--c-danger); }

/* 住宿发票单元格（2026-09-15 新增）：已传缩略图 + 「+」上传位，可并存。
   尺寸统一取 44px（--tap-min）—— 手机上这一列和另外 5 列抢宽度，
   但触控目标不能再小，所以用「+」而非文字按钮来省空间。 */
/* 每行只一张发票 → 未传只出「+」、已传只出缩略图，两者互斥不并存（见 lodgingInvCell） */
.lg-inv-list { display: inline-flex; gap: var(--space-xs); align-items: center; vertical-align: middle; min-height: var(--tap-min); }
.lg-inv-cell.has-inv .lg-inv-add { display: none; }
.lg-inv-thumb { position: relative; width: var(--tap-min); height: var(--tap-min); border-radius: var(--radius-sm); overflow: hidden; border: 1px solid var(--c-border); flex: 0 0 auto; }
.lg-inv-thumb img { width: 100%; height: 100%; object-fit: cover; cursor: pointer; display: block; }
.lg-inv-thumb .del { position: absolute; top: -5px; right: -5px; width: 16px; height: 16px; background: var(--c-danger); color: #fff; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: var(--fs-xs); line-height: var(--lh-num); cursor: pointer; }
.lg-inv-thumb.pdf-thumb { display: flex; align-items: center; justify-content: center; background: #FDF0E6; border-color: #F0C9A8; }
.lg-inv-thumb.pdf-thumb a { color: #C0572F; font-size: var(--fs-xs); font-weight: 700; text-decoration: none; letter-spacing: 0.5px; }
.lg-inv-add { width: var(--tap-min); height: var(--tap-min); flex: 0 0 auto; display: flex; align-items: center; justify-content: center; border: 1px dashed var(--c-border-strong); border-radius: var(--radius-sm); color: var(--c-muted); font-size: 18px; line-height: var(--lh-num); cursor: pointer; transition: all 0.2s; }
.lg-inv-add:hover { border-color: var(--c-primary); color: var(--c-primary); }
/* 只读版（详情页 / 审批页）：DOM 里根本没有 .lg-inv-add（见 invReadonly），无需隐藏规则。
   未上传用警示色标出而不是留白 —— 留白看不出是「没传」还是「不支持」。 */
.lg-inv-none { font-size: var(--fs-xs); color: var(--c-warning); }

/* 手机端横向滚动提示：默认隐藏，仅手机显示（桌面容器够宽、不溢出，常显会误导） */
.lg-scroll-hint { display: none; }
/* 适用对象勾选（□公司领导 □其他人员）—— 2026-09-15 用户要求**整行删除**，此组样式当前无元素匹配；
   保留不删：删的是表单里那排 radio，样式留着以后若要恢复可直接复用（没有匹配元素时零副作用）。 */
.lodging-target { display: flex; gap: 18px; align-items: center; margin-bottom: 8px; flex-wrap: wrap; }
.lg-chk { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-md); color: #22334A; cursor: pointer; user-select: none; }
.lg-chk input[type="radio"] { width: 15px; height: 15px; accent-color: #1F4E79; cursor: pointer; margin: 0; }
/* 分区标题后的「（可选）」小字 */
.sec-opt { font-weight: 400; font-size: var(--fs-xs); color: #6B7686; }
@media (max-width: 640px) {
  /* 6 列（地区/费用/天数/金额/发票/删除）在手机上必然溢出，这是既定事实。
     处理方式（2026-09-15 用户确认）：保留横向滚动 + 明确提示，不做卡片式重排。
     min-width 460 → 560：按「每列 ~92px（与原 460÷5 单列宽一致）」× 6 列反推 =
     552，取 560 —— 新增的发票列不该以压缩其它列的输入框为代价。
     下方 .lg-scroll-hint 是配套提示：不给提示的话业务员只看得到前两列，
     会以为「天数 / 金额」不存在 → 直接漏填（UI 审核 P0-1）。

     ⚠ 字号：这里**刻意不写 font-size**（2026-09-15 实测踩坑）。
     住宿表单元格文字实际由上面 768px 块里的 `.app-content td { font-size: var(--fs-md) }`
     （第 633 行附近）统一接管 —— 两者权重相同、它在后，写在这里也会被覆盖，
     等于死代码。原以为能压到 11.5px「省空间」，实测根本没生效。
     输入框同理不再单独压字号：min-width 已放宽，保持桌面同一档 var(--fs-md)=13px。 */
  .lodging-table { min-width: 700px; }
  .lodging-table th, .lodging-table td { padding: 7px 8px; }
  .lodging-table input { padding: 5px 6px; }
  .lodging-target { gap: 14px; }
  .lg-scroll-hint { display: block; font-size: var(--fs-xs); color: var(--c-muted); padding: 2px 0 var(--space-xs); }
}

/* ===== 客户卡片（2026-09-14 重做）：一位客户一张卡，卡内挂这位客户自己的酒水审批明细 =====
   归属关系由 DOM 结构本身保证 —— 卡片里的酒水就是这张卡客户的，不需要手选、也不可能选错。 */
.client-card { border: 1px solid #DCE3EC; border-radius: var(--radius-md); background: #FBFCFE; padding: 12px; margin-bottom: 12px; }
.client-card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.client-card-no { font-size: var(--fs-sm); font-weight: 600; color: #1F4E79; }
.client-card-head .client-del {
  width: 30px; height: 30px; padding: 0; border-radius: var(--radius-md);
  border: 1px solid #E8C9C9; background: #FFF5F5; color: #D9534F; font-size: 16px; line-height: var(--lh-num);
  cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s;
}
.client-card-head .client-del:hover { background: #FFE9E9; border-color: #D9534F; }
/* 卡内子块（出差信息 / 费用与借款）：与酒水块同款虚线分隔，视觉上「同属这位客户」 */
.client-sub { margin-top: 12px; padding-top: 10px; border-top: 1px dashed #E4EAF2; }
.client-sub .form-row { margin-bottom: 0; }
.client-sub .form-group:last-child { margin-bottom: 0; }
/* 校验未通过时把出错的那张卡闪一下红框（focusClientCard） */
.client-card.invalid { border-color: #D9534F; box-shadow: 0 0 0 3px rgba(217,83,79,.14); background: #FFFAFA; }
/* ★ 客户与项目：客户卡片两列并排（2026-09-15 用户要求）
   排布 = 常规两列网格的行优先填充：第 1、2 张一行；第 3 张落在第 1 张下面，第 4 张落在第 2 张下面。
   minmax(0,1fr) 不能省 —— 否则卡内酒水表（min-width 660px）会把列宽顶开、整页横向溢出。 */
#tf_clients { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; align-items: start; }
#tf_clients .client-card { margin-bottom: 0; }
/* 窄屏回落单列：手机/平板上一列一卡，避免卡内表格被压到没法填 */
/* ⚠️ 必须写 minmax(0,1fr)：裸 1fr 的最小宽度是 min-content，会被卡内 660px 的酒水表顶开，
   880px 视口下整页横向溢出（2026-09-15 实测踩到） */
@media (max-width: 900px) { #tf_clients { grid-template-columns: minmax(0, 1fr); } }
.client-liquor { margin-top: 12px; padding-top: 10px; border-top: 1px dashed #E4EAF2; }
.client-sub-title { font-size: var(--fs-sm); font-weight: 600; color: #3D5166; margin-bottom: 8px; }
.client-liquor .liquor-table-wrap { border-color: #E4EAF2; }
/* 整单汇总（客户分区底部）：只读胶囊，随卡片输入实时变 —— 让人当场看见「整单长什么样」
   ★ 2026-09-17（第 27 批）：改**两行**展示（行程一行 / 金额一行）+ 字号上调一档 ——
   用户反馈「6 个胶囊挤一行、字太小，看不清整单费用」。行内保留 flex-wrap，窄屏继续折行不溢出。
   只调本组件字号，**不动全站 token 阶梯**（理由见本文件顶部 --fs-base 处的说明）。 */
.trip-sum { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; }
.ts-line { display: flex; flex-wrap: wrap; gap: 10px; }
.trip-sum .ts-item {
  display: inline-flex; align-items: baseline; gap: 8px;
  background: #F6F9FC; border: 1px solid #E4EAF2; border-radius: var(--radius-md); padding: 8px 14px;
}
.trip-sum .ts-label { font-size: var(--fs-md); color: #8A94A6; }
.trip-sum b { font-size: var(--fs-base); color: #1F4E79; font-variant-numeric: tabular-nums; }
/* 金额行再大一档并加粗：让「这趟要花多少钱」一眼可见 */
.trip-sum .ts-line-money b { font-size: var(--fs-lg); font-weight: 700; }
/* 出差详情：每位客户一块，块内显示该客户的酒水招待小计 */
/* ★ 2026-09-15：详情页客户块改两列并排（用户要求「客户一、客户二并排一行，
   客户三在客户一下面、客户四在客户二下面」）。排布 = 常规两列网格的行优先填充，
   与表单页 #tf_clients 同一套规则。
   ⚠️ minmax(0,1fr) 不能省 —— 裸 1fr 的最小宽度是 min-content，块内三列 form-row 会被顶开、整页横向溢出。 */
.detail-clients { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; align-items: start; }
@media (max-width: 900px) { .detail-clients { grid-template-columns: minmax(0, 1fr); } }
/* 由「虚线分隔的纵向块」改为「并排卡片」：两列后各块高度不等，靠虚线对齐会显得散 */
.detail-client-block { padding: 12px; border: 1px solid #E4EAF2; border-radius: var(--radius-md); background: #FCFDFF; }
.detail-client-sub { font-size: var(--fs-sm); color: #1F4E79; margin-top: 8px; padding-top: 8px; border-top: 1px dashed #E4EAF2; }
/* 每位客户卡片内的「酒水招待明细」（2026-09-15 用户要求：明细跟着客户走，不用去底部总表里找）
   一位客户可能有多笔酒水 → 每笔两行：主行=类别+品名+小计，副行=容量/数量/单价（灰字）。
   窄卡片（两列并排后约 590px，手机更窄）下比 6 列小表可读得多。 */
.detail-client-liquors { margin-top: 8px; padding-top: 8px; border-top: 1px dashed #E4EAF2; }
.dcl-head { display: flex; align-items: baseline; gap: 6px; font-size: var(--fs-sm); font-weight: 600; color: #3D5166; margin-bottom: 6px; }
.dcl-head .dcl-count { font-weight: 400; font-size: var(--fs-xs); color: #8A94A6; }
.dcl-row { padding: 6px 9px; border-radius: var(--radius-md); background: #F4F8FD; }
.dcl-row + .dcl-row { margin-top: 5px; }
.dcl-line { display: flex; align-items: baseline; gap: 7px; font-size: var(--fs-md); color: #22334A; }
.dcl-cat { flex: 0 0 auto; font-size: var(--fs-xs); line-height: var(--lh-loose); color: #1F4E79; background: #E7F0FA; border-radius: var(--radius-sm); padding: 0 5px; }
.dcl-name { flex: 1 1 auto; min-width: 0; font-weight: 600; overflow-wrap: anywhere; }
.dcl-total { flex: 0 0 auto; font-weight: 700; color: #1F4E79; white-space: nowrap; }
.dcl-spec { font-size: var(--fs-xs); color: #7A879B; margin-top: 2px; }
/* 明细块已经用虚线跟上方字段分隔，紧跟其后的合计行不再重复画一条 */
.detail-client-liquors + .detail-client-sub { border-top: none; padding-top: 0; }
/* 酒水合并总表下方的「按客户小计」 */
.liquor-subline { font-size: var(--fs-sm); color: #1F4E79; margin-top: 8px; line-height: var(--lh-loose); }
/* 按客户汇总（报销单）：客户名 + 金额的胶囊列表 */
.client-sum-box { display: flex; flex-wrap: wrap; gap: 8px; }
.cs-item { display: inline-flex; align-items: baseline; gap: 8px; background: #F8FAFC; border: 1px solid #E4EAF2; border-radius: var(--radius-md); padding: 7px 12px; }
.cs-name { font-size: var(--fs-sm); color: #3D5166; }
.cs-amt { font-size: var(--fs-md); font-weight: 600; color: #1F4E79; }
@media (max-width: 640px) {
  .client-card { padding: 10px; }
  .cs-item { padding: 6px 10px; }
}

/* 费用明细 */
.expense-item { background: #F8FAFC; border-radius: var(--radius-md); padding: 12px; margin-bottom: 10px; border: 1px solid #EEF2F7; }
.expense-item .form-row { margin-bottom: 12px; }
.expense-item > .form-group:last-child { margin-bottom: 0; }
.expense-item-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.expense-item-header .idx { font-size: var(--fs-md); font-weight: 600; color: #1F4E79; }
.expense-item-header .del { font-size: var(--fs-sm); color: #C9302C; cursor: pointer; background: none; border: none; font-family: inherit; line-height: 1.2; padding: 8px 10px; margin: -8px -10px; border-radius: var(--radius-sm); }
.expense-item-header .del:hover { background: #FDEEED; }
.expense-item-header .del:focus-visible { outline: 2px solid #1F4E79; outline-offset: 1px; }
.expense-item .form-row .form-group { flex: 1 1 120px; min-width: 100px; margin-bottom: 0; }

/* 图片上传 */
.upload-area { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.upload-btn { width: 72px; height: 72px; background: #F8FAFC; border: 1px dashed #C8D3E0; border-radius: var(--radius-md); display: flex; flex-direction: column; align-items: center; justify-content: center; cursor: pointer; color: #6B7686; font-size: var(--fs-xs); }
.upload-btn:hover { border-color: #1F4E79; color: #1F4E79; }
.upload-btn .plus { font-size: 20px; line-height: var(--lh-num); margin-bottom: 2px; }
.upload-thumb { position: relative; width: 72px; height: 72px; border-radius: var(--radius-md); overflow: hidden; border: 1px solid #DCE3EC; }
.upload-thumb img { width: 100%; height: 100%; object-fit: cover; cursor: pointer; }
.upload-thumb .del { position: absolute; top: -4px; right: -4px; width: 18px; height: 18px; background: #D9534F; color: #fff; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: var(--fs-sm); cursor: pointer; }
.upload-thumb.loading { display: flex; align-items: center; justify-content: center; background: #F8FAFC; }
.upload-thumb .spinner { width: 20px; height: 20px; border: 2px solid #DCE3EC; border-top-color: #1F4E79; border-radius: 50%; animation: spin 1s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ============ 招待费二级选项（2026-09-15 新增，见 §6.25）============
   「招待费」选中后才出现：含酒水 / 酒水外带 二选一（radio 同 name 天然互斥）。
   选「酒水外带」再展开酒水费用输入 + 酒水发票上传（PDF 走 .pdf-thumb 卡片）。 */
.ent-liquor { display: flex; gap: 18px; align-items: center; padding: 4px 0; }
.ent-liquor label { display: flex; align-items: center; gap: 5px; font-size: var(--fs-md); color: #22334A; cursor: pointer; white-space: nowrap; }
.ent-liquor input[type="radio"] { accent-color: #1F4E79; cursor: pointer; }
.ent-hint { font-size: var(--fs-xs); color: #8A94A6; margin-top: 4px; line-height: var(--lh-loose); }
/* PDF 发票缩略图：<img> 渲染 PDF 会裂图，改成一个可点开的文字卡片 */
.upload-thumb.pdf-thumb { display: flex; align-items: center; justify-content: center; background: #FDF0E6; border-color: #F0C9A8; }
.upload-thumb.pdf-thumb a { color: #C0572F; font-size: var(--fs-md); font-weight: 700; text-decoration: none; letter-spacing: 0.5px; }
.upload-thumb.pdf-thumb a:hover { text-decoration: underline; }
/* 票据缩略图右下角的「下载」角标（2026-09-17）：同源 <a download>，点角标直接存本地。
   与点缩略图看大图互不干扰（两者是兄弟元素）；一直可见，不做 hover 才出现 —— 触屏设备没有 hover。 */
.upload-thumb .thumb-dl { position: absolute; right: 2px; bottom: 2px; width: 22px; height: 22px; background: rgba(15,34,56,0.78); color: #fff; border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: var(--fs-sm); line-height: 1; cursor: pointer; text-decoration: none; }
.upload-thumb .thumb-dl:hover { background: #1F4E79; }
/* 只读详情页的票据缩略图（2026-09-17）：
   默认 .upload-thumb 是 72×72 + object-fit:cover，会把 1240×430 的火车票裁成中间一条红边，
   财务根本看不出这是张什么票 —— 审票场景等于白给。这里改为按比例完整显示（contain）+ 加宽，
   并用白底衬托（票面本是白纸）。仅作用于带 thumb-receipt 的缩略图，不影响上传区/酒水票。 */
.upload-thumb.thumb-receipt { width: 112px; height: 80px; background: #fff; }
.upload-thumb.thumb-receipt img { object-fit: contain; }

/* 智能填报弹窗里的发票缩略图：可点开放大（2026-09-17 第 26 批）。
   72×72 + cover 的缩略图看不出票面，业务员没法核对「这张票是哪笔消费」。
   复用全站 image-preview-mask（z-index 2000 > .modal-mask 1000，天然盖在弹窗之上）。
   放大镜角标用 hover 淡入而非常驻：右下角留给 .thumb-dl、右上角被 × 占用，
   常驻第三个小角标会把 72px 的图塞得过满。触屏无 hover，靠 title 与 zoom-in 光标兜底。 */
#ai_upload_area .upload-thumb img { cursor: zoom-in; }
#ai_upload_area .upload-thumb::after {
  content: '🔍';
  position: absolute; left: 2px; bottom: 2px;
  width: 18px; height: 18px; border-radius: 5px;
  background: rgba(15, 34, 56, 0.72);
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; line-height: 1;
  opacity: 0; transition: opacity 0.15s;
  pointer-events: none;   /* 点角标等同点图，不拦事件 */
}
#ai_upload_area .upload-thumb:hover::after { opacity: 1; }

/* ============ 招待二级酒水明细 + 预估参照区（2026-09-15 二次修订）============
   「含酒水」「酒水外带」两种情形都要填酒水明细（字段对齐出差单酒水表）；
   区别只有：含酒水不传票、金额仅记录；外带必传票、金额计入总额。
   明细表用 .ent-liq-wrap 横向兜底（窄屏不挤压列宽）。 */
.ent-liq-wrap { overflow-x: auto; border: 1px solid #E3E9F0; border-radius: var(--radius-md); }
.ent-liq-table { width: 100%; border-collapse: collapse; font-size: var(--fs-md); min-width: 680px; }
.ent-liq-table th { background: #F5F8FC; color: #3D5166; font-weight: 600; text-align: left; padding: 7px 8px; border-bottom: 1px solid #E3E9F0; white-space: nowrap; }
.ent-liq-table td { padding: 5px 6px; border-bottom: 1px solid #EEF2F7; }
.ent-liq-table tbody tr:last-child td { border-bottom: none; }
.ent-liq-table tfoot td { background: #FAFCFE; font-size: var(--fs-md); color: #3D5166; padding: 7px 8px; border-top: 1px solid #E3E9F0; }
.ent-liq-table input, .ent-liq-table select { width: 100%; box-sizing: border-box; height: 30px; padding: 2px 6px; border: 1px solid #D8E0EA; border-radius: var(--radius-sm); font-size: var(--fs-lg); }
.ent-liq-table input:focus, .ent-liq-table select:focus { outline: none; border-color: #1F4E79; }
.ent-liq-table .el-total { white-space: nowrap; font-weight: 600; color: #1F4E79; }
.ent-liq-sum { margin-top: 6px; font-size: var(--fs-md); color: #3D5166; }
.ent-liq-sum b { color: #C0572F; }
/* 只读预估参照区（灰底虚线框，和可编辑区明确区分） */
.est-liq-box { background: #F7F9FC; border: 1px dashed #D8E0EA; border-radius: var(--radius-md); padding: 10px 12px; }
.est-liq-title { font-size: var(--fs-md); font-weight: 600; color: #3D5166; margin-bottom: 6px; }
.est-liq-empty { font-size: var(--fs-md); color: #8A94A6; padding: 4px 0; }
.est-liq-note { margin-top: 7px; font-size: var(--fs-xs); color: #8A94A6; line-height: var(--lh-loose); }
.est-liq-note b { color: #5A6B7F; }
/* 详情页里的酒水明细只读展示 */
.ent-liq-view { margin: 6px 0 8px; }
.ent-liq-view-title { font-size: var(--fs-xs); color: #8A94A6; margin-bottom: 4px; }
.ent-liq-view .ent-liq-table { min-width: 560px; }
.ent-liq-view .ent-liq-table td { color: #22334A; }

/* 汇总区 */
.summary-box { background: #F8FAFC; border-radius: var(--radius-md); padding: 12px 16px; margin: 16px 0; }
.summary-row { display: flex; justify-content: space-between; font-size: var(--fs-md); padding: 4px 0; }
.summary-row .label { color: #5A6B7F; }
.summary-row .value { font-weight: 600; }
.summary-row.total { border-top: 1px solid #EEF2F7; padding-top: 8px; margin-top: 4px; font-size: var(--fs-lg); }
.summary-row.total .value { color: #1F4E79; font-weight: 700; font-size: var(--fs-xl); }
.summary-row.refund .value { color: #D9534F; }

/* 差旅标准提示 */
.standard-tip { background: #FFF8E6; border-radius: var(--radius-md); padding: 8px 12px; border-left: 3px solid #E8B84B; font-size: var(--fs-xs); color: #8A6D2E; line-height: var(--lh-loose); margin: 12px 0; }

/* 弹窗
   ★ 第 91 批：标题栏「深蓝渐变」→「白底 + 0.5px 底边线」（与卡片头同语言，方案 §一.8）；
            底部按钮改为**右置**（方案 §一.8）；补**单层投影**（方案 §一.4）；补入场动效。
   为什么整批改：第 83 批 L1 全站换肤漏掉了 .modal-* —— 弹窗是全站唯一还留着旧色板的组件。
   34 处弹窗全走同一个 showModal()，所以只改这里一处，全站弹窗一起升级。 */
.modal-mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(23,35,61,0.5); display: flex; align-items: center; justify-content: center; z-index: 1000; padding: 20px; }
.modal { background: #fff; border-radius: var(--radius-lg); width: 100%; max-width: 640px; max-height: 85vh; display: flex; flex-direction: column; overflow: hidden; border: 0.5px solid rgba(0,0,0,.08); box-shadow: 0 8px 24px rgba(0,0,0,.12); animation: modalIn .18s ease-out; }
/* 入场动效：用 scale（不改**几何中心**）而非 translateY —— 桌面居中断言容差只有 8px，
   位移动画会在测量瞬间把中心推偏；scale 的中心恒定，既有「弹出」感又不干扰居中回归。 */
@keyframes modalIn { from { opacity: 0; transform: scale(.98); } to { opacity: 1; transform: scale(1); } }
/* 宽弹窗：出差申请/详情的酒水表有 7 列，560px 会逼出横向滚动、看不到「总价」，桌面上放宽到 760px */
/* 760 → 880：出差申请/详情改成「客户卡片 + 卡内酒水表」后，详情页的酒水合并总表
   多了一列「对应客户」（8 列），760 会把最后的总价列藏进横向滚动里。 */
.modal.modal-wide { max-width: 880px; }
.modal-header { background: #fff; padding: 14px 18px; color: #1A1D21; display: flex; justify-content: space-between; align-items: center; border-bottom: 0.5px solid rgba(0,0,0,.08); }
.modal-header h3 { font-size: var(--fs-lg); font-weight: 700; color: #1A1D21; }
/* 关闭按钮：× 文本 → 内联 SVG 线性图标（第 91 批 · 方案 §一.10）；28×28 命中区便于点按 */
.modal-header .close { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; flex: none; cursor: pointer; color: #8A94A6; border-radius: var(--radius-sm); font-size: 18px; }
.modal-header .close:hover { background: #F2F5F9; color: #1A1D21; }
.modal-header .close .svg-ico { width: 18px; height: 18px; vertical-align: 0; }
.modal-body { padding: 16px 18px; overflow-y: auto; flex: 1; }
/* 底部按钮右置（方案 §一.8）。手机端在 768 媒体查询里改回**等宽撑满**（移动端底部操作条惯例）。 */
.modal-footer { padding: 12px 18px; border-top: 0.5px solid rgba(0,0,0,.08); display: flex; gap: 10px; justify-content: flex-end; }
/* 入场动效的关停：总开关 / 系统「减弱动态效果」（与第 88 批动效体系同一套开关） */
:root[data-motion-off="1"] .modal { animation: none !important; }
@media (prefers-reduced-motion: reduce) { .modal { animation: none !important; } }

/* 审批历史时间线 */
.timeline { padding-left: 4px; }
.timeline-item { display: flex; gap: 10px; margin-bottom: 12px; position: relative; }
.timeline-dot { flex: 0 0 8px; display: flex; flex-direction: column; align-items: center; }
.timeline-dot .dot { width: 8px; height: 8px; border-radius: 50%; background: #1F4E79; margin-top: 5px; }
.timeline-dot .dot.green { background: #2E9E5B; }
.timeline-dot .dot.red { background: #D9534F; }
.timeline-dot .line { width: 1px; flex: 1; background: #DCE3EC; margin-top: 2px; }
.timeline-content { flex: 1; padding-bottom: 4px; }
.timeline-content .action { font-size: var(--fs-md); color: #17233D; }
.timeline-content .action b { font-weight: 600; }
.timeline-content .time { font-size: var(--fs-xs); color: #8A94A6; margin-top: 2px; }
.timeline-content .remark { font-size: var(--fs-xs); color: #D9534F; background: #FFF5F5; padding: 5px 8px; border-radius: var(--radius-sm); margin-top: 4px; }

/* 图片预览 */
.image-preview-mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.85); display: flex; align-items: center; justify-content: center; z-index: 2000; }
.image-preview-mask img { max-width: 90%; max-height: 85%; object-fit: contain; }
.image-preview-mask .close { position: absolute; top: 20px; right: 24px; color: #fff; font-size: 28px; cursor: pointer; }
/* 预览层底部工具条：计数 + 下载（2026-09-17 加下载功能时由 .counter 单元素改为条状容器） */
.preview-bar { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); display: flex; align-items: center; gap: 12px; }
.preview-counter { color: #fff; font-size: var(--fs-md); background: rgba(0,0,0,0.5); padding: 4px 12px; border-radius: var(--radius-lg); }
.preview-dl { display: inline-flex; align-items: center; gap: 6px; background: #1F4E79; color: #fff; font-size: var(--fs-md); padding: 8px 16px; border-radius: var(--radius-lg); text-decoration: none; white-space: nowrap; }
.preview-dl:hover { background: #17405F; }
/* PDF 票据无法当图片渲染（会裂图），预览层改为给一个「新窗口打开」的入口 */
.preview-pdf { color: #fff; font-size: var(--fs-lg); background: rgba(255,255,255,0.12); padding: 18px 28px; border-radius: var(--radius-md); }
.preview-pdf a { color: #fff; }

/* Toast */
.toast { position: fixed; top: 20px; left: 50%; transform: translateX(-50%); padding: 10px 20px; border-radius: var(--radius-md); font-size: var(--fs-md); color: #fff; z-index: 3000; box-shadow: 0 4px 12px rgba(0,0,0,0.15); animation: toastIn 0.3s; }
.toast.success { background: #2E9E5B; }
.toast.error { background: #D9534F; }
.toast.info { background: #1F4E79; }
@keyframes toastIn { from { opacity: 0; transform: translateX(-50%) translateY(-10px); } to { opacity: 1; transform: translateX(-50%) translateY(0); } }

/* 空状态 */
.empty-state { text-align: center; padding: 40px 20px; }
.empty-state .icon { width: 64px; height: 64px; border-radius: 50%; background: #F2F5F9; margin: 0 auto 12px; display: flex; align-items: center; justify-content: center; font-size: 24px; color: #C8D3E0; font-weight: 300; }
.empty-state .title { font-size: var(--fs-base); font-weight: 600; color: #3D5166; }
.empty-state .desc { font-size: var(--fs-sm); color: #8A94A6; margin-top: 4px; margin-bottom: 14px; }

/* 筛选tab */
/* 「出差与报销」模块内的两个页签（2026-09-15 上午侧栏两项合并后新增）
   ⚠️ 当日下午用户要求「把出差与报销的两个表重新拆开」→ 侧栏恢复两项、页签不再渲染，
      本组样式**当前无元素匹配**。保留不删，理由与 JS 里 docsTabsHTML 相同（同日反复过一次）。
   若恢复，注意刻意与下方 .filter-tabs（状态筛选）做出层次差：
   页签 = 浅灰轨道 + 白底选中药丸；筛选 = 白底 + 深蓝选中。
   两排若都做成深蓝 pill，用户会分不清哪排是「换单据类型」、哪排是「筛状态」。 */
.docs-tabs { display: inline-flex; gap: 4px; padding: 4px; background: #EEF2F7; border-radius: var(--radius-md); margin-bottom: 14px; }
.docs-tab { display: flex; align-items: center; gap: 6px; padding: 7px 18px; border-radius: var(--radius-md); font-size: var(--fs-md); color: #5A6B7F; cursor: pointer; user-select: none; }
.docs-tab.active { background: #fff; color: #1F4E79; font-weight: 600; box-shadow: 0 1px 2px rgba(31,78,121,0.10); }
.docs-tab-badge { min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--radius-md); background: #D9534F; color: #fff; font-size: var(--fs-xs); line-height: 18px; text-align: center; font-weight: 600; }
.docs-tab.active .docs-tab-badge { background: #1F4E79; }
@media (max-width: 640px) { .docs-tabs { display: flex; width: 100%; } .docs-tab { flex: 1; justify-content: center; padding: 7px 8px; } }
.filter-tabs { display: flex; gap: 8px; margin-bottom: 14px; }
.filter-tab { padding: 7px 16px; background: #fff; border: 1px solid #DCE3EC; border-radius: var(--radius-md); font-size: var(--fs-sm); color: #8A94A6; cursor: pointer; }
.filter-tab.active { background: #1F4E79; color: #fff; border-color: #1F4E79; font-weight: 600; }

/* ============ 基础设置：预算设置 / 差旅标准 两栏并排（2026-09-15 用户要求）============
   用户原话「把这两个并在一起，这两个一行并排展示」→ 同屏左右两栏，各自带保存按钮。
   刻意与 .docs-tabs（页签切换）不同：这里是**同时可见**，不是二选一。
   ⚠️ 与 §6.10/§6.13 同一条理由：必须写 minmax(0,1fr)，裸 1fr 的最小宽度是 min-content，
      栏内 form-group 的输入框会把它顶开、整页横向溢出。
   ⚠️ 窄屏回落单列（与 .detail-clients 同一断点 900px，保证同一屏内两种并排行为一致）。 */
.base-settings-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; align-items: start; margin-bottom: 4px; }
.base-settings-grid .card { max-width: none; margin-bottom: 0; }
.base-card-head { font-size: var(--fs-base); font-weight: 600; color: #1F4E79; margin-bottom: 4px; }
.base-card-sub { font-size: var(--fs-sm); color: #8A94A6; line-height: var(--lh-loose); margin-bottom: 14px; }
@media (max-width: 900px) { .base-settings-grid { grid-template-columns: minmax(0, 1fr); } }

/* 列表页搜索框：按单号 / 客户 / 申请人检索 */
.search-bar { margin-bottom: 14px; }
.search-input {
  width: 100%; max-width: 340px; padding: 8px 12px;
  border: 1px solid #C8D3E0; border-radius: var(--radius-md); background: #fff;
  font-size: var(--fs-lg); color: #22303F; outline: none; transition: border-color 0.2s;
}
.search-input:focus { border-color: #1F4E79; }
.search-input::placeholder { color: #A9B4C2; }

/* 列表页筛选条：主按钮 + 多个下拉筛选 + 搜索框一行排布（NCR 列表首用，2026-09-25）
   规范对齐：输入控件一律 --fs-lg（iOS 聚焦不放大阈值）、描边 #C8D3E0、圆角 --radius-md、
   聚焦深蓝描边 —— 与 .search-input / .form-group input 同一套 token，不允许裸原生控件。 */
.filter-bar { display: flex; gap: 8px; align-items: center; margin-bottom: 14px; flex-wrap: wrap; }
.filter-bar select {
  height: 40px; padding: 8px 30px 8px 12px; border: 1px solid #C8D3E0; border-radius: var(--radius-md);
  background: #fff url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%235A6478' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat right 10px center;
  appearance: none; -webkit-appearance: none;
  font-size: var(--fs-lg); color: #22303F; outline: none; transition: border-color 0.2s; cursor: pointer;
}
.filter-bar select:focus { border-color: #1F4E79; }
.filter-bar select:hover { border-color: #A8BDD6; }
.filter-bar .filter-search {
  flex: 1; min-width: 160px; height: 40px; padding: 8px 12px;
  border: 1px solid #C8D3E0; border-radius: var(--radius-md); background: #fff;
  font-size: var(--fs-lg); color: #22303F; outline: none; transition: border-color 0.2s;
}
.filter-bar .filter-search:focus { border-color: #1F4E79; }
.filter-bar .filter-search::placeholder { color: #A9B4C2; }
.filter-bar .btn { height: 40px; padding: 8px 16px; flex: none; }

/* ★ 第 77 批：NCR 列表快捷筛选开关（「只看逾期」「只看我负责」）
   ⚠️ 刻意用 <button class="ncr-toggle"> 而非 <select> —— verify_ncr_toolbar_ui 断言
      「.filter-bar 下拉 4 个」+「控件同行对齐」，多一个 select 会集体假红。
   放在搜索框之后且 flex:none：前 5 个控件（4 下拉 + 搜索框）必然仍在同一行。 */
.filter-bar .ncr-toggle {
  height: 40px; padding: 0 14px; flex: none; display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid #C8D3E0; border-radius: 20px; background: #fff; cursor: pointer;
  font-size: var(--fs-sm); color: #5A6478; transition: all .15s; white-space: nowrap;
}
.filter-bar .ncr-toggle:hover { border-color: #A8BDD6; color: #22303F; }
.filter-bar .ncr-toggle.on { background: #EAF0F7; border-color: #1F4E79; color: #1F4E79; font-weight: 600; }
.filter-bar .ncr-toggle .nt-cnt { font-size: var(--fs-xs); opacity: .75; }

/* NCR 列表分页页脚（第 77 批） */
.ncr-pager { display: flex; align-items: center; gap: 10px; margin-top: 10px; font-size: var(--fs-xs); color: #8A94A6; }
.ncr-pager .np-btn {
  padding: 4px 10px; border: 1px solid #DCE3EC; border-radius: var(--radius-sm); background: #fff;
  color: #22303F; cursor: pointer; font-size: var(--fs-xs);
}
.ncr-pager .np-btn:hover:not(:disabled) { border-color: #1F4E79; color: #1F4E79; }
.ncr-pager .np-btn:disabled { color: #C2CAD6; cursor: not-allowed; background: #FAFBFC; }
.ncr-pager .np-info { margin-left: auto; }

/* 预算进度条 */
.budget-box { background: #fff; border-radius: var(--radius-md); border: 1px solid #DCE3EC; padding: 16px; margin-bottom: 16px; }
.dash-paid-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; }
.dash-paid-row .budget-box { margin-bottom: 0; }
.paid-month-box { background: #fff; border-radius: var(--radius-md); border: 1px solid #DCE3EC; padding: 16px; display: flex; flex-direction: column; }
.paid-month-box .budget-info { margin-top: auto; }
.budget-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.budget-header .title { font-size: var(--fs-md); font-weight: 600; }
.budget-amount { display: flex; align-items: baseline; gap: 6px; }
.budget-amount .used { font-size: var(--fs-2xl); font-weight: 700; color: #1F4E79; }
.budget-amount .total { font-size: var(--fs-sm); color: #8A94A6; }
.budget-bar { height: 8px; background: #EEF2F7; border-radius: var(--radius-sm); overflow: hidden; margin-bottom: 6px; }
.budget-bar-fill { height: 100%; border-radius: var(--radius-sm); transition: width 0.5s; }
.budget-bar-fill.green { background: linear-gradient(90deg, #2E9E5B, #4CAF7A); }
.budget-bar-fill.yellow { background: linear-gradient(90deg, #E8B84B, #F0C858); }
.budget-bar-fill.red { background: linear-gradient(90deg, #D9534F, #E8706B); }
.budget-info { display: flex; justify-content: space-between; font-size: var(--fs-xs); }
.budget-info .percent { font-weight: 600; }

/* 手机端顶部导航（原底部导航，已上移） */
.mobile-nav { display: none; position: fixed; top: 48px; left: 0; right: 0; background: #fff; border-bottom: 1px solid #E8EAEE; padding: 8px 0; z-index: 99; }
.mobile-nav-item { flex: 1; text-align: center; cursor: pointer; padding: 4px 0; }
.mobile-nav-item .label { font-size: var(--fs-md); color: #5A6B7F; display: flex; align-items: center; justify-content: center; gap: 4px; }
.mobile-nav-item.active .label { color: #185FA5; font-weight: 600; }

/* 响应式 */
@media (max-width: 768px) {
  .login-box { flex-direction: column; max-width: 400px; }
  .login-brand { flex: none; }
  .login-brand-logo { padding: 20px; }
  .login-brand-logo img { max-width: 90px; }
  .login-brand-info { padding: 18px 20px; }
  .login-form { padding: 24px 20px; }
  .app-sidebar { display: none; }
  .app-header { padding: 0 14px; height: 48px; }
  .app-header-left img { height: 24px; }
  /* ★ 第 85 批补丁 v3：手机端「耀润」同样翻倍（14 → 28px）；.en 规则随副标题删除而移除。 */
  .app-header-left .title { font-size: calc(var(--fs-base) * 2); }
  .header-user .name, .header-user .role { display: none; }
  .app-content { padding: 14px; padding-top: 100px; }
  .page-title { font-size: var(--fs-lg); }
  /* 用 grid 2 列替代 flex:1 1 45%（UI 审核 P0-3）——
     flex 的 grow 会把「奇数张时的最后一张」撑满整行剩余空间：5 张卡渲染成
     177/177/177/177/362，极差 185px，最后一张比其它宽一倍。
     grid 每列固定等宽，最后一张只占半宽，既不翻倍也不留白。 */
  .stats-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  .stat-card { min-width: 0; padding: 12px; }
  .stat-card .value { font-size: var(--fs-2xl); }
  .form-row .form-group { flex: 1 1 100%; }
  .table-wrap { overflow-x: auto; }
  .mobile-nav { display: flex; }
  .modal { max-width: 100%; max-height: 90vh; border-radius: var(--radius-lg) var(--radius-lg) 0 0; position: fixed; bottom: 0; left: 0; right: 0; }
  .modal.modal-wide { max-width: 100%; }
  .modal-mask { align-items: flex-end; padding: 0; background: rgba(23,35,61,0.5); }
  /* 手机端底部操作条：按钮等宽撑满（移动端惯例；且 M6 断言要求两个按钮等宽、高度 ≥ 36px） */
  .modal-footer .btn { flex: 1; }
}

/* 加载骨架 */
.skeleton { background: #E8EDF3; border-radius: var(--radius-sm); animation: shimmer 1.5s infinite; }
@keyframes shimmer { 0% { opacity: 0.6; } 50% { opacity: 1; } 100% { opacity: 0.6; } }

/* 行内文字操作链接 */
.link-action { color: #1F4E79; cursor: pointer; margin-right: 10px; white-space: nowrap; }
.link-action:hover { text-decoration: underline; }
.link-action.danger { color: #D9534F; }
.link-action.ok { color: #2E9E5B; }

/* 退回原因提示 */
.reject-note { background: #FFF5F5; border-left: 3px solid #D9534F; border-radius: var(--radius-md); padding: 10px 12px; font-size: var(--fs-sm); color: #B83A36; margin-bottom: 12px; line-height: var(--lh-loose); }

/* 审批弹窗顶部预算超支警告条 */
.budget-alert { background: #FFF0F0; border-left: 3px solid #D9534F; border-radius: var(--radius-md); padding: 10px 12px; font-size: var(--fs-md); color: #B83A36; font-weight: 600; margin-bottom: 12px; }

/* 图片预览左右切换 */
.image-preview-mask .nav { position: absolute; top: 50%; transform: translateY(-50%); color: #fff; font-size: 40px; line-height: var(--lh-num); cursor: pointer; padding: 10px 16px; user-select: none; opacity: 0.75; }
.image-preview-mask .nav:hover { opacity: 1; }
.image-preview-mask .nav.prev { left: 8px; }
.image-preview-mask .nav.next { right: 8px; }

/* 手机端补偿：触控区与正文字号（设计文档 7.4） */
@media (max-width: 768px) {
  .btn { min-height: 44px; }
  .filter-tab { min-height: 40px; display: inline-flex; align-items: center; }
  .sidebar-item, .mobile-nav-item { min-height: 44px; }
  .app-content { font-size: var(--fs-base); }
  .app-content td, .app-content .form-group label { font-size: var(--fs-md); }

  /* 列表卡片化：不做横向滚动表格（设计文档 5.1.2） */
  .table-wrap.cardify { border: none; background: transparent; }
  .table-wrap.cardify table,
  .table-wrap.cardify tbody,
  .table-wrap.cardify tr,
  .table-wrap.cardify td { display: block; width: 100%; }
  .table-wrap.cardify thead { display: none; }
  .table-wrap.cardify tr { background: #fff; border: 1px solid #DCE3EC; border-radius: var(--radius-md); padding: 10px 14px; margin-bottom: 10px; }
  .table-wrap.cardify td { border-bottom: none; padding: 5px 0; display: flex; justify-content: space-between; align-items: center; gap: 12px; text-align: right; }
  .table-wrap.cardify td::before { content: attr(data-label); color: #8A94A6; font-size: var(--fs-sm); flex: 0 0 auto; text-align: left; }
  .table-wrap.cardify td:first-child { border-bottom: 1px dashed #EEF2F7; padding-bottom: 8px; margin-bottom: 4px; }
  .table-wrap.cardify td:first-child::before { display: none; }
  .table-wrap.cardify td:first-child > div { text-align: left; }
  .table-wrap.cardify tr:hover td { background: transparent; }
}

/* ============ 销售总监工作台 ============ */
/* 统计卡里的金额字号略小，避免「¥12,050.00」在窄卡片里折行 */
.wb-stat .value.amt { font-size: var(--fs-2xl); letter-spacing: -0.3px; }
.wb-card { padding: 0; overflow: hidden; }

/* 待我审批 / 已审批 双 tab */
.wb-tabs { display: flex; gap: 4px; padding: 0 16px; border-bottom: 1px solid #EEF2F7; }
.wb-tab {
  padding: 13px 4px; margin-right: 22px; font-size: var(--fs-md); color: #8A94A6; cursor: pointer;
  border-bottom: 2px solid transparent; display: flex; align-items: center; gap: 6px;
  transition: color .15s, border-color .15s;
}
.wb-tab:hover { color: #1F4E79; }
.wb-tab.active { color: #1F4E79; font-weight: 600; border-bottom-color: #1F4E79; }
.wb-tab-count {
  background: #D9534F; color: #fff; font-size: var(--fs-xs); font-weight: 700; line-height: var(--lh-num);
  min-width: 17px; height: 17px; border-radius: var(--radius-md); padding: 0 5px;
  display: inline-flex; align-items: center; justify-content: center;
}
.wb-tab-count.zero { background: #C8D3E0; }
.wb-list { padding: 4px 0 8px; }

/* 分组小标题（出差申请 / 报销单） */
.wb-group { font-size: var(--fs-sm); color: #8A94A6; font-weight: 600; letter-spacing: .3px; padding: 12px 16px 6px; display: flex; align-items: center; gap: 6px; }
.wb-group-n { background: #EAF0F7; color: #1F4E79; font-size: var(--fs-xs); padding: 1px 6px; border-radius: var(--radius-md); }

/* 审批条目：左侧信息可点开详情，右侧内联操作 */
.wb-item { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-top: 1px solid #F4F7FA; transition: background .15s; }
.wb-item:hover { background: #FAFCFE; }
.wb-item-body { flex: 1; min-width: 0; cursor: pointer; }
.wb-item-line1 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.wb-item-type { font-size: var(--fs-xs); color: #8A94A6; font-family: ui-monospace, Menlo, monospace; background: #F4F7FA; padding: 2px 7px; border-radius: var(--radius-sm); flex-shrink: 0; }
.wb-item-title { font-size: var(--fs-md); font-weight: 600; color: #17233D; }
.wb-item-amt { margin-left: auto; font-size: var(--fs-md); font-weight: 700; color: #1F4E79; white-space: nowrap; }
.wb-item-next { font-size: var(--fs-xs); color: #8A94A6; }
.wb-item-line2 { font-size: var(--fs-sm); color: #8A94A6; margin-top: 5px; line-height: var(--lh-loose); }
.wb-item-line2 b { color: #3D5166; font-weight: 600; }
.wb-item-ops { display: flex; gap: 8px; flex-shrink: 0; }
.op-btn { padding: 6px 15px; border-radius: var(--radius-md); font-size: var(--fs-md); font-weight: 600; border: 1px solid transparent; background: #fff; transition: all .15s; white-space: nowrap; }
.op-btn.ok { background: #2E9E5B; color: #fff; }
.op-btn.ok:hover { background: #25804A; }
.op-btn.no { background: #fff; color: #D9534F; border-color: #E8B4B2; }
.op-btn.no:hover { background: #FFF5F5; border-color: #D9534F; }

/* 已审批中被打回的单据：整条浅红底，驳回意见铺满一行 */
.wb-item.done.is-rejected { background: #FFF7F7; flex-wrap: wrap; }
.wb-item.done.is-rejected:hover { background: #FFF2F2; }
.wb-reject { flex: 1 1 100%; background: #FFF0F0; border-left: 3px solid #D9534F; border-radius: var(--radius-md); padding: 9px 12px; font-size: var(--fs-sm); color: #B83A36; line-height: var(--lh-loose); margin-top: 8px; }
.wb-reject b { font-weight: 700; }

/* 空状态 */
.wb-empty { text-align: center; padding: 44px 20px; }
.wb-empty-icon { width: 52px; height: 52px; border-radius: 50%; background: #EAF0F7; color: #2E9E5B; font-size: 22px; display: flex; align-items: center; justify-content: center; margin: 0 auto 12px; }
.wb-empty-title { font-size: var(--fs-base); font-weight: 600; color: #3D5166; }
.wb-empty-desc { font-size: var(--fs-sm); color: #8A94A6; margin-top: 4px; }

/* 底部两栏：趋势图 + 类别占比 */
.wb-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 16px; }
.wb-grid .card { margin-bottom: 0; }
.wb-chart-empty { text-align: center; padding: 34px 0; color: #C8D3E0; font-size: var(--fs-sm); }

/* 柱状图（纯 CSS，无图表库） */
.wb-bars { display: flex; align-items: flex-end; gap: 14px; height: 150px; padding: 6px 4px 0; }
/* min-width:0 不可省（UI 审核 P0-2）——
   flex 子项默认 min-width:auto，会被列内「X月」+「1.2万」的文字宽度锁成 24px 不可压缩，
   12 列合计恒 407px，硬撑进手机 332px 容器 → 最右侧的当月柱被裁出屏外，
   连 430px 的 iPhone Pro Max 都还看不到 9 月。设为 0 后列宽改由容器均分，12 个月全可见。 */
.wb-bar-col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; height: 100%; }
.wb-bar-val { font-size: var(--fs-xs); color: #8A94A6; margin-bottom: 5px; height: 13px; }
.wb-bar-track { flex: 1; width: 100%; display: flex; align-items: flex-end; justify-content: center; }
.wb-bar-fill { width: 72%; max-width: 46px; background: linear-gradient(180deg, #4A7FA8, #2E5F8C); border-radius: var(--radius-sm) var(--radius-sm) 0 0; transition: height .5s ease; }
.wb-bar-fill.cur { background: linear-gradient(180deg, #2E6FA8, #1F4E79); }
.wb-bar-label { font-size: var(--fs-xs); color: #8A94A6; margin-top: 7px; }
.wb-bar-label.cur { color: #1F4E79; font-weight: 700; }

/* 类别占比条 */
.wb-share { display: flex; flex-direction: column; gap: 13px; padding-top: 2px; }
.wb-share-top { display: flex; align-items: baseline; gap: 8px; font-size: var(--fs-md); margin-bottom: 5px; }
.wb-share-name { display: flex; align-items: center; gap: 7px; color: #3D5166; }
.wb-share-name i { width: 8px; height: 8px; border-radius: var(--radius-sm); display: inline-block; }
.wb-share-amt { margin-left: auto; font-size: var(--fs-sm); color: #8A94A6; }
.wb-share-pct { font-weight: 700; color: #17233D; min-width: 34px; text-align: right; }
.wb-share-track { height: 6px; background: #EEF2F7; border-radius: var(--radius-sm); overflow: hidden; }
.wb-share-fill { height: 100%; border-radius: var(--radius-sm); transition: width .5s; }

/* 业务员报销金额横向条形图 */
.sm-rows { display: flex; flex-direction: column; gap: 12px; padding-top: 2px; }
.sm-row { display: flex; align-items: center; gap: 10px; font-size: var(--fs-md); }
.sm-name { width: 56px; flex-shrink: 0; color: #3D5166; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sm-track { flex: 1; height: 8px; background: #EEF2F7; border-radius: var(--radius-sm); overflow: hidden; }
.sm-fill { height: 100%; border-radius: var(--radius-sm); background: linear-gradient(90deg, #4A7FA8, #2E5F8C); transition: width .5s; }
.sm-amt { flex-shrink: 0; min-width: 52px; text-align: right; font-weight: 600; color: #17233D; }
/* ★ 2026-09-17 第 28 批：数据统计「各月业务员报销」里带 user_id 的行可点 → 直达该业务员台账逐月明细。
   交互语言与台账卡（.ledger-person）保持一致；负外边距抵消内边距，行间距视觉不变。 */
.sm-row-link { cursor: pointer; margin: 0 -6px; padding: 3px 6px; border-radius: var(--radius-sm); transition: background .15s; }
.sm-row-link:hover { background: #F0F5FB; }
.sm-row-link:hover .sm-name { color: #1F4E79; font-weight: 600; }

/* 数据统计页顶部紧凑图表区（4 栏小卡片，紧贴标题） */
.dash-charts { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 16px; }
.dash-chart { background: #fff; border: 1px solid #DCE3EC; border-radius: var(--radius-md); padding: 12px 14px; min-width: 0; }
.dash-chart-title { font-size: var(--fs-md); font-weight: 600; color: #17233D; margin-bottom: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dash-chart .wb-bars { height: 96px; gap: 8px; }
/* 注：数据统计页唯一含柱状图的 .dash-chart 就是那个 dash-full 整宽卡片（列宽约 89px，
   放得下「7.15万」）；另外两个 4 栏小格子里放的是占比条与横向条形图，不含柱状图。
   窄列（手机端每列 16~26px）的数值咬合问题，统一由下方 @media (max-width: 560px) 处理。 */
.dash-chart .wb-bar-val { font-size: var(--fs-xs); }
.dash-chart .wb-bar-fill { max-width: 22px; }
.dash-chart .wb-share { gap: 8px; }
.dash-chart .sm-rows { gap: 8px; }
.dash-chart .sm-name { width: 44px; }
.dash-chart .sm-amt { min-width: 42px; font-size: var(--fs-xs); }
.dash-chart .sm-row { font-size: var(--fs-sm); }

/* 数据统计页 · 2026-09-14 新布局：整行 12 月趋势 → 两栏卡（类别占比 / 年度报销）→ 4×3 逐月业务员卡 */
.dash-full { display: block; margin-bottom: 16px; }
.dash-full .wb-bars { height: 200px; gap: 10px; }
.dash-full .wb-bar-fill { max-width: 52px; }
.dash-full .wb-bar-val { font-size: var(--fs-xs); }
.dash-full .wb-bar-label { font-size: var(--fs-sm); }
.dash-chart-note { font-size: var(--fs-xs); font-weight: 400; color: #8A94A6; margin-left: 8px; }
.dash-row-half { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; }
.dash-row-half .dash-chart { padding: 14px 16px; }
.dash-row-half .wb-share { gap: 12px; }
.dash-row-half .sm-rows { gap: 11px; }
.dash-section-title { font-size: var(--fs-md); font-weight: 600; color: #17233D; margin: 4px 0 10px; }
.dash-month-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.dash-month-grid .month-card { padding: 11px 13px; }
.month-card .dash-chart-title { margin-bottom: 9px; font-size: var(--fs-sm); }
.month-card .sm-rows { gap: 7px; }
.month-card .sm-name { width: 48px; }
.month-card .sm-amt { min-width: 46px; font-size: var(--fs-xs); }
.month-card .sm-row { font-size: var(--fs-sm); }
.month-card .wb-chart-empty { padding: 14px 0; }
.month-card.is-cur { border-color: #9CBEE0; background: #F7FAFD; }
.month-card.is-cur .dash-chart-title { color: #1F4E79; }

/* ===== 业务员台账（2026-09-14）===== */
/* 入口条：数据统计页底部 + 手机端可达 */
.ledger-entry { display: flex; align-items: center; gap: 10px; margin-top: 16px; padding: 13px 16px;
  background: #F7FAFD; border: 1px solid #DCE6F2; border-radius: var(--radius-md); cursor: pointer; transition: all .15s; }
.ledger-entry:hover { background: #EFF6FC; border-color: #9CBEE0; }
.ledger-entry .le-title { font-size: var(--fs-md); font-weight: 600; color: #1F4E79; }
.ledger-entry .le-desc { flex: 1; font-size: var(--fs-sm); color: #8A94A6; }
.ledger-entry .le-go { font-size: var(--fs-sm); color: #1F4E79; font-weight: 500; }

/* 仅手机端显示的入口条（管理岗报销入口：PC 端侧栏已有菜单，不必重复占位）*/
.only-mobile { display: none !important; }
@media (max-width: 900px) { .only-mobile { display: flex !important; } }

/* 列表页：业务员卡 */
.ledger-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.ledger-person { background: #fff; border: 1px solid #E8ECF3; border-radius: var(--radius-md); padding: 14px 16px;
  cursor: pointer; transition: all .15s; }
.ledger-person:hover { border-color: #1F4E79; box-shadow: 0 3px 12px rgba(31, 78, 121, .1); transform: translateY(-1px); }
.ledger-person .lp-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.ledger-person .lp-name { font-size: var(--fs-base); font-weight: 600; color: #17233D; }
.ledger-person .lp-year { font-size: var(--fs-xs); color: #8A94A6; white-space: nowrap; }
.ledger-person .lp-mid { display: flex; align-items: baseline; gap: 8px; margin-top: 8px; }
.ledger-person .lp-big { font-size: var(--fs-2xl); font-weight: 700; color: #1F4E79; }
.ledger-person .lp-tag { font-size: var(--fs-xs); color: #8A94A6; }
.ledger-person .lp-spark { display: flex; align-items: flex-end; gap: 3px; height: 34px; margin: 11px 0 9px; }
.ledger-person .lp-spark-col { flex: 1; min-height: 3px; background: #E1E9F4; border-radius: var(--radius-sm); }
.ledger-person .lp-spark-col.has { background: #1F4E79; }
.ledger-person .lp-foot { display: flex; justify-content: space-between; align-items: center;
  border-top: 1px solid #F0F3F8; padding-top: 9px; font-size: var(--fs-sm); color: #5A6478; }
.ledger-person .lp-go { color: #1F4E79; font-weight: 500; }
.ledger-person .lp-inflight { margin-top: 8px; font-size: var(--fs-xs); color: #8A6D3B; }

/* 「费用构成」迷你条（paintLedgerCats() 产出的 .lp-cats* 骨架）。
   ★ 一个大坑：这些规则**必须限定作用域**，因为同一段 HTML 有三个宿主、形态各不相同：
     ① `.ledger-person`（业务员台账卡片）——窄卡约 280-300px，单列图例；
     ② `.cu-cats-host`（客户详情页）——独立白底块 + 12px 粗条 + 多列图例（见文件下半部）；
     ③ `.cu-card-cats`（客户台账卡片，2026-09-17 第 36 批新增）——与 ① 同形态，故并列共用本条。
   ⚠️ 漏掉任一宿主 ⇒ 该处的迷你条会**无样式裸奔**（灰底黑字、堆叠条变一列方块）。
      新增宿主时务必回到这里并列选择器，别指望样式自动继承。
   ⚠️ 图例 2026-09-15 由 `1fr 1fr` 两列改为**单列**：金额比 "52%" 长得多，
      「交通费 ¥26,880.00」放在约 130px 宽的半列里会溢出撑破卡片；单列后每行独占整宽才放得下。
      仍保留 `min-width:0` + 金额 `overflow:hidden` 作兜底，防超大金额撑破卡片。 */
.ledger-person .lp-cats, .cu-card-cats .lp-cats { margin-top: 10px; }
.ledger-person .lp-cats-head, .cu-card-cats .lp-cats-head { display: flex; justify-content: space-between; align-items: baseline;
  gap: 6px; font-size: var(--fs-xs); color: #5A6478; margin-bottom: 5px; }
.ledger-person .lp-cats-note, .cu-card-cats .lp-cats-note { font-size: var(--fs-xs); color: #8A94A6; white-space: nowrap; }
.ledger-person .lp-cats-bar, .cu-card-cats .lp-cats-bar { display: flex; height: 8px; border-radius: var(--radius-sm); overflow: hidden;
  background: #EEF2F7; }
.ledger-person .lp-cat-seg, .cu-card-cats .lp-cat-seg { height: 100%; min-width: 0; }
.ledger-person .lp-cats-legend, .cu-card-cats .lp-cats-legend { display: grid; grid-template-columns: 1fr; gap: 3px;
  margin-top: 7px; font-size: var(--fs-xs); color: #5A6478; }
.ledger-person .lp-cat-item, .cu-card-cats .lp-cat-item { display: flex; align-items: center; gap: 4px; min-width: 0;
  white-space: nowrap; }
.ledger-person .lp-cat-item i, .cu-card-cats .lp-cat-item i { width: 7px; height: 7px; border-radius: var(--radius-sm); flex: none; }
.ledger-person .lp-cat-item b, .cu-card-cats .lp-cat-item b { margin-left: auto; font-weight: 600; color: #17233D;
  overflow: hidden; text-overflow: ellipsis; }
.ledger-person .lp-cat-item.is-zero, .cu-card-cats .lp-cat-item.is-zero { color: #B6BFCC; }
.ledger-person .lp-cat-item.is-zero b, .cu-card-cats .lp-cat-item.is-zero b { font-weight: 400; color: #B6BFCC; }
.ledger-person .lp-cats-empty, .cu-card-cats .lp-cats-empty { font-size: var(--fs-xs); color: #B6BFCC; padding: 1px 0 2px; }

/* 明细页：返回条 + 逐月折叠行 */
.ld-topbar { display: flex; align-items: center; gap: 12px; margin-bottom: 4px; }
.ld-topbar .ld-back { font-size: var(--fs-md); color: #1F4E79; cursor: pointer; }
.ld-topbar .ld-back:hover { text-decoration: underline; }
.ld-topbar .ld-who { font-size: var(--fs-xl); font-weight: 700; color: #17233D; }
.ld-month { background: #fff; border: 1px solid #E8ECF3; border-radius: var(--radius-md); margin-bottom: 9px; overflow: hidden; }
.ld-month .ld-month-head { display: flex; align-items: center; justify-content: space-between;
  padding: 12px 16px; cursor: pointer; }
.ld-month .ld-month-head:hover { background: #FAFCFE; }
.ld-month .ld-m { font-size: var(--fs-md); font-weight: 600; color: #17233D; }
.ld-month .ld-right { display: flex; align-items: center; gap: 12px; }
.ld-month .ld-amt { font-size: var(--fs-base); font-weight: 700; color: #1F4E79; }
.ld-month .ld-amt.zero { color: #C3CAD6; font-weight: 500; }
.ld-month .ld-cnt { font-size: var(--fs-sm); color: #8A94A6; min-width: 44px; text-align: right; }
.ld-month .ld-arrow { font-size: var(--fs-xs); color: #8A94A6; transition: transform .15s; }
.ld-month.open .ld-arrow { transform: rotate(180deg); }
.ld-month.open .ld-month-head { background: #F7FAFD; border-bottom: 1px solid #EEF2F7; }
.ld-month .ld-reports { display: none; padding: 10px 16px 12px; }
.ld-month.open .ld-reports { display: block; }
.ld-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.ld-table th { text-align: left; font-weight: 500; color: #8A94A6; font-size: var(--fs-xs);
  padding: 6px 8px; border-bottom: 1px solid #EEF2F7; }
.ld-table td { padding: 7px 8px; border-bottom: 1px solid #F4F7FB; color: #33405A; }
.ld-table tr:last-child td { border-bottom: none; }
.ld-table .ld-no { font-family: ui-monospace, Menlo, monospace; font-size: var(--fs-sm); color: #5A6478; white-space: nowrap; }
.ld-table .ld-amt-cell { font-weight: 600; color: #1F4E79; white-space: nowrap; }
/* ---- 台账逐月明细：勾选列 / 单号链接 / 导出工具条（2026-09-17 第 22 批）---- */
.ld-table .ld-ck { width: 30px; padding-right: 2px; }
.ld-table .ld-ck input { width: 15px; height: 15px; margin: 0; vertical-align: middle; cursor: pointer; accent-color: #1F4E79; }
/* 已勾选行整行淡蓝，让「选了哪几张」一眼可见（一张几十行时很必要） */
.ld-table tr.is-picked td { background: #F2F8FE; }
/* 单号做成「可点」的样子：虚线下划线比实线轻，与等宽字体更搭。
   ⚠️ 用 <span class="ld-link" onclick> 而不是 <a href="javascript:;"> —— 站点 CSP 的
      `script-src-elem 'self'` 会拦掉 javascript: URL（控制台报违规、且是刻意做的安全加固）。
      全站内联点击元素（.ld-back / .ld-month-head / .ledger-person）也都是 span 写法，保持一致。 */
.ld-table .ld-no .ld-link { color: #1B6FB8; text-decoration: none; border-bottom: 1px dashed #9CC3E4; cursor: pointer; }
.ld-table .ld-no .ld-link:hover { color: #14568C; border-bottom-style: solid; }
.ld-export-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; padding: 9px 12px; background: #F7FAFD; border: 1px solid #E8ECF3; border-radius: var(--radius-md); }
/* 工具条内按钮统一收小一档 —— 用作用域覆盖，不新增全局 .btn-sm，避免影响别处按钮 */
.ld-export-bar .btn { padding: 6px 12px; font-size: var(--fs-sm); font-weight: 500; }
.ld-export-bar .export-btn { padding: 6px 12px; font-size: var(--fs-sm); }
.ld-export-hint { font-size: var(--fs-xs); color: #8A94A6; margin-left: auto; }
.ld-tag { display: inline-block; padding: 1px 7px; border: 1px solid; border-radius: var(--radius-md); font-size: var(--fs-xs); }
.ld-empty { font-size: var(--fs-sm); color: #8A94A6; padding: 6px 0; }

@media (max-width: 1200px) {
  .dash-month-grid { grid-template-columns: repeat(3, 1fr); }
  .ledger-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 900px) {
  .dash-month-grid { grid-template-columns: 1fr 1fr; }
  .dash-row-half { grid-template-columns: 1fr; }
  .ledger-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 768px) {
  .dash-charts { grid-template-columns: 1fr 1fr; }
  .dash-paid-row { grid-template-columns: 1fr; }
  .dash-full .wb-bars { height: 150px; }
  .ledger-grid { grid-template-columns: 1fr; }
  .ledger-entry .le-desc { display: none; }
  .led-month .ld-right { gap: 8px; }
}

/* 审批确认弹窗内的单据摘要 */
.wb-confirm { background: #F8FAFC; border-radius: var(--radius-md); padding: 12px 14px; }
.wb-confirm-row { display: flex; justify-content: space-between; gap: 12px; font-size: var(--fs-md); padding: 4px 0; }
.wb-confirm-row span { color: #5A6B7F; flex-shrink: 0; }
.wb-confirm-row b { color: #17233D; text-align: right; }
.wb-confirm-tip { font-size: var(--fs-sm); color: #8A94A6; margin-top: 10px; line-height: var(--lh-loose); }

/* 打款确认弹窗内的退款方式单选（2026-09-17 新增）——替代原生 prompt：
   原生弹层由浏览器定位（贴顶、样式固定），无法居中；改到站内弹窗后由 .modal-mask flex 居中 */
.pay-refund-pick { margin-top: 12px; background: #F8FAFC; border-radius: var(--radius-md); padding: 12px 14px; }
.pay-refund-title { font-size: var(--fs-md); color: #17233D; font-weight: 600; margin-bottom: 10px; }
.pay-refund-opt { display: flex; align-items: center; gap: 8px; padding: 9px 10px; margin-top: 6px; border: 1px solid #DCE3EC; border-radius: var(--radius-md); background: #fff; cursor: pointer; font-size: var(--fs-md); color: #3D5166; }
.pay-refund-opt:first-of-type { margin-top: 0; }
.pay-refund-opt input { accent-color: #1F4E79; }
.pay-refund-opt:has(input:checked) { border-color: #1F4E79; background: #EEF4FB; color: #17233D; font-weight: 600; }

@media (max-width: 768px) {
  .wb-stat .value.amt { font-size: var(--fs-lg); letter-spacing: -0.5px; }
  .wb-grid { grid-template-columns: 1fr; }
  .wb-grid .card { margin-bottom: 16px; }
  /* 手机端：条目转为上下两段，按钮铺满一整行便于点按 */
  .wb-item { flex-direction: column; align-items: stretch; gap: 10px; padding: 13px 14px; }
  .wb-item-ops { justify-content: flex-end; }
  .op-btn { flex: 1; min-height: 40px; }
  .wb-item-amt { margin-left: 0; width: 100%; text-align: left; font-size: var(--fs-base); }
  .wb-item-line1 { gap: 6px; }
  /* 窄屏要把 12 列挤进 ~330px：gap 收到 4px（比 8px 省 44px），标签字号下调防折行 */
  .wb-bars { height: 128px; gap: 4px; }
  .wb-bar-val { font-size: var(--fs-xs); }
  .wb-bar-label { font-size: var(--fs-xs); }
}

/* ============ 侧边栏角色标题 ============ */
/* 侧边栏顶部一行不可点的「XX工作台」，只作分组，不参与高亮 */
.sidebar-role {
  padding: 4px 20px 12px; font-size: var(--fs-md); font-weight: 700; color: #1A1D21;
  letter-spacing: .3px; margin-bottom: 8px;
  border-bottom: 1px solid #EEF0F3;
}
@media (max-width: 768px) { .sidebar-role { display: none; } }

/* 手机端柱状图（UI 审核 P0-2 修复过程中目检发现的问题）
   12 个月要挤进 ~330px，每列只剩 12~22px：
   ① 柱顶数值「7.15万」有 5 个字符，物理上放不下 —— 相邻列数值会咬合成一串乱码，
      比不显示更糟。手机端只保留柱高与月份，精确金额走「导出 Excel」；
   ② 月份标签去掉「月」字，否则「10月」会折行成「10 / 月」两行，或把「月」挤出列外被裁；
   ③ gap 由 10px 收到 5px（.dash-full .wb-bars 更具体，必须另写一条才压得住）。 */
@media (max-width: 560px) {
  .wb-bar-val { display: none; }
  .wb-bar-label .wb-mu { display: none; }
  .dash-full .wb-bars { gap: 5px; }
}

/* ============ 业务员工作台：顶部两个大按钮 ============ */
.quick-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px; }
.quick-card {
  background: #fff; border: 1px solid #DCE3EC; border-radius: var(--radius-md);
  padding: 15px 18px; cursor: pointer; transition: border-color .15s, box-shadow .15s;
}
.quick-card:hover { border-color: #1F4E79; box-shadow: 0 2px 10px rgba(31,78,121,0.10); }
.quick-title { font-size: var(--fs-base); font-weight: 700; color: #1F4E79; }
.quick-desc { font-size: var(--fs-sm); color: #8A94A6; margin-top: 5px; }

/* ============ 单据进度条目（业务员）============ */
/* 条目整体改为上下结构：抬头一行 → 横向时间线 →（退回时）意见与重提按钮 */
.wb-item.wb-prog { display: block; padding: 14px 16px; }
.wb-prog-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; cursor: pointer; }
.wb-prog-head .wb-item-amt { margin-left: auto; }
.wb-prog-ops { display: flex; justify-content: flex-end; margin-top: 12px; }

/* 横向进度时间线：已完成=绿勾、当前=深蓝、未到=灰、退回=红感叹号 */
.wb-steps { display: flex; margin-top: 16px; }
.wb-step { flex: 1; position: relative; display: flex; flex-direction: column; align-items: center; min-width: 0; }
.wb-step::after { content: ''; position: absolute; top: 10px; left: 50%; width: 100%; height: 2px; background: #E5EBF2; z-index: 0; }
.wb-step:last-child::after { display: none; }
.wb-step.done::after { background: #A8D8BE; }
.wb-step.current::after { background: #B9CCE0; }
.wb-step.rejected::after { background: #F0B3B0; }
/* 指向「退回」节点的这一段也标红：被打回的那一段整体是红的 */
.wb-step:has(+ .wb-step.rejected)::after { background: #F0B3B0; }
.wb-step-dot {
  width: 22px; height: 22px; border-radius: 50%; background: #EDF1F6; color: #98A6B8;
  font-size: var(--fs-xs); font-weight: 700; display: flex; align-items: center; justify-content: center;
  position: relative; z-index: 1; border: 2px solid #fff; box-sizing: border-box;
}
.wb-step.done .wb-step-dot { background: #2E9E5B; color: #fff; }
.wb-step.current .wb-step-dot { background: #1F4E79; color: #fff; }
.wb-step.rejected .wb-step-dot { background: #D9534F; color: #fff; }
.wb-step-label { font-size: var(--fs-sm); color: #8A94A6; margin-top: 8px; text-align: center; white-space: nowrap; }
.wb-step.done .wb-step-label { color: #3D5166; }
.wb-step.current .wb-step-label { color: #1F4E79; font-weight: 700; }
.wb-step.rejected .wb-step-label { color: #D9534F; font-weight: 700; }

/* ============ 财务工作台：明细尺码块与票据核验标识 ============ */
.wb-item-meta {
  background: #F4F7FA; border: 1px solid #E5EBF2; border-radius: var(--radius-sm);
  padding: 2px 8px; font-size: var(--fs-sm); color: #3D5166; font-weight: 600; white-space: nowrap;
}
.tk { font-size: var(--fs-sm); font-weight: 600; white-space: nowrap; }
.tk.ok { color: #2E9E5B; }
.tk.ok::before { content: '✓ '; }
.tk.bad { color: #D9534F; }
.card-note { font-weight: 400; font-size: var(--fs-sm); color: #8A94A6; }

/* 财务打款清单 —— 按预计打款月分组 */
.pay-group { margin-bottom: 16px; }
.pay-group:last-child { margin-bottom: 0; }
.pay-group-head { display: flex; justify-content: space-between; align-items: center; padding: 10px 14px; background: #F5F8FC; border-radius: var(--radius-md) var(--radius-md) 0 0; border: 1px solid #DCE3EC; border-bottom: none; }
.pay-group-title { font-size: var(--fs-md); font-weight: 600; color: #1F4E79; }
.pay-group-meta { font-size: var(--fs-sm); color: #8A94A6; }
.pay-group .table-wrap { border: 1px solid #DCE3EC; border-radius: 0 0 var(--radius-md) var(--radius-md); }

/* 批量打款弹窗：月份多选 */
.pay-month-list { display: flex; flex-direction: column; gap: 8px; max-height: 320px; overflow-y: auto; }
.pay-month-option { display: flex; align-items: center; gap: 10px; padding: 11px 12px; border: 1px solid #DCE3EC; border-radius: var(--radius-md); cursor: pointer; transition: background .15s, border-color .15s; }
.pay-month-option:hover { background: #F8FAFC; border-color: #98A6B8; }
.pay-month-option input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; flex-shrink: 0; }
.pay-month-label { font-size: var(--fs-base); font-weight: 600; color: #1F4E79; }
.pay-month-meta { font-size: var(--fs-sm); color: #8A94A6; margin-left: auto; }

/* 财务工作台「待打款清单」按提交月 + 按业务员分组样式 */
.pay-month-group { margin-bottom: 14px; border: 1px solid #DCE3EC; border-radius: var(--radius-md); overflow: hidden; }
.pay-month-group:last-child { margin-bottom: 0; }
.pay-month-head { display: flex; justify-content: space-between; align-items: center; padding: 10px 14px; background: #F5F8FC; border-bottom: 1px solid #DCE3EC; }
.pay-month-title { font-size: var(--fs-base); font-weight: 600; color: #1F4E79; }
.pay-month-meta { font-size: var(--fs-sm); color: #8A94A6; }
.pay-user-block { padding: 8px 14px; border-bottom: 1px dashed #E8ECF2; }
.pay-user-block:last-child { border-bottom: none; }
.pay-user-head { display: flex; align-items: center; gap: 10px; padding: 6px 0; }
.pay-user-name { font-size: var(--fs-md); font-weight: 600; color: #2C3E50; }
.pay-user-sum { font-size: var(--fs-sm); color: #8A94A6; margin-left: auto; }
.pay-user-head .op-btn.pay { padding: 4px 12px; font-size: var(--fs-sm); }
.wb-item.slim { padding: 8px 12px; background: #FAFBFC; border: 1px solid #EBF0F5; border-radius: var(--radius-md); margin-bottom: 6px; }
.wb-item.slim:last-child { margin-bottom: 0; }
.wb-item.slim .wb-item-line1 { font-size: var(--fs-md); }
.wb-item.slim .wb-item-line2 { font-size: var(--fs-sm); margin-top: 2px; }

/* 补充按钮变体：灰框（查看明细）/ 深蓝实心（确认打款、重新提交）*/
.op-btn.ghost { background: #fff; color: #3D5166; border-color: #C8D3E0; }
.op-btn.ghost:hover { background: #F8FAFC; border-color: #98A6B8; }
.op-btn.pay, .op-btn.primary { background: #1F4E79; color: #fff; }
.op-btn.pay:hover, .op-btn.primary:hover { background: #16324F; }

@media (max-width: 768px) {
  .quick-actions { grid-template-columns: 1fr; gap: 10px; }
  .wb-item.wb-prog { padding: 13px 14px; }
  .wb-prog-head .wb-item-amt { margin-left: 0; width: 100%; }
  .wb-step-dot { width: 20px; height: 20px; font-size: var(--fs-xs); }
  .wb-step::after { top: 9px; }
  .wb-step-label { font-size: var(--fs-xs); white-space: normal; line-height: var(--lh-body); }
  .wb-steps { margin-top: 13px; }
  .wb-item-meta { font-size: var(--fs-xs); }
  .wb-prog-ops .op-btn { flex: none; width: 100%; }
}


/* ============ 账号快速切换条（仅演示模式显示）============ */
/* ★ 2026-09-16 修复：原先这里是 display:flex 且没有任何模式判断 ⇒ **正式版右上角也挂着
   「测试切换」条**（用户截图报障）。现改为「默认隐藏 + 失败安全」：
   只有 app.js 查到 /api/app-mode 返回 demo=true 才加 .is-on 显示；
   接口挂了 / JS 未执行 / 正式模式 → 一律不显示。 */
/* ★ 2026-10-08 第 83 批：切换条随顶栏浅色化（原深蓝底 → 白底胶囊） */
.test-switcher {
  position: fixed;
  top: 12px;
  right: 12px;
  z-index: 9999;
  display: none;
  align-items: center;
  gap: 6px;
  padding: 5px 8px;
  background: #fff;
  border: 1px solid #E8EAEE;
  border-radius: var(--radius-lg);
  box-shadow: 0 4px 16px rgba(0,0,0,.10);
  /* ★ 2026-09-26 第 52 批：切换条补齐工厂侧账号后按钮变多（9 个，约 737px），
     而本元素是 right:12px 向左展开、原先既不换行也没有宽度上限 ⇒ 窄屏（手机 390px）
     会被推到视口左侧之外，中间的按钮**点不到**（Playwright 报 element is outside of the viewport）。
     加 max-width + flex-wrap + 右对齐：宽屏单行不变，窄屏自动换行且整体仍在视口内。
     ★ 2026-09-27 第 60 批：切换条定为 12 键（人名），桌面 1440 实测约 870px 仍是单行；
     这里的 flex-wrap 是**窄桌面窗口的兜底**（窗口变窄时整体仍在视口内、按钮不被推出左侧）；
     手机端（≤768px）**不靠折行**（折行会压住底导航，见文末 ≤768px 段）——
     由那段「收紧间距 + 2 字短标签」保证单行。两段分工不同，别删任何一段。 */
  max-width: calc(100vw - 24px);
  flex-wrap: wrap;
  justify-content: flex-end;
}
.test-switcher.is-on {
  display: flex;
}
.ts-label {
  font-size: var(--fs-xs);
  color: #B0713F;
  font-weight: 600;
  padding: 0 6px;
  white-space: nowrap;
}
/* ★ 2026-10-06 第 81 批：切换条改**下拉菜单** (.ts-btn ×12 → .ts-select ×1)。
   旧版 12 个按钮在桌面上占掉约 870px 整条、窄屏还要靠 2 字短标签才塞得下；
   下拉菜单恒定约 150px，桌面/手机同一套样式即可（窄屏段相应大幅简化）。 */
.ts-select {
  border: 1px solid #D0D5DD;
  background: #F7F8FA;
  color: #1A1D21;
  font-size: var(--fs-sm);
  padding: 5px 8px;
  border-radius: var(--radius-lg);
  cursor: pointer;
  max-width: min(260px, calc(100vw - 72px));
  outline: none;
  transition: border-color .15s, background .15s;
}
.ts-select:hover { border-color: #B9C0CC; background: #F1F3F6; }
.ts-select:focus { border-color: #185FA5; }
/* 忙碌时（切换进行中）由 app.js 置灰，明确「正在切」而不是让人连点 */
.ts-select:disabled { opacity: .55; cursor: default; }
/* 展开后的候选项：macOS 下原生菜单继承不了上面这套配色（系统渲染），
   但 Windows/Chrome 会用这组配色，故显式给上，避免白底白字。 */
.ts-select option { background: #fff; color: #1A1D21; }

/* ============ 业务员工作台「按月报销金额」3 个小展示块 ============ */
.wb-month-stats {
  display: flex;
  gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid #ECEFF4;
}
.wb-month-stat {
  flex: 1;
  background: #F7F9FC;
  border-radius: var(--radius-md);
  padding: 10px 12px;
  text-align: center;
}
.wb-month-stat-title {
  font-size: var(--fs-sm);
  color: #8A94A6;
  margin-bottom: 4px;
}
.wb-month-stat-amt {
  font-size: var(--fs-xl);
  font-weight: 600;
  color: #1F4E79;
  font-variant-numeric: tabular-nums;
}

/* ============ 出差申请表单：整页版式（2026-09-14 由弹窗改为独立页面）============
   背景：客户卡片结构让表单变长，弹窗（880px、内部滚动）里要滚两屏、手机端更挤。
   这里是「源头单」，改为占满内容区的一整个页面：
     · 顶部一行「← 返回」+ 标题 + 副标题（知道自己从哪来、到哪去）
     · 中间一张白卡片装 2 个分区（基本信息 / 客户与项目；客户的出差信息、费用与借款、酒水都在卡片里，见 §6.9）
     · 底部操作条 sticky 吸底，长表单滚到哪儿都能看到「提交申请」
   列宽仍受 .liquor-table 的 min-width 660px 约束，故客户卡片保持单列堆叠，不做并排。 */
.form-page { max-width: 1040px; margin: 0 auto; }
/* 出差整页表单比报销单宽一档：两列卡片时每列 ~690px，卡内酒水表（min-width 660px）才不用横向滚
   （报销单是单列分区，1040px 就够，不加这个类） */
.form-page.form-page-wide { max-width: 1400px; }
.form-page-head { margin-bottom: 14px; }
.form-page-back {
  display: inline-block; margin-bottom: 10px; padding: 0;
  border: none; background: none; font-size: var(--fs-md); color: #1F4E79;
}
.form-page-back:hover { text-decoration: underline; }
.form-page-title { font-size: var(--fs-xl); font-weight: 700; margin-bottom: 4px; }
.form-page-sub { font-size: var(--fs-sm); color: #8A94A6; line-height: var(--lh-loose); }
.form-page-body {
  background: #fff; border: 1px solid #E4EAF2; border-radius: var(--radius-md);
  padding: 18px 20px;
}
.form-page-body .form-section:last-child { margin-bottom: 0; }
/* 底部操作条：吸在内容区底部，滚动时始终可见 */
.form-page-foot {
  position: sticky; bottom: 0; z-index: 20;
  display: flex; justify-content: flex-end; gap: 10px;
  margin-top: 12px; padding: 12px 20px;
  background: #fff; border: 1px solid #E4EAF2; border-radius: var(--radius-md);
  box-shadow: 0 -6px 18px rgba(23,35,61,.06);
}
.form-page-foot .btn { min-width: 128px; }
/* ⚠️ 上面那条 sticky 想生效，必须同时改下面两条（由 app.js 在进/出本页时挂/摘 .form-page-host）：
     ① .app-content 全局 overflow-y:auto → 它是个「不滚动的滚动容器」，sticky 会以它为参照物而失效；
        放开 overflow 后参照物变回文档（=视口），sticky 才吸得住。
     ② 但 .app-content 是 .app-body（flex 容器）的子项，一旦不再是滚动容器，
        它的 min-width:auto 就从 0 变成「内容最小宽度」——卡内酒水表 min-width 560px 会把整页撑到 610px，
        手机端直接横向溢出版。所以必须一起钉 min-width:0。
     两条少一条都不行，2026-09-14 实测各踩一次（见 _工具_离线验证/no_trip_page_ui.js）。 */
.app-content.form-page-host { overflow-y: visible; min-width: 0; }
@media (max-width: 768px) {
  .form-page-body { padding: 14px 12px; }
  .form-page-foot { padding: 10px 12px; }
  .form-page-foot .btn { flex: 1; min-width: 0; }
  .form-page-title { font-size: var(--fs-lg); }
}


/* ★ 2026-09-15：客户卡片内的酒水明细由「7 列表格一行」改为「每行 3 项 × 2 行」（用户要求）。
   起因：客户卡片改两列并排后每张卡片变窄，6 列表格要横向滚动才看得全。
   改法：.liquor-row 由 <tr> 改为 CSS Grid 容器，每条酒水固定 3 列 × 2 行，每格自带字段名。
   ⚠️ 详情页 / 审批页的酒水总表仍走 .liquor-table（那边页面够宽），两套样式并存，上面那段不要删。 */
.liquor-grid { display: flex; flex-direction: column; gap: 10px; }
.liquor-row {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px 12px; padding: 10px 12px;
  border: 1px solid #DCE3EC; border-radius: var(--radius-md); background: #fff;
}
.lq-cell { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.lq-label { font-size: var(--fs-xs); line-height: var(--lh-body); color: #8A94A6; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.liquor-row input, .liquor-row select {
  width: 100%; padding: 6px 8px; font-size: var(--fs-lg); color: #22334A;
  border: 1px solid #DCE3EC; border-radius: var(--radius-md); background: #fff; box-sizing: border-box;
}
.liquor-row input:focus, .liquor-row select:focus { outline: none; border-color: #1F4E79; box-shadow: 0 0 0 2px rgba(31,78,121,0.08); }
.lq-total-line { display: flex; align-items: center; justify-content: space-between; gap: 6px; min-height: 30px; }
.liquor-row .lq-total { font-weight: 600; color: #1F4E79; white-space: nowrap; font-size: var(--fs-md); }
/* 删除按钮：基础样式原本只挂在 .liquor-table / .lodging-table 作用域下，网格里需另补一份 */
.liquor-row .client-del {
  flex: 0 0 auto; width: 28px; height: 28px; padding: 0; border-radius: var(--radius-md);
  border: 1px solid #E8C9C9; background: #FFF5F5; color: #D9534F; font-size: 15px; line-height: var(--lh-num);
  cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s;
}
.liquor-row .client-del:hover { background: #FFE9E9; border-color: #D9534F; }
.liquor-foot { display: flex; justify-content: flex-end; align-items: baseline; gap: 8px; margin-top: 10px; font-size: var(--fs-md); color: #3D5166; }
.liquor-foot .liquor-sum { font-weight: 700; color: #1F4E79; font-size: var(--fs-md); }

/* ★ 2026-09-15：出差申请详情 / 报销单详情由弹窗改为独立整页（用户要求「审批页面整屏展示」）。
   头部把「标题 + 状态标签 + 单号」放在同一行，替掉原来塞在弹窗正文顶部的状态行。
   页面主体直接复用出差申请表单那套 .form-page / .form-page-body / .form-page-foot，
   宽度用 .form-page-wide（1400px）—— 详情里有 min-width 660px 的酒水总表，窄了会横向滚。 */
.detail-head { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; flex-wrap: wrap; }
.detail-head .form-page-title { margin-bottom: 0; }
.detail-doc-no { font-size: var(--fs-sm); color: #8A94A6; font-family: monospace; }

/* ★ 2026-09-15：去掉数字输入框的上下调节按钮（spinner）—— 用户要求「单价那里不要调那种
   上下调动价格的按钮，直接填价格就行」。给全站 type=number 统一处理，而不是只改酒水单价：
   同一张卡里「容量/数量」有箭头、「单价」没有，看起来像坏了；而且费用/借款/天数/住宿标准
   同样只需要手填，箭头只会挤占窄格子的输入宽度。
   ✅ 仍保留 type=number：手机唤起数字键盘、min/max/step 校验都还在；键盘 ↑↓ 微调也仍可用，
      只是不再渲染那两个箭头按钮。 */
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type=number] { -moz-appearance: textfield; appearance: textfield; }

/* ===== 智能填报入口按钮（2026-09-15 新增）===== */
.btn-ai {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 14px; border-radius: 8px; border: 1px solid #7F77DD;
  background: #EEEDFE; color: #26215C;
  font-size: var(--fs-md); font-weight: 500;
  cursor: pointer; width: 100%; margin-bottom: 10px;
  transition: background .15s;
}
.btn-ai:hover { background: #CECBF6; }
.btn-ai:active { background: #B9B5F2; }

/* ===== 发票核验（2026-09-17 第 24 批）=====
   财务审单时点「核对发票金额」，逐笔显示「票面 vs 填报」的比对结论。
   配色一律走语义 token：一致=success / 不一致=danger / 没读出来=warning / 没票=muted。
   ⚠ 「不一致」与「没读出来」必须**不同色**（红 vs 橙）—— 否则财务会把
      「机器没看清」误当成「业务员多报了」，这是两种性质完全不同的结论。 */
.vfy-bar { display: flex; align-items: center; gap: var(--space-sm); flex-wrap: wrap; margin: var(--space-sm) 0 var(--space-xs); }
.vfy-btn { padding: 6px 14px; font-size: var(--fs-sm); }
.vfy-btn:disabled { opacity: .6; cursor: default; }
.vfy-hint { font-size: var(--fs-xs); color: var(--c-muted); }

/* 汇总横幅：给财务一个「这单能不能放心过」的总览 */
.vfy-banner { border-radius: var(--radius-md); padding: 10px 12px; margin-bottom: var(--space-sm); border: 1px solid transparent; }
.vfy-banner-head { font-size: var(--fs-md); line-height: var(--lh-body); }
.vfy-banner-sub { font-size: var(--fs-xs); margin-top: var(--space-xs); line-height: var(--lh-loose); }
.vfy-disclaim { color: var(--c-muted); }
.vfy-banner.vfy-ok   { background: #EDF8F1; border-color: #BFE4CD; color: #1D6B3D; }
.vfy-banner.vfy-bad  { background: #FDEDEC; border-color: #F3C2C0; color: #A32F2B; }
.vfy-banner.vfy-warn { background: #FFF8E6; border-color: #F0DCA8; color: #8A6D2E; }
.vfy-banner.vfy-mute { background: var(--c-bg-soft); border-color: var(--c-border); color: var(--c-text-sub); }

/* 逐笔结论标签（:empty 不占位，未核验时页面与之前完全一样） */
.vfy-result:empty { display: none; }
.vfy-tag { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-sm);
           padding: 3px 10px; border-radius: var(--radius-sm); margin-top: 6px; border: 1px solid transparent; }
.vfy-ic { font-weight: 700; }
.vfy-tag.vfy-ok   { background: #EDF8F1; border-color: #BFE4CD; color: #1D6B3D; }
.vfy-tag.vfy-bad  { background: #FDEDEC; border-color: #F3C2C0; color: #A32F2B; font-weight: 600; }
.vfy-tag.vfy-warn { background: #FFF8E6; border-color: #F0DCA8; color: #8A6D2E; }
.vfy-tag.vfy-mute { background: var(--c-bg-soft); border-color: var(--c-border); color: var(--c-muted); }
/* ★ 2026-09-18 第 43 批：「居间免票」第五态。
   用与「居间」科目一致的暗金 #B8860B —— **必须与 .vfy-mute（灰）明显可分**：
   灰 = 「这笔该有票却没有」，金 = 「这类按口径不用票」，两件事相反，同色会误导财务。 */
.vfy-tag.vfy-exempt { background: #FBF3E0; border-color: #E6D2A6; color: #8A6508; }

/* 每张票的识别明细（读出来的才列，便于财务核对具体是哪张票） */
.vfy-invs { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 5px; }
.vfy-inv { font-size: var(--fs-xs); color: var(--c-text-sub); background: var(--c-bg-soft);
           border: 1px solid var(--c-border); border-radius: var(--radius-sm); padding: 2px 8px; }
.vfy-lowconf { color: var(--c-warning); }
.vfy-note { font-size: var(--fs-xs); color: var(--c-muted); margin-top: var(--space-xs); }

/* 金额单元格高亮：红=确定不一致 / 橙=没读出来（两者不可同色，理由见上） */
.vfy-amt-ok   { color: var(--c-success); }
.vfy-amt-bad  { color: var(--c-danger); background: #FDEDEC; border-radius: var(--radius-sm); padding: 1px 6px; }
.vfy-amt-warn { color: var(--c-warning); }

/* ============================================================
   客户档案 / 客户台账 / 客户详情（2026-09-17 第 31 批）
   ------------------------------------------------------------
   视觉语言与业务员台账（.ledger-person / .ld-table）保持一致：
     · 迷你柱状图照 .lp-spark 的读法（12 根、由远及近、越靠右越近）
     · 档案页用卡片网格、台账页用表格 —— 这是用户要求的两个菜单两种视角
   ⚠️ 一个坑：paintLedgerCats() 产出的 .lp-cats* **样式全部写在 `.ledger-person` 作用域下**，
      客户详情页没有那层容器 ⇒ 构成条会变成一堆无样式的 div。所以下面补了一份
      `.cu-cats-host .lp-*` 等价规则（宽屏还换成了多列图例）。
      不要删掉它以为"重复定义"——两条规则各自服务不同的容器。
   ============================================================ */

/* ---- 状态小标签（.cu-tag-inflight 是「审批中」的补充标记） ---- */
.cu-tag { display: inline-block; flex: none; font-size: var(--fs-xs); line-height: 1.5;
  padding: 1px 7px; border-radius: var(--radius-sm); border: 1px solid transparent; white-space: nowrap; }
.cu-tag-inflight { margin-left: 6px; color: #8A6D2E; border-color: #F0DCA8; background: #FFF8E6; }

/* ---- 待办提示条（待批准删除 / 详情页的待批横幅共用） ---- */
.cu-notice { background: #FFF8E6; border: 1px solid #F0DCA8; color: #8A6D2E;
  border-radius: var(--radius-md); padding: 10px 12px; margin-bottom: var(--space-md);
  font-size: var(--fs-md); line-height: var(--lh-loose); }
.cu-notice b { color: #7A5C12; }
.cu-notice-item { display: inline-block; margin: 2px 8px 2px 0; padding: 1px 8px; background: #fff;
  border: 1px solid #F0DCA8; border-radius: var(--radius-sm); cursor: pointer; color: #8A6D2E; }
.cu-notice-item:hover { border-color: #D9A400; color: #6B500E; }

/* ---- 客户档案：卡片网格 ---- */
.cu-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.cu-card { background: #fff; border: 1px solid #E8ECF3; border-radius: var(--radius-md);
  padding: 14px 16px; transition: border-color .15s, box-shadow .15s, transform .15s; }
.cu-card:hover { border-color: #1F4E79; box-shadow: 0 3px 12px rgba(31, 78, 121, .1); transform: translateY(-1px); }
.cu-card-head { display: flex; align-items: center; gap: 8px; }
.cu-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--fs-base); font-weight: 600; color: #17233D; cursor: pointer; }
.cu-name:hover { color: #1F4E79; text-decoration: underline; }
.cu-owner { font-size: var(--fs-xs); color: #8A94A6; white-space: nowrap; }
.cu-card-mid { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-top: 8px; }
.cu-amount { font-size: var(--fs-base); font-weight: 700; color: #1F4E79; }
.cu-meta { font-size: var(--fs-xs); color: #8A94A6; }
.cu-spark { display: flex; align-items: flex-end; gap: 3px; height: 30px; margin: 10px 0 8px; }
.cu-spark-col { flex: 1; min-height: 3px; background: #E1E9F4; border-radius: var(--radius-sm); }
.cu-spark-col.has { background: #1F4E79; }
.cu-remark { font-size: var(--fs-xs); color: #5A6478; line-height: var(--lh-body);
  background: var(--c-bg-soft); border-radius: var(--radius-sm); padding: 4px 8px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cu-remark-empty { color: #B6BFCC; }
.cu-pending { margin-top: 6px; font-size: var(--fs-xs); color: #A32F2B; }
.cu-card-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 10px;
  padding-top: 9px; border-top: 1px solid #F1F4F9; font-size: var(--fs-sm); }
.cu-link { color: #1F4E79; font-weight: 500; cursor: pointer; }
.cu-link:hover { text-decoration: underline; }

/* ---- 客户台账 / 详情内表格 ---- */
.cu-table-wrap { background: #fff; border: 1px solid #E8ECF3; border-radius: var(--radius-md);
  overflow-x: auto; margin-bottom: 4px; }
.cu-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.cu-table th { text-align: left; font-weight: 500; color: #8A94A6; font-size: var(--fs-xs);
  padding: 10px 12px; border-bottom: 1px solid #EEF2F7; white-space: nowrap; }
.cu-table td { padding: 10px 12px; border-bottom: 1px solid #F4F7FB; color: #33405A; vertical-align: middle; }
.cu-table tbody tr:hover td { background: #FAFCFE; }
.cu-table tfoot td { padding: 10px 12px; font-weight: 600; color: #17233D; background: var(--c-bg-soft); }
.cu-table .num { text-align: right; white-space: nowrap; }
.cu-table .cu-td-name { font-weight: 600; color: #17233D; }
/* 「详情 / 编辑」两个入口同格（第 32 批：客户档案列表）—— 不给间距两个词会粘在一起 */
.cu-table .cu-td-ops { white-space: nowrap; }
.cu-table .cu-td-ops .cu-link + .cu-link { margin-left: 12px; }
.cu-table .cu-spark { height: 26px; margin: 0; min-width: 110px; }
.cu-table-sm th, .cu-table-sm td { padding: 7px 10px; }
.cu-nowrap { white-space: nowrap; }
.cu-wrap { min-width: 160px; }
/* 第 35 批 · 业务员版「拜访记录」列宽（用户要求：时间/目的地压缩，项目多留空间）
   ⚠️ 只作用于 .cu-table-visit（业务员版 4 列表）；.cu-table 是**共用类**，管理岗 7 列表与其它表不受影响。
   fixed 布局 = 列宽完全由 colgroup 决定 ⇒ 项目写再长也只在自己列内折行，不撑动其余三列。 */
.cu-table-visit { table-layout: fixed; }
.cu-table-visit .cv-time { width: 200px; }
.cu-table-visit .cv-dest { width: 96px; }
.cu-table-visit .cv-note { width: 26%; }
/* ⚠️ overflow-wrap 必须挂在 <td>（单元格）上 —— 挂在 <col> 上**完全无效**：
   col 不渲染内容，且 overflow-wrap 不是可继承属性。第 35 批首版就挂错了元素——
   「列宽断言全绿」但 286 字符无空格串照样把容器撑破，靠注入长串量 scrollWidth 才抓到。
   时间列自带 white-space:nowrap，本属性对其无效，行为不变。 */
.cu-table-visit td { overflow-wrap: anywhere; }
.cu-na { color: #B6BFCC; }

/* ---- 详情页操作按钮条 ---- */
.cu-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: var(--space-md) 0; }
.cu-wait { font-size: var(--fs-sm); color: #8A6D2E; }
.cu-actions .btn { margin: 0; }

/* ---- 近 12 个月走势 ---- */
.cu-months { display: flex; gap: 6px; align-items: flex-end; background: #fff;
  border: 1px solid #E8ECF3; border-radius: var(--radius-md); padding: 14px 16px 10px;
  margin-bottom: var(--space-md); overflow-x: auto; }
.cu-month { flex: 1; min-width: 52px; text-align: center; }
.cu-month-bar { height: 56px; display: flex; align-items: flex-end; justify-content: center; }
.cu-month-bar i { display: block; width: 60%; max-width: 26px; background: #1F4E79;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0; min-height: 2px; }
.cu-month-amt { font-size: var(--fs-xs); color: #1F4E79; font-weight: 600; margin-top: 5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cu-month-amt.zero { color: #C3CAD6; font-weight: 400; }
.cu-month-label { font-size: var(--fs-xs); color: #8A94A6; margin-top: 2px; }

/* ---- 资料区块（联系人 / 备注）---- */
.cu-block { background: #fff; border: 1px solid #E8ECF3; border-radius: var(--radius-md);
  padding: var(--card-pad-md); margin-bottom: var(--space-md); }
.cu-block .cu-table-wrap { border: none; border-radius: 0; margin-bottom: 0; }
.cu-block .cu-table th, .cu-block .cu-table td { padding: 8px 10px; }
.cu-block-title { font-size: var(--fs-md); font-weight: 600; color: #17233D; margin-bottom: 8px; }
.cu-remark-box { font-size: var(--fs-md); color: #33405A; line-height: var(--lh-loose);
  background: var(--c-bg-soft); border-radius: var(--radius-sm); padding: 10px 12px; white-space: pre-wrap; }
.cu-empty-line { font-size: var(--fs-sm); color: #8A94A6; padding: 6px 0; }

/* ---- 操作记录（变更留痕）---- */
.cu-logs { background: #fff; border: 1px solid #E8ECF3; border-radius: var(--radius-md);
  overflow: hidden; margin-bottom: var(--space-md); }
.cu-log { display: flex; gap: 12px; align-items: baseline; padding: 9px 16px;
  border-bottom: 1px solid #F4F7FB; font-size: var(--fs-sm); }
.cu-log:last-child { border-bottom: none; }
.cu-log-time { color: #8A94A6; font-size: var(--fs-xs); white-space: nowrap;
  font-family: ui-monospace, Menlo, monospace; }
.cu-log-op { color: #1F4E79; font-weight: 600; white-space: nowrap; }
.cu-log-act { color: #33405A; }

/* ---- 编辑 / 新建弹窗里的联系人行 ---- */
.cu-contact-row { display: grid; grid-template-columns: minmax(0, 1fr) 132px minmax(0, 1fr) 32px;
  gap: 8px; align-items: center; margin-bottom: 8px; }
.cu-contact-row input, .cu-contact-row select { width: 100%; padding: 8px 10px;
  border: 1px solid var(--c-border-strong); border-radius: var(--radius-md); font-size: var(--fs-lg); }
.cu-contact-row input:focus, .cu-contact-row select:focus { border-color: #1F4E79; outline: none; }
.cu-contact-row .client-del { width: 32px; height: 32px; border: 1px solid var(--c-border);
  border-radius: var(--radius-md); background: #fff; color: #8A94A6; font-size: var(--fs-xl);
  line-height: 1; padding: 0; }
.cu-contact-row .client-del:hover { background: #FFE9E9; border-color: var(--c-danger); color: var(--c-danger); }

/* ---- paintLedgerCats() 在客户详情页的落位（等价于 .ledger-person .lp-*，宽屏用多列图例）---- */
.cu-cats-host .lp-cats { background: #fff; border: 1px solid #E8ECF3; border-radius: var(--radius-md);
  padding: var(--card-pad-md); margin-bottom: var(--space-md); }
.cu-cats-host .lp-cats-head { display: flex; justify-content: space-between; align-items: baseline;
  gap: 6px; font-size: var(--fs-sm); color: #5A6478; margin-bottom: 8px; }
.cu-cats-host .lp-cats-note { font-size: var(--fs-xs); color: #8A94A6; }
.cu-cats-host .lp-cats-bar { display: flex; height: 12px; border-radius: var(--radius-sm);
  overflow: hidden; background: #EEF2F7; }
.cu-cats-host .lp-cat-seg { height: 100%; min-width: 0; }
.cu-cats-host .lp-cats-legend { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 6px 18px; margin-top: 10px; font-size: var(--fs-sm); color: #5A6478; }
.cu-cats-host .lp-cat-item { display: flex; align-items: center; gap: 6px; min-width: 0; white-space: nowrap; }
.cu-cats-host .lp-cat-item i { width: 8px; height: 8px; border-radius: var(--radius-sm); flex: none; }
.cu-cats-host .lp-cat-item b { margin-left: auto; font-weight: 600; color: #17233D;
  overflow: hidden; text-overflow: ellipsis; }
.cu-cats-host .lp-cat-item.is-zero { color: #B6BFCC; }
.cu-cats-host .lp-cat-item.is-zero b { font-weight: 400; color: #B6BFCC; }
.cu-cats-host .lp-cats-empty { font-size: var(--fs-xs); color: #B6BFCC; padding: 1px 0 2px; }

/* ---- 窄屏（与台账同一套断点：1200 / 900 / 640）---- */
@media (max-width: 1200px) {
  .cu-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
  .cu-grid { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  /* 表格横向滚动，不挤压金额列（金额被折行后读不出大小对比） */
  .cu-table { min-width: 760px; }
  .cu-months { padding: 12px 12px 8px; }
  .cu-month { min-width: 46px; }
}
@media (max-width: 640px) {
  .cu-actions { gap: 6px; }
  .cu-actions .btn { flex: 1 1 auto; }
  /* 联系人行：手机上改成「姓名 + 职位 + 删除」一行、电话独占第二行 */
  .cu-contact-row { grid-template-columns: minmax(0, 1fr) 108px 32px; }
  .cu-contact-row .cu-c-name  { grid-column: 1; grid-row: 1; }
  .cu-contact-row .cu-c-role  { grid-column: 2; grid-row: 1; }
  .cu-contact-row .client-del { grid-column: 3; grid-row: 1; }
  .cu-contact-row .cu-c-phone { grid-column: 1 / 4; grid-row: 2; }
  .cu-log { flex-wrap: wrap; gap: 4px 10px; padding: 9px 12px; }
  .cu-cats-host .lp-cats-legend { grid-template-columns: 1fr 1fr; gap: 5px 12px; }
}
@media (max-width: 480px) {
  .cu-cats-host .lp-cats-legend { grid-template-columns: 1fr; }
}

/* ============================================================
   品质管理 · NCR 详情页 + 品质工作台（2026-09-25 批 A / M1）
   ------------------------------------------------------------
   只**新增**类，不改动任何既有规则（零回归风险）。全部引用上面的 Design Token。
   ============================================================ */

/* ---------- 详情页顶部条 ---------- */
.detail-head { margin-bottom: 14px; }
.detail-head-top { display: flex; align-items: center; gap: 10px; font-size: var(--fs-md); margin-bottom: 6px; }
.detail-head-spacer { flex: 1; }
.detail-head-main { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.detail-no { font-family: ui-monospace, Menlo, monospace; font-size: var(--fs-xl); font-weight: 700; color: #1F4E79; }
.detail-head-sub { margin-top: 4px; font-size: var(--fs-md); color: #8A94A6; }

/* ---------- 页签 ---------- */
.tab-bar { display: flex; gap: 2px; border-bottom: 1px solid #E3E8EF; margin-bottom: var(--space-md); overflow-x: auto; }
.tab-item {
  padding: 10px 16px; font-size: var(--fs-base); color: #5A6B80; cursor: pointer;
  border-bottom: 2px solid transparent; white-space: nowrap; display: flex; align-items: center; gap: 6px;
  transition: color .15s, border-color .15s;
}
.tab-item:hover { color: #1F4E79; }
.tab-item.active { color: #1F4E79; font-weight: 600; border-bottom-color: #1F4E79; }
.tab-cnt { background: #EAF0F7; color: #1F4E79; border-radius: 9px; padding: 0 6px; font-size: var(--fs-xs); font-weight: 600; line-height: 18px; }
.tab-body { min-height: 160px; }

/* ---------- 第 76 批：NCR 详情页「下一步」行动卡 ----------
   作用：单页长卷下先回答「我现在该干什么」（状态机：措施 → 验证 → 关闭）。
   🔴 类名独立（.nc-next*），**不复用 .card-head / .card** —— 验收脚本有「数 .card-head 标题」的断言。 */
.nc-next {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px; margin-bottom: var(--space-md);
  border: 1px solid #E3E8EF; border-left: 4px solid #1F4E79; border-radius: var(--radius-md);
  background: #F7FAFD; font-size: var(--fs-md); line-height: 1.6;
}
.nc-next-ico { font-size: 16px; flex-shrink: 0; }
.nc-next-txt { flex: 1; min-width: 0; color: #2B3A4A; }
.nc-next-txt b { font-weight: 700; color: inherit; }
.nc-next-btn { flex-shrink: 0; }
.nc-next-danger { border-left-color: #B3261E; background: #FEF6F5; }
.nc-next-danger .nc-next-txt b { color: #B3261E; }
.nc-next-warn   { border-left-color: #B0713F; background: #FFFBF2; }
.nc-next-ok     { border-left-color: #1B5E20; background: #F4FAF5; }
@media (max-width: 900px) { .nc-next { flex-wrap: wrap; } }

/* ---------- 第 71 批：NCR 详情页「五区合一」—— 锚点导航条 + 分区 ---------- */
/* 说明：上面 .tab-bar/.tab-item/.tab-body/.tab-cnt 四类**保留不删**（历史引用仍在），
   详情页自本批起不再生成它们，改用下面的 .anchor-bar 系列。
   分区内**不套二级卡片**（内部 .card 保持原样），避免「卡中卡」双层边框。 */
.anchor-bar {
  position: sticky; top: 0; z-index: 10;
  display: flex; gap: 2px;
  background: #fff; border: 1px solid #E3E8EF; border-radius: 10px;
  padding: 4px 6px; margin-bottom: var(--space-md);
  overflow-x: auto;
  box-shadow: 0 2px 8px rgba(31, 78, 121, .06);
}
.anchor-item {
  flex: 0 0 auto; padding: 7px 13px; font-size: var(--fs-base); color: #5A6B80;
  border: none; background: transparent; border-radius: 7px; cursor: pointer;
  white-space: nowrap; font-family: inherit; transition: color .15s, background .15s;
  display: flex; align-items: center; gap: 2px;
}
.anchor-item:hover { color: #1F4E79; background: #F0F5FA; }
.anchor-item.active { color: #fff; background: #1F4E79; font-weight: 600; }
.anchor-cnt {
  background: #EAF0F7; color: #1F4E79; border-radius: 9px;
  padding: 0 6px; font-size: var(--fs-xs); font-weight: 600; line-height: 18px; margin-left: 4px;
}
.anchor-item.active .anchor-cnt { background: rgba(255, 255, 255, .25); color: #fff; }

.ncr-sections { display: block; }
.ncr-sec { margin-bottom: 24px; scroll-margin-top: 62px; }
.ncr-sec-head {
  display: flex; align-items: center; gap: 8px;
  padding: 0 2px 8px; margin-bottom: 12px;
  border-bottom: 1px solid #E9EEF4;
}
.ncr-sec-idx {
  width: 20px; height: 20px; border-radius: 50%; flex: 0 0 auto;
  background: #EAF0F7; color: #1F4E79;
  font-size: var(--fs-xs); font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.ncr-sec-title { font-weight: 700; color: #1F2E3E; font-size: var(--fs-base); }
.ncr-sec-cnt {
  background: #EAF0F7; color: #1F4E79; border-radius: 9px;
  padding: 0 6px; font-size: var(--fs-xs); font-weight: 600; line-height: 18px;
}
.ncr-sec-body { min-height: 40px; }

/* ---------- 卡片小标题 + 键值行 ---------- */
.card-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: var(--fs-lg); font-weight: 600; color: #1F2937;
  padding-bottom: 10px; margin-bottom: 10px; border-bottom: 1px solid #EEF2F6;
}
.kv { display: flex; gap: 12px; padding: 7px 0; font-size: var(--fs-base); }
.kv-k { flex: 0 0 88px; color: #8A94A6; }
.kv-v { flex: 1; color: #1F2937; word-break: break-word; }
.kv-v.pre { white-space: pre-wrap; line-height: var(--lh-loose); }

/* ---------- 时间轴（措施跟踪 / 进度流水） ---------- */
.timeline { display: flex; flex-direction: column; }
.tl-item { display: flex; gap: 10px; padding-bottom: 14px; position: relative; }
.tl-item:not(:last-child)::before {
  content: ''; position: absolute; left: 4px; top: 16px; bottom: 0;
  width: 1px; background: #E3E8EF;
}
.tl-dot { flex: 0 0 9px; width: 9px; height: 9px; border-radius: 50%; margin-top: 6px; z-index: 1; }
.tl-body { flex: 1; min-width: 0; }
.tl-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 3px; }
.tl-kind { font-size: var(--fs-md); font-weight: 600; color: #1F4E79; }
.tl-time { font-size: var(--fs-xs); color: #8A94A6; }
.tl-text { font-size: var(--fs-base); color: #1F2937; line-height: var(--lh-body); word-break: break-word; }
.tl-meta { font-size: var(--fs-xs); color: #8A94A6; margin-top: 3px; }
/* ★ 第 71-B 批：处理进展（feed）在时间线骨架上加了「照片 / 上传提示 / 改善结果勾选框」三样 */
/* 缩略图形态：时间线里**不占满整屏**，点开才看大图（`onclick` 走 window.open） */
.tl-img { display: block; max-width: 260px; max-height: 180px; border-radius: var(--radius-sm); border: 1px solid #C8D3E0; margin-top: 6px; cursor: zoom-in; }
.feed-tip { font-size: var(--fs-xs); color: #8A94A6; margin-left: 10px; }
.feed-check { display: flex; align-items: center; gap: 8px; font-size: var(--fs-base); color: #1F2937; cursor: pointer; margin-top: 4px; }
.feed-check input { width: 16px; height: 16px; }
.tl-quote {
  font-size: var(--fs-md); color: #5A6B80; background: #F7F9FC;
  border-left: 3px solid #C8D3E0; padding: 6px 10px;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0; margin-top: 5px; line-height: var(--lh-body);
}

/* ---------- 证据 Before / After ---------- */
.ev-wrap { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-md); }
.ev-col { min-width: 0; }
.ev-col-head {
  font-size: var(--fs-md); font-weight: 600; color: #1F2937;
  border-left: 3px solid #8A94A6; padding-left: 8px; margin-bottom: 10px;
  display: flex; align-items: center; gap: 6px;
}
.ev-cnt { font-size: var(--fs-xs); color: #8A94A6; font-weight: 400; }
.ev-card { background: #fff; border: 1px solid #E3E8EF; border-radius: var(--radius-md); padding: 10px; margin-bottom: 10px; }
/* 证据网格：一行 4 张（第 73 批修复 2，用户拍板「一行 4 张尺寸合适」），窄屏降为 2 张 */
.ev-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
.ev-grid .ev-card { margin-bottom: 0; }
@media (max-width: 900px) { .ev-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* 🔴 证据照片**不许裁切**（第 73 批修复，禁 cover —— 缺陷可能落在照片任何角落）。
   修复 2 起图片装进正方形格子（.ev-img-box），contain 完整居中：方图恰好铺满、
   非方图格内留白，看原图走点击放大（zoom-in → window.open）。
   同坑先例：.thumb-receipt 火车票缩略图（本文件上方）。 */
.ev-img-box { aspect-ratio: 1 / 1; background: #F7F9FC; border-radius: var(--radius-sm); overflow: hidden; }
.ev-img { width: 100%; height: 100%; object-fit: contain; border-radius: var(--radius-sm); cursor: zoom-in; display: block; }
.ev-text { font-size: var(--fs-base); color: #1F2937; line-height: var(--lh-body); margin-top: 6px; word-break: break-word; }
.ev-note { font-size: var(--fs-xs); color: #5A6B80; margin-top: 5px; }
.ev-meta { font-size: var(--fs-xs); color: #A9B4C2; margin-top: 6px; }
.ev-empty {
  font-size: var(--fs-md); color: #A9B4C2; text-align: center;
  padding: 18px 0; background: #FAFBFD; border: 1px dashed #E3E8EF; border-radius: var(--radius-md);
}

/* ---------- 品质工作台（副总首页） ---------- */
/* ★ 第 78 批：统计卡 4 → 5 张（加「平均挂起天数」）—— 1440px 下列宽约 218px，
   「平均挂起天数」6 字 label 单行放得下；窄屏走下方 @media 的 2 列。 */
.q-stat-row { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--space-md); margin-bottom: 14px; }
.q-stat {
  background: #fff; border: 1px solid #E3E8EF; border-radius: var(--radius-md);
  padding: 14px 16px; cursor: pointer; transition: box-shadow .15s, transform .15s;
}
.q-stat:hover { box-shadow: 0 2px 10px rgba(31, 78, 121, .10); transform: translateY(-1px); }
/* ★ 第 76 批：当前筛选卡高亮（看列表时一眼知道「这些数字是哪个口径」）+ 无筛选口径的卡不可点。 */
.q-stat.on { border-color: #1F4E79; box-shadow: 0 0 0 2px rgba(31, 78, 121, .14); }
.q-stat-static { cursor: default; }
.q-stat-static:hover { box-shadow: none; transform: none; }
.q-stat-num { font-size: var(--fs-3xl); font-weight: 700; line-height: var(--lh-num); }
.q-stat-label { font-size: var(--fs-md); color: #8A94A6; margin-top: 6px; }
.q-todo { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 9px 4px; border-bottom: 1px solid #F3F6FA; cursor: pointer; }
.q-todo:last-child { border-bottom: none; }
.q-todo:hover { background: #F7F9FC; }
.q-todo-no { font-family: ui-monospace, Menlo, monospace; font-size: var(--fs-md); color: #1F4E79; font-weight: 600; }
.q-todo-meta { font-size: var(--fs-sm); color: #8A94A6; }

/* ---------- ★ 第 75 批：待办三桶 —— 行内快捷动作 + 「等验证 / 等关闭」折叠桶 ---------- */
/* 行内动作：右浮、小号、描边，悬停加深；danger 用于「去关闭」（不可逆动作视觉区分）。 */
.q-todo-act {
  margin-left: auto; font-size: var(--fs-sm); color: #1F4E79; font-weight: 600;
  padding: 2px 8px; border: 1px solid #D3DFEC; border-radius: 4px;
  background: #F7FAFF; white-space: nowrap;
}
.q-todo-act:hover { background: #EAF0F7; }
.q-todo-act.danger { color: #B3261E; border-color: #F3D2CE; background: #FFF7F6; }
.q-todo-act.danger:hover { background: #FDECEA; }
/* 折叠桶：summary 直接复用 .card-head 外观，去掉原生三角、用自绘 caret 旋转表示开合。 */
.q-wait > summary.card-head { cursor: pointer; list-style: none; display: flex; align-items: center; gap: 8px; }
.q-wait > summary.card-head::-webkit-details-marker { display: none; }
.q-wait-caret { display: inline-block; transition: transform .15s; }
.q-wait[open] .q-wait-caret { transform: rotate(90deg); }
.q-wait-body { padding-top: 2px; }
/* 桶头计数与标题拉开一点：.ev-cnt 全局无左间距，三桶头部连读会像「需跟进2」 */
.q-cnt { margin-left: 6px; }

/* ---------- 页头动作区（品质工作台：标题在左、动作按钮在右） ---------- */
/* 复用 .page-title-row 既有范式（数据统计 / 业务员台账用它放导出按钮），只补「右侧动作组」与副标题对齐。 */
.page-title-row.with-actions { margin-bottom: 16px; }
.page-title-row.with-actions .page-sub { margin-bottom: 0; }
.page-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; }
/* 与筛选条控件等高（40px）—— 保证按钮挪到页头后尺寸不变 */
.page-actions .btn { height: 40px; padding: 8px 16px; }

/* ============ P3「历史方案复用」：同类历史参考卡片 + AI 建议区 ============ */
/* 设计依据：品质管理_P3历史方案复用_设计_第1轮/第2轮_20260925.md §4 */
.ncr-sim-card { margin-bottom: var(--space-md); padding-bottom: 4px; }
/* ★ 第 76 批：整卡折叠 —— 默认收起为一行标题（含「N 条 · 最高匹配档」摘要），点标题展开。
   作用：详情页 7 屏长，「执行措施」被 400+ 行历史参考埋到第 3 屏 ⇒ 收起来回到第 1.5 屏。
   🔴 折叠用 display 开关（DOM 保留）⇒ verify_p3_ui 里 .ncr-sim-row / .ncr-ai 的查询与
      textContent 断言全部照旧成立（第 76 批施工记录）。 */
.ncr-sim-fold-head { cursor: pointer; user-select: none; }
.ncr-sim-fold-head:hover { color: var(--c-primary); }
.ncr-sim-fold-caret { display: inline-block; margin-left: 6px; color: var(--c-muted); font-size: var(--fs-sm); }
.ncr-sim-body-wrap { display: none; }
.ncr-sim-card.open .ncr-sim-body-wrap { display: block; }
.ncr-sim-body-wrap > .ncr-sim-row:first-child { border-top: 0; }
.ncr-sim-tip { padding: 10px 4px; font-size: var(--fs-sm); color: var(--c-text-sub); line-height: 1.75; }
.ncr-sim-muted { color: var(--c-muted); font-size: var(--fs-sm); }

/* ---- 历史单行（默认折叠，点整行内联展开；🔴 不跳页）---- */
.ncr-sim-row { border-top: 1px solid var(--c-border); }
/* ⚠️ 用相邻兄弟选择器而不是 :first-of-type —— 卡片里第一个 div 是 .card-head，
   `.ncr-sim-row:first-of-type` 永远不匹配（同类型第一个不是它），会多出一条莫名其妙的分隔线。 */
.ncr-sim-card > .card-head + .ncr-sim-row { border-top: 0; }
.ncr-sim-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 10px 4px; cursor: pointer; }
.ncr-sim-head:hover { background: var(--c-bg-soft); }
.ncr-sim-caret { color: var(--c-muted); font-size: var(--fs-sm); width: 12px; flex-shrink: 0; }
.ncr-sim-no { font-weight: 600; color: var(--c-primary); font-size: var(--fs-md); }
.ncr-sim-match { font-size: var(--fs-xs); color: #5E35B1; background: #F3EEFB; border-radius: var(--radius-sm); padding: 1px 6px; }
.ncr-sim-score { font-size: var(--fs-xs); color: var(--c-muted); }
.ncr-sim-meta { margin-left: auto; font-size: var(--fs-xs); color: var(--c-muted); white-space: nowrap; }
.ncr-sim-desc { padding: 0 4px 10px 24px; font-size: var(--fs-md); color: var(--c-text); line-height: 1.7; }

/* ---- 展开后的四段：根因 / 当时措施 / 先止 / 验证 ---- */
.ncr-sim-body { margin: 0 4px 12px 24px; background: var(--c-bg-soft); border: 1px solid var(--c-border); border-radius: var(--radius-md); padding: 10px 12px; }
.ncr-sim-block { display: flex; gap: 8px; padding: 5px 0; }
.ncr-sim-block + .ncr-sim-block { border-top: 1px dashed var(--c-border); }
.ncr-sim-block-k { flex: 0 0 60px; font-size: var(--fs-xs); color: var(--c-muted); padding-top: 2px; }
.ncr-sim-block-v { flex: 1; min-width: 0; font-size: var(--fs-md); color: var(--c-text-sub); line-height: 1.7; }
.ncr-sim-act { display: flex; gap: 6px; align-items: baseline; }
.ncr-sim-act + .ncr-sim-act { margin-top: 4px; }
.ncr-sim-act-flag { color: var(--c-success); flex-shrink: 0; }
.ncr-sim-act-text { flex: 1; min-width: 0; }
.ncr-sim-act-meta { font-size: var(--fs-xs); color: var(--c-muted); white-space: nowrap; }

/* ---- 放宽提示（用户主动点击，不自动放宽）---- */
.ncr-sim-relax { padding: 10px 4px 4px; font-size: var(--fs-sm); color: var(--c-text-sub); }

/* ---- 第③步：AI 建议区 ---- */
.ncr-ai { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--c-border); }
.ncr-ai-head { display: flex; align-items: center; gap: 8px; }
.ncr-ai-title { font-weight: 600; color: var(--c-primary); font-size: var(--fs-md); }
.ncr-ai-ops { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.ncr-ai-note { margin-top: 6px; font-size: var(--fs-xs); color: var(--c-warning); }
.ncr-ai-tip { padding: 10px 0 2px; font-size: var(--fs-sm); color: var(--c-text-sub); line-height: 1.75; }
.ncr-ai-err { margin-top: 8px; padding: 8px 10px; border-radius: var(--radius-md); background: #FDECEA; color: #B3261E; font-size: var(--fs-sm); }
.ncr-ai-sec { margin-top: 12px; }
.ncr-ai-sec-k { font-size: var(--fs-xs); color: var(--c-muted); margin-bottom: 4px; }
.ncr-ai-item { display: flex; gap: 6px; align-items: baseline; flex-wrap: wrap; padding: 4px 0; }
.ncr-ai-idx { flex-shrink: 0; color: var(--c-primary); font-size: var(--fs-sm); font-weight: 600; }
.ncr-ai-item-txt { flex: 1; min-width: 0; font-size: var(--fs-md); color: var(--c-text); line-height: 1.7; }
.ncr-ai-pri { font-size: var(--fs-xs); color: #B3261E; background: #FDECEA; border-radius: var(--radius-sm); padding: 1px 6px; }
.ncr-ai-meta { font-size: var(--fs-xs); color: var(--c-muted); white-space: nowrap; }
.ncr-ai-basis { font-size: var(--fs-xs); color: var(--c-primary); background: #EAF0F7; border-radius: var(--radius-sm); padding: 1px 6px; cursor: pointer; white-space: nowrap; }
.ncr-ai-basis.invalid { color: var(--c-muted); background: #F1F3F6; }
.ncr-ai-text { font-size: var(--fs-md); color: var(--c-text-sub); line-height: 1.75; }
.ncr-ai-foot { margin-top: 12px; padding-top: 8px; border-top: 1px dashed var(--c-border); font-size: var(--fs-xs); color: var(--c-muted); line-height: 1.7; }

/* ---- 第 73 批：同类历史处置方案（月报根因 / 改善措施）----
   🔴 类名刻意独立（.ncr-kb-*），**不复用** .ncr-sim-block-* ——
   复用会污染 verify_p3_ui.js 对历史单行内「块标题」的数组全等断言。 */
.ncr-kb-block { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--c-border); }
.ncr-kb-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  font-weight: 600; color: var(--c-primary); font-size: var(--fs-md); }
.ncr-kb-type { font-size: var(--fs-xs); font-weight: 400; color: #1F4E79;
  background: #EAF0F7; border-radius: var(--radius-sm); padding: 1px 6px; }
.ncr-kb-src { margin-left: auto; font-size: var(--fs-xs); font-weight: 400; color: var(--c-muted); }
.ncr-kb-sec { margin-top: 10px; }
.ncr-kb-k { font-size: var(--fs-xs); color: var(--c-muted); margin-bottom: 2px; }
.ncr-kb-item { display: flex; gap: 6px; align-items: baseline; flex-wrap: wrap; padding: 3px 0; }
.ncr-kb-mark { flex-shrink: 0; font-size: var(--fs-xs); color: var(--c-primary); }
.ncr-kb-txt { flex: 1; min-width: 0; font-size: var(--fs-md); color: var(--c-text); line-height: 1.7; }
.ncr-kb-meta { font-size: var(--fs-xs); color: var(--c-muted); white-space: nowrap; }
.ncr-kb-note { margin-top: 8px; font-size: var(--fs-xs); color: var(--c-muted); }

/* ★ 第 73 批：NCR 列表「参考覆盖」徽标 —— 绿=有历史可参考；橙=新型问题（历史库无同类） */
.nc-ref { display: inline-block; padding: 1px 6px; border-radius: 10px; font-size: var(--fs-xs);
  background: #E8F5E9; color: #1B5E20; }
.nc-ref.warn { background: #FFF7E6; color: #B0713F; }
/* 卡片内的小按钮（与全站 .btn 42px 区分：这里是卡内次级操作） */
.btn-sm { height: 32px; padding: 4px 12px; font-size: var(--fs-sm); }

@media (max-width: 720px) {
  .q-stat-row { grid-template-columns: 1fr 1fr; }
  .ev-wrap { grid-template-columns: 1fr; }
  .kv-k { flex: 0 0 72px; }
  .page-title-row.with-actions { flex-wrap: wrap; }
  .page-actions { width: 100%; justify-content: flex-start; }
  /* P3：窄屏下历史单的 meta 不右浮、块标签改纵向，避免挤压正文 */
  .ncr-sim-meta { margin-left: 0; width: 100%; }
  .ncr-sim-block { flex-direction: column; gap: 2px; }
  .ncr-sim-block-k { flex: none; }
  .ncr-sim-desc, .ncr-sim-body { padding-left: 4px; margin-left: 0; }
  /* 第 73 批：知识块在窄屏同样不右浮、不挤压正文 */
  .ncr-kb-meta, .ncr-kb-src { margin-left: 0; width: 100%; }
}

/* ============ 执行措施（★ 2026-09-26 第 54 批）============
   用于：① 新建不合格项整页表单（含措施动态行）② 详情页「执行措施追踪区」
   （汇总带 / 按会议轮次分组 / 措施行 / 负责人标签 / 完成证据缩略图）
   配色沿用设计令牌：主蓝 #1F4E79、绿 #1B5E20、橙 #B0713F、红 #B3261E、灰 #8A94A6。 */

/* ---- 新建页整页布局 ---- */
.nc-new-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--space-md); }
.form-hint { font-size: var(--fs-xs); color: #8A94A6; margin-top: 4px; }

/* ---- 措施动态行（新建页与措施弹窗共用）---- */
.nc-act-row { border: 1px solid #DCE4EE; border-radius: var(--radius-md); padding: 10px;
  margin-bottom: 10px; background: #FBFCFE; }
.nc-act-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
.nc-act-idx { font-size: var(--fs-sm); font-weight: 600; color: #1F4E79; }
/* ★ 2026-09-27 第 62 批：措施行内的控件**不在 .form-group 内**，拿不到全局控件 token
   （本文件的控件样式只挂在 `.form-group` 后代选择器上），会掉成浏览器原生裸控件
   —— 实测 date 框 `border 2px inset #767676 / radius 0 / padding 0 / height 28px`、
   措施 textarea `1px solid #767676 / radius 0 / padding 0`。
   此处按本文件既定的控件规范补同一套 token：描边 #C8D3E0 · 圆角 6px · 高 44px ·
   内边距 10px 12px · 聚焦 #1F4E79 ⇒ 与 .form-group input/textarea 完全一致。
   同一模板两处共用：新建不合格项页（app.js L937-940）+ 新增/编辑执行措施弹窗（L1964-1967）。 */
.nc-act-row textarea, .nc-act-grid input {
  width: 100%; height: 44px; box-sizing: border-box; padding: 10px 12px;
  border: 1px solid #C8D3E0; border-radius: 6px; background: #fff; outline: none;
  font-size: var(--fs-lg); color: #22303F; transition: border-color 0.2s;
}
.nc-act-row textarea { height: auto; min-height: 44px; resize: vertical; }
.nc-act-row textarea:focus, .nc-act-grid input:focus { border-color: #1F4E79; }
.nc-act-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.nc-act-grid label { display: block; font-size: var(--fs-sm); color: #3D5166; margin-bottom: 6px; }
.nc-act-owners { margin-top: 8px; }
.nc-act-owners-head { font-size: var(--fs-sm); color: #5B6B7F; margin-bottom: 6px; font-weight: 600; }
.nc-act-picked { font-size: var(--fs-xs); color: #1F4E79; margin-top: 6px; }

/* 负责人标签：点选切换（多选）——比 <select multiple> 手机友好，且一眼看清选了谁 */
.nc-chip-wrap { display: flex; flex-wrap: wrap; gap: 6px; }
.nc-chip { display: inline-block; padding: 4px 10px; border: 1px solid #C8D3E0; border-radius: 14px;
  font-size: var(--fs-sm); color: #46566B; background: #fff; cursor: pointer; user-select: none; }
.nc-chip.on { background: #1F4E79; border-color: #1F4E79; color: #fff; }

/* ---- 汇总带：总措施 / 已完成 / 进行中 / 已逾期 ---- */
.nc-sum-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-sm); margin-bottom: 12px; }
.nc-sum { background: #F7F9FC; border: 1px solid #E3EAF3; border-radius: var(--radius-md);
  padding: 10px 8px; text-align: center; }
.nc-sum-num { font-size: var(--fs-3xl); font-weight: 700; line-height: var(--lh-num); }
.nc-sum-label { font-size: var(--fs-xs); color: #8A94A6; margin-top: 4px; }

/* ---- 会议轮次分组 ---- */
.nc-round { border-top: 1px dashed #E3EAF3; padding-top: 10px; margin-top: 10px; }
.nc-round:first-of-type { border-top: none; margin-top: 0; padding-top: 0; }
.nc-round-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.nc-round-tag { display: inline-block; padding: 2px 8px; border-radius: var(--radius-sm);
  background: #EAF0F7; color: #1F4E79; font-size: var(--fs-xs); font-weight: 600; }
.nc-round-meta { font-size: var(--fs-xs); color: #8A94A6; }
.nc-round-summary { font-size: var(--fs-sm); color: #5B6B7F; margin: 6px 0 8px;
  padding-left: 8px; border-left: 3px solid #E3EAF3; }

/* ---- 措施行：左侧色条 = 状态（绿完成 / 红逾期 / 橙临期 / 蓝进行中）---- */
.nc-exec { display: flex; gap: 10px; justify-content: space-between; align-items: flex-start;
  border-left: 3px solid #1F4E79; background: #fff; border-radius: var(--radius-sm);
  padding: 8px 10px; margin-bottom: 8px; box-shadow: 0 1px 2px rgba(31,78,121,.05); }
.nc-exec-main { flex: 1; min-width: 0; }
.nc-exec-text { font-size: var(--fs-md); color: #263445; line-height: var(--lh-body); }
.nc-exec-meta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 6px;
  font-size: var(--fs-xs); color: #8A94A6; }
.nc-exec-owners { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 6px; }
.nc-owner { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: var(--fs-xs);
  background: #F1F3F6; color: #46566B; border: 1px solid transparent; }
.nc-owner.done { background: #E8F5E9; color: #1B5E20; }
.nc-owner.tap { border-color: #1F4E79; color: #1F4E79; background: #EAF0F7; cursor: pointer; }
.nc-owner.tap:hover { background: #1F4E79; color: #fff; }
.nc-done-cnt { font-size: var(--fs-xs); color: #8A94A6; }
.nc-exec-note { font-size: var(--fs-xs); color: #8A94A6; margin-top: 4px; }
.nc-done-img { max-height: 60px; border-radius: 4px; border: 1px solid #C8D3E0;
  vertical-align: middle; cursor: zoom-in; }
.nc-exec-ops { display: flex; flex-direction: column; gap: 4px; align-items: flex-end; flex: none; }
.nc-resched-tag { background: #FFF7E6; color: #B0713F; padding: 1px 6px; border-radius: var(--radius-sm); }

/* ---- 会议记录块 ---- */
.nc-meet { border-bottom: 1px dashed #E3EAF3; padding: 8px 0; }
.nc-meet:last-child { border-bottom: none; }
.nc-meet-head { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.nc-meet-body { font-size: var(--fs-md); color: #263445; margin-top: 6px; line-height: var(--lh-body); }

/* ---- 窄屏（手机）：汇总带两列、措施行竖排、动态行单列 ---- */
@media (max-width: 720px) {
  .nc-new-grid, .nc-act-grid { grid-template-columns: 1fr; }
  .nc-sum-row { grid-template-columns: 1fr 1fr; }
  .nc-exec { flex-direction: column; }
  .nc-exec-ops { flex-direction: row; align-items: center; }
}

/* ============================================================================
   ★ 2026-10-06 第 81 批总述（先读这条）：切换条已改**下拉菜单**，
     下面整段「12 键宽度预算」的历史推演**只对旧版按钮形态生效**，条内规则也已替换。
     但**四个坑依然成立、仍别踩**：① 别挪到底部 ② 别用 overflow-x 横滑
     ③ 别只缩 padding ④ 窄屏别折行压住 .mobile-nav(top:48)。
     —— 下拉形态下这四条自然满足（恒定 ~150px 宽、~37px 高），故窄屏段变得很短。
   ★ 2026-09-27 修：窄屏「测试切换条」压住手机端导航栏
   —— 第 52 批给切换条补了 4 个工厂侧账号按钮，共 9 个；在 390px 下 flex-wrap 换行成
      3 行、条高 111px，而 .mobile-nav 是 `position: fixed; top: 48px; z-index: 99`，
      .test-switcher 是 z-index 9999 ⇒ 两者重叠区域（y 48~123）里的导航项**点不动**
      （实测：elementFromPoint 命中的是 .ts-btn，verify_ui 手机段直接在
       「点底导航进报销」这一步超时失败）。
   处置：窄屏改「单行 + 短标签（data-s）」 —— 9 个按钮一行放得下，条高 ~42px，
      整条落在导航上沿 48px **之上**，按钮一个不少且**每个都能直接点**。
   ★ 2026-09-27 第 60 批：切换条定为 **12 键**（人名），窄屏宽度预算重算 ——
      按原参数（按钮左右 padding 4+4、gap 2）每键 2 字标签约 32px
      ⇒ 12×32 + 11×2 = 406px > 390px 的可用 362px，**必折行**（回到第 52 批的坑：折行压底导航）。
      处置：gap 2→1、按钮左右 padding 4→2、条 padding 6→4 ⇒ 12×28 + 11×1 = **347px**，
      390px 可用 370px ⇒ 单行放下（余 23px）；
      另加 ≤380px 二级兜底（::after 字号 fs-xs→10px ⇒ 12×26 + 11 = 323px），360px 安卓也单行。
      上面三条「别踩的坑」约束不变（仍不挪底部、仍不横滑）。
   ⚠️ 三个别踩的坑（前两个都亲测过）：
      ① **别改成「挪到底部」**：手机上弹窗是 max-height 90vh 的贴底 sheet，而切换条
         z-index 9999 > .modal-mask 1000 ⇒ 会盖住弹窗的确认按钮。
      ② **别用 overflow-x: auto 横滑代替**：本元素基线带 `justify-content: flex-end`，
         两者叠加会把内容推到**负坐标侧**，左侧按钮滑到滚动也够不到的不可达区
         ⇒ verify_workbench_v2 手机段「点财务」报 element is outside of the viewport。
      ③ **别只缩 padding**：9 个长标签（含「品质负责人」5 字）实测合计 478px > 可用 362px，
         单靠缩小间距仍会折行 ⇒ 必须换短标签（index.html 的 data-s）。
   影响面：仅 ≤768px（桌面宽度足够，本来就是单行，规则不生效）。
   ============================================================================ */
@media (max-width: 768px) {
  .test-switcher {
    top: 2px;
    right: 8px;
    gap: 4px;
    padding: 3px 4px;
    max-width: calc(100vw - 12px);
  }
  /* 「测试切换」标签约 66px，窄屏优先让给下拉本身（桌面段不受影响，
     verify_devmode_ui 的 innerText 断言仍在 1440 桌面视口跑） */
  .test-switcher .ts-label { display: none; }
  /* ★ 2026-10-06 第 81 批：下拉只有一项宽（最长文字「陈国良 · 工厂管理」≈ 8 字），
     条高 = 3+3 padding + ~31 = 37px（y 2~39）稳落在 .mobile-nav(top:48) 之上；
     ★ 旧版那段「12 键宽度预算 / gap 1 / padding 2 / data-s 短标签」全部作废 —— 
       下拉的宽度与账号数无关，加账号再也不会把这条挤折行（旧坑根因就此消失）。 */
  .test-switcher .ts-select {
    padding: 7px 8px;            /* 第 81 批：上下 7px ⇒ 实测高 ~33px，满足移动端 ≥32px 触控建议 */
    font-size: var(--fs-sm);
    max-width: calc(100vw - 24px);
  }
}
/* ★ 2026-10-06 第 81 批：≤380px 段**已删** —— 它当年存在的唯一理由是给 12 键的
   2 字短标签（.ts-btn::after）再降一档字号以挤进 360px 安卓；
   下拉菜单宽度约 150px，这个兜底已无对象（保留注释是为了说明「不是漏删」）。 */

/* ============================================================
   手写会议记录 OCR 登记（2026-10-05 第 79 批）
   ------------------------------------------------------------
   全部 .mt- 前缀，避免与既有类名相撞（改前已确认 style.css 里 .mt- 命中 0 处）。
   配色沿用本站既有调色板：主蓝 #1F4E79 / 边框 #DCE3EC / 次要文字 #8A94A6
   / 危险红 #D9534F / 成功绿 #1B7A4A —— 不引入新色，保证与全站同族。
   ============================================================ */

/* ---------- 列表页工具条 ---------- */
.mt-toolbar { display: flex; gap: 10px; align-items: center; margin-bottom: 12px; }
.mt-search {
  flex: 1; min-width: 0; height: 36px; padding: 0 12px;
  border: 1px solid #DCE3EC; border-radius: var(--radius-sm);
  font-size: var(--fs-base); background: #fff; color: #22303F;
}
.mt-search:focus { outline: none; border-color: #1F4E79; }

/* ---------- 记录条目 ---------- */
.mt-list { display: flex; flex-direction: column; }
.mt-item {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 12px;
  padding: 14px 4px; border-bottom: 1px solid #EEF2F7; cursor: pointer;
}
.mt-item:last-child { border-bottom: none; }
.mt-item:hover { background: #F8FAFC; }
.mt-item-main { min-width: 0; flex: 1; }
.mt-item-title { font-size: var(--fs-base); font-weight: 600; color: #22303F; margin-bottom: 5px; }
.mt-item-meta { font-size: var(--fs-sm); color: #5A6878; margin-bottom: 3px; }
.mt-item-meta .mt-d { font-weight: 600; color: #1F4E79; }
.mt-item-sub { font-size: var(--fs-xs); color: #8A94A6; }
.mt-item-badges { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex-shrink: 0; }

.mt-badge {
  display: inline-block; padding: 2px 8px; border-radius: 10px;
  font-size: var(--fs-xs); white-space: nowrap; line-height: 16px;
  background: #EEF2F7; color: #5A6878;
}
.mt-badge.warn { background: #FDECEA; color: #C0392B; font-weight: 600; }
.mt-badge.conf-ok { background: #E7F5EC; color: #1B7A4A; }
.mt-badge.conf-mid { background: #FDF3E3; color: #A9761B; }
.mt-badge.conf-low { background: #FDECEA; color: #C0392B; }

/* ---------- 上传区 ---------- */
.mt-upload { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 14px; }
.mt-upload-add {
  width: 96px; height: 96px; border: 1px dashed #B9C6D6; border-radius: var(--radius-md);
  background: #F8FAFC; color: #5A6878; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
}
.mt-upload-add:hover { border-color: #1F4E79; color: #1F4E79; background: #EEF4FA; }
.mt-upload-add span { font-size: 22px; line-height: 1; }
.mt-upload-add em { font-style: normal; font-size: var(--fs-sm); }
.mt-upload-full { font-size: var(--fs-sm); color: #8A94A6; }
.mt-upload .upload-thumb { width: 96px; height: 96px; }
.mt-upload .upload-thumb img { width: 100%; height: 100%; object-fit: cover; }

/* ★ 第 80 批：拖动添加 —— 上传区外层 dropzone（拖入时整块高亮 + 覆盖提示） */
.mt-dropzone {
  position: relative; min-height: 108px; padding: 6px; margin: 0 -6px 8px;
  border: 1.5px dashed transparent; border-radius: var(--radius-md);
  display: flex; align-items: center;
  transition: border-color .15s, background .15s;
}
.mt-dropzone .mt-upload { margin-bottom: 0; width: 100%; }
.mt-dropzone.dragover { border-color: #1F4E79; background: #EEF4FA; }
.mt-dropzone.dragover::after {
  content: '松手即添加到上传区 · 最多 5 张';
  position: absolute; inset: 0; border-radius: var(--radius-md);
  display: flex; align-items: center; justify-content: center;
  background: rgba(31, 78, 121, .88); color: #FFFFFF;
  font-size: var(--fs-base); font-weight: 600; letter-spacing: .5px;
  pointer-events: none;   /* 关键：覆盖层不能接住 drop 事件，否则落点变成它自己 */
  z-index: 3;
}

/* ---------- 草稿对照区（左图右文）---------- */
.mt-draft { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 18px; align-items: start; }
.mt-draft-left { position: sticky; top: 8px; }
.mt-draft-left-title { font-size: var(--fs-sm); font-weight: 600; color: #5A6878; margin-bottom: 8px; }
.mt-draft-imgs { display: flex; flex-direction: column; gap: 10px; }
.mt-draft-imgs img {
  width: 100%; border: 1px solid #DCE3EC; border-radius: var(--radius-md);
  cursor: zoom-in; background: #F8FAFC; display: block;
}
.mt-draft-right { min-width: 0; }
.mt-draft-right .form-group { margin-bottom: 12px; }
.mt-draft-right input, .mt-draft-right textarea { width: 100%; box-sizing: border-box; }

/* ---------- 存疑提示 / 置信度 ---------- */
.mt-notes {
  background: #FFF9F0; border: 1px solid #F0D9B0; border-radius: var(--radius-md);
  padding: 10px 12px; font-size: var(--fs-sm); color: #7A5A18; margin-bottom: 12px;
}
.mt-notes ul { margin: 6px 0 0; padding-left: 20px; }
.mt-notes li { margin-bottom: 3px; line-height: var(--lh-loose); }
.mt-notes-err { background: #FDECEA; border-color: #F2B8B5; color: #A32B25; }
.mt-conf-line { font-size: var(--fs-sm); color: #5A6878; margin-bottom: 14px; }

/* ---------- 待办编辑行 ---------- */
.mt-sub-title {
  font-size: var(--fs-sm); font-weight: 600; color: #1F4E79;
  margin: 8px 0 8px; display: flex; align-items: center; gap: 10px;
}
.mt-act-row { display: grid; grid-template-columns: minmax(0, 1fr) 110px 140px 30px; gap: 6px; margin-bottom: 6px; }
.mt-act-row input {
  height: 34px; padding: 0 8px; box-sizing: border-box;
  border: 1px solid #DCE3EC; border-radius: var(--radius-sm); font-size: var(--fs-md); color: #22303F;
}
.mt-act-row input:focus { outline: none; border-color: #1F4E79; }
.mt-act-del {
  height: 34px; border: 1px solid #DCE3EC; border-radius: var(--radius-sm);
  background: #fff; color: #D9534F; font-size: var(--fs-lg); line-height: 1; cursor: pointer;
}
.mt-act-del:hover { background: #FDECEA; border-color: #F2B8B5; }
.mt-empty-line { font-size: var(--fs-sm); color: #8A94A6; padding: 6px 0; }

.link-btn {
  border: none; background: none; padding: 0; cursor: pointer;
  color: #1F4E79; font-size: var(--fs-sm); text-decoration: underline;
}
.req { color: #D9534F; }

/* ---------- 原始转录折叠 ---------- */
.mt-raw { margin-top: 10px; font-size: var(--fs-sm); }
.mt-raw summary { cursor: pointer; color: #5A6878; }
.mt-raw pre {
  margin: 8px 0 0; padding: 10px 12px; background: #F8FAFC; border: 1px solid #EEF2F7;
  border-radius: var(--radius-md); white-space: pre-wrap; word-break: break-word;
  font-size: var(--fs-sm); color: #3C4A5A; line-height: var(--lh-loose); max-height: 320px; overflow: auto;
}

/* ---------- 详情页 ---------- */
.mt-detail-meta { display: flex; flex-wrap: wrap; gap: 8px 22px; }
.mt-kv { font-size: var(--fs-md); color: #22303F; display: inline-flex; align-items: center; gap: 6px; }
.mt-kv em { font-style: normal; font-size: var(--fs-sm); color: #8A94A6; }
.mt-tags { display: flex; flex-wrap: wrap; gap: 8px; }
.mt-tag {
  display: inline-block; padding: 3px 10px; border-radius: 12px;
  background: #EEF4FA; color: #1F4E79; font-size: var(--fs-sm);
}
.mt-decisions { margin: 0; padding-left: 22px; font-size: var(--fs-base); color: #22303F; }
.mt-decisions li { margin-bottom: 7px; line-height: var(--lh-loose); }
.mt-pre { white-space: pre-wrap; word-break: break-word; font-size: var(--fs-base); color: #22303F; line-height: var(--lh-loose); }
.mt-act-table { width: 100%; border-collapse: collapse; font-size: var(--fs-md); }
.mt-act-table th, .mt-act-table td {
  border-bottom: 1px solid #EEF2F7; padding: 9px 8px; text-align: left; vertical-align: top;
}
.mt-act-table th { font-size: var(--fs-sm); color: #5A6878; font-weight: 600; background: #F8FAFC; }
/* 图片加载失败（例如无权读他人上传的原图）——不留破图，给一条文字提示 */
img.img-fail, .upload-thumb.img-fail img { visibility: hidden; }
.upload-thumb.img-fail::after {
  content: '无权查看'; position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; font-size: var(--fs-xs); color: #8A94A6; background: #F8FAFC;
}

/* ---------- 窄屏：左图右文改上下堆叠 ---------- */
@media (max-width: 860px) {
  .mt-draft { grid-template-columns: minmax(0, 1fr); }
  .mt-draft-left { position: static; }
  .mt-draft-imgs { flex-direction: row; flex-wrap: wrap; }
  .mt-draft-imgs img { width: 46%; }
  .mt-act-row { grid-template-columns: minmax(0, 1fr) 90px 120px 30px; }
  .mt-item-badges { flex-direction: row; }
}

/* ============================================================
   ★ 2026-10-08 第 83 批：门户页（.portal-*，登录落地页）
   飞书风：白卡细边、板块色顶条（OA 蓝 / 工厂绿 / 管理后台灰蓝）、
   卡片内入口列表（文字链 + › 箭头）。窄屏自动单列纵排。
   ============================================================ */
.portal { max-width: 960px; margin: 0 auto; }
.portal-hello { margin: 8px 0 20px; }
.portal-hello-title { font-size: var(--fs-2xl); font-weight: 700; color: #1A1D21; }
.portal-hello-sub { font-size: var(--fs-sm); color: #9BA1AB; margin-top: 4px; }
.portal-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 16px; }
.portal-card { background: #fff; border: 1px solid rgba(0,0,0,.08); border-radius: var(--radius-md); overflow: hidden; transition: box-shadow .15s; }
.portal-card:hover { box-shadow: 0 4px 16px rgba(0,0,0,.06); }
.portal-card-head { display: flex; align-items: center; gap: 12px; padding: 16px; cursor: pointer; }
.portal-card-head:hover { background: #F7F8FA; }
.portal-icon { width: 44px; height: 44px; border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.portal-card-title { font-size: var(--fs-lg); font-weight: 600; color: #1A1D21; }
.portal-card-desc { font-size: var(--fs-xs); color: #9BA1AB; margin-top: 2px; }
.portal-entries { border-top: 1px solid #F1F2F4; }
.portal-entry { display: flex; align-items: center; justify-content: space-between; padding: 11px 16px; font-size: var(--fs-base); color: #5F6470; cursor: pointer; border-bottom: 1px solid #F5F6F8; transition: background .12s; }
.portal-entry:last-child { border-bottom: none; }
.portal-entry:hover { background: #F7F8FA; color: #185FA5; }
.portal-entry-arrow { color: #C0C6CF; font-size: var(--fs-lg); line-height: 1; }
.portal-entry:hover .portal-entry-arrow { color: #185FA5; }
.portal-empty { padding: 20px 16px; font-size: var(--fs-sm); color: #B9BEC7; text-align: center; }
/* 窄屏：门户卡片单列纵排、问候语收一档 */
@media (max-width: 768px) {
  .portal { max-width: none; }
  .portal-hello-title { font-size: var(--fs-xl); }
  .portal-grid { grid-template-columns: 1fr; gap: 12px; }
}

/* ============ 第 85 批：板块隔离（门户态无侧栏 / 侧栏返回门户）============ */
/* 门户页（currentPage='portal'）= 板块选择页：不带侧栏、不带底导航，卡片区全宽居中。
   app.js 在 navigate() 里给 #appLayout 挂/摘 .mode-portal（唯一的形态开关，别处不要重复 toggle）。
   ⚠️ 走作用域类而不是改 .app-sidebar / .mobile-nav 本体 —— 板块内页面的侧栏/底导航一字不变。 */
.app-layout.mode-portal .app-sidebar { display: none; }
.app-layout.mode-portal .portal { max-width: 1080px; }
.app-layout.mode-portal .app-content { padding: 28px 24px; }
/* 侧栏底部「返回门户」：板块隔离后这是唯一显式的跨板块切换入口（顶栏 logo 也可点，但那是隐性知识）。
   margin-top:8px + 上边线 = 与个人中心组拉开层次；不可与 .sidebar-item 混用类名（断言按 .sidebar-item 取值）。 */
.sidebar-portal-btn { margin: 12px 16px 4px; padding: 9px 12px; border: 1px solid #E3E7EC; border-radius: 8px;
  font-size: var(--fs-sm); color: #6B7280; text-align: center; cursor: pointer; transition: all .15s; }
.sidebar-portal-btn:hover { background: #F2F4F7; color: #185FA5; border-color: #C8D3E0; }
@media (max-width: 768px) {
  .app-layout.mode-portal .mobile-nav { display: none; }
  /* 底导航（top:48 + 高约 44）被摘掉后内容区不用再给它让位，收到顶栏之下即可 */
  .app-layout.mode-portal .app-content { padding: 16px 14px; padding-top: 62px; }
}

/* ============ 第 88 批：全站按钮动效（方案 E · 组合）============
   拍板：用户选「方案 E」—— 悬停上浮 1px + 提亮 + 主按钮投影；按下回弹 scale(.97) 下压；
         链接类按钮悬停右移 2px + 下划线。
   落地原则：纯增量叠加，不改任何既有配色/尺寸/文案/布局；只加动效层。
   ─ 全局总开关：--motion-on（1 开 / 0 关）。改根变量即可一键关停全部动效。
   ─ 无障碍：尊重 prefers-reduced-motion，系统「减弱动态效果」时降级为纯色变（无位移/缩放）。
   ─ 触屏兜底：hover 无触发，靠 :active 点击态反馈（transform 已在 :active 保留）。 */
:root { --motion-on: 1; }

/* 主/次/危险/成功按钮 —— 统一「上浮 + 投影 + 按压回弹」 */
.btn { will-change: transform; }
.btn:not(:disabled):hover { transform: translateY(-1px); filter: brightness(1.04); }
.btn:not(:disabled):active { transform: translateY(1px) scale(.97); box-shadow: none; }
.btn-primary:not(:disabled):hover { box-shadow: 0 5px 14px rgba(24,95,165,.3); }
.btn-success:not(:disabled):hover { box-shadow: 0 5px 14px rgba(46,158,91,.28); }
.btn-default:not(:disabled):hover { box-shadow: 0 2px 8px rgba(15,34,56,.08); border-color: #A8BDD6; }
.btn-danger:not(:disabled):hover { box-shadow: 0 2px 8px rgba(217,83,79,.14); }

/* 操作小按钮（审批/打款/工作台 op-btn） */
.op-btn { will-change: transform; }
.op-btn:hover { transform: translateY(-1px); filter: brightness(1.04); }
.op-btn:active { transform: translateY(1px) scale(.97); }
.op-btn.primary:hover, .op-btn.pay:hover { box-shadow: 0 4px 12px rgba(31,78,121,.28); }
.op-btn.ok:hover { box-shadow: 0 4px 12px rgba(46,158,91,.26); }

/* 链接文字按钮（link-action / link-btn）—— 右移 + 下划线 */
.link-action { display: inline-block; transition: color .15s ease, transform .12s ease; }
.link-action:hover { text-decoration: underline; transform: translateX(2px); }
.link-btn { transition: color .15s ease, transform .12s ease; }
.link-btn:hover { transform: translateX(2px); }

/* 杂项按钮：导出 / AI 填报 / 新增客户 */
.export-btn:not(:disabled):hover { transform: translateY(-1px); box-shadow: 0 2px 8px rgba(15,34,56,.1); }
.export-btn:not(:disabled):active { transform: translateY(1px); }
.btn-ai:not(:disabled):hover { transform: translateY(-1px); box-shadow: 0 3px 10px rgba(127,119,221,.28); }
.btn-ai:not(:disabled):active { transform: translateY(1px) scale(.97); }
.btn-add-client:hover { transform: translateY(-1px); }

/* 分页按钮 */
.np-btn:not(:disabled):hover { transform: translateY(-1px); box-shadow: 0 2px 6px rgba(15,34,56,.08); }
.np-btn:not(:disabled):active { transform: translateY(0) scale(.97); }

/* 侧栏项 / 门户卡 / 卡片头 —— 导航级轻量动效（只阴影+位移，不 scale，避免列表跳动） */
.sidebar-item:hover { transform: translateX(2px); }
.portal-card-head:hover { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(15,34,56,.1); }

/* 全局总开关：关掉动效 = 只保留原有 hover 色变 */
:root[data-motion-off="1"] .btn,
:root[data-motion-off="1"] .op-btn,
:root[data-motion-off="1"] .link-action,
:root[data-motion-off="1"] .link-btn,
:root[data-motion-off="1"] .export-btn,
:root[data-motion-off="1"] .btn-ai,
:root[data-motion-off="1"] .btn-add-client,
:root[data-motion-off="1"] .np-btn,
:root[data-motion-off="1"] .sidebar-item,
:root[data-motion-off="1"] .portal-card-head {
  transform: none !important; box-shadow: none !important; filter: none !important;
}

/* 无障碍：系统「减弱动态效果」开启时，动效降级为纯色变（无位移/缩放/投影） */
@media (prefers-reduced-motion: reduce) {
  .btn, .op-btn, .link-action, .link-btn, .export-btn, .btn-ai, .btn-add-client,
  .np-btn, .sidebar-item, .portal-card-head {
    transition: none !important;
    transform: none !important;
    box-shadow: none !important;
    filter: none !important;
  }
}

/* ============ 第 89 批：内联线性图标（SVG stroke 2 · 24 视图框）============
   替代彩色 emoji 当功能图标（方案 §一.10 / 红线 4）。currentColor 随上下文变色：
   空态圆底内 28px（继承 .empty-state .icon 的 #C8D3E0）；卡头/标题内 1em 随文字。 */
.svg-ico { width: 1em; height: 1em; vertical-align: -0.12em; flex: none; }
.empty-state .icon .svg-ico { width: 28px; height: 28px; vertical-align: 0; }
.ncr-kb-head .svg-ico { align-self: center; }

/* ============ 2026-11-15 上线合规：ICP 备案号页脚（固定底部，全站可见）============ */
.site-icp {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 998;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 4px 10px;
  background: rgba(247, 248, 250, 0.94);
  border-top: 0.5px solid rgba(0, 0, 0, 0.06);
  font-size: var(--fs-xs);
  color: #5A6B7F;
  pointer-events: none;
}
.site-icp a {
  color: #185FA5;
  text-decoration: none;
  pointer-events: auto;
}
.site-icp a:hover { text-decoration: underline; }

