/* ==========================================================================
   达播工作台 — table.css
   表格 / 单元格 / 骨架屏 / 空态·错误态 / 分页
   ========================================================================== */

/* ---- 表格 ---- */
.table-wrap {
  overflow-x: auto;
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-sm);
}

/* 首 / 末列左右留白对齐卡片内的工具栏（2026-09-14 乐哥反馈「列表文字紧贴边框」）
   ⚠️ 数值依据（真实渲染实测）：`.table-toolbar` 水平 padding = --space-5(20px)，
      而 `.table` 单元格 = --space-3(12px) → **表格首列文字比工具栏标题左移 8px**，
      视觉上就像贴住卡片左边框（实测：工具栏文字距卡片左 21px、表格首列文字仅 13px）。
      这里把首/末列补齐到同一 20px，让「工具栏标题 ↔ 表格首列」「表格末列 ↔ 工具栏右侧」对齐。

   ⚠️ 2026-09-14 二次修正 —— 排除条件从 `.table--sub` 换成**真实结构判据**：
      上一版写 `.table:not(.table--sub)`，本意是排除"嵌在父表单元格里的子表"，
      但 `table--sub` 在本项目里**语义已漂移** —— 它既用在真嵌套子表上，也用在
      **面板里的顶层表**上（结算明细的「本期佣金构成」「业绩构成」两张就是）。
      结果这两张顶层表被误排除、首末列仍是 12px，而同层级的提成明细是 20px
      → 乐哥看到的「达人结算二级页和提成总览不一样」，主因就是这 8px。
      （实测：全站 18 张顶层表里只有结算明细那 2 张漏网；真嵌套子表实际 **0 张**。）
      改用结构判断：**在 `td` 里的**才是子表（跟随父表列宽，不能加内边距），
      其余顶层表一律补 20px。`:where()` 不参与优先级计算，本条权重维持不变。
   · 只改 padding 不改 width：`table-layout: fixed` 下宽度含 padding，不会撑破列宽预算。 */
.table:not(:where(td .table)) > thead > tr > th:first-child,
.table:not(:where(td .table)) > tbody > tr > td:first-child {
  padding-left: var(--space-5);
}
.table:not(:where(td .table)) > thead > tr > th:last-child,
.table:not(:where(td .table)) > tbody > tr > td:last-child {
  padding-right: var(--space-5);
}

.table thead th {
  background: var(--table-header-bg);
  color: var(--table-header-fg);
  font-weight: var(--font-weight-medium);
  font-size: var(--font-size-xs);
  letter-spacing: 0.01em;
  /* 全列居中（乐哥 2026-09-14 定稿，方案B）：原为左对齐。
     配套改动见本文件「全列居中」区块（.is-num 同步改居中 + flex 子容器补偿）。 */
  text-align: center;
  height: 44px;
  padding: 0 var(--space-3);
  /* ⭐ 2026-09-25 Gashora 骨架落地：表头分隔线 --color-border(#E1E8F2，**带蓝调**) → #EFEFEF
     （中性浅灰，参考图实测值）。蓝调是与整体中性灰白不协调的来源（乐哥：「表格的线不对」）。 */
  border-bottom: 1px solid var(--table-header-line);
  white-space: nowrap;
}

.table thead th.is-num {
  /* 表头**保持居中**（乐哥 2026-09-15：「其他所有的位置都不变」）。
     即：正文数值靠右、表头居中 —— 这是"只动数字、别的一律不动"的忠实执行。
     若要改成表头也靠右（整列一条竖轴），把这里改成 right 即可，只此一处。 */
  text-align: center;
}

/* 表头排序（库存列表等）：所有可排列表头常驻箭头指示，hover/激活高亮 */
.table thead th.sortable {
  cursor: pointer;
  user-select: none;
}
.table thead th.sortable:hover {
  color: var(--color-accent-text);
}
.table thead th.sortable:hover .th-sort-ic {
  color: var(--color-accent-text);
}
.table thead th.is-sorted {
  color: var(--color-accent-text);
}
.table thead th .th-sort-ic {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
  margin-left: 4px;
  color: var(--color-muted);
  line-height: 0;
}
.table thead th .th-sort-ic svg {
  display: block;
}
.table thead th .th-sort-ic svg + svg {
  margin-top: -4px;
}
.table thead th .th-sort-ic--on {
  color: var(--color-accent-text);
}

.table tbody td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--table-divider);
  color: var(--color-fg);
  vertical-align: middle;
}

.table tbody tr:last-child td {
  border-bottom: none;
}

.table tbody tr {
  transition: background-color var(--motion-fast) var(--motion-ease-standard);
}

.table tbody tr:hover {
  background: var(--table-row-hover);
}

/* ==========================================================================
   隔行底色（斑马纹）· **已按乐哥要求去掉**（2026-09-25）
   --------------------------------------------------------------------------
   ▸ 历史：2026-09-15 乐哥要求加（「这些表格为了看的清楚，错行用很浅的背景色做区分」），
     当时定为**全站默认生效**（48 张表统一，避免"8 张有、40 张没有"的读法不一致）。
   ▸ 2026-09-25 乐哥改主意：「表格斑马纹，我觉得是不是可以不要」+「我的报销页也有斑马纹」
     ⇒ 本次**全线去掉**，不止这一处（全站共 4 处实现，都已处理）：
        ① 本文件       `.table tbody tr:where(:nth-child(even))`   ← 全站默认（主战场）
        ② `pages.css`  `.table--zebra tbody tr:nth-child(even)`   ← 售后分析的历史写法
        ③ `pages.css`  `.pmd-table tbody tr.pmd-row.is-alt`       ← 利润月明细（自己按主行序号加类）
        ④ `pricing-compare.css` `.pc-table tbody tr:nth-child(even)` ← 机制比价（自己实现）

   ▸ 去掉斑马纹后，行与行的区分靠什么（**不能什么都不靠**，否则横排数字会串行）：
       · **行分隔线**：`.table tbody td` 自带的 `border-bottom`（本文件上方定义）——
         淡到几乎看不见但足以引导视线，这是当前的主要手段
       · **hover 高亮**：`.table tbody tr:hover`（下方定义），鼠标所在行整行变色 ⇒
         读长行数字时"当前行是哪一行"始终有反馈
       · **特殊行底色**：合计行 / 主指标行仍有自己的底色
         （`.an-pnl-total`、`.so-subtotal`、`.af-audit__main`、`.af-bd__total` 等，各自独立定义，
          **不依赖本段规则**，所以本次删除不会让它们掉色）
     ⚠️ 如果乐哥以后反馈"看数字串行"，优先**加深行分隔线**（改 `--color-border-soft`），
        而不是加回斑马纹 —— 分隔线更"简约"，且不会在展开子表/隐藏行上错位。

   ⚠️ 以下原注释保留，说明**当初为什么用 `:where()`**（万一以后要恢复斑马纹，直接抄这段）：
       「必须把斑马纹的特异性压到最低，否则会盖掉页面自己的行样式。
         用 `:where()` 把伪类包裹 —— `:where()` 内选择器特异性记 0：
           `.table tbody tr:where(:nth-child(even))` → (0,1,2)
         而各页面/子表的行规则普遍是 (0,2,2) 及以上，自动胜出，例如：
           `.table tbody tr:hover` (0,2,2)、`.an-pnl-table tbody tr.an-pnl-total` (0,2,2)、
           `.table--sub tbody tr.so-subtotal` (0,2,2)、`.af-audit__main` / `.af-bd__total` (0,2,2)。
         ⇒ 不需要维护"特殊行清单"、也不依赖 CSS 加载顺序。」
   ⚠️ 展开子表（`.table--sub`，全站 16 张）当初就**不加**斑马纹：它嵌在父表展开行里、
      通常只有 2~4 行，再加纹会与父表行底/展开区底叠成"三层底色"。
      现在全站都没有斑马纹了，这条差异自动消失。
   ========================================================================== */
/* ⛔ 2026-09-25 起这两条规则已删除（保留位置与说明，方便回溯）：
     .table tbody tr:where(:nth-child(even)) { background: var(--table-row-alt); }
     .table--sub tbody tr:where(:nth-child(even)) { background: transparent; }
   恢复方式：取消上面两行注释即可（`--table-row-alt` 令牌仍在 design-tokens.css 里，未删除）。 */

.table .is-num {
  font-feature-settings: "tnum", "lnum";
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-weight-medium);
}
/* ══ 数值列靠右（乐哥 2026-09-15 定稿：数字靠右，其他位置一律不变）══════════════
   原话：「列表的文字，看下要不要数据，就是数字靠右，其他所有的位置都不变，和之前一样」

   背景：2026-09-14 曾把数字从右改**居中**（与表头共一条中线）。改回右对齐的实测理由：
     金额列居中后，同列里「¥6.9万 / ¥4,816.00 / ¥125.00」位数参差、看不出列边界；
     靠右后末位对齐，对账时逐位可比 —— 那是本系统最高频的用法。

   ⚠️⚠️ 下面这串选择器**不能简化**（这是本次最容易白改的一处）：
     本文件上方「全列居中」区块有一条
        `.table:not(:where(td .table)) > tbody > tr > td { text-align: center; }`
     特异性 (0,1,3)；而原来的 `.table .is-num` 只有 (0,2,0)，**压不过它**。
     ⇒ 只把 `center` 改成 `right` 会**静默不生效**（页面看起来"改了没反应"）。
     故显式写到 `tbody td` 层级拿 (0,2,2)，稳赢 (0,1,3)。
     （`.table--sub` 子表一并覆盖：它嵌在 td 里，会**继承**父 td 的居中，
       不显式声明就跟着居中 —— 全站 16 张子表。）

   ⚠️ 表头**保持居中不动** —— 乐哥明确「其他所有的位置都不变」。
      若日后想改成"表头也跟着靠右"（整列同一竖轴、更整齐），
      只需给下面 `thead th.is-num` 那块也加 `right`，一处即可切换。 */
.table tbody td.is-num,
.table tfoot td.is-num,
.table--sub tbody td.is-num,
.table--sub tfoot td.is-num {
  text-align: right;
}

/* ══ 表格列对齐规范（乐哥 2026-09-14 定稿）═════════════════════════════════════
   两条规则，一句话可背：
     ① **长文本列靠左** —— 货品名、达人名、套餐名、备注这种"长短不一的一句话"
     ② **其他全部居中** —— 表头 + 数字列 + 短文本列（状态/类型/编号/时间/人员/操作…）
   为什么这样分（可验证的理由，不是审美）：
     · 长文本靠左：长短不一的文本若居中，每行起点参差、扫读更难；左对齐有固定起始线。
     · 其余居中：这些列内容短且长度接近，居中后两侧留白均等；表头也居中 →
       表头与正文共用同一条中线，整列成一条竖轴 —— 比"贴左"和"贴右"都整齐。

   ▸ 实现分工（**默认居中 + 例外类**，这样新增列不用做任何事就是对的）：
     · 默认居中写在 `th` / `td` 层（下面 .table tbody td / tfoot td / thead th）
     · "长文本列"由 JS 在渲染后打 `.col-align-left`（判定逻辑见 app.js 的 `fixColAlign()`）
       为什么用 JS 判定而不是 CSS：CSS 无法知道某列内容是"一句话"还是"一个词"，
       只能靠**实测内容**判定；用 JS 判定还能自动覆盖将来新增的页面，不用逐页配。
   ▸ 与上一版（2026-09-14 上午「文字左 + 数字右」）的差异：
     数字从**右**改**居中**、表头从**左**改**居中**、短文本列从**左**改**居中**；
     仅"长文本列"维持靠左。
   ▸ 2026-09-15 微调（乐哥定稿）：**数字改回靠右**，其余（表头、文本列）一律不动。
     即最终形态 = 长文本左 / 其余居中 / **数值列靠右**。
   ⚠️ 回退方式：删掉 `.col-align-left` 的规则即可回到"全居中"；
      再把 `.is-num`/`.num` 那两块改回 `center` 即回到 9-14 版本。 */
.table:not(:where(td .table)) > thead > tr > th,
.table:not(:where(td .table)) > tbody > tr > td,
.table:not(:where(td .table)) > tfoot > tr > td {
  text-align: center;
}
/* 长文本列（JS 判定后打类）→ 靠左。子元素（.cell-main/.cell-sub 等）自动继承。 */
.table .col-align-left,
.table--sub .col-align-left {
  text-align: left;
}

/* ② 数字靠右：`.num` 是同义的另一种写法（base.css 里定义的等宽数字类），
   表格内必须与 `.is-num` **同规则**，否则会出现"同一列有的格靠右、有的格居中"
   （实测提成总览有 2 处只写了 `.num`）。
   特异性要求与 `.is-num` 完全相同，理由见上方那块的注释。 */
.table tbody td.num,
.table tfoot td.num,
.table--sub tbody td.num,
.table--sub tfoot td.num {
  text-align: right;
}

/* 盈亏正负颜色：盈利=红，亏损=绿（中式股市惯例，涨红跌绿） */
/* ⚠️ 盈亏正负色（**全站约定：盈利=红、亏损=绿**，国内红涨绿跌习惯）
   特异性必须 ≥ 0,2,1 —— 因为上面有 `.table tbody td { color: var(--color-fg) }`（0,2,1）。
   2026-09-13 修正：原来写成单类 `.num-pos`（0,1,0）**被它压过**，
   导致**全站表格里的盈亏正负色从来没生效过**（KPI 卡里的生效，表格里的不生效 —— 两处表现不一致）。
   故加上 `.table tbody td` 前缀，并同时覆盖 `.table--sub`。 */
.table tbody td.num-pos,
.table--sub tbody td.num-pos,
.num-pos { color: var(--color-danger); }
.table tbody td.num-neg,
.table--sub tbody td.num-neg,
.num-neg { color: var(--color-success); }

.cell-sub {
  display: block;
  margin-top: 2px;
  font-size: var(--font-size-xs);
  color: var(--color-muted);
}

/* ⚠️ 兜底：`td` 上误用 `.cell-sub`（2026-09-15 乐哥报「说明和分摊没有横线和斑马纹」，第 4 次踩到）
   ----------------------------------------------------------------------------
   `.cell-sub` 是「**格内第二行小字**」用的类，带 `display:block`。挂到 **td 自身**时，
   该格会**脱离表格单元格渲染** —— 浏览器为它包一层匿名单元格，后果：
     · 行高按内容算、不再撑满整行 → 横线（td 的 border-bottom）画在内容框底边，
       视觉上"断"在行的中间，看起来就是**没有横线**
     · 斑马纹设在 tr 上，而匿名框与 td 自身背景都透明 → 斑马纹在**这一列断开**
   项目此前已在 schedule-detail ×2 / fan-experience 踩过并逐个改成 `<span class="cell-sub">`；
   本次 profit-ledger 逐笔明细与 profit-settlement 校准弹窗又各出现一次，故加此兜底防复发。
   **正确写法**：`<td><span class="cell-sub">…</span></td>`（小字类只包内容，不挂单元格）。
   ⚠️ 只覆盖 display，font-size / color 仍沿用上方 `.cell-sub`（保留"小字"本意）。 */
.table td.cell-sub,
.table--sub td.cell-sub {
  display: table-cell;
}

/* 单元格内多信息 */
.cell-main {
  font-weight: var(--font-weight-medium);
  color: var(--color-fg);
}

/* 表格内头像 + 文本 */
.cell-person {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
}

/* 人员列：「名字 + 岗位」同一行（2026-09-14 乐哥：「岗位和名字一行，不要分行」）
   ----------------------------------------------------------------------------
   改前：`<div>名字</div><div>岗位徽章</div>` 上下两行 → 行高被撑起来、扫读时要分两段看。
   改后：`.cell-person__line` 一个 flex 行内放名字与岗位徽章，超宽时整行换行（不会把名字截断）。
   ⚠️ 必须把 `.cm-pitem__roles` 的 `margin-top: 3px` 归零 —— 那个边距是给左栏人员列表
      （上下堆叠布局）用的，在表格行内会让徽章比文字低 3px、看着没对齐。 */
.cell-person__body {
  flex: 1;
  min-width: 0;
}
.cell-person__line {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.cell-person__line .cm-pitem__roles {
  margin-top: 0;
}

/* 费用列表人员列：名字完整展示、不换行、不截断（区别于达人列表的省略号） */
.cell-person--full .cell-person__name {
  white-space: nowrap;
  overflow: visible;
  text-overflow: clip;
}

.cell-person__avatar {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-pill);
  background: var(--color-primary-100);
  color: var(--color-accent-text);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  flex-shrink: 0;
  overflow: hidden;
}

.cell-person__avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cell-person__meta {
  min-width: 0;
}

.cell-person__name {
  font-weight: var(--font-weight-medium);
  color: var(--color-fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 达人姓名下的平台/机构标签行 */
.cell-person__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 3px;
}

/* 达人姓名下的所属商务小字 */
.cell-person__sub {
  margin-top: 2px;
  font-size: var(--font-size-xs);
  color: var(--color-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 达人一行展示（无头像）：姓名 + 平台/机构/类型标签 + 所属商务，默认单行，空间不足自动换行（不裁切） */
.cell-person-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  min-width: 0;
}
.cell-person-row__name {
  font-weight: var(--font-weight-medium);
  color: var(--color-fg);
  white-space: nowrap;
}
.cell-person-row__bd {
  font-size: var(--font-size-xs);
  color: var(--color-muted);
  white-space: nowrap;
}

/* ⚠️ 带视图 tab 的卡片：顶部补回呼吸空间（2026-09-14 实测修正）
   ----------------------------------------------------------------------------
   合并成一张卡时，为消除"卡外空容器"的灰缝，卡片被设了 `margin-top: -16px`。
   tab 行搬进卡内顶部后会被这个负 margin 顶到筛选行下面（实测重叠 -16px）。
   这里用 **padding-top** 补回来并多留 12px 呼吸（16 抵消 + 12 = 28px）。
   ⚠️ 必须用 padding：合并后卡片 `border-top: 0`，子元素的 margin-top 会穿透到卡片外
      （margin collapse），改不成效果。 */
.toolbar--join-target.card--has-tabs { padding-top: 28px; }

/* ── 表格「视图 tab」：下划线式（2026-09-14 乐哥：「tab 选择和其他工具栏混在一起了」）
   ════════════════════════════════════════════════════════════════════════════
   背景：表格视图切换（全部 88 / 待合作 47 / 已结束 24…）原本用的是**分段按钮**样式
     （`.pill-filter` / `.seg`：白底带框、选中实底块）。
     把它和「搜索框 / 下拉筛选」并到一排后，乐哥指出问题：
       「tab 选择和其他工具栏**混在一起**了」—— 对，因为两者都是"带框的控件"，
       读者分不清哪个是"切换视图"、哪个是"筛选条件"。

   解法：把视图切换改成**下划线式 tab**，并让它**独立成一行、紧贴表格**。
     · 视觉上与"带框下拉"天然区分（一排文字 + 底部指示条 vs 带边框的下拉）
     · 位置紧贴表格 = 语义上属"表格的一部分"（它切换的就是表格显示什么）
     · **完全复用**项目已有的 `.tabs` / `.tab` 语言（pages-influencer.css:321）：
       40px 高、24px 项间距、2px 主色指示条、未选中用 --color-muted
       → 不新造视觉语言，与订单明细页的「直播业绩/私域业绩/订单明细」同一套观感

   ⚠️ 覆盖的是 `.pill-filter__item` / `.seg__btn` 两个内部类（分段控件两套类名并存，
      本项目"同一件事两套名字"的老问题）—— 两个都写，否则有一半页面改不动。
   ⚠️ 必须把 .seg 外容器的白底/边框/内边距也清掉，否则下划线 tab 会被套在白色胶囊里。 */
.table-tabs {
  display: flex;
  align-items: center;
  flex-wrap: wrap;                  /* 极窄屏时工具组可折行，不挤压 TAB */
  gap: var(--space-6);              /* 与 .tabs 一致的 24px 项间距 */
  margin: 0;
  padding: 0 var(--space-5);        /* 与表格 / .table-toolbar 同左边界（20px） */
  border: 0;
  border-bottom: 1px solid var(--color-border-soft);   /* 与 .tabs 相同的基线 */
  border-radius: 0;
  background: transparent;
  /* ⚠️ 必须是 overflow: visible，**不能**用 overflow-x: auto（2026-09-14 实测修正）
     原因：CSS 规范规定「当一个轴不是 visible 时，另一个轴的 visible 会计算为 auto」，
     所以 `overflow-x: auto` 会让 `overflow-y` 也变成 auto；
     而选中态的下划线用了 `bottom: -1px`（为了压住容器那 1px 底边框），
     内容高度 41px > 容器 40px → **纵向溢出 1px → 右侧出现一条纵向滚动条**
     （乐哥截图里红框圈出的那条竖杠）。
     现在行内用 flex-wrap 折行，不需要横向滚动，直接 visible 最干净。 */
  overflow: visible;
}

/* ── TAB 行内的「表格工具」（多选 / 共N条 / 每页）────────────────────────────
   乐哥 2026-09-14：「多选 / 共88位达人 / 20条每页 这个是不是也应该和
                     全部88 待合作47 … 同一行，然后相同的尺寸」
   → 对。它们和 TAB 同属"表格自己的事"（视图切换 + 批量操作 + 分页统计），
     都是表格头部工具条的一部分；而"搜索/下拉"才是页面级筛选，留在第 1 排。
   本段负责：靠右 + **尺寸统一**（这是乐哥特别强调的）。

   ⚠️ 为什么要统一尺寸：搬过来之前是三套尺寸混排 ——
      多选按钮 30px、共N条 18px（字号还小一号，12px）、每页下拉 28px，
      而 TAB 是 40px / 14px。三种高度并排会显得"东倒西歪"。
      现在：字号一律 14px（--font-size-sm），控件高度一律 30px。
   ⚠️ TAB 保持 40px 高不跟着改 30px：它的 40px 是行高 + 下划线基线（同 .tab），
      工具是"控件"，两者高度不必相同，靠 align-items:center 垂直居中即视觉齐平。 */
.table-tabs > .table-toolbar__right {
  margin-left: auto;                /* 推到最右，与 TAB 分列两端 */
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: none;
}
.table-tabs > .table-toolbar__right .btn,
.table-tabs > .table-toolbar__right .select {
  /* 34px：与筛选行的控件（`.toolbar--list` 那组）**统一为同一个高度**。
     ⚠️ 原来是 30px，但那样一页里会出现三种高度：
        筛选行控件 34px、TAB 行工具 30px、TAB 项 40px —— 看着仍然"不齐"。
        统一规格：**有框控件一律 34px**、**TAB 项一律 40px**（它是文字+下划线、无框，属"标签"）。
        这样全站只有两个数字，好记也好维护。 */
  height: var(--control-height-sm);
  min-height: var(--control-height-sm);
  font-size: var(--font-size-sm);
}
.table-tabs > .table-toolbar__right .table-toolbar__total {
  font-size: var(--font-size-sm);   /* 12px → 14px，与同行 TAB 字号一致 */
  color: var(--color-fg-2);
  white-space: nowrap;
}
.table-tabs .pill-filter__item,
.table-tabs .seg__btn {
  position: relative;
  height: 44px;                     /* 与 .tab 同高（2026-09-18：40 → 44，配合 16px 字号） */
  padding: 0 2px;
  background: transparent;
  border: 0;
  border-radius: 0;
  color: var(--color-muted);        /* 未选中（同 .tab） */
  /* ⚠️ 2026-09-18 乐哥：「字号大一点点」→ 14 → 16px（--font-size-lg）。
     ⚠️ 必须改**这里**，不能只改 `.tab` —— 本规则选择器是 `.table-tabs .seg__btn`（0,2,0），
        特异性**高于** `.tab`（0,1,0），会把 `.tab` 的 font-size 整个盖掉。
        实测踩过：只改 `.tab` → 13 个页面探测出来全是 14px，一度以为 CSS 没生效。
        （这类"改了一处被另一处盖掉"的坑，本项目已栽多次，见技能
          dabotai-ui-consistency-fix「语义色被更具体选择器盖过」一节。） */
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-medium);
  white-space: nowrap;
  transition: color var(--motion-fast) var(--motion-ease-standard);
}
.table-tabs .pill-filter__item:hover,
.table-tabs .seg__btn:hover { color: var(--color-accent-text); }
/* 选中：主色文字 + 2px 底部指示条（同 .tab::after 的观感） */
.table-tabs .pill-filter__item.is-active,
.table-tabs .seg__btn.is-active {
  background: transparent;
  color: var(--color-accent-text);
  font-weight: var(--font-weight-semibold);
}
.table-tabs .pill-filter__item.is-active::after,
.table-tabs .seg__btn.is-active::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  border-radius: 1px;
  background: var(--color-accent);
}

/* ── 嵌在「页面级工具栏」里的 TAB 条（人员成本 / 兼职助播）────────────────────
   它们的 seg 直接放在 `.toolbar` 内（不在 .table-toolbar 里），由 JS 加了
   `.table-tabs` 复用下划线样式，并移到工具栏最前。
   本段让它**独占一行**，并去掉重复缩进。

   ⚠️ 行序：**TAB 在上、筛选在下**（2026-09-18 乐哥改版，参照微信小店）。
      这与 2026-09-14 那一版相反 —— 当时定的是"筛选在上、视图切换在下"，
      乐哥 2026-09-18 看到微信小店的形态后改主意：「那个 tab 栏，我看别的系统是
      放在工具栏上面的…我觉得这样更合理」。
      ⇒ 实现方式仍是 `flex-basis: 100%`（独占一行），但**行序由 DOM 顺序决定**：
        JS 改为 `insertBefore(seg, tb.firstChild)`（搬到最前），**不用 CSS order**
        —— order 会让键盘 Tab 焦点顺序与视觉顺序不一致（无障碍问题）。
   ⚠️ 必须清掉左右 padding：`.table-tabs` 自带 20px 左缩进，而父级工具栏**也有** 20px，
      不区分会变成 40px 双重缩进、与其它页面的 TAB 不对齐。 */
.toolbar--has-page-tabs > .table-tabs {
  flex-basis: 100%;
  padding: 0;
  /* TAB 行与下方筛选行的间距（改版后它在上面，需要与筛选拉开一点，读者才分得清两行）
     ⚠️ 与 `.toolbar` 的 `row-gap: var(--space-2)` 叠加 → 实际 8 + 8 = 16px。 */
  margin-bottom: var(--space-2);
}

/* ══════════════════════════════════════════════════════════════════════════
   状态 TAB「住进页面标题行」后的形态（2026-09-25 骨架级第 1 批）
   --------------------------------------------------------------------------
   排版目标（一行三块）：
     「达人管理   ｜ 全部83 待合作43 待开始4 …  ｜ [导入][导出][新增达人]」
        标题             TAB 组（占据中间弹性空间）         页面级操作按钮

   ⚠️ 触发条件用 `.page-header--has-tabs`（由**页面自己**在标记里写上，见
      `pages/influencer-list.js` 的说明）—— 全站 41 页有标题行、只有少数页有 TAB，
      标记法能把影响**严格限定**在这些页内。
   ⛔ 为什么不由框架统一加类/搬节点：实测会踩到 2026-09-24 那次线上故障的同一条路径
      （框架反复搬动 + 卡片异步重渲染 ⇒ 不收敛 ⇒ 业绩总表主线程卡死：
       改动前 2568ms 正常、改动后 6 秒起阻塞 40 秒不恢复）。
      ⇒ 结论：**这类"把节点从卡内搬到卡外"的动作，只能在页面渲染时一次性生成，
        不能让框架反复搬。** 详见 `docs/骨架级改动-立项方案-20260925.md`。

   ⚠️ 为什么 TAB 项从 44px 降到 32px：44px 是它当年"独占一行 + 带下划线基线"时的高度；
      进了标题行后标题行自身高 44px，TAB 项若也是 44px 会把标题行撑高、吃掉收益。
   ⚠️ 下划线从 `bottom:-1px` 改为 `bottom:0`：原来的 -1px 是为压住容器自身的 1px 底边框；
      标题行里没有那条基线了，且 -1px 会造成纵向溢出 ⇒ 在 `overflow-x:auto` 下
      右侧会冒出一条纵向滚动条（本项目 2026-09-14 已因此踩过坑）。 */
.page-header--has-tabs {
  align-items: center;                  /* 标题 / TAB / 按钮 三者垂直居中 */
  gap: var(--space-4);
  margin-bottom: var(--space-4);        /* 原 24 → 16：把省下的高度让给数据区 */
}
.page-header--has-tabs > div:first-child {
  flex-shrink: 0;                       /* 标题「达人管理」永不被压缩 */
}

.table-tabs--in-header {
  flex: 1 1 auto;                       /* 占据标题与按钮之间的弹性空间 */
  min-width: 0;                         /* 允许内部滚动而不撑破标题行 */
  padding: 0;                           /* 标题行已有左右 gutter，去掉 TAB 自带的 20px */
  border-bottom: 0;                     /* 标题行里没有那条下划线基线 */
  gap: var(--space-4);                  /* 项间距 24 → 16（横向空间比独占一行时紧） */
  overflow-x: auto;                     /* TAB 项过多时可横向滚动 */
  overflow-y: hidden;
  scrollbar-width: none;
}
.table-tabs--in-header::-webkit-scrollbar { display: none; }

/* ⭐ 2026-09-25 乐哥：「货品页不对，那个 tab 和工具栏放一起了」——
   被**搬到工具栏之前**的 TAB（`data-lifted` 标记，见 app.js 的 fixTableTabs）。
   它现在是内容区白大卡上的**独立一行**，下面依次是工具栏卡、表格卡（与达人管理页同构）。
   ⚠️ 与"卡内 TAB 行"（.table-tabs 的基础样式）的区别只在**外部间距**：
      基础样式自带 `padding: 0 20px`（与表格/工具栏内文字左对齐，实测对齐误差 0）
      与 `border-bottom` 下划线基线 —— 两条都保留（独立一行时基线让"这是一组 tab"更明确）。
   ⚠️ 只加下外边距（与下方工具栏卡留出呼吸），不加左右外边距（保持与卡内文字对齐）。 */
/* ⚠️ 只对"落在工具栏前"的兜底形态生效；进了标题行（--in-header）的不需要这个下边距
   —— 标题行自身有 margin-bottom（16px），再加会撑出双倍间距。 */
.table-tabs[data-lifted]:not(.table-tabs--in-header) {
  margin-bottom: var(--space-3);   /* 12px：与下方工具栏卡的间距（它是两张独立的卡/行） */
}
/* 首个元素时（页面内容顶部）不留额外上边距 —— 白大卡自身已有 padding-top。 */
.table-tabs[data-lifted]:first-child { margin-top: 0; }

/* ⭐ 2026-09-25（第二轮）乐哥：「货品那个 tab 上面留白也太多，和其他页面不统一」
   —— TAB 现在搬进**页面标题行**（`.page-header--has-tabs` + `.table-tabs--in-header`，
   与达人管理页同构）。上面那套 `.table-tabs--in-header` 的样式（去左右 padding、
   去下划线基线、flex:1 占中间位）**是现成的**（达人管理页在用），此处无需重复定义。
   ⚠️ 但"标题已隐藏"的页面（乐哥刚要求去掉页面标题）有个副作用要处理：
      `.page-header--has-tabs > div:first-child`（标题容器）`flex-shrink:0`
      但宽度为 0 ⇒ TAB 会被 `gap: 16px` 推出 16px 的左侧空档、与下方工具栏左缘错位。
      ⇒ 让**标题容器为空时**不参与 flex 排布（`:empty` 判据），TAB 就能贴到行首。
   ⭐⭐ 2026-09-28 修 Tab 左错位（乐哥：「现在修复」，13 页实测错位 134~390px）：
      ⛔ 只写 `:empty` 不够 —— 标题全局 `display:none` 后，容器里 `<h1>` **节点仍在**，
         `:empty` 判据不命中 ⇒ 容器继续占 flex 位 ⇒ space-between 把 TAB 当中间元素推到页头中部，
         与下方工具栏/表格左缘错位（实测：达人管理 134px、排期列表 299px、样品包 390px）。
      ✅ 补 `:has(.page-title)` 判据：容器内**含页面标题节点**（无论是否可见）⇒ 整容器隐藏。
      ⚠️ 两条判据都要留：`:empty` 兜底"真正空容器"、`:has(.page-title)` 覆盖"藏着标题的空容器"。
      ⚠️ 为什么不用 `justify-content: flex-start`：那会改动整个页头的对齐语义（按钮靠右要另写
         margin-left:auto），且与无 tab 页面的页头行为分化；隐藏空容器是**最小改动**。 */
.page-header--has-tabs > div:first-child:empty,
.page-header--has-tabs > div:first-child:has(.page-title) { display: none; }

/* ⭐⭐ 2026-09-28 页头内的 TAB 改**胶囊形态**（乐哥拍板「方案C」+ 尺寸反馈）：
   ─────────────────────────────────────────────────────────────────────────────
   背景：TAB 原本是「下划线式」设计（2026-09-14，当时 TAB 紧贴表格）；2026-09-24 为省高度
   搬进页头后形态没跟着换 ⇒ 一排 16px 大字下划线 TAB 孤零零悬在页面顶部（乐哥：很奇怪）。
   本次与「页头包盒」配套改为胶囊（白容器 + 选中蓝块），与卡片内语言一致。
   ⚠️ 乐哥两条尺寸反馈（照做）：
     · 高度太矮 —— 胶囊总高提到 **44px**（容器 padding 4 + 项 34 + 边框 2），
       与页头右侧操作按钮（.btn--lg = 44px）齐平；
     · 宽度右边空非常多 —— 容器原是 flex 拉伸（909px 宽），改 **flex: none** 收缩到内容宽。
   ⚠️ 必须同时清掉 .table-tabs 的「下划线形态」遗留：透明底 / border-bottom 基线 /
     padding 0 20 / gap 24 / 项高 44 项距 2px，全部按胶囊规格重设。 */
.table-tabs--in-header {
  flex: none;                          /* 不拉伸：宽度随内容（乐哥：右边空太多） */
  gap: var(--space-1);                 /* 项间距 24 → 2（胶囊内挤着排） */
  padding: 4px;                        /* 容器内边距：总高 4+34+4+2(边框)=44，与右侧按钮齐平 */
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}
.table-tabs--in-header .pill-filter__item,
.table-tabs--in-header .seg__btn {
  height: 34px;                        /* 32 → 34：胶囊项高度（乐哥：太矮） */
  padding: 0 16px;                     /* 1px → 16：胶囊项横向留白 */
  border-radius: var(--radius-seg);
  font-size: var(--font-size-sm);      /* 16 → 14：与页头控件同号 */
  flex: none;                          /* 不被 flex 压扁文字 */
  white-space: nowrap;
}
.table-tabs--in-header .pill-filter__item.is-active,
.table-tabs--in-header .seg__btn.is-active {
  background: var(--gradient-brand);
  color: var(--color-accent-on);
}
/* 胶囊形态不需要下划线指示条（下划线是「贴表格」形态的指示方式） */
.table-tabs--in-header .pill-filter__item.is-active::after,
.table-tabs--in-header .seg__btn.is-active::after {
  display: none;
}

/* ── 列表页筛选控件：全站统一高度（2026-09-14）────────────────────────────────
   由 app.js 的 fixPageTabs 给「含表格的页面」的工具栏打上 `.toolbar--list`。
   统一为 **34px**：搜索框 / 下拉 / 日期选择器 / 重置按钮 全部同高。

   ⚠️ 为什么需要「跨页统一」而不只是"同一行统一"（乐哥两次反馈逼出来的）：
     ① 第一次：同一行里三种高度（32/42/30px）→ 已修
     ② 第二次：「日期选择控件尺寸和其他的不对」→ 同一行里 44 vs 34 → 已修
     ③ 第三次（本门禁 `probe-toolbar-height.js` 抓出）：**跨页也不一致** ——
        订单业绩 / 业绩总表 的工具栏**本来就在卡内**、不参与合并，
        于是它们的筛选控件仍是 44px，而其它页已是 34px。
     只按"已合并的工具栏"写规则，就会漏掉这类页面。
     → 判据改成「这页有表格」即套用统一高度，跨页才真正一致。

   ⚠️ 覆盖 `.mp__trigger`（日期选择器）时必须用**后代选择器**：
      它的真实层级是 `span.mp-host > div.mp > button.mp__trigger`（是孙子不是儿子），
      写 `.toolbar--list > .mp__trigger` 会一条都匹配不上（实测踩过）。 */
.toolbar--list .select,
.toolbar--list .input,
.toolbar--list .input--search,
.toolbar--list .input--search > .input,
.toolbar--list .mp__trigger,
.toolbar--list .btn {
  height: var(--control-height-sm);
  min-height: var(--control-height-sm);
}

/* ══════════════════════════════════════════════════════════════════════════════
   ⭐⭐ 2026-09-26 两档制**全局兜底**（乐哥：「令牌化 + 全局兜底」）
   ──────────────────────────────────────────────────────────────────────────────
   ⛔ 改前的问题：紧凑档（34px）只写在 3 个**具体选择器**里
      （`.toolbar--list` / `.toolbar--plain` / `.table-tabs > .table-toolbar__right`）——
      ⇒ 任何**没加这些修饰类**的工具栏就回落标准档 44px。
      实测踩到：业绩总表搜索框 44px（它的容器是**普通 `.toolbar`**，没加 `--list`）、
      报销/结算工具栏的「刷新」36px 与旁边 select 44px 并排。
   ✅ 改法：**按容器兜底**，不按修饰类 —— `.toolbar` 内的一律 34px。
      这样"新页面把控件放进工具栏"就**自动**是对的，不依赖谁记得加修饰类。
   ⚠️ 刻意**不**覆盖的场景（各保持原样，理由都成立）：
      · `.page-actions`（页面头部主按钮）—— 不在 toolbar 内 ⇒ 自动不受影响 ✅
      · 弹窗/抽屉里的控件 —— 不在 toolbar 内 ⇒ 保持标准档 44px ✅
      · 分页区单独一条（在上面，因为它常常**不在** toolbar 内、而在卡片底部）
   ⚠️ `.btn--lg` 要排除：它是"页面头部级"的大按钮，被塞进工具栏时也该保持标准档
      （目前无此用法，但排除掉更稳 —— 免得将来有人放进去却静默变 34）。
   ══════════════════════════════════════════════════════════════════════════════ */
.toolbar .input,
.toolbar .select,
.toolbar .input--search > .input,
.toolbar .mp__trigger,
/* ⭐ 2026-09-27 补 `.dtp-trigger`（日期选择器触发器）：
   乐哥看了「达人分账附表」工具栏后指出控件不齐。实测 dtp-trigger 基础值 40px，
   而兜底规则里**没有它** ⇒ 放进工具栏仍是 40px（两档制外的第三档，与 34px 的
   输入框/按钮混排肉眼可见地不齐）。补上后工具栏内所有控件归紧凑档 34px。 */
.toolbar .dtp-trigger,
.toolbar .btn:not(.btn--lg) {
  height: var(--control-height-sm);
  min-height: var(--control-height-sm);
}
/* 工具栏内的图标按钮也归一档（否则 icon-btn 的 34 与别的混排仍可能不一致） */
.toolbar .icon-btn {
  width: var(--control-height-sm);
  height: var(--control-height-sm);
}

/* ══════════════════════════════════════════════════════════════════════════════
   ⭐ 2026-09-26：操作列的图标按钮**不许被压缩**（乐哥：「操作列的按钮、文字等」）
   ──────────────────────────────────────────────────────────────────────────────
   ⛔ 改前的隐形问题：操作列若放 3 个图标按钮（货品/达人管理那种 日志+编辑+删除），
      列宽不够时 **flex 会把每个按钮从 34px 压到 26px** ——
      按钮自己的高度还是 34（= 一列里按钮宽度参差），且图标(16px)几乎贴住相邻按钮。
      实测：货品页 td 可用宽 83px、3 个按钮实需 102px ⇒ 每个被压到 26px。
   ✅ `flex: none` 让按钮**保持声明尺寸**，宁可让列宽参与布局（列宽由表格分配）。
      ⚠️ 若加宽后表格超容器，会出横向滚动条 —— 那说明**该表列宽本身需要调整**
         （属于"列宽统一"的范畴，见下一条注释），而不是靠压扁按钮来硬塞。
   ══════════════════════════════════════════════════════════════════════════════ */
.table td .icon-btn,
.table td .btn {
  flex: none;
}

/* ⭐ 2026-09-26：操作列的 td 收窄**左侧**内边距（给按钮腾空间）
   ──────────────────────────────────────────────────────────────────────────────
   背景：操作列常放 2~3 个按钮（34px 各），而列宽由表格分配 ——
        实测货品页 3 个按钮需 102px + 内边距(12+20)=134px，但列只有 115px
        ⇒ 加 `flex:none` 保住按钮尺寸后，表格**溢出 3px**（出横向滚动条）。
   ✅ 收窄**左**内边距（12 → 4，省 8px）：操作列是"右侧动作区"，
      左侧那点留白没有对齐意义；**右侧 20px 保留不动** ——
      它有明确约定（最右列留白对齐卡片内的工具栏，见本文件上方注释）。
   ⚠️ 判据用 `:has(> .toolbar)` —— 本项目操作列的按钮都包在 `.toolbar` 里
      （见各页渲染函数），比 `td:last-child` 更精确（末列不一定是操作列）。
   ══════════════════════════════════════════════════════════════════════════════ */
.table:not(:where(td .table)) > tbody > tr > td:has(> .toolbar) {
  padding-left: var(--space-1);
}

/* ══════════════════════════════════════════════════════════════════════════════
   ⭐⭐ 2026-09-26 操作列「按钮统一」（乐哥：「操作列的按钮，都看着统一下，展示方式也优化下」）
   ──────────────────────────────────────────────────────────────────────────────
   ⛔ 改前是**三种形态混用**（全站 14 张表 · 真机普查 `probe-td` 逐格量过）：

     | 形态 | 出现在 | 问题 |
     |---|---|---|
     | ① 纯图标（灰/红） | 9 张表（达人/货品/排期/费用…） | 本身没问题，但图标色**三档不齐**（见下） |
     | ② **蓝色实心文字 + 图标** | 库存「入库」/ 业绩「维护」/ 结算「确认」 | **与页面级主按钮撞权重** |
     | ③ 灰描边文字 + 图标 | 签约公司「查看」/ 用户管理「改角色・改部门」/ 日志详情 | 与②同是"业务动作"，长相却完全不同 |

   ⛔ 具体量到的三处「不齐」：
     · **图标颜色 5 种**：`data-log` 是 `--color-fg-2`(#3F4753，最深)、`data-edit` 是
       `--color-muted`、`data-confirm/finish/void/copy` 全是 `--color-fg-2`、
       `data-del` 红、`pc-del`（比价页删除）**却是深灰不是红**、`data-unlock` 是**黄色**
       （#F2A918 —— 全站唯一的黄色按钮，在一列灰/蓝里格外突兀，且白底对比度仅 ~2:1）
     · **图标尺寸**：佣金配置页 14px、比价页 15px、其余 16px
     · **动作顺序**：库存是「入库 → 日志」（业务在前）、其余是「日志 → 业务」；
       排期是「日志 → 编辑 → 删除 → 解锁」（业务动作排到了最末）

   ✅ 解法（**按语义分三档，一处 CSS 全覆盖全站 14 张表，不动任何页面的 JS 类名**）：
     · **业务文字按钮**（入库/维护/确认/查看/改角色/改部门/日志详情）
       → `--button-soft-bg` 软蓝底 + 蓝字（`.btn--primary` 与 `.btn--ghost` 统一成同一张脸）
       ⇒ 页面右上角的真 CTA 重新成为"全页最重的按钮"
     · **图标·辅助类**（变更日志/编辑/更多/成本类目）→ 中性灰，hover 变蓝
     · **图标·业务类**（确认锁定/解锁/成本校验/完成/作废/复制）→ 品牌蓝
       （⚠️ 只给"动作"上色，一列里**有色的就是能改变数据状态的**，扫一眼就能找到）
     · **图标·危险类**（删除）→ 红（含比价页漏网的 `.pc-del`）

   ⚠️⚠️ 为什么用「`.table td` 后代」做判据而不是给按钮加新类名：
     操作列在全站是 **13 个页面各写一份**渲染函数（本项目刻意不复用，见 AGENTS.md），
     逐个改类名 = 改 13 个文件 + 以后新页面必然漏。而**"在表格单元格里"是稳定判据** ——
     真机普查确认：全站 14 张表**只有末列（操作列）的 td 里有按钮**，非末列一处都没有。
   ⚠️ 特异性说明：`.table td .btn--ghost`(0,2,1) 高于 `.table .icon-btn[data-edit]`(0,3,0)？
     不是 —— 类/属性数前者是 2、后者是 3 ⇒ 后者更高。故下面"辅助类"那条必须写足
     `.table td .icon-btn[data-x]`(0,3,1) 才能盖住既有规则。已逐条对齐。
   ⚠️ 内联 `style="color:..."` 会盖过本段所有规则 —— 排期页的锁定/解锁按钮原来带内联色，
      已**同步从 JS 里删掉**（见 schedule-list.js 同批改动），此处才管得住。
   ══════════════════════════════════════════════════════════════════════════════ */

/* ⓪ 相邻的**文字按钮**之间必须补足间距（2026-09-26 乐哥：「按钮也粘一起了」）
   ──────────────────────────────────────────────────────────────────────────
   背景：全站 32 处操作列的容器都写着内联 `style="gap:2px"` —— 那是为**图标按钮**定的
        （16px 图标 + 2px 间距 = 紧凑的一排，像一组）。但操作列里还有**文字按钮**
        （用户管理的「改角色」「改部门」、报销后台的「详情」、达人结算的「登记回款」…），
        两段文字之间只隔 2px ⇒ **读起来是糊成一坨**，且两段文字的边界看不清。
   实测（/settings/user-management）：`.btn--ghost` ↔ `.btn--ghost` 的间距 = **2px**。
   ✅ 修法：只在"**前一个也是文字按钮**"时补 6px（合计 8px）。
      ⚠️ 用 `.btn + .btn` 而不是 `td > .toolbar > * + *`：
         后者会把图标按钮也撑开（图标排布就该紧凑），破坏上面那条"紧凑一排"的设计。
      ⚠️ 图标按钮的类名是 `.icon-btn`、**不含 `.btn`**，所以 `.btn + .btn` 精确命中
         "文字按钮紧跟文字按钮"，零副作用。
      ⚠️ 用 margin 而不是改裸的 gap：gap 写在 JS 的内联样式里（32 处），
         改 CSS 压不住内联；margin 则能正常叠加在 gap 之上。 */
.table td > .toolbar > .btn + .btn {
  margin-left: 6px;
}

/* ① 业务文字按钮：蓝实心 / 灰描边 → **软蓝**（统一的"行内次级动作"脸） */
.table td .btn--primary,
.table td .btn--ghost {
  background: var(--button-soft-bg);
  background-image: none;                /* 清掉主按钮的品牌渐变（它是"页面级 CTA"的语言） */
  color: var(--button-soft-fg);
  border-color: transparent;
  font-weight: var(--font-weight-semibold);
}
.table td .btn--primary:hover:not(:disabled),
.table td .btn--ghost:hover:not(:disabled) {
  background: var(--button-soft-bg-hover);
  color: var(--button-soft-fg);
}
/* ⚠️ 保活 `.btn--ghost[data-del]`（红字删除）—— 它在操作列里是危险动作，不能被软蓝盖掉。
   特异性：本条 (0,3,1) > 上面 (0,2,1) ⇒ 生效。 */
.table td .btn--ghost[data-del] {
  background: transparent;
  color: var(--color-danger);
}
.table td .btn--ghost[data-del]:hover:not(:disabled) {
  background: var(--color-danger-bg);
  color: var(--color-danger);
}

/* ② 图标·辅助类（变更日志 / 编辑 / 更多操作 / 成本类目）→ 中性灰 */
.table td .icon-btn[data-log],
.table td .icon-btn[data-edit],
.table td .icon-btn[data-edit-live],
.table td .icon-btn[data-ops],
.table td .icon-btn[data-allocate] {
  color: var(--color-muted);
}
.table td .icon-btn[data-log]:hover,
.table td .icon-btn[data-edit]:hover,
.table td .icon-btn[data-edit-live]:hover,
.table td .icon-btn[data-ops]:hover,
.table td .icon-btn[data-allocate]:hover {
  color: var(--color-accent-text);
  background: var(--color-primary-100);
}

/* ③ 图标·业务类（确认锁定 / 解锁 / 成本校验 / 完成 / 作废 / 复制）→ 品牌蓝
   （"有色的就是能改变数据状态的"，与辅助灰形成可扫读的区分） */
.table td .icon-btn[data-lock],
.table td .icon-btn[data-unlock],
.table td .icon-btn[data-confirm],
.table td .icon-btn[data-check],
.table td .icon-btn[data-finish],
.table td .icon-btn[data-void],
.table td .icon-btn[data-copy] {
  color: var(--color-accent-text);
}
.table td .icon-btn[data-lock]:hover,
.table td .icon-btn[data-unlock]:hover,
.table td .icon-btn[data-confirm]:hover,
.table td .icon-btn[data-check]:hover,
.table td .icon-btn[data-finish]:hover,
.table td .icon-btn[data-void]:hover,
.table td .icon-btn[data-copy]:hover {
  color: var(--color-accent-hover);
  background: var(--color-primary-100);
}

/* ④ 图标·危险类（删除）→ 红
   ⚠️ 含机制比价页的 `.pc-del` / `.pc-rec-del` —— 它们原先**漏配了语义色**，
      用的是默认深灰，与其它页真正的"删除红"不一致（同一个动作两种颜色）。
   ⚠️ `.table .icon-btn[data-del]` 的基础规则已存在（components.css），
      此处只补这两条漏网的类。 */
.table td .icon-btn.pc-del,
.table td .icon-btn.pc-rec-del {
  color: var(--color-danger);
}
.table td .icon-btn.pc-del:hover,
.table td .icon-btn.pc-rec-del:hover {
  color: var(--color-danger);
  background: var(--color-danger-bg);
}

/* ⑤ 图标尺寸统一 16px（原 14/15/16 三种混用）
   ⚠️ 用 `svg` 后代选择器把**渲染尺寸**钉住，不依赖各页面 `I.icon(x, n)` 传的 n ——
      否则"改了 CSS 却还有页面是 14px"（因为 svg 自带 width/height 属性）。
      这样即使某个页面漏改 JS 的尺寸参数，视觉也一致。 */
.table td .icon-btn > svg,
.table td .btn > svg {
  width: 16px;
  height: 16px;
}

/* ══ 二级明细页：内容区统一为「白底卡片」（2026-09-14 乐哥：「有的有底色，有的没底色，统一下」）
   ══════════════════════════════════════════════════════════════════════════════
   实测三张明细页**三种底色**（逐页采样）：
     · 结算明细     `.st-drill`  → **#F5F6F8**（页面灰底）
     · 提成明细     `.co-expand` → **#FAFBFC**（surface-2）
     · 华大对账明细 `.hs-drill`  → **透明**（露出的其实是页面灰底）
   三种底、三张皮 → 乐哥说"乱七八糟"完全准确。

   根因是**类名复用**：`.st-drill`（pages.css:2507）/`.co-expand`（pages.css:2486）/
     `.hs-drill`（pages.css:3149）本来是**列表页「行内展开面板」**的样式
     （注释都写着"用底色把展开明细与主表分层"），被明细页拿去当"明细区容器"用了
     → 于是各自继承了一身不同的"展开面板皮"。

   ⚠️ 注意 `.hs-drill` 那条：今天早些时候已为它做过一次"去灰底"
      （pages.css:3158 `.detail-drill .hs-drill { background: transparent }`），
      当时的注释写「transparent 露出白卡片」——**但那时并没有白卡片**，
      所以实际露出的是页面灰底，等于只做了一半（灰底没了、卡片也没补上）。
      本次把这一半补完。

   解法：在**明细页容器 `#dt-body`** 作用域内，把三个内容容器统一成白卡
     （与列表页 `.card` 同规格：白底 + 1px 边框 + 12px 圆角）。
     → 全站只剩「灰底页面 + 白卡内容」一种层次，与列表页同构。

   ⚠️ 为什么用 `#dt-body`（ID 选择器）而不是 `.detail-drill`：
      ① `.detail-drill` 只被结算/华大两页使用，**提成明细用的是 `#dt-commission`**，
         用它做作用域会漏掉提成明细；
         而 `#dt-body` 是 detail.js 的 `setBody()` 统一注入点，**三页都经过它**，是可靠判据。
      ② 已有的 `.detail-drill .hs-drill` 规则特异性是 (0,2,0)，
         普通类选择器（如 `.detail-drill > *:not(...)`）压不过它 —— 第一版就这么输了，
         实测 `.hs-drill` 一直保持透明。ID 选择器 (1,0,0) 稳定胜出。
   ⚠️ 必须清掉 `position: sticky`：`.st-drill` 在 ≥1024px 有 sticky
      （pages.css:2526，给展开面板横向滚动钉左用），明细页没有横向滚动容器。 */
#dt-body .st-drill,
#dt-body .hs-drill,
#dt-body .co-expand {
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-top: 1px solid var(--color-border-soft);   /* 覆盖展开面板那条 2px 上边界 */
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  position: static;
}
/* 白卡内的表格不再重复铺底（含已被旧规则设过灰底的 `.hs-drill .table--sub`） */
#dt-body .table-wrap,
#dt-body .hs-drill .table--sub {
  background: transparent;
}

/* ══ 二级明细页的表格：用「正文规格」而不是「子表规格」（2026-09-14）
   ══════════════════════════════════════════════════════════════════════════════
   乐哥：「达人结算里的结算明细，二级页面和其他地方的二级页面表格界面不一样，看下怎么处理」

   实测（12 页普查 · probe-table-density.js）：**全站正文基准 = 14px / 上下内边距 12px**，
     · 主列表页 6 页**全部一致**（达人列表/货品/库存/订单/排期/达人售后）
     · 结算明细 14px ✓ 12px ✓   提成明细 14px ✓ 12px ✓   ← 两者本就合规
     · **华大对账明细 12px ✗ 8px ✗**                       ← 唯一不合规的
   → 所以「不一样」的是**华大对账明细**，不是结算明细（此处先前的判断方向相反，已更正）。

   根因仍是**类名复用**：`.table--sub` 的规格（components.css:1308）本是给
     **「嵌套在主表里的子表」**用的 —— 8px 内边距 + 12px 字号（子表该比主表小一号）。
     华大对账明细把它拿来当**主表**（huada-settlement.js:484/492），于是整表偏小偏紧。

   解法：只在**二级明细页作用域**（`#dt-body`）内，把 `.table--sub` 提回正文规格：
     表格字号 12→14px、**数据行**上下内边距 8→12px。
     ⚠️ **表头完全不动**（字号仍 12px、上下内边距仍 8px）——
        全站表头标准就是「12px 字 + 44px 高」，这是一条独立的标准线。
        第一版顺手给 th 也加了 12px 上下内边距，实测把表头从 **44px 撑到 59px**
        → 被 `probe-table-standard.js` 的 ① 抓出（"表头 59px ≠ 44px"）。
     ⚠️ **副文本（.cell-sub 等）不动**（保持 12px）—— 它们是显式声明，属"主 14 + 副 12"的正常层级。
     ⚠️ 列表页展开区的 `.table--sub` **不受影响** —— 那里它就是子表，8px/12px 是对的。
        这就是限定 `#dt-body` 作用域的原因。 */
#dt-body .table--sub {
  font-size: var(--font-size-sm);
}
/* ⚠️ 必须显式把表头字号钉回 12px：上一条 (1,0,1) 的特异性高于
   `.table--sub th` (0,1,1)，不钉会被一起改成 14px、破坏表头标准。 */
#dt-body .table--sub > thead > tr > th {
  font-size: var(--font-size-xs);
}
/* 只提**数据行**的上下内边距（表头保持原 8px，见上） */
#dt-body .table--sub > tbody > tr > td {
  padding-top: var(--space-3);
  padding-bottom: var(--space-3);
  font-size: var(--font-size-sm);
}

/* ── 「轻量形态」：只有单一月份控件的页面（2026-09-14 乐哥选 B 方案）──────────────
   乐哥选 **B（按需）**：「有筛选就套标准工具栏；**只有"月份"这种单一控件的，
   就让它和白卡贴合、控件 34px，不再包一层工具栏**」。

   覆盖：华大对账 / 成本总览（只有月份选择器）、我的提成（月份 + 重置）。
   做法：**不铺白底、不描边** —— 就是内容上方一行轻量控件，
        避免"为了统一而多出一层空壳"（那样反而更乱）。
   ⚠️ 与 `.toolbar--join-card`（铺白底 + 上圆角、与下方卡片拼成一体）是**两种形态**，
      由 JS 按"筛选控件是否只有一个且为月份"自动判定，不手工指定。
   ⚠️ 必须自己带 34px 规则：我的提成页**没有表格**（不满足 `.toolbar--list` 的前置条件），
      不声明的话它的月份选择器仍是 44px（实测跨页不一致）。 */
.toolbar--plain {
  margin: 0 0 var(--space-3);      /* 与下方内容贴合（不是飘着的独立工具栏） */
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
}
.toolbar--plain .select,
.toolbar--plain .input,
.toolbar--plain .mp__trigger,
.toolbar--plain > .input--search > .input,
.toolbar--plain .btn {
  height: var(--control-height-sm);
  min-height: var(--control-height-sm);
}

/* ── 售后页「口径说明行」里的筛选下拉也要 34px（2026-09-14）──────────────────────
   达人售后 / 商品售后 的月份与店铺下拉长在 `.an-flex-between`（口径说明行）里，
   用的是原生 select + `.input` 类，**不在任何 `.toolbar` 内**，
   所以 `.toolbar--list` 那条规则覆盖不到 → 实测它们一直是 44px。
   ⚠️ 只改高度、不动位置 —— 「筛选控件与口径说明混排」是另一个话题
      （要动 DOM 结构，风险更高），本轮的诉求是"标准统一"，先把尺寸对齐。 */
.an-flex-between select.input,
.an-flex-between .input {
  height: var(--control-height-sm);
  min-height: var(--control-height-sm);
}

/* ── 订单明细主表：把宽度让给「商品」列（2026-09-14 乐哥：「列表超出了页面的边界，需要左右拖动」）
   ─────────────────────────────────────────────────────────────────────────────
   问题：`table-layout: auto` 下所有列都参与"分配剩余宽度"，商品名列虽是弹性列却没优先权，
        实测「达人」列被压到 **48px**（"坚强的糖豆" 折成 3 行）、商品列只剩 89px（长名折 4~5 行），
        而整表仍溢出容器 25~209px（要横向拖）。
   修法（与 `.sdo-sumtbl` 同一套，见 pages.css）：
        **除「商品」列以外的所有列锁死单行**（`nowrap`）→ 它们的 min-content == max-content，
        浏览器压不动它们，只能把富余宽度全部让给唯一还能换行的商品列。
   ⚠️ 用 `:not(:nth-child(4))` 定位商品列 —— 列序：①勾选 ②订单号 ③达人 **④商品**
       ⑤收款 ⑥退款 ⑦净额 ⑧归属 ⑨备注 ⑩操作。
       ⚠️ 勾选列在多选模式下才出现，但它固定在**第一位**，商品列始终是第 4 个 → 定位稳定。
   ⚠️ 表头不用管：全站 `.table thead th` 本来就是 `nowrap`（本文件 27 行）。
   ⚠️ 新开作用域类、**不动** `.is-num` / `.num` 等公共类 —— 它们全站几十张表在用。 */
.so-detail-tbl tbody td:not(:nth-child(4)) {
  white-space: nowrap;
}
/* 商品列是唯一可换行列 → 限宽 + 裁剪，超长名折 2 行内 */
.so-detail-tbl tbody td:nth-child(4) {
  max-width: 320px;
  overflow: hidden;
}

/* 展开行内的子表（达人明细），更轻盈：字体小一号 */
.table--sub {
  font-size: var(--font-size-xs);
  table-layout: fixed;
}
/* ⚠️ 2026-09-14 乐哥拍板「所有列表统一标准」：子表表头**不再单独一套皮**。
   改前 `.table--sub thead th` 是 `transparent 底 + 28px 高 + muted 字`，
   而主表 `.table thead th` 是 `浅灰底 + 44px 高 + 12px 字` —— 两套皮并存，
   表现为「二级明细页（华大/结算）的表头比一级列表矮一截、还没有底色」，
   乐哥反馈「列头的高度和颜色，很多表格都不一致」说的就是它。
   （`table--sub` 在本项目既用在真嵌套子表、也用在二级页的顶层表上，语义已漂移 ——
    这是同一个坑的第三张脸，前两张分别是首末列留白与灰色底。）
   现改为**只保留 position: static**（子表在自己的容器内，不需要 sticky 表头），
   背景/高度/字色/字号全部继承主表 → 全站表头收敛为一种。 */
.table--sub thead th {
  position: static;
}
/* ── 列间竖线：**只在大类边界**（2026-09-14 乐哥二次修正 + 参考微信小店）
   ─────────────────────────────────────────────────────────────────────────
   乐哥原话：「也不用所有表格都加竖线，我觉得微信小店这种，大类加竖线的就很好」

   改前（v1，同一天早先版本）：`td + td` 给**每一列之间**都加线 —— 太密。
   微信小店实测（像素级分析三张参考图）：
     · 订单表只有 **2 条**竖线，位置是把「实收款/优惠信息」这个独立信息组夹在中间；
     · 商品表 / 带货者表是 **0 条**（那些表没有需要分隔的信息组）；
     · 线色 rgb(229,229,229)=#E5E5E5，1px，**贯穿表头 + 全部数据行**。
   → 结论：竖线是**大类分隔**，不是列分隔。

   现行规则（由 app.js 的 `UI.markColumnGroups()` 打标，CSS 只负责画）：
     只在「第一个数值列之前」和「最后一个数值列之后」各画一条，**每表最多 2 条**。
     数值列用既有的 `.is-num` 判定（该类的含义就是"数值列"，全站 13/14 张表覆盖一致）。
   好处：
     · 一张表内最多 2 条 → 不会变密；
     · 没有数值列的表（如达人列表）自动 0 条 → 与微信小店的商品表同理；
     · 复用 is-num，不新增维护点（新增列时只要正常标 is-num 就自动获得正确分组）。

   ⚠️ 为什么用 **box-shadow: inset** 而不用 `border-left`：
      项目已有若干**语义竖线** —— `st-col-fcast`（提成总览「应发星盟」分组线）、
      `st-drill-pendrow`（未满 35 天行左侧虚线）、`st-col-payable/fcasthead` 等。
      `border-left` 与它们是**同一个属性**，本类优先级更高会把语义线整条覆盖掉 ——
      线还在、但含义变了，极难排查。box-shadow 与 border 是两个独立属性，可叠加共存。
      另外 inset 阴影**不占布局宽度**：用 border 的话 12 列表会多 12px，
      而结算明细 10 列本就贴着容器下限（再窄 53px 就横滚）。 */
.table .col-sep,
.table--sub .col-sep {
  box-shadow: inset 1px 0 0 var(--color-border-soft);
}
/* 订单业绩天维度：主表固定布局 + colgroup 固定数字列宽，与展开子表精确对齐 */
.so-table--fixed {
  table-layout: fixed;
}
/* 展开子表所在的单元格去掉内边距，让子表左边界与主表对齐（上下间距由 .so-expand 提供） */
.table tbody td.so-expand-cell {
  padding: 0;
}
/* ⚠️ 2026-09-14 删除：此处原有 `.table--sub thead th { background: transparent;
   color: muted; height: 28px; ... }` —— 与 `.table thead th`（浅灰底/44px）并存的第二套皮，
   就是「二级页表头矮一截、没底色」的根源。已并入上方统一规则（只留 position: static）。 */
.table--sub tbody tr:hover {
  background: transparent;
}
.table--sub tbody td {
  padding-top: var(--space-2);
  padding-bottom: var(--space-2);
}
/* 子表数字不加粗（与主表数字列视觉一致） */
.table--sub .is-num {
  font-weight: normal;
}
/* 子表达人列自适应宽度（数字列用 colgroup 固定宽度与主表对齐，达人列吃剩余空间） */
.table--sub .sub-influencer {
  min-width: 0;
  overflow: hidden;
}
/* 天维度展开子表：未匹配达人整行标灰 */
.table--sub tbody tr.so-unmatched {
  background: var(--color-gray-50);
}
.table--sub tbody tr.so-unmatched:hover {
  background: var(--color-gray-50);
}
/* 天维度展开子表：底部当日小计行 */
.table--sub tbody tr.so-subtotal {
  border-top: 1px solid var(--table-divider);
  background: var(--color-surface);
  font-weight: var(--font-weight-medium);
}
.table--sub tbody tr.so-subtotal td {
  font-weight: var(--font-weight-medium);
  color: var(--color-fg);
}

/* ⭐ 2026-09-25：**非子表**的「交叉表合计行」独立定义。
   ⛔⛔ 这条是补一个**隐藏依赖**（删斑马纹时暴露出来的）：
      `.so-subtotal` 共 3 处使用 ——
        · `pages/aftersale.js`（售后分析交叉表）、`pages/analytics.js`（经营看板）
          → 这两处的表是普通 `.table`（售后分析还带 `.table--zebra`），**不在 `.table--sub` 内**
        · `pages/shop-orders-shared.js`（天维度展开子表）→ 在 `.table--sub` 内
      而 `.so-subtotal` 原本只有两个来源：① 上面那条 `.table--sub` 的（只管子表）；
      ② `pages.css` 里 `.table--zebra tbody tr.so-subtotal`（管非子表）。
      ⇒ 删掉斑马纹把 ② 一起删了，结果**非子表的合计行失去了唯一底色**（手工 A/B 实测：
        `rgb(250,251,252)` → 透明）。本条就是把 ② 的职责**独立化**，不再挂在斑马纹上。
   ⚠️ 特异性 (0,1,2) **低于**上面的 `.table--sub tbody tr.so-subtotal` (0,2,2)
      ⇒ 子表仍走 `--color-surface`，非子表走 `--color-surface-2`，两者互不干扰（这是有意的：
        子表嵌在展开行里、底色已由展开区提供，只需极淡的区分）。 */
.table tbody tr.so-subtotal {
  background: var(--color-surface-2);
}

/* ---- 骨架屏 ---- */
.skeleton {
  background: linear-gradient(
    90deg,
    var(--color-surface-2) 25%,
    var(--color-border-soft) 50%,
    var(--color-surface-2) 75%
  );
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.4s ease infinite;
  border-radius: var(--radius-sm);
}

@keyframes skeleton-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.skeleton-table-row {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-3);
  border-bottom: 1px solid var(--table-divider);
  align-items: center;
}

.skeleton-line {
  height: 14px;
  border-radius: var(--radius-sm);
}

/* 「保留表头的加载态」（2026-09-18，乐哥「切 tab 向右移动然后闪一下」）
   --------------------------------------------------------------------------
   切 tab 时不再把整张表换成灰条，而是保留表头、只把表体换成这些 `.is-loading-row` 行
   （实现见 ui.js 的 skeletonInto）。
   ⇒ 表头不消失、列宽不重算 → 切换瞬间页面结构与位置完全不变，看不到"闪"与错位。
   这些行不可交互（不是真实数据），所以去掉 hover 高亮与手型光标。 */
.table tbody tr.is-loading-row,
.table--sub tbody tr.is-loading-row {
  cursor: default;
}
.table tbody tr.is-loading-row:hover,
.table--sub tbody tr.is-loading-row:hover {
  background: transparent;
}
.table tbody tr.is-loading-row > td {
  padding-top: var(--space-3);
  padding-bottom: var(--space-3);
}
/* 灰线放在单元格内：垂直居中，横向留出一点边距（避免贴住列线） */
.table tbody tr.is-loading-row .skeleton-line {
  margin: 0 auto;
  max-width: 88%;
}

/* ---- 空态 / 错误态 ---- */
.state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-12) var(--space-6);
  gap: var(--space-3);
}

.state__icon {
  width: 48px;
  height: 48px;
  border-radius: var(--radius-lg);
  background: var(--color-surface-2);
  color: var(--color-muted);
  display: flex;
  align-items: center;
  justify-content: center;
}

.state__title {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-medium);
  color: var(--color-fg);
}

.state__desc {
  font-size: var(--font-size-sm);
  color: var(--color-muted);
  max-width: 42ch;
}

/* 空状态下"换个范围就有结果"的出口（如：当前月份没有，但全部月份有 N 条） */
.state__hint {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px dashed var(--color-border);
  font-size: var(--font-size-sm);
  color: var(--color-fg-2);
}
.state__hint-link {
  color: var(--color-accent);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
}
.state__hint-link:hover { text-decoration: underline; }

/* ---- 搜索范围提示：有月份筛选时，在搜索框下方说明"搜索被限制在哪个月" ----
   ⚠️ 2026-09-14 乐哥：「这些页面我选了月份后，工具栏和下面的内容栏隔开了」
   ────────────────────────────────────────────────────────────────────────
   根因（两层叠加，缺一不可）：
     ① 本类原先 `margin: -8px 0 **12px**` —— 下边距 12px 直接把"工具栏 → 内容"顶开；
     ② app.js 的 `markToolbarJoin` 用**几何判据**决定"工具栏是否与卡片拼成一体"：
        `gap = card.top - toolbar.bottom; if (gap > 24) 不合并`。
        而本提示行隐藏时高 0px（不在判据里），**显示后高 19px + 12px 下边距 = 31px**
        → 恰好越过 24px 阈值 → 工具栏与卡片**不再拼成一体**，视觉上断开一道缝。
   修法：**让提示行在视觉上归属工具栏**（成为它的"第二行"），而不是独立夹在中间：
     · 下边距 12px → 0（不再顶开内容）
     · 补上工具栏的白底 + 左右边框（上边不加，与工具栏相接；下边不加，与卡片相接）
       → 工具栏(白·上圆角) + 提示行(白·左右边框) + 卡片(白·下圆角) 三者连成一体，缝消失
     · 左右内边距对齐工具栏的 --space-5（20px），文字与上面控件左对齐
   ⚠️ 只在「紧跟已合并工具栏」时套这套皮（`.toolbar--join-card + .kw-scope`）——
      其余页面（工具栏没参与合并的）保持原来的轻量样式，避免无谓改动。 */
.kw-scope {
  margin: calc(var(--space-2) * -1) 0 var(--space-3);
  font-size: var(--font-size-xs);
  color: var(--color-fg-2);
  line-height: 1.6;
}
.kw-scope:empty { display: none; }
/* 提示行与工具栏相邻时，只清**提示行自己**的边距，让它贴住工具栏。
   ⛔⛔ 2026-09-26 修（乐哥实报「部分页面工具栏和列表粘一起了」）——
      原来写的是 `.toolbar + .kw-scope, .kw-scope + .toolbar { margin: 0; }`。
      后半个选择器 `.kw-scope + .toolbar` 命中的是**工具栏自己**，于是把 `.toolbar`
      的 `margin-bottom: var(--space-4)`（16px，"工具栏 ↔ 下方表格卡"的缝）**清成了 0**。
      而且它是 (0,2,0) 特异性 —— **压得过** `.toolbar--join-card`（(0,1,0)）的 margin-bottom，
      所以 CSS 加载顺序也救不回来。
      ⇒ 后果：凡是"提示行紧邻工具栏"的页面，工具栏与下方表格卡**完全贴死**（实测 gap=0px）；
        没有提示行的页面正常（gap=16px）—— 所以只有**部分**页面出问题。
        实测受影响：排期列表 / 费用明细 / 样品发放 / 订单明细（都是 gap=0）。
      ✅ 正确做法：**谁的边距该清，就写在谁身上**，绝不在"相邻选择器"里顺手清别人的。
         · 提示行在工具栏**上方**（`.kw-scope + .toolbar` 这种结构，见 ui.js 的 ensureTip）
           ⇒ 清提示行的 `margin-bottom`（用 :has 表达"我后面跟着工具栏"）
         · 提示行在工具栏**下方**（`.toolbar + .kw-scope`）
           ⇒ 清提示行的 `margin-top`（同时保留下边距，它还要与下方内容留缝）
      ⚠️ `.kw-scope:empty` 是 display:none 但**仍在 DOM 里**，所以 `+ .toolbar` 依然会命中 ——
         "空元素不占位所以无所谓"是错觉，这正是本 bug 能藏这么久的原因。 */
/* 两条都只清**提示行自己**的边距 —— 选择器命中谁，就只动谁。
   ⛔ 不要再写任何"命中 .toolbar"的相邻选择器（那正是本 bug 的形态）。 */
.toolbar + .kw-scope { margin-top: 0; }              /* 提示行在工具栏**下方**：清它的上边距 */
.kw-scope:has(+ .toolbar) { margin-bottom: 0; }      /* 提示行在工具栏**上方**：清它的下边距 */
.kw-scope {
  padding: 0 var(--space-5) var(--space-2);
}
.kw-scope b { color: var(--color-accent); font-weight: var(--font-weight-semibold); }
.kw-scope__sep { margin: 0 6px; color: var(--color-fg-3); }
.kw-scope__link { color: var(--color-accent); cursor: pointer; }
.kw-scope__link:hover { text-decoration: underline; }

/* ---- 表格卡片顶部筛选条（左：二级 tab / 右：总数 + 每页条数） ---- */
.table-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-5);
  border-bottom: 1px solid var(--color-border-soft);
}

.table-toolbar__right {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-left: auto;
}

.table-toolbar__total {
  font-size: var(--font-size-xs);
  color: var(--color-meta);
  white-space: nowrap;
  /* 定最小宽度 + 靠右（2026-09-18，乐哥「切 tab 工具组会跳」）
     ------------------------------------------------------------------
     它是工具组里最靠左的一项，而工具组**右对齐** → 本行文字一变长/变短，
     整组的左边缘就跟着移动。实测切 tab 时的位移：
       样品发放「共 40 条发放记录」→「共 32 位达人」：91→67px（组左移 **24px**）
       订单明细「共 6,375 条订单」→「共 0 条订单」  ：83→60px（**23px**）
       业绩总表 78→70px（8px） / 达人列表 73→67px（6px）
     给定最小宽度后，短文案不再让整组回缩；文字靠右贴住右侧下拉，观感不变。 */
  min-width: 100px;
  text-align: right;
}

/* ---- 分页（左：范围统计 / 右：页码分页器） ---- */
.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--color-border-soft);
  font-size: var(--font-size-sm);
  color: var(--color-muted);
}

.pagination__info {
  font-feature-settings: "tnum", "lnum";
  font-variant-numeric: tabular-nums;
  font-size: var(--font-size-xs);
  color: var(--color-meta);
}

.pagination__controls {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.pagination__page {
  min-width: 28px;
  height: var(--control-height-sm);   /* 两档制：28 → 34（紧凑档，与同排控件齐平） */
  padding: 0 6px;
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-fg-2);
  font-size: var(--font-size-sm);
  font-feature-settings: "tnum", "lnum";
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background var(--motion-fast) var(--motion-ease-standard),
    color var(--motion-fast) var(--motion-ease-standard);
}
.pagination__page:hover {
  background: var(--color-surface-2);
}
.pagination__page.is-current {
  background: var(--color-accent);       /* 当前页主色实底 */
  color: var(--color-accent-on);
  font-weight: var(--font-weight-medium);
}

.pagination__nav {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: var(--control-height-sm);   /* 两档制：28 → 34（紧凑档，与同排控件齐平） */
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-fg-2);
  cursor: pointer;
  transition: color var(--motion-fast) var(--motion-ease-standard),
    border-color var(--motion-fast) var(--motion-ease-standard);
}
.pagination__nav:hover:not(:disabled) {
  color: var(--color-accent-text);
  border-color: var(--color-accent);
}
.pagination__nav:disabled {
  color: var(--color-disabled);
  cursor: not-allowed;
}

.pagination__ellipsis {
  min-width: 20px;
  text-align: center;
  color: var(--color-meta);
}

.pagination__size {
  width: auto;
  height: var(--control-height-sm);   /* 两档制：28 → 34（紧凑档，与同排控件齐平） */
  padding: 0 26px 0 10px;
  margin-right: var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-fg-2);
  border-radius: var(--radius-md);
  background-position: right 8px center;
}

/* 页码跳转输入：与页码按钮同高、描边一致 */
.pagination__jump {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-muted);
  white-space: nowrap;
}

.pagination__input {
  width: 48px;
  height: var(--control-height-sm);   /* 两档制：28 → 34（紧凑档，与同排控件齐平） */
  padding: 0 6px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-fg);
  font-size: var(--font-size-sm);
  font-family: inherit;
  text-align: center;
  outline: none;
  transition: border-color var(--motion-fast) var(--motion-ease-standard);
}
.pagination__input:focus {
  border-color: var(--color-accent);
}
.pagination__input::-webkit-outer-spin-button,
.pagination__input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* ---- 移动端：表格触控滚动 + 分页简化 ---- */
@media (max-width: 768px) {
  .table-wrap {
    -webkit-overflow-scrolling: touch;   /* iOS 惯性滚动 */
    overscroll-behavior-x: contain;
  }
  .pagination {
    flex-wrap: wrap;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
  }
  .pagination__info {
    order: 2;                            /* 统计文案换到操作下方 */
    flex-basis: 100%;
    font-size: var(--font-size-xs);
    color: var(--color-meta);
  }
  .pagination__controls {
    flex-wrap: wrap;
    row-gap: var(--space-2);
  }
}

/* ==========================================================================
   可跳转单元格链接（.cell-link）—— 2026-09-13 补齐
   ---------------------------------------------------------------------------
   ⚠️ 原来**全站没有定义** .cell-link，而 base.css 里有 `a { color: inherit }`
      → 排期编号/场次编号这类可跳转内容显示为**普通深色文字**，
      用户完全看不出能点（乐哥 2026-09-13 反馈）。
   统一为主色蓝：一眼可辨"这里能跳"，hover 加下划线强化可点感。
   ========================================================================== */
.cell-link {
  color: var(--color-primary-500);
  text-decoration: none;
  cursor: pointer;
  transition: color var(--motion-fast) var(--motion-ease-standard);
}
.cell-link:hover {
  color: var(--color-primary-600);
  text-decoration: underline;
}
.cell-link:active { color: var(--color-primary-700); }

/* ==========================================================================
   密集表（列很多的宽表）：**减小水平内边距**，把宽度让给内容
   --------------------------------------------------------------------------
   背景（乐哥 2026-09-13「整体排查表格 ui 问题」）：全站巡检发现两张表超出容器、
   需要左右拖才能看到右侧列（「操作」「预估应结」被推出可视区）：
     · 人员成本  1633px > 容器 1374px（需横滚 259px）
     · 达人结算  1642px > 容器 1374px（需横滚 268px）
   这两张表都是 **16 列**，而列宽下限由「表头文字（nowrap 不可折）」与「内容宽度」共同决定
   （实测：达人结算各金额列内容最宽仅 81px，但表头「截止目前应结」就要 84px）。
   在不动信息、不缩字号、不折行的前提下，唯一可榨的空间就是**列内边距**：
   默认 `0 var(--space-3)` = 左右各 12px，16 列共占 384px；收到 4px 可省 256px
   （实测：5px 时「达人结算」自然宽度 1384px，仍比容器 1374px 多 10px；4px 后 1352px 达标）。

   ⚠️ 为什么新开一个类、而不是改 `.table thead th` 的默认 padding：
   那是全站 33 张表共用的基础规则（本项目铁律：改公共样式前先查复用范围）。
   这里只给「确实需要省宽度」的宽表加类，其余表保持原有舒适间距。
   ========================================================================== */
.table--dense thead th,
.table--dense tbody td {
  padding-left: 4px;
  padding-right: 4px;
}
/* 密集表里「操作」列的按钮组本来靠 gap 撑开，同步收一点，避免按钮贴边 */
.table--dense tbody td .toolbar { gap: 2px; }

/* ══ tfoot 单元格的 padding 必须**独立声明**（2026-09-14 乐哥：「下面求和这个，行高好窄」）
   ──────────────────────────────────────────────────────────────────────────────────
   根因：本项目表格单元格的 padding 只有一条规则 —— `.table tbody td { padding: 12px }`（本文件 93 行），
       它**只作用于 tbody**。而 `tfoot` 是**独立的行组**，thead/tbody 的规则一律覆盖不到它
       （pages.css:3167 的注释早已点明这一点）。
   实测后果（修复前）：
     · 普通表 tfoot  → padding **0px**、行高 **22px**（数据行 68~130px、表头 44px）→ 一条被压扁的窄条
     · `.table--sub` tfoot → padding 8px，而它的 tbody 是 12px → 同表内也不一致
   影响面：全站 **7 个页面**的 tfoot 合计行（华大对账 `.cm-foot-row`、提成总览、排期明细、
          订单明细、费用类、粉丝体验装…），都是这个毛病 —— 不是单个页面的问题。
   做法：在 tfoot 层**统一**补齐，规格与 tbody 完全对齐（12px 基础 + 首末列 20px）。
        这样无论合计行叫什么类名（`.is-sum` / `.cm-foot-row` / `.hs-drill__sum-row`）都自动生效，
        新增合计行也不会再漏。
   ⚠️ 排除密集表 `.table--dense`（它的 thead/tbody 左右只有 4px，单独给它一条规则），
      排除嵌套在单元格里的子表（`:where(td .table)`）。
   ⚠️ 不要用 `.table tbody td, .table tfoot td` 合并写法 —— 那会把 `border-bottom` /
      `vertical-align` 等 tbody 专有属性也带给 tfoot，影响合计行的既有视觉。只补 padding。 */
.table:not(.table--dense):not(:where(td .table)) > tfoot > tr > td {
  padding: var(--space-3);
}
.table:not(.table--dense):not(:where(td .table)) > tfoot > tr > td:first-child {
  padding-left: var(--space-5);
}
.table:not(.table--dense):not(:where(td .table)) > tfoot > tr > td:last-child {
  padding-right: var(--space-5);
}
/* 密集表：左右收窄到 4px，与它的 thead/tbody 一致（上下仍是 12px） */
.table--dense:not(:where(td .table)) > tfoot > tr > td {
  padding: var(--space-3) 4px;
}

/* ══ 表格「合计行」通用样式（2026-09-14 乐哥：「所有涉及费用的，表格上应该有一个
   地方能显示汇总，不然我们筛选出来都看不到总数」）══════════════════════════════════
   用法：`<tfoot><tr class="is-sum"><td>…</td></tr></tfoot>`
   口径 = **当前筛选条件下的全部匹配行**（不是当前页）——
     订单明细共 6,367 单而每页只显示 20 行，只算当前页的数字没有意义。
   ⚠️ 用 tfoot 而不是 tbody 尾行：tfoot 在语义上就是"表尾合计"，
      且不会被"全选/行展开"等交互误当作数据行处理。
   （内边距由上面那条 tfoot 统一规则提供，此处只管视觉区分） */
.table tfoot tr.is-sum > td,
.table tbody tr.is-sum > td {
  background: var(--color-surface-2);
  font-weight: var(--font-weight-semibold);
  color: var(--color-fg);
  border-top: 1px solid var(--color-border);
}
/* 合计行里的金额用等宽感更强的排版，方便与明细逐位核对；不换行避免金额被折行 */
.table tfoot tr.is-sum > td,
.table tbody tr.is-sum > td {
  white-space: nowrap;
}
.table tfoot tr.is-sum > td.num,
.table tbody tr.is-sum > td.num {
  font-variant-numeric: tabular-nums;
}
/* ⭐ 合计行里的盈亏格**必须保留红/绿**（2026-09-17 乐哥去掉全站金额的 `+` `-` 后暴露）
   ----------------------------------------------------------------------------
   上面的 `.table tfoot tr.is-sum > td { color: var(--color-fg) }` 特异性 (0,2,2)，
   **压过了** `.num-pos` / `.num-neg`（0,1,0）→ 合计行的盈亏一直是黑字。
   在"带 `+` 号"的年代这没问题（正负看符号），但符号去掉后：
   合计行的盈亏**既没符号也没颜色** → 看不出是赚还是亏（而它是全表最该看清的一格）。
   ⚠️ 这是本项目第 4 次被"高特异性规则盖掉语义色"咬到（pages.css 里已记过 3 次）——
      凡是用语义色表达的类，都要检查有没有被**页内更具体的选择器**压过。
   ⚠️ 只加 `td.num-pos` / `td.num-neg` 两条，**不动**其它合计行样式（底色/字重/nowrap 保持）。 */
.table tfoot tr.is-sum > td.num-pos,
.table tbody tr.is-sum > td.num-pos { color: var(--color-danger); }    /* 盈利 = 红 */
.table tfoot tr.is-sum > td.num-neg,
.table tbody tr.is-sum > td.num-neg { color: var(--color-success); }   /* 亏损 = 绿 */

/* 表格行「已单独校准」标记（2026-09-15）：暖底提示这是一行被人为改过的值。
   用途：项目团队成本「按月校准」弹窗 —— 填了金额的月份标出来，一眼看出哪几个月不是默认值。
   特异性 (0,2,2) 高于斑马纹的 (0,1,2)（后者用 :where() 压过），能稳定覆盖它。
   ⚠️ 底色只用最浅的暖色：这是"提示"不是"告警"，过重的底色会让人以为数据出错了。 */
.table tbody tr.is-custom > td {
  background: var(--color-head-on-bg);
}


/* ⭐ 2026-09-25 Gashora 骨架落地：**含表格的卡片裁切圆角**。
   背景：`.card` / `.module-card` 自身无内边距（padding:0，见 components.css），
   表头直接贴到卡片边缘 ⇒ 表头的**背景色会在卡片圆角弧线处溢出**（卡片 overflow:visible 不裁切），
   表现为"圆角被表头方角顶破"（乐哥报「表格左上角那个圆角线还没修好」）。
   修法：给含表格的卡片加 overflow:hidden，把表头背景裁进圆角内。
   ⚠️ 安全性依据（两处实测确认）：
      · 卡内下拉/选择器全是**原生 select** —— 原生下拉菜单由浏览器绘制，不受祖先 overflow 影响；
      · 卡内的浮层（若有）都是 `position: fixed` 且卡片链上无 transform/filter ⇒ 不受裁剪。
   ⚠️ 用 `:has()` 而非给所有 .card 加（会让不装表的卡片也无谓裁切，可能切到悬停浮出的提示）。 */
.card:has(.table),
.module-card:has(.table),
.table-card { overflow: hidden; }
