/* 结算周报 · 方案 A「密集终端风」+ C 版侧滑抽屉
 *
 * 视觉 token 逐条照 ui-spec-a-dense.md，交互取 C 版抽屉（用户 2026-08-21 选定）。
 * 规格 §6 原本要求「允许多行同时展开」，那是内联展开方案；抽屉替代它，
 * 展开区的内容规格（4 列 grid 算式、下沉背景、蓝色反转标记）整套搬进抽屉。
 *
 * 与生产 `style.css`（浅色品牌绿）刻意分开：那份被账号池/客户分成/报表页共用，
 * 改它会把四个页面一起拖进深色。这个文件只服务结算周报。
 */

:root {
  --bg: #0e1116;
  --pn: #161a21;
  --pn2: #1c212a;
  --ln: #272d38;

  /* ---- 文字层级：五级，步进拉开 ----------------------------------
   *
   * 旧版只有 e7eaf0 / 8b93a5 / 6b7280 / 5b6270，后三个都是灏灰且两两相差
   * 不足 20，在密集表里基本看不出差别 —— 结果是「标题/数据/说明」三类信息
   * 堆在同一个亮度层上，眼睛没有落点。现在每级至少差 28。
   */
  --tx: #f2f5fa;          /* 标题、重要数字（最亮） */
  --tx2: #d3d9e4;         /* 表格正文数据 */
  --mu: #949cad;          /* 次要标签与说明 */
  --dim: #6e7686;         /* 弱提示、单位、辅助词 */
  --foot: #565d6b;        /* 页脚（最弱） */

  /* ---- 语义色 --------------------------------------------------------
   *
   * **三元组是唯一来源，实色由它派生。** 亮色主题（`[data-theme="light"]`）只覆盖
   * 这四行三元组，下面的实色与所有 `rgba(var(--x-rgb), α)` 自动跟着变 ——
   * 两处各写一份迟早不一致，而"某个边框还留着深色主题的红"这种错不会报错。
   *
   * 透明度档位（.05 ~ .5）**两个主题共用**：它表达的是强度层级而不是颜色。
   * 深底上 `rgba(亮色, .05)` 是轻微提亮，浅底上 `rgba(深色, .05)` 是轻微压暗，
   * 方向一致，所以档位不必分主题。
   */
  --pos-rgb: 61, 220, 132;    /* 正向：此方收钱 / 采集正常 */
  --neg-rgb: 255, 107, 107;   /* 负向：此方付钱 / 不会自愈的故障 */
  --wn-rgb: 251, 191, 36;     /* 警告：会自愈 / 等待中 */
  --ac-rgb: 91, 157, 255;     /* 强调：我自己 / 方向反转 / 进行中 */

  --pos: rgb(var(--pos-rgb));
  --neg: rgb(var(--neg-rgb));
  --wn: rgb(var(--wn-rgb));
  --ac: rgb(var(--ac-rgb));

  /* 降饱和的正负。**用于信息性金额**（如用户输赢），与结算类金额拉开。
   * 理由见下面 .amt 的注释：满屏饱和色块等于没有重点。 */
  --pos-soft: #6cb894;
  --neg-soft: #cf8b8b;

  /* 色块底色。写成变量是为了让 rgba 里那串数字只出现一次。 */
  --pos-bg: rgba(var(--pos-rgb), .13);
  --neg-bg: rgba(var(--neg-rgb), .13);
  --wn-bg: rgba(var(--wn-rgb), .14);
  --ac-bg: rgba(var(--ac-rgb), .14);

  /* 遮罩与投影。亮色主题下要压低不透明度：同样的 .5 黑在浅色页面上重得多。 */
  --scrim: rgba(0, 0, 0, .5);
  --scrim-strong: rgba(0, 0, 0, .55);
  --shadow-drawer: -14px 0 40px rgba(0, 0, 0, .45);

  /* 强调色块上的文字色（蓝底白字那种）。**不是 --tx** —— 深色主题里 --tx 是浅色，
   * 而这里要的是"在饱和蓝底上可读"，两个主题下都由主题自己决定。 */
  --on-ac: #0a0d11;

  /* 规格 §2.1 的补充硬编码色。收进变量便于一处改，语义名跟着规格里的用途写。 */
  --row-ln: #1e232c;      /* 表格行底边框：比 --ln 更暗，密集表格才不显脏 */
  --row-hv: #1a1f28;      /* 行 hover */
  --kpi-sub: #6e7686;     /* KPI 第三行提示（= --dim，保留旧名字避免改一堆调用点） */
  --sink: #11141a;        /* 展开明细背景：比页面底色更深，形成下沉感 */
  --acc-ln: #2b3240;      /* 展开区账号左边框（常规） */
  --expr: #a8b0c0;        /* 算式表达式文字 */

  /* 浏览器原生部件（滚动条、下拉箭头、日期选择器）跟着主题走。
   * 不设的话亮色主题下会出现深色滚动条，最显眼的地方反而不一致。 */
  color-scheme: dark;
}

/* ---- 普通版（亮色，**默认主版本**）--------------------------------------
 *
 * 用户 2026-08-31：「整体上白色风格叫普通版，现在这个风格改成暗夜版」。
 *
 * ## 为什么用 `:not([data-theme="dark"])` 而不是 `[data-theme="light"]`
 *
 * 这样**没有 `data-theme` 属性时就是亮色**，也就是"默认主版本"的字面含义。
 * 反过来写（`:root` 亮 + `[data-theme="dark"]` 暗）要把上面整块值全换成亮色，
 * 而那些注释（"比页面底色更深"、"深色面板上"）讲的都是暗色语境，会全部变成
 * 与代码不符的说明。
 *
 * 更要紧的是**首屏不闪**：`theme.js` 只在用户选了暗夜版时才写 `data-theme="dark"`。
 * 脚本没跑、跑失败、或用户禁用 JS 时，页面停在亮色 —— 而那正是想要的默认。
 * 若写成"JS 负责加 light"，脚本执行前的一瞬间会是暗色，切回来就是一次闪黑。
 *
 * 特异性：`:root:not([...])` 是 (0,2,0)，高于上面 `:root` 的 (0,1,0)，覆盖成立。
 *
 * ## 语义色为什么不能照搬
 *
 * 上面四个三元组是照深底调的亮色（`#3ddc84` 这类），放到白底上对比度只有 1.5:1
 * 左右，等于看不见。这里全部换成压深的同色系，正文级对比度都在 4.5:1 以上。
 * **透明度档位不改** —— 它表达强度层级，深底上提亮、浅底上压暗，方向本来就一致。
 */
:root:not([data-theme="dark"]) {
  color-scheme: light;

  /* 面板是纯白、页面底色带一点灰：面板才能从背景里"浮"起来。
   * 反过来（白底 + 灰面板）会让表格看起来是塌进去的。 */
  --bg: #f4f6f9;
  --pn: #ffffff;
  --pn2: #eaeef4;
  --ln: #d2d9e3;

  /* 文字五级，步进与深色版对齐（每级至少差一档可辨认的灰）。 */
  --tx: #0f1620;
  --tx2: #2b3441;
  --mu: #5a6472;
  --dim: #79828f;
  --foot: #8d95a2;

  /* 压深后的语义色。括号里是对白底的对比度。 */
  --pos-rgb: 13, 124, 69;     /* #0d7c45  4.8:1 */
  --neg-rgb: 198, 40, 40;     /* #c62828  5.4:1 */
  --wn-rgb: 141, 95, 0;       /* #8d5f00  4.9:1 —— 琥珀在白底上必须压到棕黄才读得清 */
  --ac-rgb: 20, 97, 204;      /* #1461cc  5.6:1 */

  --pos-soft: #4a7d61;
  --neg-soft: #a55b5b;

  /* 遮罩用带蓝的深色而不是纯黑：纯黑压在浅色页面上显脏。不透明度也调低 ——
   * 同样的 .5 黑在白底上比在深底上重得多。 */
  --scrim: rgba(15, 22, 32, .38);
  --scrim-strong: rgba(15, 22, 32, .45);
  --shadow-drawer: -14px 0 40px rgba(15, 22, 32, .16);

  /* 饱和蓝底上的文字：亮色主题下是白字。 */
  --on-ac: #ffffff;

  --row-ln: #e6eaf0;      /* 行底边框：比 --ln 更淡，密集表格才不显脏 */
  --row-hv: #f0f4f9;
  --kpi-sub: #79828f;     /* = --dim，同深色版的约定 */

  /* 展开明细的底色。**必须比 `--pn2` 更暗**，因为展开行本身就是 `--pn2`。
   *
   * 2026-09-01 修：原来给的是 `#eef1f6`，比 `--pn2`(#eaeef4) **更亮** —— 方向反了，
   * 而且 RGB 只差 4，肉眼分不出。用户当天的原话是「菜单和子菜单边际感不明显」。
   *
   * 三档必须单调递进（越深表示层级越里）：
   *   普通行 --pn  #ffffff
   *   展开行 --pn2 #eaeef4   与上一层差 17
   *   展开区 --sink #dde3ed  与上一层差 13
   *
   * 暗夜版那三档本来就是对的（#161a21 / #1c212a / #11141a，sink 最暗），
   * 所以只有亮色这一份出过错。改这里之前先看 `.acc-exp` 与 `tr.acc-sub` ——
   * 那两处是这个变量最主要的消费者。 */
  --sink: #dde3ed;
  --acc-ln: #c6cfdb;
  --expr: #47505e;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--tx);
  font: 13px/1.5 -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* **所有数字都要等宽。** 漏掉这条，密集表格就无法竖向扫读，整个方案的价值消失
 * （规格 §9 把它列为第一号错误）。 */
th, td, .kpi-v, .mono, .num { font-variant-numeric: tabular-nums; }

.mono { font-family: ui-monospace, Menlo, Consolas, monospace; }

.pos { color: var(--pos); }
.neg { color: var(--neg); }
.zero { color: var(--mu); }

/* ---- 金额：三档，不是一律上色 ---------------------------------------
 *
 * 旧版把**所有**带符号的数字都涂成饱和绿/红，一屏二三十个色块，
 * 结果是哪笔都在叫——于是哪笔都不突出。颜色要能区分，就必须有不上色的东西。
 *
 * 三档按**这个数字能不能直接拿去行动**分：
 *
 *   .amt          中性。流水、行数、基数这类背景量 —— 它们没有「好/坏」，
 *                 流水大不代表赚钱，涂绿是在误导。
 *   .amt.soft     降饱和带符号。用户输赢这类**信息性**金额：符号有意义，
 *                 但它不是「谁给谁钱」的结论。
 *   .amt.hard     满饱和。**只给结算类**（net_amount / transfer_amount /
 *                 应收应付）—— 一屏里这种数字就几个，上色才有导向作用。
 *
 * 方向靠 .up / .down，而不是直接写 pos/neg：同一个负号在「输赢」列是亏了钱，
 * 在「结算」列是要付钱，语义不同，让调用方显式选。
 */
.amt { font-variant-numeric: tabular-nums; color: var(--tx2); }
.amt.zero { color: var(--dim); }
.amt.soft.up { color: var(--pos-soft); }
.amt.soft.down { color: var(--neg-soft); }
.amt.hard.up { color: var(--pos); }
.amt.hard.down { color: var(--neg); }
/* 结算类再加一级字重：颜色之外再给一个不靠色彩的线索（辅助识读）。 */
.amt.hard { font-weight: 500; }

/* ---- moneyClass() 的三个返回值 ------------------------------------------
 *
 * **这三个类之前在本文件里完全没有定义，所以 board.js 里 13 处、
 * realtime.js 里 2 处调用全部落空 —— 结算金额从来没上过色。**
 *
 * 成因：`api.js` 是从生产 `web/` 搬过来的，而 `web/style.css` 里确实定义了
 * `.money-in` / `.money-out` / `.dim`；但 dense.css 是重写的，用了 `.pos/.neg/.zero`
 * 这套名字。名字对不上，浏览器不会报错，只是安静地继续用默认色。
 *
 * **默认给降饱和色（soft）而不是满饱和。** `moneyClass()` 是通用函数，不区分
 * 「信息性金额」与「结算类金额」，全部给满饱和就回到了一屏色块、哪笔都不突出
 * 的局面。真正要强调的列显式写 `.amt.hard.up/.down`。
 */
.money-in { color: var(--pos-soft); }
.money-out { color: var(--neg-soft); }
.dim { color: var(--dim); }
/* 净额列（`.net`）是要拿去行动的数，升到满饱和 + 加粗。
 * 写成复合选择器而不改 JS：调用方已经在那些位置写了 `net ${moneyClass(...)}`。 */
.net.money-in { color: var(--pos); font-weight: 500; }
.net.money-out { color: var(--neg); font-weight: 500; }

/* ---- 状态标签：按「要不要你动手」分级 ------------------------------
 *
 * 旧版把已失效/已停用/待验证码/已熔断 全涂成黄或灰，而这四个状态对用户
 * 的要求完全不同。现在分四类，且**不只靠色相区分**，还靠填充与边框：
 *
 *   .s-dead   红色实心   不会自愈，且你能动手（账密错误→改密码、熔断→重置）
 *   .s-stuck  红色描边   卡住了，但**系统里没有对应操作**（待验证码）
 *   .s-wait   黄色描边   会自愈，不用管（限流重试）
 *   .s-run    蓝色描边   正在进行
 *   .s-ok     绿色循环   正常。**字重最轻、不给底色** —— 一屏里它最多，
 *                          让它安静下去，异常才浮得出来
 *   .s-off    灰色删线   不参与采集（已停用）
 *
 * `.s-stuck` 单独一类是因为它在本系统里无解：**全仓没有提交验证码的端点**，
 * 所以界面只能告知状态、不能给按钮。拿它和「改密码就能好」同色会让人一直找
 * 那个不存在的按钮。
 */
/* **基类叫 `.s-tag` 而不是 `.s`。** `.s` 会撞上 board.js 里表头的 sortable 标记
 * （`thead th.s`，那是本文件第 356 行早就有的规则）：`display:inline-flex` 会让 <th>
 * 脱离表格列布局，表头按内容收缩、数据行照常撑满，于是整张表看起来「没对齐」。
 * 已踩过一次，现象是表头七列共 492px 而数据行 816px。 */
.s-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 11px;
  line-height: 1.6;
  white-space: nowrap;
  border: 1px solid transparent;
}
.s-dead { background: var(--neg-bg); color: var(--neg); border-color: rgba(var(--neg-rgb), .45); font-weight: 500; }
.s-stuck { color: var(--neg); border-color: rgba(var(--neg-rgb), .38); }
.s-wait { color: var(--wn); border-color: rgba(var(--wn-rgb), .38); }
.s-run { color: var(--ac); border-color: rgba(var(--ac-rgb), .40); }
/* 正常态：无底无框，只一个小绿点。它占了一屏的大多数。 */
.s-ok { color: var(--mu); padding-left: 0; }
.s-ok::before { content: "●"; color: var(--pos); font-size: 9px; }
.s-off { color: var(--dim); padding-left: 0; }
.s-off::before { content: "○"; color: var(--dim); font-size: 9px; }

/* ---- 参与方身份 -------------------------------------------------------
 *
 * **两层，不能合成一层。**
 *
 * 外层（参与方）只分「我 vs 别人」。内层（逐行明细）才分法人/股东。
 *
 * 理由：`PartyTotalOut.roles` 是**数组**——法人按代理认定，同一个人可以在
 * A 代理是法人、B 代理是股东（fixture 里「你自己」与「老王」都是
 * `['legal','shareholder']`）。把法人/股东做成参与方级别的二分色，到这种人身上
 * 就必须二选一，而两个选项都是错的。
 */
.p-me { color: var(--ac); font-weight: 600; }
/* 左侧色条：颜色之外再给一个位置线索，扫列表时不用读字就能找到自己。 */
tbody tr.row-me td:first-child { box-shadow: inset 2px 0 0 var(--ac); }
tbody tr.row-me td { background: var(--ac-bg); }
.tag-me { background: var(--ac-bg); color: var(--ac); }
/* 法人：收付汇集点，实心强调。股东：描边，数量多、不需要每个都叫。 */
.tag-legal { background: var(--ac-bg); color: var(--ac); border: 1px solid rgba(var(--ac-rgb), .4); }
.tag-sh { color: var(--mu); border: 1px solid var(--ln); }

/* ---- header（sticky） ---- */

header.top {
  position: sticky;
  top: 0;
  /* **必须高于侧栏（30）。** 顶栏铺满整宽、始终压在侧栏上方，收起按钮才永远点得到 ——
   * v1.1.0 踩过：侧栏盖住汉堡后，「再点一次关闭」这个最自然的动作直接失效。
   * 仍然低于参与方明细抽屉（60/61），那个是模态语义，压住页头是对的。 */
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 20px;
  background: var(--bg);
  border-bottom: 1px solid var(--ln);
}

/* `margin: 0` 是必要的：这个标题现在是 <h1>（读屏靠它建立标题层级），
   而 h1 自带 0.67em 上下外边距，在 flex 页头里会把整条撞开。 */
.h-title { font-size: 16px; font-weight: 600; letter-spacing: -0.01em; margin: 0; }

/* 周期选择器：pill。深色下用 --pn2 底 + --ln 边框，不用浏览器原生 select 外观。 */
.period-pill {
  font: inherit;
  font-size: 12px;
  padding: 4px 9px;
  border-radius: 5px;
  background: var(--pn2);
  border: 1px solid var(--ln);
  color: var(--tx);
  cursor: pointer;
}
.period-pill:hover { border-color: var(--ac); }

/* ---- 站内导航：汉堡按钮 + 左侧抽屉 --------------------------------------- *
 *
 * 用户 2026-08-25 要求「做成 T9 那种左边可以打开的格式」。T9（i.t9live1.vip，
 * 2026-08-25 实测）的形态：顶栏左上一个汉堡，点开后黑底菜单从左侧滑入覆盖内容，
 * 右侧压一层遮罩，菜单项竖排、当前项灰底，末尾放「修改密碼 / 登出」。
 *
 * **抽屉而不是常驻侧栏**，这是刻意的：四个页面全是密集表格（结算周报「按账号明细」
 * 7 列、报表页 9 列），已经要在 `.tablewrap` 里横向滚动。固定切掉 200 多像素等于让
 * 每张表都更早触发横向滚动，而这套界面的全部价值就在于一屏能并排看更多列。
 *
 * **类名一律 `nav-` 前缀。** `.drawer` / `.scrim` 已被 board.js 的参与方明细面板占用
 * （z-index 60/61）。复用会让两套抽屉的 transform 与 z-index 互相污染，症状是
 * 「点表格某一行，导航跟着滑出来」这种毫无线索的怪现象。
 */

/* 汉堡按钮。三条横线用 <span> 画 —— 全站只有这一个图标，为它引字体或 SVG 不值得。 */
.nav-toggle {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
  width: 30px;
  height: 26px;
  padding: 0 6px;
  margin-right: 4px;
  border: 1px solid transparent;
  border-radius: 4px;
  background: none;
  cursor: pointer;
  flex: none;
}
.nav-toggle:hover { border-color: var(--ln); background: var(--pn2); }
.nav-toggle-bar { display: block; height: 1.5px; border-radius: 1px; background: var(--mu); }
.nav-toggle:hover .nav-toggle-bar { background: var(--tx); }

/* 侧栏宽度。就近声明在唯一的使用处（侧栏自身 + 内容让位 + 窄屏断点），
   不塞进文件顶部的 :root —— 那里是全站配色，混进布局尺寸会更难找。 */
:root { --nav-w: 232px; }

/* 遮罩。**只有窄屏的覆盖式模式用它**：常驻侧栏不是模态，一直压一层半透明黑
   会把整页压暗。层级 29 在页头（40）之下 —— 窄屏下页头要留在遮罩上方，
   否则收起按钮点不到。 */
.nav-scrim {
  position: fixed;
  inset: 0;
  z-index: 29;
  background: var(--scrim);
  opacity: 0;
  pointer-events: none;
  transition: opacity .16s ease;
}
.nav-scrim.on { opacity: 1; pointer-events: auto; }

/* 侧栏本体。**用 transform 位移而不是切 left/width**：transform 走合成层，不触发
   布局重算 —— 背后是几百行表格，用 left 做动画会在每一帧重排整张表。
 *
 * 从页头下方开始（不是 top: 0）。具体值由 `ops.js` 按页头实测高度写进 `--nav-top`：
 * 页头高度取决于内容（某些页会传 lead/right），写死 px 迟早对不上。兜底 51px 是
 * 当前实测值。这样页头铺满整宽、始终在侧栏上方，收起按钮永远点得到。
 *
 * 收起时加 `visibility: hidden` 把它移出 Tab 顺序 —— 只靠 transform 移出视区的话，
 * 键盘用户仍会 Tab 进一个看不见的菜单里。visibility 的过渡延到位移结束再生效，
 * 否则滑出动画会在第一帧就消失。 */
.nav-drawer {
  position: fixed;
  top: var(--nav-top, 51px);
  left: 0;
  bottom: 0;
  z-index: 30;
  width: var(--nav-w);
  display: flex;
  flex-direction: column;
  background: var(--pn);
  border-right: 1px solid var(--ln);
  transform: translateX(-100%);
  visibility: hidden;
  transition: transform .18s ease, visibility 0s linear .18s;
  overflow-y: auto;
}
.nav-drawer.on {
  transform: translateX(0);
  visibility: visible;
  transition: transform .18s ease, visibility 0s;
}

.nav-list { display: flex; flex-direction: column; padding: 6px 0; }

/* 菜单项。比 T9 的 72px 矮一档（那是给触屏的），但仍留足点击区。
   `border-left` 常驻透明 —— 只在选中态改颜色，避免选中时整行左移 2px。 */
.nav-item {
  display: block;
  padding: 9px 16px;
  border: 0;
  border-left: 2px solid transparent;
  background: none;
  font: inherit;
  font-size: 13px;
  text-align: left;
  text-decoration: none;
  color: var(--mu);
  cursor: pointer;
}
.nav-item:hover { color: var(--tx); background: var(--pn2); }
/* 焦点环。**不能写 `outline: none`** —— 打开抽屉时焦点会被送进第一个菜单项
 * （抽屉是准模态：有遮罩、锁滚动、Esc 关闭），去掉焦点环等于让键盘用户彻底失去
 * 「我现在在哪」的指示。
 *
 * 但浏览器默认的 `outline: auto` 在这里是橙黄色（实测 rgb(229,151,0)），在深色面板上
 * 既突兀又容易被误读成警告状态。改用强调色，并且**只在 `:focus-visible` 时给** ——
 * 鼠标点击不该留下焦点环。
 *
 * 用 inset box-shadow 而不是 outline：抽屉有 `overflow-y: auto`，outline 画在元素外侧，
 * 第一项与最后一项的环会被裁掉一半。 */
.nav-item:focus { outline: none; }
.nav-item:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 1px var(--ac);
  color: var(--tx);
}
/* 当前页。**同时改底色、字色与左边条**：只靠颜色标记当前位置，对色觉障碍用户
   等于没有标记。 */
.nav-item[aria-current="page"] {
  color: var(--ac);
  background: var(--ac-bg);
  border-left-color: var(--ac);
  font-weight: 600;
}

/* 退出。与 T9 一样放在抽屉末尾，`margin-top: auto` 把它顶到底部。 */
.nav-drawer-ft { margin-top: auto; padding: 6px 0 10px; border-top: 1px solid var(--ln); }
.nav-item-exit { width: 100%; color: var(--dim); }
.nav-item-exit:hover { color: var(--neg); background: var(--neg-bg); }

/* 主题开关（左下角，退出登录上方）。用户 2026-08-31 指定的位置。
 *
 * 做成 `role="switch"`，所以形态是「小滑轨 + 圆点」而不是普通菜单项：
 * 二态开关要让人一眼看出当前是开还是关，而一行纯文字做不到这件事。
 *
 * **状态只由 `aria-checked` 驱动**，不额外挂 `.on` 类 —— 两个来源迟早不一致，
 * 而不一致的表现是「滑轨看着是开的，实际是亮色」。读屏与视觉共用同一个真值。 */
.nav-theme {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 9px;
  color: var(--dim);
}
.nav-theme:hover { color: var(--tx); background: var(--pn2); }

/* 滑轨。宽 26 高 14，比常规开关小一档 —— 它在侧栏底部，不该抢导航项的注意力。 */
.nav-theme-dot {
  position: relative;
  flex: 0 0 auto;
  width: 26px;
  height: 14px;
  border-radius: 999px;
  background: var(--pn2);
  border: 1px solid var(--ln);
  transition: background .16s ease, border-color .16s ease;
}
/* 圆点。`left` 从 2px 滑到 12px（26 − 2 − 10 − 2），两端各留 2px 余量。 */
.nav-theme-dot::after {
  content: "";
  position: absolute;
  top: 1px;
  left: 2px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--mu);
  transition: left .16s ease, background .16s ease;
}
.nav-theme[aria-checked="true"] .nav-theme-dot {
  background: var(--ac-bg);
  border-color: var(--ac);
}
.nav-theme[aria-checked="true"] .nav-theme-dot::after {
  left: 12px;
  background: var(--ac);
}

/* 内容让位。**必须逐个列出这三种容器，不能给 body 加 padding** —— 页头也是 body
 * 的子元素，给 body 加 padding 会把铺满整宽的页头一起推走，左上角露出一块空白。
 *
 * 三个选择器覆盖两种页面结构：settlement / reports 是 `<main class="page">` 包住
 * 一切（含 #ver）；week / accounts 是 `#root` 与 `#ver` 两个平级 div。
 * 登录页是 `main.auth`，但它不调 `pageHeader()`，`nav-docked` 永远不会加到它身上。
 *
 * 用 margin-left 而不是 padding-left：`.page` 自己有 `padding: 0 20px 40px`，
 * 再叠一层 padding 会把两个值算在一起，边距变成 252px。 */
body.nav-docked > main,
body.nav-docked > #root,
body.nav-docked > #ver { margin-left: var(--nav-w); }

/* 过渡在首帧之后才由 `ops.js` 加 `nav-anim` 打开。**不能直接写在上面那条规则里**：
   常驻侧栏默认是展开的，页面一加载就会看到内容从左边缘滑到位一次。 */
body.nav-anim > main,
body.nav-anim > #root,
body.nav-anim > #ver { transition: margin-left .18s ease; }

/* 窄屏退化成覆盖式：232px 在窄屏上是整屏的三分之一，常驻会把表格挤到没法看。
   断点与文件里既有的 860px 一致。 */
@media (max-width: 860px) {
  body.nav-docked > main,
  body.nav-docked > #root,
  body.nav-docked > #ver { margin-left: 0; }
}

/* 覆盖式模式下锁背景滚动：那时侧栏是 fixed 覆盖层，背景跟着滚会让人分不清在滚哪一层。
   常驻模式不加这个类 —— 侧栏一直在，锁住整页滚动等于页面废了。 */
body.nav-open { overflow: hidden; }

.h-lock { margin-left: auto; font-size: 12px; color: var(--mu); white-space: nowrap; }
/* 圆点用 <i> + font-style:normal（规格 §3.1），避免为一个点引入图标字体。 */
.h-lock i { font-style: normal; color: var(--pos); margin: 0 3px; }

/* ---- 警示横幅 ---- */

.banner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 20px;
  font-size: 12px;
  background: rgba(var(--wn-rgb), .09);
  border-bottom: 1px solid rgba(var(--wn-rgb), .25);
  color: var(--wn);
}
.banner.ok {
  background: rgba(var(--pos-rgb), .08);
  border-bottom-color: rgba(var(--pos-rgb), .22);
  color: var(--pos);
}
.banner .b-link {
  margin-left: auto;
  font: inherit;
  background: none;
  border: 0;
  padding: 0;
  color: inherit;
  text-decoration: underline;
  cursor: pointer;
}

/* ---- KPI 条 ---- *
 * **是分栏条，不是卡片。** 四格等分并排、1px 竖线分隔，省垂直空间给表格
 * （规格 §9 第 7 条把「做成圆角卡片 + 大留白」列为错误）。 */

.kpi {
  display: flex;
  background: var(--pn);
  border-bottom: 1px solid var(--ln);
}
/* 首格文字的左对齐**不需要额外规则**：`.kpi-cell` 自带 `padding: 11px 20px`，
   而 `.kpi` 被负 margin 拉回窗口左缘，两者相加正好落在 20px —— 与表格首列对齐。 */
.kpi-cell {
  flex: 1;
  min-width: 158px;
  padding: 11px 20px;
}
.kpi-cell + .kpi-cell { border-left: 1px solid var(--ln); }
.kpi-k { font-size: 11px; color: var(--mu); }
.kpi-v { font-size: 19px; font-weight: 600; line-height: 1.35; letter-spacing: -0.01em; }

/* 窄视口下 KPI 换行成 2×2，而不是横向溢出把第四格切掉。
 *
 * 四格各有 min-width:158px，共 632px；实测 523px 视口下「自留 0%」那格被截断，
 * 而它正是三类告警之一 —— 告警被切掉比没有告警更糟。
 */
@media (max-width: 700px) {
  .kpi { flex-wrap: wrap; }
  .kpi-cell { flex: 1 1 50%; min-width: 0; }
  /* 换行后第 3 格落在新行行首，它的左边框贴着容器边缘，看起来像多一条竖线。 */
  .kpi-cell:nth-child(3) { border-left: 0; }
  .kpi-cell:nth-child(n+3) { border-top: 1px solid var(--ln); }
}
.kpi-s { font-size: 11px; color: var(--kpi-sub); }

/* ---- 工具栏 ---- */

/* 以下几类是**通栏条**：底色与分隔线要铺满整宽，不能跟着正文缩进。
 *
 * 它们自带 `padding: … 20px`，在 `.page` 里恰好与容器边距叠成"文字对齐、底色通栏"
 * 的效果 —— 因为 `.page` 的 padding 由父容器给，条自身仍是满宽。
 * 而 `#root` 加上 padding 后，这些条会跟着缩进 20px，露出两侧的页面底色。
 *
 * 用负 margin 抵消回去，再靠自身的 20px padding 把文字推到正确位置：
 * 最终文字左缘仍是 20px，但底色铺满整宽，与结算周报一致。 */
#root > .bar,
#root > .note,
#root > .foot,
#root > .banner,
#root > .kpi { margin-left: -20px; margin-right: -20px; }

.bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 20px;
  border-bottom: 1px solid var(--ln);
}

.tab {
  font: inherit;
  font-size: 12px;
  padding: 4px 10px;
  border: 0;
  border-radius: 5px;
  background: none;
  color: var(--mu);
  cursor: pointer;
}
.tab:hover { color: var(--tx); }
/* 激活态：底色 + inset 描边（规格 §3.4）。用 aria-pressed 驱动，读屏能听到「已按下」。 */
.tab[aria-pressed="true"] {
  background: var(--pn2);
  color: var(--tx);
  box-shadow: inset 0 0 0 1px var(--ln);
}

.bar-right { display: flex; align-items: center; gap: 10px; margin-left: auto; }

.bar input[type="search"] {
  font: inherit;
  font-size: 12px;
  width: 170px;
  padding: 4px 8px;
  border-radius: 5px;
  background: var(--pn2);
  border: 1px solid var(--ln);
  color: var(--tx);
}
.bar input[type="search"]:focus { outline: none; border-color: var(--ac); }
.bar input[type="search"]::placeholder { color: var(--mu); }

.chk { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--mu); cursor: pointer; }
.chk input { accent-color: var(--ac); }

.bar-count { font-size: 11px; color: var(--kpi-sub); }

/* ---- 表格 ---- */

.tablewrap { overflow: auto; }

/* 结算周报「本周账目」：超过 7 行时表格自身滚动，不把下方的结算结论顶下去。
 * 用户 2026-08-31：「本周账目大于 7 条就只显示 7 条，可以滑动往下显示」。
 *
 * **限的是容器不是行数**，所以两个高度必须跟着 `tbody td` / `thead th` 的内边距走：
 *
 *   行高   = 7px×2 内边距 + 19.5px 行高（13px × 1.5）+ 1px 底边框 = 34.5px
 *   表头高 = 7px×2 内边距 + 16.5px 行高（11px × 1.5）+ 1px 底边框 = 31.5px
 *
 * **两个数都要写足小数。** 先按 34/32 估算过一版，实测第 7 行被切掉 2.4px ——
 * 少算的那 1px 乘 7 行就够吃掉一整行的下边框，看起来像「第 7 行没显示完」。
 *
 * 改那两处 padding 或字号就要回来改这里，否则可视行数会悄悄变成 6 或 8 行。
 *
 * `max-height` 而不是 `height`：只有三行数据时不该留一大片空白。
 *
 * **表头会自动粘在容器顶部** —— `thead th` 本来就是 `position: sticky; top: 0`，
 * 放进滚动容器后它的包含块从页面变成这个容器，正好是想要的效果，不必额外写规则。
 *
 * `overscroll-behavior: contain` 阻断滚动链：滚到表格底部时不要接着把整页往下带，
 * 否则用户想看第 8 行却把结算结论滚过去了。
 *
 * 横向也给 auto：这张表 8 列且 `tbody td` 是 nowrap，窄屏必然溢出。 */
.rows-scroll {
  max-height: calc(31.5px + 34.5px * 7);
  overflow: auto;
  overscroll-behavior: contain;
}

table { width: 100%; border-collapse: collapse; }

thead th {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--pn);
  font-size: 11px;
  font-weight: 500;
  color: var(--mu);
  text-align: left;
  padding: 7px 12px;
  white-space: nowrap;
  border-bottom: 1px solid var(--ln);
}
thead th.r { text-align: right; }
thead th.s { cursor: pointer; user-select: none; }
thead th.s:hover { color: var(--tx); }
thead th .ar { opacity: .55; margin-left: 2px; }
thead th[aria-sort] .ar { opacity: 1; color: var(--ac); }

tbody td {
  padding: 7px 12px;
  border-bottom: 1px solid var(--row-ln);
  white-space: nowrap;
}
tbody td.r { text-align: right; }
tbody tr.click { cursor: pointer; }
tbody tr.click:hover { background: var(--row-hv); }
/* 抽屉打开时高亮来源行，关掉抽屉才知道刚看的是哪一行。 */
tbody tr.on { background: var(--row-hv); box-shadow: inset 2px 0 0 var(--ac); }

/* ---- 「無直接往來」的佔成者：默认收起 ----------------------------------
 *
 * 用户 2026-09-05：「没有数据的股东应该不显示，可以有个灰度的小展开」。
 *
 * 这批方六列全是「—」，摊在表里只会把真正要结算的人挤下去。但**不能直接不渲染** ——
 * 用户确实配过他们，而且他们的比例挤小了我的自留；彻底藏掉会让人以为配置丢了。
 * 所以收进一个折叠开关，数量写在按钮上。
 */

/* 摊开后仍然压暗：它们没有可结算的金额，不该跟上面那些真要处理的行抢注意力。
   `td.name` 的 600 字重也一并压平（选择器 (0,2,3) 稳压它的 (0,1,1)）。 */
tbody tr.p-idle td { color: var(--mu); }
tbody tr.p-idle td.name { font-weight: 400; }
/* 不给 cursor: pointer、不给 hover 底色：这些行点了没有任何反应（抽屉会是空的），
   给出可点的暗示等于骗一次点击。 */

/* 开关自己占一行。上边框把它与数据行分开 —— 它是表尾的入口，不是一条数据。 */
tbody tr.idle-tog td {
  padding: 5px 12px;
  border-top: 1px solid var(--ln);
  background: var(--sink);
}

/* 用真 <button>：键盘要能 Tab 到、Enter 能开。整行点击那套（`tr.click`）本身
   键盘不可达，所以这里不沿用它。 */
.idle-btn {
  display: inline-flex;
  align-items: center;
  padding: 0;
  border: 0;
  background: none;
  color: var(--mu);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}
.idle-btn:hover { color: var(--tx2); }
.idle-btn:hover .caret { border-color: var(--ac); color: var(--ac); }
/* 展开态填充强调色，与 `.caret` 那套保持同一个视觉语言。**选择器落在 button 上**
   而不是 tr 上：`aria-expanded` 挂在按钮上（tr 不是可交互元素，放它身上是错的）。 */
.idle-btn[aria-expanded="true"] .caret {
  background: var(--ac-bg);
  border-color: rgba(var(--ac-rgb), .45);
  color: var(--ac);
}
.idle-btn:focus { outline: none; }
.idle-btn:focus-visible { outline: 1px solid var(--ac); outline-offset: 2px; }

td.name { font-weight: 600; }
.mu { color: var(--mu); }
.net { font-weight: 600; }

/* 小标签。10px，3px 圆角（规格 §2.4）。 */
.tag {
  display: inline-block;
  font-size: 10px;
  padding: 1px 5px;
  border-radius: 3px;
  margin-left: 5px;
  vertical-align: 1px;
  white-space: nowrap;
}
.tag.warn { background: rgba(var(--wn-rgb), .16); color: var(--wn); }
.tag.rev { background: rgba(var(--ac-rgb), .16); color: var(--ac); }
.tag.mu { background: var(--pn2); color: var(--mu); }

.btn {
  font: inherit;
  font-size: 11px;
  padding: 3px 8px;
  border-radius: 4px;
  background: none;
  border: 1px solid var(--ln);
  color: var(--mu);
  cursor: pointer;
  white-space: nowrap;
}
.btn:hover { color: var(--ac); border-color: var(--ac); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn:disabled:hover { color: var(--mu); border-color: var(--ln); }

.empty { padding: 34px 20px; text-align: center; color: var(--mu); }

/* ---- 算式明细（抽屉主体） ---- *
 * 规格 §4.4 的展开区规格整套搬进抽屉：下沉背景、账号块左侧竖线、4 列 grid 算式。
 * 这是整个页面的核心 —— 庄家靠它向合伙人解释每一分钱。 */

.calc { background: var(--sink); padding: 10px 12px 12px; }

.acc {
  border-left: 2px solid var(--acc-ln);
  padding: 6px 0 6px 11px;
  margin-bottom: 7px;
}
/* 对方为法人 = 方向反转，蓝色左边框 + 蓝标签。这是最容易看错的地方（规格 §9 第 6 条）。 */
.acc.rev { border-left-color: var(--ac); }
/* 数据缺失：黄边框，整块文字也变黄。 */
.acc.miss { border-left-color: var(--wn); color: var(--wn); }

.acc-hd { font-size: 12px; margin-bottom: 3px; }
.acc-hd b { font-weight: 600; }
.acc-hd .meta { color: var(--mu); font-weight: 400; }
.acc.miss .acc-hd .meta { color: var(--wn); }

/* 4 列：标签 / 算式 / 结果 / 方向（规格 §4.4）。 */
.row4 {
  display: grid;
  grid-template-columns: 64px 1fr 108px 26px;
  gap: 8px;
  font-size: 12px;
  padding: 1px 0;
}
.row4 .lbl { color: var(--mu); }
.row4 .expr { color: var(--expr); overflow: hidden; text-overflow: ellipsis; }
.row4 .val { text-align: right; font-weight: 600; }
.row4 .dir { color: var(--mu); }

/* 小计：虚线分隔，与算式行同一 grid 才能对齐。 */
.row4.sub {
  border-top: 1px dashed var(--acc-ln);
  margin-top: 3px;
  padding-top: 4px;
}

/* 合计：3 列（规格 §4.4 末），实线分隔，13px/600。 */
.row3 {
  display: grid;
  grid-template-columns: 1fr 108px 26px;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  border-top: 1px solid var(--ln);
  margin-top: 9px;
  padding-top: 8px;
}
.row3 .val { text-align: right; }
.row3 .dir { color: var(--mu); font-weight: 400; }

/* ---- 侧滑抽屉（C 版交互） ---- */

.scrim {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  opacity: 0;
  pointer-events: none;
  transition: opacity .16s ease;
  z-index: 60;
}
.scrim.on { opacity: 1; pointer-events: auto; }

.drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(44rem, 94vw);
  display: flex;
  flex-direction: column;
  background: var(--pn);
  border-left: 1px solid var(--ln);
  box-shadow: var(--shadow-drawer);
  transform: translateX(100%);
  transition: transform .18s ease;
  z-index: 61;
}
.drawer.on { transform: none; }

.dr-hd {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--ln);
}
.dr-who { font-size: 14px; font-weight: 600; }
.dr-net { margin-left: auto; font-size: 14px; font-weight: 600; }

.dr-bd { flex: 1; overflow: auto; padding: 12px 14px 24px; }

.dr-ft {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 9px 14px;
  border-top: 1px solid var(--ln);
  background: var(--bg);
}
.dr-pos { font-size: 11px; color: var(--kpi-sub); margin-left: 4px; }
.dr-ft .grow { margin-left: auto; }

.icon {
  font: inherit;
  font-size: 13px;
  line-height: 1;
  padding: 4px 7px;
  border-radius: 4px;
  background: none;
  border: 1px solid var(--ln);
  color: var(--mu);
  cursor: pointer;
}
.icon:hover { color: var(--tx); border-color: var(--mu); }

/* ---- 页脚 ---- *
 * 符号约定始终可见（规格 §7）。这一页所有正负号都按它读。 */
.foot {
  padding: 14px 20px;
  font-size: 11px;
  color: var(--foot);
  border-top: 1px solid var(--ln);
}

/* ---- 实时查询 / 账号同步状态 两页专属 ---------------------------------- *
 *
 * 沿用同一套 token（规格 §10：延展时保持一致）。这里只加这两页需要的结构件。 */

/* 状态圆点 + 文字。**颜色不作为唯一编码**：圆点旁边永远有文字。 */
.st { display: inline-flex; align-items: baseline; gap: 5px; white-space: nowrap; }
.st i { font-style: normal; font-size: 10px; line-height: 1.6; }
.st.ok i { color: var(--pos); }
.st.warn i { color: var(--wn); }
.st.err i { color: var(--neg); }
.st.off i { color: var(--mu); }
.st.ok { color: var(--pos); }
.st.warn { color: var(--wn); }
.st.err { color: var(--neg); }
.st.off { color: var(--mu); }

/* 需要干预的行：左侧竖条 + 极淡底色。置顶之外再给一层视觉，
 * 否则滚动到中段就分不清哪些是要处理的。 */
tbody tr.attn td { background: rgba(var(--wn-rgb), .05); }
tbody tr.attn td:first-child { box-shadow: inset 2px 0 0 var(--wn); }

/* 失效（熔断/账密错误）比「这次失败了」更重：它不会自愈。 */
tbody tr.dead td { background: rgba(var(--neg-rgb), .05); }
tbody tr.dead td:first-child { box-shadow: inset 2px 0 0 var(--neg); }

/* 停用账号整行压暗：它不参与采集，不该和正常账号争注意力。 */
tbody tr.disabled td { opacity: .5; }

/* 行内操作按钮组 */
.acts { display: inline-flex; gap: 4px; }

/* 工具栏里的主操作（全部刷新 / 批量重抓） */
.btn.primary {
  border-color: var(--ac);
  color: var(--ac);
}
.btn.primary:hover { background: rgba(var(--ac-rgb), .12); }

/* 二级说明行：夹在工具栏与表格之间，放口径解释。 */
.note {
  padding: 7px 20px;
  font-size: 11px;
  color: var(--kpi-sub);
  border-bottom: 1px solid var(--ln);
}
.note b { color: var(--mu); font-weight: 500; }

/* ---- 弱化区块（实时页的「预估分成」） ---- *
 *
 * **这是实时页与周报页最重要的区别**（display-spec §4.1）：这个数会随剩余天数剧烈
 * 变化，绝不能让人拿去要钱。所以它必须在视觉上明显更轻：不给品牌色、不给大字号、
 * 底色比页面更暗、字全部走 --mu，并且带一条常驻警示。 */

.weak {
  margin: 0;
  padding: 11px 20px 14px;
  background: var(--sink);
  border-top: 1px solid var(--ln);
}
.weak-hd {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 12px;
  color: var(--mu);
  margin-bottom: 7px;
}
.weak-hd .warn-txt { color: var(--wn); }
.weak-hd a { color: var(--ac); text-decoration: none; margin-left: auto; font-size: 11px; }
.weak-hd a:hover { text-decoration: underline; }

/* 预估条目：小字、等宽数字、灰底。**不上绿/红**——上色会让它看起来像结论。 */
.weak-list { display: flex; flex-wrap: wrap; gap: 6px; }
.weak-item {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 3px 8px;
  border-radius: 4px;
  background: var(--pn2);
  border: 1px solid var(--ln);
  font-size: 12px;
  color: var(--mu);
}
.weak-item b { font-weight: 500; color: var(--tx); }
.weak-item span { font-variant-numeric: tabular-nums; }

/* 空态里的次要说明 */
.empty .sub { display: block; margin-top: 6px; font-size: 11px; color: var(--kpi-sub); }

/* ---- 客户分成三版对比专属 ------------------------------------------------ *
 *
 * 沿用同一套 token。这里只加三版需要的结构件。 */

/* 原型切换条。**只存在于原型**，不进生产。
 *
 * 底色**必须跟着主题走**，不能写死深色。原来是 `#0a0d11`（照当时"整站只有深色"写的），
 * 加入普通版后那行深底配 `var(--tx)` 文字就变成**深底深字**，整条读不出来。
 * `--pn2` 在两个主题下都是"比面板再深/浅一档"，正好是这种附属条需要的层次。 */
.proto-bar {
  display: flex;
  align-items: center;
  /* **必须允许换行。** 草稿评审期这条上会挂七八个版本入口，不换行会横向溢出，
     而它是 sticky 顶条、溢出后右边几项永远点不到。dev-banner 只有 3 项不受影响。 */
  flex-wrap: wrap;
  gap: 10px;
  padding: 6px 20px;
  background: var(--pn2);
  border-bottom: 1px solid var(--ln);
  font-size: 11px;
  position: sticky;
  top: 0;
  z-index: 30;
}
.proto-bar strong { color: var(--tx); font-weight: 600; }
.proto-bar .note-txt { color: var(--kpi-sub); }
.proto-bar .spacer { margin-left: auto; }
.proto-bar a {
  color: var(--mu);
  text-decoration: none;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--ln);
}
.proto-bar a:hover { color: var(--tx); border-color: var(--mu); }
.proto-bar a.on { background: var(--ac); border-color: var(--ac); color: var(--on-ac); font-weight: 600; }

/* header 在 proto-bar 之下，sticky 时不能盖住它。 */
.proto-bar ~ * header.top { top: 27px; }

/* ---- 额度条 ---- *
 * 三版共用。比 .weak 更紧凑：它是编辑时的即时反馈，不是弱化信息。 */
.quota {
  padding: 8px 11px;
  background: var(--pn2);
  border: 1px solid var(--ln);
  border-radius: 5px;
}
.quota .weak-hd { margin: 0 0 5px; font-size: 11px; }
.quota .weak-item { background: var(--pn); font-size: 11px; padding: 2px 7px; }

/* ---- A 版：分组平铺 ---- *
 *
 * 代理作为分组标题行，客户行直接铺在下面。**不点开任何东西。** */

/* 分组标题行：比普通行重，底色区分，左侧强调条。 */
tbody tr.group-row td {
  background: var(--pn);
  border-top: 1px solid var(--ln);
  border-bottom: 1px solid var(--ln);
  padding-top: 9px;
  padding-bottom: 9px;
}
tbody tr.group-row td:first-child { box-shadow: inset 3px 0 0 var(--ln); }
/* 失效分组：整组标红，它下面的比例都不生效。 */
tbody tr.group-row.stale td { background: rgba(var(--neg-rgb), .07); }
tbody tr.group-row.stale td:first-child { box-shadow: inset 3px 0 0 var(--neg); }
/* 自留 0%：黄条提示。合法但更可能是填错了。 */
tbody tr.group-row.zero td:first-child { box-shadow: inset 3px 0 0 var(--wn); }

.group-title { font-weight: 600; }
.group-agent { color: var(--mu); font-weight: 400; }

/* 分组标题行里的额度摘要：紧凑一行，改比例时它实时变。 */
.group-quota {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  font-size: 11px;
  color: var(--mu);
  font-variant-numeric: tabular-nums;
}
.group-quota b { color: var(--tx); font-weight: 500; }
.group-quota .over { color: var(--neg); }
.group-quota .dirty { color: var(--wn); }

/* 客户行缩进，与分组标题形成层级。 */
tbody tr.child-row td:first-child { padding-left: 30px; }

/* ---- 行内编辑 ---- *
 *
 * 比例直接可改。**输入框必须窄**：宽输入框在密集表格里像一个洞。 */
.edit-cell {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  justify-content: flex-end;
}
.edit-cell input {
  font: inherit;
  font-size: 12px;
  width: 4.4rem;
  padding: 2px 5px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  background: var(--pn2);
  border: 1px solid var(--ln);
  border-radius: 4px;
  color: var(--tx);
}
.edit-cell input:focus { outline: none; border-color: var(--ac); }
/* 改动未保存：黄框。保存前用户必须能看出「这个数还没生效」。 */
.edit-cell input.dirty { border-color: var(--wn); }
/* 会被服务端拒绝：红框。 */
.edit-cell input.bad { border-color: var(--neg); }
.edit-cell .pctsign { color: var(--mu); font-size: 11px; }

/* 行内保存/撤销按钮，只在有改动时出现。 */
.edit-acts { display: inline-flex; gap: 3px; margin-left: 5px; }

/* ---- B 版：主从两栏 ---- */
.split {
  display: grid;
  grid-template-columns: minmax(19rem, 24rem) 1fr;
  align-items: start;
  min-height: 0;
}
.split .pane-l {
  border-right: 1px solid var(--ln);
  overflow: auto;
  /* 减去 proto-bar + header + banner + kpi + bar 的高度，让左栏自己滚。 */
  max-height: calc(100vh - 27px);
}
.split .pane-r { overflow: auto; max-height: calc(100vh - 27px); }

/* 主从两栗在窄视口下退化为上下两段。
 *
 * 这是全站第一条宽度断点：其余三页都是单列表格，靠横向滚动就能活；只有客户分成
 * 是左右分栗，宽度不够时右侧面板会被压成逐字竖排（实测 523px 视口下左栗占 384px，
 * 右栗只剩 139px，「额度」四项每个字占一行）。
 *
 * 阈值 860px 是量出来的，不是猜的：右侧额度条自然宽 475px 加面板内边距 28px 约 503px，
 * 客户表 384px 比它窄因而不是瓶颈；左栗最窄 19rem = 304px。两者相加加边框约 810px，
 * 取 860px 留一点余量。
 *
 * **退化后仍然不用抽屉**：面板就展开在选中项下方（由 customers.js 的 place() 插入 DOM），
 * 列表仍在上下文里，不遮任何东西。非模态是这一版的立身之本，窄屏也不能丢。
 *
 * 阈值改动时 `customers.js` 里的 `matchMedia('(max-width: 860px)')` 要同步 ——
 * 两边不一致会出现「看起来是两栏但点一下就收起」这种说不通的状态。
 */
@media (max-width: 860px) {
  .split { grid-template-columns: 1fr; }
  .split .pane-l {
    border-right: 0;
    /* 不能限高也不能自己滚：面板现在是左栏的子节点，限高会把它闷在
       一个小滚动框里，反而比抽屉更难用。整页滚就行。 */
    max-height: none;
    overflow: visible;
  }
  /* 同理，面板也不再靠自身滚动，否则出现嵌套滚动条。 */
  .split .pane-r { max-height: none; overflow: visible; }

  /* 展开的面板要看得出是「属于上面那一项」，而不是又一个平级区块：
     左侧留一条强调色竖线 + 轻微内缩。 */
  .split .pane-r:not(:last-child),
  .split .pane-l > .pane-r {
    border-bottom: 1px solid var(--ln);
  }
  .split .pane-l > .pane-r {
    box-shadow: inset 2px 0 0 var(--ac);
    background: var(--pn);
  }
}

/* 手风琴箭头，只在堆叠态渲染。定宽避免 ▸/▾ 字形宽度不同导致标题微微抖一下。 */
.pane-item .pi-caret {
  display: inline-block;
  width: 10px;
  color: var(--mu);
  font-size: 10px;
}

/* 左栏列表项：不用 table，密度更高。 */
.pane-item {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--row-ln);
  padding: 7px 12px;
  cursor: pointer;
  color: var(--tx);
}
.pane-item:hover { background: var(--row-hv); }
.pane-item[aria-current="true"] { background: var(--row-hv); box-shadow: inset 2px 0 0 var(--ac); }
.pane-item .pi-top { display: flex; align-items: baseline; gap: 6px; }
.pane-item .pi-name { font-weight: 500; font-size: 12px; }
.pane-item .pi-agent { color: var(--mu); font-size: 11px; margin-left: auto; }
.pane-item .pi-sub {
  display: flex;
  gap: 8px;
  font-size: 11px;
  color: var(--mu);
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
}
.pane-item.stale { box-shadow: inset 2px 0 0 var(--neg); }

/* 右侧面板 */
.pane-body { padding: 12px 14px 24px; }
.pane-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 10px 14px;
  border-bottom: 1px solid var(--ln);
  background: var(--pn);
  position: sticky;
  top: 0;
  z-index: 4;
}
.pane-head .ph-name { font-size: 14px; font-weight: 600; }
.pane-head .ph-acts { margin-left: auto; display: inline-flex; gap: 5px; }
.pane-empty { padding: 60px 20px; text-align: center; color: var(--mu); }

/* ---- C 版：内联展开 ---- */
.exp-mark {
  display: inline-block;
  width: 11px;
  color: var(--mu);
  font-size: 9px;
}
tbody tr.detail-row > td {
  background: var(--sink);
  padding: 10px 12px 12px 30px;
  border-bottom: 1px solid var(--ln);
}
/* 展开区里的小表格：与外层区分，底色更亮一层。 */
tbody tr.detail-row table { background: var(--pn); }
tbody tr.detail-row .quota { margin-bottom: 9px; }

/* --- /dev 落地页的表内链接 ---------------------------------------------
 *
 * dense.css 原本没有通用 `a` 样式：页面里的链接全在导航（`.nav-item`）或 `.proto-bar`
 * 作用域内，各自带样式。落地页的表格里出现了裸 <a>，于是拿到浏览器默认的
 * #0000EE，在深色底上刺眼且几乎读不清。
 *
 * **不写成通用 `a {}`**：那会连带改掉 `.nav-item` 与 proto-bar 的链接（它们靠自己的
 * 规则定义颜色与内边距，通用规则会插进层叠里制造意外）。限定在 `td.name a`，
 * 而 td.name 里的 <a> 只有落地页有。
 */
td.name a {
  color: var(--ac);
  text-decoration: none;
  font-weight: 500;
}
td.name a:hover { text-decoration: underline; }

/* ---- 按账号明细的折叠 -------------------------------------------------- *
 *
 * `.click` 已经给了 cursor 与 hover（第 367 行），这里只补折叠特有的三件。
 */

/* 定宽箭头：▸ 与 ▾ 字形宽度不同，不定宽时展开/收起会让账号名横向抖一下。 */
/* 展开开关。**做成带边框的小方块，不是一个裸箭头字符。**
 *
 * 裸字符看起来像装饰，用户不知道整行可以点（用户 2026-08-24 反馈「展开不明显」）。
 * 方块 + hover 变色 + 展开后填充强调色，三层反馈叠起来才明确。
 *
 * `inline-flex` 在这里是安全的：`.caret` 只用在 <td> 里的 <span> 上。
 * （给 <th> 用 inline-flex 会让它脱离表格列布局 —— 见 `.s-tag` 的注释。） */
.caret {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  margin-right: 6px;
  border: 1px solid var(--ln);
  border-radius: 3px;
  background: var(--pn2);
  color: var(--mu);
  font-size: 9px;
  vertical-align: -2px;
}
tbody tr.click:hover .caret { border-color: var(--ac); color: var(--ac); }
/* 已展开：填充强调色。收起/展开两态一眼可分，不必去读箭头方向。 */
tbody tr.acc-row.open .caret,
tbody tr.click[aria-expanded="true"] .caret {
  background: var(--ac-bg);
  border-color: rgba(var(--ac-rgb), .45);
  color: var(--ac);
}
/* 不可展开的行（本周数据里没抓到数据那些）：保留占位宽度但不画框 ——
   一个空方框看起来像坏掉的按钮，比没有更糟。 */
.caret.caret-off { border-color: transparent; background: none; }

/* 账号分组头：比子行稍亮一档，让「账号 → 关联方」的层级看得出来。
 * 分组头自己不用背景色（展开态例外，见下），层级靠子行的下沉底色表达。 */
tbody tr.acc-row td { border-top: 1px solid var(--ln); }
tbody tr.acc-row td:first-child { color: var(--tx); }
/* 展开态：账号行本身也着色，与它下面的子行连成一段，否则一屏里多组展开后
   分不清哪几行属于哪个账号。 */
tbody tr.acc-row.open td { background: var(--pn2); }

/* 子行缩进。原先写成内联 style，为了 CSP 的 style-src 收紧过一轮，
 * 这类固定值一律进 CSS。 */
td.child { padding-left: 30px !important; }

/* 展开出来的子行。用户 2026-08-31：「展开的内容和下方可以展开的内容重合度太高，
 * 分不开哪边是展开的」。
 *
 * 原来子行只有 `td.child` 的缩进，而**缩进只作用在第一列** —— 右边六列与未展开的
 * 账号行完全同形。一屏里展开两三组之后，就看不出某一行属于上面哪个账号了。
 *
 * 三条线索一起给，任一条单独都不够：
 *   1. 下沉底色（与抽屉展开区同一个 `--sink`）：一眼分出「这是展开出来的内容」
 *   2. 贯穿整行的左内嵌竖线：把同一组子行串成一列，比缩进更连续
 *   3. 末行底部加粗分隔线：明确「这一组到此为止」，下面那行是新的账号
 *
 * **必须排除 `.row-me`。** 「我自己」那行的淡蓝底与左侧蓝条是身份标识，优先级高于
 * 分组线索。而 `tbody tr.row-me td` 与 `tbody tr.acc-sub td` 选择器权重相同
 * ((0,1,3))，本文件里 row-me 在前、这里在后，不排除就会把它的蓝底盖掉。 */
tbody tr.acc-sub:not(.row-me) td { background: var(--sink); }
tbody tr.acc-sub:not(.row-me) td:first-child { box-shadow: inset 2px 0 0 var(--ln); }
/* 组末边界：比普通行底边框（1px `--row-ln`）明显一档。 */
tbody tr.acc-sub-last td { border-bottom: 2px solid var(--ln); }

/* ---- 本周数据：行内展开区 ---------------------------------------------- *
 *
 * 展开区放的是**周内预估**分成。它与结算周报的展开区刻意长得不同：
 * 那边是结论（满饱和金额、白底强调），这边全程降饱和 + 一条常驻警示条，
 * 因为这一周还没结束，数字明天就会变。
 */

/* 承载展开内容的那一行：去掉常规单元格内边距，让内部块自己控制。 */
tbody tr.wk-exp-row > td { padding: 0; background: var(--sink); }

.wk-exp { padding: 10px 14px 12px; }

/* 警示条。**常驻，不可关闭** —— 架构文档原本禁止在这一页做结算展示，
 * 现在做了，就必须让人一眼看出它不是结论（用户 2026-08-22 知情同意）。 */
.wk-warn {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  padding: 6px 10px;
  margin-bottom: 10px;
  border-radius: 4px;
  background: var(--wn-bg);
  border: 1px solid rgba(var(--wn-rgb), .3);
  font-size: 11px;
  color: var(--mu);
}
.wk-warn b { color: var(--wn); font-weight: 600; }
.wk-warn a { color: var(--ac); text-decoration: none; margin-left: auto; white-space: nowrap; }
.wk-warn a:hover { text-decoration: underline; }

/* 代理分组头。同一账号下多个代理是多笔独立的钱，必须有明确分界。 */
.wk-agent {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 10px 0 4px;
  font-size: 11px;
  color: var(--mu);
}
.wk-agent b { color: var(--tx2); font-size: 12px; font-weight: 600; }
.wk-agent:first-of-type { margin-top: 0; }

/* 展开区内的表：比外层更紧，且不要 sticky 表头（它在滚动容器里会错位）。 */
.wk-tbl thead th {
  position: static;
  padding: 3px 8px;
  font-size: 10px;
  background: none;
  border-bottom: 1px solid var(--row-ln);
}
.wk-tbl tbody td { padding: 3px 8px; font-size: 12px; }

/* 没有可分成数据时的占位。给出原因与下一步，不是空白。 */
.wk-none { padding: 8px 2px; font-size: 12px; color: var(--mu); }
.wk-none .sub { display: block; margin-top: 3px; font-size: 11px; color: var(--dim); }

/* ---- 账号·分成：左栏两层树 -------------------------------------------- *
 *
 * 左栏是「账号 → 代理」两层。两者都是 <button>（可点、可 Tab 到），
 * 但**必须一眼分清层级**，否则代理项看起来像另一个账号。
 * 手段：账号头有底色 + 上边框，代理项缩进 + 无底色。
 */
.pane-acc {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  border: 0;
  border-top: 1px solid var(--ln);
  background: var(--pn);
  padding: 8px 12px;
  cursor: pointer;
  color: var(--tx);
}
.pane-acc:hover { background: var(--pn2); }
/* 选中态用左侧强调条，与代理项的选中态一致，靠缩进区分层级而不是靠颜色。 */
.pane-acc[aria-current="true"] { background: var(--pn2); box-shadow: inset 2px 0 0 var(--ac); }
.pane-acc .pa-top { display: flex; align-items: center; gap: 7px; }
.pane-acc .pa-name { font-weight: 600; font-size: 12px; }
.pane-acc .pa-sub {
  display: flex;
  align-items: baseline;
  gap: 9px;
  margin-top: 3px;
  font-size: 11px;
}

/* 代理项缩进，视觉上挂在账号下面。`.pane-item` 的其余样式复用客户分成那套。 */
.pane-l .pane-item { padding-left: 24px; }

/* 状态说明条。**不是横幅**：它解释「当前这个状态该做什么」，常驻在面板顶部。
 * bad 变体给红色边框 —— 那几个状态调度已经停了，不能看起来像普通提示。 */
.acc-hint {
  padding: 7px 10px;
  margin-bottom: 10px;
  border-radius: 4px;
  background: var(--pn2);
  border: 1px solid var(--ln);
  font-size: 11px;
  line-height: 1.65;
  color: var(--mu);
}
.acc-hint.bad { background: var(--neg-bg); border-color: rgba(var(--neg-rgb), .35); }

/* 左栏里的法人名。用文字颜色而不是标签底色：一屏里代理项很多，
 * 每个都挂一个蓝色色块会把左栏变成花的。 */
.tag-legal-txt { color: var(--ac); }

/* 固定间隔。原先写成内联 style="height:10px"，为 CSP 的 style-src 收紧过一轮，
 * 这类固定值一律进 CSS。 */
.gap-10 { height: 10px; }

/* 紧凑版说明条与上边距。用 data-* 属性而不是再造两个类名：
 * 它们是同一个 `.note` / `.weak-hd` 的排版变体，不是新组件。 */
.note[data-inline="tight"] { padding: 8px 0 0; border: 0; }
.weak-hd[data-mt="1"] { margin-top: 14px; }

/* ---- 账号·分成：单表 + 行内展开 --------------------------------------- *
 *
 * 这一版取代了原来的左右两栏（用户 2026-08-24：「整个页面有点复杂」）。
 * 与结算周报的「按账号明细」同一个模式，样式也刻意复用 `.acc-row` / `.caret`：
 * 两页的展开交互长得一样，学一次就够。
 */

/* 承载展开内容的那一行。去掉单元格内边距，让内部块自己控制。 */
tbody tr.acc-exp-row > td { padding: 0; background: var(--sink); }

.acc-exp { padding: 10px 14px 12px; }

/* 操作条。**账号级按钮只出现在这里** —— 收起态整张表没有按钮，
 * 一屏才不会像上一版那样堆着二十几个任何时候都不该点的按钮。 */
.acc-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--ln);
  font-size: 11px;
}

/* 一个代理一块。**必须有明确边界**：同一账号下每个代理是独立的 100% 额度与
 * 独立法人，视觉上连成一片会让人以为那些比例在同一个池子里。 */
.ag-box {
  margin-top: 10px;
  padding: 9px 11px;
  border: 1px solid var(--ln);
  border-radius: 4px;
  background: var(--pn);
}
/* 失效的代理左侧给红条：它下面的比例都不生效，分成正在静默归零。 */
.ag-box.stale { border-color: rgba(var(--neg-rgb), .35); box-shadow: inset 2px 0 0 var(--neg); }

.ag-hd {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 8px;
  font-size: 11px;
  color: var(--mu);
}
.ag-hd b { color: var(--tx); font-size: 12px; font-weight: 600; }
/* 代理级操作推到右端，与账号级操作条在视觉上分开层级。 */
.ag-acts { margin-left: auto; display: flex; gap: 6px; }

.ag-foot { margin-top: 7px; font-size: 11px; color: var(--dim); }

/* 展开区里的客户表：比外层紧，且表头不 sticky（它在展开区里 sticky 会错位）。 */
.ag-box table thead th {
  position: static;
  padding: 3px 8px;
  font-size: 10px;
  background: none;
  border-bottom: 1px solid var(--row-ln);
}
.ag-box table tbody td { padding: 3px 8px; font-size: 12px; }

/* ---- 账号·分成主表：合并格表达层级 ------------------------------------- *
 *
 * 用户 2026-08-24 指出「没有体现哪些代理属于哪个账号，同一个站点下面可能有多个账号」。
 * 前后做过七版原型（卡片 / 色带 / 一行一代理 / 合并格 / 钻取 / 分组头吸顶 / 减法），
 * 2026-09-01 定了合并格这版，并按用户要求把层级排成：
 *
 * ```text
 *   合并格            代理行            客户列
 *   平台+账号     →   一行一个代理  →   客户数 + 客户名
 * ```
 *
 * 上一版是「同平台账号数超过 1 时才插一行站点名（`.site-row`）」，于是**有没有那行分组头
 * 本身成了一条要用户去推断的信息**，而搜索过滤之后那行就没了，只剩「3号」这种看不出归属
 * 的名字。合并单元格把归属交给单元格的**物理边界**回答：不必读文字、不必辨色、也不多占
 * 任何一行，而且这正是 Excel 里表达层级最传统的做法 —— 用户对账时天天看这种表。
 *
 * ## rowspan 本身「看不出来」，边界要靠三条线索一起给
 *
 * 相邻两行之间少一条 1px 的线，在密集表里扫视时根本注意不到。所以：
 *
 *   1. 合并格自己的底色 + 右侧竖线 —— 画成一条纵向的「槽」，左右边界成立
 *   2. 账号组的上下边界 2px —— 合并只管左右，上下要靠这个才有「框」
 *   3. 平台组的末尾用强调色再重一档 —— 见 `.plat-end` 的说明
 */

/* **表体单元格统一 top 对齐。** 不加这条时合并格里的账号名会比代理名高出几像素：合并格
   是 `top`，而右边四个 `<td>` 继承的是默认 `middle` —— 合并格跨 3 行时高度是代理行的三倍，
   `middle` 会把代理名钉在它自己那一行的中线上，两边基线对不齐。

   **必须用子选择器 `> tbody > tr > td`。** 写成后代选择器会连展开区里嵌套的客户表一起
   命中，那张表的单元格应当保持 `middle`。 */
.acc-tbl > tbody > tr > td { vertical-align: top; }

/* ---- 合并格：平台 + 账号 + 抓取 + 账号设置 ------------------------------ */

/* 它是 `<th scope="rowgroup">` 而不是 `<td>`（读屏会把它当作这组行的行组表头念出来），
   所以 `tbody td` 与 `thead th` 两套规则都命中不到它，排版要在这里从头给全。
   这其实是好事：合并格要的边框规则与普通行相反（整组的上下边界，而不是每行一条底线），
   落在自己的选择器里写，不必跟 `tbody td` 打层叠优先级的架。 */
.acc-tbl th.acc-own {
  /* 与上面那条一起才成立：只给合并格 top、不给代理格 top，仍然是错位。 */
  vertical-align: top;
  padding: 7px 12px;
  text-align: left;
  font-weight: 400;

  /* **底色必须不透明。** 这一格物理上属于组内第一个代理的 `<tr>`，而
     `tbody tr.acc-row.open td` 是把底色打在行上的 —— 单元格透明时，展开第一个代理会让
     整块合并格一起变色，看起来像「整个账号被选中了」。给它自己一层 `--pn2` 就同时解决了
     串色和「合并块要看得出来」两件事。 */
  background: var(--pn2);

  /* 右侧竖线 = 合并块的右边界。1px 就够：左边界由表格自身的左沿给。 */
  border-right: 1px solid var(--ln);

  /* 光标不要继承 `tbody tr.click` 的 pointer：这一格不可点（JS 里也 stopPropagation
     拦掉了冒泡），显示成可点会让人以为点它有别的作用。 */
  cursor: default;

  /* 内部分两列后，宽度由「左侧文字 + 右侧按钮列」决定。不给下限的话「金好运-3号」这类
     长名字会被挤成两行 —— 而那正好抵消掉两列布局要省的纵向空间。 */
  min-width: 208px;
}

/* 账密错误 / 已熔断：左侧一条 3px 负色竖条。
   做在 inset box-shadow 上而不是 border-left —— border 会改变盒宽，让异常账号与正常账号
   的第一列宽度差 3px，整表左沿看起来是歪的。 */
.acc-tbl th.acc-own.bad { box-shadow: inset 3px 0 0 rgba(var(--neg-rgb), .85); }

/* 已停用：整格压暗，但**不隐藏** —— 用户要能看到它还在，只是不参与采集。 */
.acc-tbl th.acc-own.off { opacity: .62; }

/* 合并格内部的两列：左边文字，右边按钮。
 *
 * 用户 2026-09-01：「上面两个字抓取，下面两个字账号设置，这样会节省一点纵向的空间。」
 * 竖排三行（名字 / 状态 / 按钮）时按钮那一行自己就占三十几像素；两列之后格子高度
 * = max(左侧两行, 右侧两个按钮)，每个账号组省下约 20px。
 *
 * **用 div 包一层，不能让 `<th>` 自己 `display: flex`**：th 一旦变成 flex 容器，
 * `vertical-align: top` 就失效（那条属性只对 table-cell 生效），而合并格跨多行时必须靠
 * 它把内容钉在顶部。`align-items: flex-start` 而不是默认的 stretch：合并格跨 3 行时高达
 * 一百多像素，stretch 会把两列都拉成那么高，按钮跟着被拉开、与账号名对不齐。 */
.acc-own-box { display: flex; align-items: flex-start; gap: 10px; }

/* 左列占满剩下的宽度。**`min-width: 0` 不能省** —— flex 子项默认 `min-width: auto`，
   长账号名会把这一列顶宽、把按钮列挤出合并格。 */
.acc-own-info { flex: 1; min-width: 0; }

/* 平台 - 登录名。平台名压暗一档、登录名加重：两者都写全（这一格是归属的唯一出处），
   但扫视目标是登录名。

   **column-gap 必须是 0。** 分隔符「-」是一个独立元素（只靠 flex 间距时 textContent 会
   变成「金好运3号」，读起来像两个不相干的词），沿用 4px 的 gap 会让它两边各空 4px、
   看起来像个减号。row-gap 留着：长备注换行时两行不该贴在一起。 */
.acc-own-name {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  column-gap: 0;
  row-gap: 2px;
  line-height: 16px;
}
.acc-own-name b { color: var(--tx); font-weight: 600; font-size: 13px; }
.acc-own-site { color: var(--mu); font-size: 11px; }
.acc-own-dash { color: var(--dim); font-size: 11px; margin: 0 2px; }

/* 第二行：状态标签 + 最近成功。 */
.acc-own-sub {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 4px;
  font-size: 11px;
}

/* 右列：两个按钮竖排。`align-items: stretch` 让它们等宽 ——「抓取」两字、「账号设置」
   四字，不等宽时右边缘参差不齐。 */
.acc-own-acts {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
  flex: none;
}

/* **按钮必须压到比左列文字矮，否则这次改动等于白做。**
 *
 * 实测过程：按 `.btn` 默认的 `3px 8px` 内边距，每个按钮 23px，两个加 4px 间距 = 50px，
 * 而左列两行文字只有 42.6px —— **按钮反过来成了决定格子高度的那一项**，格子只从 78.4px
 * 降到 66px，省下的空间被它吃掉一半。去掉上下内边距后每个 19px，两个加间距 42px < 42.6px，
 * 文字重新成为上限，格子才降到 58.6px。
 *
 * 判据很简单：**让文字成为那一格里最高的元素。** 控件默认高度往往大于文字行高，
 * 压密度时先量控件，再动内边距。 */
.acc-own-acts .btn {
  padding: 0 8px;
  line-height: 17px;
  white-space: nowrap;
  text-align: center;
}

/* 「账号设置」展开时反色，让按钮自己说明「下面那一行是我开出来的」。 */
.acc-set-btn.on {
  border-color: var(--ac);
  background: var(--ac);
  color: var(--on-ac);
  font-weight: 600;
}

/* ---- 代理行 ------------------------------------------------------------- */

/* 代理名列。**不缩进** —— 归属已由合并格表达，再缩进只会让代理名与表头对不齐
   （上一版的 `.in-site` 缩进 20px 是为了表达「我属于上面那个分组头」，现在不需要了）。 */
.acc-tbl td.ag-name { padding-left: 12px; }

/* 失效代理整行压暗：它名下的比例已经不生效，不该跟正常代理抢注意力。
   但仍然显示（行内有「已失效」红标）—— 藏起来用户就不知道要去新代理下重配。 */
.acc-tbl tbody tr.stale td { opacity: .72; }

/* 客户列：数字 + 名字串。**必须能截断** —— 一个代理下 5 个客户会把这列拉得很宽，
   把右边两列挤出视区。`tbody td` 已有 `white-space: nowrap`，所以只补 max-width 与
   ellipsis 就够；全文在 `title` 里（见 accounts.js 的 agentCells）。 */
.acc-tbl td.cust-cell { max-width: 260px; overflow: hidden; text-overflow: ellipsis; }
.cust-names { font-size: 11px; }

/* 「还没有代理」那一行：说明为什么没有、下一步做什么。压暗，它不是扫视目标。 */
.acc-tbl td.ag-none { white-space: normal; font-size: 11px; line-height: 17px; }

/* ---- 账号设置行 --------------------------------------------------------- */

/* 复用 `.acc-exp-row`，所以内边距与 `--sink` 底色已由那条规则给（见上面「单表 + 行内
   展开」一节）。这里只给内部盒子的内边距。 */
.acc-setbox { padding: 8px 14px 10px; }

/* ---- 分组边界 ----------------------------------------------------------- *
 *
 * 上面那条 `tbody tr.acc-row td { border-top: 1px solid var(--ln) }` 是给「每行都是一个
 * 独立账号」的旧结构写的。放到这一版里会**把每一个代理行都画成组边界**，于是真正的组边界
 * 与组内分行长得一模一样 —— 合并单元格白做了。
 *
 * 所以先清掉它，再只在组的首尾各画一条。
 *
 * **两条规则的选择器权重必须掰清楚，原型阶段踩过一次。** 当时重置写成 `tr.acc-row td`
 * (0,2,3)、边界写成 `tr.gtop > *` (0,2,2)，于是重置反过来压住了边界：`<td>` 拿到
 * `border-top: 0`，只有不被重置命中的 `<th>`（合并格）画出了那条线。表现是**组的上边界
 * 只在最左边一格有线，右边几列没有** —— 框缺了一整条顶边，而这一版全靠这个框表达分组。
 *
 * 现在：重置 `.acc-tbl tbody tr.acc-row > *` 是 (0,2,2)，压过原规则的 (0,1,3)；
 * 边界多带一个类升到 (0,3,2)，稳压重置，不依赖两条规则在文件里的先后顺序。 */
.acc-tbl tbody tr.acc-row > * { border-top: 0; }

/* 账号组的上边界。`> *` 一起覆盖 `<th>` 与 `<td>` —— 只写 td 的话合并格那一段会缺一截线，
   框就断在左上角。 */
.acc-tbl tbody tr.acc-row.acc-gtop > * { border-top: 2px solid var(--ln); }

/* 账号组的下边界。**不能限定 `.acc-row`** —— 组内最后一个代理展开时、或账号设置行打开时，
   `acc-gend` 落在那一行 `.acc-exp-row` 上，限定 `.acc-row` 会让这两种情况下的组末没有
   下边界。`tbody td` 的 1px 底线权重只有 (0,0,2)，这条 (0,2,2) 稳压它。 */
.acc-tbl tbody tr.acc-gend > * { border-bottom: 2px solid var(--ln); }

/* 平台组的下边界：强调色，再重一档。
 *
 * **合并格是账号级的，平台这一层没有别的装置在表达了** —— 金好运有 2 个账号、皇朝有 2 个，
 * 它们各自有自己的合并格，光看格子分不出「这两个账号属于同一个站」。这条线是那一层唯一的
 * 表达，所以必须比账号组的边界更明显。
 *
 * 写在 `.acc-gend` 之后：两个类会同时落在同一行上（平台组的最后一行必然也是某个账号组的
 * 最后一行），权重相同 (0,2,2) 时后写的胜出。 */
.acc-tbl tbody tr.plat-end > * { border-bottom: 2px solid rgba(var(--ac-rgb), .55); }

/* ---- 跳过来时闪一下（B1 / B2）--------------------------------------------- *
 *
 * 结算周报与本周数据可以带 `?account=&agent=` 跳到这一页改比例（见 accounts.js 末尾的
 * URL 定位）。**光滚过去不够** —— 页面看起来只是停在一个随机位置，用户不知道该看哪一行。
 *
 * **权重必须压过 `tbody tr.acc-row.open td`（0,2,3）**：跳过来时那一行往往正是展开态
 * （定位会自动展开目标代理），而那条规则给 `--pn2` 底色。写成 `.acc-flash > *` 只有
 * (0,2,2)，会被它压住 —— 表现是「滚过去了但没有任何高亮」。多带一个 `.acc-row` 升到
 * (0,3,2)，类数先比，稳压。`> *` 一起覆盖 `<th>`（合并格）与 `<td>`。
 *
 * **用底色而不是 @keyframes**：全站至今没有一条关键帧动画，只有 transition（房子风格）。
 * 单次淡入淡出也不涉及闪烁，不必额外处理 `prefers-reduced-motion`；滚动本身用的是
 * 默认的瞬时行为，没有平滑滚动。 */
.acc-tbl tbody tr.acc-row.acc-flash > * {
  background: rgba(var(--ac-rgb), .18);
}

/* 让高亮淡入淡出。**放在基础规则上而不是 `.acc-flash` 里** —— 写在后者里的话，
   摘掉类的同时 transition 也跟着消失，高亮会硬切回去。
   0.16s 与全站其余 transition 同一档。 */
.acc-tbl tbody tr.acc-row > * { transition: background .16s ease; }

/* ---- 行内「配分成」链接（B1 / B2）----------------------------------------- *
 *
 * 结算周报的账号明细行、本周数据的代理块头各有一个，都跳到账号·分成页那个代理所在的行
 * （链接由 `api.js` 的 `accountConfigHref()` 构造）。
 *
 * **做成看得出来的小片，而不是一段纯文字链接**：在结算周报里它嵌在一个**整行可点**的
 * `<tr>` 里，长得像普通文字的话用户分不清「点它」和「点这一行」有什么区别 ——
 * 而两者一个是跳到另一页，一个只是展开。
 *
 * 全站没有全局 `a` 规则（链接样式一向各处自己给），所以 color 与 text-decoration
 * 必须在这里写全，不能指望继承。 */
.row-lnk {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border: 1px solid rgba(var(--ac-rgb), .4);
  border-radius: 3px;
  color: var(--ac);
  font-size: 10px;
  text-decoration: none;
  white-space: nowrap;
  vertical-align: 1px;
  transition: background .16s ease;
}
.row-lnk:hover { background: rgba(var(--ac-rgb), .14); }

/* 代理块头是 flex 容器且已有 8px gap，上面那 6px margin 会叠上去变成 14px。 */
.wk-agent .row-lnk { margin-left: 0; }

/* ---- 展开区里的归属前缀 ------------------------------------------------- */

/* 代理块头部的归属前缀（`皇朝-主号 ›  A区-陈`）。**week.js 也在用**，不要跟着主表一起改。
   刻意比代理名弱：它是定位用的上下文，主体仍是代理名。

   这一版主表已经把归属画在合并格上，但展开区仍然需要它：展开区可以滚得很长，
   块头离开合并格的视野之后，这个前缀是唯一还带着「这是谁的代理」的东西。 */
.ag-owner { color: var(--dim); font-size: 11px; }
.ag-sep { margin: 0 5px; color: var(--ln); }

/* ---- 页脚版本号 -------------------------------------------------------- *
 *
 * 用户 2026-08-24 要求可回退。回退的实际难点不是切代码，是**切完怎么确认真的切过去了** ——
 * 浏览器缓存会让「部署了但页面没变」同时对应「回滚没生效」和「拿了缓存」两种情况，
 * 有版本号才能一眼分开。所以它必须每页可见，但不能抢注意力。
 */
.ver {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 10px 20px 14px;
  font-size: 11px;
  color: var(--foot);
}
/* 等宽：版本号是要被读出来、对着念的字符串，比例字体下 1 和 l 容易看混。
   字体栈与 `.mono`（第 71 行）保持一致 —— dense.css 没有字体变量，别写 var(--mono)。 */
.ver-num {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  color: var(--dim);
}

/* ---- 结算周报：加载提示与币种分组标题 --------------------------------- */

/* 汇总要吃全部命中行，比报表列表慢。空白一两秒会像点了没反应。 */
.loading { padding: 20px; font-size: 12px; color: var(--mu); }

/* 多币种时的分组标题。**只在真出现第二个币种时渲染**（见 board.js 的 loadBoard）。
   写成类而不是 attrs.style：CSP 的 style-src 将来要收紧到不含 'unsafe-inline'，
   届时内联 style 会被整条丢掉，而那是静默失效。 */
.cur-title { font-size: 13px; }

/* ---- 页面正文外框与筛选表单 -------------------------------------------- *
 *
 * 这一段是合并时从 `style.css` 移植过来的（用户 2026-08-24：展示按 dev、数据按主站）。
 * **不是照搬**：那边是浅色主题、rem 尺寸、居中 `.wrap`；dense 是深色、px、通栏。
 * 只保留行为约定（选中态由 aria-pressed 驱动、周按钮可换行），视觉重做。
 */

/* 正文左右留白。**三页必须一致**（用户 2026-09-01：「本周数据和账号分成左边顶太满，
 * 应该跟结算周报一样离边框有点间距」）。
 *
 * 病因是两种页面结构：结算周报的内容全在 `<main class="page">` 里、吃到了这份
 * padding；而 week / accounts 是裸 `<div id="root">`，一点内边距都没有 ——
 * 于是表格与 KPI 直接贴在窗口左边缘（实测 left: 0）。
 *
 * `.note` / `.bar` / `.foot` 各自带 `padding: … 20px`，所以那几条看起来正常，
 * 一眼扫过去只觉得"表格挤"，实际是整个容器都贴边。
 *
 * **左右给 padding、下边给 padding，但上边不给**：页头是 sticky 通栏元素、不在这个
 * 容器内，给上边距会在页头与第一块内容之间多出一条空隙。
 *
 * 不用 `max-width` 居中壳（style.css 那套 68rem）—— 密集表格的价值就在于一屏能放
 * 更多列。 */
.page { padding: 0 20px 40px; }
/* **只给左右，不给下边距。** 结算周报的 `#ver` 在 `.page` 内部，那 40px 落在版本号
 * 之后当页面底部留白；而 week / accounts 的 `#ver` 是 `#root` 的**兄弟**，同样的
 * 40px 会插在表格与版本号之间 —— 那是一道原本没有的空隙，而用户提的只是左边。 */
#root { padding: 0 20px; }

.page h1 { font-size: 15px; font-weight: 600; margin: 16px 0 6px; }
.page h2 { font-size: 13px; font-weight: 600; margin: 22px 0 6px; }

.sub { color: var(--mu); font-size: 11px; margin: 0 0 12px; }
.sub.tight { margin: 0 0 8px; }
.sub strong { color: var(--tx2); font-weight: 500; }
.sub a { color: var(--ac); text-decoration: none; }
.sub a:hover { text-decoration: underline; }

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  align-items: flex-end;
  padding: 10px 12px;
  background: var(--pn);
  border: 1px solid var(--ln);
  border-radius: 5px;
}
.filters .field { display: flex; flex-direction: column; gap: 3px; }
.filters label, .field-label { font-size: 11px; color: var(--mu); }

.filters input, .filters select {
  font: inherit;
  font-size: 12px;
  padding: 3px 7px;
  border: 1px solid var(--ln);
  border-radius: 4px;
  background: var(--pn2);
  color: var(--tx);
}
.filters input:focus, .filters select:focus { outline: 1px solid var(--ac); border-color: var(--ac); }
.filters button[type="submit"] {
  font: inherit;
  font-size: 12px;
  padding: 4px 12px;
  border: 1px solid var(--ac);
  border-radius: 4px;
  background: var(--ac-bg);
  color: var(--ac);
  cursor: pointer;
}

/* 周选择器：‹ 下拉 ›。
 *
 * 一年 52/53 周，按钮组会占满整屏，所以用下拉 + 前后翻。两侧箭头是为了「上周、
 * 再上周」这类连续往回看 —— 那是最常用的动作，每次都展开下拉找一遍太慢。
 *
 * 选项文字里带日期区间（见 settlement.js 的 `weekLabel`），所以下拉要给足宽度：
 * `min-width` 兜住「第 35 周　08-24 → 08-30」不被截断成省略号。 */
/* 「補抓這一週」那一格：只有一个按钮、没有 label。
 *
 * `.filters` 是 `align-items: flex-end`，所以它自然与两个下拉底边对齐。但 `.btn` 是
 * 11px / `padding: 3px 8px`，而 `.filters select` 是 12px / `3px 7px` —— 直接放会比
 * 下拉矮两三个像素，一排控件里那点不齐很显眼。这里对齐到与 `.filters` 里其它控件
 * 相同的字号与内边距。
 *
 * **不能复用 `.filters button[type="submit"]` 那条规则**：这个按钮刻意是
 * `type="button"`（它在 <form> 里，submit 会提交表单并重载页面，选中的周会丢）。 */
.filters .field-act .btn { font-size: 12px; padding: 4px 12px; }

.week-pick { display: flex; align-items: center; gap: 4px; }
.week-pick select { min-width: 15em; }
.week-pick button {
  font: inherit;
  font-size: 13px;
  line-height: 1;
  padding: 4px 8px;
  border: 1px solid var(--ln);
  border-radius: 3px;
  background: var(--pn2);
  color: var(--tx2);
  cursor: pointer;
}
.week-pick button:hover:not(:disabled) { border-color: var(--ac); color: var(--ac); }
/* 到头了要看得出来，否则用户会反复点一个没反应的按钮。 */
.week-pick button:disabled { opacity: .35; cursor: not-allowed; }

.pager {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
  font-size: 11px;
  color: var(--mu);
}
.pager button { font: inherit; font-size: 11px; padding: 2px 8px; border: 1px solid var(--ln);
  border-radius: 4px; background: none; color: var(--mu); cursor: pointer; }
.pager button:hover:not(:disabled) { color: var(--ac); border-color: var(--ac); }
.pager button:disabled { opacity: .4; cursor: not-allowed; }


/* 报表行里的用户名列：这一列是扫读锚点，比其他列亮一档。 */
.cell-title { color: var(--tx); }

/* `.num` 的完整定义。
 *
 * 第 69 行那条只给了 `font-variant-numeric`（等宽数字），**没有右对齐** ——
 * 而 style.css 里 `.num` 是带 `text-align: right` 的，`settlement.js` 与 `accounts.js`
 * 的金额列在用它。漏掉这条，迁过来的金额会全部变成左对齐，
 * 密集表格就无法竖向扫读（规格 §9 把它列为第一号错误）。
 *
 * dense 自己的表格用 `.r`（见第 361/372 行的 `th.r` / `td.r`）。两个类并存是刻意的：
 * `.r` 只管对齐、能用在任何单元格上；`.num` 额外带 nowrap，用于金额。
 */
.num { text-align: right; white-space: nowrap; }

/* 正文里的横幅。
 *
 * dense 的 `.banner`（第 236 行）是**通栏警示条**：左右 20px 内边距 + 下边框，
 * 直接贴在页头下面。而结算周报把 `#banner` 放在 `.page` 内部当状态提示用，
 * 那里需要的是一张卡片 —— 否则会双重缩进，且下边框只有内容宽度，看起来像根断线。
 *
 * **用后代选择器改写，不加修饰类**：`settlement.js` 会整体重写 className
 * （`banner.className = 'banner info'`），任何写在 HTML 上的修饰类都会被抹掉。
 */
.page .banner {
  padding: 7px 10px;
  border: 1px solid rgba(var(--wn-rgb), .25);
  border-radius: 4px;
  margin-bottom: 12px;
}

/* 中性提示。**必须有这一条**：`.banner` 基础色是黄色警示，而「已提交采集，正在等报表」
   这类进行中状态不是警告 —— 染成黄色会让人以为出了问题。
   `.banner.warn` 不需要覆写：基础色本来就是警示色。 */
.banner.info {
  background: var(--pn);
  border-color: var(--ln);
  color: var(--mu);
}

/* 周按钮那一格的间距比其他 field 紧：标签与按钮组之间不需要输入框那么大的呼吸。 */

/* ---- [hidden] 必须真的隐藏 --------------------------------------------- *
 *
 * **这条不能删。** `hidden` 属性靠的是 UA 样式表里的 `[hidden] { display: none }`，
 * 那条规则的优先级最低 —— 任何作者样式里的 `display` 都会盖掉它。
 *
 * dense 里 `.banner` 与 `.pager` 都是 `display: flex`，于是 `<div class="banner" hidden>`
 * 会照常显示：页面上多出一个空的黄色警示框，看起来像「有警告但文字没加载出来」。
 * 已在结算周报页实测到（2026-08-24 合并时）。
 *
 * 用 `!important` 是因为它要压住的正是同等或更高优先级的 class 规则；
 * 这是 `[hidden]` 这一条少数确实该用 important 的场合。
 */
[hidden] { display: none !important; }

/* ---- 表单弹窗（dialog.js） --------------------------------------------- *
 *
 * 用原生 `<dialog>`：焦点陷阱、Esc、背景 inert 都由浏览器给，自己用 div 模拟会漏掉
 * 键盘可达性。这里只管外观。
 */

.dlg {
  width: min(380px, calc(100vw - 32px));
  padding: 0;
  border: 1px solid var(--ln);
  border-radius: 6px;
  background: var(--pn);
  color: var(--tx);
}
/* `::backdrop` 不继承页面的字体与颜色，且不受 `.dlg` 的层叠影响，必须单独写。 */
.dlg::backdrop { background: var(--scrim-strong); }

.dlg form { display: flex; flex-direction: column; gap: 10px; padding: 14px 16px 16px; }
.dlg h3 { margin: 0; font-size: 13px; font-weight: 600; }

/* 说明段。`white-space: pre-line` 让文案里的换行生效 —— 这些说明常要分点写
   （比如「改完不会自动恢复调度」），挤成一段没人会读完。 */
.dlg-note {
  margin: 0;
  font-size: 11px;
  line-height: 1.6;
  color: var(--mu);
  white-space: pre-line;
}

.dlg-f { display: flex; flex-direction: column; gap: 3px; }
.dlg-f label { font-size: 11px; color: var(--mu); }
.dlg-f input, .dlg-f select {
  font: inherit;
  font-size: 12px;
  padding: 4px 7px;
  border: 1px solid var(--ln);
  border-radius: 4px;
  background: var(--pn2);
  color: var(--tx);
}
.dlg-f input:focus, .dlg-f select:focus { outline: 1px solid var(--ac); border-color: var(--ac); }
/* 数字框右对齐：比例是要和旁边的额度对着看的数字。 */
.dlg-f input[type="number"] { text-align: right; font-variant-numeric: tabular-nums; }
.dlg-hint { font-size: 11px; color: var(--dim); }

/* 错误条。**出错时弹窗不关**（见 dialog.js），所以这条要显眼到不会被忽略，
   否则用户会以为点了没反应而反复提交。 */
.dlg-err {
  padding: 6px 8px;
  border: 1px solid rgba(var(--neg-rgb), .4);
  border-radius: 4px;
  background: var(--neg-bg);
  color: var(--neg);
  font-size: 11px;
  line-height: 1.5;
}

.dlg-acts { display: flex; justify-content: flex-end; gap: 6px; margin-top: 2px; }

/* 危险操作按钮（删除）。用红描边而不是红底：红底按钮在深色界面里过于抢眼，
   而这个按钮多数时候只是摆在那里不该被点。 */
.btn.danger { border-color: rgba(var(--neg-rgb), .5); color: var(--neg); }
.btn.danger:hover { background: var(--neg-bg); border-color: var(--neg); }

/* ---- 展开行里的成句文字必须能换行 ------------------------------------- *
 *
 * `tbody td` 有 `white-space: nowrap`（第 367 行），那是为数字列服务的：金额、时间、
 * 比例断行会让密集表格无法竖向扫读。
 *
 * **但展开行的 `td` 里装的是整段说明**（账号状态解释、周内预估警示、空态提示），
 * nowrap 会让它们永不换行、直接被右边缘截掉 —— 而那些正是出问题时最该被读完的文字。
 * 截图才发现，量宽度和查类名都抓不到（页面本身没有溢出，是表格在 .tablewrap 里横向滚动）。
 *
 * 只重置外层展开 `td`：里面嵌套的客户表 `tbody td` 会被那条规则重新命中，
 * 数字列仍然保持 nowrap，正是想要的结果。
 */
tbody tr.acc-exp-row > td,
tbody tr.wk-exp-row > td { white-space: normal; }

/* ---- 登录页 ------------------------------------------------------------- *
 *
 * 登录页**没有 `header.top`、汉堡按钮与导航抽屉**：未登录状态下那些入口都会跳回登录页，
 * 摆在那里只会让人以为点了没反应。所以这一段是全站唯一不带页头的布局。
 *
 * 从 style.css 移植，但 `.auth-name` 的 `var(--brand)` **不能照搬** —— dense.css 里
 * 没有这个变量，直接搬过来会拿到一个空值，文字退回继承色。改用 `--tx`。
 */

body.centered {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  box-sizing: border-box;
}

main.auth {
  width: 100%;
  max-width: 340px;
  background: var(--pn);
  border: 1px solid var(--ln);
  border-radius: 8px;
  padding: 22px 22px 20px;
}

main.auth h1 { font-size: 15px; font-weight: 600; margin: 0 0 12px; }

.auth-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 14px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--ln);
}

/* 标志图。**不要加 background 或 border-radius**：money-eyes.svg 自带 #0E4F4A 圆角
 * 底板（viewBox 100 上 rx=22），再叠一层会让两个圆角对不齐、露出品牌绿的边。
 *
 * `display:block` 去掉 inline 元素的基线间隙（否则图与右侧文字块底部差几像素）；
 * `flex:none` 防止它在这一行被压窄。 */
.auth-mark { width: 40px; height: 40px; display: block; flex: none; }

.auth-name { font-weight: 600; color: var(--tx); letter-spacing: -0.01em; font-size: 13px; }

/* 纵向单列，与筛选栏那种横向 `.filters` 刻意不同。 */
main.auth form { display: flex; flex-direction: column; gap: 12px; }
main.auth .field { display: flex; flex-direction: column; gap: 4px; }
main.auth .field label { font-size: 11px; color: var(--mu); }

/* **输入框必须自己给样式。** dense.css 里的输入框规则都限定在 `.filters` 与 `.dlg-f`
 * 作用域内，登录页的裸 `<input>` 命中不到 —— 那样会拿到浏览器默认的浅色外观，
 * 在深色卡片上是一块突兀的白底。 */
main.auth input {
  font: inherit;
  font-size: 13px;
  width: 100%;
  box-sizing: border-box;
  padding: 7px 9px;
  border: 1px solid var(--ln);
  border-radius: 4px;
  background: var(--pn2);
  color: var(--tx);
}
main.auth input:focus { outline: 1px solid var(--ac); border-color: var(--ac); }

main.auth button[type="submit"] {
  font: inherit;
  font-size: 13px;
  margin-top: 4px;
  padding: 8px;
  border: 1px solid var(--ac);
  border-radius: 4px;
  background: var(--ac-bg);
  color: var(--ac);
  cursor: pointer;
}
main.auth button[type="submit"]:hover:not(:disabled) { background: rgba(var(--ac-rgb), .2); }
main.auth button[type="submit"]:disabled { opacity: .55; cursor: not-allowed; }

/* 卡片内的横幅：`.banner` 基础规则是通栏警示条（左右 20px + 下边框），
 * 在卡片里要改成一张小卡，否则会顶满卡片宽度且下边框看起来像根断线。
 * 与 `.page .banner` 同一个理由。 */
main.auth .banner {
  padding: 7px 9px;
  margin-bottom: 12px;
  border: 1px solid rgba(var(--wn-rgb), .3);
  border-radius: 4px;
}

.auth-note {
  margin: 15px 0 0;
  font-size: 11px;
  color: var(--foot);
  line-height: 1.6;
}
