/* —— 手写体问候语：霞鹜文楷（用户 2026-09-26 从 14 款候选中选定 1 号）——
   @font-face 内嵌的是 GB2312 一级常用字（3755 字）+ 常用标点子集（woff2 约 840KB），
   覆盖日常问候语所需字符；用户以后自定义问候语（lw_greet）只要用常用字就不会缺字。
   回退栈接系统楷体：缺字时降级到设备楷体，不破版、不混淆风格。 */
@font-face{font-family:'LXGW WenKai';src:url(../fonts/lxgw-wenkai.woff2) format('woff2');
  font-weight:400;font-display:swap}
.wel-greet{font-family:'LXGW WenKai','Kaiti SC','STKaiti','KaiTi','楷体',cursive}
:root{
  /* 卡片标题左内边距基准 —— 让「案件统计」能和「律师费收支总计」左对齐
     （用户 2026-09-17 指定）。

     为什么需要一个变量而不是直接写数字：两者的外框结构不同。
       · .kpi-merged：元素自身带 1px 边框 + 4px 内边距，标题 .kpi-head 再给 18px
         → 图标起点 = 卡片外边界 + 1 + 4 + 18 = 偏移 23px
       · .st-card：  元素自身 1px 边框，标题 .card-head 直接给 14px
         → 图标起点 = 卡片外边界 + 1 + 14 = 偏移 15px
     差 8px，这就是标题肉眼看着偏左的原因（430px 实测：图标差 8px、文字差 9.25px）。

     变量取值 = 「kpi 那边图标距卡片外边缘的距离」减去「本卡片自身 1px 边框」：
       · 宽屏：kpi 偏移 23px（1 边框 + 4 padding + 18 head）→ 本值 22px
       · 窄屏：kpi 偏移 19px（.kpi-head padding 降到 14）  → 本值 18px
     用变量而不是两边各写数字：任一侧以后改了间距，对齐会静默失效且很难发现，
     变量至少把「这两个数必须同步」的约束显式留在了同一个地方。 */
  --card-head-pad-l:22px;
  /* 标题图标的固定盒宽 —— 让「案件统计」与「律师费收支总计」的**文字起点**也对齐。
     光把图标左边界对齐还不够：🏛️ 渲染宽度 17.47px、🪙 18.72px（同为 15px 字号，
     不同 emoji 字形宽度本就不同），图标占了不同宽度后面的文字自然差 1.25px。
     把两侧图标都套进同一个定宽盒并居中，文字起点就与字形宽窄无关了。
     取 19px ≈ 🪙 的实测宽度，这样参照那侧的标题只位移 0.28px（看不出来），
     换来的是两边严格对齐、且以后换 emoji 也不跑偏。 */
  --card-head-ico-box:19px;
  --bg:#f3f8fb;
  --card:#ffffff; --card-2:#f7f9fd; --border:#eef1f7; --border-strong:#e0e6f0; --border-stronger:#c9d2e0; --card-grad:var(--card-grad2);
  --fg:#1e2433; --muted:#66708a; --muted-2:#98a2ba; --emerald:#4c6b9e; --emerald-d:#3a5480; --emerald-l:#5677ac;
  /* 压在品牌色（--emerald 渐变）上的前景色 + 品牌色 rgb 分量。
     默认是浅底浅色主色的组合 → 白字没问题（#fff on #4c6b9e ≈ 5.5:1）。
     ⚠ pine 的 --emerald 是荧光黄绿，白字会失效，必须覆盖这两个（见 .btn-primary）。 */
  --on-emerald:#fff; --em-rgb:76,107,158;
  /* 正文强调色的提亮版（深底用得到；浅底一并给全，避免跨主题继承） */
  --em-text-hi:#3a5480; --em-text-hi-d:#2f4668;
  /* 「低于全省」的灰线专用色：三通道接近的纯灰，不随蓝紫调主题偏移。
     用户明确要求"灰色的横线"，所以不能复用 --muted-2（#98a2ba 偏蓝紫）。 */
  --sw-strike:#919191;
  --nav-idle:#3a5480; --tb-icon:#3A4658; --nav-active:#eef3f9;
  --card-grad2:linear-gradient(155deg,#ffffff 0%,#f3f8fb 38%,#d9ecf5 80%,#c9e3f0 100%);
  --doc-tint:#c9e3f0; --doc-tint-base:#ffffff; --doc-tint-on:1;
  --rose:#f0617e; --violet:#8f7ae0; --sky:#3aa8e8; --amber:#e6a23c; --cyan:#2ab7c9; --teal:#22b49e;
  /* 支出专用的正红（用户 2026-09-19：「支出金额用红色」）。
     为什么不复用 --rose：--rose #f0617e 偏粉，用户明确要「红色」。
     #e8354f 与 --rose 同色相族（约 350°），只是饱和度更高、明度更低，
     放在浅底上依然是清晰的「红」而不是「粉」。暗色模式另给更亮的 #ff6b81。 */
  --expense-red:#e8354f;
  /* 案件统计卡：纯蓝底「蓝色版指标卡」（用户 2026-09-16 指定）。
     参照顶部紫色指标卡 .kpi-merged 的实现逻辑 —— 同样是「纯卡片底 + :before 彩色渐变叠加」，
     只是把紫换成蓝（--violet #8f7ae0 → --sky #3aa8e8）。
     关键差别：.st-card 不用 --card-grad2（那是「上白下蓝」的通用卡片渐变，
     用户明确说「卡片不做上白下蓝」），改用 --card 纯色打底。
     --st-tint-a/b 是叠加层渐变的起止色，浅色/暗色各一套（见 body.theme-dim）。
     浓度演进（用户三次反馈，别再调淡回去）：
       ① .13/.045 —— 太淡，用户反馈「这个卡片蓝色太淡了点」；
       ② .22/.10  —— 明显加深，在 #ffffff 上合成后约 #dbe9fa 量级；
       ③ .30/.16（现在）—— 用户又反馈「案件统计 这个卡片 颜色浅了」。
          这个方向被反悔过两次，所以把量也记下来：合成后约 #cddff9，
          比 ① 深约 40%、比 ② 深约 15%，与页面底色 --bg(#f3f8fb) 拉开到
          肉眼一眼能分辨的程度，仍不抢内容（标题 15px/800、数字 800 的
          对比度远高于底色与背景之差）。
      再往上走要警惕：a 值到 .40 以上时蓝色会开始盖过卡片里的分隔线
      （--border 是 #e2e8f0，与深蓝底的明度差被压缩），那时得连边框一起调。
     注意这是**半透明叠加**，实际观感随底层 --card 变化：
     浅色底是 #ffffff，暗色底是 #182234，所以暗色单独给了更高透明度。 */
  --st-tint-a:rgba(58,168,232,.30); --st-tint-b:rgba(42,140,214,.16);
  /* 通用卡片蓝：把案件统计那套蓝底推广到其它卡片
     （用户 2026-09-17：「今日元气满满 / 今日待办 / 近期事项 / 案件类型分布 /
      案件卡片 / 甘特图 / 通讯管理 / 日历 / 日程列表 / 文档中心第一个卡片
      这些卡片颜色深浅参照案件统计卡片的颜色」）。
     为什么另开一套变量而不是直接复用 --st-tint-*：**改一处能一次调全**。
     用户的原话是「颜色深浅**参照**案件统计卡片的颜色」，所以取值上就是**同一个值**：
     浅色 .30/.16、暗色 .44/.24，与 --st-tint-* 严格相等。
     曾按「大卡/中卡/小卡」分过三档（担心列表页成排的卡片会整屏发蓝），
     实测各档合成色与案件统计差 0.03~0.07 明度，肉眼能看出"不是同一个蓝"，
     与"参照"的要求不符 —— 所以三档全部拉平到同一个值。
     保留三个变量名是为了**将来**需要微调时有抓手，现在三者相等：
       --card-tint-*     （大卡：案件列表、甘特图、日历、文档类型卡）
       --card-tint-*-sm  （小卡：今日待办/近期事项/案件类型分布、日程条目）
       --card-tint-*-mid （条目：案件卡片、客户行、文档条目）
     ⚠ 改其中任何一个都要考虑另外两个是否同步，否则又会出现"深浅不一"。
     与 --st-tint-* 一样，浅色/暗色各一套，改一个必须同步改另一个。 */
  --card-tint-a:rgba(58,168,232,.30); --card-tint-b:rgba(42,140,214,.16);
  --card-tint-a-sm:rgba(58,168,232,.30); --card-tint-b-sm:rgba(42,140,214,.16);
  /* 中档：成排出现的条目（案件卡片、客户行、文档条目）。现值与上面两档相等。 */
  --card-tint-a-mid:rgba(58,168,232,.30); --card-tint-b-mid:rgba(42,140,214,.16);
  --shadow:0 1px 2px rgba(30,36,51,.05),0 10px 26px -10px rgba(30,36,51,.10);
  --shadow-soft:0 1px 2px rgba(30,36,51,.04),0 6px 18px -8px rgba(30,36,51,.07);
  --radius:20px; --radius-sm:12px; --nav-bg:#171f31;
  --cal-sel:#93aed2;
  /* 输入框统一底色/描边：此前用 --card-2(#f7f9fd) 与页面底色 --bg(#f3f8fb) 几乎同色，
     搜索框等看起来像「没有框」，这里改为白底 + 更深的描边，从底色中明确分离。 */
  --field-bg:#ffffff; --field-bd-hover:#b9c6d8;
  /* 条件展开的二级输入框（如自定义案件类型）：靠描边与强调线突出，底色保持与普通输入框一致 */
  --type-custom-bd:#9fb4d4; --type-custom-accent:#4c6b9e; --type-custom-ring:rgba(76,107,158,.16);
  --nav-hl:linear-gradient(132deg,rgba(140,180,224,.65) 0%,rgba(160,195,235,.3) 26%,rgba(160,195,235,.12) 44%,rgba(160,195,235,0) 62%);
  --nav-ring:rgba(150,188,228,.9);
  /* ---------- 顶栏天光 / 底栏玻璃 / kpi-home 卡底（浅底默认 = light） ----------
     2026-09-21 变量化：这三处此前是**写死的渐变**，每个新主题都得复制一整条
     `body.theme-X .topbar{...}` 覆盖（上一版 4 主题就已有 12 条这种特例）。
     扩到 6 主题会变成 30+ 条重复，且改一处结构要在 6 个地方同步 —— 必然漏改。
     现统一提成变量，CSS 里只留**一条**通用规则，主题块只给颜色值。
     ⚠ 下面 --top-dim / --top-fade 是「一个值铺满多段」的写法，原因见 .topbar 处注释。 */
  --top-dim:rgba(255,255,255,0);
  --top-glow-1:#a9d5e8; --top-glow-2:#aed8ea; --top-glow-3:#b6dcec;
  --top-glow-4:#c2e2ef; --top-glow-5:#d0e8f2; --top-glow-6:#ddeef6;
  --top-glow-7:#e9f4f9; --top-glow-8:#f3f8fb;
  --top-fade:rgba(243,248,251,0);
  --nav-glass:linear-gradient(180deg,rgba(214,240,247,.21),rgba(178,214,235,.11));
  --nav-bd:rgba(84,136,166,.27);
  --nav-shadow:0 8px 22px -14px rgba(52,96,124,.50);
  --nav-ind:linear-gradient(135deg,#9fd0e8,#6fc0dd);
  --kpi-home-1:#cfe6f4; --kpi-home-2:#e2f0f8; --kpi-home-3:#f7fbfd;
  --wel-bg:linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  /* 工伤待遇计算器顶部条 / LPR 卡：
     ⚠⚠⚠ 2026-09-21 第九版（用户：「把工伤待遇计算器的颜色 还有LPR 卡片的颜色
       都修改一下 按照问候语卡片来。一定万参照！」）
     —— 不再自己调色，改为**与问候卡完全同源**：三处共用同一组变量拼出同一公式：
        卡底   linear-gradient(180deg, --kpi-home-1 0%, --kpi-home-2 46%, --kpi-home-3 100%)
        叠加层 淡色系 = 纵向 rgba(--tint-rgb,.06/.03/0) + 135deg(--card-tint-a,--card-tint-b)
               深色系 = 纵向 rgba(--kpi-dark-rgb,.30/.14/0)
     ⚠ 停靠点统一为 **0 / 46 / 100**（原 --wi-top 与 --lpr 都是 55%），
       与问候卡/第2张卡的 46% 对齐，否则「同公式」不严格成立。
     ⚠ 变量复用策略：--wi-top 直接内联整条公式（它只被 .wi-top 用）；
       LPR 拆成 --lpr-a/m/b（卡底三色）+ --lpr-overlay（叠加层），
       由 .calc-lpr-card 用 `background: var(--lpr-overlay), <卡底>` 合成 ——
       与 .welcome 的「卡底 + ::before 叠加」渲染结果等价，但不需要新增伪元素
       （少一个可能失效的环节，见第八版那条被提前闭合的注释教训）。
     ⚠ 文字色 --wi-top-fg / --lpr-fg 保持不变（各主题品牌深档）；
       对比度已重算：淡色系 4.55~6.49:1、深色系 9.16~13.96:1，全部达标。 */
  --wi-top:linear-gradient(180deg,rgba(var(--tint-rgb),.06) 0%,rgba(var(--tint-rgb),.03) 46%,rgba(var(--tint-rgb),0) 100%),linear-gradient(135deg,var(--card-tint-a),var(--card-tint-b)),linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  --wi-top-fg:#3a5480;
  --wi-top-ov:rgba(0,0,0,.06);
  --lpr-a:var(--kpi-home-1); --lpr-m:var(--kpi-home-2); --lpr-b:var(--kpi-home-3); --lpr-overlay:linear-gradient(180deg,rgba(var(--tint-rgb),.06) 0%,rgba(var(--tint-rgb),.03) 46%,rgba(var(--tint-rgb),0) 100%),linear-gradient(135deg,var(--card-tint-a),var(--card-tint-b)); --lpr-fg:#3a5480;
  /* 卡片叠加层基色 = --card-tint-a 的同色三元组（见 --tint-rgb 说明） */
  --tint-rgb:58,168,232;
  --kpi-tint-rgb:58,168,232; --kpi-tint-rgb-d:42,140,214;
  --kpi-tint-rgb:58,168,232; --kpi-tint-rgb-d:42,140,214;
}
/* ============================================================
   深色模式（dark）—— 原有深蓝底主题，本轮**保持原样不变**
   ------------------------------------------------------------
   它与 ink/pine 共享 61 条 .theme-dim 深底补偿规则，这里只覆盖颜色变量。
   ⚠ --emerald 三兄弟**刻意不覆盖**：dark 是蓝调主题，:root 的 #4c6b9e
     就是它的品牌色（浅底用 #4c6b9e 深值、深底文字用途由
     body.theme-dim .em-text{color:#7fb8e8} 接管）。这是 dark 与
     其它新主题的**关键差异** —— 新主题必须覆盖，dark 不能。 */
body.dark::before,html.dark::before{background:var(--bg)}
body.dark,html.dark{
  --bg:#0f1524; --card:#182234; --card-2:#141d2e; --border:#22304a; --border-strong:#2e3f5e; --border-stronger:#43567c; --card-grad:var(--card-grad2);
  --fg:#e6ebf5; --muted:#94a3bd; --muted-2:#5f6c88; --shadow:0 1px 2px rgba(0,0,0,.4),0 12px 28px -12px rgba(0,0,0,.5);
  /* 暗色下灰线要亮一些才看得见（亮色的 #8b93a3 压在深底上偏暗） */
  --sw-strike:#a3a3a3;
  --shadow-soft:0 1px 2px rgba(0,0,0,.35),0 6px 18px -10px rgba(0,0,0,.4);
  --nav-bg:#0d1420; --cal-sel:#456692;
  --wel-bg:linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  /* 费用计算首页 LPR 卡：同色系三停渐变（与改动前同值，视觉不变） */
  --lpr-a:var(--kpi-home-1); --lpr-m:var(--kpi-home-2); --lpr-b:var(--kpi-home-3); --lpr-overlay:linear-gradient(180deg,rgba(var(--kpi-dark-rgb),.30) 0%,rgba(var(--kpi-dark-rgb),.14) 34%,rgba(var(--kpi-dark-rgb),0) 100%); --lpr-fg:#fff;
  /* --wi-top / --lpr-*：与问候卡同源公式（完整说明见 :root 处第九版注释） */
  --wi-top:linear-gradient(180deg,rgba(var(--kpi-dark-rgb),.30) 0%,rgba(var(--kpi-dark-rgb),.14) 34%,rgba(var(--kpi-dark-rgb),0) 100%),linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  --wi-top-fg:#e6ebf5;
  --wi-top-ov:rgba(255,255,255,.14);
  --nav-idle:#eef3f9; --tb-icon:#B4C0D2; --nav-active:#4a5567;
  --nav-hl:linear-gradient(132deg,rgba(255,255,255,.85) 0%,rgba(255,255,255,.42) 24%,rgba(255,255,255,.16) 42%,rgba(255,255,255,0) 60%);
  --nav-ring:rgba(255,255,255,.9);
  /* 暗色：输入框比卡片底略亮，描边更清楚，避免与背景糊在一起 */
  --field-bg:#1c2740; --field-bd-hover:#43567a;
  --type-custom-bd:#5a7099; --type-custom-accent:#8fb0dd; --type-custom-ring:rgba(143,176,221,.18);
  --card-grad2:linear-gradient(155deg,#19233a 0%,#1a2c44 45%,#15374f 100%);
  /* 暗色模式：文档卡片不跟随浅色渐变，统一用卡片底色 */
  --doc-tint:#182234; --doc-tint-base:#182234; --doc-tint-on:0;
  /* 案件统计卡蓝色叠加层（暗色）：透明度比浅色更高，
     因为深色底 --card(#182234) 上同样的 alpha 观感会弱很多。
     浅色 .30/.16 → 暗色 .44/.24（浅色那边每次加深，这里同步 +.10/+.08 保持比例）。
     ⚠ 两套值要一起改 —— 只改浅色不改暗色，暗色下就比浅色淡一档。 */
  --st-tint-a:rgba(58,168,232,.44); --st-tint-b:rgba(42,140,214,.24);
  /* 通用卡片蓝（暗色）：与 --st-tint-* 同步加深，比例保持一致。
     深底 --card(#182234) 上同样的 alpha 观感弱很多，所以暗色的值一律更高。 */
  --card-tint-a:rgba(58,168,232,.44); --card-tint-b:rgba(42,140,214,.24);
  --card-tint-a-sm:rgba(58,168,232,.44); --card-tint-b-sm:rgba(42,140,214,.24);
  --card-tint-a-mid:rgba(58,168,232,.44); --card-tint-b-mid:rgba(42,140,214,.24);
  /* 正文强调色的提亮版（dark 不覆盖 --emerald，但文字用途需提亮） */
  --em-text-hi:#7fb8e8; --em-text-hi-d:#6a9fe0;
  /* 顶栏天光 / 底栏玻璃 / kpi-home 卡底（深底默认 = dark，变量化见 :root 处说明） */
  --top-dim:rgba(6,14,24,.72);
  --top-glow-1:#2c5f7d; --top-glow-2:#326888; --top-glow-3:#3a7291;
  --top-glow-4:#457f9c; --top-glow-5:#548da8; --top-glow-6:#6699b2;
  --top-glow-7:#7aa6bd; --top-glow-8:#8fb2c7;
  --top-fade:rgba(15,21,36,0);
  --nav-glass:rgba(26,34,46,.23);
  --nav-bd:rgba(255,255,255,.72);
  --nav-shadow:0 8px 22px -14px rgba(0,0,0,.50);
  --nav-ind:linear-gradient(135deg,#a8cfe8,#6fa8cc);
  --kpi-home-1:#16294a; --kpi-home-2:#1d3355; --kpi-home-3:#24405f;
  --tint-rgb:58,168,232;
  /* 深底压暗层的「近黑」基色：dark=近黑蓝，要与蓝色卡底同族 */
  --kpi-dark-rgb:0,4,12;
}
/* ============================================================
   主题变量块 · 浅底二（苔原 moss / 暮云 dusk）
   ------------------------------------------------------------
   2026-09-21 重构：原「暖阳模式（米杏+琥珀）」「墨玉模式（深青绿+亮青）」
   经用户反馈「不好看」，连同新增 4 个一起重做，共 6 主题：
     浅底：light(原有) / moss 苔原 / dusk 暮云
     深底：dark(原有) / ink 玄墨 / pine 松烟

   风格依据（用户选：莫兰迪低饱和 + 自然绿系/森系）：
     · 莫兰迪色 = 所有颜色都掺了灰度，饱和度压低、明度靠中间，
       彼此有共同基调，所以放在一起天然和谐（这也是它「高级」的来源）。
       参考取色：灰豆绿 #a5b4a6 / 灰橄榄 #969687 / 深灰紫 #6D6875 /
       淡灰紫 #d6c6d6 / 雾霾蓝 #96a7c7。（来源：莫兰迪色卡）
     · 森系取色参考 Fernwood 与 Rainforest Canopy 两套自然色板：
       森林阴影 #1A3A2A / 深蕨 #2D5A3D / 苔藓 #7FAF7A / 地衣 #C2D9B8 /
       晨光 #E8F0E4。这两套是**成体系**的（shadow → mid → light 六级递进），
       比单点取色更适合做主题 —— 底色、卡片、边框可以直接落在不同级上。

   ⚠⚠ 每个主题都必须显式覆盖 --emerald 三兄弟 ！
     :root 里 --emerald 是蓝调（#4c6b9e），而深底那套（body.dark）**从未覆盖它**
     —— 它驱动着全站最显眼的品牌色：.btn-primary 渐变、.brand .logo、
     .mobile-nav button 默认色、.set-avatar 描边、:focus-visible 描边、
     .pg.on 分页高亮 ……（styles.css 共 39 处 var(--emerald)）。
     不覆盖的话新主题的按钮/图标/导航仍是蓝的，主题名不副实。
   ⚠⚠ 凡是把 --emerald 换成**浅亮色**的主题，还必须同时给 --on-emerald
     （压在品牌色上的前景色）。
     原因见 .btn-primary 的注释：品牌色亮到一定程度后，写死的白字会
     对比度不足（例如浅亮绿 #C6F24E 上白字仅 1.30:1，几乎看不见）。
   ⚠⚠ 深底主题（dark/ink/plum）还必须覆盖语义色（--rose/--violet/--sky/--amber/
     --cyan/--teal/--expense-red）：:root 那套是给浅底调的，
     压在深底上会发闷（实测 --expense-red #e8354f 在 ink 底上仅 4.36:1）。
     注：--emerald 本身在深底上偏低（如 #4c6b9e 压在 #182234 上 2.96:1），
     但文字用途早已由 body.theme-dim .em-text{color:#7fb8e8}（7.53:1）接管，
     --emerald 在深底只承担「填充」，故不受影响。

   ⚠ 只覆盖**颜色**变量，公共布局变量（--radius / --card-head-pad-l /
     --card-head-ico-box）一律不动 —— dark 也只覆盖颜色，保持一致。
   ⚠ 顶栏天光 / 底栏玻璃 / kpi-home 卡底现在都是**变量驱动**（见后文），
     所以每个主题要把 --top-* / --nav-glass* / --kpi-home-* 一整套给全，
     否则会继承上一主题的色相（这就是上一版「墨玉顶栏是深蓝天光」的病根）。 */

/* ---------- 苔原模式（moss）—— 灰豆绿浅底 + 苔藓绿点缀 ---------- */
body.moss,html.moss{
  --bg:#EFF3EA; --card:#FBFCF8; --card-2:#F4F7EF;
  --border:#E2E9D9; --border-strong:#D2DCC5; --border-stronger:#B9C7A8;
  --card-grad:var(--card-grad2);
  --card-grad2:linear-gradient(155deg,#FBFCF8 0%,#F4F7EF 38%,#E4EBD8 80%,#D6E2C6 100%);
  --fg:#222B1E; --muted:#616B58; --muted-2:#8A9583;
  --sw-strike:#949494;
  /* 侧栏保持深色（全站侧栏/底栏本就是「深底 + 浅字」，
     浅底主题不该把侧栏也变浅 —— 会与 .brand .t1 的 #fff 写死浅字打架）。 */
  --nav-bg:#232B1E;
  --nav-idle:#CBD4C2; --tb-icon:#3F4A36; --nav-active:#E8EEDD;
  --nav-hl:linear-gradient(132deg,rgba(190,212,160,.65) 0%,rgba(190,212,160,.30) 26%,rgba(190,212,160,.12) 44%,rgba(190,212,160,0) 62%);
  --nav-ring:rgba(184,208,152,.9);
  --cal-sel:#A5BA8C;
  --field-bg:#FBFCF8; --field-bd-hover:#B9C7A8;
  --type-custom-bd:#A8B894; --type-custom-accent:#5E7A4A; --type-custom-ring:rgba(94,122,74,.16);
  /* 品牌主色：蓝 → 苔藓绿（莫兰迪灰豆绿压深后仍保有绿色相） */
  --emerald:#5E7A4A; --emerald-d:#3D5230; --emerald-l:#5A7548;
  --on-emerald:#fff; --em-rgb:94,122,74;
  /* 正文强调色的提亮版（深底用得到；浅底一并给全，避免跨主题继承） */
  --em-text-hi:#4A6239; --em-text-hi-d:#3D5230;
  --doc-tint:#D6E2C6; --doc-tint-base:#FBFCF8; --doc-tint-on:1;
  /* 卡片叠加层：蓝 → 苔藓绿同族，避免「绿底飘蓝」 */
  --st-tint-a:rgba(122,155,98,.30); --st-tint-b:rgba(104,136,82,.16);
  --card-tint-a:rgba(122,155,98,.30); --card-tint-b:rgba(104,136,82,.16);
  --card-tint-a-sm:rgba(122,155,98,.30); --card-tint-b-sm:rgba(104,136,82,.16);
  --card-tint-a-mid:rgba(122,155,98,.30); --card-tint-b-mid:rgba(104,136,82,.16);
  --shadow:0 1px 2px rgba(40,52,32,.06),0 10px 26px -10px rgba(40,52,32,.12);
  --shadow-soft:0 1px 2px rgba(40,52,32,.05),0 6px 18px -8px rgba(40,52,32,.09);
  /* 顶栏天光（浅底：从稍深的绿灰渐变到 --bg，8 个 stop 与原版同结构） */
  --top-dim:rgba(255,255,255,0);
  --top-glow-1:#E3EAD6; --top-glow-2:#E6ECD9; --top-glow-3:#E9EEDE;
  --top-glow-4:#EBF0E2; --top-glow-5:#EDF1E4; --top-glow-6:#EEF2E6;
  --top-glow-7:#EFF2E8; --top-glow-8:#EFF3EA;
  --top-fade:rgba(239,243,234,0);
  /* 底栏玻璃 */
  --nav-glass:linear-gradient(180deg,rgba(228,238,214,.21),rgba(214,228,196,.11));
  --nav-bd:rgba(132,156,102,.27);
  --nav-shadow:0 8px 22px -14px rgba(90,116,66,.50);
  --nav-ind:linear-gradient(135deg,#A9C48E,#7E9C64);
  /* kpi-home 卡底三段 */
  --kpi-home-1:#DCE7CB; --kpi-home-2:#EEF3E4; --kpi-home-3:#F8FAF2;
  --wel-bg:linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  /* --wi-top / --lpr-*：与问候卡同源公式（完整说明见 :root 处第九版注释） */
  --wi-top:linear-gradient(180deg,rgba(var(--tint-rgb),.06) 0%,rgba(var(--tint-rgb),.03) 46%,rgba(var(--tint-rgb),0) 100%),linear-gradient(135deg,var(--card-tint-a),var(--card-tint-b)),linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  --wi-top-fg:#3D5230;
  --wi-top-ov:rgba(0,0,0,.06);
  --lpr-a:var(--kpi-home-1); --lpr-m:var(--kpi-home-2); --lpr-b:var(--kpi-home-3); --lpr-overlay:linear-gradient(180deg,rgba(var(--tint-rgb),.06) 0%,rgba(var(--tint-rgb),.03) 46%,rgba(var(--tint-rgb),0) 100%),linear-gradient(135deg,var(--card-tint-a),var(--card-tint-b)); --lpr-fg:#3D5230;
  --tint-rgb:122,155,98;
  --kpi-tint-rgb:122,155,98; --kpi-tint-rgb-d:104,136,82;
}

/* ---------- 暮云模式（dusk）—— 淡灰紫浅底 + 灰紫点缀 ---------- */
body.dusk,html.dusk{
  --bg:#F2EEF4; --card:#FCFAFD; --card-2:#F7F3F9;
  --border:#E9E2EE; --border-strong:#DBD1E3; --border-stronger:#C3B5CF;
  --card-grad:var(--card-grad2);
  --card-grad2:linear-gradient(155deg,#FCFAFD 0%,#F7F3F9 38%,#EBE3F0 80%,#DED3E7 100%);
  --fg:#26212E; --muted:#675F73; --muted-2:#918AA0;
  --sw-strike:#949494;
  --nav-bg:#2A2431;
  --nav-idle:#D3CCDB; --tb-icon:#453C50; --nav-active:#EFEAF3;
  --nav-hl:linear-gradient(132deg,rgba(200,180,220,.65) 0%,rgba(200,180,220,.30) 26%,rgba(200,180,220,.12) 44%,rgba(200,180,220,0) 62%);
  --nav-ring:rgba(196,176,218,.9);
  --cal-sel:#B8A5CB;
  --field-bg:#FCFAFD; --field-bd-hover:#C3B5CF;
  --type-custom-bd:#B4A4C4; --type-custom-accent:#66587A; --type-custom-ring:rgba(102,88,122,.16);
  /* 品牌主色：蓝 → 灰紫（莫兰迪「深灰紫」压深，保住紫调又不艳） */
  --emerald:#66587A; --emerald-d:#524668; --emerald-l:#7C6B8E;
  --on-emerald:#FFFFFF; --em-rgb:102,88,122;
  /* 正文强调色的提亮版（深底用得到；浅底一并给全，避免跨主题继承） */
  --em-text-hi:#524668; --em-text-hi-d:#453A58;
  --doc-tint:#DED3E7; --doc-tint-base:#FCFAFD; --doc-tint-on:1;
  --st-tint-a:rgba(140,120,160,.30); --st-tint-b:rgba(122,104,142,.16);
  --card-tint-a:rgba(140,120,160,.30); --card-tint-b:rgba(122,104,142,.16);
  --card-tint-a-sm:rgba(140,120,160,.30); --card-tint-b-sm:rgba(122,104,142,.16);
  --card-tint-a-mid:rgba(140,120,160,.30); --card-tint-b-mid:rgba(122,104,142,.16);
  --shadow:0 1px 2px rgba(44,36,52,.06),0 10px 26px -10px rgba(44,36,52,.12);
  --shadow-soft:0 1px 2px rgba(44,36,52,.05),0 6px 18px -8px rgba(44,36,52,.09);
  --top-dim:rgba(255,255,255,0);
  --top-glow-1:#E7DFEE; --top-glow-2:#E9E2F0; --top-glow-3:#ECE5F1;
  --top-glow-4:#EEE8F3; --top-glow-5:#F0EAF4; --top-glow-6:#F1ECF5;
  --top-glow-7:#F2EDF5; --top-glow-8:#F2EEF4;
  --top-fade:rgba(242,238,244,0);
  --nav-glass:linear-gradient(180deg,rgba(240,232,246,.21),rgba(226,214,236,.11));
  --nav-bd:rgba(158,130,176,.27);
  --nav-shadow:0 8px 22px -14px rgba(112,88,130,.50);
  --nav-ind:linear-gradient(135deg,#C2AED4,#9A85AE);
  --kpi-home-1:#E2D6EA; --kpi-home-2:#F2ECF6; --kpi-home-3:#FBF9FC;
  --wel-bg:linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  /* --wi-top / --lpr-*：与问候卡同源公式（完整说明见 :root 处第九版注释） */
  --wi-top:linear-gradient(180deg,rgba(var(--tint-rgb),.06) 0%,rgba(var(--tint-rgb),.03) 46%,rgba(var(--tint-rgb),0) 100%),linear-gradient(135deg,var(--card-tint-a),var(--card-tint-b)),linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  --wi-top-fg:#524668;
  --wi-top-ov:rgba(0,0,0,.06);
  --lpr-a:var(--kpi-home-1); --lpr-m:var(--kpi-home-2); --lpr-b:var(--kpi-home-3); --lpr-overlay:linear-gradient(180deg,rgba(var(--tint-rgb),.06) 0%,rgba(var(--tint-rgb),.03) 46%,rgba(var(--tint-rgb),0) 100%),linear-gradient(135deg,var(--card-tint-a),var(--card-tint-b)); --lpr-fg:#524668;
  --tint-rgb:140,120,160;
  --kpi-tint-rgb:140,120,160; --kpi-tint-rgb-d:122,104,142;
}
/* ---------- 暖沙模式（sand）—— 米杏暖白底 + 陶土棕点缀 ----------
   2026-09-21 用户「再增加三个主题」新增。
   定位：补齐 6 主题缺失的**暖色相** —— 浅底三款（light 蓝 / moss 绿 / dusk 紫）
   全是冷色或中性，没有一个「暖光」档。
   取色依据：暖沙色板（沙丘 #F6F1E8 / 陶土 #9A5B33 / 亚麻 #EDE4D5）。
   注意：陶土棕压深到 #7A4525 才够承载白字（6.45 / 7.64:1）；
        最初的 #C67B4E 白字仅 3.4:1，不达标。 */
body.sand,html.sand{
  --bg:#F6F1E8; --card:#FFFDF9; --card-2:#FBF6EE;
  --border:#EDE4D5; --border-strong:#DFD2BC; --border-stronger:#C6B49A;
  --card-grad:var(--card-grad2);
  --card-grad2:linear-gradient(155deg,#FFFDF9 0%,#FBF6EE 38%,#F2E9DA 80%,#E8DCC7 100%);
  --fg:#2A2016; --muted:#6B5B4A; --muted-2:#948370;
  --sw-strike:#949494;
  --nav-bg:#6B4526;
  --nav-idle:#E0D2BE; --tb-icon:#4A3A28; --nav-active:#F7F1E6;
  --nav-hl:linear-gradient(132deg,rgba(220,196,160,.65) 0%,rgba(220,196,160,.30) 26%,rgba(220,196,160,.12) 44%,rgba(220,196,160,0) 62%);
  --nav-ring:rgba(214,188,150,.9);
  --cal-sel:#C6A97E;
  --field-bg:#FFFDF9; --field-bd-hover:#C6B49A;
  --type-custom-bd:#C0AB8C; --type-custom-accent:#9A5B33; --type-custom-ring:rgba(154,91,51,.16);
  /* 品牌主色：蓝 → 陶土棕 */
  --emerald:#9A5B33; --emerald-d:#7A4525; --emerald-l:#8A4E2A;
  --on-emerald:#FFFDF9; --em-rgb:154,91,51;
  --em-text-hi:#7A4525; --em-text-hi-d:#63371C;
  --doc-tint:#E8DCC7; --doc-tint-base:#FFFDF9; --doc-tint-on:1;
  --st-tint-a:rgba(178,132,88,.30); --st-tint-b:rgba(150,110,72,.16);
  --card-tint-a:rgba(178,132,88,.30); --card-tint-b:rgba(150,110,72,.16);
  --card-tint-a-sm:rgba(178,132,88,.30); --card-tint-b-sm:rgba(150,110,72,.16);
  --card-tint-a-mid:rgba(178,132,88,.30); --card-tint-b-mid:rgba(150,110,72,.16);
  --shadow:0 1px 2px rgba(72,52,32,.06),0 10px 26px -10px rgba(72,52,32,.12);
  --shadow-soft:0 1px 2px rgba(72,52,32,.05),0 6px 18px -8px rgba(72,52,32,.09);
  --top-dim:rgba(255,255,255,0);
  --top-glow-1:#E8DCC8; --top-glow-2:#EADFD0; --top-glow-3:#EDE3D6;
  --top-glow-4:#EFE7DC; --top-glow-5:#F1EAE1; --top-glow-6:#F3EDE5;
  --top-glow-7:#F4EFE7; --top-glow-8:#F6F1E8;
  --top-fade:rgba(246,241,232,0);
  --nav-glass:linear-gradient(180deg,rgba(246,236,220,.21),rgba(236,222,200,.11));
  --nav-bd:rgba(160,120,80,.27);
  --nav-shadow:0 8px 22px -14px rgba(120,86,52,.50);
  --nav-ind:linear-gradient(135deg,#D9A87A,#B8825A);
  --kpi-home-1:#EFE3CF; --kpi-home-2:#F8F2E7; --kpi-home-3:#FDFBF6;
  --wel-bg:linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  /* --wi-top / --lpr-*：与问候卡同源公式（完整说明见 :root 处第九版注释） */
  --wi-top:linear-gradient(180deg,rgba(var(--tint-rgb),.06) 0%,rgba(var(--tint-rgb),.03) 46%,rgba(var(--tint-rgb),0) 100%),linear-gradient(135deg,var(--card-tint-a),var(--card-tint-b)),linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  --wi-top-fg:#7A4525;
  --wi-top-ov:rgba(0,0,0,.06);
  --lpr-a:var(--kpi-home-1); --lpr-m:var(--kpi-home-2); --lpr-b:var(--kpi-home-3); --lpr-overlay:linear-gradient(180deg,rgba(var(--tint-rgb),.06) 0%,rgba(var(--tint-rgb),.03) 46%,rgba(var(--tint-rgb),0) 100%),linear-gradient(135deg,var(--card-tint-a),var(--card-tint-b)); --lpr-fg:#7A4525;
  --tint-rgb:178,132,88;
  --kpi-tint-rgb:178,132,88; --kpi-tint-rgb-d:150,110,72;
}


/* ============================================================
   主题变量块 · 深底二（玄墨 ink / 绛紫 plum）
   ------------------------------------------------------------
   ⚠⚠ 变更沿革（2026-09-21，供后续维护对照）：
     本区块标题原为「玄墨 ink / 松烟 pine」。**pine（松烟/暗黑荧光绿）
     已于本轮整体移除**，名额先后由 mist（雾灰）与 sakura（樱花）顶替；
     随后又新增 plum（绛紫）补齐暗紫档。
     故正文注释里凡是提到 pine 的地方，都属于**当轮的历史叙述**
     （例如「现有深底三款 dark 深蓝 / ink 中性 / pine 荧光绿」），
     不代表 pine 仍在应用中 —— 当前实际生效的主题恒为下列 9 个：
       浅底 6：light 淡色 / moss 苔原 / dusk 暮云 / sand 暖沙 / mist 雾灰 / sakura 樱花
       深底 3：dark 深色 / ink 玄墨 / plum 绛紫
     （唯一事实来源是 js/app-shell.js 的 THEMES 数组。）

   均与 dark 共享 61 条 .theme-dim 深底补偿规则（挂 theme-dim 基调类），
   这里只覆盖颜色变量。
   ⚠ 深底主题的卡片叠加层 alpha 一律取高值（.42）：
     深底 --card 上同样的 alpha 观感弱很多，浅底用 .30、深底用 .42。
     这是项目既有约定（见 :root 与 body.dark 的 --st-tint-* 注释）。 */

/* ---------- 玄墨模式（ink）—— 中性冷灰近黑底 + 银灰点缀 ---------- */
body.ink,html.ink{
  --bg:#14161A; --card:#1E2126; --card-2:#191C21;
  --border:#282C33; --border-strong:#363B44; --border-stronger:#4C535E;
  --card-grad:var(--card-grad2);
  --card-grad2:linear-gradient(155deg,#1F2227 0%,#23272E 45%,#2A2F37 100%);
  --fg:#E6E8EC; --muted:#9BA3AE; --muted-2:#6E7681;
  --sw-strike:#A3A3A3;
  --nav-bg:#0E1013;
  --nav-idle:#E2E5EA; --tb-icon:#C3CAD4; --nav-active:#3A3F47;
  --nav-hl:linear-gradient(132deg,rgba(255,255,255,.85) 0%,rgba(255,255,255,.42) 24%,rgba(255,255,255,.16) 42%,rgba(255,255,255,0) 60%);
  --nav-ring:rgba(255,255,255,.9);
  --cal-sel:#AAB6C6;
  --wel-bg:linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  /* 费用计算首页 LPR 卡：同色系三停渐变（与改动前同值，视觉不变） */
  --lpr-a:var(--kpi-home-1); --lpr-m:var(--kpi-home-2); --lpr-b:var(--kpi-home-3); --lpr-overlay:linear-gradient(180deg,rgba(var(--kpi-dark-rgb),.30) 0%,rgba(var(--kpi-dark-rgb),.14) 34%,rgba(var(--kpi-dark-rgb),0) 100%); --lpr-fg:#AAB6C6;
  /* --wi-top / --lpr-*：与问候卡同源公式（完整说明见 :root 处第九版注释） */
  --wi-top:linear-gradient(180deg,rgba(var(--kpi-dark-rgb),.30) 0%,rgba(var(--kpi-dark-rgb),.14) 34%,rgba(var(--kpi-dark-rgb),0) 100%),linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  --wi-top-fg:#AAB6C6;
  --wi-top-ov:rgba(255,255,255,.14);
  --field-bg:#22262C; --field-bd-hover:#4C535E;
  --type-custom-bd:#5C6470; --type-custom-accent:#AAB6C6; --type-custom-ring:rgba(170,182,198,.18);
  /* 品牌主色：蓝 → 银灰（中性色，与冷灰底同一族，克制不抢内容） */
  --emerald:#9AA6B8; --emerald-d:#7A8595; --emerald-l:#AAB6C6;
  --on-emerald:#15181C; --em-rgb:154,166,184;
  /* 正文强调色的提亮版（深底用得到；浅底一并给全，避免跨主题继承） */
  --em-text-hi:#B8C2D0; --em-text-hi-d:#94A0B0;
  --doc-tint:#1E2126; --doc-tint-base:#1E2126; --doc-tint-on:0;
  /* 卡片叠加层：蓝 → 冷银灰。中性色叠加不会「飘色」，观感最干净。 */
  --st-tint-a:rgba(150,163,182,.42); --st-tint-b:rgba(120,132,150,.24);
  --card-tint-a:rgba(150,163,182,.42); --card-tint-b:rgba(120,132,150,.24);
  --card-tint-a-sm:rgba(150,163,182,.42); --card-tint-b-sm:rgba(120,132,150,.24);
  --card-tint-a-mid:rgba(150,163,182,.42); --card-tint-b-mid:rgba(120,132,150,.24);
  --shadow:0 1px 2px rgba(0,0,0,.44),0 12px 28px -12px rgba(0,0,0,.54);
  --shadow-soft:0 1px 2px rgba(0,0,0,.39),0 6px 18px -10px rgba(0,0,0,.44);
  --top-dim:rgba(10,12,15,.72);
  --top-glow-1:#2B3038; --top-glow-2:#2E333C; --top-glow-3:#333841;
  --top-glow-4:#373D47; --top-glow-5:#3D434D; --top-glow-6:#454B56;
  --top-glow-7:#4E5561; --top-glow-8:#5A6270;
  --top-fade:rgba(20,22,26,0);
  --nav-glass:rgba(28,32,38,.23);
  --nav-bd:rgba(255,255,255,.72);
  --nav-shadow:0 8px 22px -14px rgba(0,0,0,.50);
  --nav-ind:linear-gradient(135deg,#AEB9C8,#7E8794);
  --kpi-home-1:#1A1D22; --kpi-home-2:#23272D; --kpi-home-3:#2D323A;
  --tint-rgb:150,163,182;
  --kpi-tint-rgb:150,163,182; --kpi-tint-rgb-d:120,132,150;
  /* 深底压暗层的近黑基色：ink 是中性冷灰，用近黑灰而非近黑蓝 */
  --kpi-dark-rgb:10,12,15;
  /* 语义色提亮（:root 那套给浅底调的，深底发闷） */
  --rose:#F07C93; --violet:#AE9BEC; --sky:#5FBCF5; --amber:#E8AC55;
  --cyan:#45D3E0; --teal:#57CFB4; --expense-red:#FF6B81;
}

/* ---------- 樱花模式（sakura）—— 淡粉白底 + 玫红点缀 ----------
   2026-09-21 用户「把松烟模式去掉，增加一个淡色模式，看看有没有合适的粉色系」。
   pine（松烟/暗黑荧光绿）已整体移除，名额由 sakura 顶替。
   定位：全站唯一的**暖粉**浅色主题。
   与既有浅色主题的色相区分（H 值）：
     · light  淡色 —— 202°  冷蓝
     · moss   苔原 ——  87°  灰绿
     · dusk   暮云 —— 280°  灰紫
     · sand   暖沙 ——  39°  暖黄
     · mist   雾灰 —— 210°  中性灰（S 仅 0.077）
     · sakura 樱花 —— 342°  **暖粉** ← 唯一落在红紫区间的
   sakura 与 dusk 最近（dH=62°）也足够分开：dusk 是冷紫（280°），
   sakura 是暖粉（342°），观感一个是"薰衣草紫"一个是"樱花粉"，不会混。
   取色依据：樱花粉底 #FBF1F4 / 玫红 #B04A6E。
   品牌色属深色调（白字 5.18:1）→ 配白字前景，与 sand/moss 同策略。 */
body.sakura,html.sakura{
  --bg:#FBF1F4; --card:#FFFFFF; --card-2:#FDF6F8;
  --border:#F3E2E8; --border-strong:#E8D0DA; --border-stronger:#D4B0C0;
  --card-grad:var(--card-grad2);
  --card-grad2:linear-gradient(155deg,#FFFFFF 0%,#FDF5F7 38%,#F8E9EE 80%,#F2DCE4 100%);
  --fg:#33232A; --muted:#7A5C66; --muted-2:#927B84;
  --sw-strike:#949494;
  --nav-bg:#7A3550;
  --nav-idle:#EBD8DF; --tb-icon:#4A3038; --nav-active:#FDF6F8;
  --nav-hl:linear-gradient(132deg,rgba(232,196,212,.65) 0%,rgba(232,196,212,.30) 26%,rgba(232,196,212,.12) 44%,rgba(232,196,212,0) 62%);
  --nav-ring:rgba(226,188,204,.9);
  --cal-sel:#D8A8BD;
  --field-bg:#FFFFFF; --field-bd-hover:#D4B0C0;
  --type-custom-bd:#D0ADBB; --type-custom-accent:#B04A6E; --type-custom-ring:rgba(176,74,110,.16);
  /* 品牌主色：玫红 */
  --emerald:#B04A6E; --emerald-d:#8E3A58; --emerald-l:#B85475;
  --on-emerald:#FFFFFF; --em-rgb:176,74,110;
  --em-text-hi:#8E3A58; --em-text-hi-d:#74304A;
  --doc-tint:#F2DCE4; --doc-tint-base:#FFFFFF; --doc-tint-on:1;
  --st-tint-a:rgba(196,130,158,.30); --st-tint-b:rgba(168,104,132,.16);
  --card-tint-a:rgba(196,130,158,.30); --card-tint-b:rgba(168,104,132,.16);
  --card-tint-a-sm:rgba(196,130,158,.30); --card-tint-b-sm:rgba(168,104,132,.16);
  --card-tint-a-mid:rgba(196,130,158,.30); --card-tint-b-mid:rgba(168,104,132,.16);
  --shadow:0 1px 2px rgba(70,40,52,.06),0 10px 26px -10px rgba(70,40,52,.12);
  --shadow-soft:0 1px 2px rgba(70,40,52,.05),0 6px 18px -8px rgba(70,40,52,.09);
  --top-dim:rgba(255,255,255,0);
  --top-glow-1:#F2DCE4; --top-glow-2:#F4E0E7; --top-glow-3:#F6E4EA;
  --top-glow-4:#F7E8ED; --top-glow-5:#F9ECF0; --top-glow-6:#FAEFF2;
  --top-glow-7:#FAF0F3; --top-glow-8:#FBF1F4;
  --top-fade:rgba(251,241,244,0);
  --nav-glass:linear-gradient(180deg,rgba(250,236,241,.21),rgba(244,224,232,.11));
  --nav-bd:rgba(176,110,140,.27);
  --nav-shadow:0 8px 22px -14px rgba(122,53,80,.50);
  --nav-ind:linear-gradient(135deg,#D98CA8,#B8608A);
  --kpi-home-1:#F2DCE4; --kpi-home-2:#FAF0F3; --kpi-home-3:#FEFBFC;
  --wel-bg:linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  /* --wi-top / --lpr-*：与问候卡同源公式（完整说明见 :root 处第九版注释） */
  --wi-top:linear-gradient(180deg,rgba(var(--tint-rgb),.06) 0%,rgba(var(--tint-rgb),.03) 46%,rgba(var(--tint-rgb),0) 100%),linear-gradient(135deg,var(--card-tint-a),var(--card-tint-b)),linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  --wi-top-fg:#8E3A58;
  --wi-top-ov:rgba(0,0,0,.06);
  --lpr-a:var(--kpi-home-1); --lpr-m:var(--kpi-home-2); --lpr-b:var(--kpi-home-3); --lpr-overlay:linear-gradient(180deg,rgba(var(--tint-rgb),.06) 0%,rgba(var(--tint-rgb),.03) 46%,rgba(var(--tint-rgb),0) 100%),linear-gradient(135deg,var(--card-tint-a),var(--card-tint-b)); --lpr-fg:#8E3A58;
  --tint-rgb:196,130,158;
  --kpi-tint-rgb:196,130,158; --kpi-tint-rgb-d:168,104,132;
}
/* ---------- 绛紫模式（plum）—— 暗紫罗兰底 + 兰紫点缀 ----------
   2026-09-21 用户「再增加三个主题」新增。
   定位：暗紫档。现有深底三款（dark 深蓝 / ink 中性 / pine 荧光绿）没有紫色，
   dusk 虽是紫但为浅底，暗紫场景缺失。
   取色依据：暗紫罗兰 #14101C / 兰紫 #C4A8F0。
   品牌色 #C4A8F0 偏亮 → 必须配近黑前景 #1A1424（10.56 / 5.92:1）；
   配白字只有 1.9:1，会完全看不清（详见 .btn-primary 注释）。 */
body.plum,html.plum{
  --bg:#14101C; --card:#1E1929; --card-2:#191423;
  --border:#2B2438; --border-strong:#3A3149; --border-stronger:#524665;
  --card-grad:var(--card-grad2);
  --card-grad2:linear-gradient(155deg,#1E1929 0%,#231D31 45%,#2A2340 100%);
  --fg:#E9E4F2; --muted:#A79EBA; --muted-2:#7A718C;
  --sw-strike:#A3A3A3;
  --nav-bg:#0E0A14;
  --nav-idle:#E2DCEF; --tb-icon:#C9BFDC; --nav-active:#3B3150;
  --nav-hl:linear-gradient(132deg,rgba(255,255,255,.85) 0%,rgba(255,255,255,.42) 24%,rgba(255,255,255,.16) 42%,rgba(255,255,255,0) 60%);
  --nav-ring:rgba(255,255,255,.9);
  --cal-sel:#D4BCF8;
  --wel-bg:linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  /* 费用计算首页 LPR 卡：同色系三停渐变（与改动前同值，视觉不变） */
  --lpr-a:var(--kpi-home-1); --lpr-m:var(--kpi-home-2); --lpr-b:var(--kpi-home-3); --lpr-overlay:linear-gradient(180deg,rgba(var(--kpi-dark-rgb),.30) 0%,rgba(var(--kpi-dark-rgb),.14) 34%,rgba(var(--kpi-dark-rgb),0) 100%); --lpr-fg:#D4BCF8;
  /* --wi-top / --lpr-*：与问候卡同源公式（完整说明见 :root 处第九版注释） */
  --wi-top:linear-gradient(180deg,rgba(var(--kpi-dark-rgb),.30) 0%,rgba(var(--kpi-dark-rgb),.14) 34%,rgba(var(--kpi-dark-rgb),0) 100%),linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  --wi-top-fg:#D4BCF8;
  --wi-top-ov:rgba(255,255,255,.14);
  --field-bg:#231D31; --field-bd-hover:#524665;
  --type-custom-bd:#5F5375; --type-custom-accent:#C4A8F0; --type-custom-ring:rgba(196,168,240,.18);
  --emerald:#C4A8F0; --emerald-d:#A585D6; --emerald-l:#D4BCF8;
  --on-emerald:#1A1424; --em-rgb:196,168,240;
  --em-text-hi:#D4BCF8; --em-text-hi-d:#BCA2EE;
  --doc-tint:#1E1929; --doc-tint-base:#1E1929; --doc-tint-on:0;
  --st-tint-a:rgba(180,150,230,.42); --st-tint-b:rgba(140,115,190,.24);
  --card-tint-a:rgba(180,150,230,.42); --card-tint-b:rgba(140,115,190,.24);
  --card-tint-a-sm:rgba(180,150,230,.42); --card-tint-b-sm:rgba(140,115,190,.24);
  --card-tint-a-mid:rgba(180,150,230,.42); --card-tint-b-mid:rgba(140,115,190,.24);
  --shadow:0 1px 2px rgba(0,0,0,.48),0 12px 28px -12px rgba(0,0,0,.58);
  --shadow-soft:0 1px 2px rgba(0,0,0,.42),0 6px 18px -10px rgba(0,0,0,.48);
  --top-dim:rgba(9,6,14,.74);
  --top-glow-1:#231B33; --top-glow-2:#281F3A; --top-glow-3:#2E2441;
  --top-glow-4:#342949; --top-glow-5:#3B2F52; --top-glow-6:#44375D;
  --top-glow-7:#4E4069; --top-glow-8:#5A4A79;
  --top-fade:rgba(20,16,28,0);
  --nav-glass:rgba(26,20,36,.23);
  --nav-bd:rgba(255,255,255,.72);
  --nav-shadow:0 8px 22px -14px rgba(0,0,0,.55);
  --nav-ind:linear-gradient(135deg,#D4BCF8,#A585D6);
  --kpi-home-1:#1B1526; --kpi-home-2:#241D32; --kpi-home-3:#2E2540;
  --tint-rgb:180,150,230;
  --kpi-tint-rgb:180,150,230; --kpi-tint-rgb-d:140,115,190;
  --kpi-dark-rgb:9,6,14;
  --rose:#FF8FB0; --violet:#C4A8F0; --sky:#7AC0FF; --amber:#F5C169;
  --cyan:#5FE0E0; --teal:#63D6B0; --expense-red:#FF7A95;
}

/* ====================================================================
   ink / plum 专属修复（2026-09-22）
   --------------------------------------------------------------------
   仅对玄墨（ink）与绛紫（plum）两套深底主题生效；其余 7 套主题的
   LPR 卡 / 工伤顶栏卡逻辑一律不动。
   背景：这两套深底主题里，LPR 卡文字原用近黑（#15181C / #1A1424）
   落在暗渐变卡底上 → 完全不可读；工伤计算器顶栏卡（.wi-top）文字虽
   为浅色，但整卡与深底页面同色、无边界 → 视觉上"融"进背景。
   修法：文字改用各自主题点缀色（ink 银灰 / plum 兰紫，即 --emerald-l），
   并加同色低透明度描边，使两张卡在深底中凸显且明确"主题色"。
   ==================================================================== */
body.ink .calc-lpr-card,
body.plum .calc-lpr-card{border:1px solid color-mix(in srgb,var(--emerald-l) 42%,transparent)}
body.ink .wi-top,
body.plum .wi-top{border:1px solid color-mix(in srgb,var(--emerald-l) 50%,transparent)}

/* ---------- 雾灰模式（mist）—— 淡灰底 + 深青灰点缀 ----------
   2026-09-21 用户「靛蓝模式取消，换一个，看有没有淡灰色」——
   用 mist 顶替原 cobalt 的名额（cobalt 已整体移除，key 不复用）。
   定位：全站唯一的**中性冷灰**浅色主题。
   与既有浅色主题的区分：
     · light 淡色 —— 冷蓝白（#f3f8fb，蓝相）
     · moss  苔原 —— 灰绿白（#EFF3EA，绿相）
     · dusk  暮云 —— 灰紫白（#F2EEF4，紫相）
     · sand  暖沙 —— 米杏白（#F6F1E8，暖黄相）
     · mist  雾灰 —— 中性灰（#F1F2F3，**无彩色相**）← 唯一一个不带色相的
   用户说「淡灰色」，所以底色刻意做到 HLS 饱和度仅 0.077（其余浅色主题
   都在 0.21~0.50），是真正的「灰」而不是「带一点颜色的白」。
   取色依据：雾灰 #F1F2F3 / 深青灰 #4A6478（品牌色）。
   品牌色走**低饱和青灰**而非纯灰 —— 纯灰品牌色在灰底上会糊成一片，
   压一点青相才能在灰底上「立」起来（/card 6.20:1）。
   品牌色属深色调 → 配白字前景（6.20 / 5.27:1）。 */
body.mist,html.mist{
  --bg:#F1F2F3; --card:#FFFFFF; --card-2:#F8F9FA;
  --border:#E5E7E9; --border-strong:#D6D9DD; --border-stronger:#B8BDC3;
  --card-grad:var(--card-grad2);
  --card-grad2:linear-gradient(155deg,#FFFFFF 0%,#F9FAFB 38%,#EFF1F3 80%,#E6E8EB 100%);
  --fg:#25282B; --muted:#5E6469; --muted-2:#7E858C;
  --sw-strike:#949494;
  --nav-bg:#2B3034;
  --nav-idle:#D6DAE0; --tb-icon:#3B4046; --nav-active:#F3F4F6;
  --nav-hl:linear-gradient(132deg,rgba(196,204,212,.65) 0%,rgba(196,204,212,.30) 26%,rgba(196,204,212,.12) 44%,rgba(196,204,212,0) 62%);
  --nav-ring:rgba(190,198,208,.9);
  --cal-sel:#A8B2BD;
  --field-bg:#FFFFFF; --field-bd-hover:#B8BDC3;
  --type-custom-bd:#B0B6BD; --type-custom-accent:#4A6478; --type-custom-ring:rgba(74,100,120,.16);
  /* 品牌主色：低饱和深青灰 */
  --emerald:#4A6478; --emerald-d:#39505F; --emerald-l:#546F84;
  --on-emerald:#FFFFFF; --em-rgb:74,100,120;
  --em-text-hi:#39505F; --em-text-hi-d:#2C3E4A;
  --doc-tint:#E6E8EB; --doc-tint-base:#FFFFFF; --doc-tint-on:1;
  --st-tint-a:rgba(120,138,156,.30); --st-tint-b:rgba(100,118,136,.16);
  --card-tint-a:rgba(120,138,156,.30); --card-tint-b:rgba(100,118,136,.16);
  --card-tint-a-sm:rgba(120,138,156,.30); --card-tint-b-sm:rgba(100,118,136,.16);
  --card-tint-a-mid:rgba(120,138,156,.30); --card-tint-b-mid:rgba(100,118,136,.16);
  --shadow:0 1px 2px rgba(42,48,54,.06),0 10px 26px -10px rgba(42,48,54,.12);
  --shadow-soft:0 1px 2px rgba(42,48,54,.05),0 6px 18px -8px rgba(42,48,54,.09);
  --top-dim:rgba(255,255,255,0);
  --top-glow-1:#E6E8EA; --top-glow-2:#E9EBED; --top-glow-3:#ECEEEF;
  --top-glow-4:#EEEFF1; --top-glow-5:#EFF1F2; --top-glow-6:#F0F1F3;
  --top-glow-7:#F1F2F3; --top-glow-8:#F1F2F3;
  --top-fade:rgba(241,242,243,0);
  --nav-glass:linear-gradient(180deg,rgba(228,232,236,.21),rgba(214,220,226,.11));
  --nav-bd:rgba(120,128,138,.27);
  --nav-shadow:0 8px 22px -14px rgba(40,46,52,.50);
  --nav-ind:linear-gradient(135deg,#7E93A6,#5A7183);
  --kpi-home-1:#E2E5E8; --kpi-home-2:#F4F5F6; --kpi-home-3:#FCFCFD;
  --wel-bg:linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  /* --wi-top / --lpr-*：与问候卡同源公式（完整说明见 :root 处第九版注释） */
  --wi-top:linear-gradient(180deg,rgba(var(--tint-rgb),.06) 0%,rgba(var(--tint-rgb),.03) 46%,rgba(var(--tint-rgb),0) 100%),linear-gradient(135deg,var(--card-tint-a),var(--card-tint-b)),linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  --wi-top-fg:#39505F;
  --wi-top-ov:rgba(0,0,0,.06);
  --lpr-a:var(--kpi-home-1); --lpr-m:var(--kpi-home-2); --lpr-b:var(--kpi-home-3); --lpr-overlay:linear-gradient(180deg,rgba(var(--tint-rgb),.06) 0%,rgba(var(--tint-rgb),.03) 46%,rgba(var(--tint-rgb),0) 100%),linear-gradient(135deg,var(--card-tint-a),var(--card-tint-b)); --lpr-fg:#39505F;
  --tint-rgb:120,138,156;
  --kpi-tint-rgb:120,138,156; --kpi-tint-rgb-d:100,118,136;
}

*{box-sizing:border-box}
html,body{margin:0;padding:0;height:100%}
body{
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  background:var(--bg); color:var(--fg); -webkit-font-smoothing:antialiased; font-size:14px;
  -webkit-text-size-adjust:100%; text-size-adjust:100%; -webkit-tap-highlight-color:transparent; touch-action:manipulation;
}
body::before{content:'';position:fixed;inset:0;z-index:-1;pointer-events:none;background:var(--bg)}
button{font-family:inherit;cursor:pointer}
input,textarea,select{font-family:inherit}
a{color:inherit;text-decoration:none}
*{scrollbar-width:none;-ms-overflow-style:none}
*::-webkit-scrollbar{width:0;height:0;display:none}
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:8px}
.hidden{display:none!important}

/* ===== 布局 ===== */
#app{min-height:100vh;display:flex}
.sidebar{
  width:230px;flex-shrink:0;background:var(--nav-bg);color:#cbd5e1;display:none;flex-direction:column;
  padding:18px 12px;position:sticky;top:0;height:100vh;height:100dvh;
}
.brand{display:flex;align-items:center;gap:10px;padding:6px 10px 18px;color:#fff}
.brand .logo{width:36px;height:36px;border-radius:11px;background:linear-gradient(135deg,var(--emerald-l),var(--emerald-d));display:flex;align-items:center;justify-content:center;color:var(--on-emerald);box-shadow:0 6px 16px -5px rgba(var(--em-rgb),.55)}
.brand .t1{font-size:15px;font-weight:700;color:#fff;line-height:1.1}
.brand .t2{font-size:11px;color:#64748b}
.nav-item{display:flex;align-items:center;gap:11px;padding:10px 12px;border-radius:10px;color:#cbd5e1;font-size:14px;margin-bottom:4px;border:none;background:none;width:100%;text-align:left;transition:.15s}
.nav-item:hover{background:rgba(255,255,255,.06);color:#fff}
.nav-item.active{background:linear-gradient(135deg,rgba(76,107,158,.28),rgba(58,168,232,.22));color:#fff;font-weight:600;position:relative;overflow:hidden}
.nav-item.active::after{content:'';position:absolute;inset:0;pointer-events:none;background:linear-gradient(135deg,rgba(255,255,255,.3),rgba(255,255,255,.10) 34%,rgba(255,255,255,0) 58%)}
.nav-item svg{width:19px;height:19px;flex-shrink:0}
.nav-spacer{flex:1}
.nav-foot{padding:8px 10px;font-size:11px;color:#475569;border-top:1px solid rgba(255,255,255,.06);margin-top:8px}
.nav-foot button{background:none;border:none;color:#94a3b8;font-size:12px;padding:6px 0;display:flex;align-items:center;gap:8px;width:100%}
.nav-foot button:hover{color:#fff}

.main{flex:1;min-width:0;display:flex;flex-direction:column;height:100vh;height:100dvh;overflow:hidden}
/* 顶栏：图片背景 + 底部向页面底色渐隐，避免与内容区硬切 */
.topbar{box-sizing:border-box;padding:calc(94px + env(safe-area-inset-top)) 20px 0;flex-shrink:0;display:flex;align-items:flex-end;justify-content:space-between;position:sticky;top:0;z-index:30;overflow:hidden;background-origin:border-box;background-clip:border-box;
  background-image:linear-gradient(180deg,var(--top-dim) 0%,var(--top-dim) 30%,var(--top-dim) 62%,var(--top-dim) 88%,var(--top-dim) 100%),linear-gradient(180deg,var(--top-glow-1) 0%,var(--top-glow-2) 16%,var(--top-glow-3) 32%,var(--top-glow-4) 48%,var(--top-glow-5) 62%,var(--top-glow-6) 74%,var(--top-glow-7) 85%,var(--top-glow-8) 100%);
  background-size:100% 100%;
  background-position:center;
  background-repeat:no-repeat}
/* ⚠ 上面 --top-dim 出现 5 次是**故意的**：light/dark 的压暗层需要 alpha 逐段
   递减（.72→.68→.62→.56→.50）才能做出「上重下轻」的天光层次，单一亮色主题
   （moss/dusk）则给 rgba(...,0) 全透明，于是这两条渐变退化成只有天光那层。
   不用「多个变量」是为了让主题块只给一个 --top-dim，取值少一处不一致风险。 */
/* 底部渐隐：把图片下缘平滑融入页面底色 --bg */
.topbar::after{content:'';position:absolute;left:0;right:0;bottom:0;height:46px;pointer-events:none;
  background:linear-gradient(180deg,var(--top-fade) 0%,var(--top-fade) 16%,var(--top-fade) 32%,var(--top-fade) 48%,var(--top-fade) 64%,var(--top-fade) 80%,var(--top-fade) 94%,var(--bg) 100%)}
/* ⚠ --top-fade 同样是「一个变量铺满多段」的写法：它必须与主题的 --bg 同色但
   全透明，否则渐隐到最后一段（var(--bg) 不透明）会从「别的颜色」跳变过来。
   light 的 rgba(243,248,251,·) 就是 --bg #f3f8fb 的同色透明版。 */
.topbar .tb-brand{transform:translateY(-20px);position:relative;z-index:2}
/* 顶栏品牌块的左对齐（用户 2026-09-19 最终口径：
   「律界移动到和下面面包折叠三横对齐，时间也是」）。
   实测：品牌块原本因 margin-left:-2px 落在 14px，而下方汉堡按钮在 16px，差 2px。
   去掉这个负 margin → 品牌块回到 16px，与汉堡按钮**严格左对齐**。
   ⚠ 这轮把前几轮的 -12 / -6 / -2 全部归零。别再重新加负 margin ——
     顶栏自身 padding 给的 16px 就是基准线，「与汉堡按钮对齐」这个目标天然等于 margin:0。
   ⚠ 移动的是 .tb-brand 整体（标题 + 时钟两行一起走），单动一行会让两行错开。 */
.topbar .tb-brand{margin-left:0}
.topbar .tb-tools{transform:none;position:relative;z-index:2}
.topbar .tb-titlebox{transform:translateY(-5px);position:relative;z-index:2}
.topbar .title{font-size:19px;font-weight:600;color:var(--fg);text-shadow:0 1px 2px rgba(255,255,255,.55)}
/* NOTE(2026-09-21): 原先这里有一条 body.theme-dim .topbar{...} 深蓝专属渐变。
   顶栏已改为「变量驱动」（--top-dim / --top-glow-* / --top-fade），
   dark 的值写在 body.dark 变量块，ink/pine 写在各自块。故删除该特例。 */
body.theme-dim .topbar .title{color:#f2f6fd;text-shadow:0 1px 3px rgba(0,0,0,.45)}
/* ============================================================
   顶栏配色 —— 已变量化（2026-09-21）
   ------------------------------------------------------------
   原先这里有 4 条 body.theme-{jade,warm} .topbar / ::after 特例。
   病根：顶栏是**写死的两段渐变**（压暗层 + 天光层），不随主题走，
   所以每加一个主题就得复制一整条；上一版 4 主题已积累 12 条这类特例，
   扩到 6 主题会变成 30+ 条重复，改结构必然漏改。
   现全部提成变量（--top-dim / --top-glow-1..8 / --top-fade），
   值分别写在 :root（浅底默认）、body.dark、各主题变量块里。
   ⚠ 新增主题只需在变量块里给这 10 个值，不要再来这里加特例。 */
.topbar .sub{font-size:12px;color:var(--muted);font-weight:600;text-shadow:0 1px 2px rgba(255,255,255,.5)}
body.theme-dim .topbar .sub{color:var(--muted);text-shadow:0 1px 3px rgba(0,0,0,.4)}
.topbar .icons{display:flex;align-items:center;gap:4px}
.tb-left{display:flex;flex-direction:column;align-items:flex-start;gap:6px;min-width:0;overflow:visible;flex:1 1 auto}
.tb-brand{display:flex;align-items:center;gap:10px;min-width:0;overflow:hidden}
.tb-brand-txt{text-align:left;min-width:0;flex:1 1 auto;overflow:hidden}
.topbar .tb-brand-txt .title{white-space:nowrap;font-size:24px;line-height:1.2;font-weight:700}
/* 时钟光学对齐（用户 2026-09-19：「时间在视觉上和律界没对齐，往右移一小点」）。
   ⚠ 这是**光学对齐**，不是盒模型对齐 —— 两者的排版盒左边界本来就都是 16px（已实测确认），
     但「律」是汉字，笔画顶到字面左缘；时钟首位是数字「2」，字形自带左侧内槽，
     所以看着比「律」更靠左。加 2px 左内边距把「2」推到与「律」的**视觉**起笔位置齐平。
   ⚠ 别为了对齐去动 .tb-brand 的 margin —— 那会连带把标题一起挪走，标题就又偏了。
      要动的只有时钟这一个元素。 */
.topbar .tb-brand-txt .sub{padding-left:2px}
.tb-tools{display:flex;align-items:center;gap:4px}
.tb-left .icon-btn{width:34px;height:34px;flex-shrink:0;border-color:transparent;background:transparent;box-shadow:none}
/* 顶栏折叠工具栏图标：hover / active / focus 一律保持透明底 + 无描边 + 无焦点框。
   背景：用户反馈「图标点击后会出现一个正方圆角框框」，要求取消变透明。
   根因是下面这行原本给了 hover 底色 ——
     .tb-left .icon-btn:hover{background:var(--bg);color:var(--fg)}
   --bg 在浅色是 #f3f8fb、暗色另有取值，配上 .icon-btn 的 10px 圆角，
   鼠标点完停留在原位（触屏是长按残留 :hover）就留下一个可见的圆角方块。
   ⚠ 注意是 :hover 不是 :focus —— 实测点击后 :focus 为 true 但 focus 态本身不设背景，
     把鼠标移开底色才消失，据此定位到 hover 规则，排查时别被 :focus 带偏。
   颜色反馈只在 :hover / :active 给（--fg 变亮）；
   ⚠ :focus 刻意**不给 color**：点击后按钮会一直保持 :focus，若在这里上色，
     图标会永久停在亮色（实测点完移开鼠标颜色仍是 --fg），等于把方块换成了残留高亮，
     与「点击后恢复原状」的诉求相悖。 */
.tb-left .icon-btn:hover,.tb-left .icon-btn:active{background:transparent;color:var(--fg)}
.tb-left .icon-btn:focus,.tb-left .icon-btn:focus-visible{background:transparent;outline:none;box-shadow:none}
.tb-left .hamburger,.tb-left .hamburger:hover,.tb-left .hamburger:active,
.tb-left .hamburger:focus,.tb-left .hamburger:focus-visible{background:transparent;border:none;box-shadow:none;outline:none}
.tb-left .hamburger svg{width:17px;height:17px}
.tb-titlebox{position:absolute;right:20px;bottom:0;text-align:right;min-width:0;z-index:2}
.tb-titlebox .title{white-space:nowrap}
.tb-titlebox .sub{white-space:nowrap}
.tb-icons{display:flex;align-items:center;gap:2px;overflow:hidden;white-space:nowrap;max-width:0;opacity:0;transition:max-width .28s ease,opacity .2s ease}
.tb-icons.open{max-width:230px;opacity:1}
.icon-btn{width:38px;height:38px;border-radius:10px;border:1px solid var(--border);background:var(--card);display:flex;align-items:center;justify-content:center;color:var(--muted)}
.icon-btn:hover{color:var(--fg);background:var(--bg)}
/* 顶栏工具栏图标 / 汉堡：颜色对齐底部导航未选中色 */
/* ⚠⚠ 这里**不能**直接用 --nav-idle。
   --nav-idle 的设计语境是「深色侧栏/底栏上的浅字」——它每套主题都取值很浅
   （light #CBD4C2 系、mist #D6DAE0、sakura #EBD8DF …），压在 --nav-bg 上
   对比度 6~18:1 完全没问题。
   但顶栏折叠工具栏所在的 .topbar 背景是**天光 --top-glow-\*** ——
   浅底主题的天光是 #E6E8EA ~ #FBF1F4 这类浅色，再压浅色的 --nav-idle
   就糊成一片（实测 moss/dusk/sand/mist 只有 1.10~1.24:1，基本看不见）。
   所以单独抽一个 --tb-icon：浅底主题给深色（贴近 --fg），深底主题沿用 --nav-idle。
   2026-09-21 用户反馈「有些主题 折叠导航栏图标看不清楚」，即此问题。 */
.tb-left .icon-btn,.tb-left .hamburger{color:var(--tb-icon)}
.tb-left .hamburger:hover{color:var(--tb-icon)}
/* 折叠工具栏面板内图标整体缩小一点 */
.tb-icons .icon-btn svg{width:21px;height:21px}
/* 顶栏圆形头像 */
.tb-avatar{width:50px;height:50px;border-radius:17px;border:1px solid rgba(255,255,255,.55);background-size:cover;background-position:center;flex-shrink:0;display:flex;align-items:center;justify-content:center;overflow:hidden;cursor:pointer;position:relative;box-shadow:0 2px 8px -3px rgba(23,49,77,.28)}
.tb-avatar input[type=file]{position:absolute;left:0;top:0;width:1px;height:1px;opacity:0;overflow:hidden;border:0;padding:0;margin:0}
.tb-avatar svg{width:24px;height:24px;color:#fff;opacity:.95}
.tb-avatar.no-img{background:linear-gradient(135deg,#7ea5cf,#4c6b9e)}
.tb-avatar:not(.no-img) svg{display:none}
/* 设置页头像 */
.set-avatar{width:56px;height:56px;border-radius:18px;border:1px solid var(--emerald-l);background-size:cover;background-position:center;flex-shrink:0;display:flex;align-items:center;justify-content:center;cursor:pointer;overflow:hidden;color:var(--bg);box-shadow:0 3px 10px -2px rgba(23,49,77,.3);position:relative}
.set-avatar input[type=file]{position:absolute;left:0;top:0;width:1px;height:1px;opacity:0;overflow:hidden;border:0;padding:0;margin:0}
.set-avatar.no-img{background:linear-gradient(135deg,#7ea5cf,#4c6b9e)}
.set-avatar svg{color:#fff;opacity:.95}
.set-avatar:not(.no-img) svg{display:none}
.content{flex:1;overflow-y:auto;overflow-x:hidden;padding:22px 20px 96px;scrollbar-width:none}
.content::-webkit-scrollbar{display:none}
@media(min-width:768px){.content{padding:26px 30px 110px}}

/* 移动端底部导航（悬浮液态玻璃） */
.mobile-nav{
  display:flex;position:fixed;bottom:14px;left:14px;right:14px;margin:0 auto;
  width:fit-content;max-width:min(540px,calc(100% - 28px));
  align-items:center;justify-content:space-between;gap:5.5px;
  background:var(--nav-glass);
  border:1px solid var(--nav-bd);
  border-radius:999px;z-index:40;padding:5px 3px calc(5px + env(safe-area-inset-bottom));
  box-shadow:var(--nav-shadow);
  -webkit-backdrop-filter:blur(1.5px);backdrop-filter:blur(1.5px);
  overflow:hidden;
  transition:transform .22s ease,opacity .22s ease,visibility .22s ease;
}
.mobile-nav.kb-hidden{transform:translateY(170%)!important;opacity:0;visibility:hidden;pointer-events:none}
.mobile-nav::before{
  content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:transparent;
}
.mobile-nav::after{
  content:'';position:absolute;inset:0;z-index:2;pointer-events:none;border-radius:inherit;
  background:transparent;
}
.mobile-nav button{position:relative;z-index:1;flex:0 0 auto;width:48px;height:44px;padding:0;background:none;border:none;color:var(--emerald);display:flex;align-items:center;justify-content:center;border-radius:50%;transition:color .2s,transform .15s,box-shadow .22s ease}
.mobile-nav button svg{width:24px;height:24px;transform-box:fill-box;transform-origin:center;flex-shrink:0;color:inherit}
.mobile-nav button:active{transform:scale(.92)}
.mobile-nav button:hover:not(.active){color:var(--emerald-d)}
.mobile-nav button.active{color:var(--nav-active);font-weight:700;transition:color var(--ind-dur,.85s) cubic-bezier(.34,.72,.26,.98)}
.mobile-nav .mn-ind{position:absolute;top:1.5px;height:calc(100% - 3px);border-radius:50%;left:0;width:0;background:var(--nav-ind);box-shadow:0 8px 18px -8px rgba(122,162,205,.4);opacity:0;pointer-events:none;z-index:0;transform:scale(.92);transform-origin:center;transition:left .22s cubic-bezier(.34,.72,.26,.98),width .22s cubic-bezier(.34,.72,.26,.98),opacity .18s ease}
/* NOTE(2026-09-21): 原先这里是 body.theme-dim .mobile-nav 的冷蓝玻璃
   （background/border-color）+ 深底专属阴影。现底栏背景/描边已变量化
   （--nav-glass / --nav-bd / --nav-shadow），值由各主题变量块提供，故删除。 */
body.theme-dim .mobile-nav{box-shadow:0 8px 24px -14px rgba(0,0,0,.44)}
body.theme-dim .mobile-nav::before{
  background:linear-gradient(180deg,rgba(255,255,255,.19),rgba(255,255,255,.05) 36%,transparent 68%);
}
body.theme-dim .mobile-nav::after{background:transparent}
body.theme-dim .mobile-nav button{color:#eef3f9}
body.theme-dim .mobile-nav button:hover:not(.active){color:#ffffff}
body.theme-dim .mobile-nav button.active{color:#4a5567;font-weight:700}
/* ============================================================
   底栏（.mobile-nav）配色 —— 已变量化（2026-09-21）
   ------------------------------------------------------------
   原先这里有 4 条 body.theme-{jade,warm} .mobile-nav / ::before / .mn-ind 特例。
   与顶栏同病：底栏玻璃拟态是**写死的色相**，每加主题就要复制一条。
   现提成变量 --nav-glass / --nav-bd / --nav-shadow / --nav-ind，
   值写在 :root（浅底默认）、body.dark、各主题变量块里。
   ⚠ 玻璃的 alpha 与结构（blur、渐变方向、stop 位置）是调过的，
     新主题只换色相、不要动 alpha 结构，否则玻璃质感会变。
   ⚠ 另：原先 body.theme-warm 还单独写了 .mobile-nav button{color:var(--emerald)}，
     那只是因为暖阳把 --emerald 换成了琥珀；现在所有非 dark 主题都在
     自己的变量块里覆盖了 --emerald，基础规则 .mobile-nav button{color:var(--emerald)}
     已自动生效，不需要每条特例。 */
@media(min-width:860px){.sidebar{display:flex}.mobile-nav{display:none}.content{padding-bottom:28px}}

/* ===== 通用组件 ===== */
.card{background:var(--card-grad2);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow-soft);min-width:0}
/* ——— 卡片蓝底（用户 2026-09-17 指定，深浅参照案件统计卡）———
   与 .st-card 完全同构：纯 --card 打底 + :before 铺一层 135° 蓝叠加。
   分两档，按卡片体量选（取值与理由见 :root 里 --card-tint-* 注释）：
     .card-tint     —— 大卡：案件列表卡、甘特图卡、日历卡、文档类型卡
     .card-tint-sm  —— 小卡：今日待办、近期事项、案件类型分布
   两档都用 .card-tint 作前缀类，只是辅类不同，便于以后整体调一处。

   ⚠ :before 是 absolute，会被同级文字的层叠顺序影响，所以下面统一把
   直接子元素提上来（z-index:1）。但**只提直接子元素**——
   子元素一旦自己 position:relative 开了层叠上下文，内部元素就压不出去了；
   这里是纯视觉叠加、不涉及交互层级，够用。

   ⚠ 不能用 overflow:hidden 裁 :before（日历卡里有 absolute 的日程气泡，
   甘特图卡也明确依赖 overflow:visible），所以 :before 自带同值圆角。
   这一点与 .st-card 踩过的坑一致，别改成 overflow:hidden。 */
/* ⚠ 圆角必须**继承宿主元素**的值，绝不能硬写 var(--radius)。
   踩过的坑（用户 2026-09-17 截图反馈「日程这个页面 卡片四角是怎么回事？」）：
   日程条目的圆角是内联的 12px，而这里 ::before 写死了 --radius(20px)，
   于是前景 12px、蓝色叠加层 20px，四个角各错开约 8px，
   露出一圈蓝色台阶 —— 看着就像"四角有问题"。
   用 border-radius:inherit 让蓝层永远跟着宿主走，宿主改成多少都不会再错开。
   （.card / .case-card / .client-row 等宿主都是 20px，inherit 后与原来一致；
     .card-tint::before 也不会继承到 .card 的 border-radius:var(--radius)，
     因为 ::before 的 inherit 取的是宿主元素计算值，正是我们要的那个值。） */
.card-tint{background:var(--card);position:relative;overflow:visible}
.card-tint::before{content:"";position:absolute;inset:0;pointer-events:none;
  border-radius:inherit;
  background:linear-gradient(135deg,var(--card-tint-a),var(--card-tint-b))}
.card-tint-sm{background:var(--card);position:relative;overflow:visible}
.card-tint-sm::before{content:"";position:absolute;inset:0;pointer-events:none;
  border-radius:inherit;
  background:linear-gradient(135deg,var(--card-tint-a-sm),var(--card-tint-b-sm))}
/* 只提"直接子元素"的层叠顺序。⚠ 这条对日程条目是**空转**的：
   它内部是裸 <div style="display:flex">，外面没包 .card，
   所以内容全靠自身 padding 撑位置，没有子元素需要提层。
   之所以仍然安全：::before 是 inset:0 铺满、pointer-events:none，
   且内容不依赖 z-index 也不会被它盖住（同级、::before 在文档流前）。
   ⚠ 唯一的例外是 opacity:.75 的已到期条目 —— 见下方专门那条。 */
.card-tint>*,.card-tint-sm>*{position:relative;z-index:1}
.card-pad{padding:18px}
.card-head{display:flex;align-items:center;justify-content:space-between;padding:16px 18px;position:relative}
.card-head::after{content:"";position:absolute;left:18px;right:18px;bottom:0;border-bottom:1px dashed var(--muted-2)}
.card-head .h{font-size:15px;font-weight:600;display:flex;align-items:center;gap:8px}
.card-head .h svg{width:17px;height:17px}
.card-head .dash-head-btn{height:20px;padding:0 9px;font-size:11.5px;line-height:18px}
.btn{display:inline-flex;align-items:center;gap:6px;justify-content:center;padding:6px 12px;border-radius:10px;border:1px solid var(--border-strong);background:var(--card);color:var(--fg);font-size:13px;font-weight:500;transition:.15s;box-shadow:var(--shadow-soft)}
.btn:hover{transform:translateY(-1px);border-color:color-mix(in srgb,var(--emerald) 35%,var(--border-strong))}
.btn:disabled{opacity:.5;cursor:not-allowed;transform:none}
/* 主按钮：渐变底 + --on-emerald 前景色。
   ⚠ 前景色**必须**走变量，不能写死 #fff ——
     一旦某主题的 --emerald 是浅亮色（如荧光黄绿 #C6F24E），白字压上去
     只有 1.30:1（几乎不可见）。:root 默认给 #fff（深调品牌色上 4.5:1+
     没问题）；若将来加浅亮品牌色的主题，把它覆盖成近黑即可（荧光绿上
     近黑字可达 15.15:1）。
     box-shadow 的发光色同理走 --em-rgb，让品牌色主题有「辉光」。 */
.btn-primary{background:linear-gradient(135deg,var(--emerald-l),var(--emerald-d));border-color:transparent;color:var(--on-emerald);box-shadow:0 6px 16px -6px rgba(var(--em-rgb),.55)}
.btn-primary:hover{background:linear-gradient(135deg,var(--emerald),var(--emerald-d));border-color:transparent;color:var(--on-emerald)}
.btn-ghost{background:none;border:none;color:var(--muted);box-shadow:none}
.btn-ghost:hover{background:var(--bg);color:var(--fg)}
/* 工伤待遇底部操作按钮：图标大小归一 */
#wi-log svg{width:22px;height:22px}
#wi-run svg{width:16px;height:16px}
/* 计算器各选项卡主按钮：图标缩小 */
#cl-run svg,#cp-run svg,#dl-run svg,#lf-run svg,#ls-run svg,#cc-run svg{width:13px;height:13px}
.btn-danger{color:var(--rose);background:none;border:none;box-shadow:none}
.btn-danger:hover{background:rgba(240,97,126,.1)}
.btn-sm{padding:6px 10px;font-size:12px;border-radius:10px;white-space:nowrap}
.btn-sm svg{width:14px;height:14px;flex-shrink:0;display:inline-block;vertical-align:-0.15em}
/* 行内图标按钮（分享 / 预览 / 下载）。
   2026-09-18 用户要求「分享按钮也不要框框，案件详情也同步不要」。
   原样式是 32px 方块：1px 边框 + 卡片底 + 10px 圆角，一排三个并排时
   像三个小方章，视觉重量盖过了文件名本身。改为**裸图标**：
     · border/background 全去掉；
     · 尺寸收到 28px（只是点击区，没有可见边界，从 32 收到 28 不会难点到，
       因为实际可点区域仍由 flex 布局撑开，且 hover 底色会给出边界提示）；
     · hover 给一个**圆形**淡底而不是圆角方块 —— 圆底和图标形状同构，
       不会在无框状态下突然冒出一个方形色块。
   ⚠ 别把 hover 的 border-radius 去掉：没有圆角就是方块底，
     正好违背"不要框框"的诉求。 */
.btn-icon{width:28px;height:28px;padding:0;border:none;background:none;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:var(--muted);transition:.15s}
.btn-icon:hover{color:var(--fg);background:var(--bg)}
.btn-icon:active{background:var(--border)}
.btn-icon svg{width:16px;height:16px}
/* 删除按钮：本来就无边框，只需与 .btn-icon 对齐 ——
   同排两个按钮尺寸/圆角不一致会看出"一个是方块一个是圆"的割裂感。 */
.btn-del{width:28px;height:28px;padding:0;border:none;background:none;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:var(--rose);transition:.15s}
.btn-del:hover{background:rgba(240,97,126,.1);color:var(--rose)}
.btn-del svg{width:16px;height:16px}
.wi-tbl-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:none;color:var(--muted);border-radius:8px;cursor:pointer;padding:0;transition:.15s;flex-shrink:0}
.wi-tbl-btn:hover{background:rgba(38,56,92,.09);color:var(--fg)}
.wi-tbl-btn.danger{color:var(--rose)}
.wi-tbl-btn.danger:hover{background:rgba(240,97,126,.12);color:var(--rose)}
.wi-tbl-btn svg{width:19px;height:19px}
/* 案件详情「工伤赔偿表格」的横向滚动壳（2026-09-20 新增）。
   仅作用于案件详情 modal 里的这张表；桌面端宽度富余不出现滚动条，视觉无变化。 */
.modal .wi-tbl-scroll{width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}
.modal .wi-tbl-scroll table{margin:0}
.modal .wi-tbl-scroll::-webkit-scrollbar{height:4px}
/* ⚠⚠ 修「金额被吞」的关键（用户 2026-09-20：「低于10万的显示很全，高于的一直被吞掉很多」）。
   实测证据：金额列的格宽**永远恰好等于内容所需宽度**（88,600→84px、886,600→104px、
   1,288,000.50→114px），一点余量都没有。这就是「刚好塞满」的临界态：
   一旦可用宽度少几个像素，auto 布局就从这一列扣，而 nowrap 的金额不会换行 → 右侧被裁。
   金额越长临界宽度越大，所以现象恰好卡在「10 万」这条线上。
   修法：
     ① table-layout:fixed —— 列宽由首行与下面的 width 决定，不再随内容抖动；
     ② 金额列给足固定宽度 132px（容得下最长的「12,880,000.50 元」= 114px 并留余量），
        它是硬约束，浏览器不会再压缩它；
     ③ 左列 width:auto 吃掉剩余宽度；它的说明小字本来就有 text-overflow:ellipsis，
        压缩左列无信息损失（本来就截断显示、完整内容在行内可查）。 */
.modal .wi-tbl-scroll .wi-tbl{table-layout:fixed}
.modal .wi-tbl-scroll .wi-tbl td:first-child{width:auto;overflow:hidden}
.modal .wi-tbl-scroll .wi-tbl-amt,
.modal .wi-tbl-scroll .wi-cn-amt{width:132px;overflow:visible}
/* 金额列内部统一右对齐（各行金额、赔偿合计、大写、按月长期都落在这条列上） */
.modal .wi-tbl-scroll .wi-tbl-amt .wi-total-num{font-size:13.5px;font-weight:800}
/* 极端兜底：金额列宽度是有限的 126px，若金额本身超过这个宽度
   （实测需「8.9 亿」这种量级的大写才会有 —— 「捌亿捌仟…捌分」宽 218px），
   不让它溢出到格线外，改为在列内省略号截断，完整数字仍可通过导出文档查看。
   正常业务金额（≤ 千万）用不到这条。 */
.modal .wi-tbl-scroll .wi-tbl-amt,
.modal .wi-tbl-scroll .wi-cn-amt{text-overflow:ellipsis}
.modal .wi-tbl-scroll .wi-cn-amt{overflow:hidden}
.btn-ghost{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:6px 10px;border:none;background:none;color:var(--muted);border-radius:8px;transition:.15s}
.btn-ghost:hover{background:rgba(38,56,92,.09);color:var(--fg)}
.btn-ghost svg{width:15px;height:15px;flex-shrink:0}
/* ---- 案件详情页(cd-modal)：卡片边框与虚线分隔加深、文档卡片留缝 ---- */
.cd-modal .modal-body [style*="1px solid var(--border)"]{border-color:#b7c1d4!important}
.cd-modal .modal-body [style*="border-top:1px dashed"],[style*="border-bottom:1px dashed"]{border-color:#b7c1d4!important}
body.theme-dim .cd-modal .modal-body [style*="1px solid var(--border)"]{border-color:#5a6d92!important}
body.theme-dim .cd-modal .modal-body [style*="border-top:1px dashed"],[style*="border-bottom:1px dashed"]{border-color:#5a6d92!important}
.cd-modal [style*="#DFE3EC"]{background:#b6c2d4!important}
.cd-modal #cd-docs{display:flex;flex-direction:column;gap:0}
.cd-modal #cd-docs .li{padding:10px 0;border:none;border-radius:0;background:none;box-shadow:none}
.cd-modal #cd-docs .li:hover,.cd-modal #cd-docs .li:active,.cd-modal #cd-docs .li:focus{background:none!important;transform:none;box-shadow:none}
.cd-modal #cd-docs.dash-list .li+.li{border-top:1px dashed #b7c1d4!important}
body.theme-dim .cd-modal #cd-docs.dash-list .li+.li{border-top:1px dashed #5a6d92!important}
.cd-modal .sh-ic{width:18px;height:18px;flex-shrink:0}
/* ---- 案件详情 · 案件进度 · 右侧事项时间（用户 2026-09-21 需求） ----
   用户原话：「后面时间 因为不同数字占位不一样导致参差不齐。」
   根因：时间文本用的数字是「比例数字」（proportional numerals），
         `1` 比 `8` 窄、`0` 又不同宽，所以 "01-05 09:05" 与 "11-18 18:18"
         渲染宽度不等，右缘参差。注意 padStart(2,'0') 只解决了「位数」，
         解决不了「同一字号的数字本身宽度不同」。
   修法：①tabular-nums 让所有数字等宽（同一字符列宽恒定）；
         ②再给一个够放最长日期串的最小宽度并右对齐，
           即使字体缺 tnum 特性，右侧仍然严格对齐。
   【2026-09-24】日期格式由 "MM-DD HH:MM" 改为 "YYYY.MM.DD HH:MM"
     （用户：「原格式08-21 15:00 改成 2025.07.03 15:30 这种格式」）。
     实测新格式在 11px 下宽 86.3px，旧的 74px min-width 已不够，
     故提到 88px —— 保证各行右缘仍然严格对齐。 */
.cd-evt-time{font-size:11px;font-weight:700;color:var(--rose);white-space:nowrap;
  flex-shrink:0;text-align:right;min-width:88px;
  font-variant-numeric:tabular-nums;font-feature-settings:'tnum' 1}
/* ---- 「记律师费」弹窗的「添加一笔收费」行（用户 2026-09-16 需求） ----
   三栏：实收金额 | 收费时间 | 收费方式。窄屏 3 栏会把金额框挤成窄条（320px 实测约 38px），
   故 ≤559px 改为两行（金额+时间 / 备注+添加）。 */
.cf-add-row{display:grid;grid-template-columns:1fr 132px 110px;gap:8px;margin-bottom:8px}
.cf-note-row{display:grid;grid-template-columns:1fr 96px;gap:8px}
/* ⚠ .modal select 全局设了 appearance:none 且 background-image:none，
   原生下拉箭头被抹掉。本控件没有 label，只靠占位文案会看不出是下拉，
   故外套 .cf-sel 并自绘一个箭头（与全站 searchSelect 的 ss-caret 同一套做法）。 */
.cf-sel{position:relative;min-width:0}
.cf-sel select{padding-right:26px}
.cf-sel-caret{position:absolute;right:8px;top:50%;transform:translateY(-50%);width:14px;height:14px;
  color:var(--muted);pointer-events:none;flex-shrink:0}
@media(max-width:559px){
  /* 窄屏：金额与时间各占一半，方式换到第二行与备注并排 */
  .cf-add-row{grid-template-columns:1fr 1fr}
  .cf-sel{grid-column:1 / -1}
  .cf-note-row{grid-template-columns:1fr 88px}
}
/* 已收明细行可点击编辑（用户 2026-09-16：「还做一个点击可编辑」）。
   行本身是 div，不是按钮，靠 hover/focus 给出可点提示；
   ⚠ 删除按钮在行内，所以 hover 只轻微变色、不整行高亮，避免误以为整行是删除。 */
.fee-row{cursor:pointer;transition:background .14s;-webkit-tap-highlight-color:transparent}
.fee-row:hover{background:var(--bg-soft)}
.fee-row:hover .btn-del{opacity:1}
.fee-row .btn-del{opacity:.75;transition:opacity .14s}
.fee-row:focus-visible{outline:2px solid var(--violet);outline-offset:-2px;border-radius:8px}
/* 「应收计划」占位行（无已收明细时）右侧的铅笔提示图标：平时半透明，
   hover 时变实 —— 与 .btn-del 同一套「悬停才显形」的语言，暗示可点 */
.fee-row-edit{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;
  border-radius:8px;color:var(--muted);opacity:.55;flex-shrink:0;transition:opacity .14s,color .14s}
.fee-row:hover .fee-row-edit{opacity:1;color:var(--emerald-d)}
.fee-row-edit svg{width:15px;height:15px}
/* 来自回款工作台的到账行（用户 2026-09-16：「以前已收点编辑后里面是空数据」的根因）。
   它不是案件内登记的收费，只能去回款工作台改，故箭头用普通色、不套 emerald，
   与「可在此就地编辑」的铅笔行在视觉上区分开。 */
.fee-row[data-fee-pay]:hover .fee-row-edit{color:var(--muted)}
.input,.select,.textarea{width:100%;padding:11px 13px;border:1px solid var(--border-stronger);border-radius:12px;background:var(--field-bg);color:var(--fg);font-size:14px;outline:none;transition:.15s}
.input:hover,.select:hover,.textarea:hover{border-color:var(--field-bd-hover)}
.input:focus,.select:focus,.textarea:focus{border-color:var(--emerald-l);box-shadow:0 0 0 3px rgba(76,107,158,.13);background:var(--card)}
.input::placeholder,.textarea::placeholder{color:var(--muted);opacity:.75}
.textarea{resize:vertical;min-height:70px}
/* 自定义类型输入框：紧跟在「类型」下拉下方，属于条件展开的二级输入。
   要点一：底色必须和其他输入框完全一致（白/深卡），否则会被误读成「禁用」状态。
   要点二：它所在的栏位窄（表单过半宽约 187px），不能用 3px 左侧粗线——
   那会同时造成两个问题：① 左右圆角不对称、边框看起来「缺了一角」；
   ② 挤掉可用宽度导致 placeholder 从中间被硬切（实测可用 163px，全文案需 196px）。
   所以最终方案：边框宽度与普通输入框一致（1px），只把「描边色」换成主题强调色，
   并收窄左右内边距把空间让给文字。视觉上靠「颜色」区分，不靠「粗细/填色」。 */
.input.type-custom{
  background:var(--field-bg);
  border-color:var(--type-custom-bd);
  padding-left:10px; padding-right:10px;
}
.input.type-custom:hover{border-color:var(--type-custom-accent)}
.input.type-custom:focus{
  background:var(--card);
  border-color:var(--type-custom-accent);
  box-shadow:0 0 0 3px var(--type-custom-ring);
}
.input.type-custom::placeholder{color:var(--muted);opacity:.8}
.label{display:block;font-size:12px;font-weight:600;color:var(--muted);margin-bottom:6px}
/* 可搜索下拉 */
.ssearch,.ssearch.select{padding:0;position:relative;width:100%;border:1px solid var(--border-stronger);border-radius:12px;background:var(--field-bg);transition:.15s}
.ssearch:focus-within{border-color:var(--emerald-l);box-shadow:0 0 0 3px rgba(76,107,158,.13);background:var(--card)}
.ssearch .ss-input{padding:11px 34px 11px 13px;border:none;box-shadow:none;background:transparent;border-radius:0}
.ssearch .ss-input:focus{border:none;box-shadow:none;background:transparent}
.ssearch.nb{position:relative;width:100%;display:block;border:none;box-shadow:none;background:transparent;padding:0;border-radius:0}
.ssearch.nb .ss-input{border:none;box-shadow:none;background:transparent;padding-left:2px}
.ssearch.nb .ss-input:focus{border:none;box-shadow:none;background:transparent}
.ssearch .ss-caret{position:absolute;right:9px;top:50%;transform:translateY(-50%);width:18px;height:18px;display:flex;align-items:center;justify-content:center;color:var(--muted);cursor:pointer;pointer-events:auto;transition:transform .15s,color .15s;flex-shrink:0}
.ssearch .ss-caret svg{width:15px;height:15px;stroke-width:2.2}
.ssearch .ss-caret:hover{color:var(--fg)}
.ssearch.ss-open .ss-caret{transform:translateY(-50%) rotate(180deg);color:var(--emerald-l)}
.ssearch .ss-input::placeholder{color:var(--muted);opacity:.75}
.ssearch .ss-input:focus::placeholder{color:var(--muted);opacity:.55}
.ssearch .ss-panel{position:absolute;left:0;right:0;top:calc(100% + 6px);z-index:80;max-height:240px;overflow:auto;border:1px solid var(--border-strong);border-radius:12px;background:var(--card);box-shadow:0 12px 32px rgba(0,0,0,.18);display:none}
.ssearch .ss-panel.open{display:block}
.ssearch .ss-item{display:flex;flex-direction:column;gap:2px;padding:10px 13px;cursor:pointer;}
.ssearch .ss-item+.ss-item{border-top:1px solid var(--line, rgba(128,128,128,.12))}
.ssearch .ss-item:hover,.ssearch .ss-item.sel{background:var(--emerald-l);color:var(--on-emerald)}
.ssearch .ss-t{font-size:14px;font-weight:600}
.ssearch .ss-item em{font-style:normal;font-size:11px;color:var(--muted)}
.ssearch .ss-item:hover em,.ssearch .ss-item.sel em{color:rgba(255,255,255,.7)}
.ssearch .ss-empty{padding:12px 13px;font-size:13px;color:var(--muted)}
/* 徽标（胶囊标签）—— 全工程统一尺寸，基准是案件卡片的做法。
   ⚠ line-height 必须写死，不能靠继承：
     不写时是 normal（≈1.2×继承字号），父容器行高一变，胶囊高度就跟着变。
     实测过同一套 font-size/padding 在不同页面渲染出 18 / 22 / 38px 三种高度，
     而案件卡片是 20px —— 视觉上「日程列表的类型框比案件卡片大」就是这么来的。
     line-height:14px 是反推出来的：11px 字 + 上下各 2px 内边距 + 2px 边框
     = 需要 14px 行盒才能落到 20px，与案件卡片逐像素一致。
   white-space:nowrap 也是必须的：不写时窄容器会把「已推进 255 天」这类
     较长的徽标折成两行，高度翻到 34px、形状从胶囊变成圆角块。
     案件卡片的徽标都是单行，这里保持一致。 */
.badge{display:inline-flex;align-items:center;padding:1px 6px;border-radius:999px;font-size:11px;line-height:13px;font-weight:600;white-space:nowrap;border:1px solid transparent}
.badge-outline{border-color:var(--border-strong);color:var(--muted)}
.badge-sec{background:var(--bg);color:var(--muted)}
/* 事项类型徽标：底色/文字色由 evTypeStyle() 内联给出（预设软色 / 自定义哈希彩色）。
   这里只负责形状与非预设色的可读性——彩色胶囊的浅底是固定浅色，
   暗色模式下必须保住它自己的深色文字，否则会被 .badge 的浅色文字规则冲掉。 */
.badge.ev-badge{padding:1px 6px;letter-spacing:.2px}
.badge.ev-badge[style*="background:#"]{color:inherit}
.chip{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;border-radius:999px;font-size:12px;font-weight:600;border:1px solid var(--border);background:var(--card);color:var(--muted);transition:.15s}
.chip:hover{border-color:color-mix(in srgb,var(--emerald) 40%,var(--border));color:var(--fg)}
.chip.active{background:linear-gradient(135deg,var(--emerald-l),var(--emerald-d));color:var(--on-emerald);border-color:transparent;box-shadow:0 4px 12px -4px rgba(var(--em-rgb),.5)}
.search-wrap{position:relative}
.search-wrap svg{position:absolute;left:11px;top:50%;transform:translateY(-50%);width:16px;height:16px;color:var(--muted-2)}
.search-wrap .input{padding-left:34px}
.tb-actions{display:flex;align-items:center;gap:8px;min-width:0}
.tb-actions .search-wrap{flex:1;min-width:0}
.ico-sm{width:16px;height:16px;flex-shrink:0}
.sep{height:1px;background:var(--border);margin:14px 0}
/* 通用 loading 旋转动画（与下方 @keyframes spin 配套；虽当前无引用，属基础设施保留） */
.spin{animation:spin 1s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.empty{padding:48px 16px;text-align:center;color:var(--muted);font-size:14px}
.progress{height:7px;background:var(--border);border-radius:999px;overflow:hidden}
.progress > i{display:block;height:100%;background:linear-gradient(90deg,var(--emerald-d),var(--emerald));border-radius:999px}
/* 卡片上的小进度条（用户 2026-09-19：「把前面进度条缩短」）——
   卡片第三行现在有「进度条 + N% + 类型徽标 + 阶段徽标」四样东西，
   原来进度条是 flex:1 独占剩余宽度，加上第二个徽标后会把它们挤出卡片，
   所以收成约 56px 的一小段（已在 JS 里内联 flex 控制，这里只管高度）。 */
.progress-sm{height:6px}
/* 进度百分比文字（用户 2026-09-19：「暗色模式 进度条 和N% 看不清」）。
   ⚠ 两个问题，分开治：
     ① N% 原来内联写 color:var(--emerald-d) —— 暗色下 --emerald-d 仍是
        浅色模式的值 #3a5480（暗色变量块里没重定义 emerald 系列），
        深蓝压在 --card(#182234) 上对比度约 1.6，几乎不可见。
        这里改用类选择器，暗色下换亮青 #4fd6c0（与「净收」的暗色处理同款）。
     ② 进度条底槽是 --border(#22304a)，与卡片底 #182234 只有 1.3 左右的对比，
        填充色又是暗蓝渐变 —— 整条几乎看不见。暗色下把底槽调亮一档、
        填充换成亮青渐变，保证「走过多少」一眼可读。 */
.prog-num{color:var(--emerald-d);font-variant-numeric:tabular-nums}
body.theme-dim .progress{background:#2f3f5c}
body.theme-dim .progress > i{background:linear-gradient(90deg,#2f9e8c,#4fd6c0)}
body.theme-dim .prog-num{color:#4fd6c0}
/* 主色（--emerald 系）**当文字用**时的暗色适配。
   ⚠ 为什么不直接在暗色变量块里重定义 --emerald：它是全站主色，同时被当作
     背景/边框在用（.btn-primary 渐变、.chip.active、focus 描边、开关滑道、
     导航图标……）。整体调亮会让这些控件的白字对比、描边观感全跟着变，
     属于「为了修一处文字、动到整站交互」——风险不成比例。
     所以只给「深底上的主色文字」加类，按需点亮：
       .em-text    深底上的主色文字  → #7fb8e8（亮蓝，对 #182234 约 6.4:1）
       .em-text-d  深底上的主色深字  → 同款亮蓝（浅色下仍是 --emerald-d 的稳重深蓝）
     ⚠ 这两个类只加在**文字**上，不要加到背景/边框的元素上。 */
.em-text{color:var(--emerald)}
.em-text-d{color:var(--emerald-d)}
body.theme-dim .em-text{color:var(--em-text-hi)}
body.theme-dim .em-text-d{color:var(--em-text-hi-d)}

/* 颜色工具
   注意：底色一律用「淡色实色」，文字色与底色色相拉开 ≥60°（不同色、也不相近）。
   这些值同样按 min(vs 卡片渐变四停靠点, vs 暗色卡) ≥1.135 求解过，
   所以放在卡片上不会糊底。历史实现是 rgba(...,.13) 的半透明软色，
   叠加后与卡片对比仅 1.12~1.22，暗色模式下几近不可见，已全部替换。 */
.c-emerald{color:#203c30;background:#a8dcc2}
.t-emerald{color:var(--fg)}
.t-rose{color:var(--rose)} .t-violet{color:var(--violet)} .t-sky{color:var(--sky)}
.t-amber{color:var(--amber)} .t-cyan{color:var(--cyan)} .t-teal{color:var(--teal)}
.bg-emerald-soft{background:#b1dac6;color:#4d2c6d}   /* 淡绿底 / 深紫字 */
.bg-rose-soft{background:#f9bdc9;color:#f0617e}      /* 逾期类：中粉底 + 数字红本体字（用户指定「文字直接用数字红」） */
.bg-violet-soft{background:#d9c9e6;color:#6d502c}    /* 淡紫底 / 深棕字 */
.bg-sky-soft{background:#bfd3e1;color:#6d2c52}       /* 淡天蓝底 / 深梅红字 */
.bg-amber-soft{background:#ded0b8;color:#2c596d}     /* 淡琥珀底 / 深青字 */
.bg-cyan-soft{background:#b4d7dc;color:#6d2c65}      /* 淡青底 / 深紫红字 */
.bg-teal-soft{background:#b1dad2;color:#602c6d}      /* 淡青碧底 / 深紫字 */
.bg-zinc-soft{background:#ced2d7;color:#392c22}      /* 中性灰底（保留：结案类需无彩色语义）/ 深赭字 */
.bg-indigo-soft{background:#cdcde7;color:#6d2c2c}    /* 淡靛底 / 深砖红字 */
.theme-dim .bg-amber-soft{color:#2c596d}

/* ===== 开关 toggle ===== */
.switch{position:relative;display:inline-block;width:42px;height:24px;flex:0 0 auto}
.switch input{opacity:0;width:0;height:0}
.switch .slider{position:absolute;cursor:pointer;inset:0;background:var(--border);border-radius:24px;transition:.2s}
.switch .slider:before{content:"";position:absolute;height:18px;width:18px;left:3px;top:3px;background:#fff;border-radius:50%;transition:.2s;box-shadow:0 1px 3px rgba(0,0,0,.3)}
.switch input:checked + .slider{background:var(--emerald)}
.switch input:checked + .slider:before{transform:translateX(18px)}
.switch input:disabled + .slider{opacity:.45;cursor:not-allowed}

/* ===== 仪表盘 ===== */
/* 经营分析顶部：四张卡片合并成的一张淡紫指标卡（用户 2026-09-15 指定）。
   共 6 格，3 列 × 2 行（律师费/已回款/未回款 · 已支出/净收款/净利率）。
   整体尺寸按「3 列能放下」收紧：图标 34→30、金额 23→19、内边距相应减小。
   断点：<340px 折 2 列兜底（极窄屏），≥341px 起即为 3 列。 */
.kpi-merged{display:grid;grid-template-columns:repeat(2,1fr);gap:0;margin-top:0;
  background:var(--card-grad);border:1px solid var(--border);border-radius:var(--radius);
  box-shadow:var(--shadow-soft);position:relative;overflow:hidden;padding:4px}
/* 底色：• 经营分析那张（默认 .kpi-merged）保持**紫色调不变** ——
     它和首页那张虽共用基类，但用户从没要求改它。
   • 首页那张（.kpi-merged.kpi-home）2026-09-17 起改为**蓝色**，
     因为用户要求「把首页前两个卡片底色互换」：
     问候卡拿走了这套紫渐变，这边就接过问候卡原来的蓝叠加。
   ⚠ 所以**不能**直接改 .kpi-merged 的 :before —— 那会连带把经营分析
     那张也染蓝。必须用 .kpi-merged.kpi-home 这个双类选择器单独覆盖。
   ⚠ 特异性提醒：.kpi-merged.kpi-home:before 是 (0,2,1)，
     .kpi-merged:before 是 (0,1,1)，前者高，**与书写顺序无关**都能覆盖。
     （之前这里靠的是"后写的赢"，那是因为两者特异性相同 (0,1,0)；
      现在换成了更高特异性的选择器，顺序就不再是关键了。） */
.kpi-merged:before{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(135deg,rgba(var(--kpi-tint-rgb),.13),rgba(var(--kpi-tint-rgb-d),.045))}
/* 首页这张的渐变（用户 2026-09-17「首页 在办案件这张卡片，你帮我做一点渐变」）。
   之前它只有**一层平铺的蓝叠加**（--card-tint-a/b 两段色、色相几乎相同），
   观感上是"一块均匀的淡蓝"，看不出渐变。
   现在改成**三层叠加**，让颜色在卡面上真正走起来：
     ① 底：原来的蓝叠加（保留，保证与其它蓝卡仍是同一族）；
     ② 斜向主渐变：左上偏青蓝 → 右下偏靛蓝，色相跨约 20°；
     ③ 右上角一团柔光斑：给一个视觉焦点，避免整块色"死平"。

   —— 第二轮（用户同日「在办案件 这里颜色现在有点深」）——
   实测第一版做深了：卡片顶部条带平均明度 **0.665**，
   而同页标准蓝卡（.card-tint-sm）是 **0.763**，深了 13%；
   最暗的左下角只有 0.579，明显发沉。
   根因是主渐变那层 alpha 给太大（.34/.22/.26）**又叠在原有的蓝叠加之上**，
   两层蓝相加就压暗了。
   修法：**把主渐变整体提亮、同时降 alpha**，让它只负责"色相走向"，
   不再负责"加深"；明度交给卡片自身的 --card-grad 渐变（顶白底蓝）。
   现在的值（.18/.10/.14）是算过的：
     预期把平均明度从 0.665 拉回 ~0.75 一档，贴近标准蓝卡但不完全相同
     （它本来就该比平铺的卡"有一点层次"，只是不该"更深"）。
   ⚠ 别再往上加 alpha 了 —— 这张卡的定位是"浅蓝带渐变"，不是深色卡。
   ⚠ 三层必须都是**半透明叠加**，不能把底色写成实色 ——
     卡片自己的 background 仍是 var(--card-grad)，
     这样暗色模式下底色自动跟着变，不用另外维护一套深色值。
   ⚠ 两张格之间只有 4px 内边距，渐变要从**卡片整体**铺过去，
     不能逐格铺 —— 逐格会让中间那道缝出现色阶断层。所以写在 :before 上。

   —— 第三轮（用户同日「再淡一点，上深 下淡这种」）——
   先说一个**实测出来的既成事实**，它决定了这一轮只能怎么改：
   卡片本体 --card-grad2 = linear-gradient(155deg, #fff 0%, #f3f8fb 38%,
   #d9ecf5 80%, #c9e3f0 100%) 本身**就是一条横跨整卡的斜向渐变**：
   实测本体在 y=120 这条线上，左端明度 0.921 → 右端 0.763，横向落差 **0.159**。
   所以任何"左右齐平"的诉求都做不到 —— 那是 .card 级别、全站 20 多张卡
   共用的底，动它会波及每一张卡（用户从没要求动它们）。
   实测对照（临时关掉 :before 量的）：
     本体纵向落差 0.031  →  叠加后 0.064（方向对上了，纵向被强化了 2 倍）
     本体横向落差 0.159  →  叠加后 0.091（横向反而被**削弱**了）
   即：这层叠加起的作用正是"削弱横向斜向、强化纵向"，
   方向与「上深下淡」一致；剩下的横向 0.09 是本体自带的，不是这层造成的。

   本轮实际改了**三处**（第二处是第三改，因为前两改力度不够）：

   ① **再淡一档**（本轮第一次改的样子）：主渐变 alpha .18/.10/.14 → .12/.07/.03。
      打底那层 var(--card-tint-a/b)（.30/.16，全站通用蓝的取值，
      和今日待办/近期事项/案件统计是**同一个值**）**不动** ——
      它负责"这张卡是蓝的"，动了它这张卡就跟其它蓝卡不是一族了。

   ② **方向改成纵向**：135° → 180°。
      用户原话「上深 下淡这种」：顶部压得深、往下逐级放开。
      180deg 的 0% 在**上边**，所以停靠点顺序必须是 深 → 中 → 淡，
      写反了就成了"上淡下深"，与要求正好相反。
      ⚠ 之前注释里写过"别改成纯纵向，会让两格的色差看起来像印歪了"，
        那条是针对**斜向**渐变的顾虑（左右两格各偏一个方向才像印歪）。
        纯纵向时两格在同一水平线上颜色**完全相同**，
        整张卡看过去横平竖直，不存在印歪的问题 —— 所以这条约束在此失效。

   ③ **改这张卡自己的底**（前两改都失败的根因，用户 2026-09-17 明确同意）：
      前两改只调叠加层，怎么都做不出"上深下淡"——原因不在叠加层，在**卡底**。
      卡片 background 用的是 var(--card-grad) = --card-grad2 =
         linear-gradient(155deg,#fff 0%,#f3f8fb 38%,#d9ecf5 80%,#c9e3f0 100%)
      这是**全站每张卡**的通用底，走向是**上白下蓝**（越往下越蓝越深）。
      实测本体自上而下 0.880 → 0.849，**往下深 0.031**。
      叠加层 alpha 只有 0.1~0.3 量级，物理上压不过它：
        · 第一版 .12/.07/.03 → 叠加后仍"上浅下深"
        · 第二版 .20/.09/.01 → 仍"上浅下深"
        · 第三版 .34/.10/.02 → 仍"上浅下深"（只是被拉平）
      所以改叠加层是死路 —— **必须把这张卡自己的底换掉**。

      ⚠ 这是**唯一**一张不用通用 --card-grad 的卡，用户已明确批准。
        范围严格限定在 `.kpi-merged.kpi-home`，不碰 .kpi-merged（经营分析那张）、
        也不碰 .card / --card-grad2，所以其它 20 多张卡一点不受影响。

      新底：linear-gradient(180deg,#cfe6f4 0%,#e2f0f8 46%,#f7fbfd 100%)
        · 180deg，0% 在**上边** → 上深下淡（与诉求一致，不再跟通用底对抗）
        · 顶部 #cfe6f4 明度约 0.79，底部 #f7fbfd 约 0.97，纵向差约 0.18
          与同页标准蓝卡（.card-tint-sm，本体 0.88~0.85 + 通用蓝叠加）
          的**整体明度**接近，所以不会显得突兀或比旁边卡更重
        · 色相同族：都是 #3aa8e8 那一族的浅蓝，不是另起一个色系

      叠加层同步**收回到只做"顶边加深"**：
        .34/.10/.02 → .10/.04/0（0% 在顶、100% 透明）
        既然方向已由卡底承担，叠加层就不该再抢戏；
        它现在只负责把最上面那条顶边再压一点，让"上深"更明确。
      ⚠ 暗色**不能**跟着用这套浅色底 —— 卡底写在 `.kpi-merged.kpi-home`
        这种不带 `.dark` 的选择器上，暗色下**同样生效**，
        会把深色卡刷成浅蓝（实测暗色卡面最亮 0.662，是刺眼的亮卡）。
        所以下面成对写了 `.theme-dim .kpi-merged.kpi-home{background:var(--card-grad)}`
        让它回落 —— 暗色本体 --card-grad2 本来就是上深下淡
        （#19233a → #15374f），方向与诉求一致，不需要换底。
      ⚠ 改这条卡底前，务必先 grep 确认 `.kpi-merged.kpi-home{` 只有**两处**
        （一处浅色底、一处暗色回落；另有一处是 grid-template-columns 布局，
        不冲突）。本项目已经因为"同名规则写了两次、后写的把前写的整条盖掉"
        踩过两次坑（.theme-dim .kpi-merged.kpi-home:before 重复定义、
        以及 180deg 被不存在的层叠问题误判），每次都是 grep 后才发现。 */
.kpi-merged.kpi-home{
  background:linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%)}
/* 暗色卡底：也必须**换掉**，不能只回落到通用底。
   我一度以为"暗色本体 --card-grad2 (#19233a → #1a2c44 → #15374f)
   本身就是上深下淡"，实测**反了**：
     明度 #19233a 0.0171 → #1a2c44 0.0244 → #15374f 0.0346
   `#15374f` 虽然是更深的**蓝**，但它的**明度更高**（0.0346 > 0.0171），
   所以通用底在暗色下是"**上深下浅**"——与诉求相反。
   （教训：判断"深浅"只能看相对明度，不能凭颜色名字猜。
     "深蓝" 说的是色彩饱和/暗度，跟 WCAG 相对明度不是一回事。）
   所以暗色单独给一套：顶部 #0f1d33 → 底部 #1b2f4d，明度 0.0158 → 0.0290，
   即"上深下浅"→ 修正为"上深下淡"。
   ⚠ 暗色的 alpha/色值不能照抄浅色 —— 浅色顶 #cfe6f4 明度 0.79，
     暗色顶 #0f1d33 明度 0.016，是两套完全不同的量级。 */
.theme-dim .kpi-merged.kpi-home{
  background:linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 48%,var(--kpi-home-3) 100%)}
/* 暗色的叠加层：**去掉通用打底层**（var(--card-tint-*)），只留纵向一层。
   为什么必须去掉 —— 手算过：暗色下打底是 .44/.24，而
     tint_a rgba(58,168,232,.44) 比 tint_b rgba(42,140,214,.24)
     **alpha 更高、颜色更亮**，于是顶部被它提亮、底部相对变暗，
     合成的结果是"顶部 0.133 / 底部 0.090" —— **方向被整个翻过来**，
     变成"上浅下深"，跟诉求正好相反。
   这是"两层渐变叠加时，谁决定方向"的典型坑：
   单看纵向层是深→淡，但打底层是**浅→深**且力度更大，两者相抵后取打底的方向。
   浅色下打底也是 .30/.16，但浅色卡底（#cfe6f4，明度 0.79）本来就很亮，
   打底的相对影响力小得多，所以浅色不需要去掉打底。
   ⚠ 去掉暗色打底的代价：这张卡在暗色下不再是"通用蓝族"的成员。
     实测可接受 —— 它自己的卡底就是蓝色系，且浅色下仍带打底层，
     两套模式下看都是"蓝的一张卡"。用户从没要求它必须与其它卡严格同色。 */
/* 暗色的叠加层：**用"压暗"而不是"染蓝"来加深顶部**。
   ⚠ 这是暗色与浅色最容易搞反的地方：
     浅色卡底明度 ~0.66，叠一层 rgba(58,168,232,·)（明度 0.36 的蓝）
     是**往下压**，所以浅色顶部的深 = 叠蓝。
     暗色卡底明度只有 ~0.028，而 rgba(58,168,232,·) 明度 0.36 ——
     叠上去是**往上提亮**！实测暗色顶部被抬到 0.051、下面反而 0.028，
     整体呈现"顶部一块亮斑 + 下面平"，方向彻底反了。
     所以暗色改用一层**适度的**压暗（近黑蓝 rgba(0,4,12,.28) → 0），
   配合卡底本身的上深下淡（#1b2f4d → #0f1d33，明度 0.028 → 0.016）。
   ⚠ 力度别给大：第一版用了 .55，实测顶部被压到 0.006（近乎纯黑），
     暗色卡看起来像"上面挖了个黑洞"。.28 就够做出可辨的纵向走向。 */
.theme-dim .kpi-merged.kpi-home:before{
  background:linear-gradient(180deg,
    rgba(var(--kpi-dark-rgb),.30) 0%,
    rgba(var(--kpi-dark-rgb),.14) 34%,
    rgba(var(--kpi-dark-rgb),0) 100%)}
.kpi-merged.kpi-home:before{
  background:linear-gradient(180deg,
    rgba(var(--tint-rgb),.06) 0%,
    rgba(var(--tint-rgb),.03) 46%,
    rgba(var(--tint-rgb),0) 100%),
    linear-gradient(135deg,var(--card-tint-a),var(--card-tint-b))}
/* ⚠ 首段 alpha 这个数**是算过的，不要随手调大**：
     卡里有一行 delta 灰字（--muted #66708a），压在"顶部最深合成色"上。
     （2026-09-25 该行已按用户要求取消，见上方 .delta 段说明；
       .06 这个值**保持不变** —— 它是当前卡底的既定观感，别因为"那行字没了"回调。）
     卡底 #cfe6f4（L 0.79）+ 纵向层 alpha 的合成明度与对比度实测：
       .10 → 顶部合成 L 0.5758 → 对比度 2.95:1  ← 不达标（WCAG 3:1）
       .08 →            0.5822 →        2.98:1
       .06 →            0.5886 →        3.01:1  ← 当前值，刚好达标
       .04 →            0.5950 →        3.04:1
     所以把首段定在 .06，二段同步从 .04 收到 .03 保持喉部平滑。
     若以后要把这张卡再调深，必须重新算这段灰字的对比度。 */
/* 暗色：本体色 --card-grad2 在暗色下**本身就是上深下淡**的
   ⚠⚠ 这里**又一次**踩了"同名规则写两条、后写的把前写的整条盖掉"的坑：
     旧的 `.theme-dim .kpi-merged.kpi-home:before`（带通用打底层那条）
     一直留在文件中，而我上面新写的暗色规则**特异性完全相同 (0,3,1)**，
     于是被它整条覆盖 —— 表现为"暗色换底生效了、但叠加层还是旧的"，
     depth 一直是 -0.022 怎么调都不动。
     这是同一个坑的**第三次**（前两次：.theme-dim ...:before 重复、180deg 误判）。
     已删除旧规则。**纪律：新增/修改带伪元素的选择器前，
     先 `grep -nE '^\.(dark )?<选择器>\{'` 数一遍，必须只有一条。** */
/* 卡片标题：图标 + 「律师费收支总计」（用户 2026-09-15 指定）。
   规格完全对齐全站通用的 .card-head .h，保证跟「收支看板」「案型结构」
   等卡片标题看起来是同一套：
     字体 15px / 600 / var(--fg)（浅色 #1e2433 近黑，暗色 #e6ebf5 自动转亮）；
     图标 17px，随 currentColor → 用户要的「黑色」在浅色下即近黑，暗色下自动反白；
     分隔线用 dashed 虚线，与 .card-head::after 一致。
   grid-column:1/-1 让标题通栏占满一行，后面的 6 格才会被挤到下面。 */
.kpi-merged .kpi-head{position:relative;grid-column:1/-1;display:flex;align-items:center;gap:8px;
  padding:16px 18px 12px;font-size:15px;font-weight:600;color:var(--fg)}
.kpi-merged .kpi-head:after{content:"";position:absolute;left:18px;right:18px;bottom:0;
  border-bottom:1px dashed var(--muted-2)}
/* 标题图标：💰 原生彩色 emoji（用户 2026-09-16 指定「还是换成 💰 有颜色的」）。
   不做任何 filter / 分层 —— 保持 emoji 自带的彩色外观。
   尺寸用 font-size 控制（emoji 尺寸跟字号走，不是 width/height），
   15px 让视觉重量与旁边 17px 线性 SVG 图标相当。
   暗色模式无需处理：emoji 自带色彩，在深浅底上都清晰。
   历史坑：曾用 filter:brightness(0) 压黑 —— 那会把钱袋与 $ 符号一起压成
   同一块纯黑，符号直接消失；emoji 是位图，无法只给其中一部分改色。 */
.kpi-merged .kpi-head-ico{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;
  font-size:15px;line-height:1;width:var(--card-head-ico-box)}
/* 若以后换回 SVG 图标，尺寸按 17px 对齐 .card-head .h svg。
   注：这里用「后代选择器」而不是子选择器 `>` —— 本沙箱的 Chromium
   对 .kpi-merged>.kpi-head-ico 这类子选择器实测 matches() 恒为 false
   （同样 DOM 用后代选择器就正常），会导致整条规则静默失效。 */
.kpi-merged .kpi-head-ico svg{width:17px;height:17px}
/* 内容水平居中（用户 2026-09-16 指定「下面内容往右移动 到整体居中」）。
   ⚠ 必须写在这一条里、而不是另起新规则：本块 `.kpi-merged>.kpi-col` 是 (0,2,0)，
   后面若用同样特异度的选择器追加 align-items:center，虽然能生效但容易被
   后续改动打乱顺序而静默失效；合并进主规则最稳。
   居中原因：每格内「图标+标签」那行很短（图标 21px + 标签约 42px ≈ 63px），
   而下方金额很宽（「116.50 万」≈ 104px）。两行都左对齐时，
   短的那行右侧会空出一大块，整格看着偏左、重心不稳。 */
.kpi-merged>.kpi-col{position:relative;display:flex;flex-direction:column;gap:6px;padding:13px 14px;min-width:0;
  justify-content:flex-start;align-items:center;text-align:center}
/* 分隔线：已全部取消（用户 2026-09-16 指定「卡片取消掉白色横线竖线」）。
   原来 6 格之间有竖线（每格描左边）+ 横线（第二行描上边），在浅色卡上呈白色细线；
   用户希望指标格之间干净通透，改为靠间距与栅格自然区分。
   注意 grid 的 gap 仍为 0 —— 去掉分隔线后若不加间距，6 格会贴在一起糊成一片，
   故给 .kpi-col 保留左右内边距（11px 10px），视觉上自然留出通道。
   历史提醒：这里曾因标题占了第 1 个 grid item 导致 nth-child 公式偏移一格
   （3n+1/n+4 应为 3n+2/n+5），现已整体删除边框规则，该坑不复存在。 */
.kpi-merged>.kpi-col+.kpi-col{border-left:none}
.kpi-merged>.kpi-col:nth-child(even){border-left:none}
.kpi-merged>.kpi-col:nth-child(n+4){border-top:none}
@media(min-width:341px){
  .kpi-merged{grid-template-columns:repeat(3,1fr)}
  .kpi-merged>.kpi-col{border-left:none}
  .kpi-merged>.kpi-col:nth-child(n+4){border-top:none}
  .kpi-merged>.kpi-col:nth-child(3n+2){border-left:none}
  .kpi-merged>.kpi-col:nth-child(n+5){border-top:none}
}
.kpi-merged .lab{font-size:11.5px;color:var(--muted);line-height:1.25;flex:1 1 auto;
  overflow:visible;text-overflow:clip;white-space:nowrap}
.kpi-merged .val{margin-top:1px;font-size:19px;font-weight:800;letter-spacing:-.4px;line-height:1.22;
  white-space:normal;overflow-wrap:anywhere}
/* 「图标 + 标签」那行也要居中，否则图标仍靠左、标签被 flex:1 撑开留在中间偏左 */
.kpi-merged>.kpi-col>div:first-child{justify-content:center}
/* 指标格图标：彩色 emoji（用户 2026-09-16 指定
   律师费🪙 已回款✅ 未回款⏳ 已支出💸 净收入💵 净利率💹）。
   原来是「紫色渐变小方块 + 白色线性 SVG」，现换成 emoji 字符：
     · 去掉 background / border-radius / box-shadow —— emoji 自身是完整图形，
       再套紫底会显脏，且 emoji 颜色各不相同，统一底色反而干扰；
     · 尺寸用 font-size 控制（emoji 跟字号走，width/height 对字符无效），
       17px 与标题图标 15px 形成层级，同时不撑高格子；
     · line-height:1 防止 emoji 撑出额外行高、把「图标+标签」那行顶歪。 */
.kpi-merged .ico{font-size:17px;line-height:1;flex-shrink:0}
.kpi-merged .ico svg{width:16px;height:16px}
/* ⚠ 暗色必须**再覆盖一次**，不能只靠上面那条浅色规则。
   踩过的坑：`body.theme-dim .kpi-merged:before`（本条，特异性 0,2,1）
   写在浅色规则 `.kpi-merged.kpi-home:before`（也是 0,2,1）**后面**，
   两者特异性相同 → **后写的赢** → 暗色下 .kpi-home 被打回紫色，
   于是暗色里两张卡又变成同一个色（实测两张都是 258°）。
   修法不是调整书写顺序（那太脆弱，谁把规则搬个位置就又坏），
   而是用 `.theme-dim .kpi-merged.kpi-home:before`：特异性 (0,3,1)，
   从**权重上**稳压 (0,2,1)，跟写在哪儿无关。 */
.theme-dim .kpi-merged:before{background:linear-gradient(135deg,rgba(var(--kpi-tint-rgb),.18),rgba(var(--kpi-tint-rgb-d),.07))}
/* ============================================================
   kpi 卡片「主题身份色」—— 已变量化（2026-09-21）
   ------------------------------------------------------------
   原先这里有 6 条 body.theme-{jade,warm} 的 kpi 特例，解决两类问题：
     ① kpi-home 卡底是**写死的浅蓝/深蓝**（不走变量）→ 其它主题继承到蓝色补丁；
     ② 压暗层 / 通用紫叠加是**写死的近黑蓝 / 紫** → 与新主题色相不搭。
   现全部提成变量，值写在各主题变量块里：
     --kpi-home-1/2/3   卡底三段（浅底主题与深底主题各一套，明度都上深下淡）
     --kpi-dark-rgb     深底压暗层的 RGB 三元组（dark=0,4,12 / ink=10,12,15 / pine=8,16,12）
     --tint-rgb         卡片叠加层基色三元组（现有 --card-tint-* 的同色版）
   ⚠ alpha（.30/.14/0 与 .06/.03/0）是**算过对比度的**，见上文两段长篇说明，
     新主题只换色相、绝不改这些数。
   ⚠ 新增主题必须把这几个变量给全，否则会继承上一主题的色相。 */
   ⚠⚠ 这里**曾经同时存在两条 `.theme-dim .kpi-merged.kpi-home:before`**：
     上面那条（值 .14/.08/.03，带 180deg）和这里这条（只有打底层）。
     两条**特异性完全相同 (0,3,1)** → 后写的赢 → 上面那条被整条丢弃，
     暗色下这张卡根本没有纵向叠加层，只剩一层 135deg 的通用蓝。
     这正是"light 正常、dark 没有纵向渐变"的根因。
     **教训：加新规则时没删掉旧的同名规则。** 改这类规则前先
     `grep -n '<选择器>' css/styles.css` 确认只有一处定义，
     别只看"我新写的那条在文件里"就以为生效了。
     现在这条已删（打底层已经在上面那条的 background 列表里，
     不需要再写一遍）。 */
@media(max-width:400px){
  .kpi-merged .val{font-size:17px}
  .kpi-merged>.kpi-col{padding:10px 8px;gap:5px}
  .kpi-merged .ico{font-size:15px}
  .kpi-merged .ico svg{width:14px;height:14px}
  .kpi-merged .lab{font-size:11px}
  .kpi-merged .kpi-head{padding:13px 14px 10px;font-size:14px}
  .kpi-merged .kpi-head:after{left:14px;right:14px}
  /* 窄屏 .kpi-head 自身 padding 从 18 降到 14，对应的对齐基准同步降 4px。
     ⚠ 这一行必须跟着 :root 的 --card-head-pad-l 一起改（22 → 18），
       漏了的话窄屏下「案件统计」会比「律师费收支总计」多右移 4px。 */
  :root{--card-head-pad-l:18px}
}
/* ============================================================
   首页概览卡 .kpi-home（用户 2026-09-17 指定「排版参照经营分析 律师费收支总计」）
   借的是 .kpi-merged 的布局逻辑：一张合并卡、横排若干格、每格竖向三层。
   两处必须单独开规则，否则会被经营分析那边的设定带偏：
   ① 列数 —— 上面 @media(min-width:341px) 把 .kpi-merged 设成 repeat(3,1fr)，
      那是给经营分析 6 格用的。首页只有 2 格，直接复用会各占 1/3、
      右侧空掉整整一列（430px 实测：卡宽 406px，两格共 264px，右空 137px），
      这就是用户说的「居中」没做到。.kpi-merged.kpi-home 是 (0,2,0)，
      比 media query 里的 (0,1,0) 高，锁成 2 列即可，与前后顺序无关。
   ② 图标 —— 沿用改版前的「渐变方块 + 白色 SVG」，不是经营分析那套 emoji
      （用户明确否掉了替换图标，详见 js/dashboard.js 里的注释）。
      背景色由 HTML 内联给出（每格不同），这里只管盒子的形状与尺寸。
   ============================================================ */
.kpi-merged.kpi-home{grid-template-columns:repeat(2,1fr)}
/* 图标尺寸（用户 2026-09-17 两次调整）：
   ① 先由 42px 收到 18px（「图标不要这么大，我要你参考经营分析那边」）——
      经营分析的指标图标是 emoji，实测渲染 17×17px，那是参照的视觉外廓；
   ② 收完后反馈「太小了，帮我扩大一点」，再加到 24px。
   24px 的依据：比参照 emoji 的 17px 大约 1.4 倍。台阶是这么来的 ——
   纯色方块比同尺寸彩色 emoji 视觉更"轻"（emoji 自带细节和色彩层次，
   方块是单色平面），等宽会显得单薄；1.4 倍双方向都稳妥：
   明显比 17px 的参照有存在感，又远小于原来 42px 的"压过一头"。
   内嵌 SVG 14px —— 与 24px 方块保持约 0.58 的比例，
   小图标（11px）在方块里会留出过多空白。
   ⚠ 不要把 emoji 的 17px 直接写成方块的 font-size：emoji 的 17px 是字形高，
   方块是容器盒，不是同一个量纲，写 17px 会让内嵌图标缩得几乎看不见。 */
/* 浅底 + 同色系深色线条（soft badge）。
   淡化的第二档（用户 2026-09-17「图标再淡一点」→ 选「浅底 + 深色线条」）：
   第一档只是把实心渐变提亮，但白色 SVG 在 #a78bfa 上对比度仅 2.7:1，
   继续提亮会糊，所以换成浅底 —— 底色亮度大幅提升（视觉上"淡"），
   线条改用同色系深色，对比度反而升到 5:1 以上。
   SVG 的 stroke 是 currentColor（见 icons.js 的 ic()），所以只改 color 就够。
   内描边 1px：浅底压在白色卡片上会"没有边界"，靠这圈描边勾出圆角方块的形。
   描边用同色系低透明度，不用中性灰 —— 灰描边在浅紫底上会显脏。 */
.kpi-home .ico{width:34px;height:34px;border-radius:11px;display:flex;align-items:center;
  justify-content:center;flex-shrink:0}
.kpi-home .ico svg{width:19px;height:19px}
/* emoji 字形（2026-09-17 起两个卡片的图标都是 emoji：📜 / 💴）。
   19px 是给 SVG 定的量纲，emoji 不能照抄：emoji 的 font-size 是**字形高**，
   而 SVG 的 19px 是外框边长，两者不等价；且 emoji 自带内边距、实际墨迹更小。
   实测 19px 的字形渲染出来只有约 17px 的可见高度，比原来的线条图标显小，
   所以按 34px 方块给到 21px（约 0.62 的比例）。
   line-height 固定 1：不固定的话 emoji 会按字体默认行高（约 1.2 倍）撑开，
   在 flex 居中的方块里会偏下 —— 这也是 emoji 常见的"看着不居中"的原因。 */
/* 21px -> 17px（用户 2026-09-17「图标缩小点，有点撑太满了」）。
   当初给 21px 是怕"显得小"，但那是照着 SVG 时代的观感推的：
   📜 的字形盒宽 26.2px（比方块 34px 只窄 8px），横向几乎顶到边，
   所以是"太满"而不是"太小"。17px 时字形盒约 21px，四周留白约 6.5px，
   与经营分析那边参照物的留白比例接近。
   ⚠ 只改字号即可，别去动方块尺寸 —— 方块 34px 是上一轮确认过的。
   —— 第二轮（用户同日「在办案件 里的图标再缩小点，因为视觉上这个图标会大一些」）：
   📜 与 💴 同为 17px、同为 21.2×17 的**几何尺寸**，但 📜 的墨迹是
   上下贯通的一整幅卷轴（顶天立地），💴 的钞票只占字形盒中间一带、
   四周本就空。字形盒相等时，墨迹的"视觉重量"完全不同 ——
   这就是同为 17px 却只显得 📜 偏大的原因。
   所以两个 emoji 用不同字号：📜 收到 15px，💴 维持 17px。
   这与"深浅参照案件统计"是同一个道理 —— 对齐看的是**视觉结果**，不是数值。
   用 .emoji-scroll / .emoji-money 两个类区分，而不是继续内联字号：
   将来再微调某一枚时，改一处、且不会波及另一枚。 */
.kpi-home .ico-emoji{font-size:17px;line-height:1;display:block}
.kpi-home .ico-emoji.emoji-scroll{font-size:15px}
/* —— 第三轮（用户 2026-09-17「这个框框里换一个颜色，因为和背景颜色一样了」）——
   根因是**同色系撞车**：卡片底已经是案件统计同款蓝（#c4e5f8 → #ddedf8），
   而方块底是 #f4f1ff / #eff7ff，两者明度差只有 0.05 左右、
   又都在同一片蓝调里，界面上就"糊成一片"看不见方块了。
   再往浅调不行、往深调一点点也不行（还是同色系），所以换**色系**：
     · 紫卡 → 实色紫罗兰
     · 蓝卡 → 实色青绿（不是蓝！蓝会和蓝底撞）
   同时把图标由"深色线条"改回**白色字形** —— emoji 是彩色字形、
       不受 color 控制，这里给白色是为了让 📜/💴 边缘有支撑，
       不然彩色 emoji 压在实色底上会显得飘。
   选色的硬指标是**色相角要离卡片蓝底(约 200°)足够远**，不只看明度。
   —— 第四轮（用户同日「不要改成实色啊，把第一个换个颜色」）——
   实色方案被否掉了，所以退回**浅底 + 深色线条**的样式（与原方案同构），
   只把撞色的那一枚换掉：
       · 在办案件 淡紫 #f4f1ff(≈265°) → **淡翡翠 #d6f5e6(≈152°)** ✅
       · 标的合计 淡蓝 #eff7ff(≈210°) → **也改成淡翡翠 #d6f5e6** ✅
         （先试过淡琥珀，用户改主意要两枚一致；底色只负责"浮出来"，
          两枚靠图标本身 📜 / 💴 区分即可）
     ⚠ 曾试过实色块，用户明确不要 —— 以后别再往实色改。
     判据是该色与**它所在卡片的底色**色相角拉开；
     注意底色已回退成原来的紫调（见 .kpi-merged 附近的说明），不是蓝的。
   ⚠ 这一档与前面「图标再淡一点」相反 —— 那边是卡片还白着、要求图标变淡；
     现在卡片自己变蓝了，图标必须重新"浮出来"。别再照旧改回去。
   投影：浅底不需要投影，留内描边勾形即可（与早期浅底方案一致）。 */
.kpi-home .ico.tone-violet{background:#d6f5e6;color:#046c4c;
  box-shadow:inset 0 0 0 1px rgba(4,108,76,.16)}
/* 标的合计：原为淡琥珀（用户随后改主意「淡琥珀 也改成淡翡翠」）。
   两枚都用淡翡翠，靠**图标本身**区分（📜 卷轴 / 💴 钞票），
   不靠底色 —— 底色只负责"从卡片背景里浮出来"这一个职责。 */
.kpi-home .ico.tone-sky{background:#d6f5e6;color:#046c4c;
  box-shadow:inset 0 0 0 1px rgba(4,108,76,.16)}
/* 暗色模式：浅底在深背景上会变成一块刺眼的亮斑，
   改用同色系低透明底 + 亮一档的线条（与早期浅底方案的处理一致）。 */
.theme-dim .kpi-home .ico.tone-violet{background:rgba(16,185,129,.18);color:#6ee7b7;
  box-shadow:inset 0 0 0 1px rgba(16,185,129,.3)}
.theme-dim .kpi-home .ico.tone-sky{background:rgba(16,185,129,.18);color:#6ee7b7;
  box-shadow:inset 0 0 0 1px rgba(16,185,129,.3)}
/* ⚠ 灰色副标题 `.kpi-home .delta` 的两条规则已删除（原为 11px / --muted /
   margin-top:10px + 左侧 13px activity 图标；曾是改版前 .stat .delta 的等价物，
   用户 2026-09-17 要求恢复，并特意用 .kpi-home 前缀锁作用域、避免泛类名 .delta
   被别的卡片撞上）。删除原因：2026-09-25 用户要求「在办 · 总案件数 /
   案件标的金额 这行取消掉」，首页两个大格不再渲染该行，规则随之无匹配对象。
   若日后要恢复该行，照上述参数重写即可。 */
@media(max-width:400px){
  /* 窄屏降一档（28 / 16px），与上面 34/19 的比例保持一致（约 0.56）。
     别只改方块不改 SVG —— 内嵌图标相对方块变小会显得空。 */
  .kpi-home .ico{width:28px;height:28px;border-radius:9px}
  .kpi-home .ico svg{width:16px;height:16px}
}
/* ============================================================
   案件统计卡（用户 2026-09-16 新增；同日追加年份/月份筛选 + 布局调整 + 蓝色底）
   标题行只有「案件统计」；切换器与年月下拉放在内容区第一行。
   ============================================================ */
/* 蓝色底（用户 2026-09-16 指定「取消掉底色，只留卡片底色，
   卡片不做上白下蓝，参照第一个紫色卡片逻辑，只是不用紫色，用蓝色的」）。
   做法与 .kpi-merged 完全同构：
     · 底层 background 用 --card（纯色），不用 --card-grad2
       —— 这就是「不做上白下蓝」：去掉 #ffffff→#c9e3f0 那条纵向渐变；
     · :before 铺一层 135° 蓝色渐变叠加（rgba 半透明，所以底仍是纯色感）。
   .st-card 在 HTML 里是 <div class="card st-card">，.card 已给了 --card-grad2，
   所以这里必须显式覆盖 background 才能压掉它（同优先级靠后生效）。
   ⚠ 不能用 overflow:hidden 来裁 :before —— 年月下拉是 absolute 定位、
     会伸出卡片边界，overflow:hidden 会把面板切掉（实测过：面板下半截被裁掉）。
     改为给 :before 自己加同值圆角（继承 --radius），并只锁 x 轴不裁 y 轴。 */
.st-card{background:var(--card);position:relative;overflow:visible}
.st-card:before{content:"";position:absolute;inset:0;pointer-events:none;
  border-radius:var(--radius);
  background:linear-gradient(135deg,var(--st-tint-a),var(--st-tint-b))}
/* 内容提到叠加层之上（:before 是 absolute，不参与 flex 布局，
   但会让同级文字被覆盖一层半透明蓝；加 position:relative + z-index 保证文字最上层） */
.st-card>.card-head,.st-card>.card-pad{position:relative;z-index:1}
/* 左边距对齐「律师费收支总计」（详见 :root 处 --card-head-pad-l 的注释）。
   ⚠ 这条必须在 media query **外面**：初版只写进 @media(max-width:559px)，
   结果 ≥560px 时退回 .card-head 的默认 18px padding，宽屏照样偏 8px。
   窄屏那条改成 var() 只是为了让这里的变量能覆盖不同断点，真正生效的是本条。 */
.st-card .card-head{padding-left:var(--card-head-pad-l)}
/* 标题行：不再挂控件，恢复成全站 .card-head 的标准形态
   （用户 2026-09-16 指定「把按月按年的按钮移到下面内容区，不要接在标题后面」）。
   下面这两条只为「防止标题意外换行」保留，不含任何工具条逻辑。 */
.st-card .card-head .h{white-space:nowrap;display:flex;align-items:center;gap:8px}
.st-card .card-head .h svg{flex-shrink:0}
/* 标题图标：🏛️ 原生彩色 emoji（用户 2026-09-16 指定，原为 ⚖️）。
   尺寸用 font-size 控制（emoji 是字符，width/height 无效）。

   图标与标题的间距（用户 2026-09-16 指定「图标和标题 间隔 参考 律师费收支总计」）：
     参考卡片 .kpi-merged .kpi-head 用的是 gap:8px，实测图标右缘→文字左缘 = 8px。
     本卡原来是 5px，现统一为 8px（间距由父级 .h 的 gap 提供，
     故模板里 `</span>` 与「案件统计」之间**不能再留空格** ——
     空格会被算作一个文本节点参与 flex 布局，实测额外多出约 4px，
     最终变成 12px 而不是 8px）。
     顺带 aria-hidden：图标是装饰，重复朗读无意义。

   ⚠ 图标不能压到下面虚线（用户 2026-09-16 指定「图标不要超过下面虚线」）：
     emoji 的「墨迹」通常比 font-size 盒更高，🏛️ 比 ⚖️ 更明显 —— 它自带
     基座与台阶，基线以下的部分会往下探。原来 15px/line-height:1 时，
     墨迹底几乎贴到虚线（实测视觉间隙只剩约 2~3px），看起来像「超线」。
     处理：字号收到 14px，并把行高固定为 1，靠 box 约束住墨迹；
     同时给 .h 一个与虚线无关的固定行盒高度，避免被撑高后挤压 padding。
     14px 与右侧标题文字（15px）同量级，视觉重量仍然相当。 */
/* 图标套进定宽盒并居中，盒宽与 .kpi-head-ico 共用同一个变量 ——
   这样 🏛️ 与 🪙 尽管字形宽度不同，后面的标题文字起点仍严格一致。 */
.st-card-ico{font-size:14px;line-height:1;flex-shrink:0;display:inline-flex;align-items:center;
  justify-content:center;width:var(--card-head-ico-box)}
/* 内容区第一行：切换器 + 年月下拉。
   独立成行、左对齐；控件高度统一 24px，避免 2px 视觉错位。
   允许换行（flex-wrap）—— 320px 极窄屏下控件会自动折行，不会溢出卡片。 */
.st-bar{display:flex;align-items:center;gap:6px;flex-wrap:wrap;padding:0 2px 9px}
.st-bar>*{height:24px}
/* ============================================================
   统一分段切换器 .seg（用户 2026-09-17 指定三处统一）
   ------------------------------------------------------------
   要求原文：
     · 通讯管理「机构 个人 企业」—— 文字大小、加粗参考**日程列表**的字体；
       且「三个标题之间间距可以再拉宽一点」；
     · 案件管理「不同标题点击」也参考改好后的「机构 个人 企业」这种样式。
   参照物实测（430px 视口）：
     日程列表徽标 .badge.ev-badge → font-size:11px / font-weight:600
     案件管理 .mode-tg            → 按钮 29px 高、12px 字、内边距 6px 12px
   所以 .seg 的口径 = 「日程列表的字号字重(11px/600) + 案件管理的控件体量」。
   为什么不直接复用 .mode-tg：它的选中态是**白底**（.mode-tg button.active
   是 --card 背景 + 阴影），而通讯管理那一版选中态是**淡紫底**，
   两者观感不同。用户说的是"参考这种样式"，指的是体量与字形，
   故选中的配色跟随全站紫调（与 .st-sw-btn 的淡紫一致），
   体量则比原来那枚 20px 高的小胶囊明显放大。
   命名用 .seg 而不是 .cl-switch：三处（通讯管理 / 案件管理 / 案件统计）
   共用同一套规则，名字带 cl- 前缀会误导下一个改动的人。
   ============================================================ */
.seg{display:inline-flex;align-items:center;gap:6px;padding:3px;border-radius:11px;
  background:var(--bg);border:1px solid var(--border);flex-shrink:0;box-sizing:border-box;
  position:relative}
.seg>button{appearance:none;border:0;background:transparent;cursor:pointer;
  height:29px;padding:0 13px;border-radius:8px;
  font-size:11px;font-weight:600;line-height:1;
  color:var(--muted);font-family:inherit;white-space:nowrap;
  position:relative;z-index:1;
  /* 文字颜色单独过渡：滑块是位置在动，文字是颜色在变，
     两者时长一致才不会一个先到一个后到、看着脱节。
     .26s 是首版（用户 2026-09-17「不要一下跳动」已够），
     同日追加「速度还可以放慢点」→ 提到 .42s；再追加「远的按钮还是太快」
     → 改随距离变化，这里必须跟着用同一个 --seg-dur 变量，
     否则滑块慢下来了、字色还按固定 .42s 变，两者会脱节。 */
  transition:color var(--seg-dur,.42s) ease}
.seg>button:focus-visible{outline:2px solid var(--violet);outline-offset:-2px}
/* 选中态的紫底**不再画在按钮上**，改由下面的 .seg-thumb 滑块承载。
   这是本次改动的关键（用户 2026-09-17：「紫色框框 不要一下跳动，缓慢滑动」）：
   原写法是给 .is-on 直接换 background:linear-gradient(...) —— 而 CSS
   **无法对渐变做插值**，transition 对它无效，所以切换时是硬切，观感就是"跳"。
   改成：一个独立的滑块元素，用 transform:translateX 移动位置、
   width 跟着目标按钮变宽变窄，这两者都是可动画属性，于是能真正滑过去。
   滑块不参与命中测试（pointer-events:none），点击照常落到按钮上。 */
.seg-thumb{position:absolute;z-index:0;top:3px;left:0;height:29px;
  width:var(--seg-w,0px);transform:translateX(var(--seg-x,0px));
  border-radius:8px;pointer-events:none;opacity:0;
  background:linear-gradient(135deg,rgba(139,92,246,.16),rgba(124,58,237,.09));
  box-shadow:inset 0 0 0 1px rgba(139,92,246,.28);
  /* 时长不是写死的：由 JS 的 syncSegThumbs() 按「这次要滑多远」写进 --seg-dur
     （近距离 .42s 起，每多 1px 加 .004s，封顶 .8s）。
     固定时长的毛病是位移越远速度越快 —— 远的按钮看着"嗖"一下就过去了。
     曲线 (.32,.06,.2,1)：起步稍快、收尾更柔，配长时长是"稳稳滑过去"，
     而 (.4,0,.2,1) 起步偏慢，时长一拉长那个"顿一下"会被放大。 */
  transition:transform var(--seg-dur,.42s) cubic-bezier(.32,.06,.2,1),
             width var(--seg-dur,.42s) cubic-bezier(.32,.06,.2,1),
             opacity .22s ease}
/* 只有存在选中项时才显示滑块 —— 否则初始状态会在左上角闪一个 0 宽的块。
   .has-on 由 JS 的 syncSegThumbs() 添加（选中项存在时才加）。 */
/* 只写 .has-on / .seg-no-anim 而不带 .seg 前缀：这两个类由 JS 加在切换器
   根元素上，而根元素可能是 .seg 也可能是 .st-switch（案件统计「按月/按年」）。
   滑块元素本身都叫 .seg-thumb，按它选就够了，不必枚举两种根。 */
.has-on>.seg-thumb{opacity:1}
/* 首次摆位时由 JS 临时加上，用于关掉过渡（详见 utils.js 的 syncSegThumbs）。
   只禁 transform / width，opacity 保留 —— 首次出现仍需要那 0.18s 的淡入。 */
.seg-no-anim>.seg-thumb{transition:opacity .22s ease}
.seg>button.is-on{color:#6d28d9}
.theme-dim .seg>button.is-on{color:#c4b5fd}
/* 通讯管理那行：切换器在搜索**上方**独占一行（用户 2026-09-17 指定），
   不能塞进 .toolbar（弹性布局会把搜索框拉到同行）。
   下边距 10px —— toolbar 自身 margin-bottom 是 14px，
   两行之间比"行到卡片"更紧凑，才不会被误读成两块无关内容。 */
.cl-filter-bar{margin-bottom:10px}
/* 分段切换器：两枚胶囊，选中态用紫色描边 + 淡紫底，与整页紫调一致。
   （2026-09-16 曾随「按月」一并删除，后按用户要求恢复，规则与删除前一致。） */
/* 与 .seg 是同一套机制（共用 .seg-thumb 滑块、共用 syncSegThumbs），
   但**尺寸刻意不同**：这里 20px 高 / 12px 字 / 7px 内边距，是嵌在案件统计
   标题行里的紧凑款；.seg 的 29px 是独立成行的常规款。别为了复用把两者合并，
   案件统计那一行高度有限，换成 29px 会把整行顶高。 */
.st-switch{display:inline-flex;align-items:center;gap:1px;padding:0 1px;border-radius:9px;
  background:var(--bg);border:1px solid var(--border);flex-shrink:0;box-sizing:border-box;
  position:relative}
.st-sw-btn{appearance:none;border:0;background:transparent;cursor:pointer;
  padding:0 7px;height:20px;border-radius:7px;font-size:12px;font-weight:600;line-height:20px;
  color:var(--muted);font-family:inherit;white-space:nowrap;
  /* 文字在滑块之上（滑块 z-index:0，按钮 z-index:1），否则紫色底会盖住字。 */
  position:relative;z-index:1;
  transition:color var(--seg-dur,.42s) ease}
/* 切换器 hover 不再变色（与案件行保持一致，用户要求取消变色反馈）。
   保留 :focus-visible 的键盘焦点环以满足可访问性。 */
.st-sw-btn:focus-visible{outline:2px solid var(--violet);outline-offset:2px}
/* 紫底**不画在按钮上**，交给 .seg-thumb 滑块 —— 与 .seg 同样的原因：
   CSS 无法对 linear-gradient 插值，写在按钮上 transition 无效、切换是硬切。
   这里只留字色。 */
.st-sw-btn.is-on{color:#6d28d9}
.theme-dim .st-sw-btn.is-on{color:#c4b5fd}
/* 紧凑款滑块：top 0 —— .st-switch 的 padding 是 "0 1px"（上下 0），
   按钮紧贴 padding box 上沿；.seg 那边 padding 是 3px 所以用 top:3px。
   高度/圆角跟着按钮走（20px / 7px），比 .seg 的 29px / 8px 小一档。 */
.st-switch>.seg-thumb{top:0;height:20px;border-radius:7px}
/* ——— 自定义下拉（年 / 月）———
   不用原生 <select>：原生控件在本 App 的玻璃拟态卡片里会渲染成系统样式，
   圆角/字号/暗色配色都对不上。这里自绘按钮 + 绝对定位面板，完全跟随主题。 */
.st-sel{position:relative;flex-shrink:0;display:inline-flex;align-items:center}
.st-sel-btn{display:inline-flex;align-items:center;gap:3px;appearance:none;cursor:pointer;
  padding:0 6px 0 8px;height:24px;border-radius:9px;border:1px solid var(--border);
  background:var(--bg);color:var(--fg);font-family:inherit;font-size:12px;font-weight:600;
  line-height:1;transition:.16s;white-space:nowrap;box-sizing:border-box}
/* 下拉按钮 hover 边框不再变紫（同上）。 */
.st-sel-btn[aria-expanded="true"]{border-color:rgba(139,92,246,.6);
  box-shadow:0 0 0 3px rgba(139,92,246,.12)}
.st-sel-cur{font-variant-numeric:tabular-nums}
.st-sel-caret{width:14px;height:14px;color:var(--muted);flex-shrink:0;transition:transform .18s}
.st-sel-btn[aria-expanded="true"] .st-sel-caret{transform:rotate(180deg)}
/* 面板高度上限放宽到 260px（用户 2026-09-16 追加油 2022 起算的年份后，
   年份项由 3 个变 6~7 个：每项约 31px，6 项 ≈ 186px+内边距；
   原 232px 会让最后一项卡在边缘需要滚动，放宽后 2022~2027 一屏看完）。 */
.st-sel-menu{position:absolute;top:calc(100% + 6px);right:0;z-index:60;min-width:100%;
  max-height:260px;overflow-y:auto;padding:4px;border-radius:12px;
  background:var(--card);border:1px solid var(--border);
  box-shadow:0 10px 28px rgba(15,23,42,.16),0 2px 6px rgba(15,23,42,.08);
  display:flex;flex-direction:column;gap:1px}
.theme-dim .st-sel-menu{box-shadow:0 12px 32px rgba(0,0,0,.5),0 2px 6px rgba(0,0,0,.3)}
.st-sel-menu[hidden]{display:none}
.st-sel-opt{appearance:none;border:0;background:transparent;cursor:pointer;text-align:left;
  padding:7px 10px;border-radius:8px;font-family:inherit;font-size:12.5px;font-weight:600;
  color:var(--fg);white-space:nowrap;transition:.14s;font-variant-numeric:tabular-nums}
/* 下拉选项 hover 底色取消（同上）；仍用字重变化提示可点。 */
.st-sel-opt:focus-visible{outline:2px solid var(--violet);outline-offset:-2px}
.st-sel-opt.is-on{color:#6d28d9;background:linear-gradient(135deg,rgba(139,92,246,.16),rgba(124,58,237,.09));
  box-shadow:inset 0 0 0 1px rgba(139,92,246,.28)}
.theme-dim .st-sel-opt.is-on{color:#c4b5fd}
/* 汇总行：左侧「本月/全年签约 N 件」+ 右侧「合计 ¥N 万」与「已收 ¥N 万」。
   等宽数字：「…签约 9 件」里的数字若用比例字宽，年份/件数会随数值抖动，
   与分组头保持一致更整齐。 */
.st-sum{display:flex;align-items:center;justify-content:space-between;gap:10px;
  /* 2026-09-18 用户指定「灰色字都改成黑色」：汇总行的引导词（「本月」「全年」、
     「本月签约 / 件」等）原是 --muted，现统一用主文本色。
     ⚠ 用 var(--fg) 而不是写死黑色 —— 暗色主题下会自动反白成 #e6ebf5。
     ⚠ .st-sum 是「案件统计」与「收费统计」两卡共用的选择器，改这里两卡同时生效，
        正合适 —— 用户对两张卡提的是同一个要求。 */
  color:var(--fg);
  font-size:12px;padding:2px 2px 8px;font-variant-numeric:tabular-nums}
.st-sum b{color:var(--fg);font-weight:800;font-size:13px}
/* 「本月/全年签约 N 件」整行加粗（用户 2026-09-17 指定）。
   原先只有中间的件数是 <b>，两侧「本月签约」「件」是 400 灰，
   一行里粗细跳两档反而看不出重点。整行统一到 700，件数再靠 <b> 升到 800，
   层级仍在但不再打断阅读。
   颜色不改，跟随 .st-sum 的 --muted —— 用户只说加粗，没说换色，别顺手替他决定。 */
.st-sum-lead{font-weight:700}
/* 右侧两个金额并排：左「合计」、右「已收」。
   flex + gap 排布，靠窄屏媒体查询（字号 11px + gap 收紧）压在单行，
   不要退回 flex-wrap:wrap 的竖排写法（用户 2026-09-16 指定
   「合计 已收 不要另起一行」）。 */
.st-sum-money{display:inline-flex;align-items:center;gap:10px;font-weight:700}
/* 加粗修正（用户 2026-09-17）：
   上一轮只做到了「本月/全年签约 N 件」这一行加粗，右侧的「合计 + 金额」
   「已收 + 金额」漏掉了 —— 用户原话「我说的这一行，后面 合计和金额
   已收和金额，你没有加粗」。现在整行（品牌行 + 金额行）统一 700。
   ⚠ 与下方 .st-sum-recv 的注释冲突，注意区分：
     2026-09-16 用户说的是「**颜色**上已收不要加粗」（当时在讨论配色层级，
     已收靠 --teal 区分于合计的黑），而 2026-09-17 的诉求是这一**行**的
     字重要统一。两者不矛盾：**字重统一 700，颜色区分照旧保留**。
   加在 .st-sum-money 容器上而不是逐个 span：以后再加第三项金额不会漏。 */
/* 「合计」黑色（--fg），与左侧文案的灰、以及右侧「已收」的蓝绿拉开层级。
   用户 2026-09-16 指定「合计 颜色改成黑色」—— 原先与左侧同灰(--muted)。
   用主题变量而非写死 #000：暗色下 --fg 自动转浅色，否则会黑底黑字看不见。 */
.st-sum-fee{color:var(--fg);font-variant-numeric:tabular-nums;white-space:nowrap}

/* 收费统计卡的汇总行同样要固定列宽（2026-09-18 修排版宽度）。
   ⚠ 必须与「案件统计卡删掉已收合计」那件事分开看 ——
   我一度以为「删了已收就不用固定列宽了」，于是把这条规则删掉，结果
   收费统计卡的「合同金额合计」又开始随右边「已收合计」的宽度漂移
   （实测换月：1132 ↔ 1138）。原因很简单：**取消已收的是案件统计卡**，
   收费统计卡的汇总行仍然是「合同金额合计 + 已收合计」两项，
   「左坐标被右元素宽度牵扯」的病根照样存在。
   ⚠ 必须限定在 [data-feestat-card] 作用域内：.st-sum-money 是两张卡共用的
   选择器，直接改会连带影响案件统计卡（那边现在只剩一项，不受益也不需要）。
   列宽取 148px —— 实测各写法的真实渲染宽度（12px / 700 / tabular-nums）：
     「合同金额合计 ¥0.00 万」    121px
     「合同金额合计 ¥34.30 万」   128px
     「合同金额合计 ¥1234.56 万」 141px   ← 上限，148 留约 7px 余量
   ⚠ 上一版写 116px 是不够的：常见的 121~128px 已经超出固定列宽，而 grid 的
     固定 px 列**不会被内容撑开**，超出部分只会溢出列边界 —— 于是对齐再次失效
     （实测换月时汇总行合同右端出现 1132 ↔ 1138 两个值）。
     教训：这种固定列宽要按「最宽可能值」留余量，宁可偏大也别刚好卡住常见值。 */
[data-feestat-card] .st-sum-money{display:grid;grid-template-columns:148px 148px;
  gap:10px;justify-items:end}
/* 「已收」用蓝绿色区分于「合计」的黑 —— 来源是实收，语义上更该被突出。
   用 --teal(#22b49e) 的深一档，浅色底上可读性达标（对比度 > 4.5:1）。
   暗色下 --teal 偏暗、在深蓝底上发闷，故单独换成亮档 #4fd6c0。
   字重跟随容器（700），层级差异只由颜色承担。 */
.st-sum-recv{color:var(--teal);font-variant-numeric:tabular-nums;white-space:nowrap}
.theme-dim .st-sum-recv{color:#4fd6c0}
/* 案件行：标题（整行宽度）+ 元信息行（类型徽标 + 状态徽标 + 律师费）+ 右箭头。
   长按/悬停变色已取消（用户 2026-09-16 指定「长按案件会变色，取消掉底色」）：
     · 原规则 .st-row:hover{background:color-mix(...violet 5%...)} —— 已删除；
     · 移动端「长按」实际触发的是 :hover 与 -webkit-tap-highlight-color 两者，
       故这里同时补上 tap-highlight-color:transparent 和 touch-callout:none，
       确保按下时任何底色/高亮都不出现（与站内 .li / .gt-row 的做法一致）。
   保留 cursor:pointer 提示可点，交互反馈靠页面跳转本身。 */
.st-list,.st-group-body{display:flex;flex-direction:column}
.st-row{display:flex;align-items:center;gap:10px;padding:10px 2px;
  border-bottom:1px solid var(--border);cursor:pointer;
  -webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}
.st-row:last-child{border-bottom:0}
/* 注：.st-row:hover / :active 的底色规则已按要求移除，此处不再有任何背景变化。 */
.st-row-main{min-width:0;flex:1}
.st-row-title{font-size:13px;font-weight:600;line-height:1.35;overflow:hidden;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.st-row-meta{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:5px}
.st-row-meta .badge{font-size:10.5px;padding:1px 7px}
/* 注：.st-row-num（案号）规则已移除 —— 用户 2026-09-16 指定取消案号，
   渲染层不再输出该节点，样式一并清掉避免留下死代码。 */
.st-row-fee{display:inline-flex;align-items:baseline;gap:2px;font-size:11.5px;
  color:var(--fg);white-space:nowrap;font-variant-numeric:tabular-nums}
/* 2026-09-18 用户指定：本卡的灰色文字统一改黑（主文本色）。
   涉及 .st-row-fee-lab（「律师费:」）/ .st-row-date（新加的委托日期）
   / .st-group-count（件数）/ .st-group-fee（分组小计）/ .st-empty（空态）。
   ⚠ 用 var(--fg) 而不是写死 #000 —— 暗色主题下 --fg 会自动变成浅色，
     写死就是「浅色看着对、暗色变成隐形黑字」。 */
/* 委托日期（如「2月25日」），紧跟在类型/状态徽标之后、律师费标签之前。
   margin-right:5px 给出与「律师费:」的呼吸感 —— 不加的话渲染出来是
   「2月25日律师费:¥16.00 万」，汉字连在一块很难断句。
   ⚠ 不要用 gap：父级 .st-row-fee 是 inline-flex 且 gap:2px，
     改容器 gap 会同时把「律师费:」与金额之间的距离也拉大。 */
.st-row-date{color:var(--fg);font-weight:600;font-variant-numeric:tabular-nums;
  margin-right:5px}
.st-row-fee-lab{color:var(--fg);font-weight:600;font-size:10.5px}
.st-row-arrow{color:var(--muted-2);flex-shrink:0;margin-left:auto}
/* 折叠分组：头部整行可点，箭头旋转 90° 表示展开。
   行内顺序（用户 2026-09-16 指定箭头移到最后）：
     「N月签约案件 (N)」  ¥xx.xx 万  ›
   箭头从行首移到行尾后，靠 .st-group-fee 的 margin-left:auto 把费用
   推到右侧、箭头紧随其后（金额列右端对齐的原理见下方 .st-group-fee 注释）。 */
.st-groups{display:flex;flex-direction:column}
.st-group{border-bottom:1px solid var(--border)}
.st-group:last-child{border-bottom:0}
/* 折叠分组头（按年模式下的「N月签约案件 (N)」行）。
   padding 曾  11px 2px（用户 2026-09-17 反馈「按年时，月份和月份上下间距
   不要这么宽」）—— 实测行高 39px、12 个月总高 479px，收起来一屏放不下。
   改 8px：行高降到 33px，总高约 393px，省出一屏的三分之一。
   为什么不再往下压：这行是**点击展开**的按钮，iOS 人机指南建议点按目标 ≥44px、
   最低不低于 ~30px；33px 已是密集列表可接受的下限，再窄误点率会明显上升。
   注意相邻行之间那 1px 间隔来自 .st-group 的 border-bottom，不是这里的外边距，
   想改间隙要动 .st-group 而不是 padding。 */
.st-group-head{display:flex;align-items:center;gap:8px;width:100%;appearance:none;border:0;
  background:transparent;cursor:pointer;padding:8px 2px;font-family:inherit;
  font-size:13px;font-weight:600;color:var(--fg);text-align:left;transition:.15s}
/* 分组头 hover 不再变紫（同上，取消变色）。 */
.st-group-head:focus-visible{outline:2px solid var(--violet);outline-offset:-2px}
/* ⚠ 必须用等宽数字（tabular-nums），否则列对不齐 —— 用户 2026-09-16 反馈：
     「10月 11月 12月 因为 1 到 0 占位没有其他月份数字占位宽，导致这三个月
       没有和上面其他月份对齐。还有括号里数量 1 这个数字时也是同样的情况」
   原因是字体默认走 proportional（比例数字）：'1' 的字宽明显小于 '0'~'9'，
   于是 '10月'~'12月' 的起点比 '01月'~'09月' 右移了几像素，
   '(1)' 也比 '(2)' 窄 —— 在左对齐的列表里就是明显的参差。
   tabular-nums 让 0~9 共用同一字宽，两组自然对齐。
   注意这一条要加在「数字所在的元素」上，而不是只加在外层：
   子元素继承 font-variant-numeric，故加在 .st-group-name / .st-group-count 上即可，
   两者原本没有该属性（只有 .st-group-fee 有），这就是漏对齐的原因。 */
.st-group-name{flex:0 0 auto;font-variant-numeric:tabular-nums}
.st-group-count{color:var(--fg);font-weight:600;font-size:12px;
  font-variant-numeric:tabular-nums}
/* 金额 / 箭头的右端对齐（2026-09-18 重做；用户反馈「按年时卡片里 ¥ 没对齐」）。
   ⚠ 旧方案给 .st-group-fee 和 .st-caret **都**挂了 margin-left:auto，
     本意是兼容「0 件分组不渲染金额」的行；但 flex 里多个 auto 边距会
     **均分**剩余空间，金额位置随自身宽度、件数位数一起漂移
     （「¥9.00 万」与「¥111.30 万」两行的 ¥ 不在同一列）—— 这就是没对齐的根源。
   现行方案（单 auto + 恒渲染占位，别再改动）：
     · 只有 .st-group-fee 带 margin-left:auto —— 独吞剩余空间，右端固定停在
       「箭头 + 间距」之前，12 行金额自然形成一列右对齐的金额列；
     · 箭头**不要** auto —— 紧跟金额之后即可，位置由上一行逻辑保证；
     · 0 件分组也渲染空的 .st-group-fee（宽度 0），auto 才始终有人承担，
       箭头与金额列在 12 行里始终停在同一右端位置（模板见 analytics.js statGroup）。 */
.st-group-fee{margin-left:auto;font-size:12px;font-weight:700;color:var(--fg);
  font-variant-numeric:tabular-nums}
.st-caret{color:var(--muted);flex-shrink:0;transition:transform .2s}
.st-group.is-open .st-caret{transform:rotate(90deg)}
/* 折叠体：默认 0 高隐藏，展开后展开；用 grid-template-rows 做平滑动画 */
.st-group-body{display:none;padding:0 2px 10px 26px}
.st-group.is-open .st-group-body{display:flex}
.st-empty{padding:14px 2px;text-align:center;color:var(--fg);font-size:12.5px}

/* ============================================================
   收费统计卡（2026-09-18 新增）—— 左右两栏：左「合同金额」/ 右「已收金额」
   ------------------------------------------------------------
   为什么是左右而不是上下：合同按**委托日**归集、已收按**收款日**归集，
   两者通常不是同一天发生。并排看的是「这月的合同盘子 vs 实际进账」，
   塞进同一行会让人误以为同一天既有签约又有收款。

   等宽数字（tabular-nums）在多处显式声明：月份 01~12、日期 1~31、
   金额都会因比例数字导致列参差 —— 与 .st-group-name 那条踩的是同一个坑。
   ============================================================ */
/* 两栏网格。align-items:start 让左右栏各自按内容高度顶对齐，
   不会因为一侧行数多就把另一侧拉高（拉高会出现大片空白）。 */
.fs-cols{display:grid;grid-template-columns:1fr 1fr;gap:12px;align-items:start}
.fs-col{min-width:0;border:1px solid var(--border);border-radius:12px;overflow:hidden}
/* 栏头：栏名 + 「N 笔 · 合计」。底色比卡片略深一档，作为两栏的分界标识。 */
.fs-col-h{display:flex;align-items:baseline;justify-content:space-between;gap:8px;
  padding:7px 10px;border-bottom:1px solid var(--border);
  background:color-mix(in srgb,var(--fg) 5%,transparent)}
.fs-col-t{font-size:12px;font-weight:700;color:var(--fg);white-space:nowrap}
/* 2026-09-18 用户指定「按月 按年 显示的灰色字 都改成黑色」：
   栏头计数、明细日期、案件标题、空态、底部说明统一用主文本色 var(--fg)。
   ⚠ 同样用 var(--fg) 而非写死黑色 —— 暗色主题下自动反白。
   不改的是：**颜色语义本身有含义**的几处 ——
     · .fs-row-a.is-recv / .fs-g-recv / .fs-col-sum.is-recv 用青色
       （区分「合同 vs 已收」两个维度，含栏头合计金额，见下方新规则）；
     · .fs-caret 箭头保持灰色（它是图标不是文字，纯黑会让整行失去层次）。 */
.fs-col-m{font-size:11px;color:var(--fg);font-variant-numeric:tabular-nums;white-space:nowrap}
.fs-col-m b{color:var(--fg);font-weight:800}
/* 栏头合计金额的颜色跟随栏语义（用户 2026-09-18 指定「已收金额后面
   N 笔 · ¥N 后面的金额改成绿色」）。此前整串都是主文本色，唯独这一处
   与栏内其它金额（明细行 / 月份组 / 汇总行）颜色不一致。
   现规则：已收金额走全卡统一的青绿 --teal（暗色换亮档 #4fd6c0，与
   .fs-row-a.is-recv / .fs-g-recv 同款）；合同金额保持主文本色（跟随
   .fs-col-m 的 var(--fg)，无需额外规则）。
   ⚠ 「N 笔」件数与「笔 ·」分隔符仍是主文本色 —— 用户只点名金额部分。 */
.fs-col-sum.is-recv{color:var(--teal)}
.theme-dim .fs-col-sum.is-recv{color:#4fd6c0}
.fs-col-list{display:flex;flex-direction:column}
/* 明细行：两列两行 —— 上行「日期 | 金额」，下行案件标题跨两列。
   金额列用 auto 宽紧贴内容，日期列 1fr 占满剩余，避免金额左右飘。 */
.fs-row{display:grid;grid-template-columns:1fr auto;grid-template-areas:"d a" "t t";
  gap:2px 8px;padding:8px 10px;border-bottom:1px solid var(--border);cursor:pointer}
.fs-row:last-child{border-bottom:0}
.fs-row-d{grid-area:d;font-size:11.5px;color:var(--fg);font-variant-numeric:tabular-nums}
.fs-row-a{grid-area:a;font-size:12.5px;font-weight:700;
  font-variant-numeric:tabular-nums;white-space:nowrap}
/* 合同金额用主文本色（黑/白），已收用蓝绿 —— 与上方 .st-sum 的
   「合计黑 / 已收青」层级一致，全站同一套颜色语义。 */
.fs-row-a.is-fee{color:var(--fg)}
.fs-row-a.is-recv{color:var(--teal)}
.theme-dim .fs-row-a.is-recv{color:#4fd6c0}
.fs-row-t{grid-area:t;font-size:11px;color:var(--fg);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fs-empty{padding:14px 10px;text-align:center;color:var(--fg);font-size:12px}
/* 底部说明：有收费未登记日期时提示，避免用户疑惑「已收合计为何偏少」。 */
.fs-note{margin-top:8px;padding:0 2px;font-size:11px;color:var(--fg)}
/* ==============================================================
   利润统计卡 · 12 个月表格（2026-09-19 新增，取代原「收支看板」柱状图）
   四列：月份 / 收入 / 支出 / 净收，末行「合计」。
   列宽：月份固定 52px，三列金额各 1fr —— 与「收费统计」卡同一排版语言
   （金额右端成直线 + tabular-nums 等宽数字），换行不会发生。
   表头/合计行用 --card-2 打底与数据行区分；暗色下该变量自动变深。
   ============================================================== */
/* 卡内柱状图容器（原「收支看板」的柱状图已并入利润统计卡）：
   浅边框把「图」与「表」分成两块，避免 12 行数字紧贴 SVG 分不清层级。 */
/* 柱状图月份热区：整列可点（透明矩形压在柱子上），hover 浅蓝高亮提示可点击。
   ⚠ fill 必须是 transparent 而不是 none —— none 不参与命中测试，点了没反应。 */
.pf-hit{fill:transparent;cursor:pointer;transition:fill .15s}
.pf-hit:hover{fill:rgba(58,168,232,.12)}
.theme-dim .pf-hit:hover{fill:rgba(143,176,221,.16)}
/* 月份小浮层（用户 2026-09-19 指定，参照其截图样式）：
   白色半透明小卡片，浮在图表顶部、横向跟随所点月份。
   · 半透明 + backdrop blur —— 能隐约透出底下的网格线，不显得"糊上一块"；
   · pointer-events:none —— 浮层不拦截点击，点到它等于点到图表；
   · 隐藏用 [hidden]{display:none}，与 JS 的 hidden 属性配合。 */
/* 利润统计卡（2026-09-19）：底色与「收费统计」「案件统计」同为 st-card 蓝底
   （用户指定「颜色要和收费统计卡片一样」）。

   标题对齐（用户两轮反馈后的最终口径：「把利字和收费统计的收字对齐，然后图标再往左移」）：
     ⚠ 注意 .h 的左边界是**图标盒**起点，不是文字起点 —— 量对齐必须用 Range 量首字，
       否则会像我第一轮那样按 .h 边界调，越调越偏。
     实测（820px 视口，Range 量首字）：
       收费统计：图标左 39px，「收」字左 66px（= 39 + 图标盒 19 + gap 8）
       利润统计：图标左 31px，「利」字左 58px —— 落后 8px。
     结论：.card-head 的 padding-left 必须比收费卡**多 8px**（即 30px = 22 + 8），
       才能让「利」也落在 66px；图标再单独 margin-left:-8px 左移到与「收」同列的视觉起点。
     ⚠ 这两条是一组，改任一条都要重算另一条（+8 与 -8 相互抵消的是"图标位置"，
       文字靠 +8 才对齐）。 */
.st-card.pf-card .card-head{padding-left:calc(var(--card-head-pad-l) + 8px)}
.st-card.pf-card .st-card-ico{margin-left:-8px}
.pf-tip{position:absolute;top:8px;transform:translateX(-50%);min-width:138px;
  background:rgba(255,255,255,.92);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  border:1px solid var(--border-strong);border-radius:10px;
  box-shadow:0 6px 18px -6px rgba(30,36,51,.28);
  padding:8px 10px;z-index:20;pointer-events:none}
.pf-tip[hidden]{display:none}
.theme-dim .pf-tip{background:rgba(24,34,52,.90);box-shadow:0 6px 18px -6px rgba(0,0,0,.5)}
/* 利润统计表：**扁平行 + 行间分隔线**，不再套一层带边框圆角的框。
   （用户 2026-09-19：「不要卡片套卡片，参考上面两个卡片」）
   ⚠ 原来这里是 `border:1px solid + border-radius:12px + overflow:hidden`，
     视觉上等于在 st-card 里面又放了一张小卡片 —— 与上方案件统计/收费统计
     的扁平列表（.st-row / .st-group 只用 border-bottom 分行）不一致。
   现在对齐那两张卡的做法：容器无边框无圆角，行与行之间一条 1px 线。 */
.pf-tbl{margin-top:2px;--pf-cols:52px 1fr 1fr 1fr}
.pf-tr{display:grid;grid-template-columns:var(--pf-cols);gap:8px;align-items:center;
  padding:8px 10px;font-size:12px}
/* 行分隔线。
   ⚠ 踩坑记录（重要，别再改回去）：
     ① 最初用 `.pf-tr+.pf-tr`（相邻兄弟）—— 每月下面插入 .pf-detail 后，
        两个 .pf-tr 不再相邻，后半张表分隔线**整片消失**。
     ② 改用 `.pf-tbl>*+*` —— 选择器能匹配（element.matches 返回 true），
        但 border-top-width 实测仍是 0px。原因是 `.pf-row` 里的 `border:0` 简写
        把 border-top-width 显式置 0，而两者**同为 (0,1,0) 权重**，靠源码顺序决胜负，
        在这种通配符 + 简写的组合下不可靠。
   现在用 `.pf-tbl>.pf-tr` 显式指定子元素类名（权重 0,2,0，稳压 .pf-row 的 0,1,0），
     再配 `:not(:first-child)` 排除首行。
   ⚠ `.pf-row` 的 `border:0` 必须保留 —— 它是为了清掉 <button> 的浏览器默认边框，
     不能靠删它来解决，只能在分隔线上加权重。 */
/* ⚠ 表头是首行，本规则 `:not(:first-child)` 会跳过它 —— 表头与第一行数据之间
     的分隔由表头自己的 border-bottom 提供（见下方 .pf-th）。
     所以这里再加 `:nth-child(2)` 排除第一行数据，避免「表头底边 + 首行顶边」双线。
     （表头恒为第 1 个子元素，第一行数据恒为第 2 个。） */
.pf-tbl>.pf-tr:not(:first-child):not(:nth-child(2)){border-top:1px solid var(--border)}
/* ⚠ 展开区不加分隔线（用户 2026-09-19：「点击月份撑开后 这个虚线不需要」）。
   原为 `.pf-tbl>.pf-detail{border-top:1px dashed var(--border)}`，已删。
   现在月份行与展开区的分界完全由展开区内部的 .pf-col 自己表达：
     · 上方有 8px 间距（.pf-col 的 margin-top）
     · 每个 .pf-col 自带 1px 实线边框 + 圆角
   即「留白 + 框」已足够交代从属关系，再加虚线是三重冗余，视觉上还显脏。 */

/* 月份行改为「可点击撑开」，所以是 <button>。
   ⚠ 必须显式重置 button 的浏览器默认样式（font/背景/边框/内边距/宽度/对齐），
     否则字体会退回系统 UI 字体、按钮会居中、还会带一圈默认边框 —— 整张表就乱了。

   背景策略（用户 2026-09-19：「点击后不要变白」）：
     · 默认、hover、展开态**一律透明** —— 整张表保持同一底色，不留任何色块；
     · 去掉 hover 浅底后，「这行能点」改由 cursor:pointer 表达（触屏无 hover 无影响）；
     · 不再需要 .is-flash / .is-open 的背景规则，一律删干净。 */
.pf-row{width:100%;appearance:none;border:0;background:transparent;
  font-family:inherit;color:inherit;text-align:left;cursor:pointer}
.pf-row.is-flat{cursor:default}                 /* 全零月份不可展开 */
.pf-row:not(.is-flat):focus-visible{outline:2px solid var(--violet);outline-offset:-2px}
/* ⚠ 显式压掉展开态可能继承到的任何背景（含 UA 的 :active / :focus 默认色）。
     用 background:none 而非 transparent，把 background-image 也一起清掉。 */
.pf-row:hover,.pf-row:active,.pf-row:focus,.pf-row.is-open,
.pf-row:not(.is-flat):hover,.pf-row.is-open:hover{background:none}

/* 展开后的逐笔明细（就地插在月份行下方，横跨整表宽度）。
   背景策略（用户 2026-09-19：「撑开的内容底色也不要用其他颜色」）：
     · 明细块**透明**，与表格同底，不再用 color-mix 浅灰；
     · 与上方月份行的从属关系改由：左侧缩进 + .pf-col 自身的边框圆角
       （用户后又指定去掉虚线分隔，见上方 .pf-tbl>.pf-tr 注释旁）。
   ⚠ 不参与 .pf-tr 的 grid 布局 —— 它是独立块，否则会被塞进 4 列里。

   ⚠ 列对齐（第一版踩的坑）：明细行原来用 `34px 1fr auto` 三列，
     结果是金额被 `auto` 顶到块的最右边缘（456px），而上面月份行的「支出」
     金额落在 224~336 那一列 —— 错位 120px，看着像两套东西串在一起。
   现在的口径：**明细行复用表格的 4 列网格**（与 .pf-tr 同一套 grid-template-columns），
     这样「日期」占月份列、「案件名」占收入列、「金额」占净收列，
     左右边界与上面的数字列天然对齐，不需要任何魔法数字。
     ⚠ 用同一个 CSS 变量 --pf-cols 承载列定义，改一处两边同步（见 .pf-tr）。 */
.pf-detail{background:none;padding:8px 10px 10px}
.pf-detail[hidden]{display:none}
/* 收入 / 支出各一个带框的小卡（用户 2026-09-19：「展开以后做个框框，
   参考收费统计 按年 点击展开后的」）。
   与 .fs-col 同一套视觉语言：1px 边框 + 12px 圆角 + overflow:hidden
   （overflow:hidden 是必需的 —— 它让栏头的浅底与内容区被圆角裁齐，
    否则栏头背景会顶出圆角之外，四角出现直角毛刺）。
   两组之间留 8px 间距；框内不加额外底色，与卡片本体同底。 */
.pf-col{min-width:0;border:1px solid var(--border);border-radius:12px;
  overflow:hidden;margin-top:8px}
/* 栏头：组名 + 「N 笔 · 合计」。底色比卡片略深一档（与 .fs-col-h 同款处理），
   作为框内分区的标识；金额部分加粗并由组语义决定颜色。 */
.pf-col-h{display:flex;align-items:baseline;justify-content:space-between;gap:8px;
  padding:7px 10px;border-bottom:1px solid var(--border);
  background:color-mix(in srgb,var(--fg) 5%,transparent)}
.pf-col-t{font-size:12px;font-weight:800;color:var(--fg);white-space:nowrap}
.pf-col-m{font-size:11px;color:var(--fg);font-variant-numeric:tabular-nums;white-space:nowrap}
.pf-col-m b{color:var(--fg);font-weight:800}
.pf-col-list{display:flex;flex-direction:column}
/* 明细行：与 .pf-tr 同一套列网格，左右边界自动对齐 */
.pf-dl{display:grid;grid-template-columns:var(--pf-cols);gap:8px;align-items:baseline;
  padding:6px 10px;font-size:11.5px;line-height:1.5}
/* 行分隔线：用 border-top 加在「非首行」上，与表格行的做法一致
   （首行已有栏头的 border-bottom，避免双线）。 */
.pf-dl+.pf-dl{border-top:1px solid var(--border)}
/* 日期占「月份」列 —— 复用 --pf-cols 第一列，和上方「03月」左边界自然对齐。
   颜色用 --muted（而非 --muted-2）：--muted-2 在浅蓝卡底上偏淡、对比度低，
   日期是扫读每一笔的锚点，要能一眼看到。 */
.pf-dl-d{color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap;
  overflow:visible;text-align:left}
/* 案件名跨「收入 + 支出」两列 → 有足够长度，超长时省略 */
.pf-dl-t{grid-column:2 / 4;color:var(--fg);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;min-width:0}
/* 金额占「净收」列：右对齐，右边界 = 上方净收数字的右边界 */
.pf-dl-n{grid-column:4;text-align:right;font-weight:700;
  font-variant-numeric:tabular-nums;white-space:nowrap}
/* 备注（方式/摘要）另起一行，从案件名起点开始铺到最右 */
.pf-dl-s{grid-column:2 / -1;color:var(--muted-2);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:11px}
/* 明细金额配色（用户 2026-09-19：「支出金额用红色」）：
     收入 → 主文本色（不用绿色 —— 用户要求「不要用其他颜色」，只有支出明确要红）
     支出 → 红色
   ⚠ 选择器必须命中**分组的框 .pf-col** 上的 is-in / is-out（见 js/analytics.js 里
     grp() 的注释）—— 类名只挂栏头时这条规则匹配不到明细行，金额会保持深色。
     这个坑踩过两次（先挂标题、后挂栏头都不对），改结构时务必确认类挂在框上。
   ⚠ 用 --expense-red 而不是全站的 --rose(#f0617e)：--rose 偏粉，
     用户要的是「红色」。这个色仍在同一色相族内，与表格「支出」列不冲突。 */
.pf-col.is-in .pf-dl-n{color:var(--fg)}
.pf-col.is-out .pf-dl-n{color:var(--expense-red)}
.theme-dim .pf-col.is-out .pf-dl-n{color:#ff6b81}
/* 栏头合计金额随组语义着色（收入主色 / 支出红），与明细行金额一致 */
.pf-col.is-out .pf-col-m b{color:var(--expense-red)}
.theme-dim .pf-col.is-out .pf-col-m b{color:#ff6b81}
/* 表头行 + 合计行。
   （用户 2026-09-19：「不要卡片套卡片，参考上面两个卡片」+「月份 金额等都加粗」）
   背景一律去掉 —— 原来用 --card-2 浅灰底会在扁平表里形成两条色带，
   正是「卡片套卡片」观感的一部分；改为纯靠字重 + 分隔线区分层级。
   表头：加粗到 800、用主文本色（不再是浅灰），字号 11.5px，
     底边给一条实线把它与数据行明确分开（否则「月份」和「01月」会糊在一起）。
   ⚠ 表头的下边框只能用 border-bottom —— 因为行分隔线是加在「非首行」的
     border-top 上，表头是首行，拿不到那条线。 */
.pf-th{color:var(--fg);font-weight:800;font-size:11.5px;background:none;
  border-bottom:1px solid var(--border-strong);padding-bottom:7px}
/* 合计行：加粗到 800，与上面两个卡片的分组小计口径一致；上边框加重一档，
   让「12 个月数据」与「合计」之间有一道更明确的分界。 */
.pf-tf{font-weight:800;background:none;
  border-top:1px solid var(--border-strong);padding-top:9px}
.pf-tf .pf-month,.pf-tf .pf-num{font-weight:800}
/* 月份与所有数字统一加粗（用户：「月份 金额等都加粗」）。
   ⚠ 月份 700、金额 700 —— 比表头(800)略轻，保留「表头 > 数据」的层级；
     净收列更高一层（pf-net 已是 800），它是最需要被扫到的列。 */
.pf-month{color:var(--fg);font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:700}
.pf-num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:700}
/* 收入保持主文本色；支出用 rose（与全站「支出」语义色一致） */
.pf-num.is-in{color:var(--fg)}
.pf-num.is-out{color:var(--rose)}
/* 净收统一翡翠绿（--teal）：与柱状图里的净收柱、图例色块同一颜色语义。
   暗色底上 --teal(#22b49e) 偏暗，用 #4fd6c0 —— 与「收费统计」卡「已收金额」同款亮青。 */
.pf-net.is-pos{color:var(--teal);font-weight:800}
.pf-net.is-neg{color:var(--rose);font-weight:800}
.pf-net.is-zero{color:var(--muted);font-weight:700}
.theme-dim .pf-net.is-pos{color:#4fd6c0}
/* 窄屏（≤400px）：月份列收到 46px、字号降半档，保证三列金额仍不折行。
   ⚠ 改的是 .pf-tbl 上的 --pf-cols（而非 .pf-tr 的 grid-template-columns），
     这样展开的明细行会跟着一起收窄，列对齐不会崩。 */
@media(max-width:400px){
  .pf-tbl{--pf-cols:46px 1fr 1fr 1fr}
  .pf-tr{gap:6px;padding:8px 8px;font-size:11.5px}
  .pf-detail{padding:6px 4px 8px}
  .pf-dl{gap:6px;padding:6px 7px;font-size:11px}
  .pf-col-h{padding:6px 8px}
}
/* 按年模式的 12 个月分组（结构与 .st-group 对齐，保持视觉一致） */
.fs-groups{display:flex;flex-direction:column}
.fs-group{border-bottom:1px solid var(--border)}
.fs-group:last-child{border-bottom:0}
.fs-group-head{display:flex;align-items:center;gap:8px;width:100%;appearance:none;border:0;
  background:transparent;cursor:pointer;padding:8px 2px;font-family:inherit;
  font-size:13px;font-weight:600;color:var(--fg);text-align:left;transition:.15s}
.fs-group-head:focus-visible{outline:2px solid var(--violet);outline-offset:-2px}
.fs-g-name{flex:0 0 auto;font-variant-numeric:tabular-nums}
/* 「合同 / 已收」两个金额的容器。
   演进三阶段（踩坑顺序留档，别退回去）：
     ① 最初 inline-flex + margin-left:auto 整体右对齐 —— 「合同」的右端被右边
        「已收」的宽度牵着走：12 个月里合同右端跑出 1194/1162/1156 三个值，
        已收左端同理 1204/1172/1166，切月还会整套漂移。这就是用户反馈的
        「排版很乱」。根因：右对齐容器里，左元素坐标依赖右元素宽度。
     ② 改 grid 固定列宽 —— 两列各自成直线了，但整组仍被推到行最右，
        「合」字起点在 1035（卡片中线才 775），不是用户要的分布。
     ③ 现在（用户追加「合同向左移动、已收靠右移动」）用 flex + flex:1：
        容器吃满「月份名之后、箭头之前」的全部剩余空间 ——
          → 合同是容器内第一个子元素，紧贴月份名排最左，「合」字成直线；
          → 已收 margin-left:auto 顶到容器最右、紧贴箭头，末位字符成直线。
   「合」字起点稳定的前提：左侧 .fs-g-name 经 stMon() 补零恒为「01月…12月」，
   配合 tabular-nums 宽度恒定。若以后改回「1月」这种不补零写法，必须给它
   flex:0 0 NNpx 固定宽度，否则相邻列起点会随位数跳动。
   ⚠ 不要再退回 inline-flex + gap，那正是 ① 的形态。 */
.fs-g-money{display:flex;flex:1;align-items:center;gap:10px;
  font-size:12px;font-weight:700;font-variant-numeric:tabular-nums}
.fs-g-fee{color:var(--fg);white-space:nowrap;flex:0 0 auto}
/* margin-left:auto 把已收顶到容器右端（紧贴箭头），实现「最后一个数字对齐」 */
.fs-g-recv{color:var(--teal);white-space:nowrap;flex:0 0 auto;margin-left:auto}
.theme-dim .fs-g-recv{color:#4fd6c0}
.fs-caret{color:var(--muted);flex-shrink:0;transition:transform .2s}
.fs-group.is-open .fs-caret{transform:rotate(90deg)}
.fs-group-body{display:none;padding:8px 2px 10px}
.fs-group.is-open .fs-group-body{display:block}

@media(max-width:559px){
  /* 窄屏（手机竖屏）两栏放不下 —— 560px 下每栏只剩约 250px，
     日期 + 金额 + 案件名三件套会挤成两行且标题大量截断。
     改为上下堆叠：合同在上、已收在下，可读性好过强行并排。 */
  .fs-cols{grid-template-columns:1fr}
  /* 窄屏下卡片左右内边距本就紧张，两栏间距收到 10px 换取更多正文宽度。 */
  .fs-cols{gap:10px}
  /* 手机点按目标：金额行高保持 ≥30px，避免误点跳转案件详情。 */
  .fs-row{padding:9px 10px}
  /* ⚠ 窄屏【不再】需要覆盖 .fs-g-money：它已改为「flex:1 + 已收 margin-left:auto」，
     宽度天然自适应，不存在固定列宽在 320px 下顶破视口的问题。
     旧的 grid-template-columns:84px 84px 随布局方案一并作废 —— 留着会误导
     后来者以为这里还在用 grid，也会在以后调宽屏值时忘同步（差 16px）。 */
  /* 但 **汇总行必须** 收窄：它仍是 148px 固定列宽（见上面 [data-feestat-card]
     .st-sum-money），148×2 + gap 在 320px 视口下会直接顶破卡片。
     取 118px：窄屏字号降到 11px（见 .st-sum 的窄屏规则），实测此时
     「合同金额合计 ¥34.30 万」约 108px，118 有余量也不会溢出。 */
  [data-feestat-card] .st-sum-money{grid-template-columns:118px 118px;gap:8px}
  /* 同类提示：下面 .st-row-fee-lab 的窄屏字号仍要收紧（那是字号不是布局）。 */
}

/* ⚠ 这个块是「案件统计」卡（.st-*）窄屏收尾。
   2026-09-18 加 .fs-* 样式时，本块的 `@media(max-width:559px){` 开头行被我误删
   （旧串含该行、新串没补回），导致下面 50 行窄屏规则**脱出媒体查询、变成全局生效**：
   所有视口下 .st-card 头部内边距变成窄屏值、.st-sum 被压到 11px 且强制 nowrap、
   .st-bar/.st-row 全部收窄。更隐蔽的是上面 .fs-cols 的堆叠规则**同时失效** ——
   因为 .fs-cols 的基础规则（1fr 1fr）在同一文件里位置更靠前，
   而上面那个 @media 块的括号闭合顺序被破坏后，LIFO 匹配把覆盖关系搞反了。
   修复 = ① 本行补回；② .fs-cols 的堆叠单独成块（就在上面），不再和本块挤在一起。
   教训：删除含 `@media` 开头行的代码块时，务必确认新串补回了花括号与闭合括号。 */
@media(max-width:559px){
  /* 左边距右边距不对称是刻意的：左值取 --card-head-pad-l 以对齐上方
     「律师费收支总计」的标题（见 :root 处注释），右侧保持 14px 不变 ——
     右边原本就有内容或空白余量，跟着动反而会让卡片内容区整体偏移。
     注意左侧这里必须继续用 var() 而不是写死数字：本条在窄屏下会覆盖上面那条
     基础规则，写死就等于把宽屏的值硬套到窄屏（差 4px）。 */
  .st-card .card-head{padding:12px 14px 12px var(--card-head-pad-l)}
  /* 窄屏图标与标题间距同样保持 8px（原来这里写 5px，会覆盖上面的 8px ——
     这就是「间距设了却没生效」的原因：媒体查询同特异度、位于文件更后处）。
     间距属于用户明确指定的「参照律师费收支总计」，不随宽度收紧。 */
  .st-card .card-head .h{font-size:14px;gap:8px}
  .st-card .card-head .h svg{width:15px;height:15px}
  .st-bar{gap:4px;padding:0 2px 8px}
  .st-sw-btn{padding:0 6px;font-size:11.5px}
  .st-sel-btn{padding:0 5px 0 7px;font-size:11.5px;gap:2px}
  .st-sel-caret{width:13px;height:13px}
  .st-row{padding:9px 2px;gap:8px}
  .st-row-title{font-size:12.5px}
  /* 元信息行现在是「类型徽标 + 状态徽标 + 委托日期 + 律师费:金额」四项
     （2026-09-18 新增委托日期）。320px 实测：可用宽 210px，两个徽标占 87px
     + 两处 gap 12px，只剩 111px，而「日期+律师费」要 116px —— 差 5px 就换行
     （行高 18 → 40）。这里从三个方向各省一点，正好压回单行：
       · 各项 gap 6 → 4（两处省 4px）；
       · 日期字号再降 0.5px、与「律师费:」的间距 3 → 2（约省 3px）。
     ⚠ 这三条是配套的，只改其中一条压不回去。改完务必复测 .st-row-meta
       的 height 是否回到 18px（单行）。 */
  .st-row-meta{gap:4px}
  .st-row-fee{font-size:11px}
  .st-row-date{font-size:10px;margin-right:2px}
  .st-row-fee-lab{font-size:10px}
  .st-group-head{font-size:12.5px;padding:7px 2px}
  .st-group-body{padding-left:18px}
  /* 汇总行窄屏**不再折行**（用户 2026-09-16 指定「合计 已收 不要另起一行」）。
     曾用过 flex-wrap + first-child{flex-basis:100%} 把「合计/已收」推到第二行，
     但用户要的是一整行。320px 下要放下「全年签约 9 件  合计 ¥111.30 万  已收 ¥45.60 万」，
     靠三处收紧实现（都不改文案）：
       · 字号 12px → 11px；
       · 左右两组之间的 gap 10px → 6px，金额之间 10px → 8px；
       · 左侧「签约 N 件」与金额组都设 flex-shrink:0 之外还允许金额组压缩 ——
         实际靠字号下降后总宽 ≈ 300px，320px 视口内正好收得下。
     若以后金额位数变多（如「¥1,116.50 万」）仍可能溢出，
     届时优先再降金额字号，而不是回到折行。 */
  .st-sum{flex-wrap:nowrap;gap:6px;font-size:11px}
  .st-sum b{font-size:12px}
  .st-sum-money{gap:8px;flex-shrink:0}
  .st-sum>span:first-child{flex-shrink:1;white-space:nowrap}
}

/* ⚠ 这条媒体查询**必须在**上面 @media(max-width:559px) 块**之外、且在其之后**：
   .fs-cols 的基础规则（grid-template-columns:1fr 1fr）在文件更前处，
   本块靠「同特异度 + 位置更后」才覆盖得住。
   2026-09-18 的教训：上面那个块的 `@media` 开头行被误删后，
   本块虽然语法没错，但 .fs-cols 的堆叠规则反而**被自己上面泄漏出来的
   基础规则盖住**（实测 320px 下仍是两列、每列 258px，明细被压爆）。
   修复要点是两个：① 补回上面那行；② 本块单独成块、不要嵌进别的块。 */
@media(max-width:559px){
  /* 窄屏（手机竖屏）两栏放不下 —— 560px 下每栏只剩约 250px，
     日期 + 金额 + 案件名三件套会挤成两行且标题大量截断。
     改为上下堆叠：合同在上、已收在下，可读性好过强行并排。 */
  .fs-cols{grid-template-columns:1fr;gap:10px}
  /* 手机点按目标：金额行高保持 ≥30px，避免误点跳转案件详情。 */
  .fs-row{padding:9px 10px}
}

.grid-2{display:grid;grid-template-columns:1fr;gap:16px}
@media(min-width:1024px){.grid-2{grid-template-columns:2fr 1fr}}
@media(min-width:1024px){.grid-2-eq{grid-template-columns:1fr 1fr}}
.grid-1-1{display:grid;grid-template-columns:1fr;gap:16px}
@media(min-width:1024px){.grid-1-1{grid-template-columns:1fr 1fr}}
/* 「你好」问候卡（2026-09-17 之前：指定颜色深浅参照案件统计卡 →
   现在：用户要求与下面那张指标卡**互换底色**）。
   底色演进：
     ① 最初自己一套「蓝紫混合」三色渐变（#eef2fc → #eaf6fb → #f3eefc），
        与案件统计的纯蓝底不是一路；
     ② 2026-09-17 改成案件统计同款蓝（纯 --card 打底 + :before 蓝叠加）；
     ③ 2026-09-17 用户要求「把首页前两个卡片底色互换」→ 本卡改拿
        指标卡那套「--card-grad 渐变 + 紫色 :before」。
   所以现在这张是**紫调渐变**，下面那张指标卡才是蓝调。
   ⚠ 两张的底色规则互换了，改其中一张前先确认另一张 —— 别照旧印象下手
     （我上一轮就是凭旧印象判断"这张是蓝的"，结果改错对象）。
   :before 的圆角必须 inherit（本文件的通用纪律，见 .card-tint 注释）。 */
/* ⚠⚠⚠ 2026-09-21 用户：「首页，问候语卡片 淡色系主题，颜色要加深，深色系不用动。
   淡色系顶部参考第一个主题从深到浅渐变。」
   ------------------------------------------------------------------
   病灶用「彩度 = S×L」量化（直观反映颜色有多"显"），以淡色模式为基准 0.489：
     light 0.489(基准) / sakura 0.415 / sand 0.353 / moss 0.271 / dusk 0.255
     / mist 0.101  ← 雾灰只有基准的 1/5，所以"几乎看不出颜色"
   ⚠ 不能只压 L（明度）——那会让颜色发浑发脏；
     正确做法是**保持各自色相不变、适度提饱和**，让彩度向基准靠拢。
   ⚠ 也不能粗暴拉齐彩度到 0.489：实测苔原会从"莫兰迪灰豆绿"变成明亮黄绿、
     暮云变成薰衣草紫、雾灰会失去"全站唯一无色相"的定位。
     故采用**温和提饱和**（原 S ×1.5 左右，上限 0.60），保留各主题的灰调性格；
     雾灰只靠下沉 L 加深、几乎不动 S，保住其中性灰身份。

   ⚠⚠ 变量隔离（重要）：**没有复用 --card-grad2**。
     --card-grad2 是全站通用变量，同时供 .card / .calc-func / .calc-panel /
     设置页卡片使用（`.card{background:var(--card-grad2)}` 等 4 处），
     改它会波及 20+ 张卡片 —— 而用户只要求改**问候语卡片这一张**。
     所以另建专属变量 --wel-bg，只被 .welcome 引用。
     （同类先例：首页指标卡早就用专属的 --kpi-home-1/2/3。）

   浅色系 6 套的 --wel-bg **不再自己调色**，改为直接引用第 2 张卡（首页在办案件卡）
   的 --kpi-home-1/2/3，几何同样取 180deg 纯纵向 ⇒ 两卡同源同色、不可能不一致：
     0% --kpi-home-1 → 46% --kpi-home-2 → 100% --kpi-home-3。
   ⚠ 历史（前四版为何都不对）见下方「第五版」注释。
   ⚠⚠⚠ 2026-09-21 第五版（用户：「首页 问候语卡片颜色不对，参照第二张卡片的颜色来。。。」）
     —— 这次不再自己调色，而是**直接引用第 2 张卡的变量**：
        --wel-bg:linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%)
     两卡同源同色，几何也都是 180deg 纯纵向 ⇒ 不可能再不一致。
     ⚠ 为什么前四版都不对（真机像素实测，非计算值）：
       ① 方向：第 2 张卡 180deg 纯纵向；问候卡原用 155deg 斜向。
          卡片宽 710px、高约 100px，斜向渐变在纵向上的投影被压扁 →
          实测问候卡「顶 0.738 / 中 0.691 / 底 0.836」——
          中段反而比顶浅，根本读不出「上深下浅」。
       ② 深度：第 2 张卡顶 L 0.61~0.78；问候卡顶 0.63~0.85，普遍偏浅。
     改用 --kpi-home-* 后，问候卡的 **background-image 已与第 2 张卡逐字相同**。
     ⚠ 但仅此还不够 —— 见「第六版」：`.welcome::before` 的品牌色蒙版
       （rgba(--em-rgb,.13→.045)）会在相同底色上再压深 ≈0.15，
       必须同步降到 .03/.012 才能让两卡**真机观感**一致。
     文字对比（合成蒙版后）：8.63~14.55:1，全部远高于 4.5:1。

   ⚠⚠ 2026-09-21 二次修正（用户：「顶部从深到浅 我没感觉？ 加油卡片这里 加深也没感觉到？」）
     第一版做成了 **0% 纯白 → 100% 深**，两个致命问题：
       ① 顶部从纯白开始，**与页面白底完全融成一片**，所以"看不到顶部"；
       ② 155deg 下最深色落在**右下角**，而卡片文字/头像占满左上大半，
          最深处被挤在最不显眼的角落 —— 叠加后整体仍是"一片浅色"，自然"没感觉"。
     现改为**左上深 → 右下浅**（深色在起点，即视觉重心所在），并把色差拉大到
     "明显看得出"的程度（深端如 light #9ec4dd，与浅端 #f4f9fc 相差显著）。
     ⚠ 注意 155deg 是"左上→右下"，所以 0% 是左上角、100% 是右下角 —— 方向别写反。
   深色系 3 套（dark/ink/plum）的 --wel-bg **取各自原本 --card-grad2 的值**，
   视觉与改动前完全一致 —— 用户明确「深色系不用动」。
   ⚠ 配套改动：`.welcome p` 的正文色由 --muted 改为 --fg（深端 --muted 仅 2.11:1）。
   各浅色主题深端 / 文字对比（fg）：light 6.62 / moss 5.94 / dusk 4.58
     / sand 5.99 / mist 5.06 / sakura 5.42 —— 全部 ≥4.5:1。 */
/* ⚠⚠⚠ 2026-09-24 用户：「首页第一个卡片 我想做成这种两个叠加一点，上面显示标题，
   下面显示内容」—— 问候卡拆成「上=彩色标题面板 / 下=内容叠加卡」两层。
     · .welcome       退化为**透明容器**（纯 flex 纵向），不再承载任何视觉；
     · .welcome-top   承接**原 .welcome 的全部视觉**（卡底 / 描边 / 圆角 / 阴影 /
                      ::before 遮罩 / ::after 光斑），即"上面那块彩色面板"，
                      内部仍是 头像 + 问候语标题；
     · .welcome-panel 内容叠加卡（见下方规则）：负 margin 上移压住彩色面板底边。
   ⚠ 与第 2 张卡(KPI)的「深度对齐」逻辑（见上方第七/八版长注释）**一字未改**，
     只是整体从 .welcome 平移到 .welcome-top，两卡仍完全一样深。 */
/* 容器：--wel-overlap = 白色叠加卡上移量，约等于顶部彩面高度的 1/3（见下方两处同步引用）。
   定义在容器上，顶面板与叠加卡都是它的子节点，都能继承到。
   ⚠ 2026-09-24 用户：「人物图片和两个卡片同步向上移动 5px」→ margin-top 44 → 39px；
     随后「再整体向上移动 5px」→ 39 → 34px（累计上移 10px）。
     整块（上卡 + 叠加卡 + 照片）一起上移：照片是叠加卡的子节点（abs 锚卡顶），
     自然同步；上卡（「加油卡片」）内部几何完全不动，三者的相对关系保持原样。
   ⚠ 照片贴住下方叠加卡顶后，卡片整体离顶部导航留出间距（用户反馈「太靠上」）；
   顶内边距 32px：比之前再收，使问候语上移、叠加卡与头像随之上移一点，
   同时保持彩色顶卡顶边位置不变（「上面这张卡片不动」）。 */
/* ⚠ 2026-09-25 用户：「把人物图片 + 两个叠加卡片移动到顶部去固定住」→ 本块改为**吸顶**。
   实现要点（四处必须同时成立，漏一处就会出现内容从卡片里透出来 / 人头被顶栏吃掉）：
     ① position:sticky：滚动 .content（首页滚动容器）时，整块（彩面板 + 叠加卡 + 照片）
        钉在顶栏下方不动，今日待办等卡片从它下面滑过。z-index:5 —— 必须低于顶栏的 30
        （否则会盖住顶栏），且高于下方 .card-tint-sm>* 的 1（否则卡片会盖住本块）。
     ② --wel-sticky-top：吸顶停靠位。⚠ 实测（Chrome/WebView 同一内核）：停靠后的
        `.welcome` 顶边 = 内容区顶 + .content 的 padding-top + top ⇒ top 必须**减掉
        padding-top** 才能贴到顶栏下方。停靠位定在「照片头顶距顶栏 ~3px」，于是
        top = 照片探出量 + 3 − padding-top。两个输入量都随断点变，必须逐档给值：
          ≤420px   探出 4.8   pad 12 → top −4（停靠后照片头顶距顶栏 3.2）
          ≤600px   探出 12.8  pad 12 → top  4（3.8）
          601~859  探出 25.2  pad 14 → top 14（2.8）
          ≥860px   探出 25.2  pad 26 → top  2（2.8）
        ⚠ pad 的分档点是 860 不是 768：.content 顶部内边距 601~859 为 14px、≥860 才 26px。
        ⚠ top 若给 0 或正值不补偿 padding，整块会被顶到顶栏下方 15~30px 处，看着没贴顶；
          若给得太小（照片探出量 > 停靠余量），照片头会钻进顶栏（层级 30 > 本块 5）被遮住。
        改照片尺寸 / --wel-overlap / .content 内边距时这四档要一起复核。
     ③ ::before 不透明底衬：本块自身是透明的（彩面板带裁剪缺口、渐变半透明，照片四角
        透明），吸顶后内容会从缺口/透明处透出来。底衬用 --bg 铺满整块并向上多铺 30px
        （盖住照片探出部分，探出量最大 25.2px）、左右各外扩 40px（被 .content 的
        overflow-x:hidden 裁掉，等于通铺到屏幕两边），z-index:-1 落在面板与照片之下。
     ④ margin-top 34 → 14px：用户要「移动到顶部」，把静止时的留白一并收掉；
        须保证「静止位置 ≥ 吸顶位」（即 margin-top ≥ top，因为两者都叠加在
        .content 的 padding-top 上），否则静止时就会被顶下去、出现一段空白。
        四档 top 里最大的是 14px，margin-top 取 14px 恰好满足（≤420 档 top 为负，更宽松）。 */
.welcome{position:sticky;top:var(--wel-sticky-top);z-index:5;
  display:flex;flex-direction:column;--wel-overlap:35px;--wel-sticky-top:4px;margin-top:14px}
/* ═══ 首页：两张叠加卡当顶栏（2026-09-25）════
   用户：「把这个叠加卡片当顶栏，旧顶栏不要了，但背景渐变颜色保留」。
   做法：dashboard 由 JS 给 <body> 加 view-home 作用域类（见 app-shell.renderView）。
   · 旧 .topbar 收出文档流 → 变成 .main 顶部的一块背景渐变兜底层（标题在首页本就 display:none，
     只剩天光渐变），z-index 压在内容之下。
   · .content 升到 z-index 之上、顶距归零 → 两张叠加卡上移到屏幕最上，代替旧顶栏位置。
   · .welcome 改为相对定位，摆脱 sticky 对「上移量」的限制，卡顶即可贴顶。
   ⚠ 仅作用域在本页面；cases/clients/calendar 等仍用常规顶栏，不受影响。 */
body.view-home .main{position:relative}
body.view-home .topbar{position:absolute;top:0;left:0;right:0;bottom:auto;z-index:0;pointer-events:none}
body.view-home .content{position:relative;z-index:5;padding-top:env(safe-area-inset-top)}
body.view-home .welcome{position:relative;top:auto;margin-top:0}
.welcome::before{content:"";position:absolute;left:-40px;right:-40px;top:-30px;bottom:0;
  background:var(--bg);z-index:-1;pointer-events:none}
/* ⚠ 2026-09-24 用户：「这个行文字（问候语）向上移动到居中」→ 顶/底内边距**等量对调**
   （顶 32→12、底 overlap+2→overlap+22）：两者之和不变 ⇒ 卡片高度、可见彩带高度、
   叠加卡位置、照片位置全部不变，只是内容盒整体上移 20px，问候语随之精确上移 20px
   （实测桌面问候语中线 326.4→306.4，正好落到可见彩带 [卡顶 260, 叠加卡顶 352.8] 的正中 306.4）。
   随后用户：「这行文字往下移动一点」→ 在同一对参数上反向走 8px（顶 12→20、底 overlap+22→overlap+14），
   问候语从正中下移 8px（仍在彩带内、且离叠加卡顶 23px 以上，不会被压住）。
   ⚠ 唯一不变式：顶 + 底 = overlap + 34px（和为常数 ⇒ 卡片高度恒定）。
     两个值必须与下列四处**同步**，漏改会导致断点之间问候语高度不一致：
     本规则块、下方 .welcome-main 前的重复块（2500 附近）、≤859px 块、≤420px 块。
   ⚠ 底内边距仍远小于卡高，内容盒底仍比叠加卡顶高 6px，文字不会被叠加卡压住。 */
.welcome-top{background:var(--wel-macaron);
  -webkit-backdrop-filter:blur(10px) saturate(1.15);backdrop-filter:blur(10px) saturate(1.15);
  /* 缺口与四角圆角是两回事：保留左上缺口(spendClip)，仅把四角圆角收到与下方叠加卡一致的 ~20px
     （手机 #spendClip 按 ~388×239、桌面 #spendClipD 按 ~859×180 折算）。 */
  clip-path:url(#spendClip);
  filter:drop-shadow(0 14px 26px rgba(60,80,120,.40));
  padding:20px 14px calc(var(--wel-overlap) + 14px) 124px;display:flex;flex-direction:column;gap:4px;
  position:relative;overflow:visible}
/* ⚠⚠ 2026-09-21 用户：「加油，元气满满的一天 这个卡片 紫色的遮照能不能根据
   主题的颜色改变？」
   原来这两层遮照是**写死**的：
     ::before  rgba(139,92,246,.13) → rgba(124,58,237,.045)  紫罗兰
     ::after   rgba(76,107,158,.10)                            蓝
   结果 9 套主题共用同一层紫+蓝，暖沙/樱花这类暖色主题上会显得脏
   （紫是冷暖之间的"中间色"，压在暖底上最容易发浑）。
   改为跟随各自的品牌色 --em-rgb（每套主题已有的三元组变量）：
     ::before 用品牌色 13% → 4.5% 的对角渐变
     ::after  用品牌色 10% 的径向光斑
   透明度刻意与原值保持一致，这样「遮照强度」的观感不变，只换色相。 */
/* ⚠⚠⚠ 2026-09-21 第七版（最终版）—— 找出「颜色不对」的真正根源
   前六版一直在调「强度」，但真正的问题是 **用错了变量**：

     第 2 张卡 .kpi-merged.kpi-home:before 用的是 --tint-rgb（亮色系）
        light: --tint-rgb = 58,168,232   ← 亮蓝
     问候卡 .welcome::before 一直用的是 --em-rgb（品牌主色）
        light: --em-rgb   = 76,107,158   ← 暗蓝

   两套变量**色相接近但明度差异明显**，所以无论把 alpha 调到多少，
   两张卡都「看着不是一个颜色」—— 这正是用户说的「颜色不对」。

   ⇒ 修复：问候卡的 ::before **完全复用第 2 张卡的蒙版公式**（同一组变量、
     同一套双层结构），使两卡从「卡底 → 蒙版」逐层同源。公式抄自
     `.kpi-merged.kpi-home:before`（css 第 1317 行附近），删去 135deg
     --card-tint 那层（那是第 2 张卡特有的第二层叠加，问候卡不需要）。

   同时保留一点品牌色身份：在最外层再叠一条极轻的 --em-rgb 平铺（.02），
   色相上仍是「这张卡自己的主题色」，但**不参与纵向明度分布**，
   所以不会破坏与第 2 张卡的深度一致。

   ⚠ 验证方式（重要）：两卡 background-image 字符串相同 **不等于** 观感相同，
     必须比对**伪元素**。t115.mjs 正是逐层 dump 了 :before/:after 才定位到本问题。

   ⚠⚠ 深色系必须单独写一条（照抄第 2 张卡的 .theme-dim .kpi-merged.kpi-home:before）：
     原因同第 2 张卡那段长注释 —— 深色卡底 L≈0.028，而 --tint-rgb（light 的
     亮蓝 58,168,232，L≈0.36）叠上去是**往上提亮**，方向完全反了；
     实测暗色顶部会被抬成"一块亮斑"。所以深色系改用 --kpi-dark-rgb 压暗层
     （近黑，.30 → .14 → 0），配合卡底自身的上深下淡做出纵向走向。
   ⚠ 深色系不再叠 --em-rgb 那层点缀：暗底上 .02 的提亮同样会破坏纵向分布。

   ⚠⚠⚠ 2026-09-21 第八版（用户确认「完全一样深」）—— 补上第 2 张卡的第二层叠加
     用户明确要求两卡**完全一样深**。第 2 张卡比问候卡多的正是这条
     `linear-gradient(135deg,var(--card-tint-a),var(--card-tint-b))`
     （--card-tint-a alpha .30 / --card-tint-b alpha .16）。
     反解核算（6 套淡色主题，在 tint 纵向层之上再补一层 tint）：
       需要补的 alpha 一律 ≈ 0.228 ——
       正好等于第 2 张卡第二层的区间中点 (.30+.16)/2 = 0.23 ⇒ 模型吻合。
     故直接照搬该层。补后顶部合成色与第 2 张卡逐主题对齐（ΔL ≤ 0.005）。
     ⚠ 此前误判「补了会过头」：是当时的像素采样点落在文字上导致，
       并非公式错误。教训：采样异常时先怀疑采样，不要急着改 CSS。
   ⚠ 深色系不加这一层：--card-tint-a 在 dark 下 alpha 达 .44，且深底上
     --tint-rgb 是亮色，会再次「提亮」；深色系继续走 --kpi-dark-rgb 压暗层。 */
.welcome-top::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(135deg,rgba(255,255,255,.30) 0%,rgba(255,255,255,0) 46%)}
  /* 第六轮注：原 border-radius:inherit 已去 —— 形状全由 clip-path 裁定，
     这层白光斜射 inset:0 铺满后被同一 clip 裁成台阶形，天然贴合。 */
/* （原 .theme-dim 深色系压暗层已随「马卡龙磨砂底」改版删除：
   新 ::before 是全主题共用的白光斜射，深底主题上呈现为柔和高光，无需单独覆盖。） */
.welcome-top>*{position:relative;z-index:1}
/* （2026-09-24 原 ::after 右上白光斑已随「台阶凸块」改版删除：
   光斑位置 right:-46px top:-46px 恰是新凸块的位置，凸块自带高光描边，
   两者叠在一起会互相打架 —— 删光斑、高光职责并入凸块的描边与内衬。 */)
.welcome h2{margin:0;font-size:19px;
  /* 2026-09-25：让加油文字下移、贴紧下方卡片顶部（间隔 3px）。
     用 transform 仅视觉平移，不改变 flex 布局位置，上面的「首页总览」不受影响。 */
  transform:translateY(20px)}
/* ⚠⚠ 2026-09-21 正文色从 --muted 改为 --fg。
   原因：--wel-bg 改「左上深 → 右下浅」后，卡片**左上区域（正是文字所在处）**
   是全卡最深的位置。--muted 是给白底设计的中间灰，
   压在深端合成色上实测只有 **2.11:1**（远低于 4.5:1），文字会发花。
   --fg 在深端 6.62:1 / 中端 9.3:1 / 浅端 13.6:1，全段安全。
   问候卡本就是首页的强调卡，正文用主色（而非次要灰）在语义上也更合适。 */
.welcome p{margin:0;font-size:13px;color:var(--fg)}
/* 问候卡布局（2026-09-24 第六轮，配合 SVG 裁剪台阶轮廓）：头像已取消。
   · 人物照片在**左侧**（absolute 挂在叠加卡 .welcome-panel，见 .wel-photo 段），
     左内边距给照片让位：照片宽 ~108px + 左距 14px + 呼吸 16px ≈ 138px；
   · 顶内边距 44px ⚠⚠ 必须大于左段下沉裁剪线（0.14×卡高 ≈ 35px）——
     clip 裁掉裁剪线以上的一切，问候语起点低于它就会被切掉上半；
     主规则块（.welcome-top 首个定义）与本处两处 padding 顶值必须同步。
   · 右侧 20px 正常 —— 右段是满高区，文字可压其上。 */
.welcome-top{flex-direction:column;align-items:stretch;gap:4px;
  padding:20px 14px calc(var(--wel-overlap) + 14px) 124px}
/* .welcome-main：文字块。左内边距已由 .welcome-top 的 138px 留出，
   这里再补一层 padding-left，防止极窄屏 / 超长自定义问候语时
   文字回缩压到照片上（照片在左缺口处、宽约 90~108px）。
   padding-top 只作用于文字块内部，不影响叠加卡几何。 */
/* 问候语整体靠右：父级（column flex）用 align-items:flex-end 把 h2 推到右端，
   h2 内部 justify-content:flex-end（见 dashboard.js 内联样式）、文本 text-align:right。 */
.welcome-main{min-width:0;flex:1;display:flex;flex-direction:column;gap:4px;
  align-items:flex-end;text-align:right;padding-top:2px;
  /* 2026-09-25：人物图片、加油文字、在办案件卡三者作为前景组整体上移 20px，
     缺角面板(.welcome-top)不动。加油文字挂在本容器，用 transform 平移。 */
  transform:translateY(-20px)}
/* 「首页总览」标题（2026-09-25：从顶栏移入问候卡，置于问候语上方）。
   顶栏已只留一条渐变带，这里承接视图标题，右对齐与问候语一致。 */
.wel-title{font-size:14px;font-weight:600;color:var(--fg);margin-bottom:18px;line-height:1.3;text-align:right;
  /* 2026-09-25：单独抵消 .welcome-main 的前景组上移(-20px)，让「首页总览」不随之上移、
     停在加油文字正上方。与 .welcome-main 的 translateY(-20px) 配对。
     2026-09-25：同时向右方向左移 25px（translateX(-25px)）。
     2026-09-26：用户「首页总览 这行字 往上移动6px」→ translateY 14px → 8px
     （净位移 -20+8=-12px，比原先 -6px 再多上移 6px）。 */
  transform:translate(-56px,8px)}
/* ---- 内容叠加卡（2026-09-24 新增）----
   负 margin 上移 --wel-overlap（40px ≈ 顶部彩面高度的 1/3），
   与 .welcome-top 底部预留的 (--wel-overlap + 2px) 内边距**精确对应**：
   面板底部那段是空的，所以既"叠"上去、又不会压到头像或标题。
   两侧 margin 为 0 → 叠加卡与顶部彩面**同宽**（"一样大"）。
   ⚠ margin 的上移量与 padding 的预留量必须同步改（都引用 --wel-overlap）：
      改一处不改另一处，叠加就会开始吃内容或露出空隙。
   底色用主题 --card（light 纯白 / dark 深蓝灰 / 各主题各自的卡色），
   描边 --border、文字 --fg/--muted —— 不写死颜色，9 套主题天然协调。 */
/* 叠加卡（2026-09-24 三次改版）：
   ① 底色用「在办案件」卡同款渐变（--kpi-home-1/2/3），实现用户所说
      「合并，颜色用在办案件卡片的」；暗色系这三段本就是深色值，文字亮色，无需另配。
   ② 内部改为**上下两行**（用户口令「现在是展示两个，改成三个」「这两个放一行」）：
      · .wp-row-top   三个小格：今日待办 / 未来7天开庭 / 本周事项（一行三个）；
      · .kpi-merged.kpi-home.wp-row-kpi  两个大格：在办案件 / 标的合计（一行两个、
        各占一半）—— 整块复用原独立卡的 .kpi-home 系列（图标/emoji/数值/副标题/
        暗色适配/窄屏适配全部自动生效），只把「卡」退成「行」，见下方覆盖块。 */
/* 用户要求「上面卡片（加油卡片）不动，人物图片和下面卡片一起移动」→ 在原有上移量上再叠一个
   固定偏移量：本卡与照片当前位置 = 较基准位置上移 8px。照片（.wel-photo，bottom:calc(100% - 1px)）
   锚在本卡顶边，故随本卡整体移动，两者相对位置（+2px 压入）不变，白线（::before 的 1px 描边）
   也就不会受影响。
   ⚠ 注意：--wel-overlap 的加减不会移动本卡（上卡的 padding-bottom 同步引用它，两者抵消），
     所以要真正移动必须在这里直接叠一个固定偏移量；该量与移动距离同处修改。 */
.welcome-panel{position:relative;z-index:2;margin:calc(-1 * var(--wel-overlap) - 8px) 0 0;
  /* 2026-09-25：在办案件卡（含内部人物图）作为前景组整体上移 20px，缺角面板不动；
     后按需额外再上移（累计 -37 → -42 → -46 → -48px）等，全部记在同一行。
     2026-09-26：用户「人物图片、加油、在办案件所在卡片一起上移8px」→ -48 → -56px；
     照片锚在本卡顶边（bottom:calc(100% - 1px)），随本卡同步上移 8px，无需单独改。
     2026-09-26：用户「这三再往上1px，首页总览不动」→ -56 → -57px（wel-title 不随动）。 */
  transform:translateY(-57px);
  display:flex;flex-direction:column;gap:10px;
  padding:12px 8px 10px;border-radius:20px;
  background:none;border:1px solid transparent;box-shadow:none}
/* ⚠ 2026-09-24 卡面改由 ::before 承担（底色/描边/投影都搬到这里），层级 z-index:-1。
   原因：负层级子元素画在「父背景之后」而不是「之下」—— 要让 .wel-photo 真正被卡面裁掉，
   卡面本身必须是比照片更靠上的一层。见 .wel-photo 段的层叠说明。
   inset:-1px：绝对定位的包含块是 padding box，故外扩 1px 正好对齐 .welcome-panel 的边框盒，
   描边画在原来的位置；父级保留 1px 透明描边仅为不改变内部盒尺寸。
   指针事件关闭：该层纯装饰，避免挡住照片自身的点击（data-nav=settings）。 */
.welcome-panel::before{content:"";position:absolute;inset:-1px;z-index:-1;pointer-events:none;
  border-radius:20px;border:1px solid var(--border);
  background:linear-gradient(180deg,var(--kpi-home-1) 0%,var(--kpi-home-2) 46%,var(--kpi-home-3) 100%);
  box-shadow:0 16px 32px -14px rgba(23,31,49,.42)}
.wp-row-top{display:grid;grid-template-columns:repeat(3,1fr);gap:4px}
/* 「在办案件/标的合计」行：容器带 .kpi-merged.kpi-home 类以整套继承原样式，
   但作为嵌入行不再需要「卡」的外壳 —— 逐项退掉：
   卡底（浅色 --kpi-home 渐变 + 暗色回落两处）、通用描边/圆角/阴影/4px 内衬、
   ::before 紫色/暗色叠加层。两列布局由原 1501 行
   `.kpi-merged.kpi-home{grid-template-columns:repeat(2,1fr)}` 兜底，此处显式重申。
   ⚠ 特异性备忘：本块 (0,3,0)/(0,4,0)，且位于被压规则（1299~1470 行一带）之后 ——
     同权重靠「后写赢」、更高权重直接稳压，双保险。 */
.welcome-panel .kpi-merged.kpi-home{display:grid;grid-template-columns:repeat(2,1fr);gap:0;
  background:transparent;border:none;border-radius:0;box-shadow:none;padding:0;overflow:visible;
  /* 2026-09-26：用户「在办案件 标的合计 这行上移12px」→ 本行整行上移；
     折叠工具栏（.tb-tools）是行内第一个格 .kpi-col.has-tools 的 absolute 子元素
     （bottom 锚在格内），随本行 transform 同步上移 12px —— 无需单独改它的
     translateY(22px)，否则会多移 12px。 */
  transform:translateY(-12px)}
.welcome-panel .kpi-merged.kpi-home:before{content:none}
.theme-dim .welcome-panel .kpi-merged.kpi-home{background:transparent}
.theme-dim .welcome-panel .kpi-merged.kpi-home:before{content:none}
/* 折叠工具栏迁入「在办案件」格（2026-09-25）：绝对定位在该格左下角。
   ⚠ .kpi-merged.kpi-home 显式 overflow:visible（见上），不会被裁。
     同网格卡里其余格子不受影响 —— 只有第一个格带 .has-tools。 */
.welcome-panel .kpi-col.has-tools{position:relative}
.welcome-panel .tb-tools{position:absolute;left:2px;bottom:2px;z-index:4;gap:2px;transform:translateY(22px)}
.welcome-panel .tb-tools .icon-btn{width:30px;height:30px;border-color:transparent;background:transparent;box-shadow:none;color:var(--tb-icon)}
.welcome-panel .tb-tools .icon-btn:hover,.welcome-panel .tb-tools .icon-btn:active{background:transparent;color:var(--fg)}
.welcome-panel .tb-tools .icon-btn:focus,.welcome-panel .tb-tools .icon-btn:focus-visible{background:transparent;outline:none;box-shadow:none}
.welcome-panel .tb-tools .hamburger{background:transparent;border:none;box-shadow:none;outline:none}
.welcome-panel .tb-tools .hamburger svg{width:17px;height:17px}
.welcome-panel .tb-tools .tb-icons .icon-btn svg{width:18px;height:18px}
.wp-item{display:flex;flex-direction:row;align-items:baseline;justify-content:center;gap:3px;min-width:0;padding:0 2px}
.wp-lab{font-size:11px;color:var(--muted);line-height:1.3;text-align:center;
  white-space:nowrap;max-width:100%;overflow:hidden;text-overflow:ellipsis}
.wp-val{font-size:17px;font-weight:800;color:var(--fg);line-height:1.2;
  letter-spacing:-.3px;font-variant-numeric:tabular-nums}
.wp-unit{font-size:10.5px;font-weight:600;color:var(--muted);margin-left:2px;letter-spacing:0}
/* 「在办案件 / 标的合计」改为「图标 + 标签 + 数值 」同一行（2026-09-25 用户：
   下面数字不要另起一行，放同一行）。数值强制不换行并微缩字号，
   否则长数字（如 11106.90万）会在窄格里把单位挤到第二行。 */
.welcome-panel .kpi-home .val{white-space:nowrap;font-size:15px}
@media(max-width:420px){.welcome-panel .kpi-home .val{font-size:14px}}
/* ===== SVG 裁剪缺口卡 + 左侧照片（2026-09-24 第七轮 spendClip）=====
   演进留档：
   ④轮 独立凸块 .wel-bump        → 用户否：「是一个整体卡片，不是叫你再加一个」
   ⑤轮 ::after 同底色台阶伪元素  → 用户发来示例 HTML：用 SVG clipPath
       把整卡裁成「左矮右高」台阶（welStepClip）。
   ⑥轮 welStepClip 落地          → 照片挂外层 .welcome，底部贴叠加卡顶。
   本轮（第七轮）用户发来第二份示例 HTML（spendClip，「消费卡」缺口轮廓）
   要求整卡换成该形状，并把人物照片**放大、上移**，且底部「贴叠加的卡片顶、
   不是贴自己这张卡」。落地：
   · path 定义在 index.html #spendClip（objectBoundingBox 归一化，
     一张 path 自适应手机 ~388px 与桌面 ~900px 卡宽）；
   · .welcome-top 引用 clip-path:url(#spendClip)（见上方主规则块），
     border/圆角/盒阴影退役，换 filter:drop-shadow 跟随轮廓投影；
   · ⚠ 照片改挂**叠加卡 .welcome-panel**（而非外层 .welcome）：
     这样才能用 bottom:100% 精确对齐「叠加卡的顶边」——挂在 .welcome 上
     只能相对彩色面板定位，无法表达「贴叠加卡顶」这一语义。
     .welcome-panel 的 z-index:2 高于 .welcome-top 的层叠上下文，照片
     z-index:3 再叠其上，故完整可见、不被彩色面板裁切。
   · .wel-photo：透明人像抠图（assets/wel-photo.webp，300×400 竖构图 17KB，
     保留 alpha 通道）。完整展示、无描边、无底框；height 定尺寸 width:auto
     按原图比例缩放；矩形 box-shadow 会露馅（人像四周透明），换
     filter:drop-shadow —— 投影紧贴人形轮廓，人物像立在这张卡上；
     自身 data-nav="settings"，点图进设置。
   ⚠ 照片宽 = height × 0.75：窄屏 71→宽 53、默认 77→宽 58、桌面 97→宽 73，
     均落在左缺口内；对应左内边距 112 / 124 / 130px（见三处 padding 与注释）。 */
/* 人物照片（2026-09-24 晚 → spendClip 缺口轮廓 + 移挂叠加卡）：
   现挂在 .welcome-panel 上（见 dashboard.js），用 bottom 偏移对齐叠加卡（下方那张卡）的
   顶边 —— 即「贴叠加的卡片顶、不贴自己这张卡」（第七轮为 bottom:100%；现改为压进卡内
   2px，见下方 ⚠⚠ 段：素材是平切半身像，需藏在卡面背后）；
   照片整体探在彩色面板之上、头部探出卡框外，相对旧版放大并上移。
   比例 300×400（0.75）：默认高 77 → 宽约 58、窄屏 71 → 53、桌面 97 → 73，
   left 22~28px 落在左侧缺口处（整体右移一点），问候语已靠右对齐，不再依赖左内边距避让。 */
/* 人物图要真正落在叠加卡「下面层」（被卡面裁出轮廓），靠的不是负 z-index 本身：
   父级 .welcome-panel 由 z-index:2 形成层叠上下文，其绘制顺序是
   「父背景/描边(第1步) → 负层级子元素(第2步)」—— z-index:-1 仍画在卡面**之上**。
   故卡面已改由 .welcome-panel::before(z-index:-1) 承担，照片降到 z-index:-2，
   两者同处 panel 的层叠上下文，负值更小者先画 ⇒ 照片在卡面之下。
   ⚠ 照片以 .welcome-panel 为包含块（仍挂在 panel 上），故探出卡顶以上的部分
     显示在彩色面板之上（panel 整体 z-index:2 高于 .welcome-top），头部照旧探出卡框。 */
/* ⚠⚠ 2026-09-24 用户：「帮我修复人物图片与卡片的遮挡问题」。
   现象：人像下半身像被下方卡片齐平切断。实测根因**不是卡片遮挡**，而是：
   ① 素材 wel-photo.webp 是 300×400 的**半身像**（头到胸口，黑衣在图片底边被平切，
      素材最后一行仍有 244 个不透明像素）；
   ② 上一版 z-index:-1 并未把照片压到卡面之下（见上方层叠说明），
      于是这条平切边露在卡外、又恰好压在叠加卡顶边与本卡 1px 描边上。
   修法：照片底边**压进叠加卡内 1px**（用户先要 10px→2px，再定 1px：「压1px行不行？」）
   —— 平切边落到卡面背后，被卡自己的轮廓裁掉。
   注：CSS 的 1px 压入 = 相对叠加卡 padding-box 顶边下移 1px，实际被卡面（外框顶边）
   盖住的部分是 2px（含 1px 描边），而素材的平切边就在图片最后一行，故 1px 足够；
   可见的裁切线变成卡片轮廓（含 20px 圆角与描边），人像即「站在卡片后面探出身子」。
   同时因卡面（含描边＝那条白线）在 ::before 上、高于照片，白线也不会再被盖住。 */
/* ⚠⚠ 2026-09-24 用户：「点击头像以后，会出现这个东西」（附手机截图：深色圆角方块 +
   白色向下箭头）。排查结论：那不是本应用的元素 —— 实测为宿主注入的
   div.trae-image-download-btn（28×28、#222427、圆角 6px、position:fixed、z-index:89990、
   title="Download image"，挂在 body 上、应用代码里零匹配），它在**悬停/点击 <img>** 时显示。
   修法：头像不再用 <img> 渲染，改为「<div> + 背景图」—— 宿主识别不到图片元素，
   该浮层就不会再弹出。视觉不变（同一张图、同一尺寸、同一个 drop-shadow 跟轮廓投影）。
   ⚠ 因 div 没有内在宽高比，原来靠 width:auto 撑开的宽度现在必须显式给出：
     宽 = 高 × 0.75（素材 300×400），三处断点各写一次（见下方基础规则与两个媒体查询）。 */
/* 2026-09-26 用户：「人物图片缩小一点」→ 三档整体缩小约 10%（严格保持素材 3:4）：
   基础 96×72→86×64、≤420px 88×66→79×59、≥601px 120×90→108×81。
   底边锚定（bottom:calc(100% - 1px)）不变，故缩小后照片底边仍压在卡面内 2px、
   left 也不变，只往上收、不往里挪。
   2026-09-26 用户：「人物图再缩小」→ 三档再缩约 10%：
   基础 86×64→77×58、≤420px 79×59→71×53、≥601px 108×81→97×73。 */
.wel-photo{position:absolute;left:34px;bottom:calc(100% - 1px);height:77px;width:58px;z-index:-2;
  /* 自定义头像优先（--wel-photo-img 由 js/app-shell.js 的 getAvatar() 写入 :root），
     未设置时退回默认素材。center/contain = 完整显示整张图，不裁剪、不加框。 */
  background:var(--wel-photo-img, url(../assets/wel-photo.webp)) center/contain no-repeat;
  filter:drop-shadow(0 10px 16px rgba(23,49,77,.38));
  cursor:pointer;user-select:none;-webkit-user-select:none;
  -webkit-tap-highlight-color:transparent;transition:transform .18s ease}
.wel-photo:active{transform:scale(.96)}
/* 窄屏：照片微缩、左内边距跟着收。裁剪形状不用改 —— path 是归一化
   坐标，自动适配任意卡宽；缺口在左上，照片落在缺口处即可。
   bottom:calc(100% - 1px) 在各断点均沿用（见上方基础规则），此处只调高度/左距。 */
@media(max-width:420px){
  .wel-photo{left:32px;height:71px;width:53px}
  /* 吸顶停靠位随「照片探出量 / 内容区左内边距」分档（见 .welcome 主规则注释②）。
     本档照片最小、探出 4.8px，故取负值抵掉 .content 的 12px 顶部内边距。 */
  .welcome{--wel-sticky-top:-4px}
  /* 选择器带 .welcome 提权重（0,2,0）：859px 块在源码更后方同为简写，
     不提权会被那条简写整体覆盖。左内边距 126 = 照片宽 ~105 + 左距 10 + 呼吸。 */
  .welcome .welcome-top{padding:20px 14px calc(var(--wel-overlap) + 14px) 112px}
}

/* ===== 2026-09-24 上边卡片 · 软萌马卡龙磨砂底（用户口令原话：=====
   「上边卡片做成软萌渐变磨砂底色+圆润不规则边缘设计，整体色调梦幻柔和，
    卡片为带轻微弧度的不规则圆角矩形，搭配半透明渐变背景(浅粉、浅黄、浅蓝、
    浅绿等马卡龙色系渐变，这些渐变根据主题来)，视觉轻盈且有氛围感。」）
   实现：--wel-macaron 按 9 套主题各给一组**半透明**马卡龙渐变，
   配合 .welcome-top 的 backdrop-filter 磨砂 + 不规则圆角（border-radius 用
   「斜杠双值」写法，四角椭圆率各不相同 → 带轻微弧度的不规则圆角矩形）。
   半透明（alpha .5~.66）是给 backdrop-filter 留出可糊的内容 —— 全实色就磨砂不出来了。
   ⚠ 深色三系（dark/ink/plum）给的是**低明度马卡龙**，同一组变量、色相随主题，
     梦幻感保留，但不会在深底上突然亮成一块。 */
:root{--wel-macaron:linear-gradient(135deg,rgba(186,216,245,.55),rgba(255,206,226,.50) 55%,rgba(206,236,214,.52))}
body.dark{--wel-macaron:linear-gradient(135deg,rgba(58,78,128,.62),rgba(108,88,150,.55) 55%,rgba(78,108,142,.55))}
body.moss{--wel-macaron:linear-gradient(135deg,rgba(198,230,188,.62),rgba(222,238,202,.55) 55%,rgba(200,226,210,.55))}
body.dusk{--wel-macaron:linear-gradient(135deg,rgba(224,208,240,.62),rgba(236,220,246,.55) 55%,rgba(210,216,240,.55))}
body.sand{--wel-macaron:linear-gradient(135deg,rgba(250,224,188,.66),rgba(255,236,202,.60) 55%,rgba(250,220,200,.60))}
body.ink{--wel-macaron:linear-gradient(135deg,rgba(72,82,96,.62),rgba(92,102,116,.55) 55%,rgba(80,90,106,.55))}
body.sakura{--wel-macaron:linear-gradient(135deg,rgba(250,214,230,.62),rgba(255,226,240,.55) 55%,rgba(246,210,226,.55))}
body.plum{--wel-macaron:linear-gradient(135deg,rgba(82,62,122,.62),rgba(112,82,152,.55) 55%,rgba(92,72,132,.55))}
body.mist{--wel-macaron:linear-gradient(135deg,rgba(210,220,230,.62),rgba(222,230,238,.55) 55%,rgba(210,218,228,.55))}
/* 「加油，努力办案！」彩色副句已于本轮取消（用户要求去掉蓝/绿色字），
   对应 .wel-cheer 元素与样式一并移除。问候语 h2 仍由 hmGreet 渲染。 */
/* 宽屏（桌面/平板）：3/5 的大叠加是手机竖版的比例，宽屏下叠加卡变矮，
   大 overlap 会把上边卡片整块吃掉 —— 这里收成「适度叠一点」。
   （叠加卡内部两行的列数手机/宽屏一致：上 3 下 2，不再单独改列。） */
@media(min-width:601px){
  /* 吸顶停靠位（见 .welcome 主规则注释②）：本档照片变高、探出 25.2px，pad 14px。 */
  .welcome{--wel-overlap:-8px;--wel-sticky-top:14px}
  /* 桌面卡更矮（overlap 64），照片仍贴住叠加卡顶（现压入 1px），
     此处放大并略右移，头部探出卡框更明显（占位上方）。 */
  .wel-photo{height:97px;width:73px;left:38px}
}
/* 宽屏（≥860）：卡更宽，照片也更大，左内边距收到 162px 让照片与文字都舒展。
   ⚠ 本块同时覆盖 --wel-sticky-top，且必须放在 .welcome 主规则**之后**：
     同为 .welcome 单类选择器，靠「后写赢」才盖得住主规则里的基础值（4px）。
     ⚠ 断点用 860（而不是 .content 那条 768 的写法）：实测 .content 的**顶部**内边距
       在 601~859 是 14px、≥860 才是 26px（后面的 ≤859 块把 768 那条简写顶掉了）。
       本档 pad 26、照片探出 25.2 ⇒ top 取 2px；601~859 档见上方 601 块（top 14）。 */
@media(min-width:860px){
  .welcome{--wel-sticky-top:2px}
  .welcome-top{padding-left:130px;clip-path:url(#spendClipD)}
}

/* 列表项 */
.li{display:flex;align-items:flex-start;gap:12px;padding:14px;border:1px solid var(--border);border-radius:16px;background:var(--card-grad);transition:.15s;box-shadow:var(--shadow-soft);-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;user-select:none;-webkit-user-select:none}
/* 日程列表文本省略（用户 2026-09-19：「案件名字太长或内容太长超出卡片的做省略显示」）。
   ⚠ 只加省略，不改排版：flex-wrap、字号、间距一律不动 ——
     上一版误把 flex-wrap 去掉重排了布局，已被用户否掉（“你怎么把排版全改了”）。

   位置演进：
     第一轮「不要省略这么前」→ 给文本加 flex:1 1 auto（原为 basis:auto，短文本只占内容宽）。
     第二轮「还没到右边边框」→ 实测发现真正的病根不在文本自身，而在**时间列**（见下）。
   ⚠ flex:1 1 auto 与 flex-wrap:wrap 的配合：flex-basis:auto 保证短文本不被拉伸留白，
     flex-grow:1 让它占满剩余空间，flex-shrink:1 允许超长时收缩。
     不要写成 flex:1（= 1 1 0%），那是 basis:0，短文本也会被撑满整行、
     把后面的徽标顶上下一行，又变成改排版。 */
.ev-ell{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 地点是独立一行（不在 flex 行里），直接占满容器宽度即可 */
.sub.ev-ell{flex:none;min-width:0;max-width:none;display:block;width:100%}
/* 案件名同样是独立一行（第三轮从标题行挪出，见 js/calendar.js 注释）——
   与地点行同样处理：display:block 铺满整宽，超长时才在卡片内边框处省略。
   ⚠ 不能只写 .ev-ell：.ev-ell 的 flex:1 1 auto 是给 flex 子项用的，
     在 block 上下文里 flex 属性无效、宽度退化为内容宽，又会提前省略。 */
.ev-case{flex:none;min-width:0;max-width:none;display:block;width:100%}

/* 日程卡时间列脱离 flex 行宽计算（用户第二轮：「省略也不要省略这么前啊，还没到右边边框」）。
   实测（Chrome CDP，430px 视口）：
     卡片外框 14→486，内容区右 471，左块（案件名+地点）却只到 393 —— 右边空着 80px。
   根因：时间列（「今天 · 09:30」）是行内兄弟节点、flex:0 0 auto 占 70px + gap 8px，
     直接把这 80px 从**整个左块**（含地点行）的可分配宽度里扣掉了。
     而时间列高度只占一行，地点行右侧那 80px 纯属白扔 —— 地点一长就提前省略。
   修法：把时间列改为 .ev-time 绝对定位到卡片右上角，退出 flex 行宽计算 →
     左块（.ev-body）拿到 442px 全宽，案件名与地点都排到卡片内边框才省略。
   防重叠：标题行（.ev-head）右侧留白 ≈ 时间列宽度 + 间距，避免长标题/长案件名
     换行后钻到时间文字下面。（#2 那版留 76px，实测临界只余 6px，故放宽到 80px。）
   实测结果：地点行右边界 393 → 471（= 内容区右边界，全宽用满）；
     案件名行因其与时间列同处一个水平带，仍在时间列左侧安全线处省略（几何上必须如此）。 */
.ev-time{position:absolute;top:12px;right:14px;font-size:11px;font-weight:600;white-space:nowrap;line-height:20px;z-index:2;font-variant-numeric:tabular-nums;font-feature-settings:'tnum' 1}
.ev-card{position:relative}
.ev-head{padding-right:80px}
@media(max-width:420px){.ev-head{padding-right:74px}}
.li:active{background:var(--card-grad)!important}
.li:hover{background:var(--card-grad);transform:translateY(-1px);box-shadow:0 8px 20px -10px rgba(30,36,51,.12)}
@media(hover:none),(pointer:coarse){.li:hover{background:var(--card-grad)!important;transform:none}}
.li .grow{flex:1;min-width:0}
.li .ttl{font-size:14px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}
.li .sub{font-size:12px;color:var(--muted);margin-top:3px;max-width:100%;box-sizing:border-box}
.li-actions{display:flex;gap:2px;align-items:center;flex-shrink:0}
/* 首页列表：扁平化 + 虚线分隔（仅工作台） */
.dash-list .li{background:none;border:none;border-radius:0;box-shadow:none;padding:10px 0;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;touch-action:manipulation}
/* 首页条目任何交互态均透明，禁止按/长按时出现渐变与位移 */
.dash-list .li:hover,.dash-list .li:active,.dash-list .li:focus{background:none!important;transform:none;box-shadow:none;border-color:transparent}
.dash-list .li+.li{border-top:1px dashed var(--muted-2)}

/* 案件卡片 */
.case-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:14px}
@media(min-width:768px){.case-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:1280px){.case-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
/* 案件卡片（用户 2026-09-17 指定颜色参照案件统计卡）。
   原来是 --card-grad2 的「上白下蓝」四段渐变，改成纯 --card + :before 蓝叠加，
   与 .card-tint 同构；但这里是**成排出现**的卡片，用中档浓度而非大卡档。
   ⚠ 不能用 overflow:hidden 裁 :before：卡片 hover 有 translateY(-2px)，
   裁掉会让位移的边看起来被切。:before 自带 --radius 圆角即可。 */
.case-card{background:var(--card);position:relative;border:1px solid var(--border);border-radius:var(--radius);padding:18px;box-shadow:var(--shadow-soft);min-width:0;cursor:pointer;transition:.18s;overflow:visible}
.case-card::before{content:"";position:absolute;inset:0;pointer-events:none;border-radius:inherit;
  background:linear-gradient(135deg,var(--card-tint-a-mid),var(--card-tint-b-mid))}
.case-card>*{position:relative;z-index:1}
.case-card:hover{border-color:color-mix(in srgb,var(--emerald) 40%,var(--border));box-shadow:0 12px 28px -12px rgba(30,36,51,.18);transform:translateY(-2px)}
.case-card .meta{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}
.case-card .name{font-size:15px;font-weight:600;line-height:1.35;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:40px}
.case-card .rows{font-size:12px;color:var(--muted);display:flex;flex-direction:column;gap:4px;margin-top:10px}
.case-card .rows .r{display:flex;justify-content:space-between;gap:8px;min-width:0}
.case-card .rows .r b{min-width:0}
.case-card .rows .r b{font-weight:600;color:var(--fg)}
.case-card .foot{display:flex;justify-content:space-between;align-items:center;margin-top:10px;padding-top:10px;border-top:1px solid var(--border);font-size:12px;color:var(--muted)}
.case-card .fee{font-weight:700;color:var(--fg)}

/* 客户 */
/* 客户行 —— **已恢复为通用 --card-grad 渐变**（用户 2026-09-17：「通讯管理页
   卡片 还是恢复以前的 渐变」）。
   历史：
     · ceaac3c 之前：background:var(--card-grad)，即 --card-grad2 的
       155° 上白下蓝渐变（#ffffff → #f3f8fb → #d9ecf5 → #c9e3f0）。
     · ceaac3c 把它改成「纯 --card 平色 + :before 135° 蓝叠加（中档 .30/.16）」，
       为了跟案件统计卡统一成一个蓝。
     · 现在按用户要求**退回**前者。实拍对照过两版：
       旧版是"左上偏白、右下偏蓝"的通透斜渐变；
       统一蓝底版是"整块平蓝 + 一道更深的斜向压色"，整体更实、更重。
   恢复要点：
     1. background 回到 var(--card-grad)；暗色下该变量自动取暗色那套
        （#19233a → #1a2c44 → #15374f），**不需要**再写 .theme-dim 覆盖。
     2. :before 整条**删掉** —— 它承载的蓝叠加就是被用户否掉的那部分。
        留着会让"退回渐变"只做了一半（渐变被平色叠加盖住，看起来还是老样子）。
     3. .client-row>*{z-index:1} 一并删掉：它原本是给 :before 垫层的，
        没有 :before 就没必要，留着会凭空建立层叠上下文。
     4. position/overflow 保留（overflow:visible 是刻意的，见下），
        但 position:relative 在去掉 :before 后已无绝对定位子元素可依托，
        仍保留无副作用，就不动它，减少本次改动的面。
   ⚠ 这条只动 .client-row。同批被 ceaac3c 推广的 .case-card / .doc-row /
     .folder-card / .calendar-card 等**都不动** —— 用户只说了通讯管理页。 */
.client-row{display:flex;align-items:center;gap:14px;padding:10px 17px;border:1px solid var(--border);border-radius:var(--radius);background:var(--card);box-shadow:var(--shadow-soft);cursor:pointer;transition:.18s;position:relative;overflow:visible}
.client-row::before{content:"";position:absolute;inset:0;pointer-events:none;border-radius:inherit;background:linear-gradient(135deg,var(--card-tint-a-mid),var(--card-tint-b-mid))}
.client-row>*{position:relative;z-index:1}
.client-row:hover{box-shadow:0 12px 28px -12px rgba(30,36,51,.18);transform:translateY(-2px);border-color:color-mix(in srgb,var(--emerald) 40%,var(--border))}
.client-row .cr-av{flex-shrink:0}
.client-row .cr-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}
.client-row .cr-name{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}
.client-row .cr-meta{display:flex;flex-direction:column;gap:2px;min-width:0}
.client-row .meta-row{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--muted);min-width:0}
/* 客户详情里的「关联案件」条目（用户 2026-09-17 要求可点击）。
   底色/hover 都在这里定义，JS 里只留 data-case 与 id，不再内联写样式。
   hover 用 --bg：它比卡片底略深一档，在浅色与暗色下都能看出"这一条被指向了"，
   不用再写 .theme-dim 覆盖（--bg 自带两套值）。
   :active 轻微下沉，给触摸端一个即时反馈 —— 手机上 hover 不可靠，
   真正让人知道"点到了"的是 :active。 */
.cl-case-item:hover{background:var(--bg);border-color:color-mix(in srgb,var(--emerald) 40%,var(--border))}
.cl-case-item:hover .cl-case-arrow{color:var(--emerald)}
.cl-case-item:active{transform:scale(.99)}
.ic-sm{width:14px;height:14px;flex-shrink:0}
.avatar{width:36px;height:36px;border-radius:11px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.avatar svg{width:18px;height:18px}
.av-male{background:#9BC9C4;color:#155C58} .av-female{background:#EABFC3;color:#B0556A} .av-org{background:#A8BEDF;color:#33557F} .av-inst{background:#F1DFB5;color:#7A5C1E}

/* 类型统计卡 */
.type-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px}
@media(min-width:768px){.type-grid{grid-template-columns:repeat(6,minmax(0,1fr))}}
.type-card{background:transparent;border:none;border-radius:14px;padding:7px 6px;display:flex;flex-direction:column;align-items:center;text-align:center;gap:4px;min-width:0;cursor:pointer;transition:.18s}
.type-card:hover{background:var(--bg);transform:translateY(-2px)}
.type-card.active{background:var(--bg);box-shadow:inset 0 0 0 1px var(--emerald)}
.type-card .ico{width:33px;height:33px;border-radius:10px;display:flex;align-items:center;justify-content:center;box-shadow:inset 0 0 0 1px rgba(255,255,255,.3),0 5px 12px -7px rgba(20,24,51,.5)}
.type-card .ico svg{width:17px;height:17px}
/* ⚠ .ico 上这条 box-shadow 只服务于「有底色的图标方块」（那是初版给 SVG 图标
   配淡彩底时加的）。.doc-glyph 分支已把它清成 none，见下方规则 —— 改这条时
   务必确认 .doc-glyph 的覆盖仍然在后面，否则六个 emoji 屁股后面会重新出现
   一圈浅浅的阴影，看着像没删干净的框。 */
/* 文档中心类型图标 —— 2026-09-18 用户指定：原生 emoji、**不要方框**。
   演进史（别退回去）：
     ① 最早走 .ico.bg-*-soft（状态徽标的淡彩底），六格灰扑扑一个调子；
     ② 中途换成一整套自绘 SVG + 独立明亮配色（字段 bg/fg/bd + --ic-bd），
        技术上对齐了，但**不是用户要的东西** —— 用户给的是 📑📄📝🧾📃🗒️；
     ③ 改为直接渲染 emoji 文本，但仍裹在一个 33px 浅底圆角方块里；
     ④ 现在：**连方块也去掉**，emoji 裸展示。用户原话「图标不需要正方圆角框框」。
   ⚠ emoji 是**彩色字形**，CSS 的 `color` 对它无效（改不动字色），所以这里
     一律不写 background/color/border —— 写了也只是在 emoji 屁股后面垫色块。
   ⚠ 必须把 .type-card .ico 自带的 box-shadow（inset 描边 + 外投影）清成 none：
     否则方块虽然透明了，那道投影还留在原地，看起来像"框没删干净"。
   ⚠ 字号 26px：用户 2026-09-18 要求「图标可以加大一点吗？就最上面卡片里加大」。
     这个尺寸是算过的，不是随手加大 —— 卡片 padding 8px、六格 gap 4px，
     320px 窄屏下每格可用宽度约 (320-24-10×2)/3 ≈ 92px。26px 的 emoji 在
     92px 里占比 28%，六格并排时既明显变大、又不会两两相碰。
     试过 30px：320px 下相邻 emoji 边缘只剩 8px 空隙，视觉上已经"粘"在一起了。
     ⚠ line-height 保持 1：emoji 字形本身有上下留白，line-height 大于 1 会把
     类型卡的垂直间距撑开，六格看起来变高变散。 */
.type-card .ico.doc-glyph{width:auto;height:auto;background:none;border:none;border-radius:0;box-shadow:none;font-size:26px;line-height:1;font-family:"Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji",sans-serif}
/* 类型名与份数：2026-09-18 用户澄清「标题名字 综合 诉状 证据 等还是要加粗的呀，
   颜色还是黑色，只是后面N份不加粗，用灰色」。
   ⚠ 上一版我把整串「综合5份」统一成了 12px/400，把类型名也一起弄淡了 ——
     这是误读。正确的做法是**拆成两个 span**，各自一套样式：
       .tn 类型名 → 12px / 700 / var(--fg)（黑，加粗）
       .tc2 份数  → 12px / 400 / var(--muted)（灰，不加粗）
   之所以要拆 span 而不是靠 :first-letter 或别的技巧：中文没有词边界，
   「综合」与「5份」在同一个文本节点里，CSS 无法只给后半段上色。
   <span> 是这里唯一可靠的切法。 */
.type-card .tc{display:flex;align-items:baseline;justify-content:center;gap:0;min-width:0}
.type-card .n{font-size:12px;font-weight:400;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.type-card .tn{font-weight:700;color:var(--fg)}
.type-card .tc2{font-weight:400;color:var(--muted)}

.cal-title{font-size:17px;font-weight:700;display:flex;align-items:center;gap:8px;color:var(--fg)}
.cal-grid{display:flex;flex-direction:column;gap:0;width:100%}
.cal-week{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:1px;position:relative}
.cal-dow-row{margin-bottom:0}
.cal-dow{text-align:center;font-size:12px;font-weight:500;color:var(--muted);padding:6px 0}
.cal-cell{min-height:40px;height:40px;display:flex;flex-direction:column;align-items:center;justify-content:center;border-radius:50%;background:transparent;border:1px solid transparent;transition:.15s;position:relative;z-index:2;cursor:pointer;color:var(--fg)}
/* hover 灰底仅保留给支持悬停的设备（桌面），触屏设备点击后不会残留灰色圆 */
@media (hover:hover){.cal-cell:hover{background:rgba(0,0,0,.04)}}
.cal-cell.out{color:var(--muted-2);background:transparent;border-color:transparent}
.cal-cell.out .dnum{opacity:.45}
.cal-cell .dnum{font-size:16px;font-weight:500;width:36px;height:36px;display:flex;align-items:center;justify-content:center;border-radius:50%;line-height:1}
.cal-cell .dot{position:absolute;bottom:4px;left:50%;transform:translateX(-50%);width:4px;height:4px;border-radius:50%;background:var(--rose);opacity:.5}
.cal-cell.sel{background:transparent !important;z-index:5}
.cal-cell.sel:hover{background:transparent !important}
.cal-cell.sel .dnum{background:transparent !important;color:var(--fg);position:relative;z-index:4;width:44px}
.cal-cell.sel .dot{opacity:.5;z-index:6}
.cal-cell.today.sel .dnum{background:transparent !important;color:var(--emerald) !important;font-weight:700}
.cal-cell.today .dnum{background:transparent;color:var(--emerald);font-weight:700}
.cal-cell:active{transform:scale(.95)}
/* 法定节假日角标（用户 2026-09-23：「日历可以增加 休 和班 吗」，指定蓝色休、红色班）
   迭代记录：
     · 一轮「放到日期数字右上角 小小的显示，还有颜色问题」
       → 字号 9→8px、去掉实心色块、定位从格子角落改到相对日期
     · 二轮「离数字太远了」
       → 根因：.dnum 是 display:flex 居中容器，角标作为 flex 子项被排在
         数字右侧；且 right 的固定偏移在 46px 窄格里显得更远。
       → 改为 position:absolute + transform 脱流定位。
     · 三轮「单日期的时候可以。双数字日期就会重叠一点」
       → 根因：定位锚点是 36px 圆圈的几何中心，双位数（如 20）比单位数
         宽约 9px、右半边多占 4~5px，固定偏移就压上去了。
       → 对策：渲染时用 <i> 包住数字本体，角标改为相对 **<i> 的右边缘**
         定位（right 负值），单/双位数自动适应，永不重叠。
   定位链条：.cal-cell > .dnum（圆圈，position:relative）
                      > i（数字本体，position:relative）> .cal-mark
   ⚠ 角标必须是 i 的**子节点**。曾误放成兄弟节点，最近定位祖先是 .dnum
     圆圈（36px），导致角标位置与数字宽度无关 —— 单位数和双位数下
     "距格子右边缘"实测都是 5.7px，双位数自然压到数字上。 */
.cal-cell .dnum{position:relative}
.cal-cell .dnum>i{font-style:normal;display:inline-block;position:relative}
.cal-cell .cal-mark{position:absolute;top:-4px;right:-8px;font-size:8px;line-height:1;font-weight:600;padding:0;border-radius:0;pointer-events:none;z-index:3;letter-spacing:0}
.cal-mark--rest{color:#4a9fd8}
.cal-mark--work{color:#e06b7d}
/* 深底主题下用更亮的色，保证在暗背景上可读 */
body.theme-dim .cal-mark--rest{color:#8ccdf5}
body.theme-dim .cal-mark--work{color:#ff8199}
.cal-actions{display:flex;gap:8px}
/* ===== 月历卡片 ===== */
/* 月历卡（用户 2026-09-17 指定颜色参照案件统计卡）：同 .card-tint 的做法，
   蓝叠加在 .card-tint::before 里，这里只把原来的 --card-grad 底色去掉。
   ⚠ 卡片必须 overflow:visible —— 选中日期的气泡是 absolute 定位、会伸出卡片。 */
.calendar-card{border:1px solid var(--border);border-radius:var(--radius);padding:18px;margin-bottom:18px;box-shadow:var(--shadow-soft);position:relative;overflow:visible}
/* 2026-09-24 历次改色（白字压深底 → 淡灰黑字 → #c9c9cb → 白内框 → 最初）后，
   用户要求"向上回档"到「气泡五项优化」那条口令执行完、且尚未做"文字看不清改色"
   及之后所有改色的状态：保留 长标题时间可见 / 圆圈缩小慢变黑+√擦画 / 点击不闪 /
   去掉内层框框，但撤销后续所有配色实验，气泡底色恢复为最初的选中高亮色 --cal-sel
   （即 09-24 白字轮之前、套白色内框卡片时期的原始底色，按主题自适应，凸帽同色无缝）。
   ⚠ 变量必须定义在 .calendar-card 上：凸帽 .cal-cap 与气泡 .cal-bubble 是
   兄弟节点，两者必须同色无缝（凸帽是从选中格长到气泡的"脖子"），
   谁单独改色都会把接缝暴露出来。选中格 .cal-cell.sel 本身是 transparent
   （高亮观感全靠凸帽顶帽），故格子无需同步。 */
.calendar-card{--bub-bg:var(--cal-sel)}
.cal-nav{display:flex;align-items:center;justify-content:space-between;margin-bottom:18px}
.cal-nav .cal-title{margin:0}
.cal-nav button{width:34px;height:34px;border-radius:10px;border:1px solid var(--border);background:var(--card);display:inline-flex;align-items:center;justify-content:center;color:var(--fg);font-size:18px}
.cal-nav button:hover{background:var(--bg)}
/* 选中日期气泡卡片 - 数字区与展开区一体化
   ⚠⚠ 2026-09-21 用户反馈「日历 点击日期后下拉的凸帽和气泡框等也看不清楚」。
   这一段的设计意图是：**日期格 + 凸帽 + 气泡要拼成一个连通的「凸」字形**，
   三者同色、无缝，靠「形状」本身表达"这个日期被展开了"。
   所以修法必须围绕「让这个形状看得出来」，而不是给它描一圈边 ——
   描边会把本该无形的接缝画成一道线，反而毁掉一体化。
   真正的病灶是**填色选错**：--cal-sel 原本是「日历选中格」的柔光底色，
   取值极浅且**与卡片底同色系**，压在卡片上几乎融成一片。
   正确修法：把 --cal-sel 当成**实心前景块**来配色 —— 它要明显区别于
   卡片底。另外清掉 .cal-bubble-empty 的硬编码 #475569。

   ⚠⚠⚠ 2026-09-21 二次修正（用户反馈「最后两个模式里 日历这里还是不行」）
   ------------------------------------------------------------------
   第一次修正**漏算了一个关键变量**，导致深底主题实际没修好：
     日历卡片（.calendar-card）的真实渲染底色 **不是 --card**，
     而是 --card 再叠一层 --card-tint-a（浅底 .30 / 深底 .42）的**同色透明层**。
     这层叠加把卡片底整体**推向品牌色并提亮**。
   第一次我用纯 --card 估算，得出深底主题分离度 1.99/1.96「达标」；
   用真实叠加底复算，玄墨只有 **1.04:1**、绛紫 **1.16:1** ——
     色块与背景几乎完全同色，等于没画。这正是「最后两个模式不行」的根因。
   （浅底主题第一次的取值恰好还行 1.53~1.75，所以问题只在深底暴露。）
   ⚠ 教训：算日历对比度必须用「--card ∘ --card-tint-a」的**合成色**，不能只用 --card。

   本次**只动最后两个主题（玄墨 ink / 绛紫 plum）**，其余 7 套一律保持原值不动
   —— 用户明确：「日历 我只说 动最后两个主题就行，其他的本来很好的」。
   我一度把 9 套全改成品牌色分档，浅底主题因此从「浅色高亮」变成「实心深色块」、
   视觉明显变重，被判为过度修改，故**已回退浅底 6 套 + dark**（教训：改前先确认范围）。

   最终取值 —— 新旧混合，只有 ink/plum 是新的：
     保持原值（用户认可，勿动）：
       light #93aed2 / dark #456692 / moss #A5BA8C / dusk #B8A5CB
       sand #C6A97E / mist #A8B2BD / sakura #D8A8BD
     本次修正（仅此两个）：
       ink  #AAB6C6  ← 品牌色**亮档 --emerald-l**（原 #4C5460，分离度只有 1.04）
       plum #D4BCF8  ← 品牌色**亮档 --emerald-l**（原 #514570，分离度只有 1.16）
   这两个深底主题改用**亮块**的理由：深底上亮块天然分离，
   且与各自的深底品牌色**色相统一、只差明度**（ink 银灰 / plum 兰紫），观感属于同一族。
   ⚠ 为什么 dark 不照此办理：其卡片底本身就是中蓝（合成后 #344665），
     与品牌蓝同色系，取亮档也只有 2.10:1，色相无法拉开；
     但 dark 原值 #456692 实测 1.61、观感尚可，且用户未提，故**不动**。

   ⚠ 以下「正文不直接压在 --cal-sel 上」的前提已被 2026-09-24 需求推翻：
     先是去掉内层白卡片，随后用户又要求「文字改成白色」—— 白字需要深底，
     气泡底色改为 50% 主色 + 50% 深藏蓝（--bub-bg，定义在 .calendar-card 上），
     文字对比度按"白字压 --bub-bg"重算 —— 见下方 .cal-bubble 区块头部的实测数据。 */
.cal-bubble{grid-column:1/-1;background:var(--bub-bg);border-radius:9px;padding:18px 12px 14px;margin:1px -16px 8px;position:relative;z-index:1;box-shadow:0 10px 26px -12px rgba(23,31,49,.16)}
.cal-bubble.cal-bubble--anim{animation:calExpand .28s cubic-bezier(.22,1,.36,1)}
@keyframes calExpand{from{opacity:0;transform:translateY(-8px) scale(.985)}to{opacity:1;transform:none}}
/* 选中态"凸"字帽：独立元素，相对所在周行定位，切换日期时从旧位置平滑滑到新位置。
   ⚠ 它与 .cal-bubble 必须**同色且无缝**：形状由 clip-path 生成
     （见 calendar.js 的 connectorClipPath），底部刻意延伸进气泡内 18px，
     与气泡重叠所以看不出接缝。因此这里不能加描边、不能加阴影 ——
     任何"给轮廓上色"的做法都会把这条本该隐形的接缝暴露出来。 */
.cal-bubble::before{content:none}
.cal-cap{position:absolute;left:0;top:0;width:62px;height:58px;background:var(--bub-bg);clip-path:path('M0,0');pointer-events:none;z-index:2;opacity:0}
.cal-cell.sel .dnum{z-index:4}

.cal-bubble-box{background:transparent;border:none;border-radius:0;overflow:visible;margin-top:10px;margin-bottom:10px}
/* ===== 回档到「气泡五项优化」口令状态（仅执行口令前四句，不做去框/改色）=====
   气泡壳底色 = 最初的选中高亮色 --cal-sel（见 .calendar-card 上的 --bub-bg，随主题自适应）；
   内层白卡片**保留**（用户纠正："去掉框框和背景颜色"这部分也不要执行）。
   只保留口令里的四项功能：长标题时间可见 / 圆圈缩小+慢变黑+√擦画 / 点击不闪。
   分隔线：日期头下 **虚线**、事项之间 **虚线**、新建按钮上方 **实线**。
   徽标/时间保持红色、时间无「·」点。 */
.cal-bubble{--bub-fg:#1a1a1a;--bub-muted:#666;--bub-line:rgba(0,0,0,.08)}
.cal-bubble-empty{display:flex;align-items:center;justify-content:center;gap:8px;color:var(--bub-muted);font-size:14px;padding:20px 0}
.cal-bubble-empty svg{width:18px;height:18px;flex-shrink:0}
/* 「新建日程」按钮（最初版）：白卡内**无底色**，深字 + 加号，上方一条实线分隔。 */
.cal-bubble-add{margin:0;display:flex;align-items:center;justify-content:center;gap:6px;width:100%;padding:13px 14px;border:none;border-top:1px solid var(--bub-line);background:transparent;color:var(--bub-fg);font-size:14px;font-weight:500;border-radius:0;cursor:pointer;transition:background .15s ease}
.cal-bubble-add:active{background:rgba(0,0,0,.04)}
/* 内层白卡片保留（用户纠正：回档到「气泡五项优化」口令时，
   "去掉框框和背景颜色"这部分也不要执行 —— 内层框框与背景色照旧保留）。
   白底 + 圆角 + 阴影，承载 日期头 + 事项 + 新建按钮；卡片内文字覆写为深字。 */
.cal-bubble-list{display:flex;flex-direction:column;gap:0;padding:6px;background:#fff;border:1px solid rgba(255,255,255,.14);border-radius:14px;box-shadow:0 8px 22px -10px rgba(0,0,0,.35);overflow:hidden;--bub-fg:#1a1a1a;--bub-muted:#666;--bub-line:rgba(0,0,0,.08)}
.cal-bubble-item{display:flex;flex-direction:column;gap:8px;padding:14px;cursor:pointer;transition:opacity .15s ease;border-top:1px dashed var(--bub-line)}
.cal-bubble-item:first-child{border-top:none}
.cal-bubble-item:active{opacity:.7}
.cal-bubble-when{display:flex;align-items:center;gap:8px;font-size:15px;color:var(--bub-muted);padding:13px 14px 11px;border-bottom:1px dashed var(--bub-line)}
.cal-bubble-when .cal-bubble-day{font-weight:700;color:var(--bub-fg)}
.cal-bubble-week{color:var(--bub-muted)}
/* 「日程」徽标：用户 2026-09-24 点名改回原样 —— rose 红字 + 红色 12% 底 */
.cal-bubble-tag{font-size:11px;font-weight:700;color:var(--rose);background:rgba(240,97,126,.12);padding:2px 7px;border-radius:20px;line-height:1.4}
.cal-bubble-row{display:flex;align-items:flex-start;gap:12px}
/* 勾选圆圈：22→18px（用户「左边圆圈可以缩小一点」）。点击热区用 ::after
   外扩到 28px（手法与案件详情 .evdot::after 一致）：视觉变小，点击不吃力。
   变黑节奏 .15s→.35s（用户「点击的时候，圆圈缓慢变黑」）。
   白色内框版：圆圈为深色描边（未办结）/ 深色实心（办结），勾用 **白色 #fff**
   压在深色实心上（与卡片内深字方案一致，勿再用 --bub-bg）。 */
.cal-bubble-check{position:relative;width:18px;height:18px;border-radius:50%;border:2px solid var(--bub-fg);display:flex;align-items:center;justify-content:center;flex-shrink:0;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color .35s ease,border-color .35s ease}
.cal-bubble-check::after{content:"";position:absolute;inset:-5px;border-radius:50%}
.cal-bubble-check svg{width:11px;height:11px;stroke-width:2.5;color:#fff;display:none}
.cal-bubble-check.done{background:var(--bub-fg);border-color:var(--bub-fg)}
.cal-bubble-check.done svg{display:block}
/* 勾「缓慢出现」：描边擦画（dasharray 24 ≥ M20 6 9 17 l-5-5 路径实长 22.6）。
   ⚠ 只挂 .just-done —— 该类由 JS 仅在「用户点出来的完成态」添加；
     初始渲染 / 翻日期重建气泡时，已完成项不会每次都重播一遍画线。 */
.cal-bubble-check.just-done svg path{stroke-dasharray:24;stroke-dashoffset:24;animation:calCheckDraw .4s ease-out forwards}
@keyframes calCheckDraw{to{stroke-dashoffset:0}}
/* 标题行（2026-09-24 重构）：时间移出 .cal-bubble-ttl 成为兄弟节点 ——
   ① 删除线只挂在标题自身上，时间天然不会被划到（比上一版 inline-block
     断线的手法更干净，也顺带修掉了那版「长标题时时间被整体挤出容器」的
     既有问题：flex 行 + flex-shrink:0，标题截断省略、时间始终可见）。
   ② done 态由 JS 同步切在 .cal-bubble-head 上。
   ③ 时间颜色：用户 2026-09-24 点名「改回原来的红色」，且不再随 done 变灰。 */
.cal-bubble-head{display:flex;align-items:baseline;gap:6px;min-width:0}
.cal-bubble-ttl{flex:1;min-width:0;font-size:15px;font-weight:600;color:var(--bub-fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cal-bubble-ttl.done{text-decoration:line-through;color:var(--bub-muted)}
.cal-bubble-time-inline{flex-shrink:0;font-weight:600;color:var(--rose);font-size:13px;font-variant-numeric:tabular-nums;font-feature-settings:'tnum' 1}
.cal-bubble-body{flex:1;min-width:0}
.cal-bubble-meta{font-size:12.5px;color:var(--bub-muted);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@keyframes fadeDayList{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.ad-num{width:46px;height:46px;border-radius:14px;background:var(--card);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:800;color:var(--fg);flex-shrink:0}
/* ===== 文档正文阅读器（AI 生成案例正文） ===== */
.doc-reader{max-height:64vh;overflow:auto}
.doc-article{padding:12px 16px 18px;line-height:1.85;font-size:14px;color:var(--fg)}
.da-h{font-size:17px;font-weight:700;margin:4px 0 10px;color:var(--fg);line-height:1.4}
.da-sub{font-size:14px;font-weight:700;margin:16px 0 6px;color:var(--fg)}
.da-p{margin:0 0 11px;white-space:pre-wrap;word-break:break-word}
@media(max-width:859px){
  .cal-actions{width:100%}
  .cal-actions .btn{width:auto;flex:1}
  .cal-cell{aspect-ratio:auto;height:auto;min-height:42px}
  .cal-cell .dnum{font-size:15px}
  .ad-num{width:50px;height:50px;font-size:22px}
}

@media(min-width:768px){.doc-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:1280px){.doc-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}

/* 文档列表：文件管理器卡片行（参考 iOS 文件列表排版） */
.doc-list{display:flex;flex-direction:column;gap:10px}
/* 文档条目（用户 2026-09-17 指定颜色参照案件统计卡）。
   原来是 --doc-tint(#c9e3f0) 按 --tint-pct 与白底混出的青蓝渐变，
   改成与其余卡片同一套蓝：纯 --card 打底 + :before 蓝叠加（中档浓度）。
   ⚠ 原来 hover 是换 background 为 --doc-tint-base(#ffffff)，
   现在底色由 :before 承载，hover 改提亮 :before 所在的整块（用 box-shadow
   内描边表达选中感），不要再写 background —— 写了也看不见，
   实底会被上面那层 :before 盖住。 */
.doc-row{display:flex;align-items:center;gap:14px;background:var(--card);border:1px solid var(--border);border-radius:16px;padding:12px 14px;cursor:pointer;transition:.15s;box-shadow:var(--shadow-soft);min-width:0;position:relative;overflow:visible}
.doc-row::before{content:"";position:absolute;inset:0;pointer-events:none;border-radius:inherit;
  background:linear-gradient(135deg,var(--card-tint-a-mid),var(--card-tint-b-mid))}
.doc-row>*{position:relative;z-index:1}
.doc-row:hover{box-shadow:0 10px 24px -12px rgba(30,36,51,.14),inset 0 0 0 1px rgba(58,168,232,.28)}
.doc-row:active{transform:scale(.995)}
.doc-badge{width:36px;height:36px;border-radius:11px;display:flex;align-items:center;justify-content:center;flex-shrink:0;border:none;box-shadow:none}
/* 文件行的类型图标 —— 2026-09-18 用户要求「上传好的文件 前面图标也更换一下对应的」。
   原来是 36px 圆角色块 + 按类型配色的 SVG 图标（`doc-badge` 内联 background/color）。
   现在同类型卡口径统一成 emoji，方框也一并去掉：
     · background/color 不再内联（emoji 是彩色字形，染色无效）；
     · 尺寸收到 24px 宽（emoji 字面宽度比同字号汉字窄，给 36 会空出一片）；
     · 用 flex 居中，行高固定，保证六个 emoji 竖向对齐成一条线。
   ⚠ 别把 width 设成 auto：emoji 在不同系统字面宽度不一样（Apple 20px /
     Noto 21px / Windows Segoe 22px），auto 会让每行图标左边缘参差不齐。 */
.doc-badge{width:26px;font-size:21px;line-height:1;font-family:"Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji",sans-serif}
.doc-badge svg{width:18px;height:18px;color:inherit}
/* 案件详情（cd-modal）里文件行的类型图标 —— docRowHTML 用的是 .doc-glyph-row。
   与 .doc-badge 同一套口径，只是行更矮（40px 上下），字号收到 19px。 */
.doc-glyph-row{width:26px;font-size:19px;line-height:1;text-align:center;flex-shrink:0;font-family:"Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji",sans-serif}
/* 预览弹窗顶部说明条：默认隐藏（内联 display:none），
   仅当 PDF 降级为浏览器内嵌显示等场景由 JS 显示出来。 */
.prev-note{padding:8px 14px;font-size:12px;color:var(--muted);background:var(--bg-soft);border-bottom:1px solid var(--border);line-height:1.5}
/* ===== PDF 站内阅读器（PDF.js 渲染到 canvas + 翻页条）=====
   .pdfv 撑满预览框；滚动区用浅灰底托住"纸面"白 canvas；
   底部翻页条常驻可见。canvas 物理像素由 JS 按 DPR 设置，
   这里只负责把它按 100% 宽展示。 */
.pdfv{display:flex;flex-direction:column;height:62vh}
.pdfv-scroll{flex:1;overflow:auto;-webkit-overflow-scrolling:touch;background:color-mix(in srgb,var(--fg) 7%,var(--bg));display:flex;justify-content:center;align-items:flex-start;padding:10px 8px}
.pdfv-scroll canvas{display:block;background:#fff;border-radius:3px;box-shadow:0 3px 14px rgba(15,21,36,.22)}
.pdfv-bar{display:flex;align-items:center;justify-content:center;gap:14px;padding:9px 12px;border-top:1px solid var(--border);background:var(--card);flex-shrink:0}
.pdfv-btn{padding:7px 16px;border:1px solid var(--border-stronger);border-radius:10px;background:var(--card);color:var(--fg);font-size:13px;font-weight:600;cursor:pointer;transition:transform .12s ease;-webkit-tap-highlight-color:transparent}
.pdfv-btn:active{transform:scale(.96)}
.pdfv-btn:disabled{opacity:.35;pointer-events:none}
.pdfv-num{font-size:12.5px;font-weight:600;color:var(--muted);font-variant-numeric:tabular-nums;min-width:62px;text-align:center}
.pdfv-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;height:62vh;color:var(--muted);font-size:13px}
.pdfv-spin{width:26px;height:26px;border-radius:50%;border:3px solid var(--border);border-top-color:var(--emerald);animation:pdfvspin .9s linear infinite;display:block}
@keyframes pdfvspin{to{transform:rotate(360deg)}}
.doc-row .grow{flex:1;min-width:0}
.doc-row .name{font-size:14px;font-weight:600;color:var(--fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3}
.doc-row .sub{font-size:12px;color:var(--muted);margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.doc-row-act{display:flex;align-items:center;gap:10px;flex-shrink:0;margin-left:2px}
/* ---- 文档页：案件文件夹 ---- */
.folder-grid{display:flex;flex-direction:column;gap:10px}
/* 文件夹卡同样改成统一蓝底（与 doc-row 一致，避免同页两套蓝）。
   :active 原本是重复 background（视觉无变化），现在底色在 :before 上，
   :active 改成整块轻微下沉即可，不要再动 background。 */
.folder-card{background:var(--card);border:none;border-radius:14px;padding:10px 12px;display:flex;flex-direction:row;align-items:center;gap:12px;cursor:pointer;transition:.15s;box-shadow:var(--shadow-soft);-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;position:relative;overflow:visible}
.folder-card::before{content:"";position:absolute;inset:0;pointer-events:none;border-radius:inherit;
  background:linear-gradient(135deg,var(--card-tint-a-mid),var(--card-tint-b-mid))}
.folder-card>*{position:relative;z-index:1}
.folder-card:active{transform:scale(.995)}
.folder-card:hover{transform:translateY(-1px);box-shadow:0 10px 22px -12px rgba(30,36,51,.2)}
.pager{display:flex;align-items:center;justify-content:center;gap:6px;flex-wrap:wrap;margin-top:14px}
.pg{border:1px solid var(--border);background:var(--card-grad);color:var(--fg);border-radius:10px;min-width:34px;height:34px;padding:0 10px;font-size:13px;cursor:pointer;transition:.15s;-webkit-tap-highlight-color:transparent}
.pg:hover:not(:disabled){border-color:var(--emerald);color:var(--emerald)}
.pg.on{background:var(--emerald);border-color:var(--emerald);color:var(--on-emerald);font-weight:700}
.pg:disabled{opacity:.4;cursor:default}
.pg-edge{font-weight:600}
.pg-dots{color:var(--muted);padding:0 3px;align-self:center}
.folder-ic{width:28px;height:28px;flex-shrink:0;object-fit:contain;display:block}
.folder-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;text-align:left}
.folder-name{font-size:13.5px;font-weight:700;color:var(--fg);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3}
.folder-sub{font-size:11px;color:var(--muted);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.doc-back{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;flex-shrink:0;border:none;background:none;padding:0;color:var(--muted);border-radius:10px;cursor:pointer;transition:.15s;margin-left:14px;position:relative;z-index:5}
.doc-back:hover{background:rgba(38,56,92,.07)}
body.theme-dim .doc-back:hover{background:rgba(255,255,255,.09)}
.doc-back svg{width:26px;height:26px}
.doc-back img{width:26px;height:26px;display:block;object-fit:contain}
.folder-head{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.folder-head .btn{white-space:nowrap;flex-shrink:0}
.folder-head .btn svg{width:14px;height:14px;flex-shrink:0;display:inline-block;vertical-align:middle}
.folder-head .btn{display:inline-flex;align-items:center}
.folder-title{font-size:16px;font-weight:700;color:var(--fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media(max-width:600px){.doc-type-grid{grid-template-columns:repeat(3,1fr)}}
@media(max-width:600px){.doc-row{padding:11px 13px}.doc-badge svg{width:17px;height:17px}}

/* ===== 弹窗 ===== */
.overlay{position:fixed;inset:0;background:rgba(23,31,49,.42);backdrop-filter:blur(6px);z-index:100;display:flex;align-items:center;justify-content:center;padding:18px;overflow-y:auto}
@media(max-width:600px){.overlay{padding:0}}
.modal{background:var(--card);border:1px solid var(--border);border-radius:24px;width:100%;max-width:560px;margin:auto;box-shadow:0 24px 70px -18px rgba(15,21,36,.45);max-height:92vh;display:flex;flex-direction:column;overflow:hidden;animation:pop .2s ease}
@keyframes pop{from{opacity:0;transform:translateY(12px) scale(.98)}to{opacity:1;transform:none}}
@media(max-width:600px){.modal{border-radius:20px 20px 0 0;max-width:100%;margin-top:auto}}
.modal-head{padding:18px 20px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;flex-shrink:0}
.modal-head .mt{font-size:17px;font-weight:700;display:flex;align-items:center;gap:8px;overflow:hidden}
.modal-head .mt .sub{font-size:12px;font-weight:400;color:var(--muted)}
/* 表单自动暂存恢复条（2026-09-25 新增，逻辑在 js/modal.js 顶部注释）。
   位置：由 openModal 插在 .modal-head 之后，因此它是 .modal 这个
   flex 纵向列的第 2 个子项 —— **必须 flex-shrink:0**，否则弹窗内容一多
   它会被压扁（.modal 是 overflow:hidden，压扁后文字会直接被裁掉）。
   配色沿用页面主蓝（同 --card-tint 的色相），一眼能看出是提示条而不是
   正文；不用红/黄是因为它表达的是"帮你留了一手"，不是错误或警告。 */
.draft-bar{display:flex;align-items:center;gap:8px;flex-shrink:0;padding:9px 16px;font-size:12.5px;line-height:1.3;
  color:var(--em-text-hi);background:rgba(58,168,232,.14);border-bottom:1px solid var(--border)}
.draft-bar>span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.draft-bar .btn{padding:3px 10px;font-size:12px;flex-shrink:0}
.modal-body{padding:18px 20px;overflow-y:auto;flex:1;min-height:0}
.modal-body>*{flex-shrink:0}
.modal-foot{padding:14px 20px;border-top:1px solid var(--border);display:flex;justify-content:flex-end;gap:10px;flex-shrink:0}
.form-grid{display:grid;grid-template-columns:1fr;gap:14px}
@media(min-width:300px){.form-grid.md2{grid-template-columns:1fr 1fr}}
.form-grid .col2{grid-column:1/-1}
@media(min-width:300px){.form-grid.md2.md3col{grid-template-columns:repeat(3,1fr)}}
.form-grid .col23{grid-column:span 2}
.form-grid .col13{grid-column:span 1}
.form-grid.cf2{grid-template-columns:1fr 1fr;gap:12px}
.field-err{color:var(--rose);font-size:12px;padding:8px 10px;border:1px solid rgba(240,97,126,.3);background:rgba(240,97,126,.06);border-radius:10px}
#ck-fields{align-content:start;align-items:start}
.close-x{width:34px;height:34px;border-radius:10px;border:1px solid var(--border);background:var(--card);display:flex;align-items:center;justify-content:center;color:var(--muted);font-size:18px}
.close-x:hover{color:var(--fg)}

/* 登录 */
.login-wrap{display:flex;align-items:center;justify-content:center;min-height:100vh;min-height:100dvh;padding:20px;background:linear-gradient(135deg,rgba(58,168,232,.10),rgba(76,107,158,.10))}
.login-card{background:var(--card);border:1px solid var(--border);border-radius:26px;padding:32px;width:100%;max-width:380px;box-shadow:0 24px 70px -20px rgba(15,21,36,.35)}
.login-card .logo-big{width:56px;height:56px;border-radius:18px;background:linear-gradient(135deg,var(--emerald-l),var(--emerald-d));display:flex;align-items:center;justify-content:center;color:var(--on-emerald);margin-bottom:18px;box-shadow:0 8px 20px -6px rgba(var(--em-rgb),.5)}
.login-card h1{font-size:21px;margin:0 0 4px}
.login-card .hint{font-size:12px;color:var(--muted);margin-bottom:20px}
/* 登录/注册 tab */
.auth-tabs{display:flex;background:var(--card-2);border:1px solid var(--border);border-radius:12px;padding:4px;margin-bottom:16px}
.auth-tabs .at-tab{flex:1;background:none;border:0;border-radius:9px;padding:8px 0;font-size:14px;font-weight:600;color:var(--muted);cursor:pointer;transition:all .18s ease}
.auth-tabs .at-tab.active{background:linear-gradient(135deg,var(--emerald-l),var(--emerald-d));color:var(--on-emerald);box-shadow:0 4px 12px -4px rgba(var(--em-rgb),.5)}

/* toast */
#toasts{position:fixed;bottom:80px;left:50%;transform:translateX(-50%);z-index:300;display:flex;flex-direction:column;gap:8px;align-items:center}
.toast{background:var(--fg);color:var(--bg);padding:10px 18px;border-radius:12px;font-size:13px;box-shadow:0 8px 24px rgba(0,0,0,.25);animation:pop .2s ease}

/* 时间线 */
.timeline{position:relative;margin-left:8px;padding-left:22px;border-left:2px solid var(--border)}
.preview-box{border:1px solid var(--border);border-radius:12px;overflow:auto;max-height:62vh;background:var(--card-2)}

/* ===== 移动端适配（断点与底部导航一致：<860px 为移动布局） ===== */
.toolbar{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.toolbar .tb-spacer{flex:1}
.toolbar .doc-tools{display:flex;gap:8px;align-items:center;flex:1;min-width:0}
.toolbar .doc-tools .search-wrap{flex:1;min-width:0}
.toolbar .doc-tools .btn{white-space:nowrap}
.chip-row{display:flex;gap:6px;flex-wrap:wrap}
/* 通讯管理的类型切换行 —— 规则已上移到 .seg 那一块（2026-09-17 三处统一），
   这里不再重复定义 .cl-filter-bar，避免同名规则分散两处、
   以后只改一处导致另一处静默覆盖。 */
@media(min-width:980px){.cal-grid-wrap{grid-template-columns:minmax(0,1.6fr) minmax(0,1fr)}.time-grid{grid-template-columns:1fr 1fr}}

/* 平板 / 手机：隐藏桌面侧栏，改由底部导航接管 */
@media(max-width:859px){
  .sidebar{display:none!important}
  .topbar{padding:calc(66px + env(safe-area-inset-top)) 16px 0}
  .topbar .title{font-size:17px}
  .topbar .icons{gap:2px}
  .content{padding:14px 14px calc(112px + env(safe-area-inset-bottom));overscroll-behavior-y:contain;-webkit-overflow-scrolling:touch}
  .mobile-nav button{padding:0}
    /* 触控目标放大到易点尺寸 */
  .icon-btn{width:42px;height:42px}
  .btn-icon{width:38px;height:38px}
  .chip{padding:6px 11px;font-size:12.5px}
  /* 工具栏窄屏竖向堆叠，控件全宽 */
  .toolbar{flex-direction:column;align-items:stretch;gap:10px}
  .toolbar .tb-spacer{display:none}
  .toolbar > .btn{width:100%}
  .toolbar .doc-tools{flex-direction:row}
  .chip-row{width:100%}
  .tb-actions{width:100%}
  /* 弹窗底部按钮（关闭/删除/编辑）强制同一行、等宽并排，不换行堆叠 */
  .modal-foot{flex-direction:row;flex-wrap:nowrap;padding:12px 14px;gap:8px}
  .modal-foot .btn{flex:1;min-width:0;width:auto}
  /* 卡片 / 列表内边距收紧 */
  .li{padding:12px}
  .li-actions{gap:4px}
  .card-head{padding:13px 14px}
  .case-card{padding:14px}
  .client-row{padding:9px 14px;gap:12px}
  .type-grid{gap:4px}
  .grid-2,.grid-1-1{gap:12px}
  /* 底部预留量 = 叠加卡的 --wel-overlap + 2px 余边（2026-09-24 起「贴紧版」：
     不再额外垫一层基础内边距 —— 叠加卡上沿直接贴住内容下沿。改 overlap 时此处自动同步）。
     左内边距 138px = 给左侧人物照片（宽 ~108 + 左距 14 + 呼吸）让位；
     顶内边距 44px ⚠ 必须大于左段下沉裁剪线（≈0.14×卡高），
     三处 padding（主规则 / 本块 / 420 块）顶值必须同步，漏改文字被裁。 */
  .welcome-top{padding:20px 14px calc(var(--wel-overlap) + 14px) 124px}
}
/* 小屏（手机）微调 */
@media(max-width:600px){
  .topbar .title{font-size:17px}
  .content{padding:12px 12px calc(118px + env(safe-area-inset-bottom))}
  .login-card{padding:24px 20px}
  .modal-head{padding:16px}
  .modal-body{padding:16px}
  /* 案件详情内「工伤赔偿表格」窄屏适配（2026-09-20 第 5 版）。
     ⚠ 教训一：上一版单独写的 `padding-right:4px !important` 被这里的
       `td{padding:5px 6px !important}` 覆盖（同权重、靠后者胜），所以「没生效」。
     ⚠ 教训二：靠收 padding 来「省空间」治不了「金额被吞」—— 根因是金额列没有确定宽度。
       现在金额列用 width 硬约束（见文件上方 .wi-tbl-amt），这里只按屏宽**逐级收紧**它，
       并同步收紧内边距；宽度永远 ≥ 最长金额所需，绝不裁字。 */
  .modal .wi-tbl-scroll td{padding:5px 7px !important}
  .modal .wi-tbl-scroll .wi-tbl-amt,
  .modal .wi-tbl-scroll .wi-cn-amt{width:126px;padding-left:2px !important;padding-right:7px !important}
  .modal .wi-tbl-scroll td.wi-cn-amt{font-size:10px !important;letter-spacing:-.2px}
  .modal .wi-tbl-scroll .wi-total-num{font-size:13px}
  .modal-foot{padding:14px}
  .cal-dow{font-size:11px;padding:4px 0}
  .cal-cell .dnum{font-size:13px}
  .case-card .name{font-size:14px}
  .welcome h2{font-size:17px}
  .card-head .h{font-size:14px}
  .type-card{padding:6px 4px}
  .preview-box{max-height:64vh}
}

/* ===== 全局搜索 ===== */
.gs-hint,.gs-empty{color:var(--muted);font-size:13px;padding:20px 6px;text-align:center}
.gs-sec{margin-bottom:14px}
.gs-sec-h{display:flex;align-items:center;gap:7px;font-size:12px;font-weight:700;color:var(--muted);margin:6px 2px 8px}
.gs-sec-h svg{width:15px;height:15px}
.gs-n{background:var(--bg);border-radius:999px;padding:1px 7px;font-size:11px;font-weight:600}
.gs-item{padding:10px 12px;border:1px solid var(--border);border-radius:12px;background:var(--card);margin-bottom:8px;cursor:pointer;transition:.15s}
.gs-item:hover{background:var(--bg);border-color:color-mix(in srgb,var(--emerald) 40%,var(--border))}
.gs-ttl{font-size:14px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gs-sub{font-size:12px;color:var(--muted);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ===== 交互打磨 ===== */
.empty{display:flex;flex-direction:column;align-items:center;gap:8px}
.empty:before{content:"";width:46px;height:46px;border-radius:14px;background:var(--bg);border:1px dashed var(--muted-2)}
.empty.no-ico{align-items:center}
.empty.no-ico:before{display:none}
:focus-visible{outline:2px solid var(--emerald);outline-offset:2px}
@media (prefers-reduced-motion: reduce){*{animation:none!important;transition:none!important}}

/* ============================================================
   案件时间线 · 圆点即完成开关（2026-09-21 二次改版）
   ------------------------------------------------------------
   改动背景：
     第 1 版把圆点放大到 20px 并改为「转绿 + 打勾」，用户反馈两点：
       ① 圆点仍显示不全（放大后超出时间线列宽被裁）；
       ② 不希望变颜色，只要打勾，且勾要"缓慢打上"。
     故本次：
       · 圆点缩小到 16px，列宽同步 16px —— 不再溢出，彻底根治裁切；
       · 保留原类型色（不再转绿），勾号用 SVG 描边动画缓慢绘制。

   设计要点：
     1) 尺寸 16px（用户要求缩小）；列宽 .ev-tl 同步 16px，二者必须一致；
     2) 未完成态 = 事项类型色实心圆（背景色由 JS 内联 style 给出）；
     3) 已完成态 = 颜色不变，圆内 SVG 对勾以 stroke-dashoffset
        从 1 → 0 缓慢"写"出来（.34s，ease-out），勾是画上去而不是蹦出来；
     4) box-shadow 0 0 0 3px var(--card) 做「挖空」描边，
        让圆点与时间线竖线之间有一圈卡片底色；
     5) 触控热区用 ::after 向外扩（视觉 16px，实际可点区域约 32px）。

   ⚠ 勾号用内联 SVG + CSS 描边动画，而不是文字「✓」：
     文字对勾无法做"逐段绘制"，只能整体出现或淡入，做不出书写感。
     SVG 路径长度经 getTotalLength 实测约 13.05，取 14 留余量。
     路径：M4 8.6 L6.9 11.4 L12.2 5.6（在 16×16 视口内）

   ⚠ 列宽 .ev-tl 同时写在 js/cases.js 的内联 style 上（16px），
     两处必须一致；改这里也要同步改那边，否则会再次溢出被裁。

   ⚠ 背景色永远由 JS 内联 style 控制（保持类型色），
     因此这里绝不写 .evdot 的 background —— 一旦写死，
     会压过内联类型色，或在未完成态误显示。
   ============================================================ */
.evdot{position:relative;width:16px;height:16px;border-radius:50%;border:none;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  cursor:pointer;flex-shrink:0;outline:none;z-index:1;
  -webkit-tap-highlight-color:transparent;user-select:none;
  box-shadow:0 0 0 3px var(--card);
  transition:transform .12s ease,box-shadow .12s ease}
/* 触控热区外扩：视觉 16px，可点区域外扩到约 32px（不影响布局与视觉尺寸） */
.evdot::after{content:"";position:absolute;inset:-8px;border-radius:50%}
.evdot:focus{outline:none}
/* ⚠ 2026-09-22：原先 hover 用 transform:scale(1.1) 放大做反馈，但圆点放大后
   会超出 .ev-tl 列的 16px 宽度；而列/祖先容器带 overflow-y:auto 时，
   CSS 规范会把另一个方向的 overflow-x:visible 强制按 auto 计算 ——
   于是放大溢出的左侧被打横裁掉，看起来像"圆点缺了一块"。
   故取消放大；按下反馈改用 scale(.92)（缩小，永不溢出）。 */
.evdot:hover{transform:none}
.evdot:active{transform:scale(.92)}
/* 勾号容器：定尺寸并锁定在圆心，避免影响 16px 圆形布局 */
.evdot svg{display:block;width:12px;height:12px;pointer-events:none}
/* 勾的笔画：白线，圆形端帽更像手写 */
.evdot svg path{fill:none;stroke:#fff;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round}
/* 已完成：颜色不变，只让勾"缓慢打上"。
   dasharray/offset 用 14（略大于实测路径长 13.05），保证起笔前完全不可见。
   注意：未勾选时 offset=14（整条隐藏），勾选后 offset=0（完整画出）。 */
.evdot:not(.on) svg path{stroke-dasharray:14;stroke-dashoffset:14}
.evdot.on svg path{stroke-dasharray:14;animation:evdotDraw .34s ease-out forwards}
@keyframes evdotDraw{
  from{stroke-dashoffset:14}
  to{stroke-dashoffset:0}
}
/* 已完成事项：标题淡化 + 删除线（2026-09-22 用户要求：长列表里一眼区分办结项）。
   不改变圆点颜色（保持类型色），仅处置文字层；transition 让勾选/取消时柔和过渡。 */
/* 未办结：明确保持全不透明（圆点也满色），防止任何继承/默认 opacity 误伤。 */
.ev-row:not(.done) .evdot{opacity:1}
/* 标题/时间的淡化改挂在外层 .ev-row.done 上：点击圆点时 handler 只给 .ev-row
   切 .done（.cd-evt 自身从不被切），所以规则必须落在 .ev-row 才能即时生效。 */
.ev-row.done .ev-title{color:var(--muted);opacity:.6;transition:color .25s ease,opacity .25s ease}
.ev-row.done .cd-evt-time{opacity:.5;transition:opacity .25s ease}
/* 已完成：连左边的圆形圆点也一起淡化（与标题、时间同节奏）。注意 .evdot 在
   .ev-row.done 内（圆点列与内容列是兄弟，故用外层 .ev-row.done 命中）。 */
.ev-row.done .evdot{opacity:.45;transition:opacity .25s ease}
/* 取消勾选时勾立刻消失（不反向播放动画，避免"倒着擦掉"的怪异观感） */
@media (prefers-reduced-motion:reduce){
  .evdot,.evdot:hover,.evdot:active{transition:none;transform:none}
  .evdot.on svg path{animation:none;stroke-dashoffset:0}
}

@media(max-width:859px){
  .icon-btn{width:44px;height:44px}
  .btn-icon{width:38px;height:38px}
  .chip{padding:6px 12px}
}

@media(min-width:520px){.form-grid.md3{grid-template-columns:repeat(3,1fr)}}
.calc-out{border:1px solid var(--border);border-radius:14px;background:var(--card-grad);padding:6px 16px}
.chk{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:var(--fg);cursor:pointer}
.modal select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:none;background-repeat:no-repeat;padding-right:8px}
.modal select:focus{outline:none}
.calc-out .co-row{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:10px 0;border-bottom:1px solid var(--border);font-size:13px}
.calc-out .co-row span{color:var(--muted)}
@media(max-width:600px){.stat-card .sc-v{font-size:19px}}

/* ===== 案件视图切换 / 阶段甘特图 ===== */
/* 案件管理的视图切换（卡片 / 阶段甘特图）。
   规则已并入统一分段切换器 .seg（2026-09-17 用户指定参考「机构 个人 企业」），
   这里只保留 Gantt 等相邻样式，不再单独定义 .mode-tg ——
   模板里 class="seg mode-tg" 的 .seg 负责外观，.mode-tg 仅作语义标记，
   若在此重复定义会与 .seg 打架（同名 .mode-tg button 特异度更高，会覆盖 .seg）。 */
.gantt{display:flex;flex-direction:column}
.gt-row{position:relative;display:flex;flex-direction:column;gap:7px;padding:13px 16px;cursor:pointer;transition:.15s;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}
.gt-row:not(:last-child)::after{content:"";position:absolute;left:16px;right:16px;bottom:0;border-bottom:1px dashed var(--muted-2)}
@media (hover:hover) and (pointer:fine){
  /* 甘特图卡改成蓝底后，行 hover 的 --bg(#f3f8fb) 与蓝色父底几乎同色、
     hover 完全看不出来（父底已不是白色）。改成白底半透明：
     在蓝底上"提亮"而不是"换色"，与蓝色卡片的整体调子一致。
     颜色从 var(--card) 派生——暗色模式的 --card 是深色，白底会突兀。 */
  .gt-row:hover{background:color-mix(in srgb,var(--card) 62%,transparent)}
}
.gt-row:active,.gt-row:focus{background:transparent;outline:none}
.gt-top{display:flex;align-items:center;justify-content:space-between;gap:10px;min-width:0}
.gt-name{display:block;font-size:13px;font-weight:700;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gt-tag{flex-shrink:0;font-size:11px;font-weight:700;padding:3px 9px;border-radius:8px;white-space:nowrap}
.gt-tag.tag-done{background:#e7f3ee;color:var(--emerald)}
.gt-tag.tag-cur{background:#eef0fb;color:var(--violet)}
.gt-segs{display:flex;gap:4px;align-items:center}
/* 客户可见进度页/阶段推进：固定 4 列网格，8 个阶段分两行每行 4 个 */
.gt-segs.grid4{display:grid;grid-template-columns:repeat(4,1fr);gap:5px}
.gt-segs.grid4 .gt-seg{min-width:0;padding:0 4px}
.gt-segs.wrap{flex-wrap:wrap}
.gt-segs.wrap .gt-seg{flex:0 0 auto;min-width:48px;padding:0 9px}
.gt-segs.grid4 .gt-seg{height:26px;font-size:11.5px}
.gt-seg{flex:1;height:24px;position:relative;display:flex;align-items:center;justify-content:center;border-radius:7px;font-size:11px;font-weight:600;background:#dfe5f0;color:var(--muted);overflow:hidden}
.gt-seg.cur{background:linear-gradient(135deg,var(--violet),#6b57c9);color:#fff;box-shadow:0 4px 10px -4px rgba(143,122,224,.7);animation:gtpulse 1.6s ease-in-out infinite}
.gt-seg.done{background:#cbe6dd;color:#2f7d5f;overflow:visible;text-decoration-line:line-through;text-decoration-thickness:2px;text-decoration-color:currentColor}
@keyframes gtpulse{0%,100%{opacity:1}50%{opacity:.78}}
.gt-foot{font-size:11.5px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gt-foot .sep{opacity:.55;margin:0 2px}
.gantt-legend{position:relative;display:flex;justify-content:center;gap:16px;flex-wrap:wrap;padding:11px 16px;font-size:13px;font-weight:550;color:var(--fg);align-items:center}
.gantt-legend::after{content:"";position:absolute;left:16px;right:16px;bottom:0;border-bottom:1px dashed var(--muted-2)}
.gantt-legend span{display:flex;align-items:center;gap:6px}
.gantt-legend i{width:14px;height:10px;border-radius:3px;display:inline-block;flex-shrink:0}
.gantt-legend .lg-done{background:#cbe6dd}
.gantt-legend .lg-cur{background:var(--violet)}
.gantt-legend .lg-future{background:#dfe5f0}
@media(max-width:600px){
  .gt-row{padding:11px 12px;gap:6px}
  .gt-row::after{left:12px;right:12px}
  .gt-seg{height:21px;font-size:10px;border-radius:6px}
  .gt-segs.wrap{gap:3px}
  .gt-segs.wrap .gt-seg{min-width:44px;padding:0 7px}
  .gt-segs.grid4{gap:4px}
  .gt-segs.grid4 .gt-seg{height:23px;font-size:10.5px;padding:0 3px}
  .gt-name{font-size:12.5px}
  .gt-tag{padding:2px 7px;font-size:10px}
  .gt-foot{font-size:11px}
}

/* ===== 日期时间选择器（+/- 步进式底部弹层） ===== */
.date-field{cursor:pointer;-webkit-user-select:none;user-select:none}
.dt-overlay{position:fixed;inset:0;z-index:3000}
.dt-mask{position:absolute;inset:0;background:rgba(15,20,32,.42)}
.dt-sheet{position:absolute;left:0;right:0;bottom:0;background:#fff;border-radius:16px 16px 0 0;padding:14px 16px calc(14px + env(safe-area-inset-bottom));box-shadow:0 -8px 30px rgba(30,36,51,.18);animation:dtUp .22s ease}
@keyframes dtUp{from{transform:translateY(30px);opacity:0}to{transform:translateY(0);opacity:1}}
.dt-head{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.dt-title{font-size:15px;font-weight:700;color:var(--fg)}
.dt-prev{flex:1;font-size:13px;color:var(--muted);font-family:monospace}
.dt-now{border:1px solid var(--border-strong);background:var(--card-2);color:var(--emerald);font-size:12px;padding:5px 12px;border-radius:999px;cursor:pointer}
.dt-cols{display:flex;gap:8px;padding:4px 0 12px}
.dt-col{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;background:var(--card-2);border-radius:12px;padding:8px 2px}
.dt-arrow{width:32px;height:32px;border:none;border-radius:10px;background:#fff;box-shadow:var(--shadow);font-size:18px;color:var(--emerald);cursor:pointer;font-weight:700;flex-shrink:0}
.dt-arrow:active{transform:scale(.92)}
.dt-num{font-size:22px;font-weight:800;color:var(--fg);line-height:1;font-variant-numeric:tabular-nums;cursor:pointer;padding:2px 6px;border-radius:8px;transition:background .15s}
.dt-num:active{background:rgba(0,122,255,.12)}
.dt-lbl{font-size:11px;color:var(--muted)}
.dt-actions{display:flex;gap:10px}
.dt-btn{flex:1;text-align:center;padding:11px 0;border-radius:12px;border:1px solid var(--border-strong);background:#fff;color:var(--fg);font-size:14px;cursor:pointer}
.dt-btn.dt-primary{background:#111827;color:#fff;border:none;font-weight:600}
.dt-btn:active{transform:scale(.98)}
/* 数字编辑小弹窗 */
.dt-edit{position:fixed;inset:0;z-index:3100;display:flex;align-items:center;justify-content:center}
.dt-emask{position:absolute;inset:0;background:rgba(15,20,32,.45)}
.dt-ecard{position:relative;width:78%;max-width:320px;background:#fff;border-radius:14px;padding:18px 16px;box-shadow:var(--shadow);text-align:center;animation:dtUp .2s ease}
.dt-etitle{font-size:16px;font-weight:700;color:var(--fg)}
.dt-erange{font-size:12px;color:var(--muted);margin:4px 0 12px}
.dt-einput-wrap{padding:2px;border:1.5px solid rgba(0,122,255,.42);border-radius:10px}
.dt-einput{width:100%;border:none;outline:none;background:#f2f6ff;font-size:20px;font-weight:700;text-align:center;padding:10px;border-radius:9px;color:var(--fg);font-variant-numeric:tabular-nums}
.dt-eactions{display:flex;gap:10px;margin-top:14px}
.dt-eactions button{flex:1;font-size:14px;padding:10px 0;border-radius:10px;border:1px solid var(--border-strong);background:#f4f6fb;color:var(--fg);cursor:pointer}
.dt-eactions button[data-ea="ok"]{background:#111827;color:#fff;border:none;font-weight:600}
.ic-sm{width:15px;height:15px;display:inline-block;vertical-align:-2.5px}

/* ==============================================================
   费用计算器（全屏版）· 参考律师计算器风格
   ============================================================== */
.calc-page{display:flex;flex-direction:column;gap:14px;padding:2px;max-width:680px;margin:0 auto}
.settings-page{display:flex;flex-direction:column;gap:14px;padding:2px;max-width:680px;margin:0 auto}
.settings-page svg{vertical-align:middle}
.settings-head{display:flex;align-items:center;gap:12px;margin-bottom:2px}
@media(max-width:859px){.settings-head{display:none}}
.settings-title{font-size:17px;font-weight:700;display:flex;align-items:center;gap:8px}
/* ============================================================
   主题设置 · 色块选择器（用户 2026-09-21 需求）
   ------------------------------------------------------------
   形态：四色圆形色块 + 下方主题名，当前主题带勾选环，点击即切换。
   色块底色用**主题自身的代表色**（THEMES[].color，见 app-shell.js），
   这样用户不点也能一眼看出四个主题各长什么样 ——
   这比纯文字列表直观得多，也是当初选这个形态的理由。

   ⚠ 选中环用**外扩 box-shadow**，绝不用 border 或 outline 撑大盒子：
     一旦选中就多 2px 边框，四个色块会横向上互相顶开、并且选中/取消时
     位置会跳（本项目对「加了样式就位移」很敏感，user 反馈过多次）。
     box-shadow 不占布局空间，加不加都不影响外框尺寸。
   ⚠ 内圈那条 1px 是**常驻**的（inset），用来在浅色主题（如淡色模式的
     #f3f8fb）上给色块描个边 —— 否则浅色块与浅色卡片底糊在一起看不见。
     所以它必须写在**所有状态**下，不能只写在 .is-on 里。 */
/* 色块容器：网格换行（用户 2026-09-21 需求，主题由 4 个增至 6 个）。
   ⚠ 先前是 flex + gap:16px 单行铺开。4 个主题在 430px 下刚好放下，
     但 6 个会挤到一行并溢出。
   ⚠ 为什么固定 3 列而不是 auto-fit：实测 auto-fit + minmax(64px,1fr)
     在 430px 下排出 **5 列**，于是 6 个主题变成「第一行 5 个 + 第二行 1 个」——
     落单那个（松烟模式）孤零零挂在左下角，视觉上很散。
     6 = 3 × 2 正好两行铺满、左右对称，是唯一能排匀的列数（也考虑过 2×3，
     但 3 列下每个色块 44px 仍有余量，2 列会显得太空）。
     宽屏下同样保持 3 列 —— 与卡片内边距的比例一致，不会拉成一条长线。 */
.theme-pick-wrap{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:12px 6px;
  justify-items:center;
}
/* 窄屏（<360px，如 iPhone SE 类）3 列会把「苔原模式」这类四字标签压换行，
   退回 2 列 —— 9 个恰好排满 4 行 + 1，虽有一格落单但比挤成换行好。 */
@media(max-width:359px){
  .theme-pick-wrap{grid-template-columns:repeat(2,1fr)}
}
.theme-pick{
  display:flex;flex-direction:column;align-items:center;gap:6px;
  background:none;border:none;padding:4px 2px;cursor:pointer;
  color:var(--muted);font-size:12px;font-family:inherit;
  -webkit-tap-highlight-color:transparent;
}
.theme-sw{
  width:44px;height:44px;border-radius:50%;flex-shrink:0;
  display:flex;align-items:center;justify-content:center;
  box-shadow:inset 0 0 0 1px var(--border-stronger);
  transition:transform .15s ease,box-shadow .2s ease;
}
.theme-sw svg{width:20px;height:20px;
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.45))}
/* ⚠ 勾的颜色必须**跟着色块明暗走**，不能一律给白。
   实测问题：淡色模式色块是 #f3f8fb（很浅），白勾压上去几乎看不见
   （截图确认「勾是白的、底也是白的」）—— 选中态等于没提示。
   修法：浅底主题的色块上勾用深色。判定依据是该主题的基调
   （THEMES[].dim），由 JS 在渲染时给色块加 .is-dark / .is-lite 类，
   CSS 只管配色 —— 避免在此处再写一遍「哪个主题是深是浅」的映射
   （那份映射的唯一定义在 app-shell.js 的 THEMES 里）。 */
.theme-sw.is-lite svg{color:#2A2318;filter:drop-shadow(0 1px 1px rgba(255,255,255,.5))}
.theme-sw.is-dark svg{color:#fff}
.theme-pick:hover .theme-sw{transform:scale(1.06)}
.theme-pick:active .theme-sw{transform:scale(.96)}
/* 选中：内圈描边（保留）+ 外扩两圈环。环不加尺寸，故不位移。
   ⚠ 最外圈**不能用 var(--bg)**：墨玉模式里 --bg 是近黑 #0A1714，
     而「墨玉模式」色块本身的代表色也是近黑 #0A1714，两者像素级相同
     （实测采样：色块填充 rgb(10,23,20) / 页面底色 rgb(10,23,20)），
     于是外圈环完全融进背景、色块失去边界 —— 选中态看着像「没选中」。
     修法：最外圈改用 --card（卡片底，永远比页面底亮一档），
     内圈那 2px 仍用 --fg 做对比环。这样在墨玉/深色下环也清晰可见，
     在淡色/暖阳下同样成立（--card 比 --bg 更白，环反而更明显）。 */
.theme-pick.is-on .theme-sw{
  box-shadow:inset 0 0 0 1px var(--border-stronger),
             0 0 0 2px var(--fg),
             0 0 0 4px var(--card)}
.theme-pick.is-on{color:var(--fg);font-weight:600}
.theme-sw-name{line-height:1.2;white-space:nowrap}
/* ⚠⚠⚠ 2026-09-21 用户：「费用计算 第一个卡片 淡色系主题都要淡一点。」
      → 追问确认：LPR 卡淡法 = 「改为品牌色浅色调」
   ------------------------------------------------------------------
   上一版（见下方历史注释）把它改成**实心品牌色渐变**——虽然解决了
   「深色主题下亮蓝扎眼」，但在淡色系里变成了整页最重的一块深色砖，
   与用户要的「淡一点」正好相反。
   本版改为**品牌色浅色调**：
     · 淡色系 6 套：品牌色以低透明度的观感浅染成淡底，配同色相深字
                    （--lpr-fg 即各主题 --emerald-d）。
     · 深色系 3 套：**原值原样搬进变量**（--emerald-l/--emerald/--emerald-d
                    + --on-emerald），视觉与改动前分毫不差 —— 用户明确只动淡色系。
   ⚠ 变量隔离：**没有复用 --emerald 三兄弟**。它们同时供 .btn-primary /
     .brand .logo / .wi-btn-p / .calc-lpr-* 等多处使用，直接改会波及全站。
     因此另建专属的 --lpr-a/--lpr-m/--lpr-b/--lpr-fg（先例：--wel-bg / --kpi-home-*）。
   ⚠ 3 停结构（a → m 60% → b）从原设计保留，这样深色系能**逐档等值**搬过来；
     若压成两色，中停会偏离原 --emerald 最多 8.4%（dark/ink 实测），深色系就不"零变化"了。
   实测（wcag）：淡色系文字对比 5.49~7.39:1；起端与白卡分离 1.25~1.33:1
     （>1.06 才看得出是独立一块）；深色系与原样完全一致。
   ------------------------------------------------------------------
   历史（保留，说明为何不是实心渐变）：
   这个 LPR 卡是全页唯一「实色填充」的主卡（其余卡片都是 --card-grad2 素底），
   靠"跳色"确立视觉优先级。原来整块写死：
     background  linear-gradient(135deg,#4a85b9,#5696cd 60%,#62a4d8)  蓝色
     color       #fff            （白字）
     .calc-lpr-val #f5c76a       （金色数字）
   后果：深色主题下这块亮蓝卡格外扎眼，与全站色调脱节。
   期间试过换成实心品牌色渐变（--emerald-l→--emerald→--emerald-d），
   深色主题问题解决了，但淡色系又太重 —— 故有本次「浅色调」定稿。 */
/* ⚠⚠⚠ 2026-09-21 第四版（用户：「打开看，还是太浅，那就参照 首页第一卡片的颜色深度来」）
     前三版都是拿 getComputedStyle 读变量值来推导，但**真机观感 ≠ CSS 值**。
     本轮改为**直接采样屏幕像素**（t110/t111.mjs，逐行取众数避开文字），
     拿到两块的真实渲染剖面，与首页在办案件卡对比后发现了真正的两个病灶：
       ① **方向**：在办案件卡是 180deg 纯纵向；这里是 135deg/155deg 斜向。
          卡片宽 710px 而高仅 ~100px，斜向渐变在纵向上的投影**几乎为 0** ——
          真机采样显示这里**顶底同色**（light 顶底都是 #E9EDF3，落差 0.000），
          所以不仅"看不出渐变"，整块也显得平、显得浅。
       ② **深度**：在办案件卡实测 顶 L 0.61~0.78 / 中 L 0.62~0.72；
          这里只有 0.82~0.89 —— 确实浅了一大截。
     修法：改成 **180deg 纯纵向**，并把深度对齐在办案件卡（其顶与中之间）：
       顶 L≈0.66 → 中(55%) L≈0.735 → 底 L≈0.805。
     文字对比 4.93~7.03:1 全部达标；对白卡分离 1.47~1.48:1。
     ⚠ 停靠点 46%：与在办案件卡 / 问候卡完全一致（同源同色，见上方 2026-09-21 第九版注释）。 */
.calc-lpr-card{background:var(--lpr-overlay),linear-gradient(180deg,var(--lpr-a) 0%,var(--lpr-m) 46%,var(--lpr-b) 100%);border-radius:16px;padding:16px 18px 14px;color:var(--lpr-fg);box-shadow:0 8px 20px -12px rgba(0,0,0,.18)}
.calc-lpr-tags{font-size:12px;color:var(--lpr-fg);opacity:.72;letter-spacing:.2px;margin-bottom:14px}
.calc-lpr-cols{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.calc-lpr-item{flex:1;min-width:86px}
/* ⚠ 2026-09-21：三个内部文字色统一由 --on-emerald 改为 --lpr-fg。
   --on-emerald 是「压在实心品牌色上」的前景色（淡色系=白、深色系=近黑），
   而本卡现在是**浅色调底**，白字会彻底消失 —— 故必须换成 --lpr-fg。
   深色系的 --lpr-fg 取的就是原 --on-emerald 值，所以深色系观感不变。
   opacity 也相应收敛（原 .82/.72/.9 是为实心深底设计的降噪手段，
   浅底上用同样的低透明度会发灰发虚）。 */
.calc-lpr-lab{font-size:11.5px;color:var(--lpr-fg);opacity:.78;margin-bottom:3px}
.calc-lpr-val{font-size:26px;font-weight:800;color:var(--lpr-fg);line-height:1;font-variant-numeric:tabular-nums}
.calc-lpr-val span{font-size:14px;font-weight:600;margin-left:1px}
.calc-lpr-sub{font-size:13px;font-weight:600;color:var(--lpr-fg);opacity:.92}
.calc-section-head{display:flex;align-items:center;justify-content:space-between}
.calc-sec-title{font-size:14px;font-weight:700;color:var(--fg);display:flex;align-items:center;gap:6px}
.calc-func-list{display:flex;flex-direction:column;gap:9px}
.calc-func{display:flex;align-items:center;gap:12px;width:100%;padding:12px 14px;border:1px solid var(--border);border-radius:13px;background:var(--card-grad2);cursor:pointer;transition:.15s;text-align:left}
.calc-func:hover{border-color:var(--border-strong);box-shadow:var(--shadow-soft)}
.calc-func-ic{flex-shrink:0;width:36px;height:36px;border-radius:11px;display:flex;align-items:center;justify-content:center;font-size:18px;font-weight:800}
.calc-func-tx{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.calc-func-t{font-size:14px;font-weight:700;color:var(--fg)}
.calc-func-d{font-size:11.5px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.calc-func-arrow{color:var(--muted);flex-shrink:0;display:flex}
.calc-func-arrow svg{width:18px;height:18px}
.calc-func.active{border-color:var(--emerald);background:var(--card-grad)}
.calc-panel{background:var(--card-grad2);border:1px solid var(--border);border-radius:16px;overflow:hidden;box-shadow:var(--shadow-soft)}
.calc-panel-head{display:flex;align-items:center;gap:8px;padding:12px 14px;border-bottom:1px solid var(--border);background:var(--card-2)}
.calc-panel-head .icon-btn svg{width:19px;height:19px;stroke-width:2.5}
.calc-panel-head .btn-ghost svg{width:22px;height:22px}
.calc-panel-title{flex:1;font-size:15px;font-weight:700;color:var(--fg)}
.calc-panel-body{padding:16px}
.calc-form{display:flex;flex-direction:column;gap:13px}
.calc-row{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.calc-field{display:flex;flex-direction:column;gap:5px}
.calc-label{font-size:12px;font-weight:600;color:var(--muted)}
.calc-moneywrap{display:flex;align-items:center;border:1px solid var(--border-strong);border-radius:10px;background:var(--card);overflow:hidden}
.calc-moneywrap:focus-within{border-color:var(--emerald)}
.calc-cny{width:32px;flex-shrink:0;text-align:center;color:var(--muted);font-size:14px;font-weight:600;background:var(--card-2);align-self:stretch;display:flex;align-items:center;justify-content:center;border-right:1px solid var(--border)}
.calc-moneywrap .input{border:none;box-shadow:none;border-radius:0;text-align:right;font-variant-numeric:tabular-nums}
.calc-upper{font-size:12px;color:var(--muted-2);margin-top:4px;min-height:16px;line-height:1.5;letter-spacing:.3px;text-align:right}
.calc-note{font-size:11.5px;color:var(--muted);line-height:1.7;background:var(--card-2);border:1px dashed var(--muted-2);border-radius:10px;padding:10px 12px}
.calc-hide{display:none!important}
.calc-out .co-row b.co-acc{color:var(--emerald);font-size:20px}
.calc-out-note{font-size:11.5px;color:var(--muted);line-height:1.6;border-top:1px dashed var(--muted-2);margin-top:6px;padding-top:8px}
.calc-warn{font-size:12px;color:var(--rose);line-height:1.6;background:rgba(244,63,94,.08);border:1px solid rgba(244,63,94,.3);border-radius:10px;padding:9px 12px;margin-bottom:6px}
.calc-err{background:rgba(244,63,94,.05);border-color:rgba(244,63,94,.3)}
.calc-hist-head{display:flex;flex-direction:column;gap:3px;margin-bottom:10px}
.calc-legend{font-size:12px;font-weight:700;color:var(--fg)}
.calc-legend-sm{font-size:11px;color:var(--muted)}
.calc-hist-table{max-height:420px;overflow-y:auto;border:1px solid var(--border);border-radius:12px}
.calc-hist-row{display:grid;grid-template-columns:1fr auto auto;gap:10px;padding:8px 12px;font-size:12.5px;border-bottom:1px solid var(--border)}
.calc-hist-row:last-child{border-bottom:none}
.calc-hist-row:nth-child(odd){background:var(--card-2)}
.ch-d{color:var(--muted)}
.ch-y1{color:var(--sky);font-weight:700;font-variant-numeric:tabular-nums;min-width:52px;text-align:right}
.ch-y5{color:var(--emerald);font-weight:700;font-variant-numeric:tabular-nums;min-width:52px;text-align:right}

/* ============================================================
 * 社评工资数据（用户 2026-09-16 新增 · 纯展示页）
 * 布局：省份徽章 → 口径说明 → 三年对比表（全省/深圳/广州/珠海）→ 依据脚注
 * 视觉沿用既有语言：卡片描边 + 斑马纹 + tabular-nums，
 * 「高于全省」的市用 --teal 强调（与经营分析「已收款」同色，表正向）。
 * ============================================================ */
.sw-prov-badge{display:inline-flex;align-items:center;gap:6px;align-self:flex-start;
  padding:6px 12px;border-radius:999px;background:var(--card-2);border:1px solid var(--border-stronger);
  font-size:12.5px;font-weight:700;color:var(--fg)}
.sw-prov-badge svg{width:14px;height:14px;color:var(--teal)}
.sw-scope{font-size:12px;font-weight:700;color:var(--muted);display:flex;align-items:center;gap:6px;margin:2px 0 0}
.sw-scope svg{width:14px;height:14px;flex-shrink:0}
.sw-table{border:1px solid var(--border);border-radius:12px;overflow:hidden}
/* 列宽随省份列数变化：--sw-cols 由面板渲染时按 data.cities.length 写入。
   兜底 4（广东），湖南写 1。
   ⚠ 原来写死 repeat(4,…)，湖南单列时只占 1/4 宽、右侧全空，
     内容看着没有居中（用户 2026-09-16 反馈）。改成 var() 后才真正铺满。 */
.sw-row{display:grid;grid-template-columns:58px repeat(var(--sw-cols,4),minmax(0,1fr));align-items:center;
  border-bottom:1px solid var(--border)}
.sw-row:last-child{border-bottom:none}

/* ——— 单列表格（湖南）的内容整体居中（用户 2026-09-17 明确要求）———
   用户原话：「计发基数往右移动到合适位置，年份也往右移动合适位置，
   然后整体看着左右到边边的距离对等，我是要这样的居中」。

   之前只做到「文字在自己的格子里居中」，但格子本身是 46px + 320px 这么切的，
   于是：年份文字距表格左边缘仅 6px，计发基数距右边缘 145px ——
   每段文字各自居中、整体却严重偏左。用户看到的「还是没改」就是这个。

   修法：单列时不让格子撑满整行，改为「两列都按内容宽度收缩、整组再居中」：
     · grid 用 max-content 让列宽贴合文字，不再被 1fr 拉开；
     · justify-content:center 把「年份+计发基数」当成一个整体摆到行中央，
       左右留白自然相等（这就是用户说的「左右到边边的距离对等」）。
     ⚠ 只对单列生效。广东有 4 列，列多且本就该铺满整行，不能套这个规则，
     否则四列会缩成一小团挤在中间。用 [data-cols="1"] 精确限定。 */
/* 单列时列宽按内容定，但要**固定住左列宽度**，见下。 */
/* 单列时列宽由内容决定；两列 padding **各自左右相等**，行间靠 column-gap 拉开。
   ⚠ 早先我给左列 padding:9px 10px 9px 14px（左 14 右 10，不对称），
     想用「右小左大」把两段文字视觉上推近一点 —— 结果两个副作用：
       ① 「年份」文本中心与数据行「2025年」文本中心错开 6px（表头 184 / 数据 190），
          因为两行的文字宽度不同，不对称 padding 会把它们推向不同位置；
       ② 触发了「左右 padding 必须对称」这条既有断言。
     改成左右同为 10px，列间距交给下面的 column-gap —— 效果一样，但没有偏置。

   ⚠⚠ 最终改用 **flex**，而不是 grid —— 这是踩过两轮才定下来的：
      目标是同时满足两条：
        (a) 左右留白相等（用户：「左右到边边的距离对等」）；
        (b) 表头「年份」与数据行「2025年」文字中心在同一竖线上。
      grid 方案做不到两条兼顾：
        · 用 max-content → 每行各自算宽度，表头/数据行轨道总宽不同，
          居中的起点跟着变，文字中心错开 7px（实测 172 vs 179）→ 违反 (b)；
        · 改成两列都写死 px → 轨道统一了，但列内文字居中会在列内留出「空隙」，
          而两列的空隙不等，导致左右留白又差 7px（115 vs 122）→ 违反 (a)。
      根因是 grid 把宽度分给「列」，而用户看的是「文字到边的距离」。
      flex 下每段内容是紧贴文字的盒子、由 column-gap 固定间距，
      justify-content:center 让整组居中，左右留白天然相等，
      且两行结构相同 → 文字中心自然对齐。
   ⚠ 左列宽度仍需固定（min-width），否则「年份」和「2025年」宽度不同，
     表头/数据行的左列右边界会错开。用 min-width + 居中即可。 */
.sw-row[data-cols="1"]{display:flex;align-items:center;justify-content:center;
  column-gap:16px}
.sw-row[data-cols="1"] .sw-city,
.sw-row[data-cols="1"] .sw-col{flex:0 0 auto;padding:9px 10px}
.sw-row[data-cols="1"].sw-head .sw-city-hd,
.sw-row[data-cols="1"].sw-head .sw-col{padding:8px 10px}
/* ⚠ 下面是本文件里**第二条** `...[data-cols="1"].sw-head .sw-col` 规则（第一条在 1402 行，
   给的是通用 8px 10px）。两条同选择器，靠**源顺序在后**生效 —— 别把这条挪到上面去，
   否则表头的右移 padding 会被 1402 行那条盖掉，标题又偏回左边 7px。 */
/* 左列**不设固定宽度**，宽度由内容（「年份」或「2025年」）决定，文字在列内居中。
   ⚠ 曾把左列写死 76px，结果是「列宽 76 − 文字 36.7 = 39.3px 的死空间」，
     左右各分 19.65px。这 19.65px 与右列内部的 (50−30)/2 = 10px 不相等，
     导致「文字到表格左右边缘」的距离差了 10px（实测 132 vs 122），
     用户要的「左右到边边的距离对等」就被这点死空间破坏掉了。
   现在左列紧贴文字（26px = 文字 36.7 的最宽值取整 + 内边距），
   两列的内部留白都趋近于 0，文字到边的距离自然相等。
   ⚠ 用 min-width 而非 width：保证「年份」这种短文字也不会把列压得过窄，
     但不会产生上面那种大面积死空间。
   ⚠ 文字仍保持居中（用户 2026-09-17 明确选择「保持居中」）。
     表头「年份」22px 与数据行「2025年」36.7px 宽度不同，
     居中后两者中心仍会差约 7px —— 这是「居中」这一选择的固有代价，
     用户已确认接受，不要再试图用固定宽度去凑齐（会把留白又搞坏）。 */
.sw-row[data-cols="1"] .sw-city,
.sw-row[data-cols="1"] .sw-city-hd{min-width:0;box-sizing:border-box;text-align:center}
/* 表头「计发基数」往右挪，与下方数值对齐（用户 2026-09-17：「计发基数 还要右移动，
   下面数据可以了」）。
   原因：表头盒宽 64px（由「计发基数」44px 撑开）、数据盒宽 50px（由「7,694」30px 撑开），
   两盒右边界几乎相同，但**宽度不等**，各自居中后中心差了 (64−50)/2 ≈ 7px，
   看上去标题比数字偏左。
   修法：把表头「计发基数」整体**右移约 7px**，与下方数值的视觉中心对齐。
   ⚠ 为什么不能用 align-items:flex-end（试过，无效后再试的）：
     表头列宽由 max-content 决定，「计发基数」44px + padding 20px 正好撑满 64px，
     列内没有任何余量，靠右对齐等于没对齐（实测中心仍 244，纹丝不动）。
     而且两列的**右边界本来就几乎重合**（276 vs 276.4）——
     问题不是「没右对齐」，而是两列宽度不同导致**居中后的中心**错开：
       表头 44px 在 64 宽里居中 → 中心 244
       数据 30px 在 50 宽里居中 → 中心 251.3
     所以要让标题往右挪，只能改 padding：左侧加大、右侧减小后文字右移。
     左 17px（原 10）+ 右 3px（原 10）= 净右移 7px，正好补上 (64−50)/2。
   ⚠ 只改表头，数据行 padding 保持 9px 10px 不动（用户说「下面数据可以了」）。 */
.sw-row[data-cols="1"].sw-head .sw-col{padding:8px 3px 8px 17px}

/* 表头行的底色单独由下面的 .sw-head 提供（那是必要的层次区分，用户未反对）。 */
.sw-head{background:var(--bg-soft);border-bottom:1px solid var(--border-stronger)}
/* 左列「年份」/「2025 年」：左右 padding 必须**相等**才能真居中。
   ⚠ 原值 padding:9px 4px 9px 10px（左 10 右 4），配合 text-align:center 时
     内容会整体偏左 3px。实测年份中心 x=53、列中心 x=55，差 2px ——
     用户反馈「数据是居中过去了，但年份没有居中」就是这个。
     改成左右同为 6px 后与表头 .sw-city-hd 的 padding 完全一致，
     两行的内容中心才会落在同一条竖线上。 */
.sw-city{padding:9px 6px;font-size:12px;color:var(--muted);white-space:nowrap;text-align:center}
/* 表头左列「年份」：用户 2026-09-16 要求此处显示「年份」二字并用**黑色**，
   且与下方各行「2025 年」一起居中（原来是左对齐留白）。 */
.sw-city-hd{text-align:center;padding:8px 6px;font-weight:700;color:var(--fg);
  display:flex;align-items:center;justify-content:center}
/* 左列年月：用户要求「数字+『年』都黑」，所以两段都从灰改到 --fg。
   ⚠ 原来 .sw-year 已是 --fg、只有 .sw-year-sub 是 --muted，
     现在把 sub 也提到 --fg，整列观感统一为黑色。 */
.sw-year{font-weight:800;font-size:13px;color:var(--fg);font-variant-numeric:tabular-nums}
/* ⚠ margin-left 已去掉（原为 1px）：用户要求「年份和计发基数同步居中」，
   实测这两段文本 + 半角间距会把「2025年」整体右推约 2px，
   使数据行中心（57）与表头「年份」中心（55）不一致。
   去掉后两行中心对齐到同一条竖线。 */
.sw-year-sub{font-size:10px;color:var(--fg)}
/* 行内左列居中（与表头「年份」对齐）。 */
.sw-row .sw-city{text-align:center}
.sw-col{padding:9px 6px;text-align:center;min-width:0}
.sw-head .sw-col{padding:8px 6px;display:flex;flex-direction:column;align-items:center;gap:3px}
.sw-col-name{font-size:11.5px;font-weight:700;color:var(--muted);white-space:nowrap}
.sw-head .sw-col.is-above .sw-col-name{color:var(--teal)}
.sw-val{font-size:13.5px;font-weight:700;color:var(--fg);font-variant-numeric:tabular-nums;white-space:nowrap}
.sw-col.is-above .sw-val{color:var(--teal)}
/* ——— 首列主色（用户 2026-09-16）———
   广东首列「全省社评」+ 其下数值 → 品牌蓝；湖南首列「计发基数」+ 其下数值 → 绿。
   实现要点：
     ⚠ 选择器必须是 3 段（.sw-col.is-tint-x 下的 .sw-val 是 3 段）才压得住
        上面 `.sw-col.is-above .sw-val`（也是 3 段），靠**源顺序在后**取胜，
        所以这两组规则必须写在 .is-above 之后，不能提到前面。
     ⚠ 首列永远不参与 is-above 比较（全省是基准），所以 tint 与 is-above
        在实际渲染里互斥，不会真正打架；把顺序摆对只是为了将来扩展时不出意外。
     ⚠ 暗色下 --emerald(#4c6b9e) 在深蓝底上偏暗发闷、--teal(#22b49e) 也会沉下去，
        故各自换亮一档（身体是 #e6ebf5 系的深色主题，用亮蓝/亮绿才读得清）。 */
.sw-col.is-tint-brand .sw-col-name{color:var(--emerald)}
.sw-col.is-tint-brand .sw-val{color:var(--emerald)}
body.theme-dim .sw-col.is-tint-brand .sw-col-name,
body.theme-dim .sw-col.is-tint-brand .sw-val{color:#8fb0e0}
.sw-col.is-tint-teal .sw-col-name{color:var(--teal)}
.sw-col.is-tint-teal .sw-val{color:var(--teal)}
body.theme-dim .sw-col.is-tint-teal .sw-col-name,
body.theme-dim .sw-col.is-tint-teal .sw-val{color:#4fd6c0}
/* 「低于全省」的格子：数值保留（不隐藏、不置空），但用一条灰色横线划过，
   提示该年该市不适用「就高」规则。用 ::after 画线而不是 line-through，
   原因是 line-through 会连同千分位逗号一起划断，且无法单独控制线的颜色/粗细。
   ⚠ 线要压在数字正中：这里用绝对定位 + 50% 顶部偏移，配合 .sw-col 的 position:relative。 */
.sw-col.is-below{position:relative}
.sw-col.is-below .sw-val{color:var(--sw-strike)}
/* ⚠ 用户明确要求「一条**灰色**的横线」，所以不能用 --muted-2（#98a2ba 是蓝紫调，
   R/G/B 相差 34，肉眼偏蓝紫）。这里专设 --sw-strike 保证三通道接近的纯灰。
   用 ::after 而非 line-through：line-through 会连千分位逗号一起划断，
   且无法单独控制线的颜色/粗细。 */
.sw-col.is-below .sw-val::after{content:'';position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:calc(100% - 14px);max-width:64px;height:1px;background:var(--sw-strike);opacity:.9}
/* 「高于全省但待遇不适用市标准」（湖南长沙）：
   数字用中性色而非 teal —— 因为它在**工伤待遇**场景下不产生就高效果，
   用 teal 会误导用户以为待遇按长沙数算。
   ⚠ 这里用 .is-na 这个**直接写在元素上的类**，不要用 :has(.sw-badge-na) 反查 ——
     徽章只在表头行，数据行里没有它，:has 永远匹配不到（曾踩到：长沙数值一直是青绿）。
   ⚠ 权重：.is-na 那条必须写成 `.sw-col.is-above.is-na .sw-val`（3 段），
     才能压过上面的 `.sw-col.is-above .sw-val`（2 段）。 */
.sw-badge-na{background:var(--card-2);color:var(--muted);border:1px solid var(--border-stronger)}
.sw-col.is-above.is-na .sw-val{color:var(--fg)}
.sw-col.is-above.is-na .sw-col-name{color:var(--muted)}
/* 表头列名另有 `.sw-head .sw-col.is-above .sw-col-name`（3 段），
   要生效必须补一条 4 段的。 */
.sw-head .sw-col.is-above.is-na .sw-col-name{color:var(--muted)}
/* 「高于全省」徽章：小尺寸，避免在窄列里换行 */
.sw-badge{display:inline-block;font-size:9.5px;line-height:1.5;padding:0 5px;border-radius:999px;
  background:rgba(34,180,158,.13);color:var(--teal);font-weight:700;white-space:nowrap}
/* 派生金额表：由计发基数按法定比例算出的具体金额（湖南用）。
   放在主表下方，视觉上比主表轻 —— 主表是「官方公布的数字」，
   这里是「推算出来的」，用不同底色区分，避免用户误当官方发布值。 */
.sw-derived{margin-top:12px;border:1px solid var(--border);border-radius:12px;
  background:var(--card-2);overflow:hidden}
/* 派生卡片标题行：只有「按该基数可直接得出的待遇金额」这一句。
   原本括号那段跟标题挤在同一行、同为加粗黑字，用户 2026-09-16 要求拆开：
   括号内文字另起一行、不加粗、灰色 —— 所以拆成 .sw-derived-head + .sw-derived-sub。
   ⚠ 原来 .sw-derived-head 自带 border-bottom 作为与表格的分隔线；
     现在它下面多了副行，那条线必须**下移**到副行上，否则标题与副行之间
     会多出一条横线，看着像两个独立段落（改的时候容易漏，已实测确认）。 */
.sw-derived-head{display:flex;align-items:center;gap:6px;padding:9px 12px 0;
  font-size:12px;font-weight:700;color:var(--fg)}
.sw-derived-head svg{width:14px;height:14px;color:var(--teal);flex-shrink:0}
.sw-derived-title{min-width:0}
/* 副行：括号用**半角且括号内不留空格**（用户明确指定「()这种没有空格的」），
   常规字重、灰色，与加粗黑色主标题形成层级。
   ⚠ 左侧 padding 必须比右侧大 20px（12 → 32），这 20px = 主标题图标的
     14px 宽 + 6px gap。用户 2026-09-17 要求「括号与上面主标题对齐」——
     指的是和主标题的**文字**左边缘对齐。若沿用 12px，括号会跑到图标正下方，
     看着像挂在图标上而不是跟着标题走。
   ⚠ 主标题字号 12px 是用户指定的（「参考下面卡片 口径与依据」），
     与 .sw-foot-title 一致；改字号时记得两边同步。 */
.sw-derived-sub{padding:3px 12px 9px 32px;font-size:11px;font-weight:400;color:var(--muted);
  line-height:1.5;border-bottom:1px solid var(--border)}
.sw-dv-table{display:flex;flex-direction:column}
.sw-dv-row{display:grid;grid-template-columns:minmax(0,1fr) 74px 84px;align-items:center;
  gap:6px;padding:8px 12px;border-bottom:1px solid var(--border)}
.sw-dv-row:last-child{border-bottom:none}
.sw-dv-hd{background:var(--bg-soft);font-size:10.5px;font-weight:700;color:var(--muted)}
.sw-dv-name{font-size:11.5px;color:var(--fg);line-height:1.5}
.sw-dv-mult{font-size:11px;color:var(--muted);text-align:center;white-space:nowrap}
.sw-dv-amt{font-size:12.5px;font-weight:800;color:var(--teal);text-align:right;
  font-variant-numeric:tabular-nums;white-space:nowrap}
.sw-derived-note{font-size:10.5px;line-height:1.6;color:var(--muted-2);padding:7px 12px;
  border-top:1px dashed var(--border-stronger)}
/* 脚注：口径与依据。全口径只在这里出现（仅全省，地市不单独公布） */
.sw-foot{margin-top:14px;padding:12px 14px;border:1px dashed var(--border-stronger);border-radius:12px;
  background:var(--card-2);display:flex;flex-direction:column;gap:7px}
.sw-foot-title{font-size:12px;font-weight:700;color:var(--fg);display:flex;align-items:center;gap:6px}
.sw-foot-title svg{width:14px;height:14px;color:var(--amber);flex-shrink:0}
.sw-foot-line{font-size:11.5px;line-height:1.7;color:var(--muted)}
.sw-foot-line b{color:var(--fg);font-weight:700;font-variant-numeric:tabular-nums}
.sw-foot-src{font-size:10.5px;line-height:1.7;color:var(--muted-2);padding-top:6px;border-top:1px dashed var(--border-stronger)}
@media(max-width:520px){
  .calc-row{grid-template-columns:1fr}
  .calc-lpr-val{font-size:22px}
  /* 窄屏：城市名列收窄、字号略降，保证四列数值仍在一屏内不被挤断。
     实测 320px 下可用宽度足够，不需要横向滚动。
     ⚠ 必须排除单列（湖南）：单列用的是 max-content + justify-content:center，
       这里若用 `46px repeat(...)` 覆盖它，年份列会被固定成 46px，
       整组又贴回左边 —— 用户「左右到边边距离对等」的要求在窄屏就失效了。
       所以单列规则单独用 :not() 排除，不靠源顺序赌。 */
  .sw-row:not([data-cols="1"]){grid-template-columns:46px repeat(var(--sw-cols,4),minmax(0,1fr))}
  /* ⚠ 窄屏只收字号，**不动 padding 左右值** ——
     原来写的是 padding-left:8px（右侧仍是 6px），会破坏左右对称、
     让年份在窄屏又偏右 1px。居中要求左右 padding 恒等，故整条去掉。 */
  .sw-city{font-size:11px}
  .sw-year{font-size:12px}
  /* ⚠ 同样要排除单列：单列的左右 padding 必须保持 10px 对称，
     这里若压成 3px，湖南两列会贴得几乎无间隙（靠 column-gap 撑不住）。 */
  .sw-row:not([data-cols="1"]) .sw-col{padding:8px 3px}
  .sw-col-name{font-size:10.5px}
  .sw-val{font-size:12px}
  .sw-badge{font-size:9px;padding:0 4px}
  /* 窄屏下划线短一点，避免碰到相邻列 */
  .sw-col.is-below .sw-val::after{width:calc(100% - 8px);max-width:46px}
  /* 湖南「高于全省 · 待遇按全省」文案比广东的长，窄屏让它换行而不是撑破列宽 */
  .sw-badge-na{white-space:normal;text-align:center;line-height:1.35;max-width:100%}
  /* 派生金额表：窄屏收窄倍数/金额两列，名称列仍要能读 */
  .sw-dv-row{grid-template-columns:minmax(0,1fr) 56px 66px;padding:7px 9px}
  .sw-dv-name{font-size:11px}
  .sw-dv-mult{font-size:10px}
  .sw-dv-amt{font-size:11.5px}
  /* 标题行与副行拆开后 padding 要各自跟上（原来只有一行，统一给 8px 9px）。
     ⚠ 两处都要改，只改父级会让副行在窄屏仍留 12px 左内边距、与标题不齐。
     ⚠ 副行左侧要保住「图标 14 + gap 6」那 20px 缩进（9 + 20 = 29），
       否则窄屏下括号又会滑到图标下方、和主标题文字错开。 */
  .sw-derived-head{font-size:12px;padding:8px 9px 0}
  .sw-derived-sub{font-size:10.5px;padding:2px 9px 8px 29px}
}

/* ==============================================================
   参考排版：编号模块卡片 + 胶囊筛选 + 复选任务清单
   ============================================================== */
/* 设置页面所有分区卡片：套用参考渐变（排除顶栏返回按钮） */
.settings-page>div:not(.settings-head){background:var(--card-grad2);border:1px solid var(--border);border-radius:12px;padding:14px;margin-bottom:12px}
@media(max-width:600px){
}


/* =====================================================================
   工伤待遇 · 广东页（源自「工伤待遇计算器-广东.html」）
   -----------------------------------------------------------------
   搬进来时做了 4 处「作用域收敛」，原因都写在对应注释里：
     ① .wi-page 去掉 max-width/padding —— 嵌进面板后会被压成窄条；
     ② .wi-top 去掉负 margin 与 sticky —— 负 margin 会左右出血；
     ③ @media print 里的 body{background:#fff} 删掉 —— 全局选择器；
     ④ 写死的 #fff 背景换成 var(--card) —— 否则暗色模式是白块。
   原文件的 :root 变量块**整块不要**：它的变量名与本项目主题重名
   （--bg / --card / --border / --emerald…），搬进来会覆盖全站配色。
   本项目已有的同名变量值与原版一致，直接用即可。
   ===================================================================== */
/* ===== 页面骨架：移动端 App 风格 ===== */
/* ⚠ 不能保留原版的 max-width:520px / padding:0 14px ——
   原版是独立整页；这里嵌在 .calc-panel-body 里面，外层已有自己的内边距，
   再叠一层会左右各多出 14px、还要被压成 520px 宽的窄条。 */
.wi-page{padding:0 0 8px}

/* 顶部标题栏
   ⚠⚠⚠ 2026-09-21 用户：「计算器工伤待遇计算器其他淡色系 这里的颜色跟着主题色走」
      → 追问后确认：「浅色底改主题浅色」；再明确：「工伤待遇计算器 这里颜色还是没改」
      → 本轮定调：「工伤待遇计算器 颜色淡一点」，追问后指明是
        「广东 / 其他省直辖市自治区 下面这个卡片」（= 本顶栏）。
   ------------------------------------------------------------------
   病灶（第一层）：这里是全站**最后一处写死配色**的地方 ——
     background:linear-gradient(135deg,#4c6b9e,#3a5480)   ← 钉死的浅蓝
     color:#fff / .wi-top-ico svg{color:#fff}            ← 钉死的白字
   实测（t104.mjs）9 个主题全部返回同一组值：
     rgb(76,107,158) → rgb(58,84,128)
   即**无论切到哪个主题，这条永远是那块浅蓝** —— 在 ink（冷灰）/ plum（紫）
   这类色相完全不同的主题里，它就是一块突兀的蓝砖，与全站配色彻底脱节。
   ------------------------------------------------------------------
   第一版修法：改用主题变量 --wi-top / --wi-top-fg（9 套主题各写一份）。
     · 浅色系 6 套：**品牌深档 → 主色 → 亮档**（--emerald-d → --emerald → --emerald-l），
       配白字，min 对比 4.54~5.36:1 全部达标。
     · 深色系 3 套（dark/ink/plum）：不能照搬 —— 它们的品牌色是**浅亮档**
       （如 ink #9AA6B8、plum #C4A8F0），拿它当大块底色会糊成一片亮色，
       而且白字压上去不可读（实测 dark 用白字仅 3.39:1）。
       改用「深底 + 品牌亮档微染（16%→26%→38%）」配各自 --fg 浅字：
         dark  #1A253A→#2A3A58 (9.52:1) / ink #2F3339→#4F555E (5.95:1)
         / plum #352E43→#5F5372 (5.30:1)
       —— 色相仍是本主题的，但明度压在深色档，与深色主题的整站调性一致。
   ------------------------------------------------------------------
   ⚠⚠⚠ 第四版修法（本轮，用户：「看截图还可以。但打开看，还是太浅，
      那就参照 首页第一卡片的颜色深度来。」）：
     第三版调到「起点 L≈0.695、落差 0.20」后，**截图看着对了，真机仍然偏浅**。
     第四版不再靠 CSS 值推导，改为**直接采样屏幕真实像素**（t110/t111.mjs：
     逐行取颜色众数、避开文字/图标），拿到两块的真实渲染剖面 ——
     于是发现了前三版一直没看见的两个病灶：
       ① **方向**：在办案件卡是 180deg 纯纵向；这里是 135deg/155deg 斜向。
          卡片宽 710px、高仅 ~100px，斜向渐变在纵向上的投影**几乎为 0**。
          真机采样铁证：这里**顶底同色** —— light 顶 #E9EDF3 / 底 #E9EDF3，落差 0.000。
          ⇒ 所以不仅"看不出渐变"，整块也平、也浅。
       ② **深度**：在办案件卡实测 顶 L 0.61~0.78、中 L 0.62~0.72；
          这里只有 0.82~0.89 —— 浅了一大截。
     修法：改 **180deg 纯纵向**，深度对齐在办案件卡（取其顶与中之间）：
       顶 L≈0.66 → 中(55%) L≈0.735 → 底 L≈0.805，落差 0.145。
     ⚠ 教训（写给以后的自己）：这个项目的"深浅"**必须看真机像素**，
       不能看 getComputedStyle 的变量值 —— 斜向渐变在扁卡片上的纵向投影、
       以及文字/图标遮挡，都会让"计算值"与"看到的值"严重不符。
       前后四轮修改里有三轮就是因为只看计算值而判断失误。
     第二版把所有浅色主题统一压到「起点 L≈0.72、落差≈0.12」——
     横向一刀切，结果**色相差异被抹平了**（六个主题起点全在 0.715~0.721），
     而且落差太小，整条几乎是一片均匀的浅色，看不出"渐变"。
     本轮改为**对齐「首页在办案件卡片」的实测深度**：
       在办案件卡 = linear-gradient(180deg, kpi1 0%, kpi2 46%, kpi3 100%)
         实测 起点 L 0.702~0.780 / 纵向落差 **0.181~0.251**
       而工伤顶栏第二版 起点 L≈0.72 / 落差仅 0.12 —— 落差只有它的一半。
     所以「太浅」的真正病灶是**落差不够**，不是起点不够暗
     （起点其实已比在办案件更深）。本轮：
       起点 L≈0.695（最上面最深）→ 中停 48% L≈0.815 → 终点 L≈0.895，
       落差拉到 **0.199~0.209**，与在办案件同一量级，
       观感即"最上面明显加深、往下慢慢淡开"。
     ⚠ 停靠点从 58% 改到 **48%** —— 中停上移让"上面深的那段"更长，
       这正对应「最上面还要加深，慢点往下淡化」（淡得慢 = 深色区间占比大）。
     ⚠ 各主题色相已重新拉开（起点 L 0.690~0.697 虽接近，
       但 R/G/B 通道值按各自品牌色走，色相差异保留）。
     第一版虽然解决了"不跟主题"的问题，但**把整块做成了深色** ——
     淡色系起点 L 只有 0.072~0.095（接近黑），在浅色页面里是一块压顶的深砖，
     与用户「淡一点」的诉求正好反向。实测：
       light #3a5480 L=0.0880 / moss #3D5230 L=0.0724 / dusk #524668 L=0.0717
       sand  #7A4525 L=0.0853 / mist #39505F L=0.0743 / sakura #8E3A58 L=0.0948
     本版把淡色系 6 套改为**品牌色浅色调**（与 LPR 卡同一路数）：
       起点 L≈0.72 → 中停 ≈0.78 → 终点 ≈0.84，文字改用**品牌深档 --emerald-d**。
     文字对比实测 5.31~7.26:1 全部达标；与白卡分离 1.36~1.37:1（>1.06 即看得出是块）。
     仍保持「135deg 左上深 → 右下浅」的方向（起点 L 最低）。
   ⚠ 深色系 3 套（dark/ink/plum）本轮**不动** —— 用户明确「只改淡色系」，
     且深色主题的整站调性本就是深色，顶栏保持深底微染才是正确的。
   ⚠ 内部叠加层（.wi-top-ico 的 rgba(255,255,255,.18)、折叠按钮的
     rgba(255,255,255,.12)）原本是**白色蒙版**，为深底设计。
     顶栏转浅后这两层白蒙版会"洗白"图标与按钮 —— 已在下方对应规则里改为
     黑色低透明度蒙版，跟随 --wi-top-fg 的明暗自动切换。
   ⚠ 文字色改走 --wi-top-fg：淡色系=品牌深档，深色系=各主题浅字。 */
.wi-top{position:static;background:var(--wi-top);color:var(--wi-top-fg);
  margin:0 0 16px;padding:14px 16px 13px;border-radius:13px;box-shadow:0 4px 18px -6px rgba(0,0,0,.28)}

.wi-top-row{display:flex;align-items:center;gap:10px}

/* ⚠ 图标底衬原本写死 rgba(255,255,255,.18)（白色蒙版，为深底设计）。
   顶栏转浅后，白蒙版会把衬底"洗白"到看不见 —— 改用 --wi-top-ov：
     淡色系 = rgba(0,0,0,.06)（黑色微蒙版，衬底变暗一点点才看得见轮廓）
     深色系 = rgba(255,255,255,.14)（保持原来的白蒙版逻辑） */
.wi-top-ico{width:34px;height:34px;border-radius:10px;background:var(--wi-top-ov);
  display:flex;align-items:center;justify-content:center;flex-shrink:0}

.wi-top-ico svg{width:19px;height:19px;color:var(--wi-top-fg)}

.wi-top-t{font-size:16px;font-weight:800;letter-spacing:.3px}

.wi-top-s{font-size:11px;opacity:.82;margin-top:2px}

/* 卡片外壳 */
.wi-card{background:var(--card);border:1px solid var(--border);border-radius:14px;
  padding:14px;margin-bottom:14px;box-shadow:0 2px 10px -4px rgba(76,107,158,.12)}

.wi-card-hd{display:flex;align-items:center;gap:7px;font-size:13px;font-weight:800;
  color:var(--fg);margin-bottom:10px}

.wi-card-hd svg{width:15px;height:15px;color:var(--emerald);flex-shrink:0}

.wi-card-hd .wi-hd-note{font-size:10.5px;font-weight:500;color:var(--muted);margin-left:auto}

/* 顶部社评工资卡：强调为「置顶信息」
   ⚠ 2026-09-21：边框原为写死的 #cfe0f2（浅蓝），在 moss/sand/plum 等主题里
     指向错误色相。改用 --border-stronger（各主题自己的强调边框色）。 */
.wi-sw-card{border-color:var(--border-stronger);background:var(--card)}

/* 表单 */
.wi-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}

.wi-grid .full{grid-column:1/-1}

.wi-label{display:block;font-size:12px;font-weight:600;color:var(--muted);margin-bottom:6px}

.wi-label .req{color:var(--rose)}

.wi-input,.wi-select{width:100%;padding:10px 12px;border:1px solid var(--border-stronger);
  border-radius:11px;background:var(--card);color:var(--fg);font-size:14px;outline:none;transition:.15s}

.wi-input:hover,.wi-select:hover{border-color:#b9c6da}

.wi-input:focus,.wi-select:focus{border-color:var(--emerald-l);box-shadow:0 0 0 3px rgba(76,107,158,.13)}

.wi-input::placeholder{color:var(--muted);opacity:.7}

/* 省级一次性补助卡 */
.wi-prov{margin-top:13px;border:1px solid var(--border);border-radius:12px;padding:12px;background:var(--card-2)}

.wi-prov-hd{display:flex;align-items:center;justify-content:space-between;gap:8px;
  font-size:12.5px;font-weight:700;margin-bottom:10px}

.wi-badge{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:700;
  color:#0d9488;background:rgba(13,148,136,.1);border:1px solid rgba(13,148,136,.28);
  border-radius:999px;padding:2px 9px;white-space:nowrap}

.wi-3col{display:grid;grid-template-columns:1fr 1fr 104px;gap:8px}

.wi-2col{display:grid;grid-template-columns:1fr 1fr;gap:8px}

.wi-yr-tag{font-size:11px;font-weight:600;color:var(--emerald-d);margin-left:6px}

/* 可选项目（实报实销，手动填写） */
.wi-opt{margin-top:13px;border:1px solid var(--border);border-radius:12px;padding:12px;background:var(--card-2)}

.wi-opt-list{display:flex;flex-direction:column;gap:9px}

/* ⚠ 2026-09-20 第三轮（用户逐项指定）：
   「住院期间伙食补助费 输入框要左移一点才能和上面的对齐，天字也移动一点对齐，
     后面 50元/天 不要动。第4到第8 框框后面 元 字加粗 颜色改成品牌蓝。
     如果加粗后影响到前面框框的话，把框框缩一点」
   实测数据（列表右缘 399）：
     行 1-2 [150元/天 / 120元/天]：输入 282→334，天 338，日标准 354→399
     行 3   [50元/天]            ：输入 288→340，天 344，日标准 360→399  ← 输入框与「天」整体右偏 6px
     行 4-8 [元]                 ：输入 278→382，「元」387
   根因：`.wi-opt-day` 是「内容自适应 + margin-left:auto」，
         日标准长短不同 → 组宽不同 → 输入框左边缘跟着漂移（117 / 111）。
   解：把「日标准」放进一个**固定宽度、左对齐**的槽（列宽 = 最长的「150元/天」= 45px），
       槽宽定死之后，左边的 [输入框][天] 就被推到同一位置，
       而日标准本身仍是左对齐 —— 「50元/天」不会被推到右边，视觉上原地不动。
   顺带：金额行的「元」按用户要求加粗、改品牌蓝；因为「元」加粗会变宽，
         把输入框从 104px 缩到 100px 补偿，保证整组仍不超右缘。 */
.wi-opt-row{display:flex;align-items:center;gap:10px}

.wi-opt-chk{display:flex;align-items:center;gap:8px;flex:1;min-width:0;cursor:pointer;
  font-size:13px;color:var(--fg);user-select:none}

.wi-opt-chk input{width:17px;height:17px;accent-color:var(--emerald);flex-shrink:0;cursor:pointer;margin:0}

/* 金额行的输入组：宽度由内容决定，margin-left:auto 让它贴右缘。 */
.wi-opt-amt{display:flex;align-items:center;gap:5px;flex:0 0 auto;margin-left:auto}

.wi-opt-amt .wi-input{padding:8px 10px;font-size:13px;width:100px}

/* 金额行的「元」：**右移**并与天数行的「天」落在同一列（用户 2026-09-20：
   「下面4到8项 后面的元也要同时移动对齐，前面框框不用动」）。
   实测：天数行「天」右缘 350→ 调整后与金额行「元」右缘同为一条竖线；
   做法与「天」对称 —— 给「元」一个固定宽度槽并右对齐，它就被钉在组的右端；
   配合上面的 .wi-opt-amt 右对齐定位，**输入框位置不变**。
   加粗 + 品牌蓝是上一轮的要求，保留。 */
.wi-opt-unit{font-size:12px;font-weight:700;color:var(--emerald-d);flex:0 0 auto}

.wi-opt-amt .wi-input:disabled{background:var(--bg);color:var(--muted);opacity:.65;cursor:not-allowed}

/* 带日标准的项目：天数输入 + 「天」+ 日标准提示（固定槽）。
   槽宽 45px = 最长的「150元/天」实测宽度 → [输入 52][天 12][槽 45] 三类行完全一致。 */
/* 天数行排版（用户 2026-09-20 第 5 轮）。
   ⚠ 需求本身存在位置冲突，说明如下（实测 430px，列表右缘 399）：
     天数行结构：[天数输入 274→326][天][日标准 354→399]
     金额行结构：[金额输入 282→382][元 387→399]
   「天」是天数的单位，语义上必须紧跟输入框、排在日标准**之前**；
   而「元」排在金额输入之后（尾部）。两者在各自行内所处的位置不同，
   因此「天」最多只能到日标准左侧（≈344），物理上无法到达「元」所在的 387 列。
   我试过三种做法并已全部回退，原因记录如下，避免以后重复踩：
     · DOM 换序（日标准在前、天在后）：渲染成「150元/天 天」，语义错误，用户不可接受；
     · margin-right 推「天」：连带把输入框从 274 顶到 249，违反「框框不要动」；
     · absolute 定位「天」到 387：与日标准文字重叠。
   当前采用的折中：让三条天数行内部的 [天] 与 [日标准] 严格互相对齐
   （三行完全同列，这是确定能做到的），并把日标准槽改为右对齐，
   使短的「50元/天」不再留右空档、视觉上整体右移（满足「50元/天 整体右移」）。
   「天」与「元」的跨行对齐在此结构下无法实现，需要用户确认是否愿意调整行内元素顺序。 */
.wi-opt-day{display:flex;align-items:center;gap:4px;flex:0 0 auto;margin-left:auto}

.wi-opt-day .wi-input{padding:8px 9px;font-size:13px;width:52px}

.wi-opt-day .wi-input:disabled{background:var(--bg);color:var(--muted);opacity:.65;cursor:not-allowed}

/* 「天」：固定 12px（与金额行「元」同宽），三行严格同列 */
.wi-opt-day .wi-opt-unit{font-size:12px;font-weight:700;color:var(--emerald-d);
  flex:0 0 auto;width:12px;text-align:left}

/* 日标准槽：固定 44px、右对齐 —— 「50元/天」(39px) 与「150元/天」(44px) 右端对齐，
   短文案不再留右空档，视觉上整体右移。 */
.wi-opt-rate{font-size:11.5px;font-weight:700;color:var(--emerald-d);
  flex:0 0 auto;width:44px;text-align:right;white-space:nowrap;overflow:visible}

.wi-opt-foot{margin-top:11px}

.wi-btn-s{flex:0 0 auto;width:auto;padding:7px 12px;font-size:12.5px;font-weight:600;
  border-style:dashed;color:var(--emerald-d);border-color:var(--emerald-l);background:none}

.wi-btn-s:hover{border-color:var(--emerald);background:rgba(76,107,158,.06);transform:none}

.wi-opt-custom{display:flex;flex-direction:column;gap:9px;margin-top:11px}

.wi-opt-custom-row{display:flex;align-items:center;gap:8px}

.wi-opt-cname{flex:1;min-width:0}

.wi-opt-cname .wi-input{padding:8px 10px;font-size:13px}

/* 自定义项目行：金额组宽度改为「输入框缩到 84px + 加粗的元」，
   与预设行的 100px 输入框区分（自定义行左侧还有名称输入框，横向更挤）。
   ⚠ 原来这里是给整组写死 width:120px，但 .wi-opt-amt 现在是
     「内容自适应 + margin-left:auto」，再写死宽度会把加粗后的「元」挤出去；
     改为只约束输入框宽度，组宽仍由内容决定。 */
.wi-opt-custom-row .wi-opt-amt .wi-input{width:84px}

.wi-opt-del{width:30px;height:30px;flex-shrink:0;border:none;background:none;border-radius:8px;
  display:flex;align-items:center;justify-content:center;color:var(--rose);cursor:pointer;transition:.15s}

.wi-opt-del:hover{background:rgba(240,97,126,.1)}

.wi-opt-del svg{width:15px;height:15px}

/* 结果表 */
.wi-out{margin-top:14px}

.wi-out .co-row{display:flex;justify-content:space-between;align-items:center;gap:12px;
  padding:10px 0;border-bottom:1px solid var(--border);font-size:13px}

.wi-out .co-row>span:first-child{color:var(--fg);min-width:0;flex:1}

.wi-out .co-row .sub{display:block;font-weight:400;margin-top:2px;font-size:11px;
  color:var(--muted);line-height:1.5}

.wi-amt{color:var(--emerald);font-weight:700;flex-shrink:0;text-align:right}

.wi-total span{font-weight:700}

.wi-total b{color:var(--emerald);font-size:20px}

/* 按钮 */
.wi-actions{display:flex;gap:8px;margin-top:14px}

/* 「计算」行右对齐（2026-09-18 用户要求：从左移到靠右）。
   ⚠ 只加在 .wi-actions-run 上，不要改 .wi-actions 本体 ——
   结果区的「复制清单 / 保存为文档」仍用默认左对齐，用户没要求动它。 */
.wi-actions-run{justify-content:flex-end}

/* ⚠ 光有 justify-content 不够：.wi-btn 有 flex:1，单个按钮会被拉满整行，
   「靠右」在视觉上根本看不出来（实测按钮宽度 372px = 整行）。
   必须把 flex 收回 auto，按钮才退回内容宽度并被推到右侧。
   min-width 96px 是为了触控区不至于太窄（纯内容宽约 52px 偏小）。 */
.wi-actions-run .wi-btn{flex:0 0 auto;min-width:96px}

.wi-btn{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:6px;
  padding:10px 12px;border-radius:11px;border:1px solid var(--border-strong);background:var(--card);
  color:var(--fg);font-size:13px;font-weight:600;transition:.15s}

.wi-btn:hover{transform:translateY(-1px)}

.wi-btn svg{width:15px;height:15px;flex-shrink:0}

.wi-btn-p{background:linear-gradient(135deg,var(--emerald-l),var(--emerald-d));
  border-color:transparent;color:var(--on-emerald);box-shadow:0 6px 16px -6px rgba(var(--em-rgb),.55)}

/* 校验错误 */
.wi-err{color:var(--rose);font-size:12px;padding:9px 11px;
  border:1px solid rgba(240,97,126,.3);background:rgba(240,97,126,.06);border-radius:10px}

/* 表单底部说明 */
.wi-note{font-size:11.5px;color:var(--muted);line-height:1.7;background:var(--card-2);
  border:1px dashed var(--border-stronger);border-radius:10px;padding:10px 12px;margin-top:12px}

@media(max-width:400px){
  .wi-grid{grid-template-columns:1fr}
  .wi-3col{grid-template-columns:1fr}
}

@media print{
  .wi-top{position:static}
  .wi-actions{display:none}
  .wi-card{box-shadow:none}
  .wi-scope{display:none}
}

/* 切换器与两页之间的衔接 */
.wi-scope{margin:0 0 14px}
.wi-scope-body{min-height:120px}
/* 广东页顶部自己带蓝条，外层就不要再叠一层间距 */
.wi-scope-body>.wi-page{padding-top:0}

/* =====================================================================
   工伤待遇 · 广东页扁平化（用户 2026-09-20：「不要框框套框框」）
   ---------------------------------------------------------------------
   改前的层级：.wi-card（大边框卡）
                 └ .wi-prov（内层边框块）×2 + .wi-opt（又一个边框块）
   视觉上是「一个框里装三个框」。改成：
     .wi-form   —— 无边框容器，只负责留白与分隔
     .wi-sec    —— 分区，用一条细横线 + 小标题区隔，**不再画边框**
     .wi-field  —— 单个字段组
   保留的框：只有输入框本身（.wi-input/.wi-select）与提示条（.wi-note）。
   每一层边框都要有存在理由，否则就是噪音（这正是用户嫌「套框」的根因）。
   ===================================================================== */
.wi-form{margin-bottom:14px}

/* 分区：细横线 + 上方留白。首条线去掉，避免它紧贴在上方内容下形成多余分界。 */
.wi-sec{
  position:relative;
  padding-top:14px;
  margin-top:14px;
  border-top:1px solid var(--border);
}
.wi-sec:first-of-type{border-top:none;padding-top:0;margin-top:0}
/* ⚠ 关联案件是 .wi-form 的直接子元素（不在 .wi-sec 里，因为它是「整页共用的
   上下文」而不是某个分区的一部分）。它之后紧跟的就是第一个 .wi-sec，
   那个 .wi-sec:first-of-type 会去掉自己的上边距 —— 结果是搜索框和「待遇计算」
   小标题贴在一起。这里给它补回间距。 */
.wi-form>.wi-field{margin-bottom:16px}
.wi-form>.wi-field+.wi-sec{margin-top:0}

.wi-sec-hd{
  display:flex;align-items:center;gap:7px;
  font-size:13px;font-weight:800;color:var(--fg);
  margin-bottom:10px;
}
.wi-sec-hd svg{width:15px;height:15px;color:var(--emerald);flex-shrink:0}
.wi-sec-hd .wi-hd-note{font-size:10.5px;font-weight:500;color:var(--muted);margin-left:auto}
.wi-sec-hd .wi-badge{margin-left:auto}

.wi-field{margin-bottom:14px}
.wi-field:last-child{margin-bottom:0}

/* 顶部条里的社平工资折叠按钮。
   一条半透明白描边 + 右边小箭头；箭头用 CSS 边框画，
   避免再引入一个 svg 图标（ic() 里没有现成的 caret）。
   ⚠ 2026-09-21：文字由写死的 #fff 改为 --wi-top-fg（深色系顶栏用浅字，
     但 dark/ink/plum 的 --fg 与纯白只差一点点，改后语义正确、观感一致）。 */
/* ⚠ 描边与底衬原为白色蒙版（深底设计）。顶栏转浅后同样要换：
   描边用 --wi-top-fg 的 28% 透明度（深字配深边、浅字配浅边，自动成立），
   底衬用 --wi-top-ov。 */
.wi-sw-toggle{
  display:flex;align-items:center;gap:8px;width:100%;
  margin-top:11px;padding:8px 11px;
  border:1px solid color-mix(in srgb,var(--wi-top-fg) 28%,transparent);
  border-radius:10px;
  background:var(--wi-top-ov);
  color:var(--wi-top-fg);font-size:12px;font-weight:600;
  cursor:pointer;text-align:left;
  transition:background .15s,border-color .15s;
}
/* hover：描边加深一档、底衬再深一点（同样走 --wi-top-fg 派生，自动适配深浅） */
.wi-sw-toggle:hover{background:color-mix(in srgb,var(--wi-top-fg) 10%,transparent);border-color:color-mix(in srgb,var(--wi-top-fg) 45%,transparent)}
.wi-sw-toggle>span:first-child{flex:1;min-width:0}
/* ⚠ 箭头原为 rgba(255,255,255,.9)（纯白 90%）。顶栏底色已成为主题色后，
   dark/ink/plum 的顶栏是深底 + 浅字，白色箭头仍然成立；
   但为与文字色一致（浅色系=纯白 / 深色系=各主题浅色 --fg），
   改用 currentColor —— 它自动继承 .wi-sw-toggle 的 --wi-top-fg。 */
.wi-sw-caret{
  width:0;height:0;flex-shrink:0;
  border-left:4.5px solid transparent;
  border-right:4.5px solid transparent;
  border-top:5px solid currentColor;
  opacity:.9;
  transition:transform .2s;
}
.wi-sw-toggle.is-open .wi-sw-caret{transform:rotate(180deg)}

/* 展开面板：贴在蓝条下方，白底卡片承载社评工资表 */
.wi-sw-panel{
  margin:0 0 14px;
  padding:12px 13px;
  border:1px solid var(--border);
  border-radius:13px;
  background:var(--card);
  box-shadow:0 2px 10px -4px rgba(76,107,158,.14);
}
.wi-sw-panel .wi-sw-hd{
  display:flex;align-items:center;gap:7px;
  font-size:12.5px;font-weight:800;color:var(--fg);margin-bottom:10px;
}
.wi-sw-panel .wi-sw-hd svg{width:15px;height:15px;color:var(--emerald);flex-shrink:0}
.wi-sw-panel .wi-sw-hd .wi-hd-note{font-size:10.5px;font-weight:500;color:var(--muted);margin-left:auto}
/* 折叠面板里的社评工资表原本自带外边距（独立页时用），这里收紧 */
.wi-sw-panel .calc-form{padding:0;margin:0}

/* 合计：金额用元（本页已不用「万」），字重加大；大写行紧跟其下 */
.co-row.wi-total b{font-size:21px;color:var(--emerald);font-weight:800;white-space:nowrap}
.co-row.wi-total-cn{align-items:baseline}
.co-row.wi-total-cn .wi-cn{
  font-size:11.5px;font-weight:600;color:var(--muted);
  letter-spacing:.3px;text-align:right;white-space:normal;line-height:1.5;
}

@media(max-width:400px){
  .co-row.wi-total b{font-size:19px}
  .co-row.wi-total-cn .wi-cn{font-size:11px}
}

/* =====================================================================
   工伤待遇 · 广东页第二轮微调（用户 2026-09-20）
   ===================================================================== */

/* 【1】折叠面板里的社评工资表：去掉外框
   用户：「下面数据 框框取消」。
   .sw-table 原本自带 1px 边框 + 圆角，配合外层面板的边框就成了「框套框」。
   这里只去边框 —— 行的分隔线（.sw-row 的 border-bottom）保留，
   否则四年的数据会糊成一片、没法横向对行。
   ⚠ 用后代选择器限定在折叠面板内：社评工资**独立页**那边仍要外框
     （它是页面主体，没有外层容器兜着，去框会显得散）。 */
.wi-sw-panel .sw-table{border:none;border-radius:0;overflow:visible}

/* 【2】封顶保底提示：小一号、不加粗
   用户：「本人工资（5000）低于受伤时社评60%……这里字体小一点，不用加粗」。
   靠琥珀色维持可辨识度，不靠字重。 */
.co-row.wi-capnote{align-items:flex-start}
/* ⚠⚠ 选择器必须写到 .wi-out .co-row.wi-capnote>span:first-child 这个深度。
   只写 .co-row.wi-capnote>span 会**静默失效**（已实测踩到）：
   文件里已有一条 `.wi-out .co-row>span:first-child{color:var(--fg)}`
   （3 个 class + 1 个伪类），优先级高于 2 个 class + 1 个元素，
   于是颜色被它按回 --fg，我这条 color:var(--amber) 根本没机会生效，
   而字号/字重因为没人竞争所以照常生效 —— 表现为「变小了但还是黑的」。
   这里补齐 .wi-out 与 :first-child，确保优先级别不低于它。 */
.wi-out .co-row.wi-capnote>span:first-child{
  font-size:11.5px;font-weight:400;color:var(--amber);
  line-height:1.6;
}
/* 非首个子元素（理论上没有，兜底）也跟随琥珀色 */
.wi-out .co-row.wi-capnote>span{color:var(--amber);font-weight:400}

/* 【3】案件详情 · 赔偿表格的「人民币大写」不换行
   用户：「最后大写不要换行，在一行显示」。
   ⚠ 大写金额（如「肆拾贰万叁仟元整」）在窄屏上会被 flex/grid 挤到折行，
     加 nowrap 让它整体成一行；同时给左侧标签留出空间，
     两个单元格都是 nowrap 时若真放不下，宁可整行横向溢出也不拆字。 */
.wi-cn-amt{white-space:nowrap}

/* ════════════════════════════════════════════════════════════
   2026-09-25 全局固定顶栏（第二轮）· 恢复「两张卡叠加 + 人物探出」关系
   ------------------------------------------------------------
   需求（用户原话）：
     · 第一轮：「人物图片超出外面 / 叠加卡片整体下移到合适位置然后固定 / 所有页面都显示」
     · 第二轮：「叠加卡片的关系 你怎么又给我搞乱了？」
   第一轮实现我为了「不让图片超出」，把卡内部几何**摊平**了
   （overlap 35→12、照片缩小、-48px/-20px 平移全清空）——
   结果白卡与彩卡的「大幅骑叠、人物站在卡交界」关系没了，被用户否掉。

   ★ 本版只动「定位」，绝不覆盖内部几何 ★：
     · 关系 = 由 2437~2771 行主规则完全决定（overlap / translate / 照片探出量
       照旧，本块**不再写 .welcome-top/.welcome-panel/.wel-photo/.welcome-main**
       的覆盖值）。
     · 「下移 + 不超出」靠顶栏渐变带的高度实现：渐变带 = 全局固定顶栏自带的
       一段留白，高度 ≥ 照片探出量，人像头部即完整落在渐变带之内、不被切顶。
     · 「固定 + 所有页面」：.wel-header 是 .main 的 flex-shrink:0 子块、位处
       .content 之外 ⇒ 不随内容滚动，对全部视图生效。
   ════════════════════════════════════════════════════════════ */

/* —— 渐变带 = 顶栏头空间（高度即给卡+探出照片让位，只调高度别调横向）——
   标题改由 .wel-title 承担，故顶栏标题隐藏。
   ⚠ 方案 A（2026-09-25 第五轮，用户「按方案 A 修复背景断层，将渐变延伸为
   全屏毛玻璃背景」）：
     · 把大气渐变**直接铺在 .main 上**（.main 是 100dvh、overflow:hidden 的
       固定高度列，内容在 .content 内滚动 ⇒ 渐变以屏为准、全程静止），
       从屏顶一路连续渐变到 var(--bg) 100% —— 顶栏段、叠加卡两侧、白卡
       下方都由这段色流承接，不再有「扁平带 / 色板」断层；
     · 内容卡片毛玻璃化（见下方 .content 毛玻璃规则）：卡片底改半透明 +
       backdrop-filter 模糊，让全屏渐变透出，形成「流体背景 + 浮空卡片」。
   标题改由 .wel-title 承担，故顶栏标题隐藏。
   ⚠ 第六轮（2026-09-26）实测补漏 —— 只铺 .main 还不够，渐变被两个
   「旧背景」盖出断层，必须一起清掉：
     ① .topbar 自带宽渐变（.topbar 基础规则 background-image 天光层）
       盖住 0~66px ⇒ 本规则给 .topbar 加 background:transparent，
       .main 渐变从屏顶直接穿出；
     ② .welcome::before 是一块实色 var(--bg) 底垫（left:-40/right:-40/
       top:-30/bottom:0，z-index:-1），几乎横跨全宽，把 y≈36~314 整段
       压成平白 ⇒ 下方新增 body.wel-top .welcome::before{background:transparent}，
       让渐变从叠加卡两侧与下方一路流过。
   同时把渐变 stops 拉长：蓝色不止于顶部，中下段（内容卡背后）仍保持
   可见的浅蓝渐变，毛玻璃 blur 才有「内容」可糊，浮空感才成立。 */
body.wel-top .main{position:relative;
  background:linear-gradient(180deg,
    var(--top-glow-1) 0%,
    var(--top-glow-3) 16%,
    var(--top-glow-5) 34%,
    var(--top-glow-6) 52%,
    var(--top-glow-7) 72%,
    var(--bg) 100%)}
body.wel-top .topbar{position:relative;z-index:0;height:calc(66px + env(safe-area-inset-top));
  padding:0;align-items:flex-end;pointer-events:none;background:transparent}
body.wel-top .topbar .tb-titlebox,
body.wel-top .topbar .title{display:none}
body.wel-top .topbar::after{height:0!important}
/* 渐变兜底穿透：welcome 背后的 --bg 实色底垫改透明，中段断层消失 */
body.wel-top .welcome::before{background:transparent}

/* —— 方案 A：内容卡片毛玻璃 ——
   覆盖 .content 下所有主卡片类：底改半透明（color-mix 基于 --card，明暗主题
   各自成立）+ backdrop-filter 模糊，透出 .main 的全屏渐变。
   ⚠ ::before 的半透明 tint（--card-tint-*）叠在毛玻璃底上不冲突 ——
     蓝 tint 与背景渐变蓝同色系，透出后融合更自然。 */
body.wel-top .content :is(.card,.card-tint,.card-tint-sm,.card-tint-mid,.st-card,.case-card,.client-row,.doc-row,.folder-card,.calendar-card,.type-card){
  background:color-mix(in srgb,var(--card) 76%,transparent);
  backdrop-filter:blur(16px) saturate(1.3);
  -webkit-backdrop-filter:blur(16px) saturate(1.3);
}

/* —— 叠加卡容器：全局固定。不设额外顶距 —— 顶距由上面渐变带承担。 */
.wel-header{flex-shrink:0;position:relative;z-index:20;padding:0 14px 2px}

/* —— 卡放回固定头内：保持原相对定位关系，只解掉 base 的 sticky/margin ——
   ⚠ 注意：这里**不**动内部几何（overlap/translate/photo），关系照旧。
   负下边距 = 收回「在办案件卡 translateY(-48px) 上移后在头部底部留下的空白
   预留区」，让内容紧贴白卡底边 —— 否则白卡与下方「今日待办」卡的视觉间距
   会被这 ~52px 白白拉开（实测 78px），与卡间常规 14px 不符。 */
/* 第七轮（2026-09-26）：叠加卡片整体上移 20px —— 顶部负 margin 把整块
   （彩色面板 + 叠加卡 + 照片）伸进渐变带 20px，视觉更紧凑；负下边距不变，
   内容区随之上移同量，间距关系照旧。 */
body.wel-top .welcome{position:relative;top:auto;z-index:auto;margin:-20px 0 -59px}
/* 2026-09-26 追加：负下边距 -50 → -58px —— 与 .welcome-panel 的 transform 同步
   （-48 → -56px，用户要求三样上移 8px）。白卡视觉上移 8px 后，content 随负下边距
   多收回的 8px 一起上移，保持「白卡底 → 内容首元素」仍为 14px，不破坏全局间距标准。
   2026-09-26 再追加：-58 → -59px —— 「内容区同理也上1px」，与三样再上移 1px 同步，
   间距仍为 14px。 */
/* 拦截点击修复（2026-09-26）：.welcome 的边框盒比可见内容（白卡底 246px）
   多出 ~48px 空洞 —— 这是负 margin 收回的「在办案件卡位移预留区」，盒身
   仍覆盖到各页顶部 seg 筛选（案件「全部/在办/已结案」、通讯「机构/个人/
   企业」…）的按钮区（264~293px），elementFromPoint 命中 .welcome 而非按钮，
   导致这些筛选点不动。修复：.welcome 整体关掉指针事件（空洞自然穿透），
   再给真正需要交互的可见部件恢复 —— 白卡（含折叠工具栏）、彩色面板、照片。 */
body.wel-top .welcome{pointer-events:none}
body.wel-top .welcome :is(.welcome-panel,.welcome-top,.wel-photo){pointer-events:auto}
/* 收回白卡下方空白后，content 顶部不再需要额外上内边距 ——
   「在办案件卡 → 今日待办卡」的 14px 间距由首卡自带 margin-top:14px 承担。 */
/* 第七轮（2026-09-26）：所有页面与顶部固定栏统一 14px 间距。
   原来只有首页首卡（内联 margin-top:14px）满足，其余视图首元素
   直接贴住叠加卡底（0px）。改为 content 顶部内边距 14px 兜底全局，
   再把各视图首元素的 margin-top 清零（首页首卡的内联 14px 已在
   dashboard.js 移除，这里兜底其余选择器来源的 margin），
   保证「叠加卡底 → 内容首元素」在全部页面一致为 14px。 */
body.wel-top .content{padding-top:14px}
body.wel-top .content > :first-child{margin-top:0}

/* —— 宽屏（桌面/平板）：照片更高、探出更多 ⇒ 渐变带随之加高 —— */
@media(min-width:601px){
  body.wel-top .topbar{height:calc(108px + env(safe-area-inset-top))}
  body.wel-top .welcome{margin:-20px 0 -52px}
  .wel-header{padding:0 20px 4px}
}
@media(min-width:860px){
  .wel-header{padding:0 26px 4px}
}





