/* =====================================================================
   开发版皮肤 —— 与原型同源（暖纸质 token 直接搬，不另起一套色）
   只写 M1 用得到的部分；原型里的演示/讲解样式一律不搬（开发版必删文案清单）
   红两支：--red 金额（信息色）· --alert 警示（逾期/驳回）
   按钮按动作分档：审核=浅底表态 · 付款=实心落实 · 打印=描边工具（§8.54）
   ===================================================================== */
:root {
  --bg: #F5F2EC;
  --paper: #FFFFFF;
  --line: #D9D2C5;
  --line-soft: #EFEBE2;
  --ink: #14304F;
  --ink-2: #3E5970;
  --mute: #616B79;
  --amber: #E08A2B;
  --amber-ink: #8A4F0E;
  --amber-soft: #FCEBD3;
  --green: #31784D;
  --green-soft: #E1F1E7;
  --red: #B14A3C;
  --alert: #98392C;
  --alert-soft: #F3D6CE;
  --red-soft: #F5DFD9;
  --blue-soft: #E1EAF3;
  --gray-soft: #EFEBE2;
  /* 紫只给「类型卡图标底」用（10-26 加）。纯装饰色，不表示状态、不做图例 —— 见原型 :root 注释。 */
  --plum-soft: #EAE4F1;
  --plum-ink: #5D4A78;
  --focus: #2F5C86;
  --shadow: 0 1px 4px rgba(20, 48, 79, .05);
  --shadow-lg: 0 12px 32px rgba(20, 48, 79, .14);
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  background: var(--bg);
  color: var(--ink);
  font: 14px/1.6 "PingFang SC", "Microsoft YaHei", system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--ink-2); }
button, input, select, textarea { font: inherit; color: inherit; }
/* 焦点态：同一套口径搬自原型（--focus 深蓝 2px 环，不跟琥珀色的选中态混）
   —— 键盘 Tab 到哪一目了然，这是可访问性底线，不是装饰 */
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 4px; }
.side a.nav:focus-visible, tbody tr:focus-visible { outline-offset: -2px; }
/* 侧栏底色变深后，全局的 --focus 深蓝环在侧栏里等于看不见 —— 侧栏内单独用白环（10-26）。
   焦点环可以低调，但不能消失。 */
.side a.nav:focus-visible { outline-color: #fff; }

/* ---------------- 骨架 ---------------- */
.app { display: flex; min-height: 100vh; }
/* 侧栏尺寸与分组长相照原型（宽 218 / 组标题 10.5px·mute·0.6 字距）
   —— 导航是三组：我的单据 / 资料 / 审核，组标题必须一眼分得开 */
.side {
  /* 10-26：底色由米白改品牌墨蓝（--ink）。整条侧栏只用这一个色号，
     其余层次全靠白色透明度叠层（.78 字 / .50 组标题 / .10 分隔与选中底），不新增色号。
     右边不再画浅米线：深蓝与米白反差已经够，加一条浅线反而脏。 */
  width: 218px; flex: 0 0 218px; background: var(--ink);
  border-right: 0;
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
}
/* 品牌区（10-26 改）：原「网上审批 / 乐美」纯文字 → 乐美 L.Vending 圆标 + 系统名。
   标是**透明底** PNG（四角 alpha=0，实测），所以不垫白底、不裁圆：绿环直接坐在墨蓝上；
   多垫一个白圆就成了「贴纸」，反而更抢眼。
   尺寸 38 是按两行文字量的（14 + 3 + 11 ≈ 31），取 38 让标志压住字块高度；
   padding 从 17/13 收到 12/11 —— 38 比原来的 31 高 7px，不收回来的话整条侧栏会被顶高一截。 */
.brand {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 18px 11px; border-bottom: 1px solid rgba(255,255,255,.10);
}
.brand .logo { width: 38px; height: 38px; flex: 0 0 38px; display: block; }
.brand .t { font-size: 14px; font-weight: 650; color: #fff; letter-spacing: .3px; }
.nav-h { font-size: 10.5px; color: rgba(255,255,255,.55); letter-spacing: .6px; padding: 12px 18px 5px; }
.side a.nav {
  display: flex; align-items: center; gap: 9px;
  margin: 0 10px 2px; padding: 9px 10px; border-radius: 7px; text-decoration: none;
  color: rgba(255,255,255,.78); font-size: 13px;
  position: relative;
}
.side a.nav:hover { background: rgba(255,255,255,.07); }
/* 选中态（10-26 改，照大R 给的图）：左侧一条琥珀竖条 + 浅色圆角底。
   原写法「整块深蓝底白字」—— 一条 218 宽的黑块压在米白页面上，视觉重量比内容还重；
   侧栏只是「去哪儿」的目录，不该抢主体。
   竖条画在**卡片外面**（left:-8 → 侧栏内缘 x=2）：竖条说「你在这格」，浅底说「这格能按」，
   两件事不该合成一个盒子。 */
.side a.nav.on { background: rgba(255,255,255,.10); color: #fff; font-weight: 600; }
.side a.nav.on::before {
  content: ''; position: absolute; left: -8px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 17px; border-radius: 0 2px 2px 0; background: var(--amber);
}
/* 图标是内联线描 SVG（10-26），原来用字符（⌂ ＋ ◷ …）。
   描边/端点写在这里统一管，路径在 layout.js 的 ICO 里；颜色走 currentColor，
   选中/常态自动跟着字色变，不用再来一套。 */
.side a.nav .ic {
  width: 16px; height: 16px; display: inline-flex; align-items: center; justify-content: center;
  opacity: .9;
}
.side a.nav .ic svg {
  width: 16px; height: 16px; display: block;
  fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
/* 角标只表示「有几件等你」，不表示状态 —— 所以只有数字，不带「待」字 */
.side a.nav .badge {
  margin-left: auto; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--amber); color: var(--ink); font-size: 10.5px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
/* 选中时角标**不再反白**（10-26 随选中态一起改）：选中底从深蓝变浅灰后，白底角标等于消失。
   角标说的是「有几件在等你」，选中与否都该是同一个样子。 */
.side .whoami {
  margin: auto 10px 12px; padding: 12px 8px 0;
  border-top: 1px solid rgba(255,255,255,.10); font-size: 12px; color: rgba(255,255,255,.55);
}.side .whoami b { display: block; color: #fff; font-size: 13px; }
/* 退出 —— 10-29 改：原先是纯行内文字，可点区只有 24×16，鼠标都要瞄。
   撑到 30px 高就够了：它只在 PC 侧栏出现（手机上 .whoami 整块 display:none，
   钉钉内不需要退出），不必按移动端 44px 标准。 */
.whoami-out { margin-top: 4px; }
/* ⚠️ 这里同时写两个选择器，是有意的：
   改了服务端模板（layout.js 里那个 div 加了 class）**不重启进程就不生效**，
   而只改 CSS 是立即生效的。用属性选择器 `a[href="/logout"]` 直接命中旧结构，
   改一次 CSS 就能验；等下次重启后 class 那套也接得上，两边不冲突。 */
.whoami-out a,
.side .whoami a[href="/logout"] {
  display: inline-flex; align-items: center; min-height: 30px; padding: 0 6px;
  margin-left: -6px; border-radius: 5px;
}
.whoami-out a:hover,
.side .whoami a[href="/logout"]:hover { background: rgba(255,255,255,.08); }

.main { flex: 1; min-width: 0; padding: 22px 26px 44px; }
/* 内容上限 —— 出处：列表与详情壳原型_v1.html 的 .main-in。
   不设上限在 1920 屏上内容横着铺满，视觉上"没有版面"。 */
.main-in { max-width: 1420px; margin: 0 auto; }
/* 页头 —— 出处：壳原型 .page-h。原来 17px 与正文只差 3px，一屏里找不到"我在哪" */
.page-h { display: flex; align-items: flex-end; gap: 10px; margin-bottom: 6px; flex-wrap: wrap; }
.page-h h1 { font-size: 22px; font-weight: 700; margin: 0; letter-spacing: -.2px; line-height: 1.3; }
.page-h .sub { font-size: 12.5px; color: var(--mute); }
/* 页头里的动作链接（付款单「换类型」/ 新建页「取消」）：要一眼看出可点，又不许跟副标题
   混成一句话 —— 下划线是唯一不需要 hover 就能看出来的"这是链接"信号。
   靠右站（margin-left:auto）：紧贴副标题 10px，会被读成「… 传凭证 → 提交 取消」一整句。
   flex:0 0 auto + nowrap：窄屏副标题一挤，「取消」会被压成「取／消」两行。 */
.page-h .hdr-link {
  font-size: 12.5px; color: var(--mute); margin-left: auto; flex: 0 0 auto; white-space: nowrap;
  text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px;
}
.page-h .hdr-link:hover { color: var(--amber-ink); }
.toolbar { display: flex; gap: 9px; align-items: center; flex-wrap: wrap; margin: 14px 0 0; }

/* 分段筛选（照原型 .seg）—— 列表的类型筛选用它，不另造下拉 */
.seg {
  display: inline-flex; border: 1px solid var(--line); border-radius: 7px;
  /* ⚠️ 10-29：`max-width` + `overflow-x` 是**必须**的。
     `inline-flex` 不限制自身宽度，标签一多（审计日志的动作类型几十个）就把整页撑到 2921px，
     `overflow:hidden` 只裁自己内部、管不住自己的宽度 —— PC 上整页横向滚动就是这么来的。
     窄屏另有 flex-wrap 折行（见下面的媒体查询），两边都要，别只留一个。 */
  max-width: 100%; overflow-x: auto; overflow-y: hidden;
  background: var(--paper); margin-top: 12px;
}
.seg a {
  padding: 6px 12px; font-size: 12px; color: var(--ink-2); text-decoration: none; white-space: nowrap;
}
.seg a + a { border-left: 1px solid var(--line); }
.seg a:hover { background: var(--gray-soft); }
.seg a.on { background: var(--ink-2); color: #fff; }
@media (max-width: 640px) {
  /* 不再横滚：5 个筛选格在 390px 上排不进一行，`overflow-x:auto` 的结果是「出差单」
     永远藏在右边、只能横拖出来（实测截图）。连体分段框折行会断边框，所以窄屏改成
     各自独立的药丸 —— 还是同一组筛选，只是不再共用外框。 */
  .seg {
    display: flex; flex-wrap: wrap; width: 100%; gap: 6px;
    overflow: visible; border: 0; background: transparent;
  }
  .seg a {
    border: 1px solid var(--line); border-radius: 999px; background: var(--paper);
    padding: 5px 11px; font-size: 12px;
  }
  .seg a.on { border-color: var(--ink-2); }
}

/* 新建单据：选类型（照原型 .types / .type）
   ⚠️ 最小宽度 215px 是算出来的：现在有 5 张单，250px 只排得下 4 张 → 第 5 张孤零零吊在第二行。
   auto-fill 自己会按容器宽度决定列数，别写死 repeat(4, 1fr)（加一种单据就得改一次）。 */
/* 口径提示块（出处：个人工作台原型_v1.html 的 .tips / .tip）——
   工作台底部那三块用它。开发版以前没有页面用过这个组件，所以一直没落过来，
   皮肤守卫也就一直没盯它；这次补上并纳入守卫（47 → 55 → 58 个组件）。
   ⚠️ 里面三个十六进制是原型原值，别改成 token：守卫是逐属性比对的，改了就红。 */
.tips { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
.tip { background: #FBF8F2; border: 1px dashed #DCCFB8; border-radius: 9px; padding: 9px 13px; font-size: 12px; color: var(--ink-2); }
.tip b { color: var(--ink); }
.tip .k { font-size: 10.5px; color: #8A6A33; display: block; margin-bottom: 2px; letter-spacing: .3px; }

.types { display: grid; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); gap: 13px; }
.type {
  display: block; text-decoration: none; color: inherit; background: var(--paper);
  border: 1px solid var(--line); border-radius: 11px; padding: 15px 16px 14px;
  box-shadow: var(--shadow); transition: transform .14s, box-shadow .14s, border-color .14s;
}
.type:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); border-color: #C6B79A; }
.type .hd { display: flex; align-items: center; gap: 9px; }
.type .ico {
  width: 30px; height: 30px; border-radius: 8px; background: var(--blue-soft); color: var(--focus);
  display: inline-flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 700;
}
/* 图标底按单据类型上色（10-26 加）：纯装饰，不表示状态、不做图例、不进任何判断。
   红系（--red / --alert）不参与分类 —— 那两个色留给金额和警示。 */
.type .ico.ico-blue  { background: var(--blue-soft);  color: var(--focus); }
.type .ico.ico-amber { background: var(--amber-soft); color: var(--amber-ink); }
.type .ico.ico-green { background: var(--green-soft); color: var(--green); }
.type .ico.ico-plum  { background: var(--plum-soft);  color: var(--plum-ink); }
.type .ico.ico-gray  { background: var(--gray-soft);  color: var(--ink-2); }
.type .nm { font-size: 13.5px; font-weight: 650; }
.type .ds { font-size: 11.5px; color: var(--ink-2); margin-top: 9px; line-height: 1.65; }
.type .ft {
  margin-top: 10px; padding-top: 9px; border-top: 1px dashed var(--line-soft);
  font-size: 11px; color: var(--mute); display: flex; gap: 8px;
}
.type .go { margin-left: auto; color: var(--amber-ink); font-weight: 600; }
@media (max-width: 640px) { .types { grid-template-columns: 1fr; } }

/* ---------------- 卡片 ---------------- */
.card {
  background: var(--paper); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: var(--shadow); overflow: hidden;
}
.card-h {
  padding: 13px 16px; border-bottom: 1px solid var(--line-soft);
  font-size: 13.5px; font-weight: 650; display: flex; align-items: center; gap: 10px;
}
.card-h .right { margin-left: auto; font-weight: 400; font-size: 12px; color: var(--mute); }
.card-b { padding: 16px; }
.card-b > :first-child { margin-top: 0; }
.card-b > :last-child { margin-bottom: 0; }

/* ---------------- 按钮（档位照原型，别自己再起一套） ----------------
   基础   白底浅描边 —— 次要动作
   .pri   墨蓝实心   —— 「点进去就办这件事」（通过 / 确认付款 / 提交）
   .danger 浅红底    —— 驳回 / 撤回（否定动作，不当主按钮）
   .warn  浅琥珀     —— 提示性动作
   .sm    列表行内动作（审核 / 登记付款）：28px 高、12px 字
   口径来源：个人工作台原型「列表行的两个动作按钮」一节
   ⛔ 两条不能破：实心每行只许一个；禁橙底白字（2.68:1，§8.5x 已否决） */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 32px; padding: 0 13px; border-radius: 7px; cursor: pointer;
  border: 1px solid var(--line); background: var(--paper); color: var(--ink-2);
  font-size: 12.5px; text-decoration: none; white-space: nowrap;
}
.btn:hover { border-color: var(--ink-2); color: var(--ink); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn.sm {
  height: 28px; padding: 0 10px; font-size: 12px; font-weight: 600;
  border-color: #C9C0B0; color: var(--ink-2); border-radius: 6px;
}
.btn.sm:hover { border-color: var(--ink); color: var(--ink); }
.btn.pri { background: var(--ink); border-color: var(--ink); color: #fff; font-weight: 600; }
.btn.pri:hover { background: #1F4063; border-color: #1F4063; color: #fff; }
.btn.danger { background: var(--alert-soft); border-color: #DDA79B; color: var(--alert); font-weight: 600; }
.btn.danger:hover { border-color: var(--alert); color: var(--alert); }
.btn.warn { background: var(--amber-soft); border-color: #E8C89A; color: var(--amber-ink); }
.btn.warn:hover { border-color: var(--amber-ink); color: var(--amber-ink); }
/* 列表行内的两个动作：审核 = 表态（浅琥珀底）· 登记付款 = 落实（墨蓝实心） */
.btn.sm.act-review { background: var(--amber-soft); border-color: var(--amber-ink); color: var(--amber-ink); }
.btn.sm.act-review:hover { background: #F8DFBE; border-color: var(--amber-ink); color: var(--amber-ink); }
.btn.sm.act-pay { background: var(--ink); border-color: var(--ink); color: #fff; padding: 0 12px; }
.btn.sm.act-pay:hover { background: #1F4063; border-color: #1F4063; color: #fff; }
.btn.ghost { border-color: transparent; background: transparent; color: var(--ink-2); }
.btn.ghost:hover { background: #FBF8F2; border-color: var(--line); }

/* ---------------- 指标卡（端 3 概览） ----------------
   逐条照 管理后台原型_v1.html 的 .kpis / .kpi 抄，不改值。
   ⛔ **不带 hover、不带 cursor:pointer** —— 它不可点。
     卡片带 hover 反馈就变成"假手型"（§6）：看着能进，点了没反应。 */
.kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 16px; }
.kpi { background: var(--paper); border: 1px solid var(--line); border-radius: 10px; padding: 15px 16px; box-shadow: var(--shadow); }
.kpi .k { font-size: 11.5px; color: var(--mute); }
.kpi .v { font-size: 25px; font-weight: 650; letter-spacing: -.3px; margin-top: 5px; font-variant-numeric: tabular-nums; }
.kpi .v small { font-size: 12px; font-weight: 500; color: var(--mute); margin-left: 4px; }
.kpi .d { font-size: 11.5px; color: var(--ink-2); margin-top: 4px; }
@media (max-width: 640px) { .kpis { grid-template-columns: 1fr 1fr; } }

/* ---------------- 壳：主列 + 右栏 / 摘要 / 时间轴 / 规则卡 ----------------
   出处全部是 列表与详情壳原型_v1.html（第 6 批样式补强，2026-10-26）。
   ⛔ 配色一处没动 —— 抄的是结构：页头、宽度、分栏、行高、呈现方式。 */

/* 工作台数字卡（壳原型 ⑨）：卡是 <a>，**整块可点**，所以带 :hover。
   ⛔ 与端 3 的 .kpi 不是一套 —— 那个不可点，故意不带 hover（带了就是假手型）。 */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(196px, 258px)); justify-content: start; gap: 12px; margin-bottom: 16px; }
.stat {
  display: block; text-decoration: none; color: inherit;
  background: var(--paper); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: var(--shadow); padding: 13px 15px 12px;
  position: relative; overflow: hidden;
  transition: border-color .14s, box-shadow .14s;
}
.stat:hover { border-color: #C6B79A; box-shadow: var(--shadow-lg); }
/* 右上角的柔和色块：**纯点缀**——不承载信息、不接鼠标、不参与 hover。
   颜色按**卡片身份**给（.s-todo / .s-mine / .s-pay），⛔ 不按位置：卡片是按角色出现的，
   基础员工只看得到中间那张，用 nth-child 上色就会串色（少一张卡，后面的颜色全错位）。 */
.stat::after {
  content: ""; position: absolute; top: -32px; right: -24px; width: 84px; height: 84px;
  border-radius: 50%; background: var(--blue-soft); opacity: .55; pointer-events: none;
}
.stat.s-todo::after { background: var(--amber-soft); }
.stat.s-mine::after { background: var(--blue-soft); }
.stat.s-pay::after { background: var(--green-soft); }
.stat .n { font-size: 25px; font-weight: 700; line-height: 1.15; font-variant-numeric: tabular-nums; }
.stat .k { display: flex; align-items: baseline; gap: 8px; font-size: 12px; color: var(--mute); margin-top: 3px; }
.stat .k .go { margin-left: auto; color: var(--amber-ink); }
/* 工作台每一块之间只补一个上边距，其余全复用 .card / .card-h */
.home-sec { margin-top: 16px; }
.home-sec .card-h .more { font-size: 12px; color: var(--amber-ink); text-decoration: none; }
.home-sec .card-h .more:hover { text-decoration: underline; }

/* 详情页与填单页共用：左主列 + 右栏（右栏 sticky，滚正文时它跟着） */
.duo {
  display: grid;
  grid-template-columns: minmax(0, 1.62fr) minmax(288px, .88fr);
  gap: 16px; align-items: start;
}
.duo > .col { min-width: 0; }
/* 填单页右栏只放「本单合计」两三个数，按 .88fr（约 380px）给纯属浪费 ——
   10-27 大R：「本单合计不用那么宽，缩小一半吧，太宽了，占用了左边的填表区域」。
   详情页右栏装的是审批记录 + 操作，宽度不动，所以只给填单页加 .tight。 */
.duo.tight { grid-template-columns: minmax(0, 1fr) minmax(0, 208px); }
.duo.tight .sum .tot .v { font-size: 17px; }
.rail { position: sticky; top: 14px; }
/* 窄屏退回单列：右栏的内容跟着主列往下排，不能浮在上面挡字段。
   ⚠️ 必须写 `minmax(0, 1fr)` —— 写 `1fr` 时列宽的下限是内容的 min-content，
      里面的宽表格会把整页顶出屏幕（表格自己的 .tbl-wrap 就没得滚了）。 */
@media (max-width: 1080px) { .duo, .duo.tight { grid-template-columns: minmax(0, 1fr); } .rail { position: static; } }

/* 填单页右栏的摘要：只放**派生出来的数**和已填的关键字段。
   ⛔ 不放「审批链预览」—— 链取决于部门与金额，填单中途算出来的链会变，
      等于给一个会骗人的预告（与「出差详情页不加链预览」同一条口径）。 */
.sum { display: flex; flex-direction: column; gap: 7px; }
.sum .r { display: flex; align-items: baseline; gap: 8px; font-size: 12.5px; }
.sum .r .k { color: var(--mute); }
.sum .r .v { margin-left: auto; font-weight: 600; font-variant-numeric: tabular-nums; }
.sum .tot { border-top: 1px solid var(--line-soft); margin-top: 6px; padding-top: 10px; }
.sum .tot .v { font-size: 20px; color: var(--ink); }

/* 审批时间轴：原来 `.chain` 是横的一串 chips，5 个节点挤一行看不出走到第几个。
   ⚠️ 只换呈现，不改"显示哪些节点"—— 哪个节点该出现仍由引擎决定。 */
.tl-v { list-style: none; margin: 0; padding: 0 0 0 20px; position: relative; }
.tl-v::before {
  content: ''; position: absolute; left: 5px; top: 6px; bottom: 10px;
  width: 1px; background: var(--line);
}
.tl-v li { position: relative; padding-bottom: 14px; }
.tl-v li:last-child { padding-bottom: 0; }
.tl-v li::before {
  content: ''; position: absolute; left: -19px; top: 4px;
  width: 11px; height: 11px; border-radius: 50%; box-sizing: border-box;
  background: var(--paper); border: 2px solid var(--line);
}
.tl-v li.ok::before { background: var(--green); border-color: var(--green); }
.tl-v li.cur::before { background: var(--amber); border-color: var(--amber); box-shadow: 0 0 0 3px var(--amber-soft); }
.tl-v li.no::before { background: var(--alert); border-color: var(--alert); }
.tl-v .h { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.tl-v .n { font-size: 12.5px; font-weight: 600; }
.tl-v .r { font-size: 11.5px; color: var(--mute); }
.tl-v .t { font-size: 11px; color: var(--mute); margin-left: auto; font-variant-numeric: tabular-nums; }
.tl-v .c { font-size: 12px; color: var(--ink-2); margin-top: 3px; }
.tl-v .skip { font-size: 11.5px; color: var(--mute); margin-top: 3px; }

/* 规则卡：一条链一张卡（原为 10 行大表 —— 查表方便，讲给人听不方便） */
.rule-c {
  border: 1px solid var(--line); border-left: 3px solid var(--amber);
  border-radius: 0 10px 10px 0; background: var(--paper);
  padding: 13px 15px;
}
.rule-c + .rule-c { margin-top: 10px; }
.rule-c .h { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.rule-c .t { font-size: 13.5px; font-weight: 650; }
.rule-c .for { font-size: 11.5px; color: var(--mute); }
.rule-c .flow { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 10px; }
.rule-c .nd {
  display: inline-flex; flex-direction: column; gap: 0;
  border: 1px solid var(--line); background: var(--bg); border-radius: 7px;
  padding: 3px 9px; font-size: 12px; line-height: 1.35;
}
.rule-c .nd b { font-weight: 600; white-space: nowrap; }
.rule-c .nd i { font-style: normal; font-size: 10px; color: var(--mute); white-space: nowrap; }
.rule-c .nd.fin { border-color: var(--amber); background: var(--amber-soft); }
.rule-c .nd.gm { border-color: var(--ink-2); background: var(--blue-soft); }
.rule-c .ar { color: var(--mute); font-size: 11px; }
.rule-c .note {
  margin-top: 10px; padding: 7px 10px; border-radius: 0 6px 6px 0;
  border-left: 2px solid var(--amber); background: var(--amber-soft);
  font-size: 11.5px; color: var(--amber-ink); line-height: 1.65;
}

/* ---------------- 表格 ---------------- */
.tbl-wrap { overflow-x: auto; }
/* 窄屏：明细表**不给下限宽度**，宁可折字也不让用户左右拖。
   ⚠️ 这里原来写的是 `min-width: 520px`（为了防「附件」列把文件名竖排成三行）。
   代价实测出来是：采购物品 6 列在 390px 上只露出前 4 列，**单价/小计要横拖才看得见** ——
   列被藏起来比字折行严重得多（10-28 大R：「不要左右拖动，宽度固定，上下移动」）。
   所以改成让它自己收窄：表格自己算列宽，字允许折，数字列单独 nowrap（折成两行的金额=看错）。
   .tbl-wrap 的 overflow-x 留着只作极端兜底（将来加列），正常渲染不该触发。 */
@media (max-width: 640px) {
  .tbl-wrap > table { min-width: 0; table-layout: auto; }
  /* ⚠️ 必须带 `.tbl-wrap` 前缀：文件后面还有一条同名的 `thead th { ... padding:10px 13px }`，
     两条特异性相同、后定义的赢 —— 只写 `thead th` 的话这几条**整段失效**（看着像改了没生效）。 */
  /* 表头**不折行**，让每列按最长的表头算宽：「报销明细」被挤成 3 行（报销明/细）比缺列
     更难读，而折行宽度是浏览器自己算的，`min-width` 在 table-cell 上不参与列宽计算
     （试过 2.2em / 4.2em，Chrome 都不认）。用 nowrap 逼它按 4 字撑开，实测 6 列仍放得下。 */
  .tbl-wrap thead th { padding: 8px 6px; font-size: 10.5px; white-space: nowrap; }
  /* break-word 而不是 anywhere：anywhere 会把每个字符都算成断点，于是浏览器认为
     「2026-11-01」的最窄宽度只有 1 个字，把日期列压成两行（2026-11- / 01，实测）。
     break-word 只在真的溢出时才断，列宽仍按最长不可断片段算。 */
  .tbl-wrap tbody td { padding: 9px 6px; font-size: 12.5px; white-space: normal; overflow-wrap: break-word; }
  /* 数字列必须整行显示：上面那条 overflow-wrap:anywhere 会把 250.00 断成「250.0 / 0」，
     金额断开就等于看错（实测第一版就是这样）。数字列反过来要求最窄宽度，宁可挤名称列。 */
  .tbl-wrap tbody td.num, .tbl-wrap thead th.num { white-space: nowrap; overflow-wrap: normal; }
  /* 序号/数量这类 1-2 个字符的列，留 18px 就够，别让它跟名称抢宽度 */
  .tbl-wrap thead th:first-child, .tbl-wrap tbody td:first-child { padding-left: 4px; padding-right: 2px; }
}

/* 手机：**列表**改成「一条一卡」，不再左右拖（10-28 大R：「需要左右拖动」）。
   上面那条 520px 是给**明细表**的（宁可横滚不折字，一行的数字要对齐才看得出关系）；
   但列表页不一样 —— 8 列横滚 = 一屏只能看到 3 列，看单子得来回拖，这不是"挤"，是"看不全"。
   字段名由 td 的 data-label 带出来：信息一个不丢，只是换方向排。
   ⚠️ 只认 .card-list。后台那些表（admin.js）在 PC 上用，不给它们加 data-label，
      一刀切会让后台在窄屏变成一堆没标签的碎行。 */
@media (max-width: 640px) {
  /* 特异性要压过 `.tbl-wrap > table`（两条都是 0,1,1，靠后者胜；这里写成两段稳一点） */
  .tbl-wrap > table.card-list { min-width: 0; }
  table.card-list thead { display: none; }
  table.card-list, table.card-list tbody { display: block; }

  table.card-list tbody tr {
    display: flex; flex-direction: column;
    background: var(--paper); border: 1px solid var(--line); border-radius: 10px;
    padding: 11px 13px 12px; margin: 0 0 9px;
    box-shadow: 0 1px 2px rgba(60,45,20,.04);
  }
  table.card-list tbody tr:last-child { margin-bottom: 0; }
  /* 桌面版的行 hover 在卡片里会整块泛黄，像被选中；卡片有自己的边框，不需要 */
  table.card-list tbody tr:hover { background: var(--paper); }
  table.card-list tbody td {
    display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 8px;
    padding: 2px 0; border: 0; font-size: 13px; line-height: 1.55;
  }
  /* 标签宽度取 auto + 52px 下限：固定 52px 时「对公 / 对私」这种 5 字标签会撑出格子、
     跟值黏成一串（列表页标签多为 2-3 字，明细页才有长标签）。 */
  table.card-list tbody td::before {
    content: attr(data-label);
    flex: 0 0 auto; min-width: 52px; font-size: 11.5px; color: var(--mute); white-space: nowrap;
  }
  /* 事由是这张卡的标题：排最上、字大、不带字段名，下面一条虚线跟其余字段分开 */
  table.card-list tbody td.reason {
    order: -1; display: block; font-size: 14.5px; font-weight: 650; color: var(--ink);
    padding: 0 0 7px; margin-bottom: 5px; border-bottom: 1px dashed var(--line-soft);
  }
  table.card-list tbody td.reason::before { display: none; }
  /* 事由下面那行小字（如"谁提的、什么公司"）在卡片里要自己占一行，别跟事由挤一起 */
  table.card-list tbody td.reason .small { display: block; font-weight: 400; margin-top: 3px; }
  /* 状态列后面的小字（如 sub_note）同理 */
  table.card-list tbody td .small { flex: 1 0 100%; }
  table.card-list tbody td.num { text-align: left; }
  table.card-list tbody td.amt { font-size: 14.5px; }
  /* 操作按钮整宽：手指点得到，也不用瞄一个 32px 的小目标 */
  table.card-list tbody td.op { padding-top: 9px; }
  table.card-list tbody td.op::before { display: none; }
  table.card-list tbody td.op .btn { width: 100%; text-align: center; }
  /* 空态不是卡片：colspan 那一行要还原成一整块普通提示，别给它边框和内边距 */
  table.card-list tbody tr.empty-row { background: transparent; border: 0; box-shadow: none; padding: 0; }
  table.card-list tbody tr.empty-row td.empty { display: block; padding: 22px 4px; }
  table.card-list tbody tr.empty-row td.empty::before { display: none; }
}
table { width: 100%; border-collapse: collapse; }
thead th {
  text-align: left; font-size: 12px; font-weight: 650; color: var(--mute);
  padding: 10px 13px; border-bottom: 1px solid var(--line); white-space: nowrap; background: #FCFAF6;
}
tbody td { padding: 11px 13px; border-bottom: 1px solid var(--line-soft); font-size: 13px; vertical-align: middle; }
tbody tr:hover { background: #FBF8F2; }
tbody tr:last-child td { border-bottom: 0; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
/* 金额列用红：中国财务习惯里红是「信息色」，不表示出事（警示才是 --alert） */
td.num.amt { color: var(--red); }
td .no { font-size: 12px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
td .small { font-size: 11.5px; color: var(--mute); }
/* 列表页：除「事由」外一律不折行 ——
   单号断成「…-20261023-」/「0001」、人名断成「徐素」/「芬」，比列宽一点更难受。
   放不下就让 .tbl-wrap 横向滚，不靠折行硬塞。 */
table.list td { white-space: nowrap; }
table.list td.reason { white-space: normal; min-width: 180px; }
/* 10-29：审计日志原来没加 `list`，六列自由分配宽度 → 「时间」被压成三行、「谁」竖排成一个字一行。
   加 nowrap 治住了，但「明细」列是 JSON 片段（120 字），nowrap 会把表格撑到横滚，
   所以单独让它折行并给上限。**现在是 nowrap 治竖排、wrap 治横撑，两处都得有。** */
table.list td.wrap { white-space: normal; min-width: 200px; max-width: 300px; word-break: break-all; }
.empty { padding: 44px 16px; text-align: center; color: var(--mute); font-size: 13px; }
.empty b { display: block; color: var(--ink-2); margin-bottom: 5px; }
.empty span { display: block; font-size: 12px; }

/* 打印次数：**只是个提示，不是按钮** —— 只占 2ch 宽显示数字，完整说法进 title。
   这一格不能把行拉高，也不能把打印按钮顶走。与原型 .pr-n 同源，改这里要同步原型。 */
.pr-n {
  display: inline-block; width: 2ch; margin-left: 7px;
  font-size: 11px; color: var(--mute); line-height: 1.2;
  font-variant-numeric: tabular-nums; white-space: nowrap;
  vertical-align: middle; text-align: left;
}

/* ---------------- 状态标签 tag ----------------
   名字和配色都照原型（不是 .chip）：语义化命名 —— wait 待审 / ok 通过 / no 驳回 / draft 草稿 / info 告知。
   ⛔ 不要按颜色取名（gray/green/red）：同一个"红"在"金额"和"驳回"是两个语义，配色规则会打架。 */
.tag {
  display: inline-flex; align-items: center; gap: 4px; height: 21px; padding: 0 8px;
  border-radius: 5px; font-size: 11.5px; font-weight: 600; white-space: nowrap;
}
.tag.wait { background: var(--amber-soft); color: var(--amber-ink); }
.tag.ok { background: var(--green-soft); color: var(--green); }
.tag.no { background: var(--alert-soft); color: var(--alert); }
.tag.draft { background: var(--gray-soft); color: var(--ink-2); }
.tag.info { background: var(--blue-soft); color: #2F5C86; }
.tag.sm { height: 18px; padding: 0 6px; font-size: 11px; font-weight: 500; }

/* ---------------- 表单 ---------------- */
.field { margin-bottom: 14px; }
.field > label { display: block; font-size: 12.5px; color: var(--ink-2); font-weight: 600; margin-bottom: 6px; }
.field > label .req { color: var(--alert); margin-left: 3px; }
.field .hint { font-size: 11.5px; color: var(--mute); margin-top: 5px; }
/* 兜底：.hint 不只出现在 .field 里（类型卡下方、登录页、前置单据提示都用它）。
   不写这条，那些提示就没样式 —— 看着像正文，实际是说明文字。 */
.hint { font-size: 11.5px; color: var(--mute); }
.input, .select, .textarea {
  width: 100%; height: 34px; padding: 0 11px; border-radius: 7px;
  border: 1px solid var(--line); background: #FFFDF9;
}
.textarea { height: auto; min-height: 64px; padding: 8px 11px; resize: vertical; line-height: 1.6; }
.input:focus, .select:focus, .textarea:focus { outline: none; border-color: var(--amber-ink); box-shadow: 0 0 0 3px rgba(224, 138, 43, .12); }
.input.err, .select.err { border-color: var(--alert); }
.input.amount { width: calc(10ch + 18px); text-align: right; font-variant-numeric: tabular-nums; }
.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.row3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 14px; }
.inline { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.check { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--ink-2); }

/* 多选 chips（交通方式等）—— 出处：M6b出差申请原型_v1.8。
   选中态是「浅橙底 + 2px 深橙边 + 深橙字 + ✓」四重信号，不是橙底白字（2.68:1 判据已否决）。
   ⚠️ 这个 .chip 与早先那个状态标签 .chip **不是一回事**（那个已改名 .tag，按语义取名）。 */
.chip-group { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 13px; font-size: 13px; line-height: 1.2;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--paper); color: var(--ink-2);
  cursor: pointer; user-select: none;
}
.chip:hover { border-color: var(--amber-ink); color: var(--amber-ink); }
.chip.selected {
  background: var(--amber-soft); border: 2px solid var(--amber-ink);
  color: var(--amber-ink); font-weight: 600;
  box-shadow: none;
}
.chip.selected::after { content: '✓'; font-size: 11px; opacity: .9; }
.chip-hint { font-size: 11px; color: var(--mute); margin-bottom: 8px; }

/* 明细子表（PC）：项目 / 描述 / 数量 / 金额 / 附件 */
.lines { border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.lines-h, .line {
  display: grid; grid-template-columns: 1.6fr 3.4fr 64px 110px 1fr 34px;
  gap: 8px; align-items: center; padding: 8px 11px;
}
.lines-h { background: #FCFAF6; border-bottom: 1px solid var(--line); font-size: 11.5px; color: var(--mute); font-weight: 650; }
.line { border-bottom: 1px solid var(--line-soft); }
.line:last-child { border-bottom: 0; }
.line .qty { width: 100%; text-align: center; }
.line .amt { width: 100%; text-align: right; font-variant-numeric: tabular-nums; }
.line .del { border: 0; background: transparent; color: var(--mute); cursor: pointer; font-size: 16px; line-height: 1; padding: 2px 4px; border-radius: 5px; }
.line .del:hover { background: var(--red-soft); color: var(--alert); }
/* 明细行的票据入口（10-27 大R：新建报销单里「附件」列只写了"存草稿后上传"，等于没有入口）。
   选好文件先只记数，存草稿拿到行号之后才真上传 —— 按钮上的数字就是"已经挑了但还没传"的张数。 */
.line .att-btn { padding: 0 8px; font-size: 11.5px; }
/* 按钮在 grid 里默认被拉满整格（手机端一行两列时尤其难看）→ 让它只占自己那么宽 */
.line .att-wrap { display: inline-flex; justify-self: start; }
.line.has-att .att-btn { background: var(--ink); border-color: var(--ink); color: #fff; }
.line.has-att .att-btn:hover { background: #1F4063; border-color: #1F4063; color: #fff; }
.lines-f { display: flex; align-items: center; gap: 10px; padding: 9px 11px; background: #FCFAF6; border-top: 1px solid var(--line); }
.lines-f .total { margin-left: auto; font-size: 13px; color: var(--ink-2); }
.lines-f .total b { font-size: 15px; color: var(--red); font-variant-numeric: tabular-nums; }

/* ---------- 附件 / 发票选择器（10-27 按原型重做）----------
   为什么不是直接摆一个 <input type=file>：它的 files 每选一次就**整体覆盖**，
   传了一张再点一次，上一张就没了，页面上还看不出来（大R：「再选一张，附件就变成 1 张了」）。
   这里把每次选的攒成一个清单：选了多少张、叫什么、各多大，一眼看得见；
   传错了删单张，接着再点「+ 上传」继续加 —— 老的不动。 */
.att-empty { padding: 13px 12px; font-size: 12.5px; color: var(--mute); line-height: 1.6; }
.att-item {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 12px; border-bottom: 1px solid var(--line-soft);
}
.att-item:last-child { border-bottom: 0; }
/* 类型标签（PDF / 图片）：⚠️ 不用 📄 emoji —— 它在部分 Windows 字体下渲染成灰方块，
   而这个小标签是判断"这是张票还是一个坏文件"的唯一线索，不能靠字体运气。 */
.att-item .ext {
  flex: none; min-width: 34px; padding: 2px 4px; border-radius: 3px; text-align: center;
  font-size: 10px; font-weight: 650; letter-spacing: .3px;
  color: var(--mute); background: var(--line-soft);
}
.att-item .nm {
  flex: 1 1 auto; min-width: 0; font-size: 12.5px; color: var(--ink-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.att-item .sz { flex: none; font-size: 11.5px; color: var(--mute); font-variant-numeric: tabular-nums; }
.att-item .own { flex: none; width: 190px; height: 28px; padding: 2px 6px; font-size: 12px; }
.att-item .del {
  flex: none; border: 0; background: transparent; color: var(--mute); cursor: pointer;
  font-size: 15px; line-height: 1; padding: 2px 5px; border-radius: 5px;
}
.att-item .del:hover { background: var(--red-soft); color: var(--alert); }

/* 报销明细：项目 / 描述 / 发票数量 / 金额 / 删（10-27 发票独立成层，附件列撤掉，
   明细行只留一个「发票数量」—— 它由发票区的张数算出来，不再手填）。 */
.lines.m1 .lines-h, .lines.m1 .line {
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 3.6fr) 68px 110px 34px;
}
/* 发票数量是**算出来的**数，不是输入框 —— 灰字摆着，一眼看出不是让你填的。
   它和发票区的张数是同一个来源（syncQty 一处算），所以不会再出现
   「附件 2 张、发票数量还是 1」这种自相矛盾。 */
.line .qty-ro {
  font-size: 12px; color: var(--ink-2); text-align: center;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.line .qty-ro.zero { color: var(--mute); }

/* 出差单的三张子表：列数不同，各自一套列宽（基础 .lines 是 6 列，给报销明细用的）
   ⚠️ 日期是**浏览器原生控件**，不给固定宽度就会被挤成「年 月」两个字 —— 这是实打实踩过的。 */
.lines.dest .lines-h, .lines.dest .line {
  grid-template-columns: minmax(0, 1.5fr) 138px 138px 112px minmax(0, 1.5fr) 34px;
}
.lines.cost .lines-h, .lines.cost .line {
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 2.6fr) 120px 34px;
}
.lines.member .lines-h, .lines.member .line {
  grid-template-columns: minmax(0, 2.2fr) minmax(0, 1.4fr) 34px;
}

/* 详情页/合计里的金额大字：红 + 数字等宽 + 负字距（照原型金额口径）
   ⛔ 别在视图里内联 font-size —— 四处各写一遍就一定会有一处写成 16px。 */
.amount-big {
  font-size: 17px; font-weight: 650; letter-spacing: -.2px;
  color: var(--red); font-variant-numeric: tabular-nums;
}
.amount-big.ml { margin-left: 8px; }

/* 提示：轻，但不糊（≥4.5:1）· 不占标题行 · 无独立色块 */
.hint-line { border-left: 2px solid var(--line); padding-left: 9px; font-size: 12px; color: var(--mute); line-height: 1.65; }
.hint-line.warn { border-left-color: var(--alert); color: var(--alert); }
.hint-line.ok { border-left-color: var(--green); color: var(--green); }

/* ---------------- 审批链预览 ---------------- */
.chain { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.chain .step {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 20px; border: 1px solid var(--line);
  background: #FFFDF9; font-size: 12.5px; color: var(--ink-2);
}
.chain .step .r { color: var(--mute); font-size: 11.5px; }
.chain .arrow { color: var(--mute); font-size: 12px; }
.chain .step.me { border-color: var(--ink); color: var(--ink); font-weight: 600; }
.chain .skipped { font-size: 11.5px; color: var(--mute); }

/* ---------------- 时间线（审批记录） ---------------- */
.tl { list-style: none; margin: 0; padding: 0; }
.tl li { display: grid; grid-template-columns: 112px 1fr; gap: 10px; padding: 9px 0; border-bottom: 1px dashed var(--line-soft); }
.tl li:last-child { border-bottom: 0; }
.tl .when { font-size: 11.5px; color: var(--mute); font-variant-numeric: tabular-nums; white-space: nowrap; }
.tl .who { font-size: 13px; font-weight: 600; }
.tl .who .r { font-weight: 400; color: var(--mute); font-size: 11.5px; margin-left: 6px; }
.tl .cmt { font-size: 12.5px; color: var(--ink-2); margin-top: 2px; }

/* ---------------- 提示条 ---------------- */
.flash { padding: 10px 14px; border-radius: 8px; font-size: 13px; margin-bottom: 14px; }
.flash.ok { background: var(--green-soft); color: var(--green); }
.flash.err { background: var(--alert-soft); color: var(--alert); }
.flash.info { background: var(--blue-soft); color: var(--ink-2); }

/* =====================================================================
   登录页（10-28 重设计：把「审批」做成一张单据）
   沿用暖纸 + 墨蓝两个既有色号，不新建皮肤。左品牌区 / 右单据卡。
   类名一律 `gate-*` / `slip*`，刻意避开侧栏的 `.brand`（已有 `.brand .logo`）。
   ===================================================================== */
.gate { display: grid; grid-template-columns: minmax(320px, 42%) 1fr; min-height: 100vh; }
/* 管理员门没有品牌区：整页一列，卡居中 */
.gate-solo { grid-template-columns: 1fr; }

.gate-brand {
  position: relative; overflow: hidden; background: var(--ink); color: #fff;
  padding: 40px 38px 32px; display: flex; flex-direction: column; justify-content: space-between;
}
/* 极淡横线：像单据纸的印刷纹，不新增色号（白 3.5% 叠层）。
   别再往上调 —— 5.5% 时在深蓝上会拼成"条带"，看着像背景没加载好。 */
.gate-brand::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: repeating-linear-gradient(180deg, rgba(255,255,255,.035) 0 1px, transparent 1px 40px);
}
/* 主文案垂直居中：直接 space-between 的话，900px 高的屏上"上五分之一有字、下面全空"，
   头重。`margin: auto 0` 让它吸收剩余空间 —— 上面那条（手机上才是窄带）不参与。 */
.gate-brand .gb-mid { position: relative; margin: auto 0; }
.gate-kicker { position: relative; font-size: 11px; letter-spacing: .16em; color: rgba(255,255,255,.6); }
.gate-brand h2 { position: relative; font-size: 31px; line-height: 1.34; margin: 22px 0 16px;
  font-weight: 600; letter-spacing: -.005em; }
.gate-brand h2::before { content: ""; display: block; width: 26px; height: 3px;
  background: var(--amber); margin-bottom: 18px; border-radius: 2px; }
.gate-brand p { position: relative; font-size: 13px; line-height: 1.9;
  color: rgba(255,255,255,.74); max-width: 25em; margin: 0; }
.gate-brand .gb-bot { position: relative; display: flex; gap: 10px; align-items: center;
  font-size: 11.5px; color: rgba(255,255,255,.48); }
.gate-brand .gb-bot i { width: 3px; height: 3px; border-radius: 50%; background: rgba(255,255,255,.35); }
/* 手机顶部那条窄带只在窄屏出现（桌面由左侧品牌区承担） */
.gate-brand .gb-top { display: none; }

.gate-stage { display: grid; place-items: center; padding: 30px; }

/* ── 单据卡（员工门 / 管理员门共用这一张"纸"） ───────────────── */
.slip {
  position: relative; width: 100%; max-width: 390px; background: var(--paper);
  border: 1px solid var(--line); border-radius: 6px; box-shadow: var(--shadow-lg);
  padding: 24px 24px 18px;
}
/* 编号行右侧留出 56px：那是盖章的位置，文字压上去就成了"废单" */
.slip-hd { display: flex; justify-content: space-between; align-items: baseline; padding-right: 56px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 10.5px; color: var(--mute); letter-spacing: .06em; }
.slip h1 { font-size: 22px; line-height: 1.3; margin: 0 0 6px; font-weight: 650; letter-spacing: -.01em; }
.slip .sub { font-size: 13px; color: var(--mute); line-height: 1.75; margin: 0 0 18px; }
/* 公司标当"章"用：不额外做图，直接压 logo（它是圆的，正好是章的形状） */
.slip .seal { position: absolute; right: 16px; top: 14px; width: 44px; height: 44px;
  border-radius: 50%; opacity: .92; }
/* 虚线撕口：单据的语汇，不是装饰线 */
.perf { height: 1px; margin: 13px 0 16px;
  background-image: linear-gradient(90deg, var(--line) 0 5px, transparent 5px 11px);
  background-size: 11px 1px; background-repeat: repeat-x; }

/* 主按钮：全站唯一"落实"档（墨蓝实心）。<a> 与 <button> 共用，所以要抹掉表单默认样式 */
.btn-main {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  width: 100%; height: 50px; border: 0; border-radius: 6px;
  background: var(--ink); color: #fff; font-size: 15px; font-weight: 600; letter-spacing: .02em;
  cursor: pointer; text-decoration: none; font-family: inherit;
  transition: background .18s, transform .16s cubic-bezier(.16,1,.3,1);
}
.btn-main:hover { background: #1B3E63; }
.btn-main:active { transform: scale(.985); }

.slip .err { display: flex; gap: 8px; align-items: flex-start;
  background: var(--alert-soft); border: 1px solid #E3B6A9; color: var(--alert);
  font-size: 12.5px; line-height: 1.6; padding: 9px 11px; border-radius: 4px; margin: 0 0 14px; }
.slip .err b { font-weight: 700; }

.steps { list-style: none; margin: 15px 0 0; padding: 0; font-size: 12px; color: var(--mute); line-height: 1.85; }
.steps li { display: flex; gap: 8px; }
.steps li::before { content: ""; flex: 0 0 4px; height: 4px; border-radius: 50%;
  background: var(--amber); margin-top: 8px; }

/* 底部「换个入口」：给走错门的人看的，压得很轻，不跟主按钮抢注意力 */
.slip-foot { margin-top: 16px; padding-top: 12px; border-top: 1px dashed var(--line);
  display: flex; justify-content: space-between; align-items: center;
  font-size: 11.5px; color: var(--mute); }
/* 10-29：这里原先是纯文字链接，**可点区只有 18px 高**（实测 72×18 / 61×18）——
   手机上基本点不中「管理员入口」。撑高到能点的尺寸，字号和位置不变，视觉几乎看不出差别。 */
.slip-foot a {
  color: var(--ink-2); text-decoration: underline; text-underline-offset: 2px;
  display: inline-flex; align-items: center; min-height: 32px; padding: 0 4px; margin-right: -4px;
}
@media (max-width: 640px) {
  .slip-foot a { min-height: 44px; }
}

/* 管理员门：斜盖一枚章，比写一句「请勿使用员工账号」省字，也更容易被看见 */
.stamp { position: absolute; right: 16px; top: 16px; transform: rotate(-7deg);
  border: 2px solid var(--alert); color: var(--alert); opacity: .78;
  font-size: 10px; letter-spacing: .16em; padding: 3px 7px; border-radius: 3px; font-weight: 600; }

/* 表单字段（登录页专用一套：输入框 16px，手机上不触发缩放） */
.fld { margin-bottom: 13px; }
.fld label { display: block; font-size: 12px; color: var(--mute); margin-bottom: 5px; }
.fld input { width: 100%; height: 42px; border: 1px solid var(--line); border-radius: 5px;
  background: #FDFCFA; padding: 0 12px; font-size: 16px; color: var(--ink); }
.fld input:focus { outline: 2px solid var(--focus); outline-offset: 1px; border-color: transparent; }
.fld .hint { font-size: 11.5px; color: var(--mute); margin-top: 5px; line-height: 1.6; }

/* 开发者入口（DEV_LOGIN=1 才渲染）：本地造数用，不该和登录按钮并列 */
.slip .devbox { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--line); }
.slip .devbox .lb { font-size: 11px; color: var(--mute); margin-bottom: 6px; }
/* 开发入口的按钮压矮一档：它是工具，不该和「登录」一样重 */
.slip .devbox .btn-main { height: 42px; font-size: 13.5px; }

/* ---------------- 手机（≤640px 同页换形态） ---------------- */
@media (max-width: 640px) {
  /* 登录页在手机上**只做降级**，不做专门设计（10-28 大R：钉钉里点开直接免登，
     手机用户根本走不到这一页）。留着是为了"手机浏览器里误打开"不撞脸：
     品牌区压成一条窄带，卡片满宽，按钮 48px。 */
  /* `grid-template-rows: auto 1fr` 不能省：只写单列时，`min-height:100vh` 会让
     两行**平分**高度，那条"窄带"被拉成 240px 高（实测）。行高按内容给，剩余全给卡片区。 */
  .gate { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .gate-brand { padding: 13px 16px; flex-direction: row; align-items: center; }
  .gate-brand h2, .gate-brand p, .gate-brand .gb-bot, .gate-brand .gate-kicker { display: none; }
  .gate-brand .gb-top { position: relative; display: flex; align-items: center; gap: 9px;
    font-size: 14px; font-weight: 650; }
  .gate-brand .gb-top img { width: 26px; height: 26px; display: block; }
  .gate-brand .gb-top span { font-size: 11px; font-weight: 400; color: rgba(255,255,255,.55); }
  .gate-stage { padding: 16px 14px 30px; align-items: start; }
  .slip { max-width: none; padding: 20px 18px 16px; box-shadow: 0 6px 20px rgba(20,48,79,.10); }
  .slip h1 { font-size: 19px; }
  .slip .seal { width: 38px; height: 38px; right: 14px; top: 12px; }
  .btn-main { height: 48px; }
  .stamp { right: 14px; top: 12px; }

  .app { display: block; }
  /* 手机：侧栏变成页顶的一条横导航。
     ⚠️ `position/height` 必须一起改 —— 桌面版是 `sticky + 100vh`，只改宽不改这两条，
        侧栏会占满一整屏，正文被顶到首屏之外（实测就是这样，一屏只剩导航）。 */
  .side {
    width: auto; flex: none; border-right: 0; border-bottom: 1px solid rgba(255,255,255,.12);
    padding: 8px 10px; position: static; height: auto;
    flex-direction: row; flex-wrap: wrap; align-items: center;
  }
  .side a.nav { margin: 2px 4px 2px 0; }
  .side .nav-h, .side .whoami { display: none; }
  /* 手机竖屏首屏寸土寸金：品牌块（38px 标志 + 两行字）横着排会独占一行、把导航挤到第二排。
     原型一直是藏掉的（`.brand, .sidebar-foot, .nav-group { display:none }`），开发版跟齐。 */
  .side .brand { display: none; }
  /* 付款整组不上手机（§8.48）—— 连分组标题一起藏，不留一个空标题。
     ⚠️ 选择器**不能**写 `.side .pay-only`：那样只藏侧栏菜单，工作台的「待付款」
        数字卡和「待付款队列」整块照样显示（实测出纳在手机上能看到 3 张待付 →
        口径「付款只在 PC」形同虚设）。付款相关的东西一律带 .pay-only，由这一条统一管。 */
  .pay-only { display: none; }
  /* 触摸目标 44px（10-29 大R 拍板）：原来 padding 6px 撑出 32px 高，
     手指点「已发起」容易落到旁边的「已完结」——横排导航两格只隔 4px。
     44 是 iOS HIG / Material 共同的触摸下限。代价是导航条 89→113px（+24px），
     但导航只占两行不满屏，24px 看不出来；点错一格的烦躁是每天几十次。
     ⚠️ 用 min-height 不用 height：字大了/角标撑高时让它继续长，别裁字。 */
  .side a.nav { display: inline-flex; padding: 6px 9px; font-size: 12.5px; min-height: 44px; }
  /* ⚠️ 上面那条 display:inline-flex 会把 .pay-only 的隐藏**反覆盖**：
     .side a.nav 特异性 (0,1,1) > 单个类 (0,1,0)，跟书写顺序无关。
     后果实测过：出纳在手机上照样看到「待付款 3 / 已付款」两个菜单，
     「付款只在 PC」在**菜单层**从来没生效（之前只验了工作台的卡片，卡片是 div，藏得住）。
     所以链接上的隐藏必须再写一遍，且特异性要压过 .side a.nav。
     · .pay-only  付款组（§8.48 付款只在 PC）
     · .pc-only   只在电脑上干的事（收款方档案：翻底档不是手机上要做的活） */
  .side a.nav.pay-only, .side a.nav.pc-only { display: none; }
  /* 手机端导航是**横排**，左侧竖条在横排里方向感是错的（它指"左边一格"，而横排的分格在右边）。
     横排的"你在这格"应该是下方一条短横线 —— 同一件事，方向跟着排列走。 */
  .side a.nav.on::before {
    left: 50%; top: auto; bottom: 1px; transform: translateX(-50%);
    width: 14px; height: 2px; border-radius: 1px;
  }
  .main { padding: 12px 12px 32px; }
  .page-h h1 { font-size: 18px; }
  .row2, .row3 { grid-template-columns: 1fr; }
  .lines-h { display: none; }
  .line { grid-template-columns: 1fr 1fr; gap: 7px; padding: 10px 11px; border-bottom: 1px solid var(--line); }
  /* 三张出差子表在窄屏也要退回两列 —— 不写这三条，上面那些固定列宽会盖掉这条规则 */
  .lines.dest .line, .lines.cost .line, .lines.member .line { grid-template-columns: 1fr 1fr; }
  .line > :nth-child(1), .line > :nth-child(2) { grid-column: 1 / -1; }
  /* 报销明细手机版：项目 / 描述各占一整行，第二行是「张数 · 金额 · 删」—— 跟 PC 一个顺序 */
  .lines.m1 .line { grid-template-columns: 64px minmax(0, 1fr) 30px; }
  .lines.m1 .line .qty-ro { text-align: left; }
  /* 手机上的附件清单：第一行「类型标签 · 文件名 · 大小 · ×」，归属下拉另起一行 */
  .att-item { flex-wrap: wrap; gap: 6px 9px; }
  .att-item .nm { flex-basis: calc(100% - 112px); }
  .att-item .own { width: 100%; order: 5; }
  .btn { height: 38px; }

  /* iOS Safari 的硬规则：输入框字号 < 16px 时，**一聚焦就把整页放大**，而且失焦不缩回。
     PC 正文 14px 是合适的，但在手机上会让「点一下账号框，页面突然又大又糊」。
     所以这一档只把**输入类**抬到 16px，正文不动（正文 16px 在 390 宽会挤掉一列）。
     列出的选择器按"实际用了 input 的地方"来的：登录页、搜索框、日期、金额、备注。 */
  .input, .select, .textarea,
  input[type="text"], input[type="password"], input[type="date"],
  input[type="number"], input[type="search"], textarea, select { font-size: 16px; }
  /* 金额框宽是 calc(10ch + 18px)，按 14px 算的；抬到 16px 后 10ch 变宽，手机上会顶到边
     → 这一档改成按容器给宽度，右边数值靠右对齐的样子不变。 */
  .input.amount { width: 100%; max-width: 160px; }
}

/* ------------------------------------------------------------------ 类型卡片
   付款 4 张 / 采购 3 张 / 暂支 3 张共用。整段照原型「付款申请单 v2.0 专属组件」搬：
   · 选中 = **同色细边 + 淡琥珀底 + 副标题转琥珀**（不是内描边、不是自造色）
     —— 判据：「选中项要看得出，但不该比它选中的内容更抢眼」；实心只留给主按钮。
   · PC 最宽 820px（原型就是 820），否则 4 张卡在宽屏上拉成一条，比例就散了。
   · 不加 transition：切类型要"立刻看见"，不要渐变动画。 */
.ptype { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; max-width: 820px; }
.ptype.c4 { grid-template-columns: repeat(4, 1fr); }
.ptype.c3 { grid-template-columns: repeat(3, 1fr); }
.ptype-card {
  display: flex; flex-direction: column; align-items: flex-start;
  padding: 10px 12px; min-height: 62px;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--paper); font: inherit; text-align: left; cursor: pointer;
}
.ptype-card:hover { border-color: var(--amber-ink); }
.ptype-card .pt-name { font-size: 13px; font-weight: 600; color: var(--ink); }
.ptype-card .pt-code { margin-top: 2px; font-size: 11px; color: var(--mute); letter-spacing: .3px; line-height: 1.45; }
.ptype-card.active { border-color: var(--amber-ink); background: var(--amber-soft); }
.ptype-card.active .pt-code { color: var(--amber-ink); }

/* 没选类型前把整块填单区收起来（付款申请单第一步只做一件事：选类型）。
   ⚠️ 不能用 `hidden` 属性：`.duo` 自己写的是 display:grid，作者样式压过 UA 的
   [hidden]{display:none}，属性加了照样显示 —— 这里用带 !important 的类兜住。 */
.is-off { display: none !important; }
@media (max-width: 640px) {
  .ptype.c4, .ptype.c3 { grid-template-columns: 1fr 1fr; }
  .ptype-card .pt-code { font-size: 10.5px; letter-spacing: 0; }
}
