/* ==========================================================================
   财务模块（`/finance`）样式 —— 全部类带 `fin-` 前缀

   ⚠️ 与门户（`ptl-`）同属"独立外壳"家族：满屏、自带头部、无达播侧栏。
      区别是财务模块**有自己的左侧导航**（门户没有内部页面，只是往别处跳）。
   ⚠️ 颜色一律取设计令牌；不写死 hex。
   ⚠️ 单开一个文件（不塞进 267KB 的 pages.css）：回归面小、类名不会冲突。
   ========================================================================== */

.fin {
  min-height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
}

/* ⚠️ 清掉 `.page` 自带内边距（独立外壳下 top 被 pages.css 改成 --space-4），
   否则头部条四周会露出一圈底色、看着像"嵌在框里"而不是通栏。
   ⚠️ 用 `:has()` 精确限定到"装着财务模块的那个 .page"—— `.page` 是全站共用容器。 */
.app-shell.is-standalone .page:has(> .fin) {
  padding: 0;
}

/* ---- 布局：内容区 ----
   ⭐ 2026-09-21：导航已搬到**应用侧栏**（`#sidebar-nav`），内容区只剩 `main`。
   ⚠️⚠️ `.fin-nav` 这个类**已不存在**（对应的规则也删了）——
      别把它加回来：加了不会有任何元素匹配，只会让后来者误以为导航还在内容区里。
      「导航去哪了」见 `pages/finance.js` 的 renderSidebarNav() 与 app.js 的
      renderFinanceSidebar()（一个管中部导航、一个管品牌区与底部）。
   ⚠️ 侧栏里那条竖分隔线由**侧栏自己**的 `border-right` 承担（base.css 的 `.sidebar`），
      这里**不要**再画一条 —— 否则会出现两条紧挨着的竖线（实测过）。
   ⚠️ `.fin-body` 保留：它仍是 `.fin` 的 flex 子项、承担 `flex:1` 的撑高。 */
.fin-body {
  flex: 1;
  display: flex;
  min-height: 0;
  width: 100%;
}

/* ---- 模块导航项（渲染在**应用侧栏内**，2026-09-21 起）----
   ⚠️ 这些类名保留 `fin-` 前缀（虽然现在挂在侧栏里）：它们**只属于财务模块**，
      与达播侧栏的 `.nav-item` 是两套东西（那边单行、这边两行带描述）。
      改成 `.nav-item` 会连带吃到达播的菜单样式与高亮逻辑（`[data-nav]` 那套绑定），
      反而更容易出错 —— 见 app.js 里关于"品牌区不许用 data-nav"的同类说明。
   ⚠️ 与达播菜单项的体量对齐：高度不写死（两行内容自然撑开），
      但左右内边距与圆角沿用同一套令牌（`--space-*` / `--radius-md`）。 */
.fin-nav__i {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  width: 100%;
  /* 与达播侧栏菜单行同一套值（规范：菜单行/按钮档 = --radius-md 8px、padding 8/12） */
  padding: var(--space-2) var(--space-3);
  margin-bottom: 2px;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-fg-2);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  position: relative;
  transition: background-color var(--motion-fast) var(--motion-ease-standard),
              color var(--motion-fast) var(--motion-ease-standard);
}
.fin-nav__i:hover { background: var(--color-surface-2); color: var(--color-fg); }
/* 选中态复用全站那一套（浅蓝胶囊 + 主色字），不新造样式 */
.fin-nav__i.is-active {
  background: var(--color-accent-bg);
  color: var(--color-accent-text);
}
.fin-nav__ic {
  position: absolute;
  left: 12px;
  top: 12px;
  display: inline-flex;
}
.fin-nav__t {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  padding-left: 24px;
  line-height: 1.4;
}
.fin-nav__d {
  font-size: var(--font-size-xs);
  color: var(--color-meta);
  padding-left: 24px;
  line-height: 1.4;
}
.fin-nav__i.is-active .fin-nav__d { color: var(--color-accent-text); opacity: .75; }

.fin-main {
  flex: 1;
  min-width: 0;
  /* ⚠️ 左右必须用 `--page-padding`(32px) —— 规范「页面内容区左右内边距 32px」。
     原值是 `--space-6`(24px)，比达播窄 8px ⇒ 同一屏幕切过去内容会"撑宽"、
     两张页面的左对齐线对不上（这是"看着不像同一个系统"最细但最持续的一种差异）。 */
  padding: var(--space-6) var(--page-padding) var(--space-8);
}
/* ⚠️ 标题用全站统一的 `.page-title`（通用巡检 `probe-all-pages.js` 查的就是它），
   本类只补外边距 —— 别自造语义类，否则该页在通用门禁上永久假红。 */

.fin-loading {
  padding: var(--space-8) 0;
  text-align: center;
  color: var(--color-meta);
  font-size: var(--font-size-sm);
}

.fin-count {
  font-size: var(--font-size-xs);
  color: var(--color-muted);
  margin-bottom: var(--space-2);
}.fin-count b { color: var(--color-fg); font-weight: var(--font-weight-semibold); }

/* ---- 标题旁的「?」使用说明（2026-09-21 乐哥）----
   ⚠️ 三个必须写对的点（每处都对应一个会**静默失效**的坑）：
     ① `.fin-help { margin-right: auto }` —— `.page-header` 是 `flex; space-between`，
        不加的话问号会被推到**页面最右边**（看着像"跑到右上角了"，而不是"标题旁边"）。
     ② `[hidden] { display: none }` 必须**显式写** —— 本元素设了 `display: inline-flex`，
        那会**盖掉** `hidden` 属性自带的 `display:none`
        ⇒ 没有说明的页面也会显示一个空问号。`.fin-help[hidden]`（0,2,0）>
        `.fin-help`（0,1,0），所以不需要 `!important`。
     ③ 面板走**绝对定位** —— 展开/收起绝不能把下面的 KPI 小片与表格整块推下去
        （那会让页面跳一下）。
   ⚠️ 浮层视觉用**浅色卡片档**（白底 + 浅描边 + 12px 圆角 + 浮起阴影），
      **不新造颜色**：与下方表格卡同一族，一眼就是"系统里的说明卡"。
      ⛔ 曾试过复用金额 tooltip 的**深色**浮层（`.af-money__tip` 那套深底反白）——
         截图实测：深色块**视觉重量压过了第一个 KPI 小片**（"替票张数"被盖住时
         看着像页面缺了一块），而且在一屏浅色的页面里显得像"另一个系统的组件"。
         ⇒ 教训：**深色浮层只适合 1~2 行的短提示**（金额 tooltip 就是），
            多行说明要用浅色卡片。
   ⚠️ 面板**盖住第一个 KPI 小片就让它盖** —— 说明是**用户主动点开**的临时层，
      用户正看着它读，此时"不遮挡下方内容"不是需求；
      而"展开时不把下方内容推下去"（不走文档流）才是必须的。
   ⚠️⚠️ 本注释**只能有一个结束标记**：我插第二批说明时多写了一个注释结束符，
      注释**提前闭合** ⇒ 后面三行变成野文本 ⇒ 紧跟着的 `.fin-help { position: relative }`
      **整条规则被吞掉**。后果是"面板定位到页面左下角、问号被 space-between 推到最右边"，
      而 CSS 不报错、门禁也不红（这正是"注释写坏结构"这类坑最难查的地方：
      **改注释也是改代码** —— 本轮 20 分钟就花在这上面）。
      ⚠️ 以及在注释里**提到那个结束符本身**时，必须拆开写（拆成星号 + 斜杠两半），
         否则你会在"解释这个 bug"的同一句话里再制造一次同样的 bug（本轮连踩两次）。 */
.fin-help {
  position: relative;
  display: inline-flex;
  align-items: center;
  align-self: center;
  /* -8px 抵消 `.page-header` 的 gap:16px ⇒ 与标题的间距收成 8px（紧贴但不贴死） */
  margin-right: auto;
  margin-left: calc(-1 * var(--space-2));
}
.fin-help[hidden] { display: none; }
.fin-help__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--color-meta);
  cursor: pointer;
}
/* 悬停 / 展开时用全站"选中态"语言（浅蓝底 + 主色字）——别新造颜色 */
.fin-help__btn:hover,
.fin-help__btn[aria-expanded="true"] {
  color: var(--color-accent-text);
  background: var(--color-accent-bg);
}
.fin-help__btn:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
.fin-help__panel {
  position: absolute;
  top: calc(100% + var(--space-2));
  left: 0;
  z-index: 30;
  width: 400px;
  max-width: min(400px, 82vw);
  padding: var(--space-4);
  background: var(--color-surface);
  color: var(--color-fg-2);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  font-size: var(--font-size-xs);
  line-height: 1.75;
  text-align: left;
  white-space: normal;      /* 标题是 nowrap 语境，这里必须**显式**放开换行 */
}
.fin-help__panel[hidden] { display: none; }
/* 窄屏：400px 定宽会超出屏幕（`max-width:82vw` 已兜底，这里再把左边缘对齐容器） */
@media (max-width: 768px) {
  .fin-help__panel { left: calc(-1 * var(--space-4)); }
}

.fin-h3 {
  margin: var(--space-5) 0 var(--space-3);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-fg);
}

/* ---- 说明条 ---- */
.fin-note {
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
  background: var(--color-primary-50);
  border-radius: var(--radius-md);
  font-size: var(--font-size-xs);
  line-height: 1.65;
  color: var(--color-fg-2);
}
.fin-note b { color: var(--color-accent-text); font-weight: var(--font-weight-semibold); }
.fin-note__sub { display: block; color: var(--color-muted); margin-top: 2px; }

/* ---- 单据号 ---- */
.fin-code {
  font-family: var(--font-family-mono);
  font-size: var(--font-size-xs);
  color: var(--color-fg);
}

/* ---- 状态标签 ---- */
.fin-tag {
  display: inline-block;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  padding: 1px 7px;
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
.fin-tag--success { background: var(--color-success-bg); color: var(--color-success-text); }
.fin-tag--danger  { background: var(--color-danger-bg);  color: var(--color-danger); }
.fin-tag--warning { background: var(--color-warning-bg); color: var(--color-warning-text); }
.fin-tag--muted   { background: var(--color-gray-50);    color: var(--color-muted); }
/* ⭐ 「待付款」= **待办**，不是异常（2026-09-21 改）。
   ⚠️ 原来它用 `--danger` 红色 —— 而红色在这套色板里表示"出问题了"（已驳回、缺票号）。
      「待付款」恰恰是**一切正常、就等财务动手**的状态，也是财务每天最该去处理的一批。
      用红色会让人以为这些单有毛病、反而不敢动；也把"真正的异常（已驳回）"稀释掉了。
   ⚠️ 用主色蓝：全站"待办/需操作"的语言就是蓝（按钮、链接、选中态）。
      于是三种色各司其职 —— 蓝=**该你动** / 橙=**别人在办** / 红=**出问题了**。 */
.fin-tag--todo    { background: var(--color-primary-100); color: var(--color-primary-700); }

/* 「缺票号」提醒 —— 这是发票核验页最该被看见的东西 */
.fin-miss {
  display: inline-block;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  padding: 1px 7px;
  border-radius: var(--radius-sm);
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
}

/* ⚠️ 这里原有 `.fin-groups`（"待付款分组 / 按人凑批次"的早期布局）——
   实测零引用（`grep -rn "fin-groups" public/js/ tests/`（含 index.html） 无结果），
   与上面那段一起删除。 */
/* ⚠️⚠️ 2026-09-21 **删掉一段死 CSS，并因此消掉一个类名撞车**：
   这里原来有一组 `.fin-group` / `.fin-group__h/n/c/a/b` + **另一个 `.fin-chip`**
   （灰底、2px 7px 内边距、4px 圆角），是早期"详情页分组标签"的样式。
   实测 `grep -rn "fin-group" public/js/ tests/`（含 index.html） **零引用** ⇒ 纯死代码。
   而那个裸 `.fin-chip` 与 **KPI 小片用的 `.fin-chip` 同名**：
     · 两处特异性都是 (0,1,0)，靠**源码先后**决定胜负（KPI 规则在后面 ⇒ 目前是它赢）；
     · 一旦有人去改那段"死"代码，会**静默影响 KPI 小片**（反之亦然）——
       这正是本项目反复强调的"同一个类名两种用途 ⇒ 必然出事"。
   ⇒ 一并删除。删除前后实测 KPI 小片的 w/h/bg/radius/padding/color **逐项一致**
     （见交付说明里的 before/after 对照），**零行为变化**。 */

/* ---- 键盘可达 ---- */
.fin-nav__i:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -1px;
}

/* ---- 手机：导航在**侧栏抽屉**里，只做"单行化"适配 ----
   ⚠️⚠️ 2026-09-21 重要修正：原来这一块是「把导航从左侧竖列改成内容区**顶部横排**」
      （`flex-direction: row` + `overflow-x: auto`），因为那时导航是内容区里的独立列、
      窄屏占宽度太狠。**现在导航搬进了应用侧栏**（`#sidebar-nav`）⇒ 那套横排逻辑不成立：
        · 侧栏在手机上本来就是**抽屉**（宽 240、滑入滑出）⇒ 不存在"占太多宽度"的问题
        · 若还保留横排，4 个导航项会在 240px 抽屉里挤成一横排、还要横向滚动（很难用）
      ⇒ 已删掉"横排容器"与"横排时压缩每项"这两组规则（`.fin-nav{…}` 与
         `.fin-nav__i{width:auto;flex:0 0 auto;margin-bottom:0}`）。
      ✅ 保留下面这几条 —— 它们治的是**竖排下的手机适配**，与横排无关：
         · `.fin-nav__d{display:none}`：手机上只留标题，4 项能一屏放下（与达播手机侧栏
           "菜单项只有一行标题"的观感一致）
         · 图标从"绝对定位在左上"改成 **static 内联**：因为描述行被隐藏后每项只剩一行，
           绝对定位的 `top:12px` 会明显偏下（图标不居中）—— 这是"隐藏一行"带出来的连带问题，
           漏了的现象是"手机上图标贴着项的底边"。
   ⚠️ 教训（值得记住）：**把元素从一个容器搬到另一个容器时，要连带检查它所有的
      `@media` 规则** —— 桌面规则好发现，写在文件下半部分媒体查询里的**最容易漏**。
      本轮就是靠部署脚本的静态自检把它抓出来的（判据是"行首出现该类的规则"）。
   📌 写这段注释时的二次教训：说明里**不要原样写出那对"类名 + 花括号"的字符**，
      否则静态自检（`grep`）会把这句说明当成"规则还在"而**误拦部署**。
      这里只用中文描述"横排容器那条规则"，不贴原文。 */
@media (max-width: 768px) {
  .fin-body { flex-direction: column; }
  .fin-nav__d { display: none; }         /* 手机上只留标题，省宽度 */
  .fin-nav__ic { position: static; margin-right: 6px; }
  .fin-nav__t { padding-left: 0; }
  .fin-nav__i { flex-direction: row; align-items: center; }
  .fin-main { padding: var(--space-4) var(--space-4) var(--space-8); }
  /* ⚠️ 原来这里有一条 `.fin-inp { width: 100% }`（窄屏搜索框占满）——
     `.fin-inp` 已随"改用标准控件"下线，而标准 `.input--search` 的窄屏规则
     components.css 里**已经有了**（`flex:1 1 auto` + `.input { width:auto !important }`）
     ⇒ 这里不再补规则。**别在本文件里写 .input--search**：pages-finance.css 是**全站引入**的
     （index.html 无条件下载），写在这儿会波及所有模块的搜索框。 */
  /* 窄屏：工具栏右侧分组改成占满一行、去掉左推（标准 .toolbar__right 是 margin-left:auto）。
     ⚠️ 类名跟着 JS 一起从 .fin-bar__right 改成了 .toolbar__right —— 只改 JS 不改 CSS
        会留下"死规则"（不报错、但窄屏布局悄悄失效）。 */
  .toolbar__right { width: 100%; margin-left: 0; }
}

/* ==========================================================================
   2026-09-20 第二轮新增：部门 tab · 审批流程条 · 报销情况旗标 · 详情页 · 发票图
   ⚠️ 颜色一律取设计令牌；不写死 hex（本项目禁硬编码颜色）
   ========================================================================== */

/* ══ 页面结构：一级 tab / 工具栏 / 二级 tab / KPI 小片（2026-09-21 定稿）═══════
   顺序：一级 tab（状态，下划线）→ 工具栏 → 二级 tab（部门，胶囊）+ KPI → 共 N 单 → 表格
   外层：整块包进 `.card`（白卡片）—— 达播台列表页的标准外壳，同时解决"tab 与工具栏重叠"。

   ⚠️⚠️ **达播台的 tab 分两级，而且是由 `app.js` 自动定形的 —— 别自己写样式对抗它**
   （2026-09-21 读代码 + 实测确认）：
      · **一级 tab** = 页面级"视图/状态大类"切换 → **下划线式**（`.table-tabs`）
      · **二级 tab** = 在当前视图内再筛（部门/岗位这类）→ **胶囊**（`.pill-filter`）
   施加者是 `app.js` 三个函数：`fixPageTabs`（页面级工具栏里的 tab）/
   `fixTableTabs`（卡内表格工具栏里的）/ `fixBareSeg`（裸在外面的）。
   它们统一把 tab 变成下划线式、并提到筛选**上面**；**但有一个明确例外**：
      `skipSeg = 页面已有 page-tabs && 卡内无 table-tabs`
      ⇒ 此时卡内的 `.pill-filter`/`.seg` **不被转换、保持胶囊**
        （原话：「页面已有 `.toolbar--has-page-tabs` ⇒ 卡内出现的 seg 只能是筛选条件」）。

   ⇒ 本页顺着框架来：
      · 状态 tab 用 `.seg`、放进页面级 `.toolbar` ⇒ 框架给下划线形态 + 独占第一行；
      · 部门筛选用 `.pill-filter`、放在卡内 `.table-toolbar` ⇒ 框架判为"筛选条件"、保持胶囊。
   ⚠️ 我第一版把状态 tab 写成 `.tabs` 且独立在卡片内 ⇒ 框架认不出它是页面级 tab
      ⇒ 部门胶囊被 `fixTableTabs` 搬出工具栏、转成下划线（类名变 `pill-filter table-tabs`）
      ⇒ 两级长得一模一样，与要求正好相反。
   ⚠️ 还有一个连带坑：KPI 的容器**不能**用 `.table-toolbar__right` ——
      框架会把这个类搬进"表格 tab 行"（实测 KPI 跑到状态 tab 那行去了）；用中性的 `.fin-chips` 就不会被搬。

   ---- 卡片外壳 ---- */
/* `.card > .tabs` / `.card > .toolbar`（左右留白 + 下边框）在 components.css 里已有，不重复定义。
   这里只补"卡片内的二级 tab 行"与"表格底部圆角"。 */
.fin-ovcard { padding: 0; overflow: hidden; }   /* overflow:hidden 让表格贴底时被卡片圆角裁齐 */
.fin-ovcard > .table-toolbar { padding: var(--space-3) var(--space-5); }
/* ⚠️ 同一页有多张表格卡时（付款管理 2 张）必须留间距 —— 实测间距是 **0px**
   （`.card + .card` 没有通用规则），两张白卡直接贴死、中间只隔着各自的 1px 描边，
   看起来像"一张卡被切开"。L4 规范：`.card` 之间 16px。 */
.fin-ovcard + .fin-ovcard { margin-top: var(--space-4); }
/* 卡片内的「共 N 单」提示行：左右留白与其它行对齐，上下收一点（它是辅助信息，不该占太多） */
.fin-ovcard > .fin-count { padding: var(--space-2) var(--space-5); margin-bottom: 0; }
/* 卡片顶部的说明条（2026-09-21：三页的说明条由"卡外灰底"移进卡内）——
   ⚠️ 为什么必须进卡内：说明条夹在工具栏与卡片之间会把两者的间距撑到 > 24px，
      框架 `markToolbarJoin` 就**不合并**了 ⇒ 这一页会长成"灰底工具栏 + 白卡表格"，
      与总览页的"工具栏并进白卡"是两种形态。放卡内则两边都合并，全模块一个样。
   ⚠️ `.fin-ovcard` 是 `padding:0`，所以这里用 margin 给左右留白（与 `.fin-count` 的 20px 对齐）。 */
.fin-ovcard > .fin-note { margin: var(--space-4) var(--space-5) 0; }
.fin-ovcard > .fin-note + .fin-count { padding-top: var(--space-3); }
/* 卡片内的"小节标题"（付款管理两张表各一个）——
   放在 `.table-toolbar` 这个标准槽位里（表格卡"表头上一行"），标题与它管的表格同卡。 */
.fin-cardttl { font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); color: var(--color-fg); }
.fin-ttl__right { margin-left: auto; display: inline-flex; align-items: center; gap: var(--space-3); }

/* ---- KPI 小片（**全模块唯一的 KPI 形态**）----
   ⚠️ 2026-09-21 三次改（乐哥：「财务中心顶部的那4个卡片，其实可以大一点，整体你看怎么弄协调些」）：
     上一版是"30px 高、数字 14px、4 个挤在左边（只占 612/1241 = 49% 宽）"，
     实测两个可量化的问题：
       ① **太小** —— 小片比表格的**表头（44px）和行（46px）都矮**，
          而它承载的是"全模块的总数"、视觉权重却最低；数字 14px 对比页面标题 24px 也压不住。
       ② **不齐** —— 右半边整块空白，与下方满宽的工具栏 / 表格左右都不对齐。
     ⇒ 改法（同时解决两条）：
       · 高 30 → **44px**（对齐全站 44px 档：表头 / 表单控件同高）
       · 数字 14 → **20px**（`--font-size-xl`，与"模块标题"同级）
       · 4 个 **等宽铺满**（grid 4×1fr）⇒ 与下方元素左右边缘对齐
       · 标签靠左、数字+说明靠右（`margin-left:auto`）⇒ 满宽但不留死白
       · 圆角 8 → **12px**（`--radius-lg`）：44px 高、满宽等分的形态已经**是卡片**，
         与下方表格卡（同为 12px）成同一族；L4 的圆角阶梯"卡片=12 / 控件=8"，
         形态变了档位跟着变 —— 这是**按规范升级**，不是放水。
         ⚠️ 配套：`verify-finance-ui-l4.js` 的 C4/C5 判据已同步改为 12px。 */
.fin-chipbar { margin-bottom: var(--space-4); }
.fin-chips {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-3);
}
.fin-chip {
  /* ⭐⭐⭐ 2026-09-21 **第 5 次改：横向 → 纵向两行**（乐哥：「上面那个卡片的数字，
     现在放大的数字位置很奇怪，看下整体怎么调整下」）。
     ⚠️ 先说清"奇怪"到底是什么 —— **量出来的**，不是感觉：
        88px 高、301px 宽的卡片里，标签「未结清」宽 42px、数字组「10单 ¥2.04万」宽 114px，
        而两者之间空出 **103px**（片2 是 121px、片4 是 89px）。
        也就是说**卡片 1/3 的宽度是一块毫无内容的死白**，数字被 `margin-left:auto`
        推到最右边、孤零零地飘着；高度从 44 加到 88 之后，这块空白在纵向上更显眼。
     ⇒ 根因不是对齐、是**布局形态**：单行横向排布 + 两端对齐，在"标签短、数值长"的
        情形下必然留大洞（这正是它从 44px 起就有的问题，只是矮的时候不明显）。
     ⇒ 改成**纵向两行**（这是 KPI 卡片的标准形态，也正是 88px 高度该有的用法）：
           行1：标签（14px，次级色）
           行2：数字(30px) + 单位 + 说明
        两行**左对齐** ⇒ 空白自然消失，且高度被真正用起来（不再"高而空"）。
     ⚠️ 别改回"标签左 / 数值右"的横向两端对齐 —— 它会重新制造那块死白。 */
  display: flex;
  flex-direction: column;
  /* 纵向居中 + 左对齐：两行作为一个整体在 88px 内垂直居中 */
  align-items: flex-start;
  justify-content: center;
  gap: 6px;
  height: 88px;
  padding: 0 var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  white-space: nowrap;
  min-width: 0;
}
/* 标签：次级信息，放**上面一行** */
.fin-chip__l {
  font-size: var(--font-size-sm);
  color: var(--color-meta);
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.fin-chip__v {
  /* ⚠️ 这里原来有 `margin-left: auto`（把数值推到右端）—— 纵向布局下**必须删掉**，
     否则数值仍会被推到最右、与标签错开，死白换个形式回来。 */
  flex-shrink: 0;
  /* 数字与单位**各自居中**（2026-09-21 第 4 次改的成果，保留）：
     原来的写法是「30px 数字 + 14px 单位」同在一条基线上 ⇒ 单位跟着数字的**基线**走，
     小字贴在大字基线上、字形中心偏低 ⇒ 看起来"没上下居中"。
     ⇒ 拆成两个 flex item + `align-items: center`，各自居中。 */
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);                 /* 数字与单位贴近但不粘连 */
  font-size: var(--font-size-3xl);     /* 30px：金额分支（.af-money）继承它 */
  font-weight: var(--font-weight-semibold);
  color: var(--color-fg);
  font-variant-numeric: tabular-nums;
  min-width: 0;
  /* ⚠️⚠️ **行高必须收紧到贴近字号**（2026-09-21 实测，这是"两行版"能居中的关键）：
     默认行高是 1.5 ⇒ 30px 数字的行盒有 **45px**，而数字字形只有 22.7px
     ⇒ 行盒里上下各留 11px 空气，与上面那行（14px 标签、行盒 21px）的留白不对等
     ⇒ 整块文字（标签 + 数值）的**墨迹**并集偏上 **2.85px**（实测上下留白 12.3 / 18）。
     ⇒ 收紧行高后，数值行盒 = 33px，墨迹并集中心落到 43.6（片中心 44）⇒ 偏差 0.4px。
     ⚠️ 别用 `line-height: 1`：中文字形可能被裁（数值行里含「单」「张」等单位）。
     ⚠️ 别删这一行去"图省事"—— 删掉后 B4（上下留白对称）会立刻报红。 */
  line-height: 1.1;
}
/* 数字 / 单位 / 金额：都是 flex item，**不许被压缩**（否则窄屏会把「10单」挤变形） */
.fin-chip__v > * { flex-shrink: 0; }
.fin-chip__num { font-size: var(--font-size-3xl); font-weight: var(--font-weight-semibold); }
/* 单位比数字小一档、颜色更轻 —— 但**中心对齐**（不再贴数字基线） */
.fin-chip__unit {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-regular);
  color: var(--color-muted);
}
.fin-chip__s {
  flex-shrink: 0;
  font-size: var(--font-size-sm);
  color: var(--color-meta);
  font-variant-numeric: tabular-nums;
}
/* 有需要注意的量（未结清 / 待付款 > 0）→ 数字用警示色 */
.fin-chip--warn .fin-chip__v { color: var(--color-warning-text); }
/* 窄屏：4 等分会把每个格子挤到放不下（≥305px → ≤90px）⇒ 退成 2 列；
   高度与字号同步降档（88px×2 行在手机上占 176px，太占屏） */
@media (max-width: 768px) {
  .fin-chips { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fin-chip { height: 64px; padding: 0 var(--space-4); }
  .fin-chip__v, .fin-chip__num { font-size: var(--font-size-2xl); }
}

/* ---- 报销单号列靠左（2026-09-21 乐哥：「报销单号靠左，金额靠右，其他居中」）----
   ⚠️ 只作用于**本表**（`.fin-ovtbl`）：全站表格规范（乐哥 2026-09-14 定稿）是
      "短文本/编号列一律居中"，这张表是**特例**；不写类名会把全站 16 张表一起改掉。
   ⚠️ 选择器必须写到 `tbody tr td` 层级：全站"全列居中"那条是
      `.table:not(:where(td .table)) > tbody > tr > td`（特异性 0,1,3），
      只写 `.fin-ovtbl td`（0,1,1）**压不过它** ⇒ 会静默不生效（看起来"改了没反应"）。
   ⚠️ 表头**保持居中** —— 与金额列同一处理（表头居中、内容按列性质对齐），
      这是项目既有约定（乐哥 2026-09-15：「其他所有的位置都不变」）。 */
.fin-ovtbl tbody tr td:first-child { text-align: left; }
/* ⚠️「N 笔」小标**不许换行**（2026-09-21）——
   原来它跟在 13 位单号后面，列一窄就被挤到第二行，把行高从 72 抬到更高、且看着像"两个单号"。
   锁 nowrap 后：单号列的最小宽度 = 单号 + 小标，布局算得准，也不会两行。 */
.fin-ovtbl .fin-badge { white-space: nowrap; }
.fin-ovtbl .fin-code { white-space: nowrap; }

/* ⭐ 列宽（2026-09-21 乐哥：「报销单号列窄一点，分给其他列」）——
   宽度由 JS 的 `<colgroup>` 给（按各列内容实测需要分配），这里只保证**固定布局**
   与"单号列不再抢空间"。用 `table-layout: fixed` 让 colgroup 真正说了算
   （auto 布局下浏览器会按内容比例重新分配，colgroup 只是"建议"）。 */
.fin-ovtbl { table-layout: fixed; }
/* ⚠️⚠️ 替票表也必须**固定布局**（2026-09-21 实测）：`table-layout:auto` 下
   「说明」列那串很长的底稿文案（「查验接口返回 HTTP 401（APIG.0303 …）」）
   会把 746px 全抢走，把「开票日期」挤到 94px ⇒ `2026-07-30` **折成两行**
   （同一张表本地 1 行、测试环境 2 行 —— 差别就是说明文案的长短）。
   ⇒ 只有"给了 colgroup 宽度"的表才加 `fin-fixtbl`；没给宽度的表保持 auto
      （否则 fixed + 无宽度会让所有列等宽，反而更差）。 */
.fin-fixtbl { table-layout: fixed; }
/* 固定布局下内容超宽会被裁 —— 给单号列与报销人列一个"至少要放得下"的兜底：
   允许它们换行而不是溢出（财务最怕看到被切掉的单号）。 */
.fin-ovtbl tbody tr td { overflow-wrap: anywhere; }
/* 首列仍是靠左（与上面那条同一意图，固定布局后需要重新声明一次以免被覆盖） */
.fin-ovtbl thead th:first-child { text-align: left; }

/* ⭐⭐ 两个状态列的「内容容器给固定宽度」——这是"开头固定位置、对齐"的实现方式
   ──────────────────────────────────────────────────────────────────────────
   乐哥原话：「报销情况，审核状态列的开头要不要固定个位置。对齐」
   实测现象：进度条左缘有 **3 种取值**（973 / 959 / 953）—— 因为整组「条 + 文字」
   被单元格**居中**，而各行文字长短不同 ⇒ 整组宽度不同 ⇒ 居中后左缘就被推来推去。

   ⚠️ 解法有两个方向，这里选后者：
     ① 把单元格改成靠左 —— 但乐哥之前定过「其他列居中」（报销单号靠左、金额靠右），
        为一个对齐去破坏既有对齐规则不划算；
     ② **给内容容器一个固定宽度**（`width`），里面再左对齐 ——
        这样"整组宽度"恒定，**居中之后左缘自然完全一致**。
   两个列都要（审核状态 / 报销情况）—— 两列结构**完全同构**
   （2026-09-21 乐哥定稿：「报销情况也按照审核状态那样子做」）。
   ⚠️ 摆放方式后来改过（乐哥当天下午又调了一次）：**标签移到最前（左）**、
      进度文字移到进度条**上面** ⇒ 对齐不再靠"条区定宽"、而是靠"标签列定宽"，
      见下面 `.pg` 的说明。 */
/* ⭐⭐ 状态块布局（两列共用）—— 乐哥 2026-09-21 下午定稿：
     原话：「把 1/4·审批完成 这个，放在那 4 个进度条上面，
            那个状态标签比如待付款那个放在所有进度的前面，
            然后高度和进度条还有进度条上面的文字整体差不大一样」

     ┌─────────────────────────────────────────┐
     │ [待付款]   4/4 · 审批完成                │  ← 上排：标签（最前/左）+ 进度文字
     │            ━━ ━━ ━━ ━━                  │  ← 下排：进度条
     └─────────────────────────────────────────┘

     实现：grid 2×2，靠**子元素顺序**摆位（标签 / 文字 / 条，见 JS 的 pgBlock）：
       [0] 标签    → 第 1 列、跨两行（垂直居中）
       [1] 进度文字 → 第 2 列第 1 行
       [2] 进度条  → 第 2 列第 2 行
     ⚠️ 第 1 列用 `auto`（按最长标签定宽）—— 现在两列的标签都是 3 个字（待付款/审批中/未开始…），
        宽度自然一致 ⇒ 第 2 列起点一致 ⇒ **文字与进度条左缘都对得齐**。
        （以前靠"条区定宽 100px"对齐，现在靠"标签列定宽"对齐，原因是条换了位置。）
     ⚠️ 行间距 3px 而不是 --space-*：这两行属于**同一个信息组**（一个状态），
        拉开会显得散、且整格变高；3px 既分得开又保持紧凑。 */
.fin-ovtbl .pg {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: var(--space-2);
  row-gap: 3px;
  margin-top: 0;
}
.fin-ovtbl .pg > .fin-tag { grid-column: 1; grid-row: 1 / span 2; }
.fin-ovtbl .pg > .pg__txt { grid-column: 2; grid-row: 1; white-space: nowrap; }
.fin-ovtbl .pg > .pg__bars { grid-column: 2; grid-row: 2; justify-self: start; }
/* ⚠️ 审批流程未同步时的兜底：那一格只有「标签 + 文字」、没有进度条
   ⇒ 文字落回第 2 列第 1 行，形态与正常的行一致（标签仍在最前）。 */
/* ⭐⭐ 状态块：**定宽 + 居中 + 内部左对齐**（乐哥 2026-09-21 15:45）
     原话：「现在这样可以，不过居中显示吧，然后居中后，开始的位置靠左对齐」

     ⚠️⚠️ 关键坑（我第一版就是错的）：**不能再写 `width:100%`**。
        写 100% 时它会撑满单元格 ⇒ 看起来是"左对齐"、根本看不出居中
        （实测：单元格内容宽 292，容器也 292，左右各只剩 padding 的 12px）。
     ✅ 正确做法：给定宽（`160px`）⇒ 单元格是 `text-align:center`（全站规范）⇒
        容器整体**居中**；容器内部 `text-align:left` ⇒ 各行内容**起点一致**。
     为什么是 160px：实测两列内容的自然宽度是 **155px**（审核）/ **154px**（付款）——
        标签 50 + 列间距 8 + max(进度文字 98, 进度条 97)。取 160 留 5px 余量。
        两列用**同一个宽度**，视觉上更整齐。
     ⚠️ `max-width:100%` 是**窄屏降级**：窗口变窄时列宽会小于 160，
        此时退回撑满（放弃居中，但不让内容溢出/被压）。
     为什么定宽是"各行左缘一致"的前提：各行内容长短不同（`0/3 · 待统一提报` vs
        `3/3 · 付款完成`），若是自适应宽度，居中后左缘会被推来推去；
        定宽之后每行的容器左缘相同 ⇒ 内容起点自然对齐。 */
.fin-ovtbl .fin-prog { display: inline-block; width: 160px; max-width: 100%; text-align: left; }

/* ⚠️ 原来这里有一套 `.fin-steps` / `.fin-step`（报销情况的"三个文字小标签"），
   2026-09-21 已随结构改造**删除** —— 报销情况改成与审核状态同构（标签 + 进度条）后，
   这两个类在 JS / CSS / 探针里都已无引用，留着只会误导后来者以为还有第二套形态。
   查证：`grep -rn "fin-step" public/ .render-check/ tests/` 无命中。 */

/* ---- 审批流程条（列表里的一行小字）---- */
/* ⭐⭐ 审批进度条（2026-09-21 重做，乐哥：「列表页的审批状态看着不直观」）
   ──────────────────────────────────────────────────────────────────────────
   形态 = 「B 的长条」+「A 的完成/当前/之后区分」+「进度数字」（乐哥拍板的组合）。
   换掉的旧实现是 4 个带底色的文字标签 + `›` 连接符，三个毛病：
     ① "正在等审"与"还没轮到"同色（都橙底）⇒ 看不出进度，只能读旁边的小字
     ② 4 个色块 + 主标签 + 小字 = 占 3 行高，整列全是色块、扫读要一个个读
     ③ 驳回后那些**永远不会执行**的节点仍是橙底"待审批" ⇒ 假信息（像流程还能走）
   ⚠️ 关键：**"还没轮到"用灰色**（`--color-gray-200`），不是 warning 橙 ——
      橙色只留给"当前正在办的那一道"，这样一眼就能看出停在哪。
   ⚠️ 段与段之间留 3px 缝：有缝才看得出"这是第几段"，无缝就成了一条进度条、数不清段数。
   ⚠️ 每段 22px 宽 × 6px 高：够看清颜色，又不至于把整列撑宽（原来 4 个节点名占满了整列）。 */
.pg { display: inline-flex; align-items: center; gap: var(--space-3); margin-top: var(--space-2); }
.pg__bars { display: inline-flex; gap: 3px; flex-shrink: 0; }
.pg__bar {
  width: 22px;
  height: 6px;
  border-radius: 3px;
  background: var(--color-gray-200);   /* 还没轮到 */
}
.pg__bar.is-done { background: var(--color-success); }
.pg__bar.is-cur  { background: var(--color-warning); }
.pg__bar.is-rej  { background: var(--color-danger); }

.pg__txt {
  font-size: var(--font-size-xs);
  color: var(--color-fg-2);
  white-space: nowrap;
}
/* 当前/驳回用更重的字色 + 加粗：让"卡在哪"成为这一格里最先被看到的信息 */
.pg__txt.is-cur  { color: var(--color-warning-text); font-weight: var(--font-weight-medium); }
.pg__txt.is-rej  { color: var(--color-danger); font-weight: var(--font-weight-medium); }
.pg__txt.is-done { color: var(--color-success-text); }

/* 窄屏：进度条小一档 + 文字不换行（手机上「报销单号」列已窄，再换行就串行了） */
@media (max-width: 768px) {
  .pg { gap: var(--space-2); }
  .pg__bar { width: 14px; }
}

/* ---- 报销情况旗标（三小格）---- */
/* ⭐ 「报销情况」三格（2026-09-20 改）
   ────────────────────────────────────────────────────────────────────────
   ⚠️⚠️ 改的原因（可计算，不是"我觉得"）：原来"已勾选"只靠**背景色**区分
      （`--color-success-bg` 绿底 vs `--color-gray-50` 灰底），而这两个底色的
      **对比度只有 1.00** —— 等于在白色卡片上放两块颜色几乎一样的浅色块，
      财务扫一眼根本分不出哪些单已经打款（而"哪些还没打款"正是他每天要看的）。
      实测：文字本身的对比度是达标的（4.57 / 4.86），所以问题不在"看不清字"，
      而在**"状态"没有足够的视觉重量**。
   ⇒ 加强三处（都不依赖配色深浅）：
      ① 已勾选加**实色描边 + 白底的字色加深**（边框是最可靠的"选中"信号）
      ② 图标本身已区分（勾 vs 时钟），再加**文字加粗**强化
      ③ 未勾选**去掉底色**只留浅描边 —— 让"没做的事"退到背景里，
         视觉重点自然落到"已完成"上（而不是两团灰绿并排） */
.fin-flags { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.fin-flag {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: var(--font-size-xs);
  padding: 1px 7px;
  border-radius: var(--radius-sm);
  background: transparent;
  border: 1px solid var(--color-border);
  color: var(--color-muted);
  white-space: nowrap;
}
.fin-flag.is-on {
  background: var(--color-success-bg);
  border-color: var(--color-success);
  color: var(--color-success-text);
  font-weight: var(--font-weight-medium);
}

/* ---- 可点的行 ---- */
.fin-row { cursor: pointer; }
.fin-row:hover > td { background: var(--color-primary-50); }
/* 操作列（2026-09-21 乐哥：最后一列应该是操作）——
   ⚠️ 原来的实现是**箭头 `›`**（宽 28px）。换成文字「查看」后：
      ① 宽度必须放宽到能容下两个字，否则「查看」会被挤成两行（28px 装不下）；
      ② 颜色不再用那个"淡灰→hover 变蓝"的箭头配色，改由内层 `.fin-link` 自带
         （主色蓝 + hover 下划线），与发票核验页的「跳到所属报销单」写法一致。 */
.fin-row__go { width: 56px; white-space: nowrap; }
.fin-row__go .fin-link { font-size: var(--font-size-xs); }
.fin-row:hover .fin-row__go .fin-link { text-decoration: underline; }
.fin-link { color: var(--color-accent-text); cursor: pointer; }
.fin-link:hover { text-decoration: underline; }

.fin-badge {
  display: inline-block;
  margin-left: 6px;
  font-size: var(--font-size-xs);
  padding: 0 5px;
  border-radius: var(--radius-sm);
  background: var(--color-accent-bg);
  color: var(--color-accent-text);
}
.fin-miss {
  display: inline-block;
  font-size: var(--font-size-xs);
  padding: 1px 7px;
  border-radius: var(--radius-sm);
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
}
.fin-count__hint { color: var(--color-meta); }

/* ---- 说明条：危险版（重复票号）---- */
.fin-note--danger { background: var(--color-danger-bg); color: var(--color-fg); }
.fin-note--danger b { color: var(--color-danger); }
.fin-dup { margin-top: 4px; font-size: var(--font-size-xs); }

/* ---- 详情页 ---- */
.fin-back {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-bottom: var(--space-3);
  padding: 4px 10px 4px 6px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-fg-2);
  font-family: inherit;
  font-size: var(--font-size-xs);
  cursor: pointer;
}
.fin-back:hover { background: var(--color-surface-2); color: var(--color-fg); }

.fin-doc__hd {
  padding: var(--space-4);
  margin-bottom: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.fin-doc__no { font-size: var(--font-size-lg); font-weight: var(--font-weight-semibold); color: var(--color-fg); }
.fin-doc__reason { font-size: var(--font-size-sm); color: var(--color-fg-2); margin-top: 2px; }
.fin-doc__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-3);
  font-size: var(--font-size-xs);
  color: var(--color-muted);
}
.fin-doc__meta b { color: var(--color-fg); font-weight: var(--font-weight-medium); }

/* 审批流程（4 道节点，横向排） */

.fin-paybar { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }

/* 发票图（乐哥要的"明细下面还有对应的发票图"） */
.fin-pics {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--space-3);
}
.fin-picbox {
  padding: var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.fin-picbox__h { font-size: var(--font-size-xs); color: var(--color-fg-2); margin-bottom: 3px; }
.fin-picbox__no { font-size: var(--font-size-xs); color: var(--color-muted); font-family: var(--font-family-mono); margin-bottom: var(--space-2); }
.fin-picbox__b { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.fin-pic {
  display: block;
  width: 132px;
  text-decoration: none;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--color-surface-2);
}
.fin-pic img { display: block; width: 100%; height: 96px; object-fit: cover; }
.fin-pic__n {
  display: block;
  font-size: var(--font-size-xs);
  color: var(--color-muted);
  padding: 2px 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 只有飞书文件码时不能渲染成图，给一个明确的说明块（避免显示破图） */
.fin-pic--none {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  width: auto;
  padding: 6px 10px;
  font-size: var(--font-size-xs);
  color: var(--color-muted);
  border-style: dashed;
}

/* ---- 付款：勾选栏 ---- */
.fin-ckcol { width: 40px; }

@media (max-width: 768px) {
  .fin-pics { grid-template-columns: 1fr; }
  .fin-doc__meta { gap: var(--space-3); }
}

/* ══════════════════════════════════════════════════════════════════════════
   标签栏里的「我的」（2026-09-20 乐哥「上面的标签该保留的也保留」）
   ──────────────────────────────────────────────────────────────────────────
   财务模块不渲染侧栏 ⇒ 渲染在**侧栏底部**的那个「我的」菜单没有落脚点，
   于是把它放进标签栏右侧工具组（见 app.js 的 profileHtml / bindProfileIn）。
   ⚠️ 复用 layout.css 的 .user-chip / .profile-menu **原样样式**，这里只加
      "在标签栏里" 需要的三点适配：容器定高、与左侧工具组的分隔线、间距。
      ⚠️ 不要在这里重写 .user-chip 的内部样式 —— 那会让它和达播侧栏那处
         长得不一样，而它们是**同一个组件**。
   ══════════════════════════════════════════════════════════════════════════ */
#finance-profile {
  display: flex;
  align-items: center;
  align-self: center;
  height: 40px;
  /* 与左边的搜索/通知之间划一条竖线：沿用板块切换器那条 `.gs-entry-wrap` 的
     "分组分隔"语言（左边是标签操作、右边是全站能力、最右是「我」）。 */
  margin-left: var(--space-1);
  padding-left: var(--space-3);
  border-left: 1px solid var(--color-border);
}
/* 标签栏只有 52px 高，把 chip 的上下内边距收一点，避免贴边 */
#finance-profile .user-chip {
  padding-top: 2px;
  padding-bottom: 2px;
}

/* ══════════════════════════════════════════════════════════════════════════
   审批流程 · 横向步骤条（2026-09-20 乐哥：「当前那个审批流程，太丑了」）
   ──────────────────────────────────────────────────────────────────────────
   换掉的旧实现（.fin-flow）：4 张等价卡片 + 小号 `›` 连接符，问题是没有进度感、
   连不成线、撑不满留宽、状态只靠 3px 左边框表达太隐晦。
   新实现：圆形节点 + 连通线。已通过=实心绿勾、驳回=红叉、进行中=橙圈+光晕、未开始=灰圈。

   ⚠️ 全部走设计令牌（禁裸 hex，仅 #fff/#000 例外）；字号 ≥12px（规范下限）。
   ⚠️ 连接线用 `flex:1` 自适应，**节点数是变长的**（飞书侧可改流程）
      ⇒ 不能用固定间距，否则 2 道时会留大片空白、6 道时会挤爆。
   ⚠️ 圆点 28px，连接线靠 `margin-top:13px` 与圆点垂直居中（不是 align-items:center，
      因为节点是"圆点 + 多行文字"的纵向结构，居中对齐会让线跑到文字中间）。
   ══════════════════════════════════════════════════════════════════════════ */

/* 步骤条放进标准卡片里（与页面其它区块同语言：白底 + 1px 浅描边 + 12px 圆角）。
   ⚠️ 12px 圆角 = 规范里 `.card` / `.radius-lg` 的值；旧代码里的 .fin-chain__n 用的是
      `--radius-md`(8px)，那是"按钮/输入框"档，卡片档应是 12px。 */
.af-step-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-5);
}

/* ══ 详情页「全流程」= 审批 + 付款 接成一条、分两段（2026-09-21 乐哥）══════════
   ⚠️ 为什么**不合成一条 7 段**、而是"分两段接起来"（结论与依据见 finance.js 的注释）：
      审批有否决权、付款没有；审批每道有人、付款原先连人都不记 ⇒ 混成一条会让人
      以为"付款也要等人批"。但业务上两者**串行**（审批过了才付款），所以该"接"。
   视觉上把两段分开的三处：① 段标题（审批 / 付款）；② 中间的分隔行；
   ③ **节点形状**（审批=圆点、付款=方点）。 */
.fin-chain { display: block; }

.fin-chain__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.fin-chain__head + .af-step { margin-bottom: var(--space-2); }
.fin-chain__lab {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-fg);
  padding: 2px 10px;
  border-radius: var(--radius-sm);
  background: var(--color-success-bg);      /* 审批 = 绿系（与它的"已完成"同色语言） */
  color: var(--color-success-text);
}
.fin-chain__lab--pay { background: var(--color-accent-bg); color: var(--color-accent-text); }
.fin-chain__hint { font-size: var(--font-size-xs); color: var(--color-meta); }
.fin-chain__act { margin-left: auto; }        /* 「刷新审批进度」靠右（它属于审批那一段） */

/* 衔接行：说明"前一段过了才有后一段"。已完成时用绿色实线感，未完时用灰色虚线感。 */
.fin-chain__sep {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-4) 0 var(--space-5);
  font-size: var(--font-size-xs);
  color: var(--color-meta);
}
.fin-chain__sep::before,
.fin-chain__sep::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--color-border-soft);
}
.fin-chain__sep.is-done { color: var(--color-success-text); }
.fin-chain__sep.is-done::before,
.fin-chain__sep.is-done::after { background: var(--color-success); opacity: .35; }

/* 付款段 = 方点（与审批的圆点区分）。其余完全复用 `.af-step` 的结构与三态配色。 */
.af-step--pay .af-step__dot { border-radius: var(--radius-sm); }
.af-step--pay .af-step__n { width: 138px; }   /* 付款的说明文字略长（含"财务凑批次提报"等） */
/* 付款段的节点宽度更大 ⇒ 连接线仍由 flex:1 自适应铺满，不必额外改 */

.af-step { display: flex; align-items: flex-start; }
.af-step--empty { padding: var(--space-2) 0; }

.af-step__n {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 104px;
  flex-shrink: 0;
}

.af-step__dot {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  background: var(--color-surface);
  color: var(--color-muted);
  border: 2px solid var(--color-border);
  box-sizing: border-box;
}

.af-step__n.is-done .af-step__dot {
  background: var(--color-success);
  border-color: var(--color-success);
  color: #fff;
}
.af-step__n.is-rejected .af-step__dot {
  background: var(--color-danger);
  border-color: var(--color-danger);
  color: #fff;
}
/* 进行中：橙色圈 + 一圈光晕。
   ⚠️ 光晕是"当前节点"最直观的表达 —— 只靠颜色深浅（橙 vs 灰）区分度不够，
      加一圈同色淡晕后视觉重量明显不同，扫一眼就知道停在哪。 */
.af-step__n.is-current .af-step__dot {
  background: var(--color-warning-bg);
  border-color: var(--color-warning);
  color: var(--color-warning-text);
  box-shadow: 0 0 0 4px var(--color-warning-bg);
}

.af-step__t {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-fg);
  margin-top: var(--space-2);
}
.af-step__n.is-current .af-step__t { color: var(--color-warning-text); }
.af-step__m {
  font-size: var(--font-size-xs);
  color: var(--color-fg-2);
  margin-top: 2px;
  /* 审批人可能很长（"张三、李四、王五"）⇒ 允许折行但不撑破节点宽度 */
  word-break: break-all;
}
.af-step__d {
  font-size: var(--font-size-xs);
  color: var(--color-muted);
  margin-top: 1px;
}
.af-step__n.is-rejected .af-step__d { color: var(--color-danger); }

/* 连接线：与圆点垂直居中（圆点 28px ⇒ 上边距 13px） */
.af-step__bar {
  flex: 1;
  height: 2px;
  min-width: 16px;
  background: var(--color-border);
  margin-top: 13px;
}
.af-step__bar.is-done { background: var(--color-success); }

@media (max-width: 768px) {
  /* 窄屏：横向 4 道在手机上放不下，硬挤会把节点名压断 ⇒ 转纵向。
     纵向时隐藏"审批人/时间"（信息密度让位给可读性），状态仍靠圆点区分。 */
  .af-step-card { padding: var(--space-4) var(--space-4); }
  .af-step { flex-direction: column; }
  .af-step__n {
    flex-direction: row;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    text-align: left;
  }
  .af-step__t { margin-top: 0; }
  .af-step__m, .af-step__d { margin-top: 0; margin-left: auto; }
  .af-step__bar {
    width: 2px;
    height: 18px;
    flex: none;
    min-width: 0;
    margin: 2px 0 2px 13px;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   报销人（头像 + 姓名）—— 乐哥 2026-09-21：「报销人得和达播台一样，有飞书头像（没有的用首字）」
   ──────────────────────────────────────────────────────────────────────────
   列表里用 `.cell-person`（**达播台的标准件**，table.css 里定义，含 28px 圆形头像、
   无图时姓名字首兜底、名字与徽章同一行的排布）—— 本文件不重写它，只做两处"在财务表格里"的适配。
   ══════════════════════════════════════════════════════════════════════════ */

/* ① 列表行更紧凑一点：财务表一屏行数多，28px 头像会把行高明显顶起来。
      收 4px 后与原来无头像时的行高接近，同时保留头像的可辨识度。 */
.fin td .cell-person__avatar {
  width: 24px;
  height: 24px;
  font-size: var(--font-size-xs);
}

/* ② 详情页头部那处「报销人」是**行内**展示（`<b>` 里），不是表格单元格 ——
      `.cell-person` 是 flex 块，直接塞进 <b> 会把基线与后续文字错开。
      这里改成 inline-flex + 与文字垂直居中对齐。 */
.fin-person {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--font-weight-medium);
}
.fin-person .cell-person__avatar {
  width: 24px;
  height: 24px;
  font-size: var(--font-size-xs);
  vertical-align: middle;
}
