/* ============================================================
   法小策律师赋能平台 · 样式表
   依据 DESIGN.md 设计系统实现
   ============================================================ */
:root{
  --c-primary:#1E3A5F; --c-primary-hover:#16304F; --c-primary-soft:#E8EEF6;
  --c-primary-border:#C5D4E6;
  --c-ink:#0F1B2D; --c-ink-soft:#16263D;
  /* ★ v4.0.6：--c-accent 同时承担「实底背景」（.btn.ok / .switch.on / 进度条）
     与「浅底上的文字」（.badge.acc / .fc-img / .st-c）两个角色。
     作为文字压在 --c-accent-soft(#E3F3F2) 上实算只有 4.39:1，差一点点；
     但**不能直接压深 --c-accent 本身** —— 那会让 .btn.ok 的实底变暗、
     白字反而更清晰，看似无害，实质是偷偷改了品牌青绿的观感。
     正确做法是按语义拆档：实底仍用品青 #0E7C7B，浅底文字另取深一档的 ink。
     #0C6E6D on #E3F3F2 = 5.30:1，on 白底 6.06:1，两处都过 AA。 */
  --c-accent:#0E7C7B; --c-accent-soft:#E3F3F2;
  --c-accent-ink:#0C6E6D;
  /* ★ v4.0.6 对比度整改：--c-warn 原 #B7791F 在白底 3.64、在告警浅底
     （#FDF6E8）3.38 —— 而它几乎**只用于浅底上**（.badge.or 背景就是
     --c-warn-bg），等于常用场景恰是最差场景。实测 44 处不达 AA。
     改为 #93601A：白底 5.35 / 告警浅底 4.85 / 浅主色底 4.58，10 种实底全达标；
     同色相只压明度（色相 38° 与原值一致），观感仍是"琥珀"不是"深棕"。
     ★ 为什么不是刚好过线的 #9A6717：它在浅主色底(--c-primary-soft 4.16)
       和告警浅底(4.40)上仍不达标 —— 而"告警徽章恰好落在浅蓝提示条里"
       是真实会发生的组合。为了 0.3 个点的暗度差留一个隐患，不值得。
     ★ 不动 --c-warn-soft/-bg/-tint 那几档浅底：它们是背景，不是文字，
       要的是"淡"，压深反而脏。真正该保证对比度的是**压在上面的字**。 */
  --c-warn:#93601A; --c-warn-soft:#FDF6E8; --c-warn-bg:#FDF6E8;
  --c-g900:#1A1F29; --c-g800:#2D3748; --c-g700:#3D4654; --c-g600:#556070; --c-g500:#6B7686;
  --c-g400:#A9B4C2; --c-g300:#C9D0DA; --c-g200:#E2E7EE;
  --c-g100:#EDF0F4; --c-g50:#F6F8FA;
  /* 文本语义别名（补齐：原先 var(--c-text) 未定义导致颜色失效） */
  --c-text:#2D3748; --c-text-sub:#6B7686;
  --c-surface:#FFFFFF; --c-surface-alt:#FAFBFC;
  --c-border:#E2E7EE; --c-border-strong:#CBD3DE; --c-bg:#F6F8FA;
  /* 视频/图片预览的套底黑：只用于媒体容器（视频属中性底色，
     用品牌深蓝 --c-ink 会让画面偏色）；浅色文字用于深底之上 */
  --c-media-backdrop:#000000; --c-on-dark:#FFFFFF;
  /* 半透明叠加：选题矩阵的热度色阶（品牌色压低透明度当底色，
     文字仍压在浅底上），与深色 hero 上的环形描边。
     此前是 rgba(14,124,123,.82) 这类字面量散在 JS 里，改配色要搜 JS。 */
  --c-accent-veil:rgba(14,124,123,.82);
  --c-warn-veil:rgba(183,121,31,.72);
  --c-primary-veil:rgba(30,58,95,.42);
  --c-on-dark-veil:rgba(255,255,255,.22);
  --c-on-dark-soft:rgba(255,255,255,.85);
  --c-success:#217A4B; --c-success-bg:#E6F4EC;
  --c-success-soft:#E4F3EA;
  --c-danger:#B3352F; --c-danger-bg:#FCEDEC;
  --c-danger-soft:#FCF4F3;
  --c-info:#1E5C99; --c-info-bg:#E8F1F9;
  /* ★ 侧栏（深青底）专用文字层级：原先 var(--c-side-text) / var(--c-side-group) 直接写死在 .sb-* 规则里，
     与灰阶令牌体系脱节，导致改侧栏配色要满文件搜 hex */
  --c-side-text:#7A8CA3; --c-side-group:#5D6E85;
  /* ★ toast 底色：原先 var(--c-success-solid)/var(--c-danger-solid)/var(--c-warn-solid) 与 --c-success/-danger/-warn 是
     同一语义的两套色（前景色 vs 实底背景色），各自硬编码。此处显式命名为
     「实底态」并统一取值，避免同一语义出现两套不相干的色。 */
  --c-success-solid:#1C6B45; --c-danger-solid:#A02C27; --c-warn-solid:#9A6717;
  /* ★ 强调紫：用于「分类/标签」语义，与主蓝、品牌青并列的第三语义色 */
  --c-purple:#5B4B9E; --c-purple-soft:#F3F0FA;
  /* 语义软底色：供标签/徽章/图标底统一取用，避免各处硬编码 */
  --c-primary-tint:#EEF3F9; --c-accent-tint:#EAF6F4;
  --c-warn-tint:#FBF3E4; --c-danger-tint:#F9EDEB;
  /* ★ v33 补定义：--c-primary-50 此前在 3 处被引用但从未定义
     （.sc-item:hover / .md-item:hover / .md-item.on），全靠调用点的
     fallback `var(--c-primary-50,#f4f7fb)` 兜住 —— 也就是说：把 fallback
     删掉，这 3 处就会「透明」；而 #f4f7fb 与主蓝软底 tint(var(--c-primary-tint)) 肉眼几乎
     无差，属于同一语义被写了两遍。这里正式定义并指向 tint，让 3 处调用点
     的 fallback 自动失效、全站主蓝软底只剩一个事实源。
     ★ 不改调用点删 fallback 的理由：fallback 是无害的防御性写法，
       留着不影响正确性，改动反而多 3 处 diff 风险。 */
  --c-primary-50:var(--c-primary-tint);
  /* ★ 边框/底色的「加深档」：标签、警示卡需要一个比 tint 更实、
     又不至于抢眼的中性档，此前满文件散落 var(--c-warn-border)/var(--c-warn-border-strong)/#F0E3C6 这类
     一次性色值（同一语义出现 3~4 个近似色）。这里按语义收敛成成对的
     「常规 / 强调」两档，配上各自的深色 tint。 */
  --c-warn-border:#E7D6B4; --c-warn-border-strong:#DCC38C;
  --c-warn-tint-deep:#FBF3E2; --c-warn-dot:#F4E4C3; --c-warn-solid-deep:#EFD9A8;
  --c-info-ink:#164A7A;                    /* info 告警条上的深蓝字 */
  --c-danger-border:#E6C9C6;               /* 失效态 chip 的描边 */
  --c-danger-ink-muted:#9C6B66;            /* 失效态 chip 的文字（比 danger 更闷） */
  --c-primary-lift:#3B6EA5;                /* 主色渐变的高光端 */
  --c-teal-wash:#F2FAF9; --c-teal-wash-deep:#EDF7F5;
  --c-teal-tint-soft:#EAF6F4;
  --c-teal-border:#B3E0DC;
  --c-surface-warm:#FCFCFB;                /* 阅读区（长文）比纯白略暖，降眩光 */
  --c-info-wash:#F7FAFF;                   /* AI 输出区的冷白底 */
  --c-danger-wash:#FDECEC; --c-danger-soft-solid:#FBE9E7;
  --c-success-soft-solid:#C8F0DC; --c-success-bright:#7FD3A6;
  --c-danger-bright:#FFD9D5; --c-danger-bright-solid:#D24B4B;
  --c-page-wash:#F7F9FC; --c-g-thumb:#94A3B8; --c-g-note:#4A5261;
  --c-primary-fallback:#EAF0F7; --c-surface-compare:#F3F6FA;
  --c-accent-light:#12A594; --c-gradient-primary:#1E3A5F 0%,#2B4C77 60%,#37618F 100%;
  /* 品牌青绿梯度：全局令牌（原散落于 .client-layout/.cl-* 的硬编码） */
  --c-teal-900:#0B2E2C; --c-teal-700:#0E3B38;
  --c-teal:#0E7C7B; --c-teal-light:#12A594; --c-teal-bright:#4FD1C5; --c-teal-lift:#17BFA9;
  --c-teal-soft:#E3F3F2; --c-teal-tint:#EAF6F4;
  --grad-brand:linear-gradient(135deg,#0F1B2D 0%,#1E3A5F 60%,#37618F 100%);
  --grad-client:linear-gradient(135deg,#0E7C7B 0%,#12A594 55%,#17BFA9 100%);
  --grad-teal-bar:linear-gradient(90deg,#12A594,#4FD1C5);
  --grad-side:linear-gradient(180deg,#0E3B38 0%,#0B2E2C 100%);
  /* 圆角令牌（统一原先散落的 6/7/8/9/12/14/16px）
     ★ 例外：微元素（≤10px 的进度条 / 图例色块 / inline code）仍用 2~4px ——
       在 7px 高的条上套 --r-xs(6px) 会变成近乎胶囊形，与它所在的卡片圆角冲突。
       这类尺寸的圆角本就该按元素高度比例给，套用页面级令牌反而更丑。
     ★ v37：上述「例外」此前只是**注释里的口头约定**，实际样式里仍是
       裸写 2px(×8) / 3px(×5) / 4px(×13) —— 注释说了、代码没照做，
       与 v33 之前间距刻度的处境一模一样（刻度是写给外人看的）。
       本轮把它们正式登记为令牌：约定只有变成可引用的名字才算成立，
       否则下一个人照样会随手写 3px，而 review 时无从判断
       「这是有意的微元素档，还是漏改的裸值」。 */
  --r-xs:6px; --r-sm:8px; --r-md:10px; --r-lg:12px; --r-xl:16px; --r-pill:999px;
  /* 微元素圆角（v37）：按元素高度比例给，专供 ≤10px 的条 / 点 / 行内码 */
  --r-2q:2px; --r-3q:3px; --r-1:4px;
  /* 字号令牌（补齐：此前无字号令牌，全站散落 10 种硬编码 font-size，
     11px 与 12px 各出现上百次且无规律，导致层级不清晰、改版要逐个替换） */
  --fs-2xs:11px;  /* 角标、辅助说明的最小可读尺寸 */
  --fs-xs:12px;   /* 次要信息、表格辅助列 */
  --fs-sm:13px;   /* 正文紧凑档、表单标签 */
  --fs-md:14px;   /* 正文默认（与 body 一致） */
  --fs-lg:16px;   /* 小标题、卡片标题 */
  --fs-xl:18px;   /* 区块标题 */
  --fs-2xl:22px;  /* 页面标题 */
  --fs-3xl:28px;  /* 品牌页大标题 */
  --fs-display:44px;  /* 展示级：品牌主标题、评分大数字（仅在营销/看板大屏使用） */
  /* 字重令牌（同样收敛成三档，避免 500/600/700 混用） */
  --fw-normal:400; --fw-medium:500; --fw-bold:600;
  /* 动效令牌 */
  --ease:cubic-bezier(.16,1,.3,1); --dur:.18s;
  /* 玻璃拟态 */
  --glass-bg:rgba(255,255,255,.78); --glass-border:rgba(255,255,255,.36); --glass-blur:blur(14px);
  --shadow-xs:0 1px 2px rgba(15,27,45,.06);
  --shadow-sm:0 1px 3px rgba(15,27,45,.08),0 1px 2px rgba(15,27,45,.04);
  --shadow-md:0 4px 12px rgba(15,27,45,.10),0 2px 4px rgba(15,27,45,.05);
  --shadow-lg:0 12px 32px rgba(15,27,45,.14),0 4px 8px rgba(15,27,45,.06);
  --shadow-xl:0 20px 48px rgba(15,27,45,.18),0 8px 16px rgba(15,27,45,.08);
  --font-sans:"PingFang SC","Microsoft YaHei","Source Han Sans SC","Noto Sans SC",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --font-num:"SF Mono","JetBrains Mono",Menlo,Consolas,monospace;
  /* ★ v33 补定义：--font-base 此前在 #s-paper（正文纸稿文本框）被引用，
     但**使用处没有 fallback**（font-family:var(--font-base)），
     未定义时整条声明失效 → 该输入框字体回退到浏览器默认（宋体/Times），
     在一屏全是无衬线中文的界面里非常突兀。这里正式定义为 --font-sans
     的别名（字体族是「基座」，与 --font-num 这个「数字专用」并列）。 */
  --font-base:var(--font-sans);
  /* ── 间距刻度 ─────────────────────────────────────────────
     ★ v33 实测与处置（不粉饰）：
       本刻度此前只有 4/8/12/16/20/24/32/40/48 九档，且 **全站引用 0 次**
       （grep 'var(--sp-' → 0）；真实样式里散布着 19 种非 4 倍数间距值，
       高频的是 10px(107) / 9px(82) / 6px(71) / 11px(70) / 14px(60)。
       也就是说：刻度是「写给外人看的」，代码根本没照它写。
     ★ 为什么不把 700 处硬编码全改回 4 的倍数：
       那是纯视觉回归风险 —— 每处改动都会让按钮/卡片的松紧发生肉眼可见的
       变化，而我无法逐一目视验证（没有像素级基准）。为了「刻度好看」
       引入几百个未经确认的视觉变更，是拿用户体验换代码洁癖，不做。
     ★ 真正的修法（v33）：把刻度**扩到覆盖实际在用的值**，让刻度与代码
       一致，而不是让代码去迁就刻度。这样：
       ① 刻度从此「是事实」，新人查表即可知道项目真实用的档位；
       ② 将来写新样式时，随手能取到 6/10/14 这些真在用的值，
          不会再有人因为「刻度里没有 10px」而随手写字面量。
       4px 主线（--sp-1/2/3/4/5…）保持不动，新增 --sp-* 半档仅作补充。

     ★ v37 续修（本轮，有像素级基准后完成 v33 未竟的部分）：
       v33 只补了**偶数**半档（2/6/10/14/18/22/26），但实测仍有
       282 处落在刻度外，且全部是**奇数子档**：
           9px×66  11px×50  3px×40  7px×39  5px×32  13px×23
           1px×17  17px×4   15px×3
       这些不是随手写的 —— 它们是「控件内边距」的常用档：
       一行 12px 字配 9px 左右内边距、13px 字配 11px，视觉最平衡。
       硬把它们拉回偶数档会真的改变控件高度与松紧。
       故新增 --sp-*q 系列（q = quarter/奇数子档）覆盖它们。
       ★ 命名为什么用 q 后缀而不是继续用 h：
         h 已被偶数半档占用（--sp-1h=6px）。奇数档是另一条线
         （每 2px 一档：1/3/5/7/9/11/13/15/17），用独立后缀
         才能在阅读样式时一眼区分「半档」与「奇数子档」，
         避免 --sp-3h(14) 与 --sp-3q(9) 这类命名互相混淆。
       ★ 至此刻度覆盖实测在用的**全部**取值，收敛才可能做到
         「视觉零变化」—— 这是本次能在有基线的前提下安全推进的前提。 */
  --sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;--sp-5:20px;--sp-6:24px;--sp-8:32px;
  --sp-10:40px;--sp-12:48px;
  --sp-0h:2px;--sp-1h:6px;--sp-2h:10px;--sp-3h:14px;
  --sp-4h:18px;--sp-5h:22px;--sp-6h:26px;
  /* 奇数子档（v37）：1/3/5/7/9/11/13/15/17 —— 控件内边距的细调档 */
  --sp-0q:1px;--sp-1q:3px;--sp-2q:5px;--sp-3q:7px;--sp-4q:9px;
  --sp-5q:11px;--sp-6q:13px;--sp-7q:15px;--sp-8q:17px;
  /* 刻度外零散值（v37）：各仅 1-3 处，但如实登记，避免继续散落 */
  --sp-15:30px;--sp-17:34px;--sp-25:50px;--sp-26:52px;--sp-28:56px;
  --z-sticky:100;--z-dropdown:300;--z-mask:1000;--z-modal:1010;--z-toast:2000;--z-tooltip:2100;

  /* ══════════════════════════════════════════════════════════
     v3.12.24 · 视觉分层升级（极简商务 / 克制干净 / 法律服务语境）
     ----------------------------------------------------------
     目标：在不改任何布局、模块、按钮、内容结构的前提下，只靠
     「色彩分层 + 留白 + 柔和阴影 + 微妙渐变 + 细微描边」提升精致度。
     原则：
       ① 主色不动（#1E3A5F 是品牌资产），只在它周围补齐同色系低饱和辅助阶；
       ② 所有新增色都压在 8%~20% 饱和度区间，不引入任何高饱和新色；
       ③ 灰阶从「偏冷的蓝灰」微调为「中性偏冷」，让深蓝主色更沉、更贵。
     ══════════════════════════════════════════════════════════ */

  /* 主色同族分层：从最浅的纸面到最深的海军，形成 7 级纵向刻度。
     ★ 为什么要补齐：此前只有 primary / hover / soft / border 四档，
       做卡片→卡头→卡内分区这种「同色系三级下沉」时无阶可用，
       只能靠灰阶硬接，于是层次看起来是「蓝+灰拼贴」而不是「一套色」。
     ★ 命名用 -p0…-p90（p = primary 的色相百分位），避免与既有
       --c-primary-soft / -border 的语义名冲突（那两个继续保留兼容）。 */
  --c-p0:#F7F9FC; --c-p1:#EFF4FA; --c-p2:#E4ECF5; --c-p3:#D3DFEC;
  --c-p5:#A8BDD4; --c-p7:#5C7A9C; --c-p9:#1E3A5F;

  /* 中性灰阶重排：降低蓝味、拉开明度差。
     ★ 原 g900 #1A1F29 与 g800 #2D3748 明度接近（ΔL 约 5），
       做「标题/正文」两级时几乎看不出差异，只能靠字重硬撑；
       新 g900 更深、g700 更浅，两级之间的落差足够让标题立起来。

     ══════════════════════════════════════════════════════════
     v4.0.6 · 对比度整改（依据 WCAG 2.1 AA，浏览器实测取证）
     ----------------------------------------------------------
     用 browser_visual_probe.py 逐页实算「渲染色 → 对比度比值」，
     16 页共 728 处不达 AA。归因后发现绝大多数不是散点，而是
     **两个令牌的取值本身就偏低**，被全站继承：

       --c-g500 #6E7A89 —— 承担 .muted / .small / .tiny / th / .k
                            等全部"次要文字"，728 处里 600+ 处是它。
                            实算：白卡 4.37、页面底 4.14、卡片头条纹底 4.14
                            → 全部卡在 4.5 线下一点点，正是最坏的取值：
                              看起来"应该合格"，逐条审也看不出错。
       --c-g400 #A3AEBC —— 邮箱时间/摘要、表格次要列。
                            实算：2.25，远低于 4.5；连大字门槛 3:1 都不到。

     ★ 为什么不"把这两类文字升成正文色（g700）"了事：
       它们表达的是「层级」—— 次要信息就该比正文弱。直接拉成正文色，
       等于把层级抹平，信息密度立刻下降（这是个一屏要塞很多字的工作台）。
       正确做法是**压到刚过法定线、但仍明显弱于正文**：
         g500: 4.37 → 5.32（白卡），仍比 g700(8.9) 弱一档，层级保留
         g400: 2.25 → 4.02（白卡），从"看不清"变成"能看清但明显更淡"
     ★ 取值为什么是这两个：
       页面最常用的底有三种（白卡 #FFF / 页底 #F7F9FC / 卡头条纹 #F7F9FB）。
       g500 还必须覆盖**浅色标签底**（.--c-primary-soft #E8EEF6 /
       --c-accent-soft #E3F3F2 / --c-success-bg #E6F4EC）——次要文字经常
       落在徽章、提示条里。实测 #636C78 在 11 种实底上最低 4.55，全部达标；
       再浅一点（#666F7B）在 --c-primary-soft 上掉到 4.36，就会被实测抓到。
       g400 无需达 AA（它承载实时时间、摘要这类"扫一眼即可"的辅助信息），
       但要摆脱「低于 3:1 = 连形状都难辨」的区间，取 4.02 留足余量。
     ══════════════════════════════════════════════════════════ */
  --c-g900:#131A26; --c-g800:#27313F; --c-g700:#3A4553; --c-g600:#525E6E;
  --c-g500:#636C78; --c-g400:#767F92; --c-g300:#C7CEDA; --c-g200:#E1E6EE;
  --c-g100:#EDF0F5; --c-g50:#F7F9FB;

  /* 表面分层：page(底) < surface(卡) < raised(浮起) < sunken(凹陷) 
     ★ 关键变化：--c-bg 从 #F6F8FA 提到 #F4F6FA 并略加压冷，
       卡片纯白在它上面才「浮」得起来；此前底色与卡片明度差仅 3%，
       大量卡片并排时页面像一整片白，只能靠边框硬划区。 */
  --c-bg:#F4F6FA; --c-page-wash:#F4F6FA;
  --c-surface:#FFFFFF; --c-surface-alt:#FAFBFD;
  --c-surface-raised:#FFFFFF; --c-surface-sunken:#F2F5F9;
  --c-border:#E4E9F0; --c-border-strong:#D2D9E3;
  --c-border-subtle:#EEF1F6;

  /* 描边三档：细 / 常规 / 强调。
     ★ 细微描边是本次「精致感」的主要来源 —— 用 1px 的极浅线
       代替重阴影来划分层级，页面立刻从「厚重」变「克制」。 */
  --c-hairline:rgba(19,26,38,.055);
  --c-hairline-strong:rgba(19,26,38,.09);

  /* 柔和阴影：多层低透明度，扩散大、偏移小。
     ★ 原阴影单层 0 1px 2px rgba(15,27,45,.06)，等于一条脏边，不像投影；
       新的三层叠加（贴边/主体/环境）才形成「物体离开纸面」的错觉，
       同时因为透明度都压在 0.05 以下，不会变脏。 */
  --shadow-xs:0 1px 2px rgba(19,26,38,.04);
  --shadow-sm:0 1px 2px rgba(19,26,38,.04),0 2px 6px rgba(19,26,38,.035);
  --shadow-md:0 1px 2px rgba(19,26,38,.04),0 4px 10px rgba(19,26,38,.045),0 12px 24px rgba(19,26,38,.03);
  --shadow-lg:0 2px 4px rgba(19,26,38,.045),0 8px 20px rgba(19,26,38,.06),0 24px 48px rgba(19,26,38,.05);
  --shadow-xl:0 4px 8px rgba(19,26,38,.05),0 16px 40px rgba(19,26,38,.08),0 40px 80px rgba(19,26,38,.06);
  /* 卡片「贴纸感」阴影：极浅，只用来把卡片从页码底上轻轻抬起 */
  --shadow-card:0 1px 2px rgba(19,26,38,.035),0 2px 8px rgba(19,26,38,.028);
  --shadow-card-hover:0 1px 3px rgba(19,26,38,.05),0 6px 16px rgba(19,26,38,.05);
  /* 顶部内高光：浅色面层的细微渐变，用来制造「纸面有厚度」的错觉 */
  --sheen-surface:linear-gradient(180deg,rgba(255,255,255,.9) 0%,rgba(255,255,255,0) 68%);
  --sheen-subtle:linear-gradient(180deg,#FFFFFF 0%,#FDFDFE 100%);

  /* 焦点环：主色 12% 单层扩散，比原来的 3px 硬环更柔 */
  --ring-primary:0 0 0 3px rgba(30,58,95,.09);
  --ring-danger:0 0 0 3px rgba(179,53,47,.09);

  /* 平台品牌识别色：抖音/小红书/视频号/公众号/知乎。
     ★ 这几个色**不属于本设计系统的调色板**，也不会被换掉 ——
       它们的职责是「让用户 0.2 秒认出这是哪个平台」，属于信息而非装饰。
       之所以收进令牌，是因为原先散在 insight.js 里做字面量，
       改配色要满 JS 搜 hex，且无法被设计令牌校验覆盖。
       注意：饱和度很高，只允许用于「平台名文字 / 小圆点 / 极细条」，
       禁止用作大面积底色 —— 那会破坏整页的克制口径。 */
  --c-plat-douyin:#1C1C1E; --c-plat-xhs:#FF2442; --c-plat-channels:#07C160;
  --c-plat-zhihu:#0084FF; --c-plat-unknown:#6B7683;
  /* 实色徽章上的字色（如评级 A/B/C 徽章背景是动态 grade_color，需要固定在深色上的白字）。
     ★ 单独立令牌而不是各处写 #fff：徽章的底色由后端下发、深浅不可预知，
       字色必须始终是"反色"，集中一处定义后换主题时只改这里。 */
  --c-on-accent:#FFFFFF;
}

/* ── 响应式断点约定（v33 归一，写在这里作为唯一口径）─────────────
   @media(max-width:640px)   手机（竖屏为主）
   @media(max-width:1024px)  平板 / 窄桌面（侧栏折叠区间）
   @media(max-width:1320px)  常规笔记本（宽内容收窄）
   ★ 本轮做的两件事：
     ① 把 639px / 1023px 两处「差 1px」的写法归一为 640 / 1024。
        它们本意是同一个断点，却让同一条规则被拆到两条 @media 里，
        维护时要同时改两处、漏一处就出现「差 1px 的死区」。
     ② 其余 720/760/860/900/940/960/1100/1439 是各模块为自身内容
        各自挑的折点（如某表格在第 N 列挤不下时换行），属**局部微调**，
        不是全局断点，本轮**不动** —— 强行合并会让那些模块的布局在不该
        换行的地方换行。新增样式请优先用上面三档；确需局部折点时，
        在该规则处写一行注释说明「为什么这里不能用全局断点」。 */
*{box-sizing:border-box;margin:0;padding:0}
html{font-size:var(--fs-lg)}
body{
  font-family:var(--font-sans);font-size:var(--fs-md);line-height:1.57;color:var(--c-g900);
  background:var(--c-bg);-webkit-font-smoothing:antialiased;
}
/* 窄屏兜底：固定定位的侧栏抽屉与不可压缩内容不应撑出横向滚动条 */
html,body{max-width:100%;overflow-x:clip}
button,input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}
a{color:var(--c-primary);text-decoration:none}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-thumb{background:var(--c-g300);border-radius:var(--r-xs)}
::-webkit-scrollbar-thumb:hover{background:var(--c-g500)}
::-webkit-scrollbar-track{background:transparent}
.mono{font-family:var(--font-num);font-variant-numeric:tabular-nums}
.muted{color:var(--c-g500)}
.small{font-size:var(--fs-sm)}
.tiny{font-size:var(--fs-xs)}
.mt4{margin-top:var(--sp-1)}.mt8{margin-top:var(--sp-2)}.mt12{margin-top:var(--sp-3)}.mt16{margin-top:var(--sp-4)}
/* ★ 类名即像素值：这是本套工具类的命名契约（.gap4=4px/.mt8=8px 全线成立）。
   但 .mb* 家族历史上是唯一例外 —— 它们停留在旧刻度（7/10/13/18），
   未随新刻度（4/8/12/16/24）迁移，于是类名与渲染值长期不符：
     .mb8  给 7px（差 1）  .mb12 给 10px（差 2）
     .mb16 给 13px（差 3） .mb24 给 18px（差 6）
   共波及 298 处调用。旧值 7/10/13/18 **恰好仍存在于新刻度里**
   （--sp-3q/--sp-2h/--sp-6q/--sp-4h），所以既不会报错也不会显眼，
   只是一直「悄悄少几个像素」—— 卡片贴得比作者本意更紧。
   现按命名契约修正为类名对应的刻度值，视觉差异为 1-3px 的间距放宽。 */
.mt24{margin-top:var(--sp-6)}.mb4{margin-bottom:var(--sp-1)}.mb8{margin-bottom:var(--sp-2)}
.mb12{margin-bottom:var(--sp-3)}.mb16{margin-bottom:var(--sp-4)}.mb24{margin-bottom:var(--sp-6)}
/* v37：间距工具类补齐到刻度全覆盖 —— 原只有 19 个（4/8/12/16/24 等粗档），
   而 JS 里有 106 处内联间距，高频值 14px/6px/10px/11px 在类里**取不到**，
   于是只能写内联 style。这是「工具类覆盖不全 → 逼出内联样式」的典型链条：
   不是开发者不愿意用类，是类里没有他要的那个值。
   补齐后同一档位既有类也有令牌，新代码没有理由再写内联间距。
   ★ 命名沿用数字后缀（即 px 数值），与既有 .mt4/.gap10 一致，
     不改成 --sp-* 的名字 —— 类名要能一眼看出像素值，改名字反而难查。 */
.mt2{margin-top:var(--sp-0h)}.mt6{margin-top:var(--sp-1h)}.mt10{margin-top:var(--sp-2h)}
.mt14{margin-top:var(--sp-3h)}.mt18{margin-top:var(--sp-4h)}.mt20{margin-top:var(--sp-5)}
.mb2{margin-bottom:var(--sp-0h)}.mb6{margin-bottom:var(--sp-1h)}.mb10{margin-bottom:var(--sp-2h)}
.mb14{margin-bottom:var(--sp-3h)}.mb18{margin-bottom:var(--sp-4h)}.mb20{margin-bottom:var(--sp-5)}
/* .mb0 = 显式清零（0 不属刻度，单独一条）。用途：警告条要贴住下方内容时
   中和 .alert 自带的下外边距，比内联 style="margin-bottom:0" 更短也更可查。 */
.mb0{margin-bottom:0}
.ml4{margin-left:var(--sp-1)}.ml6{margin-left:var(--sp-1h)}.ml8{margin-left:var(--sp-2)}
.ml10{margin-left:var(--sp-2h)}.ml12{margin-left:var(--sp-3)}
.mr4{margin-right:var(--sp-1)}.mr6{margin-right:var(--sp-1h)}.mr8{margin-right:var(--sp-2)}
.mr10{margin-right:var(--sp-2h)}.mr12{margin-right:var(--sp-3)}
.pt4{padding-top:var(--sp-1)}.pt6{padding-top:var(--sp-1h)}.pt8{padding-top:var(--sp-2)}
.pt10{padding-top:var(--sp-2h)}.pt12{padding-top:var(--sp-3)}.pt14{padding-top:var(--sp-3h)}
.pb4{padding-bottom:var(--sp-1)}.pb6{padding-bottom:var(--sp-1h)}.pb8{padding-bottom:var(--sp-2)}
.pb10{padding-bottom:var(--sp-2h)}.pb12{padding-bottom:var(--sp-3)}.pb14{padding-bottom:var(--sp-3h)}
.pl8{padding-left:var(--sp-2)}.pl10{padding-left:var(--sp-2h)}.pl12{padding-left:var(--sp-3)}
.pr8{padding-right:var(--sp-2)}.pr10{padding-right:var(--sp-2h)}.pr12{padding-right:var(--sp-3)}
.tar{text-align:right}.tac{text-align:center}
/* v37：补齐两个**被广泛使用却从未定义**的对齐类。
   ★ 怎么发现的：给 visual_baseline.py 做「用了但没定义」的死类扫描时
     报出 .tc 用了 6 次、.tr 用了 1 次，而 CSS 里搜不到任何定义 ——
     浏览器不会报错，只是**静默按默认值渲染**（左对齐）。
     实测位置：analytics 的评分表，数值列（曝光/互动/转化…）本意居中、
     阅读量列本意右对齐，实际全部左对齐，表格看起来「数字歪着」。
   ★ 为什么是新增而不是把 JS 里的类名改成 .tar/.tac：
     同类名 .tc 在 6 处、.tr 在 1 处，且 .tac/.tar 也在用 —— 两种写法并存
     是历史遗留。改 JS 要动 7 处且以后新人仍可能写 .tc；在 CSS 里给
     这三个短名做成**等价的别名**，一次解决、且两种写法以后都生效。
     别名不引入第二套样式，只是把同一份声明挂到多个选择器上。 */
.tc,.tac{text-align:center}
.tr,.tar{text-align:right}
.hide{display:none!important}
.flex{display:flex}.fcol{flex-direction:column}.fwrap{flex-wrap:wrap}
.aic{align-items:center}.ais{align-items:flex-start}.jcb{justify-content:space-between}
.jcc{justify-content:center}.jce{justify-content:flex-end}
.gap4{gap:var(--sp-1)}.gap6{gap:var(--sp-1h)}.gap8{gap:var(--sp-2)}.gap10{gap:var(--sp-2h)}.gap12{gap:var(--sp-3)}.gap14{gap:var(--sp-3h)}
.gap16{gap:var(--sp-4)}.gap20{gap:var(--sp-5)}
.gap2{gap:var(--sp-0h)}.gap3{gap:var(--sp-1q)}.gap5{gap:var(--sp-2q)}.gap7{gap:var(--sp-3q)}.gap9{gap:var(--sp-4q)}
.gap11{gap:var(--sp-5q)}.gap18{gap:var(--sp-4h)}.gap24{gap:var(--sp-6)}
.f1{flex:1;min-width:0}
/* v37：.min0 —— 同一次死类扫描发现，用了 22 次、CSS 里没有定义。
   ★ 语义是 min-width:0（flex 子项允许收缩到内容宽度以下，
     否则长文本会把容器撑破、省略号失效）。
   ★ 为什么值得补而不是删掉这些 class：
     22 处里 19 处写作 `class="f1 min0"`，而 .f1 本身已含 min-width:0，
     所以当前**恰好**没坏 —— 是「靠巧合正确」。
     另有 2 处（customer.js:77 / dashboard.js:77）单独写 `class="min0"`，
     那是**真的没生效**：它所在的 flex 子项仍是默认 min-width:auto。
     补上定义后，前者语义显式化、后者修正，两处都不再有隐患。
   ★ 不删 .min0 的理由：删掉就要动 22 处 JS；补一行 CSS 成本更低，
     且保留了这个意图明确的语义名（比 .f1 的隐式行为更好读）。 */
.min0{min-width:0}
.wrap{flex-wrap:wrap}
.w100{width:100%}
.ell{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pointer{cursor:pointer}
/* 字重/行高：与 .small/.tiny 同属排版微调，属「组件样式」范畴而非布局，
   故一并收敛，避免每处写 style="font-weight:600"。语义色类见下方 .c-* 一组的定义。 */
.fw6{font-weight:600}
.lh17{line-height:1.7}.lh18{line-height:1.75}
.divider{height:1px;background:var(--c-border);margin:var(--sp-6q) 0}

/* ---------------- 登录页 ---------------- */
.login-wrap{
  min-height:100vh;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(135deg,var(--c-ink) 0%,var(--c-primary) 55%,var(--c-primary-hover) 100%);
  padding:var(--sp-5);
}
.login-card{
  width:380px;background:var(--c-surface);border-radius:var(--r-xl);padding:var(--sp-15) 30px 26px;
  box-shadow:0 24px 56px rgba(0,0,0,.32);
}
.login-brand{display:flex;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-1h)}
.login-logo{
  width:44px;height:44px;border-radius:var(--r-md);background:var(--c-primary);color:var(--c-surface);
  display:flex;align-items:center;justify-content:center;font-size:var(--fs-xl);font-weight:700;flex:0 0 auto;
}
.login-title{font-size:var(--fs-2xl);font-weight:700;color:var(--c-primary);letter-spacing:-.01em}
.login-sub{font-size:var(--fs-xs);color:var(--c-g500);margin:var(--sp-0h) 0 26px 56px}
.login-tip{
  margin-top:var(--sp-4h);padding:var(--sp-5q) 13px;background:var(--c-g50);border-radius:var(--r-sm);
  font-size:var(--fs-xs);color:var(--c-g500);line-height:1.7;border-left:3px solid var(--c-primary-border);
}
.login-err{
  margin-top:var(--sp-3);padding:var(--sp-4q) 12px;background:var(--c-danger-bg);color:var(--c-danger);
  border-radius:var(--r-sm);font-size:var(--fs-sm);display:none;
}

/* ---------------- 布局骨架 ---------------- */
.layout{display:flex;min-height:100vh}
.sidebar{
  width:240px;flex:0 0 240px;background:var(--c-ink);display:flex;flex-direction:column;
  position:sticky;top:0;height:100vh;overflow-y:auto;overflow-x:hidden;
  transition:width var(--dur) var(--ease),flex-basis var(--dur) var(--ease);
}
/* 折叠态（桌面）：仅留图标 */
.layout.collapsed .sidebar{width:68px;flex-basis:68px}
.layout.collapsed .sb-name,.layout.collapsed .sb-sub,.layout.collapsed .sb-group,
.layout.collapsed .sb-role-tag,
.layout.collapsed .nav-item>span:not(.nav-ico),.layout.collapsed .nav-badge{display:none}
.layout.collapsed .sb-brand{justify-content:center;padding-left:0;padding-right:0}
.layout.collapsed .nav-item{justify-content:center;padding:0;margin:var(--sp-0h) 10px}
.layout.collapsed .sb-foot{padding:var(--sp-5q) 9px}
/* 侧栏底部：退出登录在右上角工具条（旧 .sb-logout 规则已删）；
   用户身份卡已移除（用户要求），底部只剩版本号，故 .sb-user/.sb-uname/.sb-urole 规则一并删除。 */
.sb-brand{
  padding:var(--sp-6q) 14px 12px;display:flex;align-items:center;gap:var(--sp-2h);
  border-bottom:1px solid rgba(255,255,255,.06);
}
.sb-logo{
  width:34px;height:34px;border-radius:var(--r-md);background:var(--grad-brand);color:var(--c-surface);
  display:flex;align-items:center;justify-content:center;font-weight:700;font-size:var(--fs-md);flex:0 0 auto;
  /* 阴影压在深色侧栏上，用带蓝味的半透明墨色，避免纯黑在深蓝底上发脏 */
  box-shadow:0 2px 6px rgba(9,15,26,.42),inset 0 1px 0 rgba(255,255,255,.18);
}
.sb-name{color:var(--c-surface);font-size:var(--fs-md);font-weight:600;line-height:1.25;white-space:nowrap}
.sb-sub{color:var(--c-side-text);font-size:var(--fs-2xs);margin-top:var(--sp-0q);white-space:nowrap}
.sb-group{font-size:var(--fs-2xs);letter-spacing:.09em;color:var(--c-side-group);padding:var(--sp-5q) 16px 5px;text-transform:uppercase;white-space:nowrap}
.nav-item{
  height:34px;padding:0 12px;margin:var(--sp-0q) 8px;border-radius:var(--r-md);font-size:var(--fs-sm);color:var(--c-border-strong);
  display:flex;align-items:center;gap:var(--sp-5q);cursor:pointer;transition:all var(--dur) var(--ease);user-select:none;
  position:relative;white-space:nowrap;
}
.nav-item:hover{background:rgba(255,255,255,.07);color:var(--c-surface)}
.nav-item.on{
  /* ★ 选中项从「实色主蓝块」改为「半透明白 + 内高光」：
     实色块在深侧栏上像贴了一块蓝胶布，且与顶栏主色块抢视觉；
     半透明层保留「我在这一项」的识别，同时让侧栏整体still是一片深色。 */
  background:rgba(255,255,255,.10);
  color:var(--c-surface);font-weight:500;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12),0 1px 3px rgba(0,0,0,.18);
  border:1px solid rgba(255,255,255,.10);
}
.nav-item.on::before{content:'';position:absolute;left:-9px;top:50%;transform:translateY(-50%);
  width:2.5px;height:16px;border-radius:0 var(--r-3q) var(--r-3q) 0;
  background:linear-gradient(180deg,#7FA8D8,#4C7FB5)}
.nav-ico{width:18px;text-align:center;font-size:var(--fs-md);flex:0 0 auto;opacity:.92}
.nav-badge{
  margin-left:auto;background:var(--c-danger);color:var(--c-surface);font-size:var(--fs-2xs);font-weight:600;
  border-radius:var(--r-pill);padding:var(--sp-0q) 6px;line-height:1.4;
}
.nav-item.on .nav-badge{background:rgba(255,255,255,.28)}
.sb-foot{margin-top:auto;padding:var(--sp-5q) 14px;border-top:1px solid rgba(255,255,255,.07)}
/* 侧栏底部版本号：低对比小字，随 /api/version 动态变化；折叠态隐藏防溢出 */
.sb-ver{margin-top:var(--sp-3q);font-size:var(--fs-2xs);line-height:1.35;color:var(--c-side-text);opacity:.72;letter-spacing:.3px;
  white-space:normal;overflow-wrap:anywhere}
.layout.collapsed .sb-ver{display:none}
.avatar{
  width:32px;height:32px;border-radius:50%;background:var(--grad-brand);color:var(--c-surface);
  display:flex;align-items:center;justify-content:center;font-size:var(--fs-sm);font-weight:600;flex:0 0 auto;
}
.avatar.sm{width:26px;height:26px;font-size:var(--fs-2xs)}

.main{flex:1;min-width:0;display:flex;flex-direction:column}
.topbar{
  height:54px;
  /* 顶部一道极淡的白到透明的渐变，让顶栏看起来像「浮在内容上的一层玻璃」，
     而不是一条与内容同一平面的色带 */
  background:linear-gradient(180deg,rgba(255,255,255,.92),rgba(255,255,255,.80));
  border-bottom:1px solid var(--c-hairline-strong);
  display:flex;align-items:center;padding:0 18px;gap:var(--sp-3);position:sticky;top:0;z-index:var(--z-sticky);
  backdrop-filter:var(--glass-blur) saturate(1.4);-webkit-backdrop-filter:var(--glass-blur) saturate(1.4);
}
.tb-title{font-size:var(--fs-lg);font-weight:600;color:var(--c-g900)}
.tb-path{font-size:var(--fs-xs);color:var(--c-g500);margin-top:var(--sp-0h)}
.tb-path .crumb-sep{opacity:.5;margin:0 6px}
.tb-path .crumb-home{color:var(--c-g500)}
.tb-path .crumb-cur{color:var(--c-g700);font-weight:500}
.tb-actions{margin-left:auto;display:flex;align-items:center;gap:var(--sp-2h);flex-wrap:wrap;justify-content:flex-end;min-width:0}
.content{flex:1;padding:var(--sp-4) 18px;max-width:1680px;width:100%;min-width:0;box-sizing:border-box}

/* ============================================================
   顶部工具条（用户要求：顶端放一工具条，退出登录放右上角）

   两段式：
     左 .tb-page   —— 当前页操作，由页面调 setPageActions() 登记
     右 .tb-global —— 全局入口，不随页面变化（保证退出登录位置恒定）
   位置 sticky 且紧贴 topbar 之下：滚动内容时工具条始终在手边，
   不必滚回顶部才能点「生成记录」「刷新」这类操作。
   ============================================================ */
.toolbar{
  position:sticky;top:54px;z-index:calc(var(--z-sticky) - 1);
  height:46px;display:flex;align-items:center;gap:var(--sp-2h);padding:0 18px;
  background:var(--c-surface);border-bottom:1px solid var(--c-hairline-strong);
  /* 工具条底部一层极浅投影，滚动时让「工具条压住内容」这件事可见 */
  box-shadow:0 1px 2px rgba(19,26,38,.03);
}
.tb-page{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;min-width:0;flex:1}
.tb-page-hint{font-size:var(--fs-xs);color:var(--c-g500)}
.tb-global{display:flex;align-items:center;gap:var(--sp-2h);flex:0 0 auto}
.tb-ai{display:inline-flex;align-items:center;cursor:pointer}

/* 右上角用户区（含退出登录下拉） */
.tb-me{display:flex;align-items:center;gap:var(--sp-2);height:34px;padding:0 10px 0 6px;
  border:1px solid var(--c-border);border-radius:var(--r-pill);cursor:pointer;
  transition:all var(--dur) var(--ease);background:var(--c-surface);max-width:210px}
.tb-me:hover{border-color:var(--c-border-strong);background:var(--c-surface-alt)}
.tb-me-txt{min-width:0;line-height:1.15}
.tb-me-n{font-size:var(--fs-xs);font-weight:600;color:var(--c-g800);max-width:104px}
.tb-me-r{font-size:var(--fs-2xs);color:var(--c-g500);max-width:104px}
.tb-me-caret{font-size:var(--fs-2xs);color:var(--c-g500)}

/* 用户下拉：轻量浮层（不用 .mask 遮罩，避免点一下背景就全屏变暗） */
.umenu{position:fixed;z-index:var(--z-modal);min-width:206px;padding:var(--sp-1h);
  background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-md);
  box-shadow:var(--shadow-lg)}
.umenu-head{display:flex;align-items:center;gap:var(--sp-4q);padding:var(--sp-2) 9px 9px}
.umenu-n{font-size:var(--fs-sm);font-weight:600;color:var(--c-g900)}
.umenu-r{font-size:var(--fs-2xs);color:var(--c-g500)}
.umenu-sep{height:1px;background:var(--c-border);margin:var(--sp-2q) 4px}
.umenu-i{display:flex;align-items:center;gap:var(--sp-4q);width:100%;padding:var(--sp-2) 9px;border:none;background:none;
  border-radius:var(--r-xs);cursor:pointer;font-size:var(--fs-sm);color:var(--c-g700);text-align:left;
  font-family:inherit;transition:background var(--dur) var(--ease)}
.umenu-i:hover{background:var(--c-surface-alt)}
.umenu-i.danger{color:var(--c-danger)}
.umenu-i.danger:hover{background:var(--c-danger-tint)}
.umenu-i>span:first-child{width:15px;text-align:center;flex:0 0 auto;opacity:.75}

@media (max-width:860px){
  .tb-me-txt{display:none}
  .tb-me{padding:0 6px;max-width:none}
  .toolbar{padding:0 12px;gap:var(--sp-1h)}
}
@media (max-width:640px){
  .tb-page-hint{display:none}
}

/* ---------------- 组件 ---------------- */
.btn{
  height:36px;padding:0 16px;border-radius:var(--r-sm);font-size:var(--fs-md);font-weight:500;
  border:1px solid transparent;cursor:pointer;transition:all .15s ease;
  display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-1h);white-space:nowrap;
}
.btn.pri{
  /* ★ 135° 从主色到 lift 的极短渐变（跨度仅 1 阶）：
     不是「渐变冒充立体」，而是让按钮顶面有一点点受光感。
     实色 #1E3A5F 在纯白卡上偏「死」，加这一档后按钮像有微微弧度。 */
  background:linear-gradient(180deg,var(--c-primary-lift) -140%,var(--c-primary) 62%);
  color:var(--c-surface);
  border-color:rgba(19,26,38,.10);
  box-shadow:0 1px 2px rgba(19,26,38,.10),inset 0 1px 0 rgba(255,255,255,.10);
}
.btn.pri:hover{background:var(--c-primary-hover);
  box-shadow:0 2px 6px rgba(30,58,95,.18),0 6px 16px rgba(30,58,95,.12),inset 0 1px 0 rgba(255,255,255,.10)}
.btn.pri:active{transform:translateY(1px);box-shadow:inset 0 1px 2px rgba(19,26,38,.18)}
.btn.sec{background:var(--c-surface);color:var(--c-g800);border-color:var(--c-border-strong);
  box-shadow:0 1px 1.5px rgba(19,26,38,.03)}
.btn.sec:hover{background:var(--c-surface-alt);border-color:var(--c-p5);color:var(--c-primary);
  box-shadow:0 1px 2px rgba(19,26,38,.05)}
.btn.ghost{background:transparent;color:var(--c-g700)}
.btn.ghost:hover{background:var(--c-g100);color:var(--c-primary)}
/* ── 按钮语义变体：一组语义 = 一个定义，别名在**同一选择器里**列出 ──
   ★ v33 收敛。此前这三组各写各的，且散落在文件三处（296 行、1998 行、2100 行），
     结果是同一颗「删除」按钮的 hover 有 3 份互相打架的定义
     （filter:brightness(.92) / background:--c-danger-solid / 又一遍 --c-danger-solid），
     后写的那份赢，但读代码的人无法从任意一处看出真正的终值——
     改了一处以为生效、实际被后面的覆盖，是这类碎片化最典型的坑。
   ★ 实测使用频次（全前端 grep）：pri 165 / sec 103 / ghost 66 /
     dan 58 · danger 60 · del 29（三者同义，共 147）/ acc 30 · ok 248（同义，共 278）。
     调用点合计数百处，逐个改名风险大且无收益 —— 所以这里做的是
     「**保留全部别名、但让它们指向同一份声明**」：
       · 危险：.dan / .danger / .del
       · 强调：.acc / .ok
     新增调用点无论用哪套词都必得同一视觉；将来若要统一命名，
     只需删选择器里的别名，不必动任何调用点。 */
.btn.dan,
.btn.danger,
.btn.del{background:var(--c-danger);color:var(--c-surface);border-color:var(--c-danger)}
.btn.dan:hover,
.btn.danger:hover,
.btn.del:hover{background:var(--c-danger-solid);border-color:var(--c-danger-solid)}
.btn.dan:disabled,
.btn.danger:disabled,
.btn.del:disabled{opacity:.55;cursor:not-allowed}
.btn.acc,
.btn.ok{background:var(--c-accent);color:var(--c-surface);border-color:var(--c-accent)}
.btn.acc:hover,
.btn.ok:hover{background:var(--c-teal);border-color:var(--c-teal)}
.btn.sm{height:30px;padding:0 12px;font-size:var(--fs-sm);border-radius:var(--r-xs)}
.btn.xs{height:26px;padding:0 9px;font-size:var(--fs-xs);border-radius:var(--r-xs);gap:var(--sp-1)}
.btn.lg{height:42px;padding:0 22px;font-size:var(--fs-md)}
.btn:disabled{opacity:.5;cursor:not-allowed}
.btn.block{width:100%}
/* ★ v4.0.6：所有按钮一律不折行、不压缩。
   踩过的坑（截图实测）：作品库表格操作列里「➤ 发布」被挤成两行
   —— 按钮是 flex 容器里的 flex item，默认 min-width:auto 允许它被压到
   内容的最小宽度以下，中文就逐字折行，看起来像"两个按钮叠在一起"。
   这类问题不会报错、接口也正常，只能靠截图才看得见。 */
.btn{white-space:nowrap;flex-shrink:0}

.card{
  background:var(--c-surface);
  /* ★ 极轻的纵向渐变（纯白 → #FDFDFE）不是装饰：纯色平涂在大面积白卡上
     会显得「平」，2% 的明度过渡能让卡面像一张有厚度的纸。肉眼几乎察觉不到
     色差，但整页的「质感」差别明显。 */
  background-image:var(--sheen-subtle);
  border:1px solid var(--c-border);
  border-radius:var(--r-lg);padding:var(--sp-3h) 16px;
  box-shadow:var(--shadow-card);
  transition:box-shadow var(--dur) var(--ease),border-color var(--dur) var(--ease),transform var(--dur) var(--ease);
}
.card:hover{box-shadow:var(--shadow-card-hover);border-color:var(--c-border-strong)}
.card.tight{padding:var(--sp-5q) 13px}
.card.accent-left{position:relative;overflow:hidden}
.card.accent-left::before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--grad-teal-bar)}
.card-head{display:flex;align-items:center;justify-content:space-between;padding-bottom:var(--sp-5q);margin-bottom:var(--sp-3);
  /* ★ 卡头分隔线改用发丝级半透明线：实线 #E4E9F0 在纯白卡上偏「硬」，
     重复出现十几次后整页像表格；半透明线（5.5% 墨色）更克制。 */
  border-bottom:1px solid var(--c-hairline);gap:var(--sp-2h)}
/* ★ 卡片标题字号基线 = --fs-lg（16px）
   此前 CSS 里写的是 --fs-md，但页面里 35 处内联 style="font-size:var(--fs-lg)"
   把它顶掉了，剩下 13 处不内联的则仍是 14px —— 同一类卡片标题在页面上呈现两种字号。
   这里把「多数派的 16px」定为基线，少数派改用 .card-title.sm（紧凑卡、密集看板）。
   同时 .card-head 的 padding-bottom/margin-bottom 也一并收敛：
   原先 48 处内联 style 有 6 种取值（9px/11px/10px × 11px/12px/14px），全部清除改用类。 */
.card-title{font-size:var(--fs-lg);font-weight:600;color:var(--c-g900);display:flex;align-items:center;gap:var(--sp-3q);line-height:1.35;
  /* 中文标题在 16px/600 下略松，收 0.15px 字距能明显提升「排好的」质感 */
  letter-spacing:-.15px}
.card-title.sm{font-size:var(--fs-md)}          /* 紧凑档：指标卡、角标型小标题 */
/* ★ 极小档（2026-10-21 新增）：用于「卡片里再分小节」的场景，
     比 sm 再小一档。原来 bidding/insight 两处直接在标签上写
     style="font-size:var(--fs-sm)" —— 内联覆盖会绕过主题与响应式
     （窄屏时卡片标题本该整体降档，内联的不会跟着变），
     故收成类，统一由这里控制。 */
.card-title.xs{font-size:var(--fs-sm);margin-bottom:8px}
.card-title .sub{font-size:var(--fs-xs);font-weight:400;color:var(--c-g500)}
.card-head.roomy{padding-bottom:var(--sp-5q);margin-bottom:var(--sp-3h)}   /* 大间隔档：长图表卡 */

.stat{background:var(--c-surface);background-image:var(--sheen-subtle);border:1px solid var(--c-border);border-radius:var(--r-lg);padding:var(--sp-3) 14px;position:relative;overflow:hidden;
  box-shadow:var(--shadow-card);transition:box-shadow var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.stat:hover{box-shadow:var(--shadow-card-hover);border-color:var(--c-border-strong)}
.stat::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--c-primary)}
.stat.acc::before{background:var(--c-accent)}
.stat.suc::before{background:var(--c-success)}
.stat.warn::before{background:var(--c-warn)}
.stat .num{font:700 24px/1.2 var(--font-num);color:var(--c-primary);font-variant-numeric:tabular-nums}
.stat.acc .num{color:var(--c-accent)}
.stat .lbl{font-size:var(--fs-xs);color:var(--c-g500);margin-top:var(--sp-1q)}
.stat .delta{font-size:var(--fs-xs);margin-top:var(--sp-1q);display:flex;align-items:center;gap:var(--sp-1)}
.stat .delta.up{color:var(--c-success)}
.stat .delta.down{color:var(--c-danger)}

.input,.select,.textarea{
  height:32px;padding:0 10px;font-size:var(--fs-sm);color:var(--c-g900);background:var(--c-surface);
  border:1px solid var(--c-border-strong);border-radius:var(--r-sm);
  /* ★ 长文本必须自己截断：<input> 内部默认不折行也不省略，内容超出可视宽度时
     浏览器会让文字溢出到框外 —— 实测配图提示词（80~110 字）会把整段文字
     糊在卡片外面，看起来像"渲染坏了"。加省略号后至少框内是干净的，
     完整内容仍可通过光标进入查看。 */
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  /* ★ 1px 内阴影：在浅描边内侧加一道极淡的暗边，输入框看起来是「凹进纸面」的，
     与凸起的按钮/卡片形成方向相反的层次 —— 这是表单区精致感的关键。 */
  box-shadow:inset 0 1px 2px rgba(19,26,38,.035);
  transition:border-color .15s,box-shadow .15s,background .15s;width:100%;
}
.select{cursor:pointer;appearance:none;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path d='M2 4.5L6 8.5L10 4.5' stroke='%236B7686' stroke-width='1.5' fill='none' stroke-linecap='round'/></svg>");
  background-repeat:no-repeat;background-position:right 11px center;padding-right:var(--sp-15)}
/* textarea 是多行输入，必须恢复换行（上面 .input 的 nowrap 会连带命中它） */
.textarea{height:auto;padding:var(--sp-2) 10px;line-height:1.6;resize:vertical;min-height:76px;font-size:var(--fs-sm);
  white-space:pre-wrap;overflow:auto;text-overflow:clip}
.input:focus,.select:focus,.textarea:focus{outline:none;border-color:var(--c-primary);
  background:var(--c-surface);box-shadow:var(--ring-primary)}
.input.invalid,.select.invalid,.textarea.invalid{border-color:var(--c-danger);box-shadow:var(--ring-danger)}
.input::placeholder,.textarea::placeholder{color:var(--c-g300)}
.input:disabled,.select:disabled{background:var(--c-g50);color:var(--c-g500);cursor:not-allowed}
.field{display:flex;flex-direction:column;gap:var(--sp-2q)}
.field label{font-size:var(--fs-xs);color:var(--c-g700);font-weight:500}
.field .hint{font-size:var(--fs-xs);color:var(--c-g500);line-height:1.5}
.field.w-sm{width:180px}.field.w-md{width:240px}.field.w-lg{width:340px}
.form-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--sp-6q) 16px}
.form-grid .span2{grid-column:1/-1}

/* 多选角色组（ui.js t:'checks'） */
.chk-group{display:flex;flex-wrap:wrap;gap:var(--sp-2) 14px;padding:var(--sp-2) 12px;border:1px solid var(--c-border);border-radius:var(--r-sm);background:var(--c-surface)}
.chk{display:flex;align-items:center;gap:var(--sp-1h);cursor:pointer;font-size:var(--fs-sm);color:var(--c-g700);user-select:none}
.chk input{width:15px;height:15px;accent-color:var(--c-primary);cursor:pointer;margin:0}
.chk:hover{color:var(--c-ink)}

.badge{display:inline-flex;align-items:center;height:22px;padding:0 9px;border-radius:var(--r-xs);
  font-size:var(--fs-xs);font-weight:500;white-space:nowrap;
  /* ★ 徽章统一加 1px 同色淡描边：纯淡底无边界时，多个徽章并排会「糊」在一起；
     描边把它们各自框住，同时不增加任何重量。 */
  border:1px solid transparent;letter-spacing:.1px}
.badge.g{background:var(--c-success-bg);color:var(--c-success);border-color:rgba(33,122,75,.14)}
.badge.or{background:var(--c-warn-bg);color:var(--c-warn);border-color:rgba(183,121,31,.16)}
.badge.r{background:var(--c-danger-bg);color:var(--c-danger);border-color:rgba(179,53,47,.14)}
.badge.b{background:var(--c-info-bg);color:var(--c-info);border-color:rgba(30,92,153,.14)}
.badge.n{background:var(--c-g100);color:var(--c-g600);border-color:var(--c-hairline)}
.badge.pri{background:var(--c-p1);color:var(--c-primary);border-color:rgba(30,58,95,.13)}
.badge.acc{background:var(--c-accent-soft);color:var(--c-accent-ink);border-color:rgba(14,124,123,.14)}
/* 别名：settings.js 传 firm:'teal' */
.badge.teal{background:var(--c-teal-soft);color:var(--c-teal)}
.badge.dot::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;margin-right:var(--sp-2q)}
.badge.lg{height:26px;font-size:var(--fs-sm);padding:0 11px}

.tabs{display:flex;gap:var(--sp-0h);border-bottom:1px solid var(--c-hairline-strong);margin-bottom:var(--sp-6q);overflow-x:auto;
  scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
/* ★ 标签页：底线从实线降为发丝线（一屏常有两组 tab 叠在卡片上，实线会打架），
   选中态不再只靠一条 2px 蓝线 —— 那样在纯白卡上像「画了道斜杠」。
   现在叠加三层：同族极浅底 + 主色文字 + 底部 2px 实条，弱而清楚。 */
.tab{padding:var(--sp-3q) 15px;font-size:var(--fs-sm);color:var(--c-g500);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;
  border-radius:var(--r-xs) var(--r-xs) 0 0;
  transition:color .15s,border-color .15s,background .15s;white-space:nowrap;user-select:none;position:relative}
.tab:hover{color:var(--c-primary);background:var(--c-p0)}
.tab.on{color:var(--c-primary);border-bottom-color:var(--c-primary);font-weight:600;background:var(--c-p1)}

.grid{display:grid;gap:var(--sp-6q)}
/* 网格子项统一允许收缩：否则 1fr 轨道的 min-content 会被卡片内不可压缩内容撑破，导致窄屏横向溢出 */
.grid>*{min-width:0}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
.g5{grid-template-columns:repeat(5,1fr)}
.g6{grid-template-columns:repeat(6,1fr)}
.g2-1{grid-template-columns:2fr 1fr}
.g1-2{grid-template-columns:1fr 2fr}
.g3-2{grid-template-columns:3fr 2fr}

.tbwrap{overflow-x:auto;border-radius:var(--r-md);border:1px solid var(--c-border);background:var(--c-surface);max-width:100%;min-width:0}
.twrap{overflow-x:auto;max-width:100%;min-width:0}
table.tb{width:100%;border-collapse:collapse;font-size:var(--fs-sm);min-width:560px}
/* 窄表：放在两列卡片里的小表用。
   560px 的最小宽度是为了保证「多列宽表」在窄屏上横向滚动而不是把字挤成一列；
   但两列网格的半宽卡片只有约 430px，套用 560px 会让最后几列永远被裁掉一半，
   用户看到的是「互动率」被切成一截。窄表本来就只有 2–3 列，允许它缩到容器宽度。 */
table.tb.narrow{min-width:0}
table.tb th{
  height:34px;padding:0 11px;text-align:left;font-size:var(--fs-xs);font-weight:600;color:var(--c-g500);
  /* ★ 表头底色从 #FAFBFC 改为极浅主色（p0）：纯灰表头在蓝调页面里像「另一套色」，
     换成同族极浅蓝之后，表头与卡片、KPI 面板属于同一个色彩家族，
     整页不再是「蓝+灰拼贴」。同时表头文字上移到 g500 更深一档。 */
  background:var(--c-p0);
  border-bottom:1px solid var(--c-border);
  white-space:nowrap;position:sticky;top:0;z-index:1;
  letter-spacing:.1px;
}
table.tb td{height:36px;padding:0 11px;
  /* 行线降为发丝：真实数据表有十几行，实线会让整张表像「网格本」；
     发丝线保留分隔功能，但让行更像「排」而不是「格子」。 */
  border-bottom:1px solid var(--c-hairline);vertical-align:middle;
  color:var(--c-g800)}
table.tb tr:last-child td{border-bottom:none}
table.tb tbody tr{transition:background .12s}
table.tb tbody tr:hover{background:var(--c-p1)}
table.tb.striped tbody tr:nth-child(even){background:var(--c-g50)}
table.tb.striped tbody tr:nth-child(even):hover{background:var(--c-primary-soft)}
table.tb td.num{font-family:var(--font-num);font-variant-numeric:tabular-nums;text-align:right}
table.tb th.num{text-align:right}
/* ★ v4.0.6：加 nowrap。
   实测截图发现：作品库「操作」列里「➤ 发布」按钮与「查看/转化/删除」
   三个链接被**拆成两行**（发布在上、链接在下），整列参差不齐，
   而且每行高了 12px，一屏少看两行数据。
   原因：flex 容器默认 flex-wrap:nowrap，但三个 span.lnk 是行内元素、
   宽度按内容算，当单元格宽度不够时会**先压按钮的 min-width**，
   按钮内的中文"发布"随之折行 —— 视觉上就成了两块。
   修法：容器与按钮都禁止折行，宽度不够就让表格横向滚动（已有 .tbwrap
   overflow-x:auto 兜底）。**不要**改成缩小字号来塞进窄列：
   那样在 1280 屏上又要再缩一次，是无底洞。 */
.tb-actions{display:flex;gap:var(--sp-1h);justify-content:flex-end;
  flex-wrap:nowrap;white-space:nowrap}
.lnk{color:var(--c-primary);cursor:pointer;font-size:var(--fs-sm)}
.lnk:hover{text-decoration:underline}
.lnk.dan{color:var(--c-danger)}
/* 「待补链接」：已发布却无作品链接时的可点提示。
   与 .dan（危险/删除）区分开——这不是错误，是「此处尚缺一份信息」，
   故用提示色而非告警红，避免运营把它当成故障。 */
.lnk.warn-txt{color:var(--c-warn);font-weight:600}
.lnk.warn-txt:hover{color:var(--c-warn-solid)}

/* 数据体检的问题条目：左侧色条 + 浅底，与卡片内其他内容区分开 */
.cons-item{border-left:3px solid var(--c-border);background:var(--c-surface-alt);
  border-radius:var(--r-md);padding:var(--sp-3) 14px}
.cons-item details summary{cursor:pointer;user-select:none}
.cons-item details summary:hover{text-decoration:underline}

/* 智能优选模型折叠组件：默认不展开下拉，只显示一行「性价比最优」芯片 */
.model-picker{display:flex;flex-direction:column;gap:var(--sp-2)}
.mp-chip{display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-4q) 12px;border:1px solid var(--c-g200);
  border-radius:var(--r-md);background:var(--c-g50);cursor:default;min-height:38px}
.mp-chip .mp-name{font-size:var(--fs-md);color:var(--c-g800);font-weight:500}
.mp-tag{flex:none;font-size:var(--fs-xs);line-height:1;padding:var(--sp-1q) 7px;border-radius:var(--r-pill);
  font-weight:600;letter-spacing:.02em}
.mp-tag.rec{color:var(--c-success-solid);background:var(--c-success-soft)}
.mp-tag.manual{color:var(--c-primary);background:rgba(30,58,95,.10)}
.mp-change{margin-left:auto}

/* ★ 空态基线定义已统一到第 6 节（见「空态与加载」），此处不再重复定义。
   原 420-423 行是「极简工具风」改版前的旧值（padding 32px/18px、.ico 28px/opacity .35），
   改版时新定义写在了文件后段，旧规则因层叠顺序被整体覆盖却从未删除 ——
   同一份 .empty 在文件里存在两套互相冲突的取值，是"视觉不统一"最隐蔽的来源。
   现只保留可行动空态（.action）这一档，它需要额外的差异视觉。 */
.empty.action{padding:var(--sp-10) 18px;border:1px dashed var(--c-border-strong);border-radius:var(--r-md);background:var(--c-surface)}
.empty.action .ico{opacity:.28}

/* ── 整卡居中容器 ──────────────────────────────────────────
   用于「整块区域只放一段说明」的场景（如未开放板块的占位页）。
   ★ 为什么需要它：emptyBox 默认 padding 34px，那是给"卡片内一小块区域为空"
     设计的；当它要撑满一整张卡片时，34px 的留白会让内容显得贴在顶部。
     这里把空态在卡片内垂直居中，并给卡片一个最小高度，
     观感上才是「一个还没开放的板块」而不是「加载失败的页面」。 */
.card.center-box{min-height:420px;display:flex;align-items:center;justify-content:center}
.card.center-box .empty{padding:0}
.card.center-box .empty .d{max-width:460px;margin:0 auto}
.empty.action .d{margin-bottom:0;max-width:460px;margin-left:auto;margin-right:auto;line-height:1.7}

.pager{display:flex;align-items:center;justify-content:flex-end;gap:var(--sp-2);padding:var(--sp-2h) 4px 0;font-size:var(--fs-sm);color:var(--c-g500)}
.pager .pg{height:30px;min-width:30px;padding:0 9px;border:1px solid var(--c-border-strong);background:var(--c-surface);border-radius:var(--r-xs);cursor:pointer;font-size:var(--fs-sm)}
.pager .pg:hover:not(:disabled){border-color:var(--c-primary);color:var(--c-primary)}
.pager .pg.on{background:var(--c-primary);color:var(--c-surface);border-color:var(--c-primary)}
.pager .pg:disabled{opacity:.4;cursor:not-allowed}

.mask{position:fixed;inset:0;background:rgba(15,27,45,.45);display:flex;align-items:center;justify-content:center;z-index:var(--z-mask);animation:fade .16s ease;padding:var(--sp-5)}
.modal{background:var(--c-surface);
  /* 弹窗加一圈发丝描边：深投影之外再有一道边界，边缘才「利」，
     纯阴影在浅背景上会显得边缘糊 */
  border:1px solid var(--c-hairline-strong);
  border-radius:var(--r-lg);box-shadow:var(--shadow-xl);
  width:min(640px,92vw);max-height:90vh;display:flex;flex-direction:column;
  animation:pop .18s cubic-bezier(.16,1,.3,1)}
.modal.wide{width:min(900px,94vw)}
.modal.xwide{width:min(1140px,96vw)}
.modal-head{padding:var(--sp-6q) 18px;border-bottom:1px solid var(--c-hairline-strong);font-size:var(--fs-lg);font-weight:600;letter-spacing:-.15px;display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3)}
.modal-head .x{cursor:pointer;color:var(--c-g500);font-size:var(--fs-xl);line-height:1;padding:var(--sp-0h) 6px;border-radius:var(--r-xs)}
.modal-head .x:hover{background:var(--c-g100);color:var(--c-g900)}
.modal-body{padding:var(--sp-7q) 18px;overflow:auto;flex:1}
.modal-foot{padding:var(--sp-5q) 18px;border-top:1px solid var(--c-hairline-strong);display:flex;justify-content:flex-end;gap:var(--sp-2h);flex-wrap:wrap}
@keyframes fade{from{opacity:0}to{opacity:1}}
@keyframes pop{from{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:none}}

.toast-wrap{position:fixed;top:18px;left:50%;transform:translateX(-50%);z-index:var(--z-toast);display:flex;flex-direction:column;gap:var(--sp-4q);align-items:center;pointer-events:none}
.toast{
  background:var(--c-ink);color:var(--c-surface);padding:var(--sp-5q) 18px;border-radius:var(--r-sm);font-size:var(--fs-sm);
  box-shadow:var(--shadow-lg);animation:pop .18s ease;max-width:520px;line-height:1.5;
}
.toast.ok{background:var(--c-success-solid)}
.toast.err{background:var(--c-danger-solid)}
.toast.warn{background:var(--c-warn-solid)}
/* ★ v33：带「撤销」按钮的 toast。
   两个关键点：
   ① .toast-wrap 是 pointer-events:none（否则一层满宽浮层会挡住底下页面点击），
      所以按钮必须显式 pointer-events:auto 才点得到；
   ② 用白色半透明描边按钮 —— toast 底色是语义色（成功绿/危险红），
      文字已是白色，按钮用 rgba 白会更协调，且不必为每种底色各写一份。 */
.toast{display:flex;align-items:center;gap:var(--sp-3)}
.toast .tx{flex:1 1 auto}
.toast-act{
  flex:0 0 auto;pointer-events:auto;cursor:pointer;
  background:rgba(255,255,255,.16);color:inherit;border:1px solid rgba(255,255,255,.5);
  border-radius:var(--r-xs);padding:var(--sp-1q) 10px;font-size:var(--fs-xs);font-weight:600;
  font-family:inherit;transition:background .15s;
}
.toast-act:hover{background:rgba(255,255,255,.3)}

.alert{padding:var(--sp-4q) 12px;border-radius:var(--r-sm);font-size:var(--fs-xs);line-height:1.6;display:flex;gap:var(--sp-2);align-items:flex-start}
/* 提示条：3px 硬色块在密集页面上过于「喊」，压到 2px 竖条 +
   1px 同色描边，语义仍一眼可辨，观感收敛 */
.alert.info{background:var(--c-info-bg);color:var(--c-info-ink);border:1px solid rgba(30,92,153,.14);border-left:2px solid var(--c-info)}
.alert.warn{background:var(--c-warn-bg);color:var(--c-warn);border:1px solid rgba(183,121,31,.16);border-left:2px solid var(--c-warn)}
.alert.dan{background:var(--c-danger-bg);color:var(--c-danger);border:1px solid rgba(179,53,47,.14);border-left:2px solid var(--c-danger)}
.alert.suc{background:var(--c-success-bg);color:var(--c-success);border:1px solid rgba(33,122,75,.14);border-left:2px solid var(--c-success)}
/* ★ 别名（v33）：把「同一语义的两种写法」都接住，而不是逐个改调用点。
   现状：全站 alert 的规范变体是 info/warn/dan/suc，但有代码沿用了
   toast 的词汇（err）和按钮的词汇（pri）：
     · materials.js 同步结果用 `alert err` —— 语义是「失败」，等同 .dan
     · publish.js 形式适配提示用 `alert pri` —— 语义是「中性提示」，等同 .info
   这两处若不接住，class 匹配不上任何规则，整个标签退化成**裸文本**
   （没有背景、没有左侧色条、没有图标留白），在一屏告警里显得像漏渲染。
   所以这里按「语义等价」补两条别名，而不是去改调用点 ——
   调用点还有若干处同类写法，改调用点是 N 处、补别名是 2 行，且别名一旦
   存在，将来新写的代码无论用哪套词都能正确上色。 */
.alert.err{background:var(--c-danger-bg);color:var(--c-danger);border:1px solid rgba(179,53,47,.14);border-left:2px solid var(--c-danger)}
.alert.pri{background:var(--c-info-bg);color:var(--c-info-ink);border:1px solid rgba(30,92,153,.14);border-left:2px solid var(--c-info)}
.alert .ai{flex:0 0 auto;font-size:var(--fs-md);line-height:1.4}
/* ★ v4.5.3：`.alert.sm` 此前被 fileupload / org 两处使用，但一直没有定义，
   于是那些提示条与普通提示条一样高 —— 「紧凑档」名存实亡。
   ★ 注意 `.sm` 在别处是**组合类**（`.btn.sm` / `.avatar.sm` / `.chart.sm`），
     全局裸写 `.sm{border-left:3px solid…}` 会污染所有带 sm 的组件，
     所以这里必须连同 `.alert` 一起限定。 */
.alert.sm{padding:var(--sp-2q) 10px;font-size:var(--fs-2xs);line-height:1.5}

.chips{display:flex;flex-wrap:wrap;gap:var(--sp-3q)}
.chip{
  height:28px;padding:0 12px;border-radius:var(--r-lg);border:1px solid var(--c-border-strong);background:var(--c-surface);
  font-size:var(--fs-xs);color:var(--c-g700);cursor:pointer;display:inline-flex;align-items:center;transition:all .15s;user-select:none;
}
/* chip 选中：实色主蓝块 -> 同族浅底 + 主色描边。
   原来满屏 chip 里每选中一个就多一块深蓝，视觉重量压过了它承载的信息
   （「当前筛了哪个平台」远比「这块是蓝的」重要）。 */
.chip:hover{border-color:var(--c-p5);color:var(--c-primary);background:var(--c-p0)}
.chip.on{background:var(--c-p1);color:var(--c-primary);border-color:var(--c-primary);font-weight:500;
  box-shadow:inset 0 0 0 1px rgba(30,58,95,.10)}
.chip.bad{border-color:var(--c-danger-border);background:var(--c-danger-soft);color:var(--c-danger-ink-muted);text-decoration:line-through}

/* ---------------- 表单 / 风格 / 平台 标签 ---------------- */
.ftag,.ctag,.stag,.ptag{
  display:inline-flex;align-items:center;gap:var(--sp-1);height:23px;padding:0 9px;border-radius:var(--r-xs);
  font-size:var(--fs-xs);font-weight:600;line-height:1;white-space:nowrap;vertical-align:middle;
}
.ftag i{font-style:normal;font-size:var(--fs-2xs);font-weight:700;opacity:.75}
.fc-txt{background:var(--c-primary-tint);color:var(--c-primary)}
.fc-img{background:var(--c-accent-tint);color:var(--c-accent-ink)}
.fc-aud{background:var(--c-warn-tint);color:var(--c-warn)}   /* 2026-10：「声音」大类已移除，本类暂留作历史数据兜底 */
.fc-vid{background:var(--c-danger-tint);color:var(--c-danger)}
.ctag{background:var(--c-g100);color:var(--c-g700);font-weight:500}
.stag{background:var(--c-purple-soft);color:var(--c-purple);font-weight:500}
.st-p{background:var(--c-primary-tint);color:var(--c-primary)}
.st-c{background:var(--c-accent-tint);color:var(--c-accent-ink)}
.st-x{background:var(--c-danger-tint);color:var(--c-danger)}
.st-d{background:var(--c-warn-tint);color:var(--c-warn)}
.st-s{background:var(--c-purple-soft);color:var(--c-purple)}
.ptag{background:var(--c-surface);border:1px solid var(--c-border);color:var(--c-g700);font-weight:500;
  box-shadow:0 1px 1px rgba(19,26,38,.03)}
/* 进度条：槽底用同族极浅底（不用灰），填充为实色主色 —— 渐变在 7px 高度上
   肉眼分不出，却会让「条有多满」的判断变模糊 */
.mini-bar{height:7px;border-radius:var(--r-1);background:var(--c-p1);overflow:hidden}
.mini-bar i{display:block;height:100%;background:var(--c-primary);border-radius:var(--r-1);transition:width .4s var(--ease)}
.row-lnk{cursor:pointer;transition:background var(--dur) var(--ease)}
/* 行悬停与表格 hover 同一口径（同族极浅底），避免页面里出现两种「选中」色 */
.row-lnk:hover{background:var(--c-p0)}

/* ---------------- 形式与风格页 ---------------- */
.fc-card{border-left:3px solid var(--c-primary)}
.fc-card.fc-img{border-left-color:var(--c-accent)}
.fc-card.fc-aud{border-left-color:var(--c-warn)}
.fc-card.fc-vid{border-left-color:var(--c-danger)}
.fc-head{display:flex;gap:var(--sp-5q);align-items:center}
.fc-i{width:34px;height:34px;border-radius:var(--r-sm);background:var(--c-primary-soft);color:var(--c-primary);
  display:flex;align-items:center;justify-content:center;font-weight:700;font-size:var(--fs-md);flex:0 0 auto}
.fc-name{font-size:var(--fs-md);font-weight:700}
.fc-desc{font-size:var(--fs-2xs);color:var(--c-g500);margin-top:var(--sp-0h);line-height:1.4}
.fc-num{margin-top:var(--sp-3);padding-top:var(--sp-2h);border-top:1px solid var(--c-border);font-size:var(--fs-xs);color:var(--c-g600)}
.fc-num b{font-size:var(--fs-xl);color:var(--c-primary);margin-right:var(--sp-1q)}
.form-list{max-height:520px;overflow-y:auto}
.form-row{display:flex;gap:var(--sp-3);align-items:center;padding:var(--sp-2h) 11px;border-radius:var(--r-sm);cursor:pointer;
  border:1px solid transparent}
.form-row:hover{background:var(--c-g50)}
.form-row.on{background:var(--c-primary-soft);border-color:var(--c-primary-border)}
.fr-name{margin-bottom:var(--sp-1q)}
.fr-plats{display:flex;gap:var(--sp-1);flex-wrap:wrap;justify-content:flex-end;max-width:230px}
.conv-list{display:flex;flex-direction:column;gap:var(--sp-2)}
.conv-row{display:flex;gap:var(--sp-4q);align-items:center;padding:var(--sp-2) 10px;background:var(--c-g50);border-radius:var(--r-sm);
  font-size:var(--fs-xs)}
.conv-arrow{color:var(--c-g400);font-weight:700}
.tb.matrix td,.tb.matrix th{text-align:center}
.tb.matrix td:first-child,.tb.matrix th:first-child{text-align:left}
.dot-on{color:var(--c-accent);font-size:var(--fs-sm)}
.dot-off{color:var(--c-border)}
.style-card{border:1px solid var(--c-border);border-radius:var(--r-sm);padding:var(--sp-3)}
.sc-desc{font-size:var(--fs-xs);color:var(--c-g700);margin:var(--sp-4q) 0 6px;line-height:1.55}
.sc-hint{line-height:1.5;margin-bottom:var(--sp-2)}
.sc-n{padding-top:var(--sp-2);border-top:1px dashed var(--c-border)}

/* ---------------- 律所 vs 律师 ---------------- */
.org-hero{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4);background:
  linear-gradient(135deg,var(--c-primary) 0%,var(--c-primary) 60%,var(--c-primary) 100%);border-radius:var(--r-lg);padding:var(--sp-4h) 20px;color:var(--c-surface)}
.org-badge{display:inline-block;background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.28);
  border-radius:var(--r-lg);padding:var(--sp-1q) 11px;font-size:var(--fs-2xs);margin-bottom:var(--sp-2)}
.org-hero h2{margin:0 0 6px;font-size:var(--fs-xl);letter-spacing:.3px}
.org-hero p{margin:0;font-size:var(--fs-xs);line-height:1.6;color:rgba(255,255,255,.82)}
.org-kpi{display:flex;gap:var(--sp-4h);flex-wrap:wrap;margin-top:var(--sp-6q)}
.org-kpi>div{display:flex;flex-direction:column;gap:var(--sp-0h)}
.org-kpi b{font-size:var(--fs-xl);font-family:var(--font-num)}
.org-kpi span{font-size:var(--fs-2xs);color:rgba(255,255,255,.68)}
.org-assets{display:flex;gap:var(--sp-4);margin-top:var(--sp-3);padding-top:var(--sp-5q);border-top:1px solid rgba(255,255,255,.16);
  font-size:var(--fs-xs);color:rgba(255,255,255,.8)}
.org-vs{background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.14);border-radius:var(--r-md);padding:var(--sp-3)}
.vs-title{font-size:var(--fs-xs);color:rgba(255,255,255,.7);margin-bottom:var(--sp-4q);letter-spacing:.5px}
.vs-row{padding:var(--sp-1h) 0;border-bottom:1px dashed rgba(255,255,255,.13);font-size:var(--fs-xs);line-height:1.5}
.vs-row:last-child{border-bottom:none}
.vs-dim{color:rgba(255,255,255,.55);font-size:var(--fs-2xs);margin-bottom:var(--sp-1)}
.vs-org,.vs-law{display:flex;gap:var(--sp-3q);align-items:flex-start;margin-top:var(--sp-1q);color:rgba(255,255,255,.9)}
.vs-law{color:rgba(255,255,255,.75)}
.vs-org i,.vs-law i{font-style:normal;flex:0 0 auto;font-size:var(--fs-2xs);border-radius:var(--r-1);padding:var(--sp-0q) 5px;
  background:rgba(255,255,255,.18)}
.vs-law i{background:rgba(255,255,255,.1)}
.kpi-row{display:flex;gap:var(--sp-2h);flex-wrap:wrap}
/* KPI 小面板：p0 底 + 发丝描边 + 顶部 1px 内高光，
   让每个指标成为「从卡面微微凸起的一小块」，而不是空白的灰格子 */
.kpi{flex:1;min-width:110px;
  /* ★ 从纯灰块改为「主色同族极浅底 + 发丝描边」：
     灰底 #F7F9FB 与卡片白只差 3%，六个 KPI 并排时像没填色的空格子；
     换成 p0(#F7F9FC) + 描边后，每个指标成为一块独立的小面板。 */
  background:var(--c-p0);border:1px solid var(--c-hairline);border-radius:var(--r-sm);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.7);
  padding:var(--sp-4q) 12px;transition:border-color var(--dur) var(--ease),background var(--dur) var(--ease)}
.kpi:hover{border-color:rgba(30,58,95,.14);background:var(--c-p1)}
.kpi .k{font-size:var(--fs-2xs);color:var(--c-g500);margin-bottom:var(--sp-1q)}
.kpi .v{font-size:var(--fs-xl);font-weight:700;font-family:var(--font-num);color:var(--c-primary)}
/* 别名子类：评分页等使用 .kpi-l/.kpi-v/.kpi-s（补齐，原先无样式退化为裸文本） */
.kpi .kpi-l{font-size:var(--fs-2xs);color:var(--c-g600);margin-bottom:var(--sp-1q);letter-spacing:.1px}
.kpi .kpi-v{font-size:var(--fs-xl);font-weight:700;font-family:var(--font-num),var(--font-num);color:var(--c-primary);line-height:1.25;
  letter-spacing:-.3px}
.kpi .kpi-s{font-size:var(--fs-2xs);color:var(--c-g500);margin-top:var(--sp-0h);line-height:1.5}

/* ---------------- 客户端（律师视角） ---------------- */
.client-layout .sidebar{background:var(--grad-side)}
.client-layout .sb-logo{background:linear-gradient(135deg,var(--c-teal-light),var(--c-teal))}
.client-layout .nav-item.on{background:rgba(18,165,148,.178);color:var(--c-surface)}
.client-layout .nav-item.on::before{background:var(--c-teal-light)}
.sb-role-tag{margin:0 12px 10px;padding:var(--sp-3q) 10px;border-radius:var(--r-xs);background:rgba(255,255,255,.07);
  border:1px solid rgba(255,255,255,.12);font-size:var(--fs-2xs);color:rgba(255,255,255,.7);line-height:1.5}
.sb-role-tag span{color:var(--c-teal-bright);font-weight:600}
/* （原 .tb-client-badge 已删除：顶栏统一为工具条后不再有独立客户徽标） */

.cl-hero{background:var(--grad-client);border-radius:var(--r-xl);
  padding:var(--sp-6) 26px;color:var(--c-surface);margin-bottom:var(--sp-3h);position:relative;overflow:hidden}
.cl-hero::after{content:'';position:absolute;right:-60px;top:-60px;width:280px;height:280px;border-radius:50%;
  background:rgba(255,255,255,.08)}
.cl-hero.compact{padding:var(--sp-5) 24px}
/* 含策动力主视觉时：横幅切为左右两列（右侧给策动力） */
.cl-hero.has-ce{display:grid;grid-template-columns:1fr auto;gap:var(--sp-5h);align-items:center}
.cl-hero-main{min-width:0}
.ce-hero-slot{display:none}
.ce-hero-slot.on{display:block}
.cl-hero-tag{display:inline-block;background:rgba(255,255,255,.2);border-radius:var(--r-lg);padding:var(--sp-1q) 12px;
  font-size:var(--fs-2xs);margin-bottom:var(--sp-4q)}
.cl-hero h1{margin:0 0 8px;font-size:var(--fs-3xl);letter-spacing:.4px;line-height:1.3;font-weight:700}
.cl-hero h1 em{font-style:normal;font-size:var(--fs-3xl);text-shadow:0 2px 14px rgba(0,0,0,.16)}
.cl-hero p{margin:0 0 15px;font-size:var(--fs-sm);line-height:1.65;color:rgba(255,255,255,.88);max-width:600px}
.cl-hero .btn{background:var(--c-surface);color:var(--c-teal);border:none;font-weight:700}
.cl-hero .btn:hover{background:var(--c-teal-tint-soft)}
.cl-kpi{display:grid;grid-template-columns:repeat(5,1fr);gap:var(--sp-5q)}
.cl-kpi-card{background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-lg);padding:var(--sp-6q) 15px;
  box-shadow:var(--shadow-xs)}
.ck-i{font-size:var(--fs-lg);margin-bottom:var(--sp-1h)}
.ck-v{font-size:var(--fs-2xl);font-weight:700;font-family:var(--font-num);color:var(--c-g900);line-height:1.15}
.ck-l{font-size:var(--fs-xs);color:var(--c-g500);margin-top:var(--sp-1q)}
.cl-plat{padding:var(--sp-2) 0;border-bottom:1px dashed var(--c-border)}
.cl-plat:last-child{border-bottom:none}
.cl-bar{height:9px;border-radius:var(--r-xs);background:var(--c-g100);overflow:hidden}
.cl-bar i{display:block;height:100%;border-radius:var(--r-xs);background:var(--grad-teal-bar)}
.cl-days{display:flex;gap:var(--sp-4q);align-items:flex-end;height:180px;padding:var(--sp-2h) 0}
.cl-day{flex:1;display:flex;flex-direction:column;align-items:center;gap:var(--sp-2q);height:100%;justify-content:flex-end}
.cd-v{font-size:var(--fs-2xs);font-family:var(--font-num);color:var(--c-g500)}
.cd-bar{flex:1;width:100%;display:flex;align-items:flex-end;max-width:64px;margin:0 auto}
.cd-bar i{width:100%;max-width:48px;margin:0 auto;background:linear-gradient(180deg,var(--c-teal-bright),var(--c-teal));border-radius:var(--r-1) var(--r-1) 0 0;min-height:6px}
.cl-days{align-items:flex-end}
.cd-d{font-size:var(--fs-2xs);color:var(--c-g500)}
.cl-flow{display:flex;align-items:center;gap:0;flex-wrap:wrap}
.cl-flow-node{flex:1;min-width:150px;text-align:center;padding:var(--sp-4q) 8px}
.cf-dot{width:26px;height:26px;border-radius:50%;background:var(--c-g100);color:var(--c-g500);margin:0 auto 6px;
  display:flex;align-items:center;justify-content:center;font-weight:700;font-size:var(--fs-sm)}
.cl-flow-node.done .cf-dot{background:var(--c-teal-light);color:var(--c-surface)}
.cf-t{font-size:var(--fs-sm);font-weight:600;margin-bottom:var(--sp-1q)}
.cl-flow-line{flex:0 0 26px;height:2px;background:var(--c-g300);margin-bottom:var(--sp-6h)}
.cl-steps{padding:var(--sp-8q) 19px}
.cl-step-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-3h)}
.cl-step b{display:flex;width:24px;height:24px;border-radius:50%;background:var(--c-teal-light);color:var(--c-surface);
  align-items:center;justify-content:center;font-size:var(--fs-sm);margin-bottom:var(--sp-3q)}
.cl-step h3{margin:0 0 4px;font-size:var(--fs-sm)}
.cl-step p{margin:0;font-size:var(--fs-xs);color:var(--c-g500);line-height:1.55}

/* ---------------- 形象赋能 / 形象审核 ---------------- */
.im-home{background:linear-gradient(135deg,var(--c-accent-tint) 0%,var(--c-teal-wash-deep) 100%);border:1px solid var(--c-teal-soft)}
.im-hero{background:var(--grad-client)}
.im-top{display:flex;align-items:center;gap:var(--sp-6);flex-wrap:wrap}
.im-top-mid{flex:1;min-width:260px}
.im-top-right{display:flex;gap:var(--sp-2h);flex-wrap:wrap}
.im-stat{background:var(--c-g50);border-radius:var(--r-lg);padding:var(--sp-2) 12px;display:flex;align-items:center;gap:var(--sp-4q);
  font-size:var(--fs-md);font-weight:700}
.im-cat-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-4q)}
.im-cat-card{border:1px dashed var(--c-border-strong);border-radius:var(--r-md);padding:var(--sp-2h) 9px;cursor:pointer;
  transition:all var(--dur) var(--ease);text-align:center;background:var(--c-surface)}
.im-cat-card:hover{border-color:var(--c-teal-light);box-shadow:var(--shadow-sm);transform:translateY(-1px)}
.im-cat-card.ok{border-style:solid;border-color:var(--c-teal-soft);background:var(--c-teal-tint)}
.im-cc-i{font-size:var(--fs-lg);color:var(--c-teal-light);margin-bottom:var(--sp-2q)}
.im-cc-l{font-size:var(--fs-sm);font-weight:600}
.im-cc-s{margin-top:var(--sp-0h)}
.im-mini{display:flex;flex-wrap:wrap;gap:var(--sp-1h)}
.im-list{display:flex;flex-direction:column}
.im-item{display:flex;gap:var(--sp-3);align-items:flex-start;padding:var(--sp-2h) 0;border-bottom:1px dashed var(--c-border)}
.im-item:last-child{border-bottom:none}
.im-thumb{width:64px;height:64px;border-radius:var(--r-md);overflow:hidden;flex:0 0 64px;background:var(--c-teal-tint);
  display:flex;align-items:center;justify-content:center}
.im-thumb img{width:100%;height:100%;object-fit:cover}
.im-ph{font-size:var(--fs-2xl);font-weight:700;color:var(--c-teal)}
.im-t{font-weight:600;display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.im-body{margin-top:var(--sp-1);max-width:640px}
.im-acts{display:flex;gap:var(--sp-3);flex:0 0 auto;padding-top:var(--sp-0h)}
.ell2{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.im-upload{border:1px dashed var(--c-border-strong);border-radius:var(--r-md);min-height:112px;cursor:pointer;
  display:flex;align-items:center;justify-content:center;overflow:hidden;background:var(--c-g50);
  transition:border-color var(--dur) var(--ease)}
.im-upload:hover{border-color:var(--c-teal-light)}
.im-upload img{max-width:100%;max-height:240px;object-fit:contain}
.im-up-ph{text-align:center;font-size:var(--fs-sm);color:var(--c-g500);line-height:1.8}

/* 创作工坊 · 两步流程条（整理素材 → 制作内容）
   ★ 2026-10 第六次重构：替换原来的「两段并列选择器」(.st-seg/.st-seg-b)。
     为什么换成流程条：
       旧的两段是「内容创作 / 内容管理」—— 平级、等宽、都在争注意力，
       用户看不出谁先谁后，也看不出「管理」其实不属于产线。
       流程条用「序号 + 箭头」把先后写进视觉里，当前步实心高亮、
       已走过的步打勾变浅，用户永远知道"我在第几步、还剩几步"。
     为什么不用更大的卡片：步骤条是**路标**不是**内容**，
       它应该低于表单的视觉权重。细长一条即可，不抢表单的注意力。 */
.st-flow{display:flex;align-items:stretch;gap:0}
.st-flow-s{flex:1;min-width:0;display:flex;align-items:center;gap:var(--sp-2h);
  padding:var(--sp-2h) 14px;border:1px solid var(--c-border);border-radius:var(--r-md);
  background:var(--c-surface);cursor:pointer;
  transition:border-color var(--dur) var(--ease),background var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
.st-flow-s:hover{border-color:var(--c-border-strong);background:var(--c-surface-alt)}
.st-flow-n{flex:0 0 auto;width:22px;height:22px;border-radius:50%;display:flex;
  align-items:center;justify-content:center;font-size:var(--fs-2xs);font-weight:700;
  background:var(--c-g100);color:var(--c-g600);transition:all var(--dur) var(--ease)}
.st-flow-tx{min-width:0;display:flex;flex-direction:column;gap:var(--sp-0h)}
.st-flow-tx b{font-size:var(--fs-md);color:var(--c-g700);line-height:1.3}
.st-flow-tx span{font-size:var(--fs-2xs);color:var(--c-g500);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 当前步：主色描边 + 浅底 + 序号实心，视觉重量明显高于另一步 */
/* ★ 当前步：从「1px 主色实描边」改为「极浅描边 + 同族浅底 + 内环」。
   实描边在浅色页面里像一根深色方框把这条压成「选中框」，与整页的克制口径冲突；
   现在把它压到位阶体系里：底色用 p0/p1 同族阶表达「这里是当前」，
   描边降到 p5 的半透明，再叠一圈 1px 内环补足边界 —— 弱而清楚。 */
.st-flow-s.on{border-color:rgba(30,58,95,.22);background:var(--c-p0);
  box-shadow:inset 0 0 0 1px rgba(30,58,95,.07),var(--shadow-xs)}
.st-flow-s.on .st-flow-n{background:var(--c-primary);color:var(--c-on-dark)}
.st-flow-s.on .st-flow-tx b{color:var(--c-primary)}
/* 已完成的步：序号变对勾、整体降权，暗示"这步不用再管了" */
.st-flow-s.done{border-color:var(--c-border-strong);background:var(--c-surface-alt)}
.st-flow-s.done .st-flow-n{background:var(--c-teal-wash);color:var(--c-teal-700)}
.st-flow-s.done .st-flow-tx b{color:var(--c-g600)}
/* ★ v4.0.6：箭头原是 --c-g300(#C7CEDA)，压在步骤条的浅底上实算 1.35:1 ——
   几乎看不见，而箭头恰恰是这条流程条**唯一的"先后"信号**：
   序号只说明"第几步"，箭头才说明"往哪走"。看不见它，流程条就退化成
   三个并排的方框，等于把重构的立意抹掉了。
   改用 --c-g600：它是装饰性符号（非文字），按 WCAG 非文本对比度 3:1 要求取。
   ★ 不用 --c-g500 的原因：g500 是"次要文字"的语义位，被全站 600+ 处引用，
     将来若再调整文字层级会连带动到这个箭头；装饰件用自己的档更稳。 */
.st-flow-arw{flex:0 0 auto;display:flex;align-items:center;padding:0 10px;
  color:var(--c-g600);font-size:var(--fs-md);user-select:none}
/* 窄屏：箭头转竖排、说明文字收起，只留「① 整理素材 → ② 制作内容」 */
@media (max-width:760px){
  .st-flow-arw{padding:0 5px}
  .st-flow-tx span{display:none}
  .st-flow-s{padding:var(--sp-4q) 11px;gap:var(--sp-3q)}
}
/* 工坊三 tab 行：列数按实际标签数自适应（继承 .up-tabs 外观）。
   ★ .up-tabs 原本写死 grid-template-columns:1fr 1fr（上传页两选一用），
     工坊这里是三个 tab，故用本类覆盖为 auto-fit。 */
.st-tabs3{grid-template-columns:repeat(auto-fit,minmax(0,1fr))}

/* 创作工坊 · 表单分组头
   ★ 为什么用「左竖线 + 组号」而不是再套一层卡片：
     卡片套卡片会让表单看起来更深、更重、更"满"—— 与本次「简化」的诉求相反。
     竖线的语义是"这几项属于一组"，但视觉上不额外增加一层容器边界。
   ★ 为什么组号是圆圈而不是裸数字：裸数字像"第 N 题"（六道题的感觉），
     圆圈更像"第 N 阶段"。同一件事，读起来轻得多。 */
.grp-h{display:flex;align-items:center;gap:var(--sp-4q);margin:0 0 9px;padding-left:var(--sp-0h)}
.grp-h::before{content:'';flex:0 0 3px;align-self:stretch;border-radius:var(--r-2q);
  background:var(--c-primary);opacity:.75}
.grp-n{flex:0 0 auto;width:19px;height:19px;border-radius:50%;display:flex;
  align-items:center;justify-content:center;font-size:var(--fs-2xs);font-weight:700;
  background:var(--c-primary-tint);color:var(--c-primary)}
.grp-tx{min-width:0;display:flex;align-items:baseline;gap:var(--sp-2);flex-wrap:wrap}
.grp-tx b{font-size:var(--fs-md);color:var(--c-g800)}
.grp-tx span{font-size:var(--fs-2xs);color:var(--c-g500)}
/* 组内分隔（同一卡片里切换子话题时用，比再开一张卡轻） */
.grp-sub{height:1px;background:var(--c-border);margin:var(--sp-3h) 0 12px}
/* 分组内的字段小标签 */
.fld-lb{display:block;font-size:var(--fs-xs);font-weight:600;color:var(--c-g700);margin-bottom:var(--sp-3q)}
.fld-lb.nomb{margin-bottom:0}
.fld-lb .sub{font-weight:400;color:var(--c-g500);margin-left:var(--sp-1)}

/* 创作工坊 · 文案脚本「产出可用性」提示
   ★ 存在的理由：用户明确要求「这个文案一定要具有可实用性」。
     把"能直接拿去干什么"写在按钮正上方 —— 这是用户按下按钮前最后一眼
     看到的东西，比藏在帮助里有效得多。
   ★ 用中性底色而非告警色：它是说明，不是警告。 */
.st-usable{background:var(--c-teal-wash);border:1px solid var(--c-teal-light);
  border-radius:var(--r-md);padding:var(--sp-5q) 13px}
.su-h{display:flex;align-items:center;gap:var(--sp-3q);font-size:var(--fs-sm);
  font-weight:600;color:var(--c-teal-700);margin-bottom:var(--sp-3q)}
.su-i{flex:0 0 auto;font-size:var(--fs-2xs)}
.su-l{margin:0;padding-left:var(--sp-8q);display:flex;flex-direction:column;gap:var(--sp-2q)}
.su-l li{font-size:var(--fs-xs);color:var(--c-g700);line-height:1.65}
.su-l b{color:var(--c-g800)}

/* 客户 360 · 形象材料就地审核动作 */
.c360-im-acts{display:flex;gap:var(--sp-1h);flex:0 0 auto}

/* 漏斗（横向） */
.funnel{display:flex;flex-direction:column;gap:var(--sp-4q)}
.fn-row{display:flex;align-items:center;gap:var(--sp-2h)}
.fn-l{flex:0 0 82px;font-size:var(--fs-xs);color:var(--c-g700)}
.fn-b{flex:1;height:11px;border-radius:var(--r-xs);background:var(--c-g100);overflow:hidden}
.fn-b i{display:block;height:100%;border-radius:var(--r-xs);transition:width .4s var(--ease)}
.fn-v{flex:0 0 66px;text-align:right;font-family:var(--font-num);font-size:var(--fs-sm);font-weight:600}

/* 环形进度 */
.ring{position:relative;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}
.ring .rv{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}
.ring .rv .n{font-size:var(--fs-xl);font-weight:700;font-family:var(--font-num);line-height:1}
.ring .rv .l{font-size:var(--fs-2xs);color:var(--c-g500);margin-top:var(--sp-1q)}

/* 上传页 */
.up-wrap{max-width:940px;margin:0 auto}
.up-head{text-align:center;margin-bottom:var(--sp-4)}
.up-head h2{margin:0 0 6px;font-size:var(--fs-2xl)}
.up-head p{margin:0 auto;font-size:var(--fs-sm);color:var(--c-g600);line-height:1.6;max-width:600px}
.up-tabs{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-2h);margin-bottom:var(--sp-3h)}
.up-tab{border:1.5px solid var(--c-border);border-radius:var(--r-md);padding:var(--sp-5q) 14px;cursor:pointer;transition:all .16s}
.up-tab b{display:block;font-size:var(--fs-sm);margin-bottom:var(--sp-1q)}
.up-tab span{font-size:var(--fs-xs);color:var(--c-g500)}
.up-tab.on{border-color:var(--c-teal-light);background:var(--c-teal-wash)}
/* 体检口径维护的三个标签 —— 复用 up-tab 外观，但列数按实际标签数量给。
   ★ 为什么单独开一个类而不是改 .up-tabs 的列数：
     上传页那两个标签是「二选一」的并列关系，用 1fr 1fr 摊满整行是对的；
     口径维护是三个平级页签，若沿用 2 列会折成「2 + 1」，第三项孤零零占半行。
     后写的规则覆盖，故 .gs-tabs 放在 .up-tabs 之后即可生效。 */
.gs-tabs{grid-template-columns:repeat(3,1fr);gap:var(--sp-2);margin-bottom:0}
.gs-tabs .up-tab{padding:var(--sp-2) 12px}
.gs-tabs .up-tab b{margin-bottom:0}
.up-know-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-3)}
.up-know-i{display:flex;gap:var(--sp-5q);align-items:flex-start}
.uki{width:30px;height:30px;border-radius:var(--r-sm);background:var(--c-accent-tint);color:var(--c-accent-ink);flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;font-size:var(--fs-md)}
.up-know-i b{font-size:var(--fs-sm);display:block;margin-bottom:var(--sp-1q)}
.up-done{text-align:center;padding:var(--sp-2) 0}
.ud-i{width:48px;height:48px;border-radius:50%;background:var(--c-accent-tint);color:var(--c-accent-ink);font-size:var(--fs-2xl);
  display:flex;align-items:center;justify-content:center;margin:0 auto 11px}
.up-done h3{margin:0 0 6px;font-size:var(--fs-lg)}
.up-done p{margin:0 0 13px;font-size:var(--fs-sm);color:var(--c-g600)}
.ud-steps{display:flex;align-items:center;justify-content:center;gap:var(--sp-2);flex-wrap:wrap;margin-bottom:var(--sp-3h);
  font-size:var(--fs-xs);color:var(--c-g500)}
.ud-steps span{padding:var(--sp-1) 10px;border-radius:var(--r-lg);background:var(--c-g50)}
.ud-steps span.on{background:var(--c-accent-tint);color:var(--c-accent-ink);font-weight:600}
.ud-steps i{color:var(--c-g300);font-style:normal}

.work-card{padding:var(--sp-6q) 16px}
.wc-head{display:flex;gap:var(--sp-4h);align-items:flex-start;flex-wrap:wrap}
.wc-title{font-size:var(--fs-md);font-weight:600}
.wc-kpi{display:flex;gap:var(--sp-5)}
.wc-kpi>div{text-align:right}
.wc-kpi b{display:block;font-size:var(--fs-lg);font-family:var(--font-num);color:var(--c-accent)}
.wc-kpi span{font-size:var(--fs-2xs);color:var(--c-g500)}
.wc-channels{display:flex;gap:var(--sp-4q);flex-wrap:wrap;margin-top:var(--sp-5q);padding-top:var(--sp-2h);border-top:1px solid var(--c-border)}
.wc-ch{display:flex;align-items:center;gap:var(--sp-1h);background:var(--c-g50);border-radius:var(--r-sm);padding:var(--sp-2q) 10px;font-size:var(--fs-xs)}
.wc-ch-v{font-weight:700;font-family:var(--font-num);color:var(--c-g900)}

/* 赋能科普页 */
.how-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-6q);margin-bottom:var(--sp-3h)}
.how-card{background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-lg);padding:var(--sp-7q) 17px}
.how-n{display:block;font-size:var(--fs-xl);color:var(--c-teal-bright);margin-bottom:var(--sp-1h);font-weight:700}
.how-card h3{margin:0 0 6px;font-size:var(--fs-md)}
.how-card p{margin:0;font-size:var(--fs-xs);color:var(--c-g600);line-height:1.62}
.faq-i{padding:var(--sp-5q) 0;border-bottom:1px dashed var(--c-border)}
.faq-i:last-child{border-bottom:none}
.faq-q{font-size:var(--fs-sm);font-weight:600;margin-bottom:var(--sp-2q);color:var(--c-primary)}
.faq-a{font-size:var(--fs-sm);color:var(--c-g600);line-height:1.65}

/* 数据分析 - 平台维度 */
.heat-c{font-size:var(--fs-xs);font-family:var(--font-num);transition:all .15s}
.tb.heat td{padding:var(--sp-4q) 10px}
.news-item{padding:var(--sp-2h) 0;border-bottom:1px dashed var(--c-border)}
.news-item:last-child{border-bottom:none}
.ni-head{display:flex;justify-content:space-between;align-items:center;gap:var(--sp-3h);margin-bottom:var(--sp-3q);font-size:var(--fs-sm)}
.ni-sites{display:flex;gap:var(--sp-2h);flex-wrap:wrap}
.ni-site{display:flex;align-items:center;gap:var(--sp-2q);background:var(--c-g50);border-radius:var(--r-xs);padding:var(--sp-2q) 9px;font-size:var(--fs-xs)}
/* ── 空态尺寸档 ──────────────────────────────────────────────
   ★ 两档语义（本次收敛后只保留这两个，不存在第三种）：
     .empty        默认档：独立占位的空态（整卡为空、整表无数据）
     .empty.sm     紧凑档：内嵌小块的空态（卡片内某个列表为空），只留一行说明

   ★ 为什么别名写法必须写进选择器组：
     实测页面里 `.empty small` 有 34 处、`.empty sm` 有 35 处，两种写法混用。
     而 CSS 此前只写了 `.empty.sm` —— 那 34 处 `.empty small` 全部不命中，
     在界面上拿到的仍是默认档的大尺寸，视觉上「有的空态很大、有的很小」，
     但源码里两处看起来几乎一样，肉眼根本查不出来。
     现把 `.small` 并入同一组选择器：两种写法等价，存量页面无需逐个改造。

   ★ 旧别名 .empty-i/.empty-t/.empty-s 已删除：全站实测引用数为 0，
     属改版遗留死代码（保留只会让后来者误以为还有人在用）。 */
.empty.sm,.empty.small{padding:var(--sp-4) 0}
.empty.sm .ico,.empty.sm .d,.empty.small .ico,.empty.small .d{display:none}
.empty.sm .t,.empty.small .t{font-size:var(--fs-sm)}

.row-lnk td:first-child{position:relative}

.pill-list{display:flex;flex-direction:column;gap:var(--sp-2)}
.pill{display:flex;gap:var(--sp-2h);align-items:flex-start;padding:var(--sp-2h) 12px;background:var(--c-g50);border-radius:var(--r-sm);font-size:var(--fs-sm);line-height:1.55}
.pill .pi{flex:0 0 auto;font-size:var(--fs-md)}

/* 周历 */
.week{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--sp-2)}
.wday{background:var(--c-surface-alt);border:1px solid var(--c-border);border-radius:var(--r-md);min-height:150px;display:flex;flex-direction:column;overflow:hidden}
.wday.today{border-color:var(--c-primary);box-shadow:0 0 0 2px rgba(30,58,95,.08)}
.wday-h{padding:var(--sp-1h) 9px;border-bottom:1px solid var(--c-border);display:flex;align-items:center;justify-content:space-between;background:var(--c-surface)}
.wday-h .d{font-size:var(--fs-xs);font-weight:600}
.wday-h .w{font-size:var(--fs-2xs);color:var(--c-g500)}
.wday-h.today .d{color:var(--c-primary)}
.wday-body{padding:var(--sp-3q);display:flex;flex-direction:column;gap:var(--sp-2q);flex:1;overflow-y:auto;max-height:300px}
.wplan{background:var(--c-surface);border:1px solid var(--c-border);border-left:3px solid var(--c-primary);border-radius:var(--r-xs);padding:var(--sp-1h) 8px;font-size:var(--fs-xs);cursor:pointer;transition:all .14s}
.wplan:hover{box-shadow:var(--shadow-sm);transform:translateY(-1px)}
.wplan.k-直播{border-left-color:var(--c-danger)}
.wplan.k-拍视频{border-left-color:var(--c-info)}
.wplan.k-写图文{border-left-color:var(--c-accent)}
.wplan.k-选题策划{border-left-color:var(--c-warn)}
.wplan.k-复盘分析{border-left-color:var(--c-g500)}
.wplan .t{font-weight:600;font-size:var(--fs-xs);line-height:1.35;margin-bottom:var(--sp-1q)}
.wplan .m{color:var(--c-g500);display:flex;flex-wrap:wrap;gap:var(--sp-1h);font-size:var(--fs-2xs)}
.wplan.done{opacity:.62}
.wday-add{margin:0 8px 8px;height:26px;border:1px dashed var(--c-border-strong);background:transparent;border-radius:var(--r-xs);color:var(--c-g500);font-size:var(--fs-xs);cursor:pointer}
.wday-add:hover{border-color:var(--c-primary);color:var(--c-primary);background:var(--c-surface)}

/* 内容工作台 */
.workbench{display:grid;grid-template-columns:340px 1fr;gap:var(--sp-3h);align-items:start}
.mat-item{display:block;border:1px solid var(--c-border);border-radius:var(--r-sm);padding:var(--sp-4q) 11px;cursor:pointer;transition:all .14s;background:var(--c-surface);margin-bottom:var(--sp-3q)}
.mat-item:hover{border-color:var(--c-primary-border);box-shadow:var(--shadow-sm)}
.mat-item.on{border-color:var(--c-primary);background:var(--c-primary-soft);box-shadow:0 0 0 2px rgba(30,58,95,.08)}
.mat-item .t{font-size:var(--fs-sm);font-weight:600;margin-bottom:var(--sp-2q);display:flex;justify-content:space-between;gap:var(--sp-2);align-items:center}
.mat-item .m{font-size:var(--fs-xs);color:var(--c-g500);line-height:1.55}
.mat-item .score{font-family:var(--font-num);font-size:var(--fs-xs);font-weight:700;color:var(--c-accent-ink);background:var(--c-accent-soft);padding:var(--sp-0q) 7px;border-radius:var(--r-xs);flex:0 0 auto}
.article{font-size:var(--fs-md);line-height:1.7;color:var(--c-g900);white-space:pre-wrap;word-break:break-word;max-height:520px;overflow-y:auto;padding:var(--sp-1)}
.article-box{background:var(--c-surface-warm);border:1px solid var(--c-border);border-radius:var(--r-md);padding:var(--sp-4) 18px;min-height:280px}
.comp-item{display:flex;gap:var(--sp-4q);padding:var(--sp-4q) 11px;border-radius:var(--r-sm);margin-bottom:var(--sp-3q);font-size:var(--fs-sm);line-height:1.55;align-items:flex-start}
.comp-item.高{background:var(--c-danger-bg);border-left:3px solid var(--c-danger)}
.comp-item.中{background:var(--c-warn-bg);border-left:3px solid var(--c-warn)}
.comp-item .cn{font-weight:600;flex:0 0 auto}
.comp-item .cm{font-family:var(--font-num);background:rgba(0,0,0,.05);padding:var(--sp-0q) 5px;border-radius:var(--r-1);font-size:var(--fs-xs)}

/* 扫码 */
.qr-box{width:190px;height:190px;border:1px solid var(--c-border);border-radius:var(--r-md);display:flex;align-items:center;justify-content:center;background:var(--c-surface);padding:var(--sp-2h)}
.qr-box img{width:100%;height:100%;object-fit:contain}
.site-card{border:1px solid var(--c-border);border-radius:var(--r-md);padding:var(--sp-6q);background:var(--c-surface);box-shadow:var(--shadow-xs)}
.site-card .sn{font-size:var(--fs-md);font-weight:600;margin-bottom:var(--sp-1q)}
.site-card .su{font-size:var(--fs-xs);color:var(--c-g500);word-break:break-all;margin-bottom:var(--sp-4q)}

/* 图表 */
.chart{width:100%;height:200px;display:block}
.chart.sm{height:158px}
.legend{display:flex;flex-wrap:wrap;gap:var(--sp-2h);font-size:var(--fs-xs);color:var(--c-g700);margin-top:var(--sp-2)}
.legend i{width:9px;height:9px;border-radius:var(--r-2q);display:inline-block;margin-right:var(--sp-2q)}
.bar-row{display:flex;align-items:center;gap:var(--sp-4q);margin-bottom:var(--sp-3q);font-size:var(--fs-xs)}
.bar-row .bl{width:104px;flex:0 0 auto;color:var(--c-g700);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bar-row .bt{flex:1;height:9px;background:var(--c-g100);border-radius:var(--r-xs);overflow:hidden}
.bar-row .bf{height:100%;background:var(--c-primary);border-radius:var(--r-xs);transition:width .4s}
.bar-row .bv{width:64px;flex:0 0 auto;text-align:right;font-family:var(--font-num);font-size:var(--fs-xs);color:var(--c-g700)}

/* 评分环 */
.ring{position:relative;width:112px;height:112px;flex:0 0 auto}
.ring svg{transform:rotate(-90deg)}
.ring .rv{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}
.ring .rv .n{font:700 var(--fs-2xl)/1 var(--font-num);color:var(--c-primary)}
.ring .rv .l{font-size:var(--fs-2xs);color:var(--c-g500);margin-top:var(--sp-1q)}

.diag-item{display:flex;align-items:center;gap:var(--sp-5q);padding:var(--sp-4q) 0;border-bottom:1px solid var(--c-border);font-size:var(--fs-sm)}
.diag-item:last-child{border-bottom:none}
.diag-item .dn{width:104px;flex:0 0 auto;color:var(--c-g700)}
.diag-item .dv{width:96px;flex:0 0 auto;font-family:var(--font-num);text-align:right;color:var(--c-g900);font-weight:500}
.diag-item .dt{flex:1;height:7px;background:var(--c-g100);border-radius:var(--r-1);overflow:hidden}
.diag-item .df{height:100%;border-radius:var(--r-1)}

.rule-item{display:flex;gap:var(--sp-2h);padding:var(--sp-2h) 0;border-bottom:1px solid var(--c-border);font-size:var(--fs-xs);line-height:1.55}
.rule-item:last-child{border-bottom:none}
.rule-no{width:22px;height:22px;border-radius:50%;background:var(--c-primary-soft);color:var(--c-primary);font-size:var(--fs-2xs);font-weight:700;display:flex;align-items:center;justify-content:center;flex:0 0 auto;margin-top:var(--sp-0q)}

.member-card{border:1px solid var(--c-border);border-radius:var(--r-md);padding:var(--sp-6q);background:var(--c-surface);box-shadow:var(--shadow-xs);transition:all .16s}
.member-card:hover{box-shadow:var(--shadow-sm);transform:translateY(-2px)}
.member-card .mh{display:flex;gap:var(--sp-5q);align-items:center;margin-bottom:var(--sp-4q)}
.member-card .ma{width:38px;height:38px;border-radius:50%;background:var(--c-primary);color:var(--c-surface);display:flex;align-items:center;justify-content:center;font-size:var(--fs-md);font-weight:600;flex:0 0 auto}
.member-card .mn{font-size:var(--fs-md);font-weight:600}
.member-card .mt2{font-size:var(--fs-xs);color:var(--c-g500)}
.member-card .mspec{display:flex;flex-wrap:wrap;gap:var(--sp-2q);margin-bottom:var(--sp-4q)}
.member-card .mstat{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-3q);padding-top:var(--sp-4q);border-top:1px solid var(--c-border);text-align:center}
.member-card .mstat .v{font:600 var(--fs-lg)/1.3 var(--font-num);color:var(--c-primary)}
.member-card .mstat .k{font-size:var(--fs-2xs);color:var(--c-g500);margin-top:var(--sp-0h)}

/* 键值对（统一定义：兼容 <span class="k">/<span class="v"> 与裸 <span>/<b> 两种写法） */
.kv{display:flex;justify-content:space-between;align-items:center;gap:var(--sp-3);padding:var(--sp-1h) 0;
  border-bottom:1px dashed var(--c-border);font-size:var(--fs-xs)}
.kv:last-child{border-bottom:none}
.kv .k,.kv>span{color:var(--c-g500);font-size:var(--fs-xs)}
.kv .v,.kv>b{font-weight:500;font-family:var(--font-num)}
/* 别名：settings.js / aihub.js 使用 .kv-list（作为 .kv 的容器，原先无样式） */
.kv-list{display:block}
.kv-list>.kv:last-child{border-bottom:none}
/* 别名：aihub.js 使用 .bar 作为 .bar-row 的进度条容器 */
.bar{flex:1;height:9px;background:var(--c-g100);border-radius:var(--r-xs);overflow:hidden}
.bar>i,.bar>span{display:block;height:100%;background:var(--c-primary);border-radius:var(--r-xs);transition:width .4s}

.spin{display:inline-block;width:15px;height:15px;border:2px solid var(--c-g300);border-top-color:var(--c-primary);border-radius:50%;animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.loading{display:flex;align-items:center;justify-content:center;gap:var(--sp-2h);padding:var(--sp-8);color:var(--c-g500);font-size:var(--fs-sm)}

.skeleton{background:linear-gradient(90deg,var(--c-g100) 25%,var(--c-g100) 50%,var(--c-g100) 75%);background-size:200% 100%;animation:sk 1.3s infinite;border-radius:var(--r-xs)}
@keyframes sk{0%{background-position:200% 0}100%{background-position:-200% 0}}

/* 响应式 */
@media(max-width:1439px){
  .g6{grid-template-columns:repeat(4,1fr)}
  .g5{grid-template-columns:repeat(4,1fr)}
}
@media(max-width:1024px){
  .g4{grid-template-columns:repeat(3,1fr)}
  .g6{grid-template-columns:repeat(3,1fr)}
  .workbench{grid-template-columns:260px 1fr}
}
@media(max-width:1024px){
  .sidebar{position:fixed;left:0;top:0;z-index:var(--z-modal);transform:translateX(-100%);transition:transform .2s}
  .sidebar.open{transform:none;box-shadow:0 0 40px rgba(0,0,0,.3)}
  .g3,.g4,.g5,.g6{grid-template-columns:repeat(2,1fr)}
  .g2-1,.g1-2,.g3-2{grid-template-columns:1fr}
  .workbench{grid-template-columns:1fr}
  .content{padding:var(--sp-6q)}
  .week{grid-template-columns:repeat(2,1fr)}
  .menu-btn{display:inline-flex!important}
  .form-grid{grid-template-columns:1fr}
}
@media(max-width:640px){
  .g2,.g3,.g4,.g5,.g6{grid-template-columns:1fr}
  .week{grid-template-columns:1fr}
  .stat .num{font-size:var(--fs-2xl)}
  .content{padding:var(--sp-2h)}
  .topbar{padding:0 12px;gap:var(--sp-4q)}
  .tb-path{display:none}
  .modal,.modal.wide,.modal.xwide{width:100%;max-height:94vh;border-radius:var(--r-lg)}
  .mask{padding:0;align-items:flex-end}
  .article{font-size:var(--fs-md)}
}
.menu-btn{display:none;width:34px;height:34px;border:1px solid var(--c-border-strong);background:var(--c-surface);border-radius:var(--r-sm);cursor:pointer;align-items:center;justify-content:center;font-size:var(--fs-lg);flex:0 0 auto}

/* ============================================================
   AI 中枢 / 插件中心 · 扩展样式（V1.1 智能版）
   ============================================================ */

/* ---- AI 状态徽标 ---- */
.ai-dot{display:inline-flex;align-items:center;gap:var(--sp-2q);font-size:var(--fs-xs);color:var(--c-g500);
  padding:var(--sp-1q) 9px;border-radius:var(--r-pill);background:var(--c-g50);border:1px solid var(--c-border)}
.ai-dot i{width:7px;height:7px;border-radius:50%;background:var(--c-success);flex:0 0 auto;
  box-shadow:0 0 0 3px rgba(33,122,75,.14)}
.ai-dot.off i{background:var(--c-g300);box-shadow:0 0 0 3px rgba(107,118,134,.12)}
.ai-dot.busy i{background:var(--c-warn);animation:ai-pulse 1s infinite}
@keyframes ai-pulse{0%,100%{opacity:1}50%{opacity:.35}}

/* ---- AI 输出面板 ---- */
.ai-out{background:linear-gradient(180deg,var(--c-info-wash),var(--c-surface));border:1px solid var(--c-primary-border);
  border-radius:var(--r-md);padding:var(--sp-3) 14px;font-size:var(--fs-sm);line-height:1.7;color:var(--c-g900);
  white-space:pre-wrap;word-break:break-word;max-height:460px;overflow:auto}
.ai-out h1,.ai-out h2,.ai-out h3{font-size:var(--fs-md);margin:var(--sp-2h) 0 5px;color:var(--c-primary)}
.ai-out strong{color:var(--c-primary)}
.ai-out code{font-family:var(--font-num);background:var(--c-g100);padding:var(--sp-0q) 5px;border-radius:var(--r-1);font-size:var(--fs-xs)}
.ai-out .md-li{display:block;padding-left:var(--sp-0h)}
.ai-meta{display:flex;gap:var(--sp-2);align-items:center;flex-wrap:wrap;margin-bottom:var(--sp-3);
  padding-bottom:var(--sp-2h);border-bottom:1px dashed var(--c-border)}
.ai-tag{font-size:var(--fs-2xs);padding:var(--sp-0h) 8px;border-radius:var(--r-pill);background:var(--c-primary-soft);
  color:var(--c-primary);border:1px solid var(--c-primary-border)}
.ai-tag.gray{background:var(--c-g50);color:var(--c-g500);border-color:var(--c-border)}
.ai-tag.warn{background:var(--c-warn-bg);color:var(--c-warn);border-color:var(--c-warn-solid-deep)}

/* ---- 流式生成：思考态 + 正文头 ---- */
/* ★ 为什么需要「思考态」而不是一个转圈：
   线上主用的推理模型（豆包 doubao-seed-2-1-lite）要先思考 40 秒以上才
   吐第一个正文字。只放一个转圈，运营看到的是「点了没反应」——
   这正是「降低卡顿、增强反馈」要消除的体感。这里如实显示已等待秒数，
   并给一个「停止」出口，把「黑箱等待」变成「可观察、可中断」。 */
.ai-think{display:flex;align-items:flex-start;gap:var(--sp-2h);padding:var(--sp-3h) 16px;
  border:1px dashed var(--c-primary-border);border-radius:var(--r-md);
  background:var(--c-primary-tint);font-size:var(--fs-sm)}
.ai-think .spin{flex:none;margin-top:var(--sp-0h)}
.ai-think b{display:block;margin-bottom:var(--sp-1q);color:var(--c-primary)}
.ai-think .f1{min-width:0}
.ai-live-head{display:flex;gap:var(--sp-2);align-items:center;flex-wrap:wrap;margin-bottom:var(--sp-2h);
  padding-bottom:var(--sp-4q);border-bottom:1px dashed var(--c-border);min-height:20px}
/* 正文逐字增长时不要因为行数变化而抖动 */
.ai-out{min-height:24px}

/* ---- AI 快捷动作条 ---- */
.ai-actions{display:flex;gap:var(--sp-2);flex-wrap:wrap}
.ai-chip{cursor:pointer;font-size:var(--fs-xs);padding:var(--sp-1h) 12px;border-radius:var(--r-pill);
  border:1px solid var(--c-primary-border);background:var(--c-primary-soft);color:var(--c-primary);
  transition:all .15s}
.ai-chip:hover{background:var(--c-primary);color:var(--c-surface);border-color:var(--c-primary)}

/* ---- 浮动 AI 助手 ---- */
.ai-fab{position:fixed;right:24px;bottom:24px;z-index:900;width:52px;height:52px;border-radius:var(--r-xl);
  background:linear-gradient(140deg,var(--c-primary),var(--c-primary));color:var(--c-surface);border:none;cursor:pointer;
  box-shadow:var(--shadow-lg);display:flex;align-items:center;justify-content:center;font-size:var(--fs-2xl);
  transition:transform .18s,box-shadow .18s}
.ai-fab:hover{transform:translateY(-2px);box-shadow:0 16px 38px rgba(30,58,95,.3)}
.ai-fab::after{content:'AI';position:absolute;bottom:-6px;right:-4px;font-size:var(--fs-2xs);font-weight:700;
  background:var(--c-accent);padding:var(--sp-0q) 5px;border-radius:var(--r-pill);letter-spacing:.5px}
.ai-panel{position:fixed;right:20px;bottom:80px;z-index:901;width:430px;max-width:calc(100vw - 32px);
  max-height:70vh;background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-xl);
  box-shadow:0 24px 64px rgba(15,27,45,.22);display:flex;flex-direction:column;overflow:hidden}
.ai-panel.hide{display:none}
.ai-panel-head{padding:var(--sp-5q) 14px;border-bottom:1px solid var(--c-border);display:flex;
  align-items:center;gap:var(--sp-2h);background:var(--c-surface-alt)}
.ai-panel-head b{font-size:var(--fs-sm);color:var(--c-primary)}
.ai-panel-body{flex:1;overflow:auto;padding:var(--sp-3) 14px;display:flex;flex-direction:column;gap:var(--sp-4q)}
.ai-panel-foot{padding:var(--sp-5q) 14px;border-top:1px solid var(--c-border);display:flex;gap:var(--sp-2);
  align-items:flex-end;background:var(--c-surface-alt)}
.ai-panel-foot textarea{flex:1;min-height:40px;max-height:110px;resize:none;font-size:var(--fs-sm);
  border:1px solid var(--c-border-strong);border-radius:var(--r-sm);padding:var(--sp-4q) 11px;font-family:inherit}
.ai-msg{max-width:88%;padding:var(--sp-4q) 13px;border-radius:var(--r-lg);font-size:var(--fs-sm);line-height:1.7;
  white-space:pre-wrap;word-break:break-word}
.ai-msg.u{align-self:flex-end;background:var(--c-primary);color:var(--c-surface);border-bottom-right-radius:4px}
.ai-msg.a{align-self:flex-start;background:var(--c-g50);border:1px solid var(--c-border);
  border-bottom-left-radius:4px;color:var(--c-g900)}
.ai-msg.sys{align-self:center;background:var(--c-warn-bg);color:var(--c-warn);font-size:var(--fs-xs);
  text-align:center;max-width:100%}

/* ---- 场景选择 ---- */
.ai-scene-bar{display:flex;gap:var(--sp-1h);overflow-x:auto;padding-bottom:var(--sp-0h);margin-bottom:var(--sp-4q)}
.ai-scene{cursor:pointer;white-space:nowrap;font-size:var(--fs-xs);padding:var(--sp-1) 10px;border-radius:var(--r-pill);
  border:1px solid var(--c-border);background:var(--c-surface);color:var(--c-g700)}
.ai-scene.on{background:var(--c-primary);color:var(--c-surface);border-color:var(--c-primary)}

/* ---- 插件卡片 ---- */
.plug-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:var(--sp-3)}
.plug-card{border:1px solid var(--c-border);border-radius:var(--r-lg);padding:var(--sp-3);background:var(--c-surface);
  display:flex;flex-direction:column;gap:var(--sp-2);transition:border-color .16s,box-shadow .16s}
.plug-card:hover{border-color:var(--c-p5);box-shadow:var(--shadow-card-hover)}
.plug-card.on{border-color:var(--c-accent);background:var(--c-accent-tint);
  box-shadow:var(--shadow-card),inset 0 0 0 1px rgba(14,124,123,.10)}
.plug-top{display:flex;align-items:flex-start;gap:var(--sp-5q)}
.plug-ico{width:38px;height:38px;border-radius:var(--r-md);background:var(--c-primary-soft);color:var(--c-primary);
  display:flex;align-items:center;justify-content:center;font-size:var(--fs-xl);flex:0 0 auto}
.plug-card.on .plug-ico{background:var(--c-accent-soft);color:var(--c-accent-ink)}
.plug-name{font-weight:600;font-size:var(--fs-sm);color:var(--c-g900);line-height:1.4}
.plug-vendor{font-size:var(--fs-2xs);color:var(--c-g500);margin-top:var(--sp-0h)}
.plug-desc{font-size:var(--fs-xs);color:var(--c-g700);line-height:1.65;flex:1}
.plug-foot{display:flex;gap:var(--sp-3q);align-items:center;padding-top:var(--sp-4q);border-top:1px dashed var(--c-border)}

/* 开关 */
.switch{position:relative;width:42px;height:23px;border-radius:var(--r-pill);background:var(--c-g300);
  cursor:pointer;transition:background .18s;flex:0 0 auto;border:none}
.switch::after{content:'';position:absolute;top:2.5px;left:2.5px;width:18px;height:18px;border-radius:50%;
  background:var(--c-surface);transition:transform .18s;
  box-shadow:0 1px 2px rgba(19,26,38,.18),0 2px 6px rgba(19,26,38,.10)}
.switch.on{background:var(--c-accent)}
.switch.on::after{transform:translateX(19px)}

/* ---- 执行步骤时间线 ---- */
.steps{display:flex;flex-direction:column;gap:0}
.step{display:flex;gap:var(--sp-5q);padding:var(--sp-4q) 0;position:relative}
.step:not(:last-child)::before{content:'';position:absolute;left:8px;top:26px;bottom:-4px;
  width:1.5px;background:var(--c-border)}
.step-dot{width:17px;height:17px;border-radius:50%;flex:0 0 auto;margin-top:var(--sp-0h);z-index:1;
  display:flex;align-items:center;justify-content:center;font-size:var(--fs-2xs);color:var(--c-surface);
  background:var(--c-success);border:2px solid var(--c-surface);box-shadow:0 0 0 1.5px var(--c-success)}
.step.warn .step-dot{background:var(--c-warn);box-shadow:0 0 0 1.5px var(--c-warn)}
.step.fail .step-dot{background:var(--c-danger);box-shadow:0 0 0 1.5px var(--c-danger)}
.step-body{flex:1;min-width:0}
.step-name{font-size:var(--fs-sm);font-weight:500;color:var(--c-g900)}
.step-detail{font-size:var(--fs-xs);color:var(--c-g500);margin-top:var(--sp-0h);line-height:1.6}
.step-time{font-size:var(--fs-2xs);color:var(--c-g300);font-family:var(--font-num);flex:0 0 auto}

/* ---- 用量迷你图 ---- */
.usage-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:var(--sp-5q)}
.usage-card{border:1px solid var(--c-border);border-radius:var(--r-md);padding:var(--sp-5q);background:var(--c-surface-alt)}
.usage-card .lbl{font-size:var(--fs-2xs);color:var(--c-g500);margin-bottom:var(--sp-1q)}
.usage-card .val{font-size:var(--fs-xl);font-weight:700;color:var(--c-primary);font-family:var(--font-num)}
.usage-card .val small{font-size:var(--fs-2xs);font-weight:400;color:var(--c-g500);margin-left:var(--sp-1q)}
.spark{display:flex;align-items:flex-end;gap:var(--sp-0h);height:38px;margin-top:var(--sp-2)}
.spark i{flex:1;background:var(--c-primary-soft);border-radius:var(--r-2q) var(--r-2q) 0 0;min-height:2px;
  transition:background .15s}
.spark i:hover{background:var(--c-primary)}

/* ---- 分类标签 tab ---- */
.cat-tabs{display:flex;gap:var(--sp-1h);flex-wrap:wrap;margin-bottom:var(--sp-3)}
.cat-tab{cursor:pointer;font-size:var(--fs-xs);padding:var(--sp-2q) 12px;border-radius:var(--r-sm);
  border:1px solid var(--c-border);background:var(--c-surface);color:var(--c-g700)}
.cat-tab.on{background:var(--c-primary);color:var(--c-surface);border-color:var(--c-primary)}

@media(max-width:640px){
  .ai-panel{right:8px;left:8px;width:auto;bottom:80px;max-height:64vh}
  .ai-fab{right:14px;bottom:14px;width:48px;height:48px;font-size:var(--fs-xl)}
  .plug-grid{grid-template-columns:1fr}
}

/* ============================================================
   品牌首页（未登录）+ 双入口登录
   ============================================================ */
.bh{min-height:100vh;background:linear-gradient(180deg,var(--c-page-wash) 0%,var(--c-primary-tint) 42%,var(--c-page-wash) 100%);
  color:var(--c-g900);padding-bottom:0}
.bh-nav{display:flex;align-items:center;justify-content:space-between;padding:var(--sp-4h) 46px;
  max-width:1320px;margin:0 auto;gap:var(--sp-4h);flex-wrap:wrap}
.bh-logo{display:flex;align-items:center;gap:var(--sp-5q)}
.bh-mark{width:38px;height:38px;border-radius:var(--r-md);background:linear-gradient(135deg,var(--c-primary),var(--c-primary-lift));
  color:var(--c-surface);display:flex;align-items:center;justify-content:center;font-size:var(--fs-xl);font-weight:700}
.bh-logo b{display:block;font-size:var(--fs-lg);letter-spacing:.5px}
.bh-logo i{display:block;font-style:normal;font-size:var(--fs-2xs);color:var(--c-g500);letter-spacing:1.4px}
.bh-nav-r{display:flex;align-items:center;gap:var(--sp-2h);flex-wrap:wrap}
.bh-org{font-size:var(--fs-xs);color:var(--c-g500);margin-right:var(--sp-1h)}

.bh-hero{display:grid;grid-template-columns:1.1fr .9fr;gap:var(--sp-25);align-items:center;
  max-width:1320px;margin:0 auto;padding:var(--sp-28) 46px 40px}
.bh-eyebrow{font-size:var(--fs-2xs);letter-spacing:2.4px;color:var(--c-accent);font-weight:600;margin-bottom:var(--sp-4)}
.bh-hero h1{font-size:var(--fs-display);line-height:1.22;letter-spacing:-.6px;margin:0 0 20px;font-weight:700;
  color:var(--c-ink)}
.bh-hero h1 em{font-style:normal;background:linear-gradient(100deg,var(--c-primary) 10%,var(--c-teal) 90%);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.bh-lead{font-size:var(--fs-lg);line-height:1.86;color:var(--c-g600);margin:0 0 30px;max-width:620px}
.bh-cta{display:flex;gap:var(--sp-6q);flex-wrap:wrap;margin-bottom:var(--sp-5)}
.bh-trust{font-size:var(--fs-xs);color:var(--c-g500)}
.bh-hero-r{display:flex;justify-content:center}
.bh-mock{width:100%;max-width:430px;background:var(--c-surface);border-radius:var(--r-xl);box-shadow:0 22px 60px rgba(15,27,45,.16),
  0 4px 12px rgba(15,27,45,.06);overflow:hidden;border:1px solid var(--c-border)}
.bh-mock-bar{display:flex;align-items:center;gap:var(--sp-1h);padding:var(--sp-5q) 15px;background:var(--c-surface-compare);
  border-bottom:1px solid var(--c-border);font-size:var(--fs-2xs);color:var(--c-g500)}
.bh-mock-bar i{width:9px;height:9px;border-radius:50%;background:var(--c-border);display:inline-block}
.bh-mock-bar span{margin-left:var(--sp-2);letter-spacing:.4px}
.bh-mock-kpi{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3);padding:var(--sp-5) 20px 6px}
.bh-mock-kpi>div{background:linear-gradient(135deg,var(--c-primary),var(--c-primary));border-radius:var(--r-md);padding:var(--sp-3h) 15px;color:var(--c-surface)}
.bh-mock-kpi b{display:block;font-size:var(--fs-2xl);font-family:var(--font-num);letter-spacing:-.5px}
.bh-mock-kpi span{font-size:var(--fs-2xs);color:rgba(255,255,255,.72)}
.bh-mock-bars{display:flex;align-items:flex-end;gap:var(--sp-5q);height:172px;padding:var(--sp-4h) 20px 20px}
.bh-bar{flex:1;display:flex;flex-direction:column;align-items:center;height:100%;justify-content:flex-end;gap:var(--sp-3q)}
.bh-bar i{width:100%;border-radius:var(--r-xs) 6px 0 0;
  background:linear-gradient(180deg,var(--c-teal-light),var(--c-primary));display:block}
.bh-bar span{font-size:var(--fs-2xs);color:var(--c-g500)}

.bh-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-4h);max-width:1320px;margin:0 auto;
  padding:var(--sp-2) 46px 52px}
.bh-stat{background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-lg);padding:var(--sp-5) 22px;
  box-shadow:var(--shadow-xs)}
.bh-stat b{display:block;font-size:var(--fs-3xl);font-family:var(--font-num);color:var(--c-primary);letter-spacing:-1px}
.bh-stat span{display:block;font-size:var(--fs-sm);font-weight:600;margin:var(--sp-2q) 0 3px}
.bh-stat i{font-style:normal;font-size:var(--fs-2xs);color:var(--c-g500)}

.bh-caps,.bh-portals{max-width:1320px;margin:0 auto;padding:0 46px 56px;text-align:center}
.bh-caps h2,.bh-portals h2{font-size:var(--fs-3xl);letter-spacing:-.3px;margin:0 0 10px;color:var(--c-ink)}
.bh-sub{font-size:var(--fs-md);color:var(--c-g500);margin:0 0 34px}
.bh-cap-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-4h);text-align:left}
.bh-cap{background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-lg);padding:var(--sp-6) 24px;
  transition:transform .18s,box-shadow .18s}
.bh-cap:hover{transform:translateY(-3px);box-shadow:var(--shadow-md)}
.bh-cap-i{width:40px;height:40px;border-radius:var(--r-md);background:var(--c-primary-soft);color:var(--c-primary);
  display:flex;align-items:center;justify-content:center;font-size:var(--fs-xl);margin-bottom:var(--sp-3h)}
.bh-cap h3{margin:0 0 9px;font-size:var(--fs-lg)}
.bh-cap p{margin:0;font-size:var(--fs-sm);line-height:1.75;color:var(--c-g600)}

.bh-portal-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-6);text-align:left;max-width:960px;margin:0 auto}
.bh-portal{background:var(--c-surface);border:1.5px solid var(--c-border);border-radius:var(--r-xl);padding:var(--sp-15) 30px;
  transition:all .2s}
.bh-portal.admin{border-color:var(--c-primary-border)}
.bh-portal.client{border-color:var(--c-teal-border)}
.bh-portal:hover{box-shadow:var(--shadow-lg);transform:translateY(-4px)}
.bh-portal-tag{display:inline-block;font-size:var(--fs-2xs);font-weight:600;padding:var(--sp-1q) 11px;border-radius:var(--r-lg);
  margin-bottom:var(--sp-6q)}
.bh-portal.admin .bh-portal-tag{background:var(--c-primary-soft);color:var(--c-primary)}
.bh-portal.client .bh-portal-tag{background:var(--c-accent-tint);color:var(--c-accent-ink)}
.bh-portal h3{margin:0 0 11px;font-size:var(--fs-xl)}
.bh-portal-lead{font-size:var(--fs-sm);color:var(--c-g600);line-height:1.7;margin-bottom:var(--sp-4)}
.bh-portal ul{list-style:none;margin:0 0 18px;padding:0}
.bh-portal li{font-size:var(--fs-sm);color:var(--c-g700);padding:var(--sp-3q) 0 7px 20px;position:relative;line-height:1.6;
  border-bottom:1px dashed var(--c-border)}
.bh-portal li:last-child{border-bottom:none}
.bh-portal li::before{content:'✓';position:absolute;left:0;color:var(--c-teal-light);font-weight:700;font-size:var(--fs-xs)}
.bh-portal-users{font-size:var(--fs-2xs);color:var(--c-g500);margin-bottom:var(--sp-3h)}
/* ★ .btn.ok 的配色已在「组件」段与 .btn.acc 合并定义，此处删除重复声明 */

.bh-foot{display:flex;justify-content:space-between;gap:var(--sp-4);flex-wrap:wrap;max-width:1320px;margin:0 auto;
  padding:var(--sp-6) 46px;border-top:1px solid var(--c-border);font-size:var(--fs-xs);color:var(--c-g500)}

/* 登录页补充 */
.login-back{font-size:var(--fs-xs);color:var(--c-g500);cursor:pointer;margin-bottom:var(--sp-4);display:inline-block}
.login-back:hover{color:var(--c-primary)}
.login-portal{display:inline-block;font-size:var(--fs-2xs);font-weight:600;padding:var(--sp-1q) 12px;border-radius:var(--r-lg);
  margin:var(--sp-2h) 0 8px}
.login-portal.admin{background:var(--c-primary-soft);color:var(--c-primary)}
.login-portal.client{background:var(--c-accent-tint);color:var(--c-accent-ink)}

@media(max-width:1024px){
  .bh-hero{grid-template-columns:1fr;gap:var(--sp-17);padding:var(--sp-10) 26px 30px}
  .bh-hero h1{font-size:calc(var(--fs-display) - 8px)}
  .bh-hero h1 em{font-size:calc(var(--fs-display) - 6px)}
  .bh-cap-grid,.how-grid{grid-template-columns:repeat(2,1fr)}
  .bh-stats{grid-template-columns:repeat(2,1fr);padding:var(--sp-2) 26px 40px}
  .bh-caps,.bh-portals{padding:0 26px 44px}
  .bh-nav,.bh-foot{padding-left:var(--sp-6h);padding-right:var(--sp-6h)}
  .cl-kpi{grid-template-columns:repeat(3,1fr)}
  .org-hero{grid-template-columns:1fr}
  .cl-step-grid{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:640px){
  .bh-portal-grid{grid-template-columns:1fr}
  .bh-cap-grid,.up-know-grid,.how-grid{grid-template-columns:1fr}
  .bh-stats{grid-template-columns:1fr}
  .bh-hero h1{font-size:var(--fs-3xl)}
  .bh-hero h1 em{font-size:var(--fs-3xl)}
  .cl-kpi{grid-template-columns:repeat(2,1fr)}
  .cl-flow-line{display:none}
  .cl-step-grid{grid-template-columns:1fr}
  .up-tabs{grid-template-columns:1fr}
  .gs-tabs{grid-template-columns:1fr}
  .wc-kpi{gap:var(--sp-3h)}
  .bh-mock-bars{height:140px}
}

/* 输出结果框 */
.outbox{background:var(--c-surface-alt);border:1px solid var(--c-border);border-radius:var(--r-sm);
  padding:var(--sp-3) 14px;font-size:var(--fs-sm);line-height:1.72;color:var(--c-g700);white-space:pre-wrap;
  max-height:400px;overflow-y:auto;word-break:break-word}
.outbox h1,.outbox h2,.outbox h3{font-size:var(--fs-md);margin:var(--sp-4q) 0 4px;color:var(--c-primary)}
.outbox p{margin:0 0 6px}
.outbox ul{margin:0 0 6px;padding-left:var(--sp-4h)}
.badge.b{background:var(--c-info-bg);color:var(--c-info)}

/* ============ 评分与方案（ZDTC-LAS v1） ============ */
.sc-hero{display:grid;grid-template-columns:240px 1fr;gap:var(--sp-4h);background:linear-gradient(135deg,var(--c-ink),var(--c-primary) 60%,var(--c-teal));color:var(--c-surface);border:0}
.sc-hero-l{border-right:1px solid rgba(255,255,255,.14);padding-right:var(--sp-4h)}
.sc-firm-score{font-size:var(--fs-display);font-weight:700;letter-spacing:-.03em;font-family:var(--font-num);line-height:1.05;margin:var(--sp-1) 0 6px}
.sc-firm-score span{font-size:var(--fs-md);font-weight:400;opacity:.5;margin-left:var(--sp-1)}
.sc-grade{display:inline-block;padding:var(--sp-1q) 12px;border-radius:var(--r-xs);font-size:var(--fs-xs);font-weight:700;color:var(--c-surface)}
.sc-hero-r{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-2h) 16px;align-content:center}
.sc-dim-top{display:flex;justify-content:space-between;align-items:baseline;font-size:var(--fs-xs);margin-bottom:var(--sp-1)}
.sc-dim-top b{font-size:var(--fs-lg);font-family:var(--font-num)}
.sc-hero .mini-bar{background:rgba(255,255,255,.16)}
.sc-hero .sc-dim .small{font-size:var(--fs-2xs);line-height:1.3;display:block;margin-top:var(--sp-1q)}
.sc-badge{display:inline-block;min-width:22px;text-align:center;padding:var(--sp-0h) 7px;border-radius:var(--r-xs);font-size:var(--fs-xs);font-weight:700;color:var(--c-surface)}
.sc-badge.sm{font-size:var(--fs-2xs);padding:var(--sp-0q) 6px}
.sc-model{grid-template-columns:repeat(3,1fr)}
.sc-mcard{background:var(--c-surface-alt);border:1px solid var(--c-border);border-radius:var(--r-md);padding:var(--sp-5q);text-align:center}
.sc-mw{font-size:var(--fs-2xl);font-weight:700;font-family:var(--font-num);color:var(--c-primary)}
.sc-mn{font-size:var(--fs-xs);font-weight:600;margin:var(--sp-1q) 0 5px}
.sc-note{margin-top:var(--sp-5q);padding:var(--sp-2h) 12px;background:var(--c-primary-soft);border-radius:var(--r-sm);font-size:var(--fs-xs);color:var(--c-g700);line-height:1.6}

/* 分布条 */
.dist-row{display:grid;grid-template-columns:82px 1fr auto;gap:var(--sp-2h);align-items:center;padding:var(--sp-2q) 0}
.dist-l{font-size:var(--fs-xs);color:var(--c-g500);font-weight:600}
.dist-bar{height:14px;border-radius:var(--r-xs);background:var(--c-g100);overflow:hidden}
.dist-bar i{display:block;height:100%;border-radius:var(--r-xs);transition:width .4s}
.dist-n{font-size:var(--fs-2xs);color:var(--c-g500);text-align:right}

/* 雷达图 */
.radar-wrap{display:flex;flex-direction:column;align-items:center;gap:var(--sp-2h)}
.radar-lg{display:flex;flex-wrap:wrap;gap:var(--sp-3);justify-content:center}
.lg-i{font-size:var(--fs-2xs);color:var(--c-g700);display:inline-flex;align-items:center;gap:var(--sp-2q)}
.lg-i i{width:10px;height:10px;border-radius:var(--r-3q);display:inline-block}

/* 方案区 */
.plan-sec{border-top:1px dashed var(--c-border);padding-top:var(--sp-4);margin-top:var(--sp-4)}
.plan-sec:first-of-type{border-top:0;margin-top:0;padding-top:0}
.plan-sec-h{display:flex;align-items:center;gap:var(--sp-2h);font-size:var(--fs-md);font-weight:600;margin-bottom:var(--sp-3);flex-wrap:wrap}
.plan-badge{display:inline-block;width:24px;height:24px;line-height:24px;text-align:center;border-radius:var(--r-xs);font-size:var(--fs-xs);font-weight:700;color:var(--c-surface)}
.plan-badge.wk{background:var(--c-accent)}.plan-badge.mo{background:var(--c-info)}.plan-badge.yr{background:var(--c-warn)}
.plan-days{display:grid;grid-template-columns:repeat(5,1fr);gap:var(--sp-4q);margin-bottom:var(--sp-2h)}
.plan-day{background:var(--c-surface-alt);border:1px solid var(--c-border);border-radius:var(--r-sm);padding:var(--sp-4q)}
.pd-d{font-size:var(--fs-2xs);font-weight:700;color:var(--c-primary);margin-bottom:var(--sp-1)}
.pd-t{font-size:var(--fs-xs);color:var(--c-g700);line-height:1.45}
.plan-phases,.plan-quarters{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-4q);margin-bottom:var(--sp-2h)}
.plan-phase,.plan-q{background:var(--c-surface-alt);border:1px solid var(--c-border);border-radius:var(--r-sm);padding:var(--sp-2h)}
.pp-w,.pq-q{font-size:var(--fs-2xs);font-weight:700;color:var(--c-accent);margin-bottom:var(--sp-1)}
.pp-g,.pq-g{font-size:var(--fs-xs);font-weight:600;margin-bottom:var(--sp-1)}
.plan-check{display:flex;flex-wrap:wrap;gap:var(--sp-2)}
.plan-ck{font-size:var(--fs-2xs);color:var(--c-g700);background:var(--c-success-bg);border-radius:var(--r-xs);padding:var(--sp-1q) 8px;line-height:1.45}
.adv-box{border:1px solid var(--c-border);border-radius:var(--r-sm);padding:var(--sp-2h) 12px;margin-bottom:var(--sp-4q)}
.adv-h{display:flex;align-items:center;gap:var(--sp-2);margin-bottom:var(--sp-1h)}
.adv-ul{margin:0;padding-left:var(--sp-4h)}
.adv-ul li{font-size:var(--fs-xs);color:var(--c-g700);line-height:1.7}
.firm-diag{display:flex;gap:var(--sp-4h);flex-wrap:wrap;padding:var(--sp-4q) 12px;background:var(--c-surface-alt);border-radius:var(--r-sm);margin-bottom:var(--sp-5q);font-size:var(--fs-xs)}
.plan-pick{display:flex;flex-wrap:wrap;gap:var(--sp-2h)}
.pp-item{display:flex;align-items:center;gap:var(--sp-2);border:1px solid var(--c-border);border-radius:var(--r-sm);padding:var(--sp-4q) 14px;cursor:pointer;transition:.15s}
.pp-item:hover{border-color:var(--c-primary);background:var(--c-primary-soft)}
.ck-cell{text-align:center}
.ck-num{font-size:var(--fs-2xl);font-weight:700;font-family:var(--font-num);margin:var(--sp-1q) 0 5px}

@media(max-width:1024px){
  .sc-hero{grid-template-columns:1fr}
  .sc-hero-l{border-right:0;border-bottom:1px solid rgba(255,255,255,.14);padding:0 0 16px}
  .sc-hero-r,.sc-model,.g5{grid-template-columns:repeat(3,1fr)}
  .plan-days{grid-template-columns:repeat(3,1fr)}
  .plan-phases,.plan-quarters{grid-template-columns:repeat(2,1fr)}
  .im-cat-grid{grid-template-columns:repeat(4,1fr)}
  .cl-kpi{grid-template-columns:repeat(3,1fr)}
}
@media(max-width:640px){
  .sc-hero-r,.sc-model,.g5{grid-template-columns:repeat(2,1fr)}
  .plan-days,.plan-phases,.plan-quarters{grid-template-columns:1fr}
  .sc-firm-score{font-size:calc(var(--fs-display) - 4px)}
  .cl-kpi{grid-template-columns:repeat(2,1fr)}
  .im-cat-grid{grid-template-columns:repeat(2,1fr)}
  .im-top{flex-direction:column;align-items:flex-start}
  .im-item,.ir-item{flex-wrap:wrap}
  .fn-l{flex-basis:64px}
}

/* ============================================================
   合并页子标签栏（.cs-tabs）—— 工作台 / 客户素材 两个合并页共用
   ------------------------------------------------------------
   ★ 为什么新开一套而不是复用 .up-tabs：
     .up-tabs 是「上传材料」表单里的二选一大卡片，列宽固定 1fr 1fr；
     这里是页面顶部的**一级导航段**，标签数量随合并页而变（2 个），
     且每个标签带一行说明文字。用 auto 宽度自适应的胶囊、而不是撑满整行的
     等分卡片，视觉上才像「页内导航」而不是「表单选项」。
   ★ 为什么不用 .c360-tab：
     .c360-tab 是「客户全景内部」的三类主体切换（律所/律师/法律人），
     它的选中态是**实心主色**，那是页内二级筛选的强调级别；
     而本组件是顶级页的段切换，选中态用**左边框强调 + 浅底**即可——
     两者在层级上不同，样式混用会让用户分不清「我在哪一层」。
   ============================================================ */
.cs-tabs{display:flex;align-items:stretch;gap:var(--sp-2h);flex-wrap:wrap}
.cs-tab{display:flex;align-items:center;gap:var(--sp-2h);padding:var(--sp-5q) 18px;
  border:1px solid var(--c-border);border-left:3px solid transparent;
  border-radius:var(--r-md);background:var(--c-surface);
  cursor:pointer;transition:all var(--dur) var(--ease);user-select:none}
.cs-tab:hover{border-color:var(--c-border-strong);background:var(--c-surface-alt)}
/* 选中态：左侧 3px 主色竖条 —— 与「客户全景」内部的三标签（实心胶囊）
   形成明确的层级差：这里是"段"，那里是"筛选项"。 */
.cs-tab.on{border-left-color:var(--c-primary);background:var(--c-primary-tint)}
.cs-tab-i{font-size:var(--fs-lg);color:var(--c-g500);line-height:1}
.cs-tab.on .cs-tab-i{color:var(--c-primary)}
.cs-tab-t{font-size:var(--fs-sm);font-weight:600;line-height:1.3}
.cs-tab.on .cs-tab-t{color:var(--c-primary)}
.cs-tab-d{font-size:var(--fs-xs);color:var(--c-g500);line-height:1.3;margin-top:var(--sp-0h)}

/* ============================================================
   客户全景（Customer 360）—— 三标签页 + 左右分栏
   ============================================================ */
.c360-tabs{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.c360-tab{display:flex;align-items:center;gap:var(--sp-3q);height:36px;padding:0 14px;
  border:1px solid var(--c-border);border-radius:var(--r-pill);background:var(--c-surface);
  cursor:pointer;transition:all var(--dur) var(--ease);user-select:none}
.c360-tab:hover{border-color:var(--c-border-strong);background:var(--c-surface-alt)}
.c360-tab.on{background:var(--c-primary);border-color:var(--c-primary);color:var(--c-surface);
  box-shadow:var(--shadow-sm)}
.c360-tab-i{font-size:var(--fs-md)}
.c360-tab-t{font-size:var(--fs-sm);font-weight:600}
.c360-tab-n{font-size:var(--fs-2xs);font-weight:700;padding:var(--sp-0q) 7px;border-radius:var(--r-pill);
  background:var(--c-bg);color:var(--c-g700)}
/* ★ v4.0.6：选中态的数字徽标原写 rgba(255,255,255,.22) + color:var(--c-surface)。
   问题不是配色不好看，而是**半透明底让实际对比度不可判定** ——
   它叠加在 .c360-tab.on 的 --c-primary 上得到 #5C7292，白字实算 4.12:1，
   卡在 4.5 线下；而在页面上肉眼看"就是个深蓝徽标"，谁也不会怀疑。
   改为实色：主色压深一档作底 + 纯白字（#16304F on #FFFFFF = 12.9:1）。
   ★ 为什么不再用半透明白：半透明是"看起来对"的写法，但**对比度无法静态
     判定**，换一次主色就可能不达标，且没有任何工具会提醒你。 */
.c360-tab.on .c360-tab-n{background:var(--c-surface);color:var(--c-primary-hover)}

.c360-wrap{display:grid;grid-template-columns:288px 1fr;gap:var(--sp-3h);align-items:start}

/* 左侧列表 */
.c360-side{position:sticky;top:14px;background:var(--c-surface);border:1px solid var(--c-border);
  border-radius:var(--r-md);overflow:hidden}
.c360-search{padding:var(--sp-2h) 11px;border-bottom:1px solid var(--c-border)}
.c360-search .input{height:30px;font-size:var(--fs-sm)}
.c360-list{max-height:calc(100vh - 210px);overflow-y:auto;padding:var(--sp-1h)}
.c360-item{display:flex;gap:var(--sp-2h);padding:var(--sp-4q) 10px;border-radius:var(--r-sm);cursor:pointer;
  transition:background var(--dur) var(--ease);border:1px solid transparent}
.c360-item:hover{background:var(--c-surface-alt)}
.c360-item.on{background:var(--c-primary-tint);border-color:var(--c-border-strong)}
.c360-av{width:34px;height:34px;flex:none;border-radius:var(--r-sm);color:var(--c-surface);
  display:flex;align-items:center;justify-content:center;font-size:var(--fs-md);font-weight:700}
.c360-name{font-size:var(--fs-sm);font-weight:600}
.c360-mini{display:flex;gap:var(--sp-2h);margin-top:var(--sp-1q);color:var(--c-g500)}
.c360-mini b{color:var(--c-g700)}

/* 右侧详情 */
.c360-main{min-height:420px}
.c360-hero{display:flex;gap:var(--sp-3h);align-items:flex-start}
.c360-hero-av{width:52px;height:52px;flex:none;border-radius:var(--r-md);color:var(--c-surface);
  display:flex;align-items:center;justify-content:center;font-size:var(--fs-2xl);font-weight:700}
.c360-hero-name{font-size:var(--fs-xl);font-weight:700;margin:0;line-height:1.3}
.c360-bio{margin-top:var(--sp-5q);padding-top:var(--sp-5q);border-top:1px dashed var(--c-border);
  color:var(--c-g700);line-height:1.7}

.c360-imstat{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--sp-2) 14px}
.c360-imstat>div{display:flex;flex-direction:column}
.c360-imstat b{font-size:var(--fs-xl);font-weight:700}
.c360-imstat span{font-size:var(--fs-2xs);color:var(--c-g500)}
/* 语义色文字工具类（集中一处，便于整体调整配色与饱和度） */
.c-ok{color:var(--c-success)} .c-warn{color:var(--c-warn)} .c-err{color:var(--c-danger)}
.c-pri{color:var(--c-primary)} .c-accent{color:var(--c-accent)} .c-muted{color:var(--c-g500)}

.c360-cats{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--sp-3q)}
.c360-cat{border:1px solid var(--c-border);border-radius:var(--r-sm);padding:var(--sp-3q) 9px;
  font-size:var(--fs-xs);background:var(--c-surface-alt)}
.c360-cat.empty{opacity:.55}
.c360-cat .req{font-style:normal;font-size:var(--fs-2xs);color:var(--c-danger);margin-left:var(--sp-1);
  border:1px solid var(--c-danger);border-radius:var(--r-3q);padding:0 3px}

.c360-imgrp{margin-top:var(--sp-5q);padding-top:var(--sp-4q);border-top:1px dashed var(--c-border)}
.c360-imgrp:first-child{margin-top:0;padding-top:0;border-top:0}
.c360-im{display:flex;gap:var(--sp-4q);align-items:center;padding:var(--sp-1h);border-radius:var(--r-sm);
  cursor:pointer;transition:background var(--dur) var(--ease)}
.c360-im:hover{background:var(--c-primary-tint)}
.c360-im-thumb{width:46px;height:34px;object-fit:cover;border-radius:var(--r-xs);
  border:1px solid var(--c-border);flex:none}
.c360-im-doc{width:46px;height:34px;flex:none;border-radius:var(--r-xs);background:var(--c-bg);
  border:1px solid var(--c-border);display:flex;align-items:center;justify-content:center;
  font-size:var(--fs-xs);color:var(--c-g500);font-weight:600}
.c360-preview{max-height:56vh;overflow:auto;border-radius:var(--r-md);background:var(--c-bg);padding:var(--sp-2h)}
.c360-preview img{max-width:100%;display:block;margin:0 auto;border-radius:var(--r-sm)}
.c360-preview-text{max-height:52vh;overflow:auto;line-height:1.8;font-size:var(--fs-sm);
  color:var(--c-g700);background:var(--c-surface-alt);padding:var(--sp-6q);border-radius:var(--r-sm)}

.c360-funnel{max-width:100%}
.c360-plans{display:flex;flex-direction:column;gap:var(--sp-1h)}
.c360-plan{display:flex;gap:var(--sp-4q);align-items:center;padding:var(--sp-3q) 9px;border-radius:var(--r-sm);
  background:var(--c-surface-alt);border:1px solid var(--c-border)}

.c360-contents{display:flex;flex-direction:column;gap:var(--sp-3q)}
.c360-content{border:1px solid var(--c-border);border-radius:var(--r-sm);overflow:hidden;
  transition:border-color var(--dur) var(--ease)}
.c360-content.on{border-color:var(--c-border-strong)}
.c360-content-h{display:flex;gap:var(--sp-4q);align-items:flex-start;padding:var(--sp-4q) 11px;cursor:pointer;
  transition:background var(--dur) var(--ease)}
.c360-content-h:hover{background:var(--c-surface-alt)}
.c360-caret{color:var(--c-g500);font-size:var(--fs-2xs);margin-top:var(--sp-1q);flex:none;transition:transform var(--dur) var(--ease)}
.c360-content-b{border-top:1px dashed var(--c-border);background:var(--c-surface-alt);padding:var(--sp-3) 14px}
.c360-body{line-height:1.85;font-size:var(--fs-sm);color:var(--c-g700);max-height:420px;overflow:auto}

/* 窄屏防溢出：网格子项与列表项的最小宽度必须归零，否则内容最小宽度会撑破列 */
.c360-wrap>*, .c360-side, .c360-search, .c360-list, .c360-item, .c360-item>.f1{min-width:0}
.c360-search .input{width:100%}
.c360-name,.c360-mini{overflow-wrap:anywhere}

@media (max-width:1024px){
  .c360-wrap{grid-template-columns:1fr}
  .c360-side{position:static}
  .c360-list{max-height:280px}
}
@media (max-width:640px){
  .c360-cats,.c360-imstat{grid-template-columns:1fr}
  .c360-hero{flex-direction:column;gap:var(--sp-2h)}
  .c360-mini{gap:var(--sp-2);flex-wrap:wrap}
}

/* ══════════════════════════════════════════════════════════════
   策动力（CePower）—— 客户端右上角每日评分
   ══════════════════════════════════════════════════════════════ */
.ce-badge{display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-1) 10px 4px 11px;height:36px;
  border:1px solid var(--c-border);border-radius:var(--r-pill);background:var(--c-surface);
  cursor:pointer;transition:all var(--dur) var(--ease);margin-right:var(--sp-0h);min-width:0}
.ce-badge:hover{border-color:var(--c-border-strong);box-shadow:var(--shadow-sm)}
.ce-badge-l{display:flex;align-items:baseline;gap:var(--sp-2q)}
.ce-badge-t{font-size:var(--fs-2xs);color:var(--c-g500)}
.ce-badge-v{font-size:var(--fs-lg);font-weight:700;line-height:1;font-variant-numeric:tabular-nums}
.ce-badge-g{color:var(--c-surface);font-size:var(--fs-2xs);font-weight:700;padding:var(--sp-0q) 6px;border-radius:var(--r-pill);
  line-height:1.5}
.ce-delta{font-size:var(--fs-2xs);font-weight:600}
.ce-delta.up{color:var(--c-danger)} .ce-delta.down{color:var(--c-success)}
.ce-delta.flat{color:var(--c-g500)}
.ce-spark{display:block;flex:none}

/* 数据不足态（尚无已发布数据，无法评分）
   为什么要单独一套样式：此前无数据主体被算成 0 分 D 级，用红色「需重点扶持」
   示人，把「不知道」渲染成了「很差」。这里统一改为中性灰 + 「待接入」措辞，
   让运营一眼区分「还没数据」与「做得不好」。 */
.ce-badge-v.muted{color:var(--c-g500)}
.ce-badge-g.pending{color:var(--c-g600);background:var(--c-g200)!important;font-weight:600}
.ceh-pending .ceh-ring-c .ceh-score.muted{color:rgba(255,255,255,.55)}
.ceh-grade.pending{background:rgba(255,255,255,.22);color:rgba(255,255,255,.92);
  font-size:var(--fs-xs);font-weight:600;padding:var(--sp-0h) 10px;border-radius:var(--r-sm)}
.ceh-pending-tip{font-size:var(--fs-xs);line-height:1.7;color:rgba(255,255,255,.82);
  padding:var(--sp-2h) 0 2px;border-top:1px solid rgba(255,255,255,.14);margin-top:var(--sp-3)}
.ce-dim.is-pending .ce-dim-v{font-size:var(--fs-xs);font-weight:500}
.ce-start-list{margin:0;padding-left:var(--sp-5);font-size:var(--fs-sm);line-height:2;color:var(--c-g700)}
.ce-start-list li::marker{color:var(--c-accent);font-weight:700}

/* 详情弹窗 */
.ce-detail{display:flex;flex-direction:column;gap:var(--sp-4)}
.ce-hero{display:flex;gap:var(--sp-4h);align-items:center;flex-wrap:wrap}
.ce-hero-r{flex:1;min-width:200px}
.ce-hero-title{display:flex;align-items:center;gap:var(--sp-4q);font-size:var(--fs-lg)}
.ce-grade{color:var(--c-surface);font-size:var(--fs-sm);font-weight:700;padding:var(--sp-0h) 10px;border-radius:var(--r-sm)}
.ce-hero-sub{margin-top:var(--sp-2q);color:var(--c-g700);font-size:var(--fs-sm)}
.ce-hero-meta{margin-top:var(--sp-2);font-size:var(--fs-xs);color:var(--c-g500)}
.ce-hero-meta .up{color:var(--c-danger)} .ce-hero-meta .down{color:var(--c-success)}
.ce-sep{margin:0 6px;opacity:.5}
.ce-hero-stat{margin-top:var(--sp-2h);padding-top:var(--sp-2h);border-top:1px dashed var(--c-border);
  font-size:var(--fs-xs);color:var(--c-g700);line-height:1.9}
.ce-hero-stat b{color:var(--c-g900);font-variant-numeric:tabular-nums}

.ce-sec{border-top:1px solid var(--c-border);padding-top:var(--sp-6q)}
.ce-sec-t{font-size:var(--fs-sm);font-weight:600;margin-bottom:var(--sp-2h);display:flex;
  align-items:baseline;gap:var(--sp-2)}
.ce-dim{display:flex;align-items:center;gap:var(--sp-2h);margin-bottom:var(--sp-3q)}
.ce-dim-l{width:88px;flex:none;font-size:var(--fs-xs);color:var(--c-g700)}
.ce-dim-b{flex:1;min-width:0;height:9px;background:var(--c-g100);border-radius:var(--r-xs);overflow:hidden}
.ce-dim-b i{display:block;height:100%;border-radius:var(--r-xs);transition:width .5s var(--ease)}
.ce-dim-v{width:44px;flex:none;text-align:right;font-size:var(--fs-xs);font-weight:600;
  font-variant-numeric:tabular-nums}

.ce-trend{background:var(--c-surface-alt);border-radius:var(--r-sm);padding:var(--sp-2) 6px 4px}
.ce-trend-x{display:flex;justify-content:space-between;font-size:var(--fs-2xs);color:var(--c-g500);
  margin-top:var(--sp-2q);padding:0 10px}

.ce-advice{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--sp-5q)}
.ce-adv{border:1px solid var(--c-border);border-radius:var(--r-sm);padding:var(--sp-5q) 13px;
  background:var(--c-surface-alt)}
.ce-adv-h{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-2);
  margin-bottom:var(--sp-3q)}
.ce-adv-h b{font-size:var(--fs-sm)}
.ce-adv-s{font-size:var(--fs-2xs);color:var(--c-warn);font-weight:600}
.ce-adv-l{margin:0;padding-left:var(--sp-8q);font-size:var(--fs-xs);color:var(--c-g700);line-height:1.85}
.ce-foot{font-size:var(--fs-2xs);color:var(--c-g500);text-align:center;padding-top:var(--sp-1)}

@media (max-width:1024px){
  .ce-badge .ce-spark{display:none}
}
@media (max-width:640px){
  .ce-badge{padding:var(--sp-1q) 8px;height:32px;gap:var(--sp-1h)}
  .ce-badge-t{display:none}
  .ce-advice{grid-template-columns:1fr}
  .ce-hero{gap:var(--sp-3);justify-content:center;text-align:center}
  .ce-hero-r{text-align:center}
  .ce-dim-l{width:74px;font-size:var(--fs-xs)}
}

/* ── 策动力 hero 主视觉（客户端首页横幅右侧，图示位置） ── */
.ceh{display:flex;flex-direction:column;gap:var(--sp-2h);padding:var(--sp-7q) 19px;border-radius:var(--r-lg);
  background:linear-gradient(150deg,rgba(255,255,255,.24),rgba(255,255,255,.1));
  border:1px solid rgba(255,255,255,.32);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  box-shadow:0 10px 32px rgba(4,26,30,.22),inset 0 1px 0 rgba(255,255,255,.24);
  cursor:pointer;position:relative;z-index:1;
  transition:all var(--dur) var(--ease);min-width:0;width:296px}
.ceh:hover{transform:translateY(-2px);
  background:linear-gradient(150deg,rgba(255,255,255,.3),rgba(255,255,255,.16));
  border-color:rgba(255,255,255,.48);
  box-shadow:0 16px 40px rgba(4,26,30,.3),inset 0 1px 0 rgba(255,255,255,.3)}
.ceh-top{display:flex;align-items:center;gap:var(--sp-3h);min-width:0}
.ceh-ring{position:relative;flex:none}
.ceh-ring svg{display:block}
.ceh-ring-c{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;pointer-events:none}
.ceh-score{font-size:var(--fs-3xl);font-weight:800;line-height:1;color:var(--c-surface);
  font-variant-numeric:tabular-nums;text-shadow:0 2px 14px rgba(0,0,0,.26)}
.ceh-unit{font-size:var(--fs-2xs);color:rgba(255,255,255,.7);margin-top:var(--sp-0h);letter-spacing:2px}
.ceh-info{min-width:0;flex:1}
.ceh-label{font-size:var(--fs-sm);font-weight:700;color:rgba(255,255,255,.9);letter-spacing:2.5px}
.ceh-grade-row{display:flex;align-items:center;gap:var(--sp-1h);margin-top:var(--sp-2q);flex-wrap:nowrap}
.ceh-grade{background:var(--c-surface);color:var(--c-teal);font-size:var(--fs-xs);font-weight:800;
  padding:var(--sp-0h) 8px;border-radius:var(--r-pill);line-height:1.6;flex:none;
  box-shadow:0 2px 8px rgba(0,0,0,.14)}
.ceh-glabel{font-size:var(--fs-2xs);font-weight:600;color:rgba(255,255,255,.86);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ceh-meta{margin-top:var(--sp-3q);font-size:var(--fs-2xs);color:rgba(255,255,255,.85);
  display:flex;align-items:center;gap:var(--sp-1h);flex-wrap:nowrap;line-height:1.5;white-space:nowrap}
.ceh-d{font-weight:700;font-variant-numeric:tabular-nums;flex:none}
.ceh-d.up{color:var(--c-danger-bright)} .ceh-d.down{color:var(--c-success-soft-solid)} .ceh-d.flat{color:rgba(255,255,255,.72);font-weight:500}
.ceh-sep{opacity:.45}
.ceh-spark{position:relative;padding-top:var(--sp-0h)}
.ceh-spark .ce-spark{display:block;opacity:.95;width:100%}
.ceh-spark-t{position:absolute;right:0;top:0;font-size:var(--fs-2xs);color:rgba(255,255,255,.6);letter-spacing:.5px}
.ceh-btn{text-align:center;background:rgba(255,255,255,.18);color:var(--c-surface);
  border:1px solid rgba(255,255,255,.34);border-radius:var(--r-pill);
  font-size:var(--fs-xs);font-weight:600;padding:var(--sp-1h) 12px;
  transition:all var(--dur) var(--ease)}
.ceh:hover .ceh-btn{background:var(--c-surface);color:var(--c-teal);border-color:var(--c-surface)}

@media (max-width:1024px){
  .cl-hero.has-ce{grid-template-columns:1fr;gap:var(--sp-4)}
  .ceh{width:100%;flex-direction:row;align-items:center;gap:var(--sp-4h);padding:var(--sp-3h) 18px}
  .ceh-top{flex:none}
  .ceh-spark{display:none}
  .ceh-btn{margin-left:auto;flex:none;white-space:nowrap}
}
@media (max-width:640px){
  .ceh{flex-direction:column;align-items:stretch;gap:var(--sp-5q);padding:var(--sp-6q) 15px}
  .ceh-top{gap:var(--sp-6q)}
  .ceh-ring{transform:scale(.82);transform-origin:left center;margin-right:-14px}
  .ceh-score{font-size:var(--fs-3xl)}
  .ceh-btn{margin-left:0;text-align:center}
}

/* ============================================================
   图片型头像 —— 与色块版同尺寸，仅补 object-fit
   （users.avatar / team_members.avatar / 客户端头像共用；色块版仍走原类）
   ============================================================ */
img.c360-av,img.c360-hero-av,img.avatar{object-fit:cover;display:block;background:none}

/* ============================================================
   头像编辑区（客户端「我的头像」/ 运营端团队成员）
   ============================================================ */
.av-edit-preview{width:72px;height:72px;flex:none;border-radius:var(--r-pill);
  object-fit:cover;display:block;border:2px solid var(--c-border-strong)}
.av-edit-preview.av-fallback{display:flex;align-items:center;justify-content:center;
  background:var(--grad-client);color:var(--c-surface);font-size:var(--fs-3xl);font-weight:700;border-color:transparent}

/* ============================================================
   附件智能填充区（components/fileupload.js）
   ============================================================ */
.fu-zone{border-style:dashed !important;background:var(--c-surface-alt);
  transition:border-color var(--dur) var(--ease),background var(--dur) var(--ease)}
.fu-zone.fu-drag{border-color:var(--c-accent) !important;background:var(--c-primary-tint)}
.fu-status:empty{display:none}
.fu-status{margin-top:var(--sp-1h)}
.fu-filled{border-color:var(--c-accent) !important;background:var(--c-teal-wash) !important}
.fu-filled:focus{box-shadow:0 0 0 3px rgba(14,124,123,.14) !important}

/* 批量上传队列清单 —— 逐条展示 等待/解析中/成功/失败 */
.fu-queue{margin-top:var(--sp-2);border:1px solid var(--c-border);border-radius:var(--r-md);
  overflow:hidden;background:var(--c-surface)}
#df-q .fu-queue{margin-top:var(--sp-2h)}
.fu-q-row{display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-1h) 10px;
  border-bottom:1px solid var(--c-border);font-size:var(--fs-xs);line-height:1.5}
.fu-q-row:last-child{border-bottom:0}
.fu-q-row.fu-q-clickable{cursor:pointer}
.fu-q-row.fu-q-clickable:hover{background:var(--c-surface-alt)}
.fu-q-row.fu-q-row.on{background:var(--c-primary-tint)}
.fu-q-row.fu-q-dis{opacity:.55}
.fu-q-i{width:14px;flex:0 0 14px;text-align:center}
.fu-q-n{flex:1;min-width:0}
.fu-q-s{flex:0 0 auto;max-width:46%;text-align:right}
.fu-q-row.on .fu-q-s{color:var(--c-primary)}

/* ============================================================
   客户全景 ⑧ 数据源接口 + 平台配置（org.js）
   左：取数通道 · 右：分发平台，逐条可测试 / 采集 / 验证
   ============================================================ */
.c360-intg-list{display:flex;flex-direction:column;gap:var(--sp-2)}
.c360-intg-item{display:flex;gap:var(--sp-2h);align-items:flex-start;
  border:1px solid var(--c-border);border-radius:var(--r-sm);
  padding:var(--sp-4q) 10px;background:var(--c-surface)}
.c360-intg-item:hover{border-color:var(--c-border-strong);background:var(--c-surface-alt)}
.c360-intg-ops{display:flex;gap:var(--sp-2q);flex-wrap:wrap;justify-content:flex-end;flex:none}
@media (max-width:900px){
  .c360-intg-item{flex-direction:column}
  .c360-intg-ops{justify-content:flex-start}
}
.c360-tplopt{display:flex;gap:var(--sp-4q);align-items:flex-start;cursor:pointer;
  border:1px solid var(--c-border);border-radius:var(--r-sm);padding:var(--sp-2) 10px;
  background:var(--c-surface);transition:border-color var(--dur) var(--ease),
  background var(--dur) var(--ease)}
.c360-tplopt:hover{border-color:var(--c-accent);background:var(--c-primary-tint)}
.c360-tplopt input{margin-top:var(--sp-1q);flex:none}

/* ============================================================
   客户全景 · 已核验真实资料卡（org.js c360VerifiedCard）
   与运营手填内容区分：绿色左边框 + 来源脚注
   ============================================================ */
.c360-verify{border-left:3px solid var(--c-success)}
.c360-verify-empty{border-left:3px dashed var(--c-border-strong);opacity:.85}
.c360-vbio{font-size:var(--fs-sm);line-height:1.75;color:var(--c-text);
  background:var(--c-surface-alt);border-radius:var(--r-sm);
  padding:var(--sp-2h) 12px;margin-bottom:var(--sp-3)}
.c360-vgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:0 20px;border-top:1px solid var(--c-border);padding-top:var(--sp-2)}
.c360-vrow{display:flex;gap:var(--sp-2h);align-items:flex-start;
  padding:var(--sp-1h) 0;border-bottom:1px dashed var(--c-border);font-size:var(--fs-xs)}
.c360-vk{flex:none;width:118px;color:var(--c-g500);font-weight:500}
.c360-vv{flex:1;min-width:0;color:var(--c-g700);word-break:break-word}
.c360-vsrc{display:flex;gap:var(--sp-2);align-items:center;flex-wrap:wrap;margin-top:var(--sp-2h);
  background:var(--c-success-bg);border-radius:var(--r-sm);padding:var(--sp-3q) 10px}
.c360-vsrc-label{font-size:var(--fs-2xs);font-weight:700;color:var(--c-success);
  border:1px solid var(--c-success);border-radius:var(--r-xs);padding:var(--sp-0q) 6px;flex:none}
@media (max-width:1100px){.c360-vgrid{grid-template-columns:1fr}
  .c360-vk{width:96px}}

/* ============================================================
   平台接入配置页（channels.js）
   —— 21 平台接入档案卡片 / 客户发布账号 / 客户画像 / 素材待确认
   ============================================================ */

/* 接入成熟度分布 */
.ch-cov{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:var(--sp-3h)}
.ch-cov-item{border:1px solid var(--c-border);border-radius:var(--r-sm);padding:var(--sp-5q) 12px;background:var(--c-surface-alt)}

/* 筛选条 */
.ch-filter{display:flex;align-items:center;gap:var(--sp-3q);flex-wrap:wrap}
.ch-filter .small{white-space:nowrap}

/* 平台档案卡 */
.ch-spec-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:var(--sp-3h)}
.ch-spec{border:1px solid var(--c-border);border-radius:var(--r-sm);background:var(--c-surface);
  display:flex;flex-direction:column;transition:box-shadow var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.ch-spec:hover{border-color:var(--c-border-strong);box-shadow:0 2px 10px rgba(30,58,95,.06)}
.ch-spec-h{display:flex;align-items:flex-start;gap:var(--sp-2h);padding:var(--sp-3) 14px;border-bottom:1px solid var(--c-border)}
.ch-spec-n{font-size:var(--fs-md);font-weight:650;color:var(--c-g800);line-height:1.3}
.ch-spec-rows{padding:var(--sp-2h) 14px;flex:1}
.ch-spec-row{display:flex;gap:var(--sp-2h);padding:var(--sp-1) 0;font-size:var(--fs-xs);line-height:1.65}
.ch-spec-row .k{flex:0 0 76px;color:var(--c-g500);white-space:nowrap}
.ch-spec-row .v{flex:1;color:var(--c-g700);word-break:break-word}
.ch-spec-f{padding:var(--sp-5q) 14px;border-top:1px solid var(--c-border);background:var(--c-surface-alt)}
.ch-spec-params{display:flex;align-items:center;gap:var(--sp-2q);flex-wrap:wrap}
.ch-spec-params .chip{font-size:var(--fs-2xs);padding:var(--sp-0h) 7px;cursor:default}
.ch-spec-params .chip b{color:var(--c-danger);margin-left:var(--sp-0h)}

/* 客户画像卡 */
.ps-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:var(--sp-3h)}
.ps-card{border:1px solid var(--c-border);border-radius:var(--r-sm);background:var(--c-surface);
  display:flex;flex-direction:column;padding:0}
.ps-h{display:flex;align-items:flex-start;gap:var(--sp-2h);padding:var(--sp-3) 14px;border-bottom:1px solid var(--c-border)}
.ps-n{font-size:var(--fs-md);font-weight:650;color:var(--c-g800)}
.ps-prompt{padding:var(--sp-2h) 14px;background:var(--c-surface-alt);border-top:1px solid var(--c-border);flex:1}
.ps-prompt-t{font-size:var(--fs-xs);line-height:1.75;color:var(--c-g600);font-family:var(--font-num);
  max-height:96px;overflow:hidden}
.ps-card > .ch-spec-rows{padding:var(--sp-2) 14px}
.ps-card > .flex{padding:0 14px 12px}

/* 素材待确认列表 */
.ib-list{display:flex;flex-direction:column;gap:var(--sp-2h)}
.ib-item{border:1px solid var(--c-border);border-radius:var(--r-sm);background:var(--c-surface);
  border-left:3px solid var(--c-warn);padding:var(--sp-3) 14px}
.ib-item.done{border-left-color:var(--c-border-strong);opacity:.72}
.ib-h{display:flex;align-items:flex-start;gap:var(--sp-3)}
.ib-body{margin-top:var(--sp-2);font-size:var(--fs-xs);line-height:1.8;color:var(--c-g600);
  background:var(--c-surface-alt);border-radius:var(--r-xs);padding:var(--sp-4q) 11px;max-height:130px;overflow:hidden}

/* 通用网格跨列 */
.gspan2{grid-column:span 2}

@media (max-width:900px){
  .ch-spec-grid,.ps-grid{grid-template-columns:1fr}
  .ch-spec-row .k{flex:0 0 62px}
  .gspan2{grid-column:span 1}
  .ib-h{flex-direction:column}
}

/* ============================================================
   插件就绪度（用户需求：每个窗口都要有实际功能，不是死链/宣传）
   ready  → 显示「前置已满足，可直接执行」
   blocked→ 明示「缺什么 + 去配置」，按钮变为「查看待办」
   ============================================================ */
.plug-card.blocked{border-color:var(--c-warn-border);background:linear-gradient(180deg,var(--c-warn-tint-deep),var(--c-surface))}
.plug-card.blocked .plug-ico{background:var(--c-warn-tint);color:var(--c-warn)}
.plug-card.blocked:hover{border-color:var(--c-warn-border-strong);box-shadow:0 2px 10px rgba(183,121,31,.10)}
.plug-need{margin:var(--sp-4q) 0 2px;padding:var(--sp-4q) 10px;border-radius:var(--r-sm,6px);
  background:var(--c-warn-tint);border:1px solid var(--c-warn-border)}
.plug-need-h{display:flex;align-items:center;gap:var(--sp-3q);margin-bottom:var(--sp-1h)}
.plug-need-i{display:flex;align-items:center;gap:var(--sp-3q);padding:var(--sp-1q) 0;font-size:var(--fs-xs);color:var(--c-g700)}
.plug-need-i .dotx{display:inline-flex;align-items:center;justify-content:center;
  width:15px;height:15px;border-radius:50%;background:var(--c-warn-dot);color:var(--c-warn);
  font-size:var(--fs-2xs);font-weight:700;flex:none}
.plug-need-i .lnk{flex:none;font-size:var(--fs-xs);white-space:nowrap}
.plug-ok{display:flex;align-items:center;gap:var(--sp-1h);margin:var(--sp-4q) 0 2px;color:var(--c-success,var(--c-success))}
.plug-ok .doty{display:inline-flex;align-items:center;justify-content:center;
  width:15px;height:15px;border-radius:50%;background:var(--c-success-soft,var(--c-success-soft));
  color:var(--c-success,var(--c-success));font-size:var(--fs-2xs);font-weight:700}
.warn-t{color:var(--c-warn)}

/* ============================================================
   文档优先表单（用户需求：裁判文书类表单不分字段切分，
   改为「上传文件 → 解析 → 复核入库」）
   ============================================================ */
.df-step{margin-bottom:var(--sp-3h)}
.df-step-h{display:flex;align-items:flex-start;gap:var(--sp-4q);margin-bottom:var(--sp-4q)}
.df-n{display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:22px;height:22px;border-radius:50%;background:var(--c-primary-soft,var(--c-primary-fallback));
  color:var(--c-primary,var(--c-primary));font-size:var(--fs-xs);font-weight:700;margin-top:var(--sp-0q)}
.df-n.ok{background:var(--c-success-soft,var(--c-success-soft));color:var(--c-success,var(--c-success))}
.df-drop{border:1.5px dashed var(--c-border-strong,var(--c-border-strong));border-radius:var(--r-md,10px);
  padding:var(--sp-5h) 16px;text-align:center;cursor:pointer;background:var(--c-surface-alt,var(--c-surface-alt));
  transition:border-color var(--dur,180ms) var(--ease,ease),background var(--dur,180ms) var(--ease,ease)}
.df-drop:hover,.df-drop.fu-drag{border-color:var(--c-accent,var(--c-teal));
  background:var(--c-accent-soft)}
.df-drop-i{font-size:var(--fs-2xl);color:var(--c-accent,var(--c-teal));line-height:1;margin-bottom:var(--sp-2q)}
.df-drop-t{font-size:var(--fs-sm);font-weight:600;color:var(--c-g800,var(--c-text));margin-bottom:var(--sp-0h)}
.df-fields{border:1px solid var(--c-border);border-radius:var(--r-md,10px);overflow:hidden}
.df-f{display:flex;gap:var(--sp-2h);padding:var(--sp-2) 11px;border-bottom:1px solid var(--c-border)}
.df-f:last-child{border-bottom:none}
.df-f:nth-child(odd){background:var(--c-surface-alt,var(--c-surface-alt))}
.df-fk{flex:none;width:72px;font-size:var(--fs-xs);color:var(--c-g500,var(--c-g-thumb));padding-top:var(--sp-0q)}
.df-fv{flex:1;font-size:var(--fs-xs);color:var(--c-g800,var(--c-text));line-height:1.7;
  white-space:pre-wrap;word-break:break-word;max-height:150px;overflow:auto}
.df-more{margin:var(--sp-2) 0 6px}
.df-more .lnk{font-size:var(--fs-xs)}

/* ============================================================
   内联附件上传区（页面内表单用）
   用户要求：「类似于上传材料的接口一定要有上传附件的接口，
   然后由大模型 AI 进行分析。」—— 页面内嵌表单（律师端「我要上传」、
   合规检测等）同样需要，故与弹窗版 df-drop 并列存在。
   ============================================================ */
.fu-inline{border:1.5px dashed var(--c-border-strong,var(--c-border-strong));border-radius:var(--r-md,10px);
  padding:var(--sp-3h) 15px;background:var(--c-surface-alt,var(--c-surface-alt));
  transition:border-color var(--dur,180ms) var(--ease,ease),background var(--dur,180ms) var(--ease,ease)}
.fu-inline:hover,.fu-inline.fu-drag{border-color:var(--c-accent,var(--c-teal));
  background:var(--c-accent-soft)}
.fu-inline.busy{opacity:.75;pointer-events:none}
.fu-inline-in{display:flex;align-items:center;gap:var(--sp-5q)}
.fu-inline-i{display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:34px;height:34px;border-radius:var(--r-sm,6px);font-size:var(--fs-lg);
  background:var(--c-accent-soft);color:var(--c-accent,var(--c-teal))}
.fu-inline-t{font-size:var(--fs-sm);font-weight:600;color:var(--c-g800,var(--c-text));margin-bottom:var(--sp-0h)}
.fu-status{min-height:15px;line-height:1.5}
.fu-status .doty,.fu-status .dotx{display:inline-flex;align-items:center;justify-content:center;
  width:14px;height:14px;border-radius:50%;font-size:var(--fs-2xs);font-weight:700;margin-right:var(--sp-1q)}
.fu-status .doty{background:var(--c-success-soft,var(--c-success-soft));color:var(--c-success,var(--c-success))}
.fu-status .dotx{background:var(--c-danger-soft-solid);color:var(--c-danger)}
#up-src{font-weight:400}

/* ============================================================
   客户 360 · AI 可见度卡（由「AI 可见度体检」迁移并入）
   ============================================================ */
.c360-geo .card-head{margin-bottom:var(--sp-3)}
.c360-geo-list{margin-top:var(--sp-1);border:1px solid var(--c-border);border-radius:var(--r-sm,6px);overflow:hidden}
.c360-geo-i{display:flex;align-items:flex-start;gap:var(--sp-4q);padding:var(--sp-2) 11px;
  border-bottom:1px solid var(--c-border);font-size:var(--fs-xs)}
.c360-geo-i:last-child{border-bottom:none}
.c360-geo-i:nth-child(odd){background:var(--c-surface-alt,var(--c-surface-alt))}
.c360-geo-i .badge{flex:none;margin-top:var(--sp-0q)}

/* ============================================================
   真实产物展示（图文卡片画廊 / 视频播放器 / 下载）
   用于内容形式转化与多模态生成对话框，让「真实文件」可见可下载
   ============================================================ */
.render-box{border:1px solid var(--c-border);border-radius:var(--r-md);padding:var(--sp-3);
  background:var(--c-surface-alt)}
.render-grid{display:grid;gap:var(--sp-2h);grid-template-columns:repeat(auto-fill,minmax(148px,1fr))}
.render-item{position:relative;border:1px solid var(--c-border);border-radius:var(--r-sm);
  overflow:hidden;background:var(--c-surface);transition:box-shadow .15s,border-color .15s}
.render-item:hover{border-color:var(--c-primary-border);box-shadow:var(--shadow-sm)}
.render-item img{display:block;width:100%;height:auto;aspect-ratio:3/4;object-fit:cover}
.render-dl{position:absolute;right:6px;bottom:6px;font-size:var(--fs-2xs);padding:var(--sp-1q) 8px;
  border-radius:var(--r-xs);background:rgba(30,58,95,.88);color:var(--c-surface);text-decoration:none;
  opacity:0;transition:opacity .15s}
.render-item:hover .render-dl{opacity:1}
.render-item:hover .render-dl:hover{background:var(--c-primary)}
video{outline:none}
.render-box video{border:1px solid var(--c-border)}

/* ============================================================
   发布引导条（.pub-cta）
   —— 用户反馈「找不到发送到各平台的路径」。做法：在作品生成结果卡片里，
      把唯一的下一步动作做成一条**高对比的整块 CTA**，文案直说「发送到各平台」，
      并在副文案里点名平台，避免用户只看到一个小按钮而错过。
   ============================================================ */
.pub-cta{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3h);
  flex-wrap:wrap;padding:var(--sp-6q) 16px;border-radius:var(--r-md);
  background:linear-gradient(90deg,var(--c-primary-soft),var(--c-surface-alt));
  border:1px solid var(--c-primary-border);border-left:4px solid var(--c-primary)}
.pub-cta-txt{display:flex;flex-direction:column;gap:var(--sp-1q);min-width:0;flex:1 1 260px}
.pub-cta-txt b{font-size:var(--fs-md);color:var(--c-primary);font-weight:700}
.pub-cta-txt span{font-size:var(--fs-xs);color:var(--c-g500);line-height:1.55}
.pub-cta .btn{flex:none;white-space:nowrap}

/* ============================================================
   紧凑指标条（运营窗口减数字展示改造）
   —— 数据分析等「以看为主」的页面仍需要指标，但不必占满四张大卡。
      统一样式：一行内联、字号小、分隔线区隔，把版面让给可操作的表格与图表。
   ============================================================ */
.metric-strip{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-1h) 20px;
  border:1px solid var(--c-border);border-radius:var(--r-md);background:var(--c-surface-alt);
  padding:var(--sp-4q) 14px;margin-bottom:var(--sp-4)}
.metric-strip .m{display:flex;align-items:baseline;gap:var(--sp-1h);font-size:var(--fs-xs);color:var(--c-g500)}
.metric-strip .m b{font:700 16px/1.1 var(--font-num);color:var(--c-primary);
  font-variant-numeric:tabular-nums}
.metric-strip .m.acc b{color:var(--c-accent)}
.metric-strip .m.suc b{color:var(--c-success)}
.metric-strip .m.warn b{color:var(--c-warn)}
.metric-strip .m .dl{font-size:var(--fs-2xs);color:var(--c-success)}
.metric-strip .m .dl.down{color:var(--c-danger)}
.metric-strip .sep{width:1px;height:16px;background:var(--c-border);flex:none}
.metric-strip .grow{flex:1}

/* 未连接外部平台时，依赖外部凭据的操作入口降权并明示前置条件 */
.pill.blocked{border-style:dashed;background:var(--c-surface-alt)}
.pill.blocked .lnk{color:var(--c-warn)}
.pill.blocked:hover{box-shadow:none;border-color:var(--c-warn-border-strong)}

/* ============================================================
   ★ 2026-10 迭代：极简工具风统一层
   ============================================================
   立场：这套界面的使用者是运营人员，每天要在这里完成几十次操作。
   装饰性的渐变、发光、玻璃拟态、悬浮抬升**不产生任何操作价值**，
   却会持续占用注意力，也让「哪里可点、哪里是数据」变得含混。

   因此这里做一次**收敛而非推翻**：
     · 保留全部语义色（成功/警告/危险/信息）与品牌主色 —— 它们有信息含义；
     · 去掉纯装饰的渐变与多重阴影 —— 它们只有观感作用；
     · 把圆角、阴影、间距压到两档，让全站看起来是同一双手做的；
     · 关键交互态（focus / disabled / 危险操作）反而**加强**，
       因为那才是运营真正需要一眼看清的地方。

   写法说明：以下规则放在文件末尾，靠同等特异性下的后置覆盖生效。
   这样业务规则（在上方）保持可读，本层只表达「统一口径」这一件事，
   将来换风格只需替换本层，不必在 1600 行里逐条找。
   品牌首页（.bh-*，未登录的营销页）除外——它面向的是外部访客，
   允许保留视觉表现力，不属于「工具」范畴。
   ============================================================ */

/* ── 1. 去掉纯装饰渐变：统一为单色或极浅的同色背景 ── */
/* 登录页底：深色渐变 → 品牌实色。实色更沉，也让白色登录卡更聚焦 */
.login-wrap{background:var(--c-ink)}
/* 运营端 hero（律所 vs 律师对比条）：三段同色渐变本就没有视觉差异，直接单色 */
.org-hero{background:var(--c-primary)}
/* 图表小条：渐变无信息含义，统一实色 */
.mini-bar i{background:var(--c-primary)}
.cd-bar i{background:var(--c-teal)}
/* 客户端首页形象卡：浅渐变 → 同色极浅底 */
.im-home{background:var(--c-teal-tint)}
/* AI 输出区：浅渐变 → 面层色 */
.ai-out{background:var(--c-primary-tint)}
/* 插件卡选中态：浅渐变 → 同色浅底，靠边框与勾选表达选中，不靠底色浓淡 */
.plug-card.on{background:var(--c-accent-tint)}
.plug-card.blocked{background:var(--c-warn-tint)}
/* 策动力 hero 主视觉：玻璃拟态+渐变 → 半透明实色。
   它压在深色横幅上，透明度足以保持层次，去掉渐变后反而更稳 */
.ceh{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.28);
  box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none}
.ceh:hover{background:rgba(255,255,255,.2);border-color:rgba(255,255,255,.4);
  box-shadow:none;transform:none}
/* 侧栏与品牌头仍保留品牌深色/青绿底（承担「我在哪一端」的识别功能，不是装饰） */

/* ── 2. 按钮：去掉「渐变冒充立体」的写法，统一为实色 + 明确的交互态 ── */
.btn.ghost{background:transparent}
/* 主按钮 hover：实色加深 + 极轻阴影（两档叠加，仍是柔影而非发光） */
.btn.pri:hover:not(:disabled){background:var(--c-primary-hover);box-shadow:var(--shadow-sm)}

/* ── 3. 统一圆角与阴影档位：全站只用 --r-sm/--r-md 与 --shadow-xs/--shadow-sm ── */
/* 卡片类：一律浅边框 + 最轻阴影。
   2026-10 二次校准：本层最初写 box-shadow:none —— 目的是压掉「每张卡都浮在半空」
   的毛躁感，方向没错，但走到了另一个极端：全部卡片同一个平面后，
   卡与页底之间只靠一条 1px 实线划分，页面反而显得「贴纸感」、层级全失。
   现在的口径是「有阴影，但只在贴边 2px 内」：
   用 --shadow-card（两层，最大扩散 8px，透明度全部 <.04）替代 none，
   hover 只把阴影加深半档、不动位置，不再 transform 抬升。
   这样既保住扁平克制，又让「卡浮在页底之上」这件事一眼可辨。 */
.card{box-shadow:var(--shadow-card);border:1px solid var(--c-border)}
.card:hover{box-shadow:var(--shadow-card-hover)}
/* 弹窗是唯一允许有明显投影的层级——因为它确实浮在内容之上，需要视觉分离 */
.modal{box-shadow:var(--shadow-xl)}
/* 徽标/标签：统一直角感更强的圆角，避免大小圆角混杂显得随意 */
.pill,.tag,.ptag,.st{box-shadow:none}

/* ── 4. 关键交互态加强（这才是运营真正需要的可见性）── */
/* 键盘可达性：此前全站无统一 focus 样式，用 Tab 操作时完全看不到焦点在哪。
   这不是美观问题——运营里有人就是键盘操作快，看不到焦点等于不能用。 */
:where(a,button,input,select,textarea,[tabindex]):focus-visible{
  outline:2px solid var(--c-primary);outline-offset:2px;border-radius:var(--r-xs)}
/* ★ 危险按钮的配色已上移到「组件」段的 .btn.dan/.danger/.del 一处统一定义，
   这里不再重复声明 —— 原先同一颗红按钮的 hover 在本文件里被写了三遍且互相覆盖，
   属于最难查的一类样式 bug（读到哪里都以为那就是终值）。 */
/* 禁用态统一：降低不透明度并禁用指针，让「不能点」一眼可见 */
.btn:disabled,.btn[disabled]{opacity:.45;cursor:not-allowed;box-shadow:none}

/* ── 5. 表格：工具风的核心是「能扫」。统一行高与斑马纹口径 ── */
table{border-collapse:separate;border-spacing:0}
table th{font-weight:var(--fw-bold);color:var(--c-g600);background:var(--c-g50)}
table td,table th{border-bottom:1px solid var(--c-border)}
table tbody tr:hover{background:var(--c-g50)}

/* ── 6. 空态与加载：与新增的「可行动空态」组件口径一致 ── */
.empty{padding:var(--sp-17) 16px;text-align:center;color:var(--c-g500)}
/* ★ 空态图标：从「一个 50% 透明的大符号」改为「同族极浅底圆片 + 主色淡符号」。
   前者看起来像资源没加载出来，后者明确表达「这里本来就是空的」。
   尺寸不变，只换承载方式，不新增任何装饰元素。 */
/* ★ v4.0.6：符号色原为 --c-p5(#A8BDD4)，压在 --c-p0(#F7F9FC) 上实算 2.30:1。
   空态图标是**纯图形信号**（旁边通常配一句"暂无数据"），
   按 WCAG 非文本对比度应 ≥3:1；低于这个值时，符号几乎溶进底片，
   又退回到改版前"像资源没加载出来"的观感——改版的本意就丢了。
   换 --c-p7(#5C7A9C)：3.60:1，仍是同族浅蓝、仍明显弱于主色，克制感不变。 */
.empty .ico{width:44px;height:44px;border-radius:var(--r-lg);margin:0 auto var(--sp-2h);
  display:flex;align-items:center;justify-content:center;
  background:var(--c-p0);border:1px solid var(--c-hairline);
  font-size:var(--fs-lg);color:var(--c-p7);opacity:1}
.empty.sm .ico,.empty.small .ico{display:none}
.empty .t{font-size:var(--fs-md);font-weight:var(--fw-medium);color:var(--c-g700);margin-bottom:var(--sp-2q);letter-spacing:-.1px}
.empty .d{font-size:var(--fs-xs);color:var(--c-g500);line-height:1.7;margin-bottom:var(--sp-0h)}

/* ── 工作台任务流（2026-10 迭代）────────────────────────────────
   首页从「指标陈列」改为「待办 → 开工 → 产出」三块后新增的样式。
   设计取舍：
     · 顶部一句话用较大字号 + 深色，因为它是这一页唯一的「结论」；
     · 「一键开工」行用整行可点（不是图标按钮）——运营常在触控屏上操作，
       整行热区比小按钮省事得多，也避免点错；
     · 待办按紧急度用左侧色条区分（危险/警告/普通），不用大面积底色，
       保证一屏能扫完 4~6 条。
   ──────────────────────────────────────────────────────────── */

/* 顶部：今天的工作量概述 */
.dash-head{padding:var(--sp-4) 20px}
.dh-ico{width:42px;height:42px;border-radius:var(--r-md);background:var(--c-primary-soft);
  color:var(--c-primary);display:flex;align-items:center;justify-content:center;
  font-size:var(--fs-xl);flex:0 0 auto}
.dh-t{font-size:var(--fs-lg);font-weight:var(--fw-bold);color:var(--c-ink);line-height:1.45}
.dh-t b{color:var(--c-primary);font-family:var(--font-num);font-size:var(--fs-xl);
  font-variant-numeric:tabular-nums;margin:0 2px}
.dh-s{font-size:var(--fs-xs);color:var(--c-g500);margin-top:var(--sp-1q);line-height:1.6}

/* 待办条：左侧色条表达紧急度 */
.pill-list .pill{border-left:2px solid transparent}
.pill-list .pill .pi.danger{color:var(--c-danger);font-weight:var(--fw-bold)}
.pill-list .pill .pi.warn{color:var(--c-warn);font-weight:var(--fw-bold)}
.pill-list .pill:has(.pi.danger){border-left-color:var(--c-danger)}
.pill-list .pill:has(.pi.warn){border-left-color:var(--c-warn)}

/* 一键开工：整行可点 */
.open-row{display:flex;align-items:center;gap:var(--sp-3h);padding:var(--sp-6q) 15px;
  border:1px solid var(--c-border);border-radius:var(--r-md);background:var(--c-surface);
  transition:border-color var(--dur) var(--ease),background var(--dur) var(--ease)}
.open-row:hover{border-color:var(--c-primary-border);background:var(--c-primary-tint)}
.open-row .or-l{flex:1;min-width:0}
.open-row .or-t{font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--c-ink);
  margin-bottom:var(--sp-0h)}
.open-row .or-d{font-size:var(--fs-xs);color:var(--c-g500);line-height:1.55;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.open-row .or-r{text-align:right;flex:0 0 auto;min-width:76px}
.open-row .or-n{font:700 var(--fs-xl)/1.1 var(--font-num);color:var(--c-primary);
  font-variant-numeric:tabular-nums}
.open-row .or-u{font-size:var(--fs-2xs);color:var(--c-g500);margin-top:var(--sp-0h);white-space:nowrap}
.open-row .or-go{flex:0 0 auto;font-size:var(--fs-xs);color:var(--c-primary);
  font-weight:var(--fw-medium);white-space:nowrap}
.open-row:hover .or-go{color:var(--c-primary-hover)}

/* ============================================================
   危险操作：二次确认弹窗 + 5 秒撤销条
   ★ 与全站极简工具风一致：无渐变、无彩色装饰，
     危险色只出现在「确认删除」这一处，其余保持中性。
   ============================================================ */

/* 危险确认弹窗正文：左侧警示符号 + 右侧说明 */
.dg-box{display:flex;gap:var(--sp-3);align-items:flex-start}
.dg-ico{flex:0 0 auto;width:22px;height:22px;border-radius:50%;
  background:var(--c-danger-bg);color:var(--c-danger);
  display:flex;align-items:center;justify-content:center;
  font-size:var(--fs-sm);line-height:1;margin-top:var(--sp-0q)}
.dg-txt{flex:1;min-width:0}
.dg-desc{font-size:var(--fs-sm);line-height:1.7;color:var(--c-g700)}
.dg-detail{margin-top:var(--sp-2h);padding:var(--sp-2) 11px;border-radius:var(--r-sm);
  background:var(--c-g50);border-left:3px solid var(--c-g300);
  font-size:var(--fs-xs);line-height:1.6;color:var(--c-g800);
  word-break:break-all;max-height:132px;overflow:auto}

/* 危险确认按钮：红色实心，与 .btn.pri 明确区分。
   ★ 配色已上移到「组件」段的 .btn.dan/.danger/.del 统一声明，此处不再重复。 */

/* 撤销条容器：底部居中，浮在内容之上、模态之下（模态打开时不应被遮挡） */
.undo-wrap{position:fixed;left:50%;bottom:26px;transform:translateX(-50%);
  z-index:var(--z-toast);display:flex;flex-direction:column;gap:var(--sp-2);
  align-items:center;pointer-events:none}
.undo{
  pointer-events:auto;display:flex;align-items:center;gap:var(--sp-5q);
  background:var(--c-ink);color:var(--c-surface);
  padding:var(--sp-2h) 14px;border-radius:var(--r-sm);box-shadow:var(--shadow-lg);
  font-size:var(--fs-sm);line-height:1.4;max-width:min(92vw,560px);
  opacity:0;transform:translateY(10px);transition:opacity .2s ease,transform .2s ease}
.undo.in{opacity:1;transform:none}
.undo-ico{flex:0 0 auto;color:var(--c-success-bright);font-size:var(--fs-sm)}
.undo-txt{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.undo-btn{flex:0 0 auto;background:transparent;border:1px solid rgba(255,255,255,.42);
  color:var(--c-surface);font-size:var(--fs-xs);font-weight:var(--fw-medium);
  padding:var(--sp-2q) 12px;border-radius:var(--r-xs);cursor:pointer;transition:background .15s}
.undo-btn:hover{background:rgba(255,255,255,.14)}
.undo-btn:disabled{opacity:.6;cursor:default}
.undo-sec{flex:0 0 auto;font-size:var(--fs-2xs);color:rgba(255,255,255,.55);
  font-variant-numeric:tabular-nums;min-width:30px;text-align:right}

/* 移动端：撤销条贴底通栏，避免窄屏挤压 */
@media (max-width:640px){
  .undo-wrap{left:12px;right:12px;bottom:14px;transform:none;align-items:stretch}
  .undo{max-width:none}
}

/* ============================================================
   可行动的错误提示（2026-10）
   「发生了什么 + 你能做什么 + 处理按钮」三段式。
   复用 .mask / .modal 外壳以保证与全站弹窗视觉一致，
   这里只补错误专属的抬头与正文排版。
   ============================================================ */
.err-modal{width:min(520px,92vw)}
.err-head{display:flex;gap:var(--sp-5q);align-items:flex-start;padding:var(--sp-8q) 18px 4px}
.err-ico{flex:0 0 auto;width:22px;height:22px;border-radius:50%;
  background:var(--c-danger-bg,var(--c-danger-wash));color:var(--c-danger,var(--c-danger-bright-solid));
  font-weight:var(--fw-bold);font-size:var(--fs-sm);line-height:22px;text-align:center}
.err-title{font-size:var(--fs-md);font-weight:var(--fw-medium);color:var(--c-ink);
  line-height:1.5;word-break:break-word}
.err-action{padding:var(--sp-1h) 18px 16px 51px;font-size:var(--fs-sm);
  color:var(--c-g700,var(--c-g-note));line-height:1.65;word-break:break-word}
.err-foot{justify-content:flex-end;gap:var(--sp-4q)}

/* 上传区就地错误：发生了什么 + 你能做什么 */
.up-err{color:var(--c-danger);line-height:1.55}
.up-err-how{margin-top:var(--sp-1q);color:var(--c-g700,var(--c-g-note));font-size:var(--fs-xs);line-height:1.6}

/* 上传解析进度条：扫描件 OCR 要 20 秒以上，进度条让等待可见。
   ★ 高度压到 3px、宽度跟随文字块 —— 目的是「有动静」而非抢视觉，
     与全站轻量反馈（.spin）保持同一量级。 */
.up-bar{height:3px;border-radius:var(--r-2q);background:var(--c-g200,var(--c-border));
  overflow:hidden;max-width:280px}
.up-bar>i{display:block;height:100%;background:var(--c-accent,var(--c-teal));
  border-radius:var(--r-2q);transition:width .35s ease}

/* ============================================================
   生成结果：独立文案块（创作工坊结果页）
   ★ 「故事叙述」与「独立文案」是并列的两样产物，视觉上必须分得开，
     否则用户会把两者当成同一份东西，只复制到其中一半。
     全部沿用既有设计令牌，不新增颜色。
   ============================================================ */
.copy-bundle{
  border:1px solid var(--c-border);border-radius:var(--r-md);
  background:var(--c-surface);padding:var(--sp-3) 14px;margin-bottom:var(--sp-2)}
.cb-line{display:flex;gap:var(--sp-2h);align-items:flex-start;margin-bottom:var(--sp-2)}
.cb-line .cb-k{
  flex:0 0 auto;font-size:var(--fs-sm);color:var(--c-text-sub);
  background:var(--c-g100);border-radius:var(--r-sm);padding:var(--sp-0h) 8px;line-height:1.6}
.cb-line .cb-v{flex:1;min-width:0;font-size:var(--fs-md);line-height:1.7;
  color:var(--c-text);word-break:break-word}
.cb-tags{display:flex;gap:var(--sp-1h);flex-wrap:wrap;margin-top:var(--sp-0h)}
.cb-tags .chip{pointer-events:none}

/* ============================================================
   素材库页（materials）—— 工作流第二环
   ★ 全部沿用既有设计令牌，不新增颜色/字号，保证与全站视觉一致。
   ============================================================ */

/* 顶部统计条：一行 5 格，窄屏自动折行 */
.stat-row{display:grid;gap:var(--sp-2h);grid-template-columns:repeat(auto-fit,minmax(118px,1fr))}
.stat-tile{
  background:var(--c-surface);border:1px solid var(--c-g200);border-radius:var(--r-md);
  padding:var(--sp-3) 14px;display:flex;flex-direction:column;gap:var(--sp-0h);
}
.stat-tile .st-n{font-size:var(--fs-xl);font-weight:700;color:var(--c-primary);line-height:1.2}
.stat-tile .st-t{font-size:var(--fs-xs);color:var(--c-g600)}
.stat-tile .st-s{font-size:var(--fs-2xs);color:var(--c-g500)}

/* 按客户分组：卡片网格 */
.mat-client-grid{display:grid;gap:var(--sp-2h);grid-template-columns:repeat(auto-fill,minmax(238px,1fr))}
.mat-client{
  border:1px solid var(--c-g200);border-radius:var(--r-md);padding:var(--sp-3) 13px;
  background:var(--c-surface);transition:border-color .15s,box-shadow .15s;
}
.mat-client:hover{border-color:var(--c-primary-border);box-shadow:0 2px 8px rgba(30,58,95,.06)}
.mat-client .mc-head{display:flex;align-items:center;gap:var(--sp-2);margin-bottom:var(--sp-1h)}
.mat-client .mc-name{font-weight:600;font-size:var(--fs-md);color:var(--c-g900);flex:1}
.mat-client .mc-count{font-size:var(--fs-sm);color:var(--c-g700);display:flex;align-items:center;gap:var(--sp-2)}
.mat-client .mc-count b{font-size:var(--fs-lg);color:var(--c-primary)}
.mat-client .mc-kinds{display:flex;gap:var(--sp-1h);flex-wrap:wrap;margin:var(--sp-2) 0}
.mat-client .mc-kinds .mk{
  font-size:var(--fs-2xs);background:var(--c-g100);color:var(--c-g700);
  border-radius:var(--r-xs);padding:var(--sp-0h) 7px;
}
.mat-client .mc-kinds .mk.muted{color:var(--c-g500);background:var(--c-g50)}
.mat-client .mc-foot{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);margin-top:var(--sp-1h)}

/* 列表里的小缩略图 / 占位图标 */
.mt-thumb{
  width:26px;height:26px;border-radius:var(--r-xs);object-fit:cover;
  vertical-align:middle;margin-right:var(--sp-3q);border:1px solid var(--c-g200);
}
.mt-thumb.ph{
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--c-g50);color:var(--c-g600);font-size:var(--fs-2xs);font-weight:600;
}

/* 窄屏：客户卡片单列，统计条两列 */
@media (max-width:720px){
  .stat-row{grid-template-columns:repeat(2,1fr)}
  .mat-client-grid{grid-template-columns:1fr}
}

/* ── 文案脚本：列表卡与选用弹窗 ────────────────────────────────
   ★ 为什么补这段：st-scripts / st-script 这两个类在 studio.js 里早就用了
     （「文案脚本」面板的脚本列表），但 CSS 里从来没有定义过 —— 一直靠
     浏览器默认块级流堆叠，看上去"能用"所以没人发现。它们的视觉层次
     （卡片边界、悬停反馈）其实是缺的。既然本次要新增同族的选用弹窗，
     就一并把这一族样式补齐，而不是新旧两套各写一半。 */
/* ★ 列表项间距从 4px 提到 8px：4px 时相邻两张卡的发丝描边几乎贴在一起，
   一列十几条会连成一整块「竖条纹」，扫读时分不清条目边界。
   8px 是这类「紧凑列表卡」的甜点位 —— 仍紧凑，但每条独立成立。 */
.st-scripts{display:flex;flex-direction:column;gap:var(--sp-2h)}
.st-script{
  padding:var(--sp-2h) 12px;border:1px solid var(--c-border);border-radius:var(--r-md);
  background:var(--c-surface);
  box-shadow:0 1px 1.5px rgba(19,26,38,.025);
  transition:border-color .15s,box-shadow .15s;
}
.st-script:hover{border-color:var(--c-border-strong);box-shadow:var(--shadow-xs)}

/* 选用弹窗的条目：与 .st-script 同族，但整块可点，故加 cursor 与选中反馈 */
.sc-list{display:flex;flex-direction:column;gap:var(--sp-2h);max-height:52vh;overflow:auto}
.sc-item{
  padding:var(--sp-5q) 13px;border:1px solid var(--c-border);border-radius:var(--r-md);
  background:var(--c-surface);cursor:pointer;
  transition:border-color .15s,background .15s;
}
.sc-item:hover{border-color:var(--c-p5);background:var(--c-p0)}

/* ── 分析结论卡 + 整篇文稿框 ──────────────────────────────────
   用户诉求（2026-10）：「生成的主题要是分析理解后的主题展示，而不是照抄
   第一句话」「内容不要分镜 1/2/3/4，全部放统一页面方便复制黏贴」。

   设计取舍：
   · 分析结论卡排在流式分析正文之上 —— 结论先读，过程后看。
     四项（主题/焦点/法条/痛点）全部可编辑，改完点「保存分析结论」回写。
   · 文稿框用只读 textarea 而非 <pre> 或 contenteditable：
     <pre> 不能 Ctrl+A 选中后复制成纯文本；contenteditable 会带富文本标记，
     粘到微信/石墨里会变形。textarea 天然是纯文本，全选复制最干净。 */
.st-topic{
  padding:var(--sp-3) 13px;border:1px solid var(--c-primary-border);
  border-radius:var(--r-md);background:var(--c-primary-tint);
}
.st-topic-h{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.st-topic label{display:block;margin-top:var(--sp-2)}
.st-topic .input,.st-topic .textarea{background:var(--c-surface)}

/* 文稿框：等宽行距放宽，长文连续阅读不挤 */
#s-paper{
  font-family:var(--font-base);resize:vertical;
  background:var(--c-surface);color:var(--c-text);
}
#s-paper:focus{outline:none}

@media (max-width:960px){
  /* 窄屏：生成区与列表区改为单列，分析卡与文稿框自然上下堆叠 */
  #s-paper{min-height:200px !important}
}

/* ── 材料来源回显条 ────────────────────────────────────────────
   用于「本次的材料来自哪里」——目前是「选了文案脚本」这一种。
   与上传框是两个并列的来源，故紧贴在上传框下方而不是塞进别的卡片。
   左侧图标 + 中间文字 + 右侧动作，是通知条的标准三段式。 */
.src-bar{
  display:flex;align-items:center;gap:var(--sp-2);margin-top:var(--sp-2);
  padding:var(--sp-2) 11px;border-radius:var(--r-sm);
  background:rgba(30,58,95,.06);border:1px solid rgba(30,58,95,.16);
  font-size:var(--fs-sm);color:var(--c-text);
}
.src-bar .sb-i{color:var(--c-primary);font-weight:700}
.src-bar .sb-t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.src-bar .sb-x{flex:none}

/* ── 我的判决书（律师端 mydocs 页） ────────────────────────────
   列表形态与 .im-item（形象材料）保持一致：左图标 + 中间文字 + 右侧标签，
   行间用虚线分隔而非卡片嵌套 —— 判决书是同一类事物的重复项，
   每条做一张卡会让长列表显得零碎，分隔线更适合「档案列表」的语义。
   图标方块复用形象材料的尺寸（64px 会过大，此处 40px 与行高更匹配）。 */
.md-list{display:flex;flex-direction:column}
.md-item{
  display:flex;gap:var(--sp-3);align-items:flex-start;padding:var(--sp-3) 0;
  border-bottom:1px dashed var(--c-border);cursor:pointer;
  transition:background .12s;
}
.md-item:last-child{border-bottom:none}
.md-item:hover{background:var(--c-primary-50,#f4f7fb)}
.md-ico{
  width:40px;height:40px;flex:0 0 40px;border-radius:var(--r-md);
  display:flex;align-items:center;justify-content:center;
  background:var(--c-primary-50,#f4f7fb);color:var(--c-primary);
  font-size:var(--fs-lg);
}
.md-t{font-weight:600}
.md-side{flex:none;display:flex;gap:var(--sp-1h);align-items:center;flex-wrap:wrap}

/* 移动端：右侧标签换行到标题下方，避免挤压标题可读宽度 */
@media(max-width:640px){
  .md-item{flex-wrap:wrap}
  .md-side{width:100%;padding-left:var(--sp-26)}
}

/* ============================================================
   意见反馈（工具条按钮 + 提交弹窗 + 台账页 + 详情对话）

   用户要求：「作一个意见反馈按钮，可以复制粘贴或者上传附件。提交后所有运营
             人员都可以看到。参考法小策 OA 平台意见反馈的做法编写软件。」

   样式口径（与全站一致，不另造一套）：
     · 颜色只用既有语义令牌（--c-primary / accent / warn / danger / 灰阶），
       不引入任何新的硬编码色值。
     · 圆角只用 --r-sm/-md/-lg，间距只用 --sp-*。
     · 对话气泡复用「运营 / 提出人」两色的语义，不复用聊天软件的左右布局 ——
       这是工单记录不是即时通讯，作者身份比左右位置更重要。
   ============================================================ */

/* ── 工具条上的反馈按钮 + 未处理徽标 ───────────────────────── */
.tb-fb{position:relative;flex:0 0 auto}
.tb-fb .tb-fb-t{margin-left:var(--sp-1)}
/* 徽标：数字角标压在按钮右上角。用 --c-danger 而非主色 ——
   它表达的是"有东西等你处理"，与全站告警语义一致。 */
.tb-dot{
  position:absolute;top:-5px;right:-5px;min-width:16px;height:16px;padding:0 4px;
  border-radius:var(--r-pill);background:var(--c-danger);color:var(--c-on-dark);
  font-size:var(--fs-2xs);font-weight:600;line-height:16px;text-align:center;
  font-family:var(--font-num);box-shadow:0 0 0 2px var(--c-surface);
}
/* 无数字提示点：律师端用它表示"你提的反馈在这里"。
   ★ 为什么不做成纯空圆点（border-radius + 宽高）：空圆点太小容易被忽略，
     做成 9px 实心圆 + 同一圈描边，与数字角标同一视觉族，一眼认得出。 */
.tb-dot.plain{min-width:9px;width:9px;height:9px;padding:0;top:-3px;right:-3px;line-height:0}
@media (max-width:640px){ .tb-fb .tb-fb-t{display:none} }

/* ── 提交弹窗表单 ─────────────────────────────────────────── */
.fb-form{display:flex;flex-direction:column;gap:var(--sp-6q)}
.fb-form .field{display:flex;flex-direction:column}
#fb-body{min-height:170px;resize:vertical;line-height:1.65}
#fb-count{text-align:right;font-family:var(--font-num)}

/* ── 台账页顶部：视角分段 + 状态计数标签 ───────────────────── */
.fb-head{display:flex;align-items:center;gap:var(--sp-3h);flex-wrap:wrap;padding-bottom:var(--sp-2h)}
.fb-head #fb-scope{margin-bottom:0;border-bottom:none;flex:0 0 auto}
/* 单个子页用 .tab 的既有外观，但取消下划线（外层没有整条底线） */
.fb-head #fb-scope .tab{border-bottom:none;padding:var(--sp-1h) 12px;border-radius:var(--r-sm)}
.fb-head #fb-scope .tab.on{background:var(--c-primary-soft);color:var(--c-primary);font-weight:600}
.fb-chips{display:flex;gap:var(--sp-1h);flex-wrap:wrap;flex:1;min-width:0}
.fb-chip{
  display:inline-flex;align-items:center;gap:var(--sp-1h);height:28px;padding:0 11px;
  border:1px solid var(--c-border);border-radius:var(--r-pill);background:var(--c-surface);
  font-size:var(--fs-xs);color:var(--c-g600);cursor:pointer;
  transition:all var(--dur) var(--ease);font-family:inherit;
}
.fb-chip:hover{border-color:var(--c-primary-border);color:var(--c-primary)}
.fb-chip.on{background:var(--c-primary);border-color:var(--c-primary);color:var(--c-on-dark);font-weight:500}
.fb-chip b{font-family:var(--font-num);font-size:var(--fs-2xs);opacity:.85}
.fb-filter .select.sm,.fb-filter .input.sm{height:32px;font-size:var(--fs-sm)}

/* ── 台账列表行 ───────────────────────────────────────────── */
.fb-list{display:flex;flex-direction:column;gap:var(--sp-2)}
.fb-row{cursor:pointer;padding:var(--sp-3) 14px}
.fb-row:hover{border-color:var(--c-primary-border);box-shadow:var(--shadow-sm)}
.fb-row-h{display:flex;align-items:flex-start;gap:var(--sp-3)}
.fb-title{font-size:var(--fs-md);font-weight:600;color:var(--c-g900);line-height:1.4}
.fb-meta{display:flex;align-items:center;gap:var(--sp-3q);flex-wrap:wrap;margin-top:var(--sp-1h)}
.fb-open{flex:0 0 auto;font-size:var(--fs-xs);color:var(--c-g500);white-space:nowrap;
  align-self:center;transition:color var(--dur) var(--ease)}
.fb-row:hover .fb-open{color:var(--c-primary)}

/* ── 详情弹窗 ─────────────────────────────────────────────── */
.fb-d-head{padding-bottom:var(--sp-2h);border-bottom:1px solid var(--c-border)}
.fb-d-title{font-size:var(--fs-lg);font-weight:600;color:var(--c-g900);line-height:1.45}
/* 正文用略暖的底 + 等宽留白：反馈正文里常粘报错栈，纯白底久看伤眼 */
.fb-d-body{
  margin-top:var(--sp-3);padding:var(--sp-3) 14px;border-radius:var(--r-sm);
  background:var(--c-surface-warm);border:1px solid var(--c-border);
  font-size:var(--fs-md);line-height:1.72;color:var(--c-g800);
  white-space:pre-wrap;word-break:break-word;max-height:300px;overflow:auto;
}
.fb-att-box{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin-top:var(--sp-2h);
  padding:var(--sp-2) 11px;border-radius:var(--r-sm);background:var(--c-primary-tint)}
.fb-att{display:inline-flex;align-items:center;gap:var(--sp-2q);font-size:var(--fs-sm);font-weight:500}
.fb-thread-head{display:flex;align-items:center;justify-content:space-between;margin:var(--sp-3) 0 9px}

/* 对话记录：每条一个气泡，运营/提出人用左侧色条区分身份 */
.fb-thread{display:flex;flex-direction:column;gap:var(--sp-4q);max-height:340px;overflow:auto}
.fb-msg{padding:var(--sp-4q) 12px;border-radius:var(--r-sm);border:1px solid var(--c-border);
  background:var(--c-surface);border-left:3px solid var(--c-g300)}
.fb-msg.staff{background:var(--c-info-wash);border-left-color:var(--c-primary)}
.fb-msg.mine{background:var(--c-surface-alt);border-left-color:var(--c-accent)}
.fb-msg-h{display:flex;align-items:center;gap:var(--sp-3q);flex-wrap:wrap;margin-bottom:var(--sp-2q)}
.fb-who{font-size:var(--fs-sm);font-weight:600;color:var(--c-g800)}
.fb-msg-b{font-size:var(--fs-sm);line-height:1.68;color:var(--c-g700);
  white-space:pre-wrap;word-break:break-word}
.fb-msg-att{margin-top:var(--sp-1h);font-size:var(--fs-xs)}

/* 回复区 */
.fb-reply{margin-top:var(--sp-3);padding:var(--sp-5q) 12px;border-radius:var(--r-sm);
  background:var(--c-page-wash);border:1px solid var(--c-border)}
#fb-reply-txt{min-height:70px;resize:vertical;background:var(--c-surface)}

/* 状态流转按钮行 */
.fb-actions{display:flex;align-items:center;gap:var(--sp-3q);flex-wrap:wrap;margin-top:var(--sp-5q);
  padding-top:var(--sp-5q);border-top:1px dashed var(--c-border)}

/* 环境信息区块 —— 运营排查复现线索用，克制的浅底卡片 */
.fb-env{margin:var(--sp-5q) 0;padding:var(--sp-2h) 12px;border-radius:var(--r-sm);
  background:var(--c-page-wash);border:1px solid var(--c-border)}
.fb-env-h{display:flex;align-items:baseline;gap:var(--sp-2);justify-content:space-between;
  margin-bottom:var(--sp-2);flex-wrap:wrap}
/* 两列网格：字段名定宽对齐，值可换行（UA/URL 会很长） */
.fb-env-g{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-2q) 16px}
.fb-env-i{display:flex;align-items:baseline;gap:var(--sp-3q);font-size:var(--fs-xs);
  min-width:0}
.fb-env-k{flex:0 0 62px;color:var(--c-g-note);text-align:right}
.fb-env-v{color:var(--c-g900);word-break:break-all;min-width:0}
.fb-env-n{color:var(--c-g-note);font-size:var(--fs-2xs);font-style:normal}
.fb-env-ua{margin-top:var(--sp-3q);font-size:var(--fs-2xs);color:var(--c-g-note)}
.fb-env-ua summary{cursor:pointer;user-select:none}
.fb-env-ua code{display:block;margin-top:var(--sp-2q);padding:var(--sp-1h) 8px;
  background:var(--c-surface);border-radius:var(--r-xs);
  word-break:break-all;line-height:1.5;color:var(--c-g700)}

/* 已结案提示条 —— 结案是可回退的，所以用成功色而非警告色 */
.fb-done-note{margin-top:var(--sp-5q);padding:var(--sp-4q) 12px;border-radius:var(--r-sm);
  background:var(--c-success-bg);border:1px solid var(--c-success-soft);
  color:var(--c-success);font-size:var(--fs-sm);line-height:1.6}

/* 结案状态下拉：窄、贴左，不与右侧按钮抢注意力 */
#fb-close-st{max-width:260px}

/* 移动端：计数标签换行，详情弹窗内边距收紧 */
@media (max-width:640px){
  .fb-head{flex-direction:column;align-items:flex-start;gap:var(--sp-4q)}
  .fb-chips{width:100%}
  .fb-d-body{max-height:220px}
  .fb-thread{max-height:260px}
  #fb-close-st{max-width:100%;width:100%}
  /* 环境信息在窄屏改为单列：两列会把「浏览器 Chrome 120」挤成两行 */
  .fb-env-g{grid-template-columns:1fr}
  .fb-env-k{flex:0 0 56px}
}

/* ============================================================
   后台任务中心（工具条角标 + 任务清单）
   —— 「关窗口不丢」的可见性支撑，见 js/components/bgtasks.js

   设计取向：**安静的常驻提示**。
   后台任务不是用户当前关注的东西，所以角标不能抢眼：
   · 默认灰底细边（.tb-bg），只有真正在跑时才带上主色和转圈；
   · 失败时才转成警告色 —— 那才是需要他处理的事；
   · 没有任务时整个盒子 display:none，工具条不留空位。
   ============================================================ */
.tb-bg-box{display:inline-flex;align-items:center}

.tb-bg{
  display:inline-flex;align-items:center;gap:var(--sp-1h);
  height:34px;padding:0 var(--sp-2h);
  border:1px solid var(--c-border);border-radius:var(--r-pill);
  background:var(--c-surface);color:var(--c-g700);
  font-size:var(--fs-xs);font-weight:500;cursor:pointer;
  transition:border-color .15s ease,background .15s ease;
}
.tb-bg:hover{border-color:var(--c-border-strong);background:var(--c-surface-alt)}
/* 进行中：主色描边 + 转圈，提示「有活正在干」但不闪烁（闪烁会持续抢注意力） */
.tb-bg.on{border-color:color-mix(in srgb,var(--c-primary) 45%,transparent);
  color:var(--c-primary)}
.tb-bg.on .spin{width:11px;height:11px;border-width:1.5px}
/* 失败：警告色。只有用户需要处理时才用强调色 */
.tb-bg.warn{border-color:color-mix(in srgb,var(--c-warn) 55%,transparent);
  background:color-mix(in srgb,var(--c-warn) 8%,var(--c-surface));
  color:color-mix(in srgb,var(--c-warn) 80%,#000)}
.tb-bg-t{white-space:nowrap}

/* 小尺寸转圈：工具条里的角标只有 11px，用 15px 会撑破 34px 的行高 */
.spin.xs{width:12px;height:12px;border-width:1.5px}

/* ---- 任务清单 ---- */
.bg-list{display:flex;flex-direction:column;gap:var(--sp-2h)}
.bg-row{
  border:1px solid var(--c-border);border-radius:var(--r-md);
  padding:var(--sp-2h) var(--sp-3);background:var(--c-surface);
}
/* 失败行左侧加一条警示边：一眼从清单里认出来该处理哪条 */
.bg-row.st-failed{border-left:3px solid var(--c-warn)}
.bg-row.st-done{border-left:3px solid var(--c-success)}

.bg-row-h{display:flex;align-items:center;gap:var(--sp-1h);min-width:0}
.bg-name{font-size:var(--fs-sm);font-weight:500;color:var(--c-g800);min-width:0;flex:1}
.bg-right{display:flex;align-items:center;gap:var(--sp-1h);flex:0 0 auto}
.bg-pct{font-size:var(--fs-xs);color:var(--c-primary);font-variant-numeric:tabular-nums}

.bg-badge{
  flex:0 0 auto;font-size:var(--fs-2xs);font-weight:600;
  padding:1px var(--sp-1h);border-radius:var(--r-sm);
  background:var(--c-g100);color:var(--c-g600);
}
.bg-badge.run{background:color-mix(in srgb,var(--c-primary) 12%,transparent);
  color:var(--c-primary)}
.bg-badge.ok{background:color-mix(in srgb,var(--c-success) 14%,transparent);
  color:color-mix(in srgb,var(--c-success) 82%,#000)}
.bg-badge.err{background:color-mix(in srgb,var(--c-warn) 16%,transparent);
  color:color-mix(in srgb,var(--c-warn) 85%,#000)}
.bg-badge.wait{background:var(--c-g100);color:var(--c-g500)}

/* 进度条：与全站其它进度条同一形态（细、无圆点、无动画条纹） */
.bg-bar{height:3px;border-radius:var(--r-pill);background:var(--c-g100);
  margin-top:var(--sp-1h);overflow:hidden}
.bg-bar i{display:block;height:100%;background:var(--c-primary);
  border-radius:var(--r-pill);transition:width .35s ease}

.bg-row-s{font-size:var(--fs-xs);color:var(--c-g500);margin-top:var(--sp-1h)}
.bg-preview{
  font-size:var(--fs-xs);color:var(--c-g600);margin-top:var(--sp-1h);
  padding:var(--sp-1h) var(--sp-2);border-radius:var(--r-sm);
  background:var(--c-surface-alt);line-height:1.5;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.bg-tail{margin-top:var(--sp-1h);font-size:var(--fs-xs)}
.bg-ok{color:color-mix(in srgb,var(--c-success) 82%,#000);font-weight:500}
.bg-err{color:color-mix(in srgb,var(--c-warn) 85%,#000);font-weight:500}

/* 窄屏：角标只留数字，文字藏掉 —— 工具条在手机上横向空间极紧。
   ★ 数字由 data-n 承载并在 ::after 里显示：直接隐藏 .tb-bg-t 会连同
     「3 个任务解析中」里的数字一起藏掉，角标就成了一个空的灰点。 */
@media (max-width:640px){
  .tb-bg{padding:0 var(--sp-1h);gap:var(--sp-0h)}
  .tb-bg-t{display:none}
  .tb-bg::after{content:attr(data-n);font-size:var(--fs-2xs);font-weight:600}
}

/* ============ 作品详情 · 图片墙（2026-10 v3.12.22） ============
   ★ 为什么必须补这段：作品库详情此前只有一个装正文的 textarea，
     工坊生成的图文卡片在作品库里**一张都看不见**（用户实测反馈）。
     现在 contents.images 落库后在此按序铺开，与正文一一对应。 */
.vc-wall{
  display:grid;
  /* 自适应列宽：卡片是 3:4 竖版，240px 一列在 1080px 宽的弹窗里刚好 4~5 列，
     窄屏自动降到 2 列，不需要写死断点。 */
  grid-template-columns:repeat(auto-fill,minmax(180px,1fr));
  gap:var(--sp-3);
  max-height:46vh;overflow-y:auto;padding:var(--sp-2);
  border:1px solid var(--c-border);border-radius:var(--r-md);
  background:var(--c-surface-alt);
}
.vc-shot{margin:0;display:flex;flex-direction:column;gap:var(--sp-1)}
.vc-shot a{display:block;border-radius:var(--r-sm);overflow:hidden;
  border:1px solid var(--c-border);background:var(--c-surface);line-height:0;
  transition:border-color .15s, box-shadow .15s}
.vc-shot a:hover{border-color:var(--c-primary-border);
  box-shadow:0 2px 8px rgba(15,27,45,.10)}
.vc-shot img,.vc-shot video{
  width:100%;height:auto;display:block;border-radius:inherit;
  background:var(--c-media-backdrop);
}
.vc-shot figcaption{
  font-size:var(--fs-2xs);color:var(--c-g500);
  text-align:center;
}
/* 无图作品的如实说明 —— 不用红色错误样式，这不是「出错」，是「这版没存」。 */
.vc-noimg{
  margin-bottom:var(--sp-3);padding:var(--sp-2) var(--sp-3);
  border:1px dashed var(--c-border-strong);border-radius:var(--r-md);
  background:var(--c-surface-alt);
  font-size:var(--fs-sm);color:var(--c-g600);line-height:1.7;
}
.vc-noimg .hint{display:block;margin-top:2px;font-size:var(--fs-xs);color:var(--c-g500)}

/* 作品库列表 · 封面缩略图（2026-10 v3.12.22）
   工坊产出的图文卡片是 3:4 竖版，用 40×52 的框裁切显示首图，
   右下角叠张数角标 —— 用户一眼能分清「12 张的成品」和「只有文字的草稿」。 */
/* ★ 封面占位：从「灰块 + 破图图标」改为「同族极浅底 + 内嵌发丝框」。
   破图的原因是 src 指向的图片已被清理（素材过期），而 <img> 仍在 DOM 里，
   浏览器就画出「撕角的图片图标」。JS 侧已在 onerror 里加 .is-broken 让图片隐藏，
   这里把占位底做得像「本来就没图」，而不是像是加载失败。 */
.cl-thumb{position:relative;display:inline-block;width:40px;height:52px;
  border-radius:var(--r-xs);overflow:hidden;background:var(--c-p0);
  border:1px solid var(--c-hairline);vertical-align:middle;cursor:pointer;
  transition:border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
.cl-thumb img{width:100%;height:100%;object-fit:cover;display:block}
/* 破图时 img 自身隐藏，露出同族浅底，避免出现浏览器默认的破图标记 */
.cl-thumb img.is-broken{display:none}
.cl-thumb:hover{border-color:rgba(30,58,95,.20);box-shadow:0 1px 3px rgba(19,26,38,.06)}
.cl-thumb-no{display:inline-flex;align-items:center;justify-content:center;
  color:var(--c-g300);font-size:var(--fs-xs);cursor:default;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.5)}
.cl-thumb-n{position:absolute;right:0;bottom:0;left:0;
  font-style:normal;font-size:var(--fs-2xs);font-weight:600;line-height:1.4;
  text-align:center;color:var(--c-on-dark);background:rgba(15,27,45,.62)}
/* ═══════════════════════════════════════════════════════════════════════
   ★ v4.0.0 · 设计规范统一层（SINGLE SOURCE OF TRUTH）

   ── 为什么要有这一层 ────────────────────────────────────────────────
   本文件在 v3.12.32 ~ v3.12.46 之间累积了 17 层「主题覆盖」，
   每一层都是为了修上一层的局部问题而追加在文件末尾：

     v3.12.32 3D 立体质感层      → 三层投影 + 位移
     v3.12.33 立体感增强          → 更大的位移 + 更重的投影
     v3.12.34 立体感静态化        → 把 v3.12.33 的位移全部改回 none
     v3.12.35 胶囊式立体菜单      → 侧栏胶囊重做（.nav-item 第 4 次定义）
     v3.12.35 续 细节补强         → 补上一层的遗漏
     v3.12.36 胶囊全量扩展        → 弹窗/输入/页签/图表全部胶囊化
     v3.12.37 亮蓝主题            → 换色（第 1 套）
     v3.12.38 黄蓝主题            → 换色（第 2 套）
     v3.12.39 蓝白主题            → 换色（第 3 套）
     v3.12.40 苹果配色            → 换色（第 4 套）
     v3.12.41 浅灰打底            → 换色（第 5 套，与 40 反转）
     v3.12.42 蓝底灰点缀          → 换色（第 6 套，与 41 反转）
     v3.12.43 深蓝主题            → 换色（第 7 套）★ 最终生效
     v3.12.44 模块组浅蓝底        → 卡片底色覆盖
     v3.12.45 侧栏分组胶囊化      → 侧栏第 5 次定义
     v3.12.46 键帽式厚度          → 侧栏第 6 次、卡片第 5 次、按钮第 4 次定义

   代价不是「文件长」（4145 行本身不算多），而是**读不出终值**：
     · .nav-item         被定义 6 次，.card 5 次，.btn.pri 4 次
     · 想改卡片投影，必须翻到 4130 行才知道 v3.12.46 覆盖了 v3.12.43
     · 7 套色板里 6 套是死代码，但每一套都真实参与过层叠计算
     · v3.12.37~42 的 :root 仍在覆盖 --c-primary，靠 43 行再覆盖回来 ——
       任何一处漏写就等于「回到亮蓝色」，这是真实存在的回归风险
   本轮按用户确认的基准（保持当前深蓝胶囊风）把这 17 层**收敛为一份**，
   终值与逐层叠加的视觉结果等价，不再保留死层。

   ── 设计基准（对外可引用的三句话）──────────────────────────────────
   1. 底色：极浅蓝灰渐变打底，白色卡浮在其上（一屏只有两层「面」）
   2. 立体：不是靠位移，是靠「顶部 1px 受光 + 底部内压暗 + 外落影」
           三件套；全站零位移（v3.12.34 起的既定要求，本轮延续）
   3. 形状：交互物（按钮/输入/页签/筛选/分页）一律胶囊 999px；
           容器（卡片/弹窗/图表）一律 16px 大圆角
   ═══════════════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────────────────────────────────────────
   1. 色板 · 深蓝主色（唯一一套，替换 v3.12.37~43 的七次换色）
   ───────────────────────────────────────────────────────────────────── */
:root{
  /* 主色阶：p9 深 → p5 浅，供背景/描边/图标分层取用 */
  --c-primary:#1D4E9E;          /* 主色：主按钮底、选中态、链接、数字 */
  --c-primary-hover:#163E82;    /* 主色按下/hover 加深 */
  --c-primary-lift:#3568BE;     /* 主色受光面：按钮渐变顶部 */
  --c-primary-soft:#E6EEF9;     /* 主色软底：选中胶囊、标签底 */
  --c-primary-deep:#122E63;     /* 主色最深处：品牌渐变起点、标题点渐变底 */
  --c-p5:#8FA8CF;               /* 主色 20% 明度：hover 描边、次级图标 */
  --c-p7:#3B619F;               /* 主色 60% 明度：图标深档 */
  --c-p9:#1D4E9E;               /* = primary，供「明确要 p9」的旧调用点 */
  --grad-brand:linear-gradient(135deg,#122E63 0%,#1D4E9E 55%,#3568BE 100%);
  --ring-primary:0 0 0 3px rgba(29,78,158,.15);   /* 焦点环 */

  /* 交互元素的墨色系（按钮/标签的文字与描边深档） */
  --c-ink-btn:#25344E;          /* 次级按钮文字 */
  --c-border-btn:#CBD4E2;       /* 次级按钮描边 */
  --c-border-chip:#7C9CCB;      /* 选中 chip 描边 */

  /* 页面层级四层（background → surface → elevated → overlay） */
  --c-app-bg-1:#EEF2F8;         /* 内容区渐变起点 */
  --c-app-bg-2:#E8EDF5;         /* 内容区渐变终点 */
  --c-surface:#FFFFFF;          /* 卡片面 */
  --c-surface-sunken:#F6F8FC;   /* 图表槽底（内凹面） */
  --c-hairline:#DCE3EE;         /* 卡片发丝描边 */
  --c-hairline-strong:#C9D4E6;  /* 卡片 hover 描边 */

  /* 侧栏（深海军蓝）专用：半透明白阶，随底色自动协调 */
  --c-side-bg-1:#122A5C;
  --c-side-bg-2:#0C1F47;
  --c-side-bg-3:#091736;
  --c-side-text:#FFFFFF;                    /* 侧栏主文字 */
  --c-side-text-sub:rgba(255,255,255,.72);  /* 分组名/版本号/页脚 */
  --c-side-line:rgba(255,255,255,.10);      /* 分隔线 */
  --c-side-line-strong:rgba(255,255,255,.16);/* 选中胶囊描边 */
  --c-side-veil-1:rgba(255,255,255,.10);    /* 胶囊顶面 */
  --c-side-veil-2:rgba(255,255,255,.04);    /* 胶囊中段 */
  --c-side-veil-3:rgba(255,255,255,.16);    /* 胶囊 hover 顶面 */
  --c-side-veil-4:rgba(255,255,255,.06);    /* 胶囊 hover 中段 */
  --c-side-shade:rgba(3,10,26,.24);         /* 胶囊底面压暗 */

  /* 阴影墨色：全站阴影统一从这一个颜色派生，改一处即全站统一 */
  --c-shade:18,46,96;           /* rgb 分量，供 rgba(var(--c-shade),a) 使用 */
  --c-shade-deep:3,10,26;       /* 侧栏深影分量 */
}

/* ─────────────────────────────────────────────────────────────────────
   2. 全局面：内容区底色 + 文字色
   ───────────────────────────────────────────────────────────────────── */
.layout{background:linear-gradient(180deg,var(--c-app-bg-1) 0%,var(--c-app-bg-2) 100%)}
.card-title,.tb-title{color:#15243F}
.topbar{box-shadow:0 1px 0 rgba(var(--c-shade),.06),0 4px 14px rgba(var(--c-shade),.05)}

/* ─────────────────────────────────────────────────────────────────────
   3. 侧栏：深海军蓝渐变 + 键帽式胶囊菜单
      （合并 v3.12.32 / 33 / 35 / 43 / 45 / 46 六次定义）
   ───────────────────────────────────────────────────────────────────── */
.sidebar{
  background:linear-gradient(180deg,var(--c-side-bg-1) 0%,var(--c-side-bg-2) 55%,var(--c-side-bg-3) 100%);
  box-shadow:6px 0 24px rgba(6,16,40,.36),12px 0 40px rgba(6,16,40,.22);
  scrollbar-color:rgba(255,255,255,.20) rgba(var(--c-shade-deep),.25);
}
.sb-brand{border-bottom:1px solid var(--c-side-line)}
.sb-foot{border-top:1px solid var(--c-side-line)}
.sb-name{color:var(--c-side-text)}
.sb-sub,.sb-group,.sb-ver,.sb-foot{color:var(--c-side-text-sub)}
.sb-logo{
  background:linear-gradient(135deg,var(--c-primary-deep),var(--c-primary-lift));
  /* 厚度边（v3.12.46 键帽语言）+ 顶光 + 内压暗 */
  box-shadow:0 4px 0 rgba(var(--c-shade-deep),.50),0 9px 16px rgba(var(--c-shade-deep),.42),
             inset 0 2px 0 rgba(255,255,255,.30),inset 0 -3px 5px rgba(var(--c-shade-deep),.32);
}

/* 3.1 分组标题：小胶囊徽章（v3.12.45） */
.sb-group{
  margin:10px 12px 6px;padding:4px 10px;width:auto;
  display:inline-flex;align-items:center;
  border-radius:var(--r-pill);
  background:linear-gradient(180deg,rgba(255,255,255,.10),rgba(255,255,255,.04));
  border:1px solid var(--c-side-line);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14),0 2px 0 rgba(var(--c-shade-deep),.45),0 4px 8px rgba(var(--c-shade-deep),.30);
  color:rgba(255,255,255,.85);font-weight:600;letter-spacing:.06em;
}
.layout.collapsed .sb-group{display:none}

/* 3.2 菜单胶囊：未选中 = 凹槽，hover = 抬起一档，选中 = 主色高光键帽 */
.nav-item{
  height:44px;margin:7px 12px;padding:0 13px;border-radius:var(--r-pill);
  background:linear-gradient(180deg,var(--c-side-veil-1) 0%,var(--c-side-veil-2) 45%,var(--c-side-shade) 100%);
  border:1px solid rgba(255,255,255,.09);
  color:rgba(255,255,255,.86);
  box-shadow:inset 0 2px 0 rgba(255,255,255,.20),
             inset 0 -3px 5px rgba(var(--c-shade-deep),.32),
             0 4px 0 rgba(5,16,44,.55),
             0 8px 14px rgba(var(--c-shade-deep),.40),
             0 2px 4px rgba(var(--c-shade-deep),.32);
}
.nav-item:hover{
  background:linear-gradient(180deg,var(--c-side-veil-3) 0%,var(--c-side-veil-4) 45%,var(--c-side-shade) 100%);
  color:#FFFFFF;
  box-shadow:inset 0 2px 0 rgba(255,255,255,.24),
             inset 0 -3px 5px rgba(var(--c-shade-deep),.32),
             0 4px 0 rgba(5,16,44,.58),
             0 10px 18px rgba(var(--c-shade-deep),.44),
             0 2px 4px rgba(var(--c-shade-deep),.34);
}
/* 选中：主色键帽（顶面受光 → 中段主色 → 底部压暗），按下 1px 贴合键位 */
.nav-item.on{
  background:linear-gradient(180deg,var(--c-primary-lift) 0%,var(--c-primary) 45%,var(--c-primary-hover) 100%);
  border-color:var(--c-side-line-strong);
  color:#FFFFFF;font-weight:600;
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.34),
             inset 0 -3px 5px rgba(var(--c-shade-deep),.34),
             0 3px 0 rgba(5,16,44,.50),
             0 8px 18px rgba(var(--c-shade-deep),.46),
             0 2px 4px rgba(var(--c-shade-deep),.36);
}
.nav-item.on .nav-ico{opacity:1;text-shadow:0 1px 2px rgba(var(--c-shade-deep),.35)}
.nav-item.on .nav-badge{background:#FFFFFF;color:var(--c-primary-hover)}
.nav-badge{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.32),0 2px 0 rgba(120,20,30,.45),0 3px 6px rgba(var(--c-shade-deep),.38);
}
.layout.collapsed .nav-item{margin:6px 10px;padding:0;justify-content:center}

/* 3.3 侧栏滚动条 */
.sidebar::-webkit-scrollbar{width:8px}
.sidebar::-webkit-scrollbar-thumb{
  background:linear-gradient(180deg,rgba(255,255,255,.22),rgba(255,255,255,.10));
  border-radius:4px;border:2px solid transparent;background-clip:padding-box;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08);
}
.sidebar::-webkit-scrollbar-track{background:rgba(var(--c-shade-deep),.28)}

/* ─────────────────────────────────────────────────────────────────────
   4. 卡片 / 指标卡：白面浮在蓝灰底上
      （合并 v3.12.32 / 33 / 34 / 36 / 43 / 44 / 46 七次定义）
   ───────────────────────────────────────────────────────────────────── */
.card,.stat{
  background:var(--c-surface);background-image:none;
  border:1px solid var(--c-hairline);
  border-radius:var(--r-xl);
  /* 三层投影：贴边 contact + 主体 key + 环境 ambient；底部再压一道厚度边 */
  box-shadow:0 1px 2px rgba(var(--c-shade),.05),
             0 4px 12px rgba(var(--c-shade),.07),
             0 5px 0 rgba(var(--c-shade),.06),
             0 10px 20px rgba(var(--c-shade),.08),
             inset 0 1.5px 0 rgba(255,255,255,.95);
}
.card:hover,.stat:hover{
  transform:none;   /* 全站零位移（v3.12.34 既定） */
  border-color:var(--c-hairline-strong);
  box-shadow:0 2px 4px rgba(var(--c-shade),.06),
             0 8px 22px rgba(var(--c-shade),.09),
             0 6px 0 rgba(var(--c-shade),.07),
             0 14px 28px rgba(var(--c-shade),.10),
             inset 0 1.5px 0 rgba(255,255,255,.95);
}
.card:active,.stat:active{transform:none}
.card-head{border-bottom-color:rgba(var(--c-shade),.08)}

/* 4.1 卡头前缀点：主色立体小圆珠 */
.card-title::before{
  background:linear-gradient(180deg,var(--c-primary-lift),var(--c-primary-deep));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.5),0 1px 2px rgba(var(--c-shade),.3);
}
/* 4.2 指标卡：左侧主色竖条 + 数字浮雕 */
.stat::before,.stat.acc::before{background:var(--c-primary);border-radius:0 var(--r-pill) var(--r-pill) 0}
.stat .num,.stat.acc .num{color:var(--c-primary);text-shadow:0 1.5px 0 rgba(255,255,255,.7)}

/* 4.3 图表卡：canvas 嵌在内凹槽里 */
.card:has(canvas) canvas,.card:has(.chart-body) canvas,.card:has(.kchart) canvas{
  border-radius:var(--r-md);
  background:linear-gradient(180deg,#FAFBFD 0%,var(--c-surface-sunken) 100%);
  border:1px solid rgba(255,255,255,.7);
  box-shadow:inset 0 2px 6px rgba(var(--c-shade),.09),inset 0 6px 14px rgba(var(--c-shade),.05);
  padding:6px;box-sizing:border-box;
}
.card canvas{filter:drop-shadow(0 3px 8px rgba(var(--c-shade),.06))}

/* ─────────────────────────────────────────────────────────────────────
   5. 按钮：胶囊 + 受光凸面 + 键帽厚度
      （合并 v3.12.32 / 33 / 35 / 36 / 43 / 46 六次定义）
   ───────────────────────────────────────────────────────────────────── */
.btn{border-radius:var(--r-pill)}
.btn.pri{
  background:linear-gradient(180deg,var(--c-primary-lift) 0%,var(--c-primary) 72%);
  color:#FFFFFF;border-color:var(--c-primary-hover);
  box-shadow:0 1.5px 4px rgba(0,102,204,.24),0 3px 0 rgba(10,45,110,.42),0 7px 14px rgba(var(--c-shade),.24),
             inset 0 1.5px 0 rgba(255,255,255,.26),inset 0 -2px 4px rgba(6,18,44,.26);
}
.btn.pri:hover{
  background:linear-gradient(180deg,var(--c-primary-lift) 0%,var(--c-primary-hover) 78%);
  box-shadow:0 1.5px 4px rgba(0,102,204,.26),0 4px 0 rgba(10,45,110,.46),0 10px 20px rgba(var(--c-shade),.28),
             inset 0 1.5px 0 rgba(255,255,255,.28),inset 0 -2px 4px rgba(6,18,44,.26);
  transform:none;
}
.btn.pri:active{
  transform:translateY(2px);
  box-shadow:inset 0 2px 5px rgba(6,18,44,.34),0 1px 2px rgba(var(--c-shade),.10);
}
.btn.sec{
  background:linear-gradient(180deg,#FFFFFF,#EFF2F7);
  color:var(--c-ink-btn);border-color:var(--c-border-btn);
  box-shadow:0 1.5px 3px rgba(var(--c-shade),.08),0 3px 0 rgba(var(--c-shade),.07),0 5px 10px rgba(var(--c-shade),.06),
             inset 0 1px 0 rgba(255,255,255,.9);
}
.btn.sec:hover{
  background:#FFFFFF;border-color:var(--c-primary);color:var(--c-primary);
  box-shadow:0 2px 4px rgba(var(--c-shade),.08),0 3px 0 rgba(var(--c-shade),.08),0 8px 16px rgba(var(--c-shade),.08),
             inset 0 1px 0 rgba(255,255,255,.9);
  transform:none;
}
.btn.sec:active,.btn.ghost:active{transform:translateY(1px)}
/* 语义变体统一到主色系（原 .acc/.ok 是青色，与深蓝主题冲突，v3.12.43 已改，此处固化） */
.btn.acc,.btn.ok{
  background:linear-gradient(180deg,var(--c-primary-lift) 0%,var(--c-primary) 75%);
  border-color:var(--c-primary-hover);color:#FFFFFF;
  box-shadow:0 1.5px 4px rgba(0,102,204,.22),0 3px 0 rgba(10,45,110,.42),0 7px 14px rgba(var(--c-shade),.22),
             inset 0 1.5px 0 rgba(255,255,255,.26),inset 0 -2px 4px rgba(6,18,44,.26);
}
.btn.acc:hover,.btn.ok:hover{
  background:linear-gradient(180deg,var(--c-primary-lift) 0%,var(--c-primary-hover) 80%);
  border-color:var(--c-primary-hover);
  box-shadow:0 1.5px 4px rgba(0,102,204,.24),0 4px 0 rgba(10,45,110,.46),0 10px 20px rgba(var(--c-shade),.26),
             inset 0 1.5px 0 rgba(255,255,255,.28),inset 0 -2px 4px rgba(6,18,44,.26);
}
.btn.dan,.btn.danger,.btn.del{
  box-shadow:0 1.5px 4px rgba(160,44,39,.22),0 3px 0 rgba(120,26,22,.42),0 7px 14px rgba(120,26,22,.20),
             inset 0 1.5px 0 rgba(255,255,255,.22),inset 0 -2px 4px rgba(60,10,8,.22);
}
.btn.dan:active,.btn.danger:active,.btn.del:active{
  transform:translateY(2px);
  box-shadow:inset 0 2px 5px rgba(60,10,8,.30);
}
.btn:disabled,.btn.pri:disabled,.btn.sec:disabled{transform:none;box-shadow:0 1px 2px rgba(var(--c-shade),.06);opacity:.55}
.tb-actions .btn{box-shadow:0 1.5px 3px rgba(var(--c-shade),.08),inset 0 1px 0 rgba(255,255,255,.85)}
.tb-actions .btn.pri{
  box-shadow:0 2px 3px rgba(var(--c-shade),.16),0 3px 0 rgba(10,45,110,.42),0 5px 12px rgba(var(--c-shade),.22),
             inset 0 1.5px 0 rgba(255,255,255,.26),inset 0 -3px 5px rgba(9,15,26,.20);
}

/* ─────────────────────────────────────────────────────────────────────
   6. 表单与选项：输入/下拉/页签/筛选/分页 全胶囊
      （合并 v3.12.36 + v3.12.43）
   ───────────────────────────────────────────────────────────────────── */
.input,.select{border-radius:var(--r-pill)}
.textarea{border-radius:var(--r-lg)}
.chip{border-radius:var(--r-pill)}
.chip:hover,.chip:active{transform:none}
.chip.on{
  background:var(--c-primary-soft);color:var(--c-primary);border-color:var(--c-border-chip);
  box-shadow:inset 0 0 0 1px rgba(var(--c-shade),.12),inset 0 1px 0 rgba(255,255,255,.7),0 2px 6px rgba(var(--c-shade),.18);
}
.tabs{position:relative}
.tab{border-bottom:none;border-radius:var(--r-pill);margin-bottom:0;padding:7px 15px}
.tab.on{
  background:var(--c-primary-soft);color:var(--c-primary);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9);
}
.pager .pg{
  border-radius:var(--r-pill);
  background:linear-gradient(180deg,#FFFFFF,#EFF2F7);border-color:var(--c-border-btn);color:var(--c-ink-btn);
}
.pager .pg.on{background:var(--c-primary);border-color:var(--c-primary);color:#FFFFFF}
.chk input{box-shadow:inset 0 1px 2px rgba(var(--c-shade),.18)}
.card .btn.xs,.card .btn.sm{border-radius:var(--r-pill)}
.badge.pri{border-color:rgba(var(--c-shade),.22)}

/* ─────────────────────────────────────────────────────────────────────
   7. 弹窗 / 轻提示
   ───────────────────────────────────────────────────────────────────── */
.modal{
  border-radius:var(--r-xl);
  border:1px solid rgba(255,255,255,.6);
  box-shadow:0 2px 6px rgba(var(--c-shade),.10),0 18px 44px rgba(var(--c-shade),.20),0 48px 100px rgba(var(--c-shade),.24),
             inset 0 1.5px 0 rgba(255,255,255,.95);
  animation:pop .18s cubic-bezier(.16,1,.3,1);
}
.modal-head{background:linear-gradient(180deg,rgba(127,168,216,.10),rgba(127,168,216,0) 90%)}
.modal-head .x{
  width:30px;height:30px;border-radius:var(--r-pill);display:flex;align-items:center;justify-content:center;
  background:linear-gradient(180deg,#FFFFFF,#F1F4F9);
  border:1px solid var(--c-border);
  box-shadow:0 1.5px 3px rgba(var(--c-shade),.10),inset 0 1px 0 rgba(255,255,255,.9);
}
.modal-head .x:hover{
  background:linear-gradient(180deg,#FFFFFF,#E9EEF5);
  box-shadow:0 2px 5px rgba(var(--c-shade),.14),inset 0 1px 0 rgba(255,255,255,.9);color:var(--c-danger);
}
.modal-foot{background:linear-gradient(180deg,rgba(249,251,253,0),rgba(240,244,249,.6))}
.modal .input,.modal .select{border-radius:var(--r-pill)}
.modal .textarea{border-radius:var(--r-lg)}
.modal .btn{border-radius:var(--r-pill)}
.modal .btn.sec{
  box-shadow:0 1.5px 3px rgba(var(--c-shade),.08),0 3px 0 rgba(var(--c-shade),.07),0 8px 16px rgba(var(--c-shade),.06),
             inset 0 1px 0 rgba(255,255,255,.9),inset 0 -2px 3px rgba(var(--c-shade),.035);
}
.toast{
  box-shadow:0 3px 6px rgba(9,15,26,.18),0 14px 36px rgba(9,15,26,.30),
             inset 0 1px 0 rgba(255,255,255,.20);
}

/* ─────────────────────────────────────────────────────────────────────
   8. 动效约束：只允许「颜色 / 阴影」过渡，禁止位移
   ───────────────────────────────────────────────────────────────────── */
.card,.stat{transition:border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
.btn{transition:background .15s ease,border-color .15s ease,color .15s ease,box-shadow .15s ease}
.nav-item{transition:background var(--dur) var(--ease),box-shadow var(--dur) var(--ease),color var(--dur) var(--ease)}
@media (prefers-reduced-motion:reduce){
  .modal{animation:none}
  .btn.pri:active,.btn.dan:active,.btn.sec:active,.btn.ghost:active,.btn.del:active{transform:none}
}

/* ─────────────────────────────────────────────────────────────────────
   9. 焦点可见性（键盘可达性）：全站统一主色焦点环
   ───────────────────────────────────────────────────────────────────── */
:where(a,button,input,select,textarea,[tabindex]):focus-visible{
  outline:2px solid var(--c-primary);outline-offset:2px;border-radius:var(--r-sm);
}
.input:focus,.select:focus,.textarea:focus{box-shadow:var(--ring-primary);border-color:var(--c-primary)}

/* ═════════════════════════════════════════════════════════════════════
   10. 企业邮箱（三栏 Outlook 式）
   ─────────────────────────────────────────────────────────────────────
   ★ 布局为什么用 grid 而不是 flex 三块：
     三栏的宽度关系是「两个定值 + 一个自适应」，grid 的
     `180px 340px 1fr` 一行就把它说清楚了；flex 需要给前两块各写
     flex:0 0 Npx、第三块写 flex:1，还得防 shrink —— 三行代码换一个
     同样的结果，且改宽度时要动三处。
   ★ 高度为什么用 calc(100vh - Npx)：
     邮箱是「整屏工作台」，最怕的是整页跟着内容滚动 —— 那样左栏文件夹树
     会跟着长列表一起滚走，用户翻到第 40 封时已经不知道该点哪个文件夹。
     这里让三个栏各自内部滚动，外层不滚。
   ★ 小屏（<1100px）退化为「左栏折叠 + 两栏」：
     340px 列表 + 正文在 1100 以下会挤到正文只剩 300px，读不了邮件。
   ═════════════════════════════════════════════════════════════════════ */
.mb-wrap{
  display:grid;grid-template-columns:186px 340px 1fr;
  height:calc(100vh - 152px);min-height:520px;
  border:1px solid var(--c-border);border-radius:var(--r-lg);
  background:var(--c-surface);overflow:hidden;
  box-shadow:var(--shadow-sm);
}

/* ─── 左栏：文件夹 ─── */
.mb-side{display:flex;flex-direction:column;background:var(--c-surface-alt);
  border-right:1px solid var(--c-border);min-width:0}
.mb-side-head{padding:14px 14px 10px;border-bottom:1px solid var(--c-border)}
.mb-account{font-size:var(--fs-sm);font-weight:600;color:var(--c-ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mb-account-sub{font-size:var(--fs-xs);color:var(--c-g500);margin-top:3px}
.mb-account-sub.warn{color:var(--c-warn)}
.mb-folder-list{flex:1;overflow:auto;padding:8px 8px 4px}
.mb-folder{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:var(--r-sm);
  cursor:pointer;font-size:var(--fs-sm);color:var(--c-g700);user-select:none}
.mb-folder:hover{background:var(--c-primary-tint)}
.mb-folder.on{background:var(--c-primary-soft);color:var(--c-primary);font-weight:600}
.mb-fi{width:16px;text-align:center;color:var(--c-g500);font-size:var(--fs-sm)}
.mb-folder.on .mb-fi{color:var(--c-primary)}
.mb-ft{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ★ v4.0.6 对比度整改：本模块（企业邮箱）四处"最弱文字"原统一用 --c-g400，
   实算 2.25:1 —— 只差一个档就接近"看不见"。时间、摘要、附件大小是
   **扫读界面时的定位锚点**（用户靠"17:07"和摘要首句判断哪封信），
   不是可省略的装饰，必须读得清。改用 --c-g500（已升至 5.09:1）。
   ★ 为什么不直接升到 --c-g600：列表里三行文字要拉开层次
     （发件人 g800 粗体 > 主题 g600 > 摘要/时间 g500），全升到 g600
     会让"主题"和"摘要"糊成一片，反而更难扫。 */
.mb-fn{font-size:var(--fs-xs);color:var(--c-g500);font-variant-numeric:tabular-nums}
/* 未读角标：原 color:#fff 字面量 → 令牌（同时符合 verify_design_tokens 的约束） */
.mb-badge{background:var(--c-primary);color:var(--c-surface);font-size:var(--fs-2xs);line-height:1;
  padding:3px 6px;border-radius:var(--r-pill);font-variant-numeric:tabular-nums}
.mb-side-foot{padding:10px 14px;border-top:1px solid var(--c-border);display:grid;gap:6px}
.mb-chk{display:flex;align-items:center;gap:6px;font-size:var(--fs-xs);
  color:var(--c-g600);cursor:pointer}
.mb-chk input{margin:0}

/* ─── 中栏：列表 ─── */
.mb-list{display:flex;flex-direction:column;border-right:1px solid var(--c-border);min-width:0}
.mb-list-head{display:flex;gap:6px;padding:10px;border-bottom:1px solid var(--c-border)}
.mb-search{flex:1;height:32px;font-size:var(--fs-sm)}
.mb-list-body{flex:1;overflow:auto}
.mb-list-foot{display:flex;align-items:center;justify-content:space-between;
  gap:8px;padding:8px 10px;border-top:1px solid var(--c-border);background:var(--c-surface-alt)}
.mb-pg-btns{display:flex;gap:6px}

.mb-item{padding:10px 12px;border-bottom:1px solid var(--c-g100);cursor:pointer;
  transition:background var(--dur) var(--ease)}
.mb-item:hover{background:var(--c-primary-tint)}
.mb-item.on{background:var(--c-primary-soft);box-shadow:inset 3px 0 0 var(--c-primary)}
.mb-item-top{display:flex;align-items:center;gap:7px;margin-bottom:5px}
.mb-av{width:22px;height:22px;border-radius:50%;color:var(--c-surface);font-size:var(--fs-2xs);font-weight:600;
  display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;line-height:1}
.mb-item-who{flex:1;font-size:var(--fs-sm);color:var(--c-g800);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mb-item.unread .mb-item-who{font-weight:700;color:var(--c-ink)}
.mb-item-time{font-size:var(--fs-xs);color:var(--c-g500);flex:0 0 auto;
  font-variant-numeric:tabular-nums}
.mb-item-subj{font-size:var(--fs-sm);color:var(--c-g600);margin-bottom:3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mb-item.unread .mb-item-subj{color:var(--c-ink);font-weight:600}
.mb-item-snip{font-size:var(--fs-xs);color:var(--c-g500);line-height:1.5;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.mb-star{color:var(--c-warn);margin-right:3px}
.mb-clip{opacity:.55;margin-right:3px}

/* ─── 右栏：阅读窗格 ─── */
.mb-read{display:flex;flex-direction:column;min-width:0;overflow:hidden}
.mb-read-empty{flex:1;display:flex;align-items:center;justify-content:center}
.mb-read-head{display:flex;align-items:flex-start;gap:12px;padding:14px 18px 10px;
  border-bottom:1px solid var(--c-border)}
.mb-read-subj{flex:1;font-size:var(--fs-lg);font-weight:600;color:var(--c-ink);
  line-height:1.4;word-break:break-word}
.mb-read-acts{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end;flex:0 0 auto}
.mb-read-meta{display:flex;gap:10px;align-items:flex-start;padding:12px 18px;
  border-bottom:1px solid var(--c-g100);background:var(--c-surface-alt)}
.mb-read-meta .mb-av{width:32px;height:32px;font-size:var(--fs-md)}
.mb-read-meta-t{flex:1;min-width:0;line-height:1.6}
.mb-read-from{font-size:var(--fs-sm);font-weight:600;color:var(--c-ink)}
.mb-atts{display:flex;flex-wrap:wrap;gap:8px;padding:10px 18px;
  border-bottom:1px solid var(--c-g100);align-items:center}
.mb-atts .mb8{flex:0 0 100%}
.mb-att{display:inline-flex;align-items:center;gap:6px;padding:5px 10px;
  border:1px solid var(--c-border);border-radius:var(--r-pill);
  font-size:var(--fs-xs);color:var(--c-g700);background:var(--c-surface);
  text-decoration:none;max-width:100%}
.mb-att:hover{border-color:var(--c-primary-border);background:var(--c-primary-tint);
  color:var(--c-primary);text-decoration:none}
.mb-att-n{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:220px}
.mb-att-s{color:var(--c-g500)}
/* 正文容器：iframe 是唯一子元素，必须 flex:1 + min-height:0，
   否则 iframe 的默认 150px 高会在长正文下把外层撑出滚动条 */
.mb-body{flex:1;min-height:0;overflow:hidden;display:flex}
.mb-frame{flex:1;width:100%;border:0;background:#fff}
.mb-body-empty{padding:24px 18px;color:var(--c-g500);font-size:var(--fs-sm)}

/* ─── 写信弹窗 ─── */
.mb-cmp{display:flex;flex-direction:column;gap:10px}
.mb-cmp-row{display:grid;grid-template-columns:56px 1fr;gap:10px;align-items:center}
.mb-cmp-row label{font-size:var(--fs-sm);color:var(--c-g600);text-align:right}
.mb-cmp-body{width:100%;min-height:300px;line-height:1.7;resize:vertical;
  font-family:inherit;font-size:var(--fs-sm)}
.mb-cmp-atts{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:6px}
.mb-cmp-att{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;
  border:1px solid var(--c-warn-border);background:var(--c-warn-tint);
  border-radius:var(--r-sm);font-size:var(--fs-xs);color:var(--c-g700)}
.mb-cmp-att em{color:var(--c-g500);font-style:normal}
.mb-cmp-att b{cursor:pointer;color:var(--c-g500);font-weight:400;padding:0 2px}
.mb-cmp-att b:hover{color:var(--c-danger)}
.mb-cmp-att-bar{display:flex;align-items:center;gap:10px}

/* ─── 配置弹窗 ─── */
.mb-cfg{display:flex;flex-direction:column;gap:12px}
.mb-cfg .fld label{font-size:var(--fs-sm);color:var(--c-g600);display:block;margin-bottom:5px}
.mb-pw-row{display:flex;align-items:center;gap:8px}
.mb-pw-row .input{flex:1}
.mb-cfg-more{border:1px solid var(--c-border);border-radius:var(--r-md);padding:10px 12px;
  background:var(--c-surface-alt)}
.mb-cfg-more summary{cursor:pointer;font-size:var(--fs-sm);color:var(--c-g700);
  user-select:none}
.mb-test-row{display:flex;align-items:center;gap:8px;padding:3px 0;font-size:var(--fs-sm)}

/* ─── 小屏退化：<1100px 收掉左栏宽度、<900px 单栏 ─── */
@media (max-width:1100px){
  .mb-wrap{grid-template-columns:150px 290px 1fr}
}
@media (max-width:900px){
  .mb-wrap{grid-template-columns:136px 1fr;height:auto}
  .mb-read{display:none}
  .mb-list{height:calc(100vh - 180px)}
}

/* 邮箱配置弹窗 · 自动收信区块（v4.0.2）
   ★ 单独给一条上边线而不是套 .card：它和上面的「服务器参数」是同一份
     配置的两个部分，视觉上应该连着，不该被卡片边框切成两块。 */
.mb-cfg-auto { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--line, #e3e8ef); }
.mb-cfg-auto .grp-h2 { font: 600 13px/1.6 inherit; color: var(--ink, #1f2733); margin-bottom: 8px; }

/* ============================================================
   抖音发布页（v4.2.0）
   ------------------------------------------------------------
   ★ 为什么全部用 .dy- 前缀且只在本段新增：
     本页是独立模块，样式不扩散到别处；同时避免与既有 .mb-（邮箱）
     .st-（工坊）等前缀撞名。前缀式命名是本项目的老规矩。
   ★ 颜色一律取 CSS 变量，不写死色值：
     对比度整改（v4.0.6）是靠调变量完成的，写死色值会让本页在未来
     一次主题调整中掉队 —— 视觉探针会直接报不达 AA。
   ============================================================ */
.dy-wrap{display:flex;flex-direction:column;gap:var(--sp-3)}

/* 顶部结论条：一句话说清「现在走哪条路、卡在哪」 */
.dy-hero{border-radius:var(--r-lg);border:1px solid var(--c-border);
  background:var(--c-surface);box-shadow:var(--shadow-card);overflow:hidden}
.dy-hero-in{display:flex;align-items:flex-start;justify-content:space-between;
  gap:var(--sp-3);padding:16px 18px;flex-wrap:wrap}
.dy-hero-l{display:flex;gap:12px;align-items:flex-start;min-width:0;flex:1}
.dy-hero-dot{width:10px;height:10px;border-radius:50%;margin-top:7px;flex:0 0 auto}
/* 三种状态色：未配置（灰）/ 已配但未授权（琥珀）/ 就绪（青绿）。
   ★ 不只靠颜色区分：右侧还有一枚文字 chip，色盲用户也读得懂。 */
.dy-hero-in.dy-ok .dy-hero-dot{background:var(--c-accent);box-shadow:0 0 0 3px var(--c-accent-soft)}
.dy-hero-in.dy-warn .dy-hero-dot{background:var(--c-warn);box-shadow:0 0 0 3px var(--c-warn-soft)}
.dy-hero-in.dy-none .dy-hero-dot{background:var(--c-g400);box-shadow:0 0 0 3px var(--c-g100)}
.dy-hero-t{font-size:var(--fs-lg);font-weight:650;color:var(--c-ink);margin-bottom:4px}
.dy-hero-s{font-size:var(--fs-sm);color:var(--c-text-sub);line-height:1.75}
.dy-hero-r{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.dy-chip{font-size:var(--fs-xs);padding:3px 10px;border-radius:999px;
  border:1px solid var(--c-border);background:var(--c-g50);color:var(--c-g700);white-space:nowrap}
.dy-chip.ok{background:var(--c-accent-soft);color:var(--c-accent-ink);border-color:var(--c-accent-soft)}
.dy-chip.warn{background:var(--c-warn-soft);color:var(--c-warn);border-color:var(--c-warn-soft)}
.dy-chip.none{background:var(--c-g100);color:var(--c-g700)}
.dy-hero-err{padding:16px 18px;color:var(--c-warn);font-size:var(--fs-sm);line-height:1.9}
.dy-hero-err b{color:var(--c-ink);display:block;margin-bottom:4px}

/* 子标签：与全站标签栏一致的两态，但不复用 .mb- 的结构（那是三栏专用的） */
.dy-tabs{display:flex;gap:4px;border-bottom:1px solid var(--c-border);padding-bottom:0}
.dy-tab{border:0;background:transparent;padding:9px 16px;font-size:var(--fs-sm);
  color:var(--c-text-sub);cursor:pointer;border-bottom:2px solid transparent;
  font-family:inherit;border-radius:var(--r-sm) var(--r-sm) 0 0}
.dy-tab:hover{color:var(--c-primary);background:var(--c-primary-soft)}
.dy-tab.on{color:var(--c-primary);font-weight:600;border-bottom-color:var(--c-primary)}

.dy-body{padding-top:var(--sp-3)}
.dy-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-3)}
.dy-card{display:flex;flex-direction:column}
/* ★ 等高卡片里的内容不要被拉变形：
     .dy-grid 默认 align-items:stretch，两张卡会等高（这是我们要的，
     参差不齐更难看）。但等高之后，内容少的那张底部会留一大片空白 ——
     实测「应用凭据」比「授权与令牌」高出约 120px。
     这里让最后一块能自己往上顶（margin-top:auto），
     把空白集中到该被吸收的位置，而不是散在中间。 */
.dy-card > :last-child{margin-bottom:0}
/* 让「授权与令牌」这张卡的最后一块（含说明与按钮）自己往上顶，
   把等高造成的多余空白集中吸收在它下方，而不是散在两张卡中间。 */
.dy-card > .dy-spacer{flex:1}
.dy-wide{grid-column:1/-1}
/* 窄屏（平板竖屏及以下）单列：两列会挤到输入框只剩 120px */
@media (max-width:900px){.dy-grid{grid-template-columns:1fr}}

.dy-h{font-size:var(--fs-md);font-weight:650;color:var(--c-ink);margin:0 0 var(--sp-2);
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.dy-hint{font-size:var(--fs-xs);font-weight:400;color:var(--c-text-sub)}
.dy-note{font-size:var(--fs-sm);color:var(--c-text-sub);line-height:1.85;
  margin:0 0 var(--sp-2);padding:10px 12px;background:var(--c-g50);
  border-radius:var(--r-sm);border-left:3px solid var(--c-border-strong)}
.dy-form{display:flex;flex-direction:column;gap:var(--sp-2h)}
.dy-form-row{flex-direction:row;gap:var(--sp-3);flex-wrap:wrap}
.dy-form-row .dy-lb{flex:1;min-width:220px}
.dy-lb{display:flex;flex-direction:column;gap:5px;font-size:var(--fs-sm);
  font-weight:550;color:var(--c-g800)}
.dy-sub{font-size:var(--fs-xs);font-weight:400;color:var(--c-text-sub);line-height:1.7}
.dy-sub code{background:var(--c-g100);padding:1px 5px;border-radius:3px;
  font-size:var(--fs-2xs);color:var(--c-g800)}
.dy-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:var(--sp-2)}

/* 令牌状态块：底色随状态变，但文字色仍取深色变量，保证对比度 */
.dy-token{border-radius:var(--r-md);padding:14px 16px;border:1px solid var(--c-border)}
.dy-token.ok{background:var(--c-accent-soft);border-color:var(--c-accent-soft)}
.dy-token.warn{background:var(--c-warn-soft);border-color:var(--c-warn-soft)}
.dy-token.expired{background:#FCEDEC;border-color:#FCEDEC}
.dy-token.none,.dy-token.unknown{background:var(--c-g50)}
.dy-token-t{font-size:var(--fs-md);font-weight:650;color:var(--c-ink);margin-bottom:5px}
.dy-token-d{font-size:var(--fs-sm);color:var(--c-g700);line-height:1.75}
.dy-token-m{display:flex;gap:18px;flex-wrap:wrap;margin-top:10px;
  font-size:var(--fs-xs);color:var(--c-g700)}
.dy-token-m b{color:var(--c-ink)}

/* 自检结果 */
.dy-test-out{margin-top:var(--sp-3)}
.dy-test-head{font-size:var(--fs-sm);font-weight:600;padding:8px 12px;
  border-radius:var(--r-sm);margin-bottom:8px}
.dy-test-head.ok{background:var(--c-accent-soft);color:var(--c-accent-ink)}
.dy-test-head.bad{background:var(--c-warn-soft);color:var(--c-warn)}
.dy-step{display:grid;grid-template-columns:18px 120px 1fr;gap:8px;
  padding:7px 4px;border-bottom:1px solid var(--c-hairline);font-size:var(--fs-sm);
  align-items:start}
.dy-step:last-child{border-bottom:0}
.dy-step-i{font-weight:700}
.dy-step.ok .dy-step-i{color:var(--c-accent-ink)}
.dy-step.bad .dy-step-i{color:var(--c-warn)}
.dy-step-t{color:var(--c-g800);font-weight:550}
.dy-step-d{color:var(--c-text-sub);line-height:1.7;word-break:break-word}

/* 任务列表 */
.dy-jlist{display:flex;flex-direction:column;gap:10px}
.dy-job{border:1px solid var(--c-border);border-radius:var(--r-md);
  padding:12px 14px;background:var(--c-surface-alt)}
.dy-job-top{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:8px}
.dy-job-t{font-size:var(--fs-sm);font-weight:600;color:var(--c-ink);
  flex:1;min-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dy-job-m{font-size:var(--fs-xs);color:var(--c-text-sub);white-space:nowrap}
.dy-badge{font-size:var(--fs-xs);padding:2px 9px;border-radius:999px;
  font-weight:600;white-space:nowrap}
.dy-badge.queued,.dy-badge.running{background:var(--c-primary-soft);color:var(--c-primary)}
.dy-badge.wait_h5{background:var(--c-warn-soft);color:var(--c-warn)}
.dy-badge.done{background:var(--c-accent-soft);color:var(--c-accent-ink)}
.dy-badge.failed{background:#FCEDEC;color:var(--c-warn)}
.dy-bar{height:4px;background:var(--c-g200);border-radius:2px;overflow:hidden;margin:6px 0}
.dy-bar i{display:block;height:100%;border-radius:2px;transition:width .3s ease}
.dy-bar i.run{background:var(--c-primary)}
.dy-bar i.ok{background:var(--c-accent)}
.dy-bar i.bad{background:var(--c-warn)}
.dy-job-step{font-size:var(--fs-xs);color:var(--c-text-sub);line-height:1.7}
.dy-job-err{margin-top:8px;padding:9px 11px;background:#FCEDEC;border-radius:var(--r-sm);
  font-size:var(--fs-sm);color:var(--c-g800);line-height:1.75}
.dy-job-err b{color:var(--c-warn)}
.dy-job-act{margin-top:5px;font-size:var(--fs-xs);color:var(--c-warn)}
.dy-job-ok{margin-top:8px;padding:9px 11px;background:var(--c-accent-soft);
  border-radius:var(--r-sm);font-size:var(--fs-sm);color:var(--c-g800);line-height:1.75}
.dy-job-ok code{background:rgba(255,255,255,.7);padding:1px 5px;border-radius:3px;font-size:var(--fs-2xs)}
.dy-scan{margin-top:10px;padding:12px;background:var(--c-primary-soft);
  border-radius:var(--r-md);font-size:var(--fs-sm);color:var(--c-g800)}
.dy-scan-url{margin:7px 0;font-family:ui-monospace,Menlo,Consolas,monospace;
  font-size:var(--fs-2xs);color:var(--c-g700);word-break:break-all;line-height:1.6;
  background:rgba(255,255,255,.75);padding:7px 9px;border-radius:var(--r-sm)}
.dy-copy{display:flex;gap:8px;align-items:center;margin-top:8px;flex-wrap:wrap}

/* ══════════════════════════════════════════════════════════════
   自动发布（RPA）· rpa.js
   ──────────────────────────────────────────────────────────────
   视觉约定（与全站一致）：
     · 颜色只走变量，不写字面色值 —— 深色模式/主题切换才不会出现「黑底黑字」
     · 圆角/间距走 var(--sp-*)，与相邻页面视觉重量一致
     · 三种状态色语义固定：ok=成功/warn=需人介入/bad=失败
       「待你确认发布」用 ok 色而不是 warn 色：它是**按设计停下的**，
       用警告色会让用户以为出错了，然后重复投递（发布不可撤销，代价很大）
   ══════════════════════════════════════════════════════════════ */

.rpa-wrap{display:flex;flex-direction:column;gap:var(--sp-3)}

/* ── 环境条 ── */
.rpa-envbar{display:flex;gap:var(--sp-2);flex-wrap:wrap;margin-bottom:var(--sp-2)}
.rpa-env-i{display:flex;align-items:center;gap:6px;padding:6px 10px;border-radius:8px;
  background:var(--c-surface);border:1px solid var(--c-border);font-size:var(--fs-xs)}
.rpa-env-i b{font-weight:600;color:var(--c-text)}
.rpa-env-note{color:var(--c-text-sub);font-size:var(--fs-2xs)}
.rpa-env-dot{width:7px;height:7px;border-radius:50%;flex:none}
.rpa-env-i.ok .rpa-env-dot{background:var(--c-success)}
.rpa-env-i.bad .rpa-env-dot{background:var(--c-danger)}
.rpa-env-i.bad b{color:var(--c-danger)}

.rpa-alert{padding:10px 14px;border-radius:10px;font-size:var(--fs-sm);line-height:1.65;
  border:1px solid;margin-bottom:var(--sp-2)}
.rpa-alert b{display:block;margin-bottom:2px}
.rpa-alert code{display:inline-block;margin:4px 0;padding:3px 8px;border-radius:6px;
  background:var(--c-g100);font-family:ui-monospace,Menlo,monospace;font-size:var(--fs-xs);
  color:var(--c-ink);word-break:break-all}
.rpa-alert-sub{margin-top:4px;font-size:var(--fs-2xs);opacity:.85}
.rpa-alert.danger{background:var(--c-danger-bg);border-color:var(--c-danger-border);color:var(--c-danger)}
.rpa-alert.warn{background:var(--c-warn-soft);border-color:var(--c-danger-border);color:var(--c-warn)}
/* 「抓到了 / 写入成功」这类**正向结果**的提示块。
   ★ 与 .rpa-alert.warn 的区别不只是颜色：warn 表示「还差一步」，
     ok 表示「已经完成、可以继续」。两者同一套结构、只换配色，
     是为了让用户在同一个视觉位置读到「结论」，不用重新找。 */
.rpa-alert.ok{background:var(--c-success-bg);border-color:var(--c-success-border);color:var(--c-success)}

/* 一行「主按钮 + 说明文字」。
   ★ 不写成 flex 的话，按钮和说明会各占一行，说明掉到按钮下面、读起来像
     第二段正文；这里让它们在一条基线上并排。 */
.rpa-acts{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.rpa-acts .rpa-hint{margin-top:0}

/* 抓取诊断里的原始行样本（只读、等宽、可滚动）。
   ★ max-height 必须给：列表页的 raw_sample 可能是一大段拼接文本，
     不限高会把下面的「写入统计」按钮顶到屏幕外好几屏。 */
.rpa-raw{margin-top:8px;padding:8px 10px;border-radius:8px;background:var(--c-g100);
  font-family:ui-monospace,Menlo,monospace;font-size:10px;line-height:1.6;
  color:var(--c-text-sub);max-height:160px;overflow:auto;word-break:break-all}

/* 数据抓取的预览表：与 .rpa-tbl 的「两列键值」不同，这里是有表头的多列表。
   ★ td:first-child 在 .rpa-tbl 里被定成 110px 宽，表头型表格必须放开，
     否则第一列「作品名」被压成 110px、标题全挤成两行。 */
.rpa-tbl thead th{padding:7px 10px;text-align:left;font-weight:600;font-size:var(--fs-2xs);
  color:var(--c-text-sub);border-bottom:1px solid var(--c-border);white-space:nowrap}
.rpa-tbl tbody td{width:auto}
.rpa-tbl tbody td:first-child{width:auto;color:var(--c-ink);white-space:normal}

/* ── 子标签 ── */
.rpa-tabs{display:flex;gap:6px;border-bottom:1px solid var(--c-border);padding-bottom:0}
.rpa-tab{background:none;border:none;border-bottom:2px solid transparent;cursor:pointer;
  padding:8px 14px;font-size:var(--fs-sm);color:var(--c-text-sub);font-weight:500}
.rpa-tab:hover{color:var(--c-text)}
.rpa-tab.on{color:var(--c-primary);border-bottom-color:var(--c-primary);font-weight:600}

.rpa-note{font-size:var(--fs-xs);color:var(--c-text-sub);line-height:1.7;
  background:var(--c-g50);border-radius:8px;padding:8px 12px;margin-bottom:var(--sp-2)}

/* ── 账号卡 ── */
.rpa-accs{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:var(--sp-2)}
.rpa-acc{background:var(--c-surface);border:1px solid var(--c-border);border-radius:10px;padding:12px 14px}
.rpa-acc.on{border-color:var(--c-primary-border);background:var(--c-surface)}
.rpa-acc-h{display:flex;justify-content:space-between;align-items:flex-start;gap:8px;margin-bottom:8px}
.rpa-acc-h b{font-size:var(--fs-sm);color:var(--c-text)}
.rpa-acc-s{font-size:var(--fs-2xs);color:var(--c-text-sub);display:flex;align-items:center;
  gap:5px;white-space:nowrap}
.rpa-ok-dot{width:6px;height:6px;border-radius:50%;background:var(--c-success);flex:none}
.rpa-idle-dot{width:6px;height:6px;border-radius:50%;background:var(--c-g400);flex:none}
.rpa-acc-b{display:flex;gap:6px;flex-wrap:wrap}
.rpa-badge-sm{display:inline-block;margin-left:6px;padding:1px 6px;border-radius:4px;
  font-size:10px;background:var(--c-primary-soft);color:var(--c-primary);font-weight:500}
.rpa-badge-sm.warn{background:var(--c-warn-soft);color:var(--c-warn)}
.rpa-cav{margin-top:8px;padding-top:8px;border-top:1px dashed var(--c-border);
  font-size:var(--fs-2xs);color:var(--c-text-sub);line-height:1.7}

/* ── 二维码面板 ── */
.rpa-qrbox{margin-top:var(--sp-3);background:var(--c-surface);border:1px solid var(--c-primary-border);
  border-radius:12px;padding:16px;max-width:420px}
.rpa-qr-h{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.rpa-qr-h b{font-size:var(--fs-sm);color:var(--c-text)}
.rpa-qr-st{margin-left:auto;font-size:var(--fs-2xs);padding:2px 8px;border-radius:10px}
.rpa-qr-st.wait{background:var(--c-primary-soft);color:var(--c-primary)}
.rpa-qr-st.ok{background:var(--c-success-bg);color:var(--c-success)}
.rpa-qr-st.bad{background:var(--c-danger-bg);color:var(--c-danger)}
.rpa-x{background:none;border:none;cursor:pointer;color:var(--c-text-sub);font-size:14px;
  padding:2px 6px;border-radius:4px;line-height:1}
.rpa-x:hover{background:var(--c-g100);color:var(--c-text)}
.rpa-qr-imgwrap{display:flex;justify-content:center;padding:8px;min-height:200px;align-items:center}
.rpa-qr{width:220px;height:220px;object-fit:contain;image-rendering:pixelated;
  border-radius:8px;background:#fff}
.rpa-qr-ph{color:var(--c-text-sub);font-size:var(--fs-xs)}
.rpa-qr-step{margin-top:8px;font-size:var(--fs-xs);color:var(--c-text-sub);text-align:center}
.rpa-qr-note{font-size:var(--fs-2xs);color:var(--c-warn);line-height:1.6;margin-bottom:8px}
.rpa-qr-err{margin-top:10px;padding:8px 10px;border-radius:8px;
  background:var(--c-danger-bg);color:var(--c-danger);font-size:var(--fs-xs);line-height:1.6}
.rpa-qr-how{margin-top:4px;opacity:.9}

/* ── 投递表单 ── */
.rpa-form{max-width:760px;display:flex;flex-direction:column;gap:var(--sp-3)}
.rpa-fld>label{display:block;font-size:var(--fs-xs);font-weight:600;color:var(--c-text);
  margin-bottom:6px}
/* 输入控件撑满栅格宽度。
   ★ .input/.select/.textarea 在基础样式里只有 height/padding，没有 width ——
     它们的默认宽度由内容决定，实测在 760px 的表单里只画出约 300px，
     标题框和正文框右边留一大片空白，看起来像「没做完」。
     这里只作用于本页的 .rpa-fld 内，不影响其它页面。 */
.rpa-fld .input,.rpa-fld .select,.rpa-fld .textarea{width:100%;box-sizing:border-box}
.rpa-fld .textarea{height:auto;padding:9px 10px}
/* 占位文字加深一档。
   ★ 全局 .input::placeholder 用的是 --c-g300（≈#C9D0DA，对白底对比度约 1.6:1），
     实测在本页截图里「例如：#法律咨询 #劳动仲裁」几乎看不见，用户会以为
     那个框是禁用状态。WCAG 对非必要文本没有硬性要求，但「看不见的提示」
     等于没有提示，这里改用 --c-g500（约 4.6:1）。
     只改本页，不动全局 —— 其它页面的占位文字与各自版式是调过的。 */
.rpa-fld .input::placeholder,.rpa-fld .textarea::placeholder{color:var(--c-g500)}
.rpa-plats{display:flex;gap:6px;flex-wrap:wrap}
.rpa-pl{position:relative;padding:6px 14px;border-radius:8px;border:1px solid var(--c-border);
  background:var(--c-surface);cursor:pointer;font-size:var(--fs-sm);color:var(--c-text)}
.rpa-pl:hover{border-color:var(--c-primary-border)}
.rpa-pl.on{background:var(--c-primary);color:#fff;border-color:var(--c-primary);font-weight:600}
.rpa-pl-dot{position:absolute;top:4px;right:4px;width:5px;height:5px;border-radius:50%;
  background:var(--c-danger)}
.rpa-drop{border:1.5px dashed var(--c-border-strong);border-radius:10px;padding:22px;
  text-align:center;cursor:pointer;font-size:var(--fs-sm);color:var(--c-text-sub);
  background:var(--c-surface-alt)}
.rpa-drop:hover{border-color:var(--c-primary);background:var(--c-primary-soft)}
.rpa-drop-ico{display:block;font-size:22px;margin-bottom:4px;color:var(--c-primary)}
.rpa-file-ok{display:flex;align-items:center;gap:8px;justify-content:center;
  color:var(--c-success);font-weight:500}
.rpa-file-mb{font-size:var(--fs-2xs);color:var(--c-text-sub)}
.rpa-up{color:var(--c-primary)}
.rpa-up-err{color:var(--c-danger)}
.rpa-hint{font-size:var(--fs-2xs);color:var(--c-text-sub);line-height:1.6;margin-top:5px}
.rpa-ta{resize:vertical;min-height:110px;line-height:1.7}
/* 未登录提示：标题一行 + 说明一行。
   ★ v1 写成单行内联，实测截图里文字挤在灰底上、离上方的平台按钮只差 4px，
     读起来像「按钮的附属说明」，用户容易当成可忽略的小字。
     加左边框 + 分两行后，它变成一块独立的「要你先做什么」的提示。 */
.rpa-warn-inline{margin-top:10px;padding:8px 12px;border-radius:8px;
  border-left:3px solid var(--c-warn);
  background:var(--c-warn-soft);color:var(--c-warn);font-size:var(--fs-2xs);
  line-height:1.75}
.rpa-warn-inline b{display:block;font-size:var(--fs-xs);margin-bottom:1px}

.rpa-radio{display:flex;flex-direction:column;gap:8px}
.rpa-radio>label{display:block;padding:10px 12px;border:1px solid var(--c-border);
  border-radius:9px;cursor:pointer;background:var(--c-surface);font-size:var(--fs-xs);
  line-height:1.65;color:var(--c-text-sub)}
.rpa-radio>label.on{border-color:var(--c-primary);background:var(--c-primary-soft)}
.rpa-radio b{display:block;color:var(--c-text);font-size:var(--fs-sm);margin-bottom:2px}
.rpa-radio input{margin-right:6px}

.rpa-submit{display:flex;align-items:center;gap:12px;padding-top:var(--sp-2);
  border-top:1px solid var(--c-border)}

/* ── 任务卡 ── */
#rpa-joblist{display:flex;flex-direction:column;gap:var(--sp-2)}
.rpa-job{background:var(--c-surface);border:1px solid var(--c-border);
  border-left:3px solid var(--c-g300);border-radius:10px;padding:12px 14px}
.rpa-job.ok{border-left-color:var(--c-success)}
.rpa-job.warn{border-left-color:var(--c-warn)}
.rpa-job.bad{border-left-color:var(--c-danger)}
.rpa-job.wait{border-left-color:var(--c-primary)}
.rpa-job-h{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:var(--fs-sm)}
.rpa-job-h b{color:var(--c-text)}
.rpa-job-t{color:var(--c-text-sub);font-size:var(--fs-xs);max-width:340px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rpa-job-time{margin-left:auto;font-size:var(--fs-2xs);color:var(--c-text-sub)}
.rpa-st{font-size:var(--fs-2xs);padding:2px 8px;border-radius:10px;font-weight:600}
.rpa-st.ok{background:var(--c-success-bg);color:var(--c-success)}
.rpa-st.warn{background:var(--c-warn-soft);color:var(--c-warn)}
.rpa-st.bad{background:var(--c-danger-bg);color:var(--c-danger)}
.rpa-st.wait{background:var(--c-primary-soft);color:var(--c-primary)}
.rpa-st.idle{background:var(--c-g100);color:var(--c-text-sub)}
.rpa-job-bar{height:3px;border-radius:2px;background:var(--c-g100);margin:8px 0 6px;overflow:hidden}
.rpa-job-bar i{display:block;height:100%;background:var(--c-primary);transition:width .4s}
.rpa-job.ok .rpa-job-bar i{background:var(--c-success)}
.rpa-job.bad .rpa-job-bar i{background:var(--c-danger)}
.rpa-job-step{font-size:var(--fs-xs);color:var(--c-text-sub)}
.rpa-live{margin-left:8px;color:var(--c-primary);font-weight:600}
.rpa-job-err{margin-top:8px;padding:8px 10px;border-radius:8px;background:var(--c-danger-bg);
  color:var(--c-danger);font-size:var(--fs-xs);line-height:1.65}
.rpa-job-how{margin-top:4px;padding-top:4px;border-top:1px dashed var(--c-danger-border);opacity:.92}
.rpa-job-f{display:flex;gap:6px;margin-top:10px;flex-wrap:wrap}
.btn.sm{padding:3px 10px;font-size:var(--fs-2xs)}

/* ── 弹窗内表格 ── */
.rpa-tbl{width:100%;border-collapse:collapse;font-size:var(--fs-xs)}
.rpa-tbl td{padding:7px 10px;border-bottom:1px solid var(--c-border);vertical-align:top;
  line-height:1.65}
.rpa-tbl td:first-child{width:110px;color:var(--c-text-sub);white-space:nowrap}
.rpa-tbl code{background:var(--c-g100);padding:1px 5px;border-radius:4px;
  font-family:ui-monospace,Menlo,monospace;font-size:11px}
.rpa-mono{font-family:ui-monospace,Menlo,monospace;word-break:break-all;font-size:11px}
.rpa-no{color:var(--c-danger)}
.rpa-yes{color:var(--c-success)}
.rpa-mt{font-size:var(--fs-sm);color:var(--c-text-sub);line-height:1.75}
/* 任务截图。
   ★ 必须 display:block —— img 是行内元素，父级 .modal-body 又是文字排版，
     实测截图下方会多出一条 4px 的基线间隙，贴着「关闭」按钮边界。
   ★ 背景给浅灰：截图本身常是白底页面，纯白卡片上看不出边界。 */
.rpa-shot{display:block;max-width:100%;margin:0 auto;border-radius:8px;
  border:1px solid var(--c-border);background:var(--c-bg)}


/* ══════════════════════════════════════════════════════════════
   资讯中心（news.js）
   ══════════════════════════════════════════════════════════════
   全部走设计令牌，不写死颜色 —— 与全站一致。
   ★ .nw-tbl 不复用 .rpa-tbl：两者的列宽策略不同。RPA 是「键值对」
     两列（左窄右自适应），资讯是「多列表格」，需要每列都能收缩、
     长文本能换行。硬套会用一列把整表撑爆。
   ══════════════════════════════════════════════════════════════ */

.nw-wrap{display:flex;flex-direction:column;gap:var(--sp-3)}
.nw-tabs{display:flex;gap:6px;border-bottom:1px solid var(--c-border)}
.nw-tab{background:none;border:none;border-bottom:2px solid transparent;
  padding:7px 12px;cursor:pointer;font-size:var(--fs-sm);color:var(--c-text-sub);
  font-family:inherit;transition:color .15s,border-color .15s}
.nw-tab:hover{color:var(--c-text)}
.nw-tab.on{color:var(--c-primary);border-bottom-color:var(--c-primary);font-weight:600}

/* ── 通用条 ── */
.nw-bar{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);
  flex-wrap:wrap}
.nw-bar-r{display:flex;gap:8px}
.nw-filter{display:flex;gap:6px;flex-wrap:wrap}
.nw-chip{background:var(--c-surface);border:1px solid var(--c-border);
  border-radius:999px;padding:4px 13px;font-size:var(--fs-xs);cursor:pointer;
  color:var(--c-text-sub);font-family:inherit;transition:.15s}
.nw-chip:hover{border-color:var(--c-border-strong);color:var(--c-text)}
.nw-chip.on{background:var(--c-primary-soft);border-color:var(--c-primary);
  color:var(--c-primary);font-weight:600}
.nw-hint{font-size:var(--fs-xs);color:var(--c-text-sub);line-height:1.75;
  background:var(--c-g50);border:1px solid var(--c-border);border-radius:8px;
  padding:8px 12px}
.nw-hint.sm{font-size:var(--fs-2xs);padding:6px 10px;margin-top:6px}
.nw-dim{color:var(--c-text-sub);font-size:var(--fs-2xs)}
.nw-mono{font-family:ui-monospace,Menlo,monospace;font-size:var(--fs-2xs)}
.nw-ok{color:var(--c-success)}
.nw-bad{color:var(--c-danger)}

/* ── 徽标 ── */
/* ★ v4.5.1：必须 white-space:nowrap。
   投送台账的「状态」列很窄（表格 5 列挤在侧栏里），没有 nowrap 时
   浏览器会把「已发出」拆成三行竖排单字，看起来像竖着的竖幅，
   完全认不出是什么。徽标是**必须整体阅读**的元素，永远不该折行。 */
.nw-badge{display:inline-block;padding:1px 8px;border-radius:999px;
  font-size:var(--fs-2xs);border:1px solid var(--c-border);
  background:var(--c-g100);color:var(--c-text-sub);line-height:1.7;
  white-space:nowrap}
.nw-badge.ok{background:var(--c-success-bg);border-color:var(--c-success);
  color:var(--c-success)}
.nw-badge.w{background:var(--c-warn-bg);border-color:var(--c-warn);color:var(--c-warn)}
.nw-badge.bad{background:var(--c-danger-bg);border-color:var(--c-danger);
  color:var(--c-danger)}
.nw-badge.g{background:var(--c-g100);border-color:var(--c-border-strong)}

/* ── 期次卡片 ── */
.nw-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));
  gap:var(--sp-3)}
.nw-card{border:1px solid var(--c-border);border-radius:10px;background:var(--c-surface);
  padding:12px 14px;display:flex;flex-direction:column;gap:7px;
  transition:border-color .15s,box-shadow .15s}
.nw-card:hover{border-color:var(--c-border-strong);box-shadow:0 2px 10px rgba(15,27,45,.06)}
.nw-card-hd{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.nw-no{font-size:var(--fs-xs);font-weight:700;color:var(--c-primary);
  letter-spacing:.4px}
.nw-card-t{font-size:var(--fs-md);font-weight:600;color:var(--c-ink);line-height:1.5}
.nw-sub{font-weight:400;color:var(--c-text-sub);font-size:var(--fs-sm)}
.nw-card-met{display:flex;gap:10px;flex-wrap:wrap;font-size:var(--fs-2xs);
  color:var(--c-text-sub)}
.nw-card-acts{display:flex;gap:6px;flex-wrap:wrap;margin-top:2px}
.nw-card-acts .btn{padding:3px 10px;font-size:var(--fs-2xs)}

/* ── 编制页头 ── */
.nw-ed-head{display:flex;align-items:flex-start;justify-content:space-between;
  gap:var(--sp-3);flex-wrap:wrap;padding-bottom:10px;
  border-bottom:1px solid var(--c-border)}
.nw-ed-title{display:flex;align-items:center;gap:8px;font-size:var(--fs-lg);
  font-weight:700;color:var(--c-ink)}
.nw-ed-sub{font-size:var(--fs-sm);color:var(--c-text-sub);margin-top:3px}
.nw-ed-acts{display:flex;gap:6px;flex-wrap:wrap}

/* ── 两栏 ── */
.nw-ed-grid{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);
  gap:var(--sp-3);align-items:start}
@media (max-width:1180px){.nw-ed-grid{grid-template-columns:1fr}}
.nw-col{display:flex;flex-direction:column;gap:var(--sp-3);min-width:0}

.nw-sec{border:1px solid var(--c-border);border-radius:10px;
  background:var(--c-surface);padding:12px 14px}
.nw-sec-hd{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  font-size:var(--fs-sm);color:var(--c-ink);margin-bottom:9px}
.nw-sec-r{margin-left:auto;display:flex;gap:6px;flex-wrap:wrap}
.nw-sec-r .btn,.nw-sec-hd .btn{padding:3px 10px;font-size:var(--fs-2xs)}

/* ── 条目 ── */
.nw-items{display:flex;flex-direction:column;gap:0}
.nw-item{display:flex;gap:10px;padding:10px 0;border-bottom:1px solid var(--c-border)}
.nw-item:last-child{border-bottom:none;padding-bottom:0}
.nw-item-no{flex:0 0 22px;height:22px;border-radius:50%;background:var(--c-g100);
  color:var(--c-text-sub);font-size:var(--fs-2xs);display:flex;
  align-items:center;justify-content:center;font-weight:600;margin-top:2px}
.nw-item-bd{flex:1;min-width:0}
.nw-item-t{display:flex;align-items:center;gap:6px;flex-wrap:wrap;
  font-size:var(--fs-sm);font-weight:600;color:var(--c-ink);line-height:1.5}
.nw-item-title{font-weight:600}
.nw-lv{font-size:var(--fs-2xs);padding:0 6px;border-radius:4px;
  background:var(--c-primary-soft);color:var(--c-primary);font-weight:600}
.nw-aiflag{font-size:var(--fs-2xs);padding:0 6px;border-radius:4px;
  background:var(--c-purple-soft);color:var(--c-purple)}
.nw-srcbad{font-size:var(--fs-2xs);padding:0 6px;border-radius:4px;
  background:var(--c-danger-bg);color:var(--c-danger);font-weight:600}
.nw-item-s{font-size:var(--fs-xs);color:var(--c-text-sub);line-height:1.75;
  margin-top:4px}
.nw-item-met{display:flex;gap:10px;flex-wrap:wrap;font-size:var(--fs-2xs);
  color:var(--c-text-sub);margin-top:5px;opacity:.9}
.nw-fig{color:var(--c-accent-ink);font-weight:600}
.nw-item-act{flex:0 0 auto;display:flex;flex-direction:column;gap:4px}
.nw-item-act .btn{padding:2px 9px;font-size:var(--fs-2xs)}

/* ── 结论块 ── */
.nw-verdict{display:flex;flex-direction:column;gap:9px}
.nw-vd-row{display:flex;gap:10px;font-size:var(--fs-sm);line-height:1.75}
.nw-vd-row>span{flex:0 0 68px;color:var(--c-text-sub);font-size:var(--fs-xs);
  padding-top:2px}
.nw-vd-row>div{flex:1;min-width:0;color:var(--c-text);white-space:pre-wrap}
.nw-empty-v{color:var(--c-danger);font-style:normal}

/* ── 自检 ── */
.nw-qa{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}
.nw-qa-i{display:flex;align-items:center;gap:6px;font-size:var(--fs-2xs);
  padding:5px 8px;border-radius:6px;border:1px solid var(--c-border);
  background:var(--c-g50)}
.nw-qa-i b{font-weight:700;color:var(--c-text-sub)}
.nw-qa-i span{flex:1;min-width:0;color:var(--c-text);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.nw-qa-i em{font-style:normal;font-weight:600}
.nw-qa-i.ok{border-color:var(--c-success);background:var(--c-success-bg)}
.nw-qa-i.ok em{color:var(--c-success)}
.nw-qa-i.bad{border-color:var(--c-danger);background:var(--c-danger-bg)}
.nw-qa-i.bad em{color:var(--c-danger)}
.nw-qa-i.dg em{color:var(--c-text-sub)}
.nw-notes{margin-top:8px;font-size:var(--fs-2xs);color:var(--c-warn);
  line-height:1.8;background:var(--c-warn-bg);border-radius:6px;padding:7px 10px}

/* ── 排版产物 ── */
.nw-files{display:flex;flex-direction:column;gap:6px;font-size:var(--fs-xs)}
.nw-files>div{display:flex;gap:8px;align-items:baseline}
.nw-files>div>span{flex:0 0 34px;color:var(--c-text-sub);font-size:var(--fs-2xs)}
.nw-files>div>b{font-weight:600;color:var(--c-ink);word-break:break-all}
.nw-files>div>em{font-style:normal;color:var(--c-text-sub);font-size:var(--fs-2xs)}
.nw-fill{margin-top:8px;display:flex;flex-direction:column;gap:4px}
.nw-fill-r{display:flex;align-items:center;gap:8px;font-size:var(--fs-2xs)}
.nw-fill-r span{flex:0 0 52px;color:var(--c-text-sub)}
.nw-fill-r i{flex:1;height:7px;border-radius:4px;background:var(--c-success);
  display:block;min-width:2px}
.nw-fill-r.warn i{background:var(--c-warn)}
.nw-fill-r.bad i{background:var(--c-danger)}
.nw-fill-r em{flex:0 0 38px;text-align:right;font-style:normal;
  color:var(--c-text-sub)}

/* ── 渠道勾选 ── */
.nw-chs{display:flex;flex-direction:column;gap:5px}
.nw-chs.sm{flex-direction:row;flex-wrap:wrap}
.nw-ch{display:flex;gap:8px;align-items:flex-start;padding:7px 9px;
  border:1px solid var(--c-border);border-radius:8px;cursor:pointer;
  background:var(--c-g50);transition:.15s}
.nw-ch:hover{border-color:var(--c-border-strong)}
.nw-ch.off{opacity:.5;cursor:not-allowed}
.nw-ch input{margin-top:2px;flex:0 0 auto}
.nw-ch>div{display:flex;flex-direction:column;gap:1px;min-width:0}
.nw-ch b{font-size:var(--fs-xs);font-weight:600;color:var(--c-ink)}
.nw-ch span{font-size:var(--fs-2xs);color:var(--c-text-sub);line-height:1.6}
/* ★ .mini 用在横向排布的 .nw-chs.sm 里，必须显式禁止收缩：
   实测（2026-10-26）不加 flex:0 0 auto + white-space:nowrap 时，
   浏览器会把每个 chip 均分压窄到十几像素，中文逐字换行 ——
   「微信公众号」变成五个字竖着一列，看着像排版坏了。
   横向 chip 的宽度应由文字决定（flex-basis:auto），不该由父容器均分。 */
.nw-ch.mini{padding:4pt 9pt;align-items:center;flex:0 0 auto;white-space:nowrap}
.nw-ch.mini>div{flex-direction:row;min-width:auto}
/* ★ v4.0.7 真根因（此前两次都改错了方向，写下来免得再犯）：
   渠道 chip 的文字溢出到下一个 chip 上、看起来「只显示一个字」，不是文字被裁，
   而是**复选框把后面的内容推出了 label 之外**。无头 Chromium 上原生
   `<input type=checkbox>` 实测盒子是 **45×13px**（不是常见的 13×13），
   而 `.nw-ch` 的可用行宽 = 71 − 24(padding) = 47px，
   于是 div 从 left:339 开始、right:363，**越过了 label 的 right:344 整整 19px**，
   两字被后画的相邻 chip 盖住第二个字。
   排查走过的两个弯路：
     ① 以为是 `.nw-chs.sm` 父容器把 chip 均分压窄 → 加 flex:0 0 auto，无效；
     ② 以为是字体回退导致字宽超标 → 逐字符量，每个字节 12px，正常。
   两个判据一开始就该先量：input 的实际盒子、以及 div.right 与 label.right 的差。
   结论：**任何把原生 checkbox 放进 flex 横排的地方，都必须显式给死宽高**，
   不能依赖 UA 默认值 —— 它在不同平台/无头环境下的尺寸不一样。 */
.nw-ch input{width:13px;height:13px;flex:0 0 13px;margin:0;accent-color:var(--c-primary)}
.nw-ch.mini input{width:13px;height:13px;flex:0 0 13px}

/* ── 表单 ── */
.nw-send-opts{display:flex;flex-direction:column;gap:6px;margin-top:9px}
.nw-ln{display:flex;flex-direction:column;gap:3px;font-size:var(--fs-2xs);
  color:var(--c-text-sub)}
.nw-ln.fw{grid-column:1/-1}
.nw-ln input,.nw-ln select,.nw-form input,.nw-form select,.nw-form textarea,
.nw-ta{border:1px solid var(--c-border-strong);border-radius:6px;padding:5px 9px;
  font-size:var(--fs-xs);font-family:inherit;color:var(--c-text);
  background:var(--c-surface);width:100%}
.nw-ln input:focus,.nw-form input:focus,.nw-form textarea:focus,.nw-form select:focus,
.nw-ta:focus{outline:none;border-color:var(--c-primary);
  box-shadow:0 0 0 2px var(--c-primary-soft)}
.nw-form{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.nw-form label{display:flex;flex-direction:column;gap:3px;font-size:var(--fs-2xs);
  color:var(--c-text-sub)}
.nw-form label.fw{grid-column:1/-1}
.nw-form textarea{resize:vertical;line-height:1.7}
.nw-ta{resize:vertical;line-height:1.7;min-height:120px}

.nw-send-btns{display:flex;gap:6px;flex-wrap:wrap;margin-top:10px}
.nw-send-btns .btn{padding:5px 12px;font-size:var(--fs-xs)}

/* ── 表格 ── */
.nw-tbl{width:100%;border-collapse:collapse;font-size:var(--fs-2xs);
  margin-top:8px}
.nw-tbl thead th{padding:6px 8px;text-align:left;font-weight:600;
  color:var(--c-text-sub);border-bottom:1px solid var(--c-border);
  white-space:nowrap;background:var(--c-g50)}
.nw-tbl tbody td{padding:6px 8px;border-bottom:1px solid var(--c-border);
  color:var(--c-text);vertical-align:top;line-height:1.65}
.nw-tbl tbody tr:last-child td{border-bottom:none}
.nw-tbl tbody tr:hover{background:var(--c-g50)}
.nw-tdact{white-space:nowrap}
.nw-tdact .btn{padding:1px 8px;font-size:var(--fs-2xs);margin-right:4px}

/* ── 提示条 ── */
.nw-alert{margin-top:8px;padding:8px 12px;border-radius:8px;font-size:var(--fs-xs);
  line-height:1.75;border:1px solid var(--c-border);background:var(--c-g50)}
.nw-alert.ok{background:var(--c-success-bg);border-color:var(--c-success);
  color:var(--c-success)}
.nw-alert.bad{background:var(--c-danger-bg);border-color:var(--c-danger);
  color:var(--c-danger)}
.nw-alert-msg{margin-top:3px;color:var(--c-text-sub);font-size:var(--fs-2xs);
  line-height:1.7;white-space:pre-wrap;word-break:break-word}
.nw-alert.ok .nw-alert-msg{color:var(--c-success)}

/* ── 素材池 / 差异对比 ── */
.nw-pool{display:flex;flex-direction:column;gap:4px;max-height:52vh;overflow:auto}
.nw-pool-i{display:flex;gap:8px;align-items:flex-start;padding:7px 9px;
  border:1px solid var(--c-border);border-radius:7px;cursor:pointer;
  background:var(--c-g50)}
.nw-pool-i:hover{border-color:var(--c-border-strong)}
.nw-pool-i input{margin-top:3px}
.nw-pool-i>div{display:flex;flex-direction:column;gap:1px;min-width:0}
.nw-pool-i b{font-size:var(--fs-xs);font-weight:600;color:var(--c-ink)}
.nw-pool-i span{font-size:var(--fs-2xs);color:var(--c-text-sub);line-height:1.6}
.nw-pool-i em{font-style:normal;font-size:var(--fs-2xs);color:var(--c-text-sub);
  opacity:.85}
.nw-diff{border:1px solid var(--c-border);border-radius:8px;padding:9px 11px;
  margin-bottom:8px;background:var(--c-surface)}
.nw-diff-t{font-size:var(--fs-xs);font-weight:600;color:var(--c-ink);
  margin-bottom:5px}
.nw-diff-o,.nw-diff-n{font-size:var(--fs-2xs);line-height:1.8;color:var(--c-text-sub);
  display:flex;gap:8px}
.nw-diff-o>span,.nw-diff-n>span{flex:0 0 30px;font-weight:600;opacity:.8}
.nw-diff-n{color:var(--c-text)}

/* ── 定时 ── */
.nw-sched-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));
  gap:10px}
.nw-days{display:flex;gap:8px;flex-wrap:wrap;margin-top:3px}
.nw-day{display:flex;align-items:center;gap:4px;font-size:var(--fs-2xs);
  color:var(--c-text);padding:3px 8pt;border:1px solid var(--c-border);
  border-radius:999px;cursor:pointer;background:var(--c-g50);
  flex:0 0 auto;white-space:nowrap}
.nw-day:has(input:checked){background:var(--c-primary-soft);
  border-color:var(--c-primary);color:var(--c-primary);font-weight:600}

/* ── 桌面端：本机发布引擎状态条（v4.6.0） ──────────────────
   只在 Electron 外壳里渲染；浏览器端 rpaEngineBar() 会把容器清空，
   所以这些样式在网页里不会被用到，不会影响现有布局。 */
.rpa-eng{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:10px 14px;margin-bottom:12px;border-radius:10px;
  border:1px solid var(--c-border);background:var(--c-surface-alt);
  font-size:var(--fs-sm)}
.rpa-eng.on{border-color:var(--c-success);background:var(--c-success-bg)}
.rpa-eng.off{border-color:var(--c-warn);background:var(--c-warn-soft)}
.rpa-eng-dot{width:8px;height:8px;border-radius:50%;flex:0 0 auto}
.rpa-eng.on .rpa-eng-dot{background:var(--c-success)}
.rpa-eng.off .rpa-eng-dot{background:var(--c-warn)}
.rpa-eng-t{font-weight:600;color:var(--c-text)}
.rpa-eng-acc{margin-left:auto;color:var(--c-text-sub);font-size:var(--fs-2xs)}
.rpa-qr-tip{font-size:var(--fs-sm);color:var(--c-text-sub);line-height:1.8}
.rpa-qr-tip.ok{color:var(--c-success)}
