/* ============================================================
   代理商素材库 · 浅蓝 AI 设计系统
   一套代码同时服务 手机 / 平板 / PC（PC 为独立设计，非放大版）
   ============================================================ */

/* ---------------- 设计变量 ---------------- */
:root{
  /* 底色与表面：改用中性冷白。原来是大面积浅蓝（#f0f5ff），底色自带色块感、
     整页发闷；素材站主要用途是看图片，中性底才不会干扰对图片颜色的判断 */
  --bg:#f8fafc;
  --surface:#ffffff;
  --solid:#ffffff;
  --solid-2:#f1f5f9;

  /* 描边：中性石板灰。原来是低饱和藏青，整页被拉向蓝；换成中性后
     边线更「沉」，也不再给页面添蓝调 */
  --line:rgba(15,23,42,.08);
  --line-2:rgba(15,23,42,.14);
  --line-3:rgba(15,23,42,.22);

  /* 文字：中性石板灰阶。原来四级全偏藏青，久看会累 */
  --txt:#0f172a;
  --txt-2:#475569;
  --txt-3:#94a3b8;
  --txt-4:#cbd5e1;

  /* 品牌色：顶栏 logo 固定用它，不随页面变 —— 站点需要一个稳定的身份锚点，
     四个 Tab 连 logo 都换色会显得没有主心骨 */
  --brand:#2563eb;
  --brand-2:#60a5fa;
  --brand-d:#1d4ed8;
  /* 原来这里有一条 --brand-grad，专门给自绘的星形 logo 方块上色
     （写死不走 --acc，好让四个 Tab 来回切时 logo 始终是品牌蓝）。
     品牌位换成设计给的 logo 图片之后它没有消费者了，撤掉 ——
     那版 logo 自带橙色渐变，也不再需要跟着 Tab 换色。 */
  --ok:#16a34a;
  --danger:#dc2626;
  /* 「代理提问」徽章那套绿：底 / 字 / 描边三件一起给，因为它是唯一一处
     不跟着库身份色走的固定语义色（绿色 = 这是同行提的问，不是官方条目） */
  --ok-soft:#ecfdf5;--ok-t:#047857;--ok-line:#a7f3d0;
  /* 「待回答 / 待审核」那套暖橙：状态徽章与提示块共用（浅底深字，
     夜里整体反转成半透明底 + 亮字，见文件末尾色系段） */
  --warn-soft:#fff7ed;--warn-t:#9a3412;--warn-line:#fed7aa;

  /* 当前页身份色。这里的默认值 = 朋友圈，同时也是「页面外元素」的兜底：
     后台、工具页、保存台、灯箱都拿不到 body[data-tab]，于是保持品牌蓝 */
  --acc:var(--brand);
  --acc-2:var(--brand-2);
  --acc-d:var(--brand-d);
  --acc-soft:rgba(37,99,235,.09);
  --acc-line:rgba(37,99,235,.15);
  --acc-ring:rgba(37,99,235,.24);
  --acc-glow:rgba(37,99,235,.30);

  /* -------- 色系（skin）用的旋钮 --------
     站点有四套色系：云锦（浅，默认）/ 星渊 / 极光 / 曜石（后三套是夜里用的）。
     客户在前端自选，运营在后台设默认，具体见文件末尾「色系」那段。
     下面这八个是「默认值 = 云锦」，深色系只需覆盖它们，不用重写整套变量。 */

  /* 压在身份色渐变 / 实色块上的文字色。
     浅色系里身份色偏深，白字正好；深色系里身份色整体提亮一档（否则在深底上
     发闷），白字就糊了 —— 那时这个值会反转成深色字。
     全站凡是「白字压在 --grad / --acc 上」的位置（主按钮、激活胶囊、KPI 数字、
     步骤序号、等级徽章……）都走的这个变量，共 28 处，改一处全站跟着变。 */
  --on-acc:#fff;
  /* 身份色四档透明度的「浓度」。深色系下整体抬高：深底上的 9% 淡底几乎看不见，
     发光描边也要更亮才立得住 */
  --sa:9%;--sl:15%;--sr:24%;--sg:30%;
  /* 氛围开关：云锦全关（保持现在这套干净的样子），深色系按各自调性打开。
     glass = 卡片玻璃模糊度，neon = 发光强度，grid/orb = 背景网格与光斑，
     img-b = 图片亮度（夜里压一点，免得亮图在深底上发飘） */
  --glass:0px;--neon:0;--grid-c:transparent;--orb:0;--img-b:1;
  /* 背景网格线的间距（深色系才用得上） */
  --grid-size:52px;

  /* 强调色 --grad / --grad-2 / --grad-soft 不在这里定义，下沉到下面的 body 规则 ——
     原因见那一段的注释：自定义属性的 var() 替换发生在「声明所在的元素」上，
     写在 :root 会被永远解析成品牌蓝，切页面不会跟着变。 */

  /* 圆角 */
  --r-xl:20px;
  --r-lg:16px;
  --r-md:11px;
  --r-sm:8px;

  /* 阴影：只留「贴边一层」。原来的大范围柔光（模糊 52~96px、负 spread -44px）
     是整页「厚重」的首要来源 —— 卡片像悬空的厚板。气氛层全部去掉，
     层次改由描边和底色差来表达 */
  --sh-1:0 1px 2px rgba(15,23,42,.05);
  --sh-2:0 1px 2px rgba(15,23,42,.04), 0 4px 12px -8px rgba(15,23,42,.10);
  --sh-3:0 4px 16px -8px rgba(15,23,42,.12);
  --sh-brand:0 1px 2px rgba(15,23,42,.08);
  --sh-brand-2:0 2px 6px rgba(15,23,42,.10);

  /* 统一的动效节奏：时长与曲线全站一套，悬停手感才一致 */
  --dur:.26s;
  --dur-fast:.16s;
  --ease:cubic-bezier(.22,.68,.24,1);

  /* 骨架尺寸 */
  --page:640px;     /* 页面容器宽度 */
  --gap:16px;       /* PC 栅格间距 */
  --barh:66px;      /* PC 顶栏高度 */
  --tabh:66px;      /* 移动端底部导航高度 */
  --tabw:64px;      /* 底栏单格的最小宽度。见下面 .tabbar-in 那段：
                      格子先按 1fr 等分，只有在「等分之后比它还窄」时才改成
                       48px 定宽 + 横向滚动。48 是 Apple HIG 的 44pt 触控下限
                       往上取的一档，也是「七格在 360px 上仍不滑」的那条线。 */
  --hdr-h:66px;     /* 顶栏的**实测**高度，由 client.js 的 syncHdrH() 写回。
                      顶栏高度是随内容折行的（手机上 logo 一行、胶囊一行），
                      写死一个值必然在某一档错位。交付内页那四条段锚点要吸在
                      顶栏下沿，所以必须知道真实的那个数。
                      这里的 66 是 PC 值，也是「脚本还没跑」时的兜底。 */
  --barpad:14px;    /* 顶栏左右留白。顶栏每一行都用它，这样第二行
                       （工具名 + 返回）的两端永远压在第一行的两条线上 */
  /* iPhone 底部小黑条安全区。这里先给 0，再由下面的 @supports 覆盖为真实值：
     老浏览器不认识 env() 时不会让整个 calc() 失效（否则底部留白变成 0，
     最后一行内容会被固定导航条永久遮住）。 */
  --safe-b:0px;
}
@supports (padding:env(safe-area-inset-bottom)){
  :root{--safe-b:env(safe-area-inset-bottom,0px)}
}

/* ---------------- 每页身份色 ----------------
   七个板块各给一个身份色，只落在四处小面积元素上：徽标胶囊、标题里的强调字、
   KPI 数字、卡片顶边那条 3px 线。底子仍是中性白，所以颜色多了也不会花。
   挂在 body 的 data-tab 上（由 client.js 的 setTab 写入），这样顶栏胶囊、
   底部导航、保存台这些也一起跟随，不用给每个元素单独挂类名。

   小字一律用 --acc-d 而不是 --acc：七支 --acc 里有三支在白底上不到 4.5:1
   （微信绿 3.50、青绿 #0d9488 3.74、天空蓝 #0284c7 4.10），做 11px 徽标
   文字会发虚；七支 --acc-d 则全部过 5:1（最低的 #15803d 是 5.02）。
   **判据是「--acc 的对比度不得低于 3.1」** —— 微信绿原值 #07c160 只有 2.38:1，
   低于这条线，所以 2026-09-17 压深了一档（见下面它自己那一段）。
   `ui-check.js` 里有一条对七支逐支复算的断言钉着这个下限。
   --acc 本身只用于填充块（胶囊底、3px 细线）和渐变大字，那里对比度要求低。

   📌 上面这些数字都是**脚本实测**的（WCAG 相对亮度公式），别再凭手算往上写 ——
   2026-09-17 就因为手算把琥珀和青绿的数字写反了（原文写的是「青绿 3.3、琥珀 3.7」，
   实测正好相反）。要改配色就顺手把这条断言跑一遍，它会打印七支的实测值。

   ⚠️ 置换口诀（改配色只动下面七个块，别去翻别处）：
   现在**教程库与物料库共用同一支青绿**（这是产品决定，不是疏忽 —— 理由写在
   教程库那一段里），而朋友圈从青绿换成了微信绿。所以再动这几支时必须
   **先取旧值再写**，直接对着改会把别人正在用的颜色顺手覆盖掉。

   ⚠️ 新板块的身份色也必须写在这一段里（不能就近写在板块自己的那节）：
   这样「置换配色只动这一处」才成立。福利库那支玫红就是照这条来的 ——
   它的详细理由（为什么回到玫红、纸面为什么反而是灰的、--acc-d 怎么定的）
   直接写在它自己那个块上面。 */
/* 朋友圈（第一个）：微信绿，压深一档 —— #069e4e。
   ------------------------------------------------------------
   朋友圈发的是朋友圈图文、转的是公众号链接，本身就是微信生态里的内容，
   所以直接用微信自己的绿最直白：一眼就知道这块和微信有关，不用靠文案解释。
   它也是七个库里唯一一支「外部品牌色」而不是自选色相的身份色 ——
   其余六支先算色相间距，这一支先要可识别性。
   （历史上它用的是青绿 #0d9488，与物料库一字不差；教程库 2026-09-25 换靛蓝后，青绿只属于物料库。）

   ⚠️ 用的是「压深一档的微信绿」，不是微信原值 #07c160 —— 原值太轻。
   它在白底上只有 **2.38:1**（实测），是七支里最低的，次低是琥珀 3.19；
   而它的落点偏偏全是「大色块 + 白字」：顶栏激活胶囊、筛选栏的已选胶囊、
   KPI 渐变大字、卡片顶边那条 3px 线。白字压在 2.38:1 的绿上会发飘，
   整页看着没力气 —— 2026-09-17 的反馈原本就是「朋友圈的颜色太轻了」。
   #069e4e 是**同一个色相**（H≈148°，原值 149°，几乎重合）压暗一档，
   对比度 3.50:1（实测），比七支里最轻的琥珀（3.19）实，也过了 3.1 那条下限。
   品牌识别没丢：色相没动，认得出的还是那支微信绿。

   ⚠️ 为什么不直接换旧版微信 logo 绿 #1aad19：它是偏黄的正绿（H≈120°），
   而且明度**更高**（实测 2.98:1），换过去还是轻，只是换了个色相。诉求是「更重」，
   不是「换一支绿」。真想更沉还有 #057a42（实测 5.43:1），但那个已经偏森林绿，
   离「微信绿」远了，留着备用。三个档位都渲染过再选的。

   --acc-2 也从 #4ade80 压到 #2ecc71（H≈145°，与主色 148° 贴得更近）：
   KPI 大字走的是 --acc → --acc-2 的渐变，浅端太浅会把后半段拉飘。

   ⚠️ --acc-d 仍要压得很深：卡片上那枚 11px 徽标文字若直接用 --acc 会虚，
   所以配 green-700 #15803d（白底 5.0:1，过 4.5:1）。
   --acc 本身只用于填充块（胶囊底、3px 细线）与渐变大字。

   ⚠️ 和站内的成功色 --ok:#16a34a 色相很近（142° 对 148°），这是用微信绿
   必然带来的重叠。判断是「落点不重叠」：--ok 只出现在「已更新」那颗 6px
   呼吸点和「已完成」按钮上，身份色只出现在胶囊 / 顶边细线 / KPI 大字上；
   两者唯一会同时入眼的地方是顶栏那颗点与激活胶囊，实测不混。 */
body[data-tab="moments"]{--c1:#069e4e;--c2:#2ecc71;--ct:#15803d;}
/* 案例库（第二个）：2026-09-30 起是**暖金 #b45309**，原为紫罗兰 #7c3aed。
   ------------------------------------------------------------
   换色的由头是「一屏全是紫色、主次分不清」。但根子不在紫色本身 ——
   旧紫白底实测 5.20:1，数值是健康的；真正的问题是那版卡片把 7 处数字
   都做成了紫渐变大字（投放花费 1 + 成果 3 + 投放数据 3），
   一屏 15 条 = 105 个彩色大字，「7 个重音等于 0 个重音」。
   2026-09-30 已把版式退回上一套（成果条整块撤掉、投放数据重回主位），
   颜色则按用户指定换成暖金。两件事是分开的两半，别只看颜色那一半。

   为什么选暖金：
   · 旧紫 H≈262°，离教程库靛蓝 #4f46e5（H≈243°）只差 ΔH 18.7° ——
     两者同属「冷紫蓝」，深浅两套色系里都是最近邻，并排容易认错。
   · 暖色位一直空着：其余八支色相全落在 148°–347° 的冷半圈，
     26° 这一档无人占位。换上之后最近邻变成福利库玫红，ΔH 39.1°。
     ⚠️ 代价说在明处：福利库那支的最近邻由 85°（旧紫）收到 39°（新金），
        比原来近了。39° 仍在「能认出来」的范围内（紫/蓝/青绿几支彼此
        只有 18°–27°），且两库隔着两个 Tab、不会并排出现在同屏。
   · 语义上：「金」天然是案例的语言 —— 投放花了多少、拿回什么。

   ⚠️ 实测见 _verify/case-gold-audit.mjs（取**最差底**，不是白底）：
      浅色 --c1 4.58:1（阈值 3.1）／--ct 6.47:1（阈值 4.5）；
      深色 --c1 7.06:1／--ct 10.52:1 —— 深色档比旧紫的 3.58:1 清楚一倍。
   ⚠️ --c2 只是渐变末端，不单独承字（白字压在它上面一向不够过线，
      置顶那类实心块另走深渐变，与本值无关）。
   要再换色，改这一行 + 文末「深色系」那段里的同名行 —— 两处都要动。 */
body[data-tab="cases"]{--c1:#b45309;--c2:#f59e0b;--ct:#92400e;}
body[data-tab="materials"]{--c1:#0d9488;--c2:#2dd4bf;--ct:#0f766e;}
/* 工具库（第四支）：2026-09-29 起是**天空蓝 #0284c7**，原为琥珀 #d97706。
   ------------------------------------------------------------
   换色原因：琥珀是八支里最轻的一支（白底实测 3.19:1），色相偏「标签黄」，
   大面积铺开显得旧、发黄 —— 用户反馈「工具库颜色不好看」。
   新值 #0284c7 白底 4.10:1，过了 3.1 那条下限；--acc-d 取 #075985（7.56:1）。
   ⚠️ 代价说在明处：它与问答库 #2563eb（H≈221）、交付库 #336ffc（H≈222）
   同属蓝系（这支 H≈200，偏青）。三者分处不同 Tab、不同屏，永不并排；
   用户在四套候选（赛博青 / 品红 / 橙红 / 天空蓝）里选定了这一支。
   要再换色，改这一行 + 文末「深色系」那段里的同名行 —— 两处都要动。 */
body[data-tab="tools"]{--c1:#0284c7;--c2:#38bdf8;--ct:#075985;}
/* 问答库（第九个，2026-09-23）：接过产品库原来那支品牌蓝（#2563eb 系）。
   ------------------------------------------------------------
   ⚠️ 这里原来是 body[data-tab="products"]（产品库）。产品库整体下线、问答库
   接的正是它那个位置，所以这条规则**原地改成 qa**，而不是删掉再新加一条：
   一是产品库那支蓝和兜底的 --brand 本来就同值，改个选择器就完成了迁移；
   二是留着 products 那条就是条永远匹配不上的死规则，下次谁来读都会以为
   站里还有个产品库页。
   问答库没有独立色相 —— 「搜答案」这件事用中性的品牌蓝最稳；
   和它相邻的交付库那支 #336ffc 偏亮，两者摆在一起也分得开。 */
body[data-tab="qa"]{--c1:#2563eb;--c2:#60a5fa;--ct:#1d4ed8;}
/* 福利库（第六个）：玫红 #e11d48 —— 权益 / 礼遇的语义。
   ------------------------------------------------------------
   ⚠️ 这支颜色走过三个版本，三版理由都留在这儿，免得下次又来回改：
   ① 最早就是玫红；② 一度换成电光青 #0891b2（想直接往「科技感」靠）；
   ③ 现在回到玫红 —— 因为「太粉」这件事，根子不在玫红这个色相上。

   为什么说根子不在色相：
   · 玫红 H≈347° 在色环上是一支「孤立色」：离它最近的是案例库暖金（H≈26°）
     差 39°，其余各支都在 104° 开外。（2026-09-30 案例库由紫罗兰换成暖金
     之前，它离旧紫 #7c3aed 有 85°；换色后收窄到 39° —— 仍在可辨认范围内，
     且两库隔着两个 Tab、不会同屏出现。）
   · 真正发粉的是封面那层「大面积淡粉纸面」（#FBE4EA → #FEF6F8 → #F7D6DF）。
     粉是个「面积」问题：同一种红，铺满一整个封面块是粉色卡纸；
     缩成一根 1px 细线、一枚徽标、一颗小胶囊，就成了玫红的光。
     （封面 2026-09-30 由 16:10 收到 16:9，见下面 .wel-cover 那段。）

   所以这一版的办法是「色相回玫红，纸面去粉」：
   纸面从淡粉换成中性冷灰（见下面 .wel-cover 那一段），玫红只以细线 / 徽标 /
   小胶囊出现。灰底 + 玫红细线读起来是「仪器面板」，不是「消费券」。

   --acc-d 取 #be123c：卡片上那枚 11px 的等级徽章文字必须过 4.5:1 ——
   #e11d48 在白底上 4.7:1（压着线过），深一档的 #be123c 有 6.3:1，不发虚。
   --acc 本身只用于填充块（胶囊底、3px 细线）与渐变大字。 */
body[data-tab="benefits"]{--c1:#e11d48;--c2:#fb7185;--ct:#be123c;
  /* 封面走深色，所以另配一套「深底上的玫红」：深蓝黑压得住 #e11d48，
     那支会发闷；深底上要更亮更纯的 #f43f5e 才读得出「光」。 */
  --acc-neon:rgba(244,63,94,.44);--acc-neon-line:rgba(244,63,94,.19);}
/* 教程库（第七个）：靛蓝 #4f46e5 —— 2026-09-25 起换色，原为青绿 #0d9488。
   ------------------------------------------------------------
   历史上它先与物料库**刻意**共用青绿（「资料家族」的说法），首屏氛围底上线后
   这个共用成了硬伤：七个库的 hero 柔光都走各自的 --acc，教程和物料的氛围
   完全同色，靠封面图形已经拉不开。遂换靛蓝 —— 与案例库的暖金 #b45309、
   问答库的蓝 #2563eb 都错得开（金是暖色、蓝偏浅，靛蓝居中偏深）。

   --acc-d 取 #3730a3：教程卡上那枚 11.5px 的难度徽章文字要过 4.5:1 ——
   #4f46e5 在白底上 4.6:1 勉强过线，深一档的 #3730a3 有 8:1，稳。
   卡片上的产品标签（.tag-prod）跟着换成了同一支靛蓝。 */
body[data-tab="tutorials"]{--c1:#4f46e5;--c2:#818cf8;--ct:#3730a3;}
/* 交付库（第八个）：2026-09-18 起是**参考站蓝 #336ffc**，原值洋红 #a21caf。
   ------------------------------------------------------------
   ⚠️ 交付库这支**换过色**，与上面那套「八支色相错开」的逻辑是冲突的，
   所以这一段单独说清楚，别当成漏改：
     用户给了一个参考站（微盟 GEO 落地页），要求参考它的**内页内容详情**。
     参考站的色板是量出来的，不是抄感觉：主色 #336ffc（页面里出现 147 次）、
     亮端 #007fff / #159dff、页面底 #fbfcff / #f7faff、正文 #565e6d、次要 #9ea8bb。
     交付库因此从洋红 #a21caf 换成参考站这支蓝 —— **用户在 2026-09-18 明确保留**：
     「卡片改回我们自己的设计」和「配色怎么办」是两个问题，被问到第二个时选了保留。
   代价说在明处：**它与产品库的蓝（#2563eb）落在同一色相区**
   （H≈221 vs H≈223，基本是邻居）。这不是没注意到 —— 是用户在两个方案里选了这一个。
   可接受的理由：两者在不同 Tab、不同屏，永远不会并排出现；
   而且交付库的骨架（卡片网格 + 内页五段章头带）与产品库（上图下文大竖卡）
   没有一处相同，认错也不会认到对方头上。以后要再调色，先看这一段的来由。

   ⚠️⚠️ **参考站的「材质」没有一起搬过来，这是有意的，别好心补上。**
   中间那版曾把卡片也做成参考站那套（无描边 + 20px 圆角 + 浅蓝整面渐变 +
   柔光阴影 + 蓝字链），被用户当场否掉：「交付库的卡片太丑了，按我们自己的设计来」，
   并说明**参考站是用来改内页内容详情的，不是改列表卡片的**。所以定下来是这样分工：
     · 列表卡片 = 全站标准卡（白面 + 1px 描边 + --sh-1），见 .dlv-card 那一段，
       为了它专门定过的六个令牌（--dlv-card-bg / -sh / -sh-2 / --dlv-ink /
       --dlv-ink-2 / --dlv-chip-bg）已全部删除，别再从 git 历史里捡回来；
     · 内页 = 借参考站的**内容组织方式**（每个对象一块：成果 → 一句总结 →
       3 条「动作 → 结果」→ 自己那枚行动按钮）+ 这一支蓝。
   教训：视觉可以借，但别借到「同一个站里两张卡不是一家」的程度。

   --acc-d 取 #1b4ee4：内页的 11px 小字（段号、字段标签、客户胶囊、行内标记）
   若直接用 --acc（#336ffc），在白底上**实测 4.36:1**，差一点点没到 4.5:1
   （11px 小字按 WCAG 要 4.5，不能用「差一点没关系」放过去）；
   深一档是 6.45:1，压在章头带淡底上也还有 5.26:1。
   这几个数字都是脚本复算的，别手算 —— 手算会把 4.36 记成 4.4。
   --acc 本身只用于填充块（胶囊底、3px 顶边细线、段号方块）与渐变大字。 */
body[data-tab="deliveries"]{--c1:#336ffc;--c2:#159dff;--ct:#1b4ee4;}

/* KPI 排布微差：物料库和工具库的核心指标是「有多少份 / 多少个」，让它占宽一点；
   朋友圈与案例库三个指标平权，保持三等分。四页骨架因此不再是同一张脸。
   ID 选择器特异性高，会盖掉桌面断点里的 repeat(3,minmax(118px,1fr))，这是有意的。 */
#viewMaterials .kpis,
#viewTools .kpis{grid-template-columns:1.4fr 1fr 1fr}
/* 产品库再换一个排法：把「关联案例」放右边加宽 —— 三个板块三种节奏，
   一眼扫过去不会觉得是同一张模板复制出来的 */
#viewProducts .kpis{grid-template-columns:1fr 1fr 1.25fr}
/* 福利库把「全等级可享」放右边加宽：那一项是福利库里最要紧的一个数
   （剩下的「几项福利 / 几个分类」是背景信息） */
#viewBenefits .kpis{grid-template-columns:1fr 1fr 1.3fr}
/* 教程库换成「中间略宽」：教程库里「覆盖几个产品」比「几篇手册」更能说明
   这个库全不全（七篇手册可能只围着两款产品），所以把它挪到视觉重心上。
   四个板块四种排法，一眼扫过去不会觉得是同一张模板复制出来的 */
#viewTutorials .kpis{grid-template-columns:1fr 1.1fr 1.3fr}
/* 交付库改成「中间加宽」，是八页里唯一一支把视觉重心压在正中那一格的：
   三格是「几项功能 / 覆盖几个行业 / 几套话术」，中间那格才是这个库的健康度
   （33 个一级行业里覆盖了几个）；两头是背景信息。八页八种排法，
   扫过去不会觉得是同一张模板复制出来的 */
#viewDeliveries .kpis{grid-template-columns:1fr 1.35fr 1fr}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0}
/* 关键：给滚动条预留固定空间。
   朋友圈与案例库两条内容高度不同，滚动条会出现/消失，
   若没有固定 gutter，页面宽度会随之变化 → 切 Tab 时整体左右位移。 */
html{scrollbar-gutter:stable}
/* 兜底：不支持 scrollbar-gutter 的浏览器改为滚动条常驻，同样不会位移 */
@supports not (scrollbar-gutter:stable){
  html{overflow-y:scroll}
}
/* --grad 必须落在 body 上，不能写在 :root —— 自定义属性的 var() 替换发生在
   「声明所在的元素」上，写在 :root 就永远按 :root 的 --acc 求值成品牌蓝，
   实测切到案例库 / 物料库 / 工具库时，标题强调字和 KPI 数字还是蓝的。
   这条与 body[data-tab] 都作用在 body 上：--acc 先定下来，--grad 再跟着解析。
   全站 44 处调用点因此一行都不用改。 */
body{
  /* 身份色的三个角色改由 body[data-tab] 登记的 --c1/--c2/--ct 推导：
     换色系时每页只需重登记这三个数，四档透明度跟着 --sa/…/--sg 自动重算，
     不必为每套色系再抄一遍（九个库 × 四套色系 = 36 组数字，抄就是错）。
     ⚠️ 名字沿用 --acc-d 不动：全站 40+ 处引用它，改名要改一大片。
        它现在的含义是「身份色里用来写字的那一档」，由 --ct 决定深浅。 */

  /* ⚠️ 兜底必须写在这里：--c1/--c2/--ct 只有九个内容库在 body[data-tab] 上登记，
     一旦切到没登记的页（个人中心 data-tab="me" 就是唯一一个），--c1 无定义 →
     --acc 整条链失效 → 激活胶囊的 --grad 变透明、文字色回落成顶栏本色，
     表现为「顶部按钮没颜色 / 看不见」。这里给一套品牌蓝兜底，
     未登记的页就走品牌蓝（也自动跟随色系，因为 --brand 本身会被色系覆盖）。 */
  --c1:var(--brand);--c2:var(--brand-2);--ct:var(--brand-d);

  --acc:var(--c1);--acc-2:var(--c2);--acc-d:var(--ct);
  --acc-soft:color-mix(in srgb,var(--acc) var(--sa),transparent);
  --acc-line:color-mix(in srgb,var(--acc) var(--sl),transparent);
  --acc-ring:color-mix(in srgb,var(--acc) var(--sr),transparent);
  --acc-glow:color-mix(in srgb,var(--acc) var(--sg),transparent);

  --grad:linear-gradient(135deg,var(--acc) 0%,var(--acc-2) 100%);
  --grad-2:linear-gradient(135deg,var(--acc-2) 0%,var(--acc) 100%);
  --grad-soft:var(--acc-soft);
}
/* 兜底：不支持 color-mix 的旧浏览器退回品牌蓝那四档固定值。
   颜色会认不出当前库（九个库共用一套蓝），但至少不会变成全透明 ——
   淡底和描边还在，只是不跟着库换色。 */
@supports not (color:color-mix(in srgb,red 10%,transparent)){
  body{
    --acc-soft:rgba(37,99,235,.09);--acc-line:rgba(37,99,235,.15);
    --acc-ring:rgba(37,99,235,.24);--acc-glow:rgba(37,99,235,.30);
  }
}
body{
  font-family:"PingFang SC","HarmonyOS Sans SC","Microsoft YaHei",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,system-ui,sans-serif;
  background:var(--bg);color:var(--txt);
  font-size:15px;line-height:1.65;
  min-height:100vh;overflow-x:clip;
}
img{max-width:100%;display:block}
figure,figcaption{margin:0}
a{color:inherit;text-decoration:none}
button,input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}
h1,h2,h3,h4{margin:0;line-height:1.3;font-weight:800}
p{margin:0}
::selection{background:var(--acc-line)}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--acc-line);border-radius:20px;border:3px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:var(--acc-ring);background-clip:content-box}

/* ---------------- 背景氛围 ----------------
   这里原来铺了三颗大光斑（660px 蓝 / 580px 青 / 520px 紫，都带 blur(100px)）
   再加一层 64px 网格纹。它们是「说不上来的不舒服」的主要来源：大面积色雾会跟
   素材图抢视线，网格纹在小图上形成干扰，三颗球还各自无限循环动画、长期占着
   合成层。整层关掉后，背景就是干干净净的 --bg 一个颜色。
   想恢复其中某一项，把对应的 display:none 去掉即可。 */
.bg{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.bg-grid,.bg-orb{display:none}
@keyframes drift{
  0%,100%{transform:translate3d(0,0,0) scale(1)}
  50%{transform:translate3d(30px,44px,0) scale(1.07)}
}

/* ---------------- 顶栏 ---------------- */
.appbar{
  position:sticky;top:0;z-index:80;
  background:var(--solid);
  border-bottom:1px solid var(--line);
  transition:box-shadow .24s ease;
}
.appbar.scrolled{box-shadow:0 1px 2px rgba(15,23,42,.05)}
.appbar-in{
  max-width:var(--page);margin:0 auto;
  padding:10px var(--barpad);
  display:flex;flex-wrap:wrap;align-items:center;gap:10px;
}
.brand{display:flex;align-items:center;gap:10px;min-width:0;font-weight:800;font-size:15.5px;letter-spacing:-.2px}
/* 品牌位是设计给的 logo（G + 感知度 + 英文行 DEGREE OF PERCEPTION），
   不再是自绘的星形方块。
   只给高度、宽度交给图片自身比例：换一版 logo 不用回来改数字。
   站内那张 861×202（按内容框裁掉四周空白），比例 4.26:1 —— 所以 24px 高 ≈ 102 宽。

   ⚠️ 这张图必须整条保留，不能只留中文那行。
   量过源图的像素分布：G 标的尾部一直垂到英文行所在的那一段高度
   （中文块只到 y247，而 G 到 y308，英文行在 y275~299 —— 两者左右并排、上下重叠）。
   所以「去掉英文行」这个裁法在几何上就切掉了 G 的下半截，看上去像 logo 少了一截。
   真要换 logo 请整张替换，别在高度上动刀。 */
.brand-logo{flex:0 0 auto;display:block;height:24px;width:auto}
/* 前台顶栏的品牌位现在「只有 logo」—— 原先跟在后面的「服务市场」四个字已删。
   下面这两条是留给后台的（admin.html 的品牌名是「发布后台 + ADMIN 小标」），
   它仍然与 logo 并排，还需要排版规则托着；.brand 上的 gap:10px 同理。 */
.brand-txt{display:flex;align-items:baseline;gap:7px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.brand-txt em{font-style:normal;font-size:10.5px;font-weight:700;letter-spacing:1.4px;color:var(--txt-4)}
/* 顶栏站名：后台「站点设置」里能开关的一行文本，**默认关**（2026-09-26 改）。
   顶栏已经有 logo 了，站名是重复信息 —— 而它偏偏是顶栏里最会惹事的一件：
   品牌块被 flex 压窄时它不肯缩（原来 flex:0 0 auto），会**溢出品牌块边界**，
   正好压在紧跟着的导航第一个 Tab 上（1440/1500/1600 实测重叠 11~19px）。
   所以默认不给；真需要文字兜底（换了 logo、想让站名可读）到后台打开即可。

   ⚠️ 打开了也必须能缩：flex-shrink 改回 1 + min-width:0，
      宽不够时它自己截省略号，绝不再把内容顶出品牌块。
      （原来写死 shrink:0 是为了防「压成 0 宽、字还在却看不见」——
       那条顾虑由 min-width:0 + text-overflow 接住了，不会突然整行消失。） */
.brand-name{
  flex:0 1 auto;max-width:170px;
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:14px;font-weight:800;letter-spacing:-.2px;color:var(--txt-2);
}
@media (max-width:1024px){.brand-name{display:none}}

.nav{
  order:3;flex:1 0 100%;
  display:flex;gap:4px;margin:2px 0 8px;
  background:var(--acc-soft);
  border:1px solid var(--line);
  border-radius:14px;padding:4px;
}
/* 前台（body.client）：手机 / 平板把 Tab 从顶栏撤下，改由底部导航接管。
   注意后台 admin.html 的顶栏也叫 .nav，所以这里必须用 .client 限定，
   否则会连后台的 Tab 一起隐藏掉。 */
.client .nav{display:none}
.tab{
  flex:1;min-width:0;border:0;background:transparent;cursor:pointer;
  border-radius:10px;padding:8px 10px;
  font-size:14px;font-weight:700;color:var(--txt-3);
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  transition:background .18s,color .18s,box-shadow .18s;
}
.tab i{width:6px;height:6px;border-radius:50%;background:currentColor;opacity:.42;transition:.18s;flex:0 0 auto}
.tab:hover{color:var(--txt-2)}
.tab.active{background:var(--solid);color:var(--acc);box-shadow:0 4px 12px -6px rgba(15,23,42,.3)}
.tab.active i{opacity:1;background:var(--grad)}

/* 退役的 Tab（目前是「招商设置」）靠 hidden 属性藏起来：按钮留在 DOM 里
   是为了回退时摘掉 hidden 就能用。但光写 hidden 不够 —— 上面那条 .tab 里的
   display:inline-flex 会把 UA 默认的 display:none 顶掉，按钮照样显示。
   必须显式压回去。.toolview[hidden] / .lead[hidden] 是同一个坑。 */
.tab[hidden]{display:none!important}

.appbar-end{order:2;margin-left:auto;display:flex;align-items:center;gap:8px}

/* ---------------- 全站水印（后台「站点设置 → 全站水印」） ----------------
   一层 fixed 铺满视口的平铺 SVG：内容（名字 + 日期）由 client.js 烙进
   background-image 的 data-URI 里，这里只负责「铺满、不挡手、盖在最上面」。
   · pointer-events:none —— 水印只是给人看的，绝不能吃掉任何一次点击；
   · z-index 高于弹层：截图外泄的场景里，弹层里的内容同样要能追到人；
   · 不加过渡动画：开关一拨就要整屏消失/出现，淡入淡出反而像「还在」。 */
#wm{
  position:fixed;inset:0;z-index:9999;pointer-events:none;
  background-repeat:repeat;user-select:none;-webkit-user-select:none;
}
@media print{ /* 打印/导出 PDF 同样带着 —— 水印只对人拦截，不拦纸 */
  #wm{display:block!important}
}
.upd{
  display:inline-flex;align-items:center;gap:7px;
  font-size:11.5px;font-weight:600;color:var(--txt-3);
  background:var(--surface);border:1px solid var(--line);border-radius:999px;
  padding:6px 12px;white-space:nowrap;
}
.upd::before{content:'';width:6px;height:6px;border-radius:50%;background:var(--ok);box-shadow:0 0 0 0 rgba(8,168,106,.5);animation:pulse 2.6s ease-out infinite}
.upd:empty{display:none}
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(8,168,106,.45)}70%{box-shadow:0 0 0 7px rgba(8,168,106,0)}100%{box-shadow:0 0 0 0 rgba(8,168,106,0)}}

/* ---------------- 搜索（PC 顶栏） ---------------- */
.search{
  display:none;align-items:center;gap:9px;
  height:40px;padding:0 12px;border-radius:12px;
  background:var(--solid);border:1px solid var(--line-2);
  transition:border-color .16s ease,box-shadow .16s ease;
}
.search:focus-within{border-color:var(--acc);box-shadow:0 0 0 3.5px var(--acc-line)}
.search .s-ico{width:16px;height:16px;color:var(--txt-4);flex:0 0 auto}
/* 注意：全局 input[type=text] 规则（本文件靠后）和 .search input 特异性相同，
   会反过来盖掉这里的清零样式，导致输入框在容器里又画一个白底带框的盒子
   ——看起来就是「两个搜索框叠在一起」。所以这里用带属性选择器的高特异性选择器
   （.search input[type=text] = 0,2,1 > input[type=text] = 0,1,1）并显式覆盖 focus 态。 */
.search input,
.search input[type=text],
.search input[type=text]:focus,
.search input[type=text]:focus-visible{
  flex:1 1 auto;width:auto;min-width:0;height:100%;
  border:0;border-radius:0;background:transparent;
  outline:none;box-shadow:none;padding:0;margin:0;
  font-size:13.5px;font-weight:600;color:var(--txt);
  -webkit-appearance:none;appearance:none;
}
.search input::-webkit-search-cancel-button,
.search input::-webkit-search-decoration{display:none}
.search input::placeholder{color:var(--txt-4);font-weight:500}
.s-clear{
  flex:0 0 auto;border:0;background:transparent;cursor:pointer;
  color:var(--txt-4);font-size:13px;line-height:1;padding:3px 5px;border-radius:7px;
}
.s-clear:hover{color:var(--acc);background:var(--acc-soft)}

/* ---------------- 移动端底部导航（模拟 APP 操作） ----------------
   手机 / 平板固定吸底，PC 端整条隐藏（由顶栏胶囊 Tab 接管）。
   z-index 78 低于所有浮层（保存台 350 / 灯箱 400 / 引导层 420 / toast 500），
   所以打开浮层时会被自然盖住，不需要额外开关。

   === 第 8 个库进来之后：这一行改成「能等分就等分、放不下才横滑」 ===
   原来它是 grid-auto-columns:1fr 硬等分，七格在 320px 屏上每格只剩 40px，
   已是天然上限（见下面 .tabbar-btn .tico 那段）。再加一个库只有两条路：
   底栏留 5 个 + 一个「更多」抽屉，或者让这一行能横滑。这里走后者。
   做法是把列宽从 1fr 换成 minmax(--tabw, 1fr)：
     · 容得下 → 每格仍按 1fr 等分，与以前一模一样（430px 及以上都走这一支）；
     · 容不下 → 每格退回 48px 定宽，整行溢出成一条可横滑的带（430px 以下）。
   所以「滑」只在真放不下的时候才出现，不是一上来就能滑。
   ⚠️ 左右留白从 .tabbar 挪到了 .tabbar-in 自己身上（padding）。
   留白若留在外层，滚动容器的可视宽度会把它们算进去，滑到两端时
   首尾两格被外面的 padding 顶住一截、看着像没滑到底。 */
.tabbar{
  position:fixed;left:0;right:0;bottom:0;z-index:78;
  background:var(--solid);
  border-top:1px solid var(--line);
  box-shadow:0 -14px 34px -28px rgba(15,23,42,.95);
  padding:0 0 var(--safe-b);
}
/* 两端渐隐：横滑时「右边还有没有东西」全靠这两条。
   没有它，第 8 个库在手机上是「看不见、也想不起来」的存在。
   只在真能滑的那一侧亮，由 client.js 的 syncTabScroll 加 can-l / can-r。 */
.tabbar::before,.tabbar::after{
  content:'';position:absolute;top:0;bottom:var(--safe-b);width:26px;z-index:1;
  pointer-events:none;opacity:0;transition:opacity var(--dur-fast) var(--ease);
}
/* ⚠️ 这两条的颜色必须跟着底栏的面走，不能写死白：
   夜里底栏是半透明玻璃（见文件末尾色系段），写死 #fff 就是横滑时两侧两道白杠。
   浅色系下 var(--solid) 就是 #fff，视觉与改之前一模一样。 */
.tabbar::before{left:0;background:linear-gradient(to right,var(--solid) 26%,transparent)}
.tabbar::after{right:0;background:linear-gradient(to left,var(--solid) 26%,transparent)}
.tabbar.can-l::before,.tabbar.can-r::after{opacity:1}
.tabbar-in{
  max-width:var(--page);margin:0 auto;
  height:var(--tabh);
  /* 列数跟着按钮数量走：加一个 Tab 不用再改这条，也不会把多出来的挤到第二行。
     minmax 的第一项 =「再挤也不能比这更窄」的那条线（见 :root 里的 --tabw） */
  display:grid;grid-auto-flow:column;grid-auto-columns:minmax(var(--tabw),1fr);gap:2px;
  padding:0 8px;
  overflow-x:auto;overflow-y:hidden;
  -webkit-overflow-scrolling:touch;
  overscroll-behavior-x:contain;   /* 滑到头时别把整页也跟着带一下 */
  scrollbar-width:none;-ms-overflow-style:none;
}
.tabbar-in::-webkit-scrollbar{display:none}
.tabbar-btn{
  position:relative;border:0;background:transparent;cursor:pointer;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  padding:8px 2px 0;min-width:0;color:var(--txt-3);
  transition:color .2s ease,transform .12s ease;
}
/* 选中时顶部滑出的一条渐变指示（参考原生 App 的 tab 高亮） */
.tabbar-btn::before{
  content:'';position:absolute;top:0;left:50%;
  width:26px;height:3px;border-radius:0 0 4px 4px;background:var(--grad);
  transform:translateX(-50%) scaleX(0);transform-origin:50% 0;
  transition:transform .26s cubic-bezier(.22,.9,.3,1);
}
/* ⚠️ 图标槽的宽度必须跟着格子收（min(42px,100%)）。
   七格时代，底栏是「屏宽 / 库数」硬等分，320px 的屏一格拉到 40.3px ——
   写死 42px 就比格子还宽，七个格子被同一行一起压榨 1.72px，
   槽与槽之间只剩 0.3px。改成 min() 之后 320px 那档槽宽回到 36.3px、
   间距回到 6px，而 360 以上八档**一格都没变**。
   第 8 个库之后格子宽被 minmax(48px,1fr) 兜住了下限，槽拿到的一直是
   42px 那一侧，所以这条 min() 现在只剩「极窄屏兜底」一个作用。 */
.tabbar-btn .tico{
  display:grid;place-items:center;
  width:min(48px,100%);height:34px;border-radius:11px;
  transition:background .2s ease,box-shadow .2s ease;
}
.tabbar-btn .tico svg{width:26px;height:26px;display:block}
.tabbar-btn .tlabel{
  font-size:12px;font-weight:700;letter-spacing:.1px;line-height:1;
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* 按下去的反馈：轻微缩一下，接近原生手感 */
.tabbar-btn:active{transform:scale(.94)}
.tabbar-btn.active{color:var(--acc-d)}
.tabbar-btn.active .tico{
  background:var(--grad-soft);
  box-shadow:inset 0 0 0 1px var(--acc-line);
}
.tabbar-btn.active::before{transform:translateX(-50%) scaleX(1)}

/* ============================================================
   后台顶栏那排 Tab，窄屏也走横滑（第八个库之后）
   ------------------------------------------------------------
   后台顶栏与前台顶栏不是一套东西：后台的 <body> 没有 .client 类，
   所以窄屏下 .client .nav{display:none} 管不到它 —— 这排 Tab 一直挂在顶栏上。
   原来它靠 .tab{flex:1} 硬压进一行，七颗时代 390 档每颗 47px：
   三字标签被迫折成「三行、一行一个字」，胶囊高 73px、整条顶栏 153px 高。
   第八颗进来后更糟 —— 这一排的最小内容宽度涨到 414px，
   超过 390 的视口，整页多出一条 37px 的横向滚动。

   做法与前台底栏同一套（定宽 + 横滑），不再硬压：
     · .tab 取消 flex:1（那正是把它压到 47px 的元凶），改成 flex:0 0 auto；
     · 补 white-space:nowrap：三字标签必然占一行，胶囊回到 35px 高；
     · .nav 变成横向滚动容器，8 颗按 75px 定宽排开，滑到哪颗看哪颗。
   为什么不做「两端渐隐」那种提示（前台底栏有）：.nav 的底是半透明的
   var(--acc-soft)，再叠一层同色渐变会出现深浅接缝。这里的滑动提示靠
   「第 5 颗被切掉一半」这种天然的裁切，看得见就够了。

   ⚠️ 只加在 #adminView 上。前台顶栏在这一档已被 .client .nav 撤掉；
      侧边栏对照稿（/sidebar.html）的 nav 是竖排轨道，都不能跟着变成横滑。 */
@media (max-width:1023px){
  #adminView .nav{
    flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;
    -webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;
    scrollbar-width:none;-ms-overflow-style:none;
  }
  #adminView .nav::-webkit-scrollbar{display:none}
  #adminView .tab{flex:0 0 auto;white-space:nowrap}}

/* ---------------- 市场概览（Hero） ---------------- */
.hero{
  position:relative;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--r-xl);
  background:var(--solid);
  box-shadow:var(--sh-1);
  padding:26px 24px 22px;margin-bottom:14px;
}
/* ---------------- 首屏氛围底 + 图形签名（2026-09-25 起恢复装饰） ----------------
   问答库的搜索首屏（.qa-hero）一直是全站唯一「有氛围」的首屏：两团柔光 +
   顶部渐显点阵 + 大标题。这一段把同一套配方给到其余七个库的 .hero ——
   颜色全部走 --acc/--acc-2，谁在用就换谁的库色，不用每页抄数字。

   ⚠️ 上面那句「去掉光晕靠排版立住」是 2026-09 初的决定，当时对 —— 那时
   整页只有 hero 一块是彩色的、光晕却是写死的蓝，切到别的库也不换色，
   七个页面千篇一律还压不住正文。现在是「每库一支色、装饰只在 hero 这一层」，
   卡片 / 列表 / 筛选条依旧克制 —— 这个边界别破：**任何卡片都不许加柔光**，
   光只允许出现在首屏。 */
.hero{
  border-radius:22px;
  background:
    radial-gradient(720px 300px at 20% -46%, color-mix(in srgb,var(--acc) 17%,transparent), transparent 68%),
    radial-gradient(520px 280px at 94% 122%, color-mix(in srgb,var(--acc-2) 15%,transparent), transparent 72%),
    linear-gradient(180deg, color-mix(in srgb,var(--acc) 7%,var(--solid)), var(--solid) 64%);
}
/* 点阵：只有压在浅色氛围底上才看得见，用 mask 只在左上渐显，
   不铺满、不进正文区（正文对比度优先）。夜里另有覆盖（见色系段）。 */
.hero::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background-image:radial-gradient(color-mix(in srgb,var(--acc) 22%,transparent) 1px,transparent 1px);
  background-size:24px 24px;
  -webkit-mask-image:radial-gradient(660px 250px at 26% 0%,#000,transparent 74%);
  mask-image:radial-gradient(660px 250px at 26% 0%,#000,transparent 74%);
}
/* 顶边一道身份色高光：夜里 color-skin 段会把它调成霓虹版，浅色下极淡 */
.hero::after{
  content:"";position:absolute;left:0;right:0;top:0;height:1px;pointer-events:none;
  background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--acc) 40%,transparent),transparent);
}
/* 每页专属的「图形签名」：复用 eyebrow 里那枚库图标，放大做水印，
   压在柔光上、被圆角裁掉一角 —— 这是方案 B：物料 / 教程这类浅色库
   在纯氛围底下仍然长得像，靠这枚图形才真正「一眼认出这是哪个库」。
   z-index:0，在 .hero-body / .kpis（都是 z-index:1）之下，永远不压文字。 */
.hero-sign{
  position:absolute;right:-26px;bottom:-34px;width:210px;height:210px;
  pointer-events:none;color:var(--acc);opacity:.16;z-index:0;
}
.hero-sign svg,.hero-sign svg *{fill:none;stroke:currentColor;stroke-width:1.05;
  stroke-linecap:round;stroke-linejoin:round}
/* eyebrow 图标里故意带 fill 的点（气泡三点 / 勾选圆点）在签名里保持实心 */
.hero-sign svg [fill="currentColor"]{fill:currentColor;stroke:none}
.hero-body{position:relative;z-index:1;min-width:0}
.eyebrow{
  display:inline-flex;align-items:center;gap:7px;
  font-size:10.5px;font-weight:800;letter-spacing:1.2px;
  color:var(--acc-d);
  background:var(--grad-soft);border:1px solid var(--acc-line);
  padding:5px 11px;border-radius:999px;
}
/* 徽标左侧的小图标。原来是一个 5px 圆点、四个页面完全一样，切 Tab 时
   毫无辨识度；改成每页一个自己的 SVG（图标语言沿用底部导航那套） */
.eyebrow i{
  width:14px;height:14px;flex:0 0 auto;
  display:grid;place-items:center;color:var(--acc-d);
}
.eyebrow i svg{width:13px;height:13px;display:block}
/* 标题随氛围底放大一档：21 是「白卡时代」的尺寸，现在首屏是整页的重点，
   用 clamp —— 手机 22、桌面封 25（问答库的 .qa-hero 有自己的字号体系，不走这条） */
.hero h1{font-size:clamp(22px,3.4vw,25px);font-weight:800;letter-spacing:-.6px;margin-top:11px}
.hero h1 .gt{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.hero p{font-size:12.5px;color:var(--txt-3);margin-top:5px;font-weight:500}

.kpis{position:relative;z-index:1;display:grid;grid-template-columns:repeat(3,1fr);gap:7px;margin-top:13px}
.kpi{
  background:var(--solid);border:1px solid color-mix(in srgb,var(--acc) 13%,var(--line));border-radius:13px;
  padding:9px 11px;min-width:0;
}
.kpi b{
  display:block;font-size:18px;font-weight:800;letter-spacing:-.7px;line-height:1.2;
  font-variant-numeric:tabular-nums;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent;
}
.kpi span{display:block;font-size:10.5px;font-weight:600;color:var(--txt-3);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ---------------- 结果条 ---------------- */
.resultbar{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  font-size:12.5px;color:var(--txt-3);font-weight:600;
  margin-bottom:12px;min-height:19px;
}
.resultbar:empty{display:none}
.resultbar b{color:var(--acc);font-weight:800;font-variant-numeric:tabular-nums}

/* ---------------- 页面容器 ---------------- */
/* 底部留白要把固定导航条的高度让出来，否则最后一行内容会被永久遮住 */
.page{
  max-width:var(--page);margin:0 auto;
  padding:16px 14px calc(var(--tabh) + 26px + var(--safe-b));
  position:relative;z-index:1;
}

/* ---------------- 标题区 ---------------- */
.toolbar{display:flex;flex-direction:column;gap:8px;margin-bottom:14px}
.tb-title h1{font-size:20px;font-weight:800;letter-spacing:-.4px;line-height:1.25}
.tb-title h1 .gt{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.tb-title p{font-size:12.5px;color:var(--txt-3);margin-top:3px;font-weight:500}
.tb-meta{display:flex;align-items:center;gap:12px;font-size:12.5px;color:var(--txt-3);font-weight:600}
.tb-meta:empty{display:none}
.tb-meta b{color:var(--acc);font-weight:800;font-variant-numeric:tabular-nums}
.link-btn{
  border:0;background:transparent;color:var(--acc);cursor:pointer;padding:0;
  font-size:12.5px;font-weight:700;
}
.link-btn:hover{text-decoration:underline}

/* ---------------- 栅格 ---------------- */
.grid{display:grid;grid-template-columns:1fr;gap:14px;align-items:start}

/* ---------------- 按钮 ---------------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  border:1px solid var(--line-2);border-radius:12px;
  padding:10px 16px;font-weight:700;font-size:14px;
  background:var(--solid);color:var(--txt);cursor:pointer;white-space:nowrap;
  transition:transform .16s ease,border-color .16s ease,color .16s ease,background .16s ease,box-shadow .16s ease,filter .16s ease;
}
.btn:hover{transform:translateY(-1px);border-color:var(--acc);color:var(--acc);box-shadow:var(--sh-1)}
.btn:active{transform:translateY(0)}
.btn.primary{background:var(--grad);color:var(--on-acc);border-color:transparent;box-shadow:var(--sh-brand)}
.btn.primary:hover{color:#fff;filter:brightness(1.07);box-shadow:0 6px 14px -8px var(--acc-glow)}
.btn.ghost{background:transparent}
.btn.ghost:hover{background:var(--solid)}
.btn.danger{color:var(--danger);border-color:rgba(238,75,75,.28)}
.btn.danger:hover{background:var(--danger);color:#fff;border-color:var(--danger)}
.btn.sm{padding:8px 13px;font-size:13.5px;border-radius:11px}
.btn.tiny{padding:5px 11px;font-size:12px;border-radius:9px;font-weight:700}
.btn.lg{padding:13px 24px;font-size:15px;border-radius:14px}
.btn.block{width:100%}
.btn[disabled]{opacity:.45;cursor:not-allowed;transform:none;box-shadow:none}
/* 按钮图标：只在 PC 出现，手机端保持窄按钮不折行 */
.btn svg{width:15px;height:15px;flex:0 0 auto;display:none;margin-right:-1px}

.icon-btn{
  flex:0 0 auto;width:32px;height:32px;border:0;border-radius:10px;
  background:transparent;color:var(--txt-3);font-size:16px;line-height:1;cursor:pointer;
  display:grid;place-items:center;transition:.16s;
}
.icon-btn:hover{background:var(--acc-soft);color:var(--acc)}

/* ---------------- 筛选条 ----------------
   一排解决问题：选项少的组直接平铺（点一下即切，不用先展开再点一次），
   选项多的组收成下拉触发器，浮层里带搜索框。
   平铺 / 下拉的划分写在 HTML 里 —— 列表项 ≤5 用 .fg，>5 用 .fg.drop；
   JS 只管开关浮层、过滤浮层内的项、把当前选中值同步到触发器上。 */
.filterbar{
  position:relative;z-index:3;
  display:flex;align-items:flex-start;flex-wrap:wrap;gap:9px;
  background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-lg);
  padding:10px 12px;box-shadow:var(--sh-1);margin-bottom:13px;
}
.fb-groups{display:flex;align-items:center;flex-wrap:wrap;gap:8px 14px;min-width:0;flex:1 1 auto}
.fb-end{display:flex;align-items:center;gap:9px;margin-left:auto;flex:0 0 auto}
.fb-end .resultbar{margin-bottom:0}

/* 组：短组平铺、长组下拉，共用 .fg-name 这个小标签 */
/* position:relative 是为了「+N」那块浮层有可依靠的定位祖先
   （浮层插在 .chips 里，要落在这条轴的下方而不是页面某处） */
.fg{position:relative;display:flex;align-items:center;gap:8px;min-width:0;max-width:100%}
.fg-name{
  flex:0 0 auto;font-size:11px;font-weight:800;letter-spacing:.5px;
  color:var(--txt-4);white-space:nowrap;
}
.fg .chips{gap:6px}

/* 长组：下拉触发器。
   注意别把类名写成 .drop —— 本文件早有一个 .drop（文件上传拖拽区，
   带 1.5px 虚线框与 20px 内边距），撞上去会凭空多出一个虚线框。 */
.fg.fg-drop{position:relative}
.fg-btn{
  display:inline-flex;align-items:center;gap:7px;max-width:100%;
  padding:6px 11px;border:1px solid var(--line-2);border-radius:10px;
  background:var(--solid);color:var(--txt-2);font-size:12.5px;font-weight:700;
  cursor:pointer;white-space:nowrap;
}
.fg-btn .fg-val{font-weight:800;max-width:14ch;overflow:hidden;text-overflow:ellipsis}
.fg-btn .fg-car{
  flex:0 0 auto;width:0;height:0;
  border-left:4px solid transparent;border-right:4px solid transparent;
  border-top:5px solid currentColor;
}
/* 触发器上有筛选（选了「全部」以外）时点亮，收起来也一眼看得见 */
.fg-btn.on{border-color:var(--acc);background:var(--grad-soft);color:var(--acc-d)}
.fg.open .fg-btn{border-color:var(--acc);box-shadow:0 0 0 4px var(--acc-soft)}
.fg.open .fg-car{transform:rotate(180deg)}

/* 浮层 */
.fg-pop{
  display:none;position:absolute;z-index:2;left:0;top:calc(100% + 7px);
  width:max-content;min-width:240px;max-width:min(430px,86vw);
  background:var(--solid);border:1px solid var(--line-2);border-radius:var(--r-lg);
  box-shadow:var(--sh-3);padding:9px;
}
.fg.open .fg-pop{display:block}
/* 一个小尖角指向触发器：浮层属于哪一组，一眼就对上了。
   浮层贴到右边界会翻转成右对齐（.right），尖角跟着挪 */
.fg-pop::before{
  content:'';position:absolute;left:19px;top:-5px;width:9px;height:9px;
  background:var(--solid);border-left:1px solid var(--line-2);border-top:1px solid var(--line-2);
  transform:rotate(45deg);
}
.fg-pop.right::before{left:auto;right:19px}
.fg-sch{
  display:flex;align-items:center;gap:7px;height:34px;padding:0 10px;
  margin-bottom:8px;border:1px solid var(--line-2);border-radius:10px;
  background:var(--solid-2);cursor:text;
}
.fg-sch svg{width:14px;height:14px;flex:0 0 auto;color:var(--txt-4)}
/* 搜索框自己不带聚焦环（它已经在带框的 .fg-sch 里了），环挪到外层容器。
   下面这段必须用「带属性选择器」的高特异性写法（.fg-sch input[type=text] = 0,2,1）：
   本文件靠后有一条全局表单规则
     input[type=text],input[type=password],…{width:100%;padding:11px 13px;border:1px…}
   特性 (0,1,1) 和 .fg-sch input 相同、却写在后面 —— 于是上面这些清零会被整段盖掉，
   输入框拿到 11px 内边距 + 1px 边框 + 白底，实测高 43px，从 34px 高的 .fg-sch 里
   上下各冒出一截，看起来就是「搜索框重叠 / 套了两层框」。
   .search（见本文件顶部）和 .afsearch 栽的都是同一个坑，这里照它们的办法一并设防。
   :focus 态必须一起写：全局那条 input:focus{border-color:…;box-shadow:0 0 0 3.5px…}
   同样是 (0,1,1)，漏了它聚焦时又会冒出一个蓝色内框。 */
.fg-sch input,
.fg-sch input[type=text],
.fg-sch input[type=text]:focus,
.fg-sch input[type=text]:focus-visible{
  flex:1 1 auto;width:auto;min-width:0;height:100%;margin:0;
  border:0;border-radius:0;background:transparent;
  outline:none;box-shadow:none;padding:0;
  font-size:13px;color:var(--txt);
  -webkit-appearance:none;appearance:none;
}
.fg-sch:focus-within{border-color:var(--acc);box-shadow:0 0 0 3px var(--acc-soft)}
.fg-pop .chips{flex-wrap:wrap;gap:6px;max-height:min(300px,46vh);overflow:auto;overscroll-behavior:contain;padding-right:2px}
.fg-pop .chip.hide{display:none}
.fg-none{display:none;padding:16px 6px;text-align:center;font-size:12.5px;color:var(--txt-4)}
.fg-pop.empty-hit .fg-none{display:block}

/* 窄屏：不要换行 —— 平铺组固定占满一行「标签 + 一条可横滑的 chip」，
   下拉触发器是短胶囊，几个并排一行。
   换行排版在手机上会散成三四行，分组标签还会孤零零挂在侧边，太碎。
   选择器刻意写 .fg > .chips（直接子元素）：浮层里的 chips 不是直接子元素，
   于是它不受影响，仍然是正常换行的网格。 */
@media (max-width:1023px){
  .filterbar{display:block}
  .fb-groups{display:flex;flex-wrap:wrap;gap:7px 8px}
  .fg:not(.fg-drop){flex:1 1 100%}
  .fg.fg-drop{flex:0 0 auto}
  .fg > .chips{
    flex:1 1 auto;min-width:0;
    flex-wrap:nowrap;overflow-x:auto;overscroll-behavior-x:contain;
    -webkit-overflow-scrolling:touch;
    scrollbar-width:none;padding-bottom:1px;
  }
  .fg > .chips::-webkit-scrollbar{display:none}
  /* 关键：nowrap 容器里 chip 默认会被当成可压缩的弹性项，
     一路压到只剩「近…」这种省略号。给它 flex:0 0 auto 保持原宽，
     装不下时由容器横向滚动来消化。 */
  .fg > .chips > .chip{flex:0 0 auto}
  /* 右边一道淡出，暗示这一行还能往右滑。
     淡出作用在容器的右边缘 16px：内容本来就装得下时那里是空的，
     所以不会误伤最后一个 chip。 */
  .fg > .chips{
    -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 16px),transparent);
    mask-image:linear-gradient(90deg,#000 calc(100% - 16px),transparent);
  }
  .fb-end{margin-top:8px;justify-content:flex-end}}

.chips{display:flex;flex-wrap:wrap;gap:7px}
.chip{
  padding:6px 12px;border-radius:10px;
  font-size:13px;font-weight:600;color:var(--txt-2);
  background:var(--solid);border:1px solid var(--line-2);
  cursor:pointer;user-select:none;white-space:nowrap;
  max-width:100%;overflow:hidden;text-overflow:ellipsis;
  transition:transform .14s ease,background .14s ease,color .14s ease,border-color .14s ease,box-shadow .14s ease;
}
.chip .ct{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.chip .cn{
  font-style:normal;font-size:10.5px;font-weight:800;
  color:var(--txt-4);margin-left:6px;
  font-variant-numeric:tabular-nums;
}
.chip.active .cn{color:rgba(255,255,255,.8)}
.chip:hover{color:var(--acc);border-color:var(--acc);transform:translateY(-1px)}
.chip.active{background:var(--grad);color:var(--on-acc);border-color:transparent;box-shadow:none}
.chip.active:hover{color:#fff}
.chip.zero{opacity:.42}
.chip.zero.active{opacity:1}

/* ---------------- 平铺组塞不下时：收进「+N」 ----------------
   交付库两条轴的候选名都很长（功能名动辄 9 个字，13 枚平铺要 1742px，
   而 1440 下能用来铺的只有 1366px），换行一次就散成四面 chip 墙。
   所以改成：一行放得下的照常平铺，放不下的收进末尾这枚「+N」，点开是全量列表。
   ⚠️ 收起与放开的活由 JS 做（fitChips），CSS 只负责被收起来的那些怎么显示、
   以及「选中的那枚必须看得见」这个顺序。
   ⚠️ 仅在 PC（.fg > .chips 是 wrap）生效：手机那档 CSS 已把它改成 nowrap 横滑，
      由滚动消化，JS 会自己退场（见 client.js fitChips 开头的判断）。 */
.chips > .chip.hid{display:none}
/* 「+N」这枚刻意不叫 .chip：筛选委托是 closest('.chip')，
   叫了 .chip 就会被当成一次选中（data-dc 未定义 → 筛选项变 undefined）。 */
.chip-more{
  flex:0 0 auto;display:inline-flex;align-items:center;
  padding:6px 11px;border-radius:10px;
  font-size:13px;font-weight:700;color:var(--txt-3);
  background:var(--solid-2);border:1px dashed var(--line-2);
  cursor:pointer;white-space:nowrap;
  transition:color .14s ease,border-color .14s ease,background .14s ease;
}
.chip-more:hover{color:var(--acc);border-color:var(--acc);background:var(--acc-soft)}
/* 「全部」钉在最前、选中的紧跟其后、其余按原序 ——
   这样被收进「+N」的那枚选中项也能在条上看得见，不用点开才知道筛了什么。
   只在真的收起来了（.overflowing）才启用，没溢出时不惊动顺序。 */
.chips.overflowing > .chip{order:2}
.chips.overflowing > .chip:first-child{order:0}
.chips.overflowing > .chip.active{order:1}
/* 「+N」永远排在最后 */
.chip-more{order:3}

/* ---------------- 卡片共用品 ---------------- */
.post,.case,.card{
  position:relative;background:var(--solid);
  border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:var(--sh-1);
}
.post,.case{padding:16px;overflow:hidden}
.post::after,.case::after{
  content:'';position:absolute;left:0;right:0;top:0;height:3px;
  border-radius:var(--r-lg) var(--r-lg) 0 0;background:var(--grad);
  opacity:0;transition:opacity .22s ease;pointer-events:none;
}

.card-top{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
/* 无图卡片：物料 / 工具 / 福利 / 教程四库已取消封面图，
   改用这枚类型色块 + 标签行区分类型，卡片更矮、一屏看得更多 */
.x-ico{width:32px;height:32px;border-radius:9px;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;background:var(--solid-2);color:var(--txt-3);font-size:10.5px;font-weight:800;letter-spacing:-.3px;line-height:1;text-align:center}
.x-ico svg{width:17px;height:17px}
.x-ico.k-pdf{background:linear-gradient(135deg,#fff2f0,#ffe4e0);color:#c0392b}
.x-ico.k-doc{background:linear-gradient(135deg,#eff5ff,#dde9ff);color:#1d4ed8}
.x-ico.k-xls{background:linear-gradient(135deg,#eafaf0,#d7f5e4);color:#0f7a4a}
.x-ico.k-ppt{background:linear-gradient(135deg,#fff4ea,#ffe5d1);color:#c2610c}
.x-ico.k-zip{background:linear-gradient(135deg,#f4f1ff,#e8e0ff);color:#6d4bd8}
.x-ico.k-misc{background:linear-gradient(135deg,#f2f6fc,#e4ecf8);color:#4a5b78}
.x-ico.k-tool,.x-ico.k-tut{background:var(--acc-line);color:var(--acc-d)}
.x-ico.k-wel{background:linear-gradient(135deg,#fff4ea,#ffe5d1);color:#c2610c}
.tag-value{background:var(--acc-line);border-color:var(--acc-ring);color:var(--acc-d)}
.tut-foot{margin-top:auto}
.tag{
  font-size:11.5px;font-weight:700;letter-spacing:.2px;
  padding:3px 9px;border-radius:8px;
  background:var(--grad-soft);color:var(--acc-d);border:1px solid var(--acc-line);
}
/* 产品分类：案例库的主维度，用实心渐变与行业标签拉开层级 */
.tag-cat{background:var(--grad);color:var(--on-acc);border-color:transparent}
.tag-top{background:var(--acc-soft);color:var(--acc-d);border-color:var(--acc-line)}
.tag-media{
  display:inline-flex;align-items:center;gap:5px;
  background:var(--solid);color:var(--txt-3);border-color:var(--line-2);
}
.tag-media svg{width:12px;height:12px;flex:0 0 auto;opacity:.75}
/* 物料归属产品标签：用产品库主色（青）与「分类」标签区分开 */
/* ⚠️ 死样式，但别删：client.js 物料渲染的注释里还留着「问答卡在用」的说法，
   实际问答卡挂产品用的是 .qa-mp（走 var(--acc-d) 自动跟库色，无需手动同步）。
   真要清理得连那条注释一起改 —— 2026-09-25 核实过，全站没有第二个渲染方。
   颜色照旧跟着教程库记：原青绿三件套已同步成靛蓝。 */
.tag-prod{background:#eef0fe;color:#4338ca;border-color:#c7d2fe}
.date{margin-left:auto;font-size:11.5px;font-weight:600;color:var(--txt-4);font-variant-numeric:tabular-nums}

/* ================= 问答库（第九个库） =================
   ★ 2026-09-23 第三版：整库版式再重做一次（第二版被用户否掉：「死板、
     一点都不大气、下面的比例也难受」）。第二版的问题出在哪，逐条记下来，
     免得下次又走回去：
       · 死板 —— 卡片一律「序号方块 + 16px 问题 + 13.5px 答案」，六十几张
         长得一模一样，没有轻重；筛选区又是一张和别页同款的厚白卡。
       · 不大气 —— 标题 29px、搜索框 60px，是手机尺寸直接搬到桌面上；
         hero 内边距只有 36px，整块缩在页面顶部一小条里。
       · 比例难受 —— hero 撑满版心（1200），列表却收窄到 880 居中，
         上下两层的左右边线对不齐，像三块不同宽度的东西摞起来。
     第三版的对策：
       · 首屏加高、标题 clamp 到 46px、搜索框 640×64；
       · hero / 工具带 / 列表 / 页底**同轴**（都撑满 .page）；
       · 列表 PC 双列、卡片重排版（徽章上移、问题 18px、页脚虚隔线）；
       · 筛选那张白卡片拆成两条无底板胶囊行，整页只剩「hero / 列表」两层。

   ★ 为什么这一库不复用站内那套模板（.hero / .filterbar / .grid / .chip）：
     理由不是审美，是用法 ——
       别的七个库是**浏览**（朋友圈、案例、物料…进来先看有什么），
       分类导航打头最合理；
       这一库是**查询**（代理商被客户问到一个点，进来就是要找答案），
       搜索框打头才合理。
     所以这一页整站独立，三块全用自己的类 —— 以后改别的库的筛选样式，
     这一页不会被牵连，反过来也一样。

   三块的分工：
     ① .qa-hero  首屏搜索带：标题 + 居中大搜索框 + 热门标签。
        这一带是整页唯一的「重点」，视觉重量全压在这儿；
     ② .qa-tools 工具带：两条筛选轴（左标签 + 胶囊横排、横滑不换行）
        + 结果条。它是**收窄**手段，排在搜索之后，重量必须低于首屏；
     ③ .qa-list  问答列表：PC 双列 / 手机单列，
        每张卡 = 徽章行 + 问题 + 答案 + 页脚（标签 / 展开）。

   ★ 这一库**没有详情页**：一问一答本身就是最小的完整单元，
     再点进去只会剩一屏空白。所以答案默认折起 4 行，
     点「展开全文」原地摊开（不跳页、不重绘列表）。 */

/* ---- ① 首屏搜索带 ----
   第三版。整块是页面上**唯一**的重心：更大的内边距、更大的标题、更大的搜索框。
   ★ 宽度：撑满 .page 容器，与下面的工具带 / 列表 / 页底**同轴**。
     第二版 hero 满宽、列表却收窄到 880 居中，上下两层左右边线对不齐 ——
     那是「比例难受」的主因，这一版把四块的左右边线钉在同一条线上。 */
.qa-hero{
  position:relative;overflow:hidden;
  margin-bottom:20px;padding:58px 24px 46px;
  border:1px solid rgba(37,99,235,.10);border-radius:26px;
  background:
    radial-gradient(880px 400px at 50% -32%, rgba(37,99,235,.15), transparent 66%),
    radial-gradient(560px 320px at 90% 116%, rgba(0,194,255,.12), transparent 70%),
    linear-gradient(180deg,#f4f8ff,#fff 68%);
}
/* 极淡的点阵：只有压在浅蓝底上才看得见，给整块添一点技术感；
   用 mask 只在顶部渐显，不让它铺满、免得干扰正文对比度 */
.qa-hero::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background-image:radial-gradient(rgba(37,99,235,.15) 1px,transparent 1px);
  background-size:26px 26px;
  -webkit-mask-image:radial-gradient(700px 300px at 50% 0%,#000,transparent 76%);
  mask-image:radial-gradient(700px 300px at 50% 0%,#000,transparent 76%);
}
.qa-hero-in{position:relative;z-index:1;max-width:780px;margin:0 auto;text-align:center}
.qa-eyebrow{
  display:inline-flex;align-items:center;gap:7px;
  padding:6px 14px 6px 8px;border-radius:999px;
  background:var(--solid);border:1px solid var(--acc-line);
  font-size:12.5px;font-weight:800;letter-spacing:.2px;color:var(--acc-d);
  box-shadow:0 1px 2px rgba(15,23,42,.05),0 8px 20px -14px rgba(37,99,235,.55);
}
.qa-eyebrow i{
  display:grid;place-items:center;width:20px;height:20px;border-radius:50%;
  background:var(--grad);color:var(--on-acc);
}
.qa-eyebrow i svg{width:13px;height:13px;display:block}
/* clamp 而不是写死：手机上 26px 起、桌面封到 46px。
   第二版的 29px 是「手机尺寸搬到了电脑上」，这是「不大气」最直接的来源。 */
.qa-hero h1{
  margin-top:18px;
  font-size:clamp(26px,4.4vw,46px);
  font-weight:800;letter-spacing:-1.4px;line-height:1.2;
}
.qa-hero h1 .gt{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.qa-hero p{margin-top:12px;font-size:13.5px;font-weight:600;color:var(--txt-3);letter-spacing:.1px}
.qa-hero p b{color:var(--acc);font-weight:800;font-variant-numeric:tabular-nums}

/* 搜索框：一块白胶囊 + 外投影，聚焦时套一圈柔光。
   全站只有这一处这样做 —— 让人一眼看出「这一页是拿来搜的」。
   640px 宽 + 64px 高：比第二版宽 40、高 4，按钮跟着长到 50 ——
   它得压得住上面 46px 的标题，否则整块会「头大身子小」。
   ⚠️ 下面清零输入框的两条规则**必须带属性选择器**抬特异性（.qa-sbox input[type=text]
   = 0,2,1）：本文件靠后有一条全局 input[type=text]{width:100%;padding:11px 13px;
   border:1px…}（0,1,1），不这样写会被整段盖掉，胶囊里会再冒出一个白底带框的
   输入框 —— 看起来就是「两个搜索框叠在一起」。
   :focus 那条也要一起写：全局的 input:focus{border-color:…;box-shadow:…} 同样是
   (0,1,1)，漏了它聚焦时又会多出一个蓝色内框。.search / .fg-sch / .afsearch
   栽的都是同一个坑，这里照它们的办法一并设防。 */
.qa-sbox{
  display:flex;align-items:center;gap:12px;
  max-width:640px;height:64px;margin:28px auto 0;padding:0 7px 0 22px;
  background:var(--solid);border:1px solid var(--line-2);border-radius:999px;
  box-shadow:0 14px 32px -20px rgba(15,23,42,.45),0 2px 6px -2px rgba(15,23,42,.06);
  cursor:text;
  transition:border-color var(--dur-fast) ease,box-shadow var(--dur-fast) ease;
}
.qa-sbox:hover{border-color:var(--line-3)}
.qa-sbox:focus-within{
  border-color:var(--acc);
  box-shadow:0 0 0 5px var(--acc-soft),0 18px 36px -20px rgba(37,99,235,.62);
}
.qa-sico{width:21px;height:21px;flex:0 0 auto;color:var(--txt-4);transition:color var(--dur-fast) ease}
.qa-sbox:focus-within .qa-sico{color:var(--acc)}
.qa-sbox input,
.qa-sbox input[type=text],
.qa-sbox input[type=text]:focus,
.qa-sbox input[type=text]:focus-visible{
  flex:1 1 auto;width:auto;min-width:0;height:100%;margin:0;padding:0;
  border:0;border-radius:0;background:transparent;outline:none;box-shadow:none;
  font-size:16px;font-weight:600;color:var(--txt);
  -webkit-appearance:none;appearance:none;
}
.qa-sbox input::placeholder{color:var(--txt-4);font-weight:500}
.qa-sbox input::-webkit-search-cancel-button,
.qa-sbox input::-webkit-search-decoration{display:none}
/* 清空：只在有词时出现（JS 控 hidden），做成一枚小圆片 */
.qa-sclear{
  flex:0 0 auto;width:26px;height:26px;border:0;border-radius:50%;
  background:var(--solid-2);color:var(--txt-3);
  font-size:12px;line-height:1;cursor:pointer;display:grid;place-items:center;
  transition:background var(--dur-fast) ease,color var(--dur-fast) ease;
}
.qa-sclear:hover{background:var(--acc-soft);color:var(--acc)}
/* ⚠️ 这一条不能省。上面给 .qa-sclear 写了 display:grid，而**作者样式会盖过
   浏览器默认的 [hidden]{display:none}**（层级里来源优先于特异性）——
   不显式压回去，没输关键词的时候那枚 ✕ 也一直摆在那儿。
   .tab / .toolview / .lead / .sb-item 栽的都是同一个坑，本站统一用 !important 兜。
   （旧版这一页的 .qs-clear 就是漏了这条：清空按钮常显。一并修掉。） */
.qa-sclear[hidden]{display:none!important}
.qa-sgo{
  flex:0 0 auto;height:50px;padding:0 30px;
  border:0;border-radius:999px;background:var(--grad);color:var(--on-acc);
  font-size:15px;font-weight:800;letter-spacing:1.5px;cursor:pointer;
  box-shadow:0 8px 20px -10px var(--acc-glow);
  transition:filter var(--dur-fast) ease,transform var(--dur-fast) ease;
}
.qa-sgo:hover{filter:brightness(1.07)}
.qa-sgo:active{transform:translateY(1px)}

/* 热门标签：一排小胶囊，居中。空数据时整块收起（:empty 兜底） */
.qa-hot{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:8px;margin-top:20px}
.qa-hot:empty{margin-top:0}
.qa-hot-l{font-size:12px;font-weight:800;letter-spacing:.8px;color:var(--txt-4);margin-right:3px}
.qa-hot-b{
  padding:6px 14px;border-radius:999px;
  background:var(--solid);border:1px solid var(--line);color:var(--txt-2);
  font-size:13px;font-weight:600;cursor:pointer;
  transition:background var(--dur-fast) ease,border-color var(--dur-fast) ease,
             color var(--dur-fast) ease,transform var(--dur-fast) ease;
}
.qa-hot-b:hover{border-color:var(--acc);color:var(--acc);background:var(--acc-soft);transform:translateY(-1px)}
.qa-hot-b.on{background:var(--acc-soft);border-color:var(--acc);color:var(--acc-d)}

/* 结果条上那句「没同时命中，已按相关度放宽」（2026-09-24 加）。
   不做成红色警告 —— 它不是错误，是一次**成功的兜底**，只是得让人知道
   这批结果是放宽来的，别当成精确匹配去逐个核对。
   用主题色的浅底而不是中性灰：灰字在这行里会被「共 N 条」吃掉。 */
.qa-relax{
  margin-left:10px;padding:3px 10px;border-radius:999px;
  background:var(--acc-soft);color:var(--acc-d);
  font-size:12px;font-weight:700;letter-spacing:.1px;white-space:nowrap;
}

/* ---- ② 工具带：两条筛选轴 + 结果条 ----
   第三版去掉那张白底卡片（.qa-filters）之后，三行直接落在页面底色上，
   gap 撑出层级=留白，而不是靠边框和阴影 —— 横在 hero 与列表之间的
   厚卡片没了，整页就只剩「hero / 列表」两层关系，不再被拦腰截断。 */
.qa-tools{display:flex;flex-direction:column;gap:11px;margin-bottom:16px}
/* 左标签定宽、右胶囊可横滑：标签列对齐了，两行才会像一组；
   胶囊不换行是刻意的 —— 换行后「分类」那行会把页面撑得很高，
   横向滑一下比拉长页面省事（手机上是同一条逻辑）。 */
.qa-frow{display:flex;align-items:center;gap:14px;min-width:0}
.qa-flabel{
  flex:0 0 40px;text-align:right;
  font-size:11px;font-weight:800;letter-spacing:1.4px;color:var(--txt-4);
}
.qa-fchips{
  display:flex;align-items:center;gap:8px;min-width:0;
  overflow-x:auto;overflow-y:hidden;
  padding:3px 1px;
  scrollbar-width:none;-ms-overflow-style:none;
}
.qa-fchips::-webkit-scrollbar{display:none}
.qa-pill{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:7px;
  padding:7px 15px;border-radius:999px;white-space:nowrap;
  background:var(--solid);border:1px solid var(--line-2);color:var(--txt-2);
  font-size:13.5px;font-weight:600;line-height:1.4;cursor:pointer;
  transition:background var(--dur-fast) ease,border-color var(--dur-fast) ease,
             color var(--dur-fast) ease,transform var(--dur-fast) ease,
             box-shadow var(--dur-fast) ease;
}
.qa-pill .n{font-size:11.5px;font-weight:800;color:var(--txt-4);font-variant-numeric:tabular-nums}
.qa-pill:hover{
  border-color:var(--acc);color:var(--acc);transform:translateY(-1px);
  box-shadow:0 6px 14px -10px var(--acc-glow);
}
.qa-pill.on{
  background:var(--grad);border-color:transparent;color:var(--on-acc);
  box-shadow:0 10px 20px -12px var(--acc-glow);
}
.qa-pill.on .n{color:rgba(255,255,255,.85)}
.qa-pill.zero{opacity:.45}
.qa-pill.zero.on{opacity:1}

/* ---- 结果条：紧贴列表上沿，是「我在看筛选后的哪一批」的现场提示 ---- */
.qa-bar{display:flex;align-items:center;min-height:20px;margin:2px 0 0;padding:0 2px}
.qa-bar .resultbar{margin-bottom:0}

/* ---- ③ 问答列表 ----
   第三版：PC 双列 / 手机单列。
   第二版单列 880 居中，在 1200 的版心里左右各空 160px，细长一列挂下来 ——
   「下面比例难受」的另一半就是它。双列后每列约 576px（一行约 30 字），
   比 880 单列的一行 59 字**更**好读，整块也跟 hero 咬合上了。
   align-items:start 是必须的：让同一行的两张卡各按自己内容收高，
   否则短卡会被长卡撑出大段空白。 */
/* align-items 用默认的 stretch（不再写 start）：同一行两张卡撑成等高，
   底边与页脚那条虚线才对得齐。卡片只有「问题占 1 行还是 2 行」这点高度差，
   撑平之后一行两张完全齐平 —— 第四版要的就是这个。 */
.qa-list{display:grid;grid-template-columns:minmax(0,1fr);gap:14px}
.qa-item{
  display:flex;flex-direction:column;
  padding:20px 22px 18px;
  background:var(--surface);border:1px solid var(--line);
  border-radius:18px;box-shadow:var(--sh-1);cursor:pointer;
  transition:border-color var(--dur-fast) ease,box-shadow var(--dur-fast) ease,transform var(--dur-fast) ease;
}
/* 整张卡是热区（点哪儿都开答案弹框）—— 键盘 Tab 聚焦时给一圈描边，
   否则 role=button 的卡片在键盘用户眼里跟普通卡片没区别 */
.qa-item:focus-visible{outline:2px solid var(--acc);outline-offset:3px}
/* 悬停：抬 2px + 换一层更深的贴边阴影。全站卡片统一是这个手势，
   幅度比第二版多 1px —— 双列网格里卡片多，反馈弱了就像没反应 */
.qa-item:hover{
  border-color:var(--acc-ring);transform:translateY(-2px);
  box-shadow:0 12px 28px -20px rgba(15,23,42,.35),0 2px 6px -3px rgba(15,23,42,.08);
}
.qa-body{flex:1 1 auto;min-width:0;display:flex;flex-direction:column}
/* 卡片顶部一行：产品 / 分类徽章。
   第三版把徽章从**页脚提到题干上方** —— 先交代「这条属于谁」，再读问题，
   比先读问题、再回头找归属顺；页脚因此只剩标签与展开按钮，也轻了。 */
.qa-tops{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-bottom:11px}
/* 三项（置顶 / 产品 / 分类）都没有的条目：整行收起，
   否则题干上方会留一道 11px 的空白。旧数据里的 prod 名不在名单内也不会为空，
   所以这条主要是给「后台还没填分类」的条目兜底 */
.qa-tops:empty{display:none}
.qa-mp{
  padding:4px 10px;border-radius:8px;font-size:11.5px;font-weight:800;letter-spacing:.2px;
  background:linear-gradient(135deg,rgba(37,99,235,.10),rgba(0,194,255,.10));
  color:var(--acc-d);border:1px solid var(--acc-line);
}
.qa-mc{
  padding:4px 10px;border-radius:8px;font-size:11.5px;font-weight:700;
  background:var(--solid-2);color:var(--txt-2);border:1px solid var(--line);
}
/* 置顶：改成暖色徽章，跟上面两枚冷色区分开 —— 第二版它是贴在问题行首的
   一小块蓝底，跟「所属产品」撞色，看不出是两种性质的信息 */
.qa-top{
  padding:4px 9px;border-radius:8px;font-style:normal;
  background:linear-gradient(135deg,#fff7ed,#ffedd5);color:#c2410c;border:1px solid #fed7aa;
  font-size:11px;font-weight:800;letter-spacing:.3px;
}
/* 问题：18px。第二版 16px 在双列窄卡里会「缩」下去，撑不起一行卡的头 */
.qa-q{
  font-size:18px;font-weight:800;letter-spacing:-.4px;line-height:1.45;
  color:var(--txt);word-break:break-word;
}
.qa-a{
  margin-top:11px;font-size:14px;line-height:1.85;color:var(--txt-2);
  word-break:break-word;
  /* 答案正文是**多段纯文本**（服务端存的就是带换行的字符串），
     必须保留换行，否则「全域爆量：… / 手机号定向：…」会挤成一坨。
     与全站 .card-text 同一套写法，那边也是 pre-wrap。 */
  white-space:pre-wrap;
}
/* 正文里的链接（答案常要报一个官方规则页地址）。带下划线 ——
   只给颜色的话，一串蓝字母和正文里的强调分不开。
   break-all 是因为这类地址很长，双列窄卡里不强制断行会顶破卡片。 */
.qa-link{color:var(--acc-d);text-decoration:underline;text-underline-offset:2px;word-break:break-all}
.qa-link:hover{color:var(--acc)}

/* ---------- 答案配图（图文支持，2026-09-23 加） ----------
   每张图包一个 button，点开进灯箱看原图。
   ★ 第四版起这一块**只在答案弹框里出现**（卡片上不放图，只留「N 张配图」记号）——
     理由见 .qa-item 上方与 client.js qaCard 上方那两段：图铺在卡片上，
     有图没图的卡片高度差一大截，双列永远对不齐。
   ★ 列数用 auto-fit + minmax，不写死 2 列：只配一张时自动占满整行，
     右半边不会剩一块空位；两张自然并排；三张以上换行。手机上一律单列。
   ★ 每张限高 340 并 contain —— 截图类配图（后台界面、接口证明）竖版居多，
     不封顶的话一张就能把弹框撑出去一大截。真要看清细节点开灯箱，
     那里有「原图 1:1」。 */
.qa-imgs{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:8px;margin-top:12px}
.qa-img{
  display:block;padding:0;border:1px solid var(--line);border-radius:12px;
  background:var(--solid-2);overflow:hidden;cursor:zoom-in;
  transition:border-color var(--dur-fast) ease,box-shadow var(--dur-fast) ease;
}
.qa-img:hover{border-color:var(--acc-ring);box-shadow:0 8px 20px -14px rgba(15,23,42,.4)}
.qa-img img{display:block;width:100%;height:auto;max-height:340px;object-fit:contain}
/* 页脚：一条虚线分隔 + 标签 / 「查看答案」。虚线而不是实线 ——
   它要说明「下面是元信息，不是正文」，但又不该像卡片边界那样抢眼。
   ★ margin-top:auto（卡片被 grid 撑成等高时用）：把这一行顶到卡片底部，
     同一行两张卡的虚线因此落在同一水平线上。 */
.qa-foot{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin-top:auto;padding-top:13px;border-top:1px dashed var(--line);
}
/* 页脚整块空了（既没标签、展开按钮也被摘掉）就连那条虚线一起收掉 ——
   CSS 这里兜一道、JS 的 qaTrimFoot() 摘一道，双保险 */
.qa-foot:empty{display:none}
.qa-ftags{display:flex;flex-wrap:wrap;gap:6px;min-width:0;flex:1 1 auto}
.qa-tag{
  padding:3px 9px;border-radius:7px;font-size:11.5px;font-weight:600;
  color:var(--txt-3);background:var(--solid-2);
}
/* 卡片右下角「N 张配图 · 查看答案 →」（第四版）。
   卡片上不放答案也不放图，但**必须留这两个记号**：
   「查看答案」说明整张卡可点（不然客户不知道点哪儿），
   「N 张配图」说明点开还有截图 —— 接口证明那两张是谈单的证据，藏起来就白配了。
   它跟着 .qa-ftags 一起 flex 1 1 auto 占位，margin-left:auto 把它顶到右边，
   标签多的条目标签会换行，不会跟它抢一行。 */
.qa-open{
  flex:0 0 auto;margin-left:auto;
  display:inline-flex;align-items:center;gap:5px;
  color:var(--acc-d);font-size:12.5px;font-weight:700;
  transition:color var(--dur-fast) ease;
}
.qa-open b{font-weight:800}
.qa-open svg{width:13px;height:13px;flex:0 0 auto;transition:transform var(--dur-fast) ease}
/* 悬停时箭头右移 3px：卡片本身就是热区，这枚箭头是「可以点进去」的暗示 */
.qa-item:hover .qa-open{color:var(--acc)}
.qa-item:hover .qa-open svg{transform:translateX(3px)}
.qa-open-img{
  display:inline-flex;align-items:center;gap:4px;font-style:normal;
  padding:3px 9px;border-radius:7px;margin-right:3px;
  font-size:11.5px;font-weight:700;color:var(--txt-3);background:var(--solid-2);
}
.qa-open-img svg{width:12px;height:12px}

/* ---------- 答案弹框（第四版，2026-09-23 晚） ----------
   卡片只出问题，完整答案 + 配图在这里展开。
   ★ z-index 340：压在留资弹窗（360）与灯箱（400）之下 ——
     弹框里点图会开灯箱，灯箱必须在上面；留资弹窗是转化动作，也得在它上面。
   ★ 框宽写死 720：答案一行约 45 字（比双列卡片还宽一点），
     长答案也不会变成一条从头拉到尾的窄面条。手机端改成贴底抽屉。 */
.qam{position:fixed;inset:0;z-index:340;display:flex;align-items:center;justify-content:center;padding:18px}
.qam[hidden]{display:none!important}
.qam-mask{position:absolute;inset:0;background:rgba(15,23,42,.55)}
.qam-box{
  position:relative;width:min(720px,100%);max-height:86vh;overflow:auto;
  background:var(--solid);border-radius:20px;padding:20px 22px 18px;
  box-shadow:var(--sh-3);animation:rise .24s cubic-bezier(.22,.9,.3,1);
}
.qam-head{display:flex;align-items:flex-start;gap:10px;margin-bottom:12px}
.qam-head .qa-tops{flex:1 1 auto;min-width:0;margin-bottom:0}
.qam-box .qa-q{font-size:19px;line-height:1.5}
/* 弹框里的答案顶上不留 11px（那是给卡片里「问题→答案」的间距用的），
   这里问题与答案之间已经有 .qam-head 的 12px + 字号差，再叠就散了 */
.qam-box .qa-a{margin-top:12px;font-size:14.5px}
.qam-box .qa-imgs{margin-top:14px}
.qam-box .qa-foot{margin-top:16px;padding-top:14px}
/* 弹框底部署操作条：只有「复制问答」一枚主按钮。
   整宽、收在内容下方，不抢答案的视觉重心；复制出去的是纯文本（见 buildQaCopy / buildAskCopy）。 */
.qam-acts{display:flex;justify-content:flex-end;margin-top:14px;padding-top:14px;border-top:1px dashed var(--line-2)}
.qam-copy{
  display:inline-flex;align-items:center;gap:6px;padding:9px 18px;
  background:linear-gradient(135deg,rgba(37,99,235,.12),rgba(0,194,255,.12));
  border:1px solid var(--acc-line);border-radius:999px;
  color:var(--acc-d);font-size:13.5px;font-weight:700;cursor:pointer;
  transition:background .15s,border-color .15s,transform .12s;
}
.qam-copy:hover{background:linear-gradient(135deg,rgba(37,99,235,.2),rgba(0,194,255,.2));border-color:var(--acc);transform:translateY(-1px)}
.qam-copy:active{transform:translateY(0)}
/* 手机端：改成贴底的抽屉 ——
   小屏上居中弹框四周留白会把正文挤成一条更窄的面条 */
@media (max-width:560px){
  .qam{align-items:flex-end;padding:0}
  .qam-box{
    width:100%;max-height:88vh;border-radius:20px 20px 0 0;
    padding:18px 17px calc(18px + env(safe-area-inset-bottom));
  }
  .qam-box .qa-q{font-size:17.5px}
  .qam-box .qa-a{font-size:14px}}

/* ⚠️ 2026-09-24：这里原有 .qa-cta —— 问答库页底「没找到答案？咨询顾问」那块留资入口。
   留资整条链路下线（弹窗 + POST /api/lead + 后台「留资线索」卡），这块连同它的
   三条规则、下面 @media(max-width:560px) 里那两条一起删除。
   看完问答还想问点别的，现在走工具带上的「提问」。 */

/* PC 档（与 --page 变宽的断点同步）才开双列。
   1024 起容器是 1200，减 28×2 内边距再减 16 栏距 → 每列约 564px。
   在 760 的平板档硬开双列会剩 ~350px 一列，比手机还窄，所以不给。 */
@media (min-width:1024px){
  .qa-list{grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
  .qa-hero{padding:64px 28px 52px}
  .qa-hero p{font-size:14px}}
/* 手机端：hero 的留白与圆角一起收，标签列也收窄 ——
   否则 34px 的标签列 + 46px 的内边距会把胶囊推到只剩两三个可见 */
@media (max-width:560px){
  .qa-hero{padding:42px 16px 36px;border-radius:22px}
  .qa-flabel{flex:0 0 32px;letter-spacing:1px}
  .qa-sbox{height:58px;padding:0 6px 0 18px;margin-top:24px}
  .qa-sbox input,.qa-sbox input[type=text]{font-size:15px}
  .qa-sgo{height:46px;padding:0 22px;font-size:14px;letter-spacing:1px}
  .qa-item{padding:18px 17px 16px}
  .qa-q{font-size:16.5px;letter-spacing:-.3px}}
/* （氛围底的手机收敛不在 560 这里 —— 手机 hero 的权威定义在 640 档，
   见下面 @media(max-width:640px) 那段，两处都写会互相覆盖。） */

/* ==================== 提问（2026-09-23 加，2026-09-24 两改）====================
   代理商在前台提问、运营在后台回答。
   2026-09-24 第二次改：提问**不再单独成块**。原先公共区是
   「官方问答列表 + 底下「大家都在问」（3 条 + 查看全部）」，两块并排；
   现在已回答的提问并进官方列表、按时间混排，靠一枚徽章区分，
   前台只剩「公共列表」与「我的提问」两个视图。
   所以提问在公共列表里用的是 .qa-item 那张卡（同圆角同手势）——
   同一份列表里出现两种卡片，会被当成两个拼起来的模块，而不是一份问答。
   .ask-item 那套卡片现在只服务「我的提问」（那里要摆状态徽章与待回答）。 */

/* 「提问」：贴在结果条右侧（2026-09-24 起与「我的提问」并排，见 .qa-bar-acts）。 */
.qa-askbtn{
  flex:0 0 auto;
  display:inline-flex;align-items:center;gap:6px;
  padding:7px 15px;border-radius:999px;
  background:var(--acc);border:1px solid var(--acc);
  color:var(--on-acc);font-size:13px;font-weight:700;cursor:pointer;
  box-shadow:0 8px 18px -12px rgba(37,99,235,.75);
  transition:background var(--dur-fast) ease,transform var(--dur-fast) ease;
}
.qa-askbtn::before{content:'＋';font-size:14px;font-weight:800;line-height:1}
.qa-askbtn:hover{background:var(--acc-d);transform:translateY(-1px)}
.qa-askbtn[hidden]{display:none}

/* 结果条右侧那两枚一起殆着的入口（2026-09-24 改）：
   margin-left:auto 挪到容器上，两个按钮各管各的间距，不必再互相让位。 */
.qa-bar-acts{display:flex;align-items:center;gap:8px;margin-left:auto;flex:0 0 auto}
/* 「我的提问」：私人入口，走进去才是自己的列表（见 index.html 的 #qaMine）。
   描边 + 红计数，跟右边实心蓝的「提问」拉开层次 ——
   两个都做成实心主按钮，看上去就成了「两个同样重要的事」，
   但其实一个是「我要问」，一个是「看看我问过的」。 */
.qa-mybtn{
  flex:0 0 auto;
  display:inline-flex;align-items:center;gap:7px;
  padding:6px 13px;border-radius:999px;
  background:var(--solid);border:1px solid var(--line-2);
  color:var(--txt-2);font-size:13px;font-weight:700;cursor:pointer;
  transition:border-color var(--dur-fast) ease,color var(--dur-fast) ease;
}
.qa-mybtn:hover{border-color:var(--acc-ring);color:var(--acc-d)}
.qa-mybtn[hidden]{display:none}
/* 计数：不是「未读几条」，是「我一共提了几条」。
   所以它常驻显示，但 0 时不出现（见 client.js 的 askRender）——
   空数字的红点过两天就会被自动忽略掉。 */
.qa-myn{
  min-width:18px;height:18px;padding:0 5px;border-radius:999px;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--danger);color:#fff;
  font-size:11px;font-weight:800;font-style:normal;font-variant-numeric:tabular-nums;
}
.qa-myn[hidden]{display:none!important}

/* ---- 公共列表里的「代理提问」徽章（2026-09-24 加） ----
   提问并入官方列表之后，区分只剩这一枚。
   选绿色：置顶是暖色、所属产品是蓝色、功能分类是灰色，
   四种徽章四种色，扫一眼就分得出「官方沉淀的」还是「同行问出来的」。
   摆在最前（见 qaCard）—— 徽章行说的是这一条的身份，来源比归属更该先看到。 */
.qa-ask{
  padding:4px 9px;border-radius:8px;font-style:normal;
  background:var(--ok-soft);color:var(--ok-t);border:1px solid var(--ok-line);
  font-size:11px;font-weight:800;letter-spacing:.3px;
}
/* 页脚那句「张代理 提问 · 3 天前回答」：只有提问条目有。
   官方条目不摆 —— 官方没有提问者，摆上去只能写「运营」或留空，两种都怪。 */
.qa-askby{
  flex:1 1 auto;min-width:0;
  font-size:12.5px;color:var(--txt-3);font-weight:600;
}

/* ---- 「我的提问」独立视图 ----
   .qa-wall 那三个类（wall / wall-sub / wall-list）现在只剩这一屏在用 ——
   公共区那块「大家都在问」连同它的 .qa-wall-head / .qa-hot-more 已在
   2026-09-24 一起删除（提问并进列表后没有落点了）。 */
.qa-wall{margin:26px 0 0}
.qa-wall[hidden]{display:none}
.qa-wall-sub{margin:0 0 14px;font-size:13px;color:var(--txt-3);line-height:1.7}
.qa-wall-list{display:grid;grid-template-columns:minmax(0,1fr);gap:14px;align-items:start}

/* ---- 我的提问：独立视图 ----
   抬头的一行「← 返回问答库」是这一屏唯一的出路：它不是二级 Tab，
   没有底栏，返回条藏起来人就会被困在自己的提问里。 */
.qa-mine{margin:4px 0 0}
.qa-mine-bar{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  margin-bottom:4px;
}
.qa-mine-back{
  flex:0 0 auto;
  padding:7px 13px;border-radius:999px;
  background:var(--solid);border:1px solid var(--line-2);
  color:var(--txt-2);font-size:13px;font-weight:700;cursor:pointer;
  transition:border-color var(--dur-fast) ease,color var(--dur-fast) ease;
}
.qa-mine-back:hover{border-color:var(--acc-ring);color:var(--acc-d)}
.qa-mine h2{
  display:flex;align-items:center;gap:9px;margin:0;
  font-size:17px;font-weight:800;letter-spacing:-.3px;color:var(--txt);
}
.qa-mine h2 i{
  display:inline-flex;align-items:center;justify-content:center;
  width:26px;height:26px;border-radius:9px;flex:0 0 auto;
  background:linear-gradient(135deg,rgba(37,99,235,.12),rgba(0,194,255,.12));
  color:var(--acc-d);border:1px solid var(--acc-line);
}
.qa-mine h2 svg{width:15px;height:15px}
/* 底下的「再提一个问题」不做整宽：整宽的主按钮在这一页看起来像
   「完成订单」那种收尾动作，但它只是开一扇表单。 */
.qa-mine-ask{margin-top:16px;padding:11px 22px}

.ask-item{
  display:flex;flex-direction:column;
  padding:18px 20px 16px;
  background:var(--surface);border:1px solid var(--line);
  border-radius:18px;box-shadow:var(--sh-1);cursor:pointer;
  transition:border-color var(--dur-fast) ease,box-shadow var(--dur-fast) ease,transform var(--dur-fast) ease;
}
.ask-item:focus-visible{outline:2px solid var(--acc);outline-offset:3px}
.ask-item:hover{
  border-color:var(--acc-ring);transform:translateY(-2px);
  box-shadow:0 12px 28px -20px rgba(15,23,42,.35),0 2px 6px -3px rgba(15,23,42,.08);
}
/* 待回答的给一道暖色左边框 —— 状态在卡片上就该看得见，
   否则「大家都在问」里混进一条没答案的，点开才发现白点 */
.ask-st{
  padding:4px 9px;border-radius:8px;font-style:normal;
  font-size:11px;font-weight:800;letter-spacing:.3px;
  background:var(--solid-2);color:var(--txt-3);border:1px solid var(--line);
}
.ask-st.wait{background:var(--warn-soft);color:var(--warn-t);border-color:var(--warn-line)}
.ask-st.done{background:linear-gradient(135deg,rgba(37,99,235,.10),rgba(0,194,255,.10));color:var(--acc-d);border-color:var(--acc-line)}
.ask-st.in{background:var(--ok-soft);color:var(--ok-t);border-color:var(--ok-line)}
.ask-q{
  font-size:16px;font-weight:800;letter-spacing:-.3px;line-height:1.5;
  color:var(--txt);word-break:break-word;
}
.ask-foot{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin-top:13px;padding-top:12px;border-top:1px dashed var(--line);
}
.ask-by{flex:1 1 auto;min-width:0;font-size:12.5px;color:var(--txt-3);font-weight:600}
.ask-foot b{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:5px;
  font-size:12.5px;font-weight:800;color:var(--acc-d);
}
/* ⚠️ 选择器是 .ask-foot svg 而不是 .ask-foot b svg —— 与 qaCard 一样，
   ICO.arr 拼在 </b> 后面，是 .ask-foot 的直接子元素，不吃 b 的选择器。
   漏了这条的话，无宽高的 svg 会按替换元素默认尺寸渲染（实测 522px 高），
   把整张卡撑到六百多像素。 */
.ask-foot svg{width:13px;height:13px;flex:0 0 auto}
@media (min-width:1024px){
  .qa-wall-list{grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}}
@media (max-width:560px){
  .qa-wall{margin-top:20px}
  /* 手机上一行放下「我的提问 + 提问」会挤到贴边，让容器换行自己排 */
  .qa-bar{flex-wrap:wrap;gap:8px}
  .qa-bar-acts{margin-left:0;width:100%}
  .qa-mybtn,.qa-askbtn{flex:1 1 auto;justify-content:center}
  .qa-mine-bar{gap:10px}
  .ask-item{padding:16px 16px 14px}
  .ask-q{font-size:15.5px}}

/* ---- 提问弹框里的「提问人 / 补充说明」与「还没回答」---- */
.qam-detail{margin-top:12px}
.qam-detail[hidden]{display:none}
.qam-by{display:block;font-size:12.5px;color:var(--txt-3);font-weight:600}
.qam-d{
  margin-top:8px;padding:11px 13px;border-radius:12px;
  background:var(--solid-2);border:1px solid var(--line);
  font-size:13.5px;line-height:1.8;color:var(--txt-2);white-space:pre-wrap;
}
.qam-wait{
  display:block;padding:14px 16px;border-radius:14px;
  background:var(--warn-soft);
  border:1px dashed var(--warn-line);
  font-size:13.5px;line-height:1.8;color:var(--warn-t);
}

/* ---- 提问表单（复用 .qam 那层壳）---- */
.qam-title{font-size:17px;font-weight:800;letter-spacing:-.3px}
.qam-sub{margin:-4px 0 16px;font-size:13px;color:var(--txt-3);line-height:1.7}
.qam-box-form{width:min(560px,100%)}
.ask-rows{margin-bottom:14px}
.ask-lb{
  display:flex;align-items:baseline;gap:8px;margin-bottom:7px;
  font-size:12.5px;font-weight:700;color:var(--txt-2);
}
.ask-lb em{font-style:normal;font-weight:600;font-size:11.5px;color:var(--txt-4)}
.ask-sel{
  width:100%;padding:10px 13px;border-radius:12px;
  border:1px solid var(--line-2);background:var(--solid);color:var(--txt);font-size:14px;
}
.ask-sel:focus{border-color:var(--acc);box-shadow:0 0 0 3.5px var(--acc-line);outline:none}
.ask-ta{width:100%;padding:11px 13px;border-radius:12px;resize:vertical;line-height:1.7}
.ask-ta:focus{border-color:var(--acc);box-shadow:0 0 0 3.5px var(--acc-line);outline:none}
/* 字数计数器常驻：写问题的人需要知道还剩多少，「还剩 20 字」比超了才提示有用 */
.ask-count{margin-top:5px;text-align:right;font-size:11.5px;color:var(--txt-4);font-variant-numeric:tabular-nums}
.ask-hint{min-height:17px;margin:2px 0 0;font-size:12.5px;font-weight:700;color:var(--danger);line-height:1.4}
.ask-acts{display:flex;gap:9px;margin-top:14px}
.ask-acts .btn{flex:1}
@media (min-width:1024px){
  .ask-acts .btn{flex:0 0 auto;min-width:104px}
  .ask-acts{justify-content:flex-end}}

.card-title{font-size:16px;font-weight:800;letter-spacing:-.2px;margin-top:10px;word-break:break-word}
.card-text{
  margin-top:7px;font-size:14px;line-height:1.76;color:var(--txt-2);
  white-space:pre-wrap;word-break:break-word;
}
.card-text.fold{display:-webkit-box;-webkit-line-clamp:5;-webkit-box-orient:vertical;overflow:hidden}
.more{
  margin-top:4px;border:0;background:transparent;padding:0;cursor:pointer;
  font-size:13px;font-weight:700;color:var(--acc);
}
.more:hover{text-decoration:underline}

.card-foot{
  display:flex;gap:8px;margin-top:14px;padding-top:13px;
  border-top:1px solid var(--line);
}
.card-foot .btn{flex:1;min-width:0;padding:9px 10px;font-size:13.5px}

/* 通栏单列的左媒体栏容器。
   手机 / 平板下 display:contents 让这层容器彻底隐形，子元素照旧顺序流动，
   所以截图、视频、长按提示的排版与改动前逐像素一致；到 PC 才变成真容器。 */
.card-media{display:contents}
/* 多图角标：「当前 / 总数」，点它开灯箱看大图。
   以前这里写的是 display:none（只在 PC 显示），理由是「手机上图片本来就全部铺开」——
   那说的是单列通栏那版。现在三端都只看得到一张，点击又被轮播占走了，
   这枚角标是手机上唯一能开大图的路，所以三端都要有。
   （放在基础层而不是 PC 断点里，就是为了让它同时覆盖手机。） */
.shot-more{
  display:flex;align-items:center;gap:4px;
  position:absolute;right:8px;bottom:8px;z-index:2;
  font-size:11.5px;font-weight:700;line-height:1;
  padding:5px 9px;border-radius:9px;
  background:rgba(15,23,42,.66);color:#fff;
  cursor:zoom-in;font-variant-numeric:tabular-nums;
  transition:background .15s ease;
}
.shot-more:hover{background:rgba(15,23,42,.86)}
.shot-more svg{width:11px;height:11px;flex:0 0 auto}

/* 卡内轮播的左右箭头（多图案例才有，见 client.js renderCases）。
   与灯箱那对 .lb-arrow 同一套写法：基础层 display:none，等 .card-media 在断点里
   变成真容器（撑起 3:2 的框）才放开 —— 这层它是 display:contents，
   自己没有盒子，absolute 会飘到别的定位祖先上去。
   常显不做 hover 才出：看图的人没有「悬停试试」的动机，藏起来等于没提示。 */
.shot-nav{
  position:absolute;top:50%;z-index:3;display:none;
  align-items:center;justify-content:center;
  width:30px;height:30px;padding:0;border:none;border-radius:50%;
  background:rgba(15,23,42,.52);color:#fff;cursor:pointer;
  box-shadow:0 3px 9px -6px rgba(15,23,42,.5);
  transform:translateY(-50%);
  transition:background .15s ease,transform .15s ease;
}
.shot-nav svg{width:15px;height:15px;display:block}
.shot-nav:hover{background:rgba(15,23,42,.86)}
.shot-nav:active{transform:translateY(-50%) scale(.9)}
.sn-prev{left:7px}
.sn-next{right:7px}

/* ---------------- 朋友圈配图 ---------------- */
.pics{display:grid;gap:6px;margin-top:12px}
.pics img{
  width:100%;aspect-ratio:1/1;object-fit:cover;
  border-radius:12px;background:var(--solid-2);
  cursor:zoom-in;display:block;
}
.pics.g1{grid-template-columns:1fr}
.pics.g1 img{aspect-ratio:auto;max-height:340px;object-fit:contain}
.pics.g2{grid-template-columns:repeat(2,1fr)}
.pics.g3{grid-template-columns:repeat(3,1fr)}

.p-video{margin-top:12px;border-radius:14px;overflow:hidden;background:#0b1524}
.p-video video{width:100%;max-height:60vh;display:block}
.vact{margin-top:9px;display:flex;align-items:center;gap:9px}
.vact .hint strong{color:var(--acc)}

/* ---------------- 案例数据 ---------------- */
.metrics{display:flex;gap:10px;margin-top:13px}
.metric{
  flex:1 1 0;min-width:0;
  background:var(--solid-2);
  border:1px solid var(--line);border-radius:var(--r-md);
  padding:11px 13px;
}
.metric i{display:block;font-style:normal;font-size:11.5px;font-weight:700;color:var(--txt-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.metric b{
  display:block;font-size:25px;font-weight:800;letter-spacing:-1px;line-height:1.22;
  font-variant-numeric:tabular-nums;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent;
}
.metric b em{font-style:normal;font-size:12px;font-weight:700;letter-spacing:0;margin-left:3px;-webkit-text-fill-color:var(--txt-2)}
.case .testi{margin-top:12px;padding:10px 12px;background:var(--solid-2);border:1px solid var(--line);border-left:3px solid var(--acc);border-radius:10px}
.case .testi .t-h{font-size:11.5px;font-weight:700;color:var(--txt-3);letter-spacing:.3px;margin-bottom:5px}
.case .testi .t-q{font-size:13px;line-height:1.66;color:var(--txt);white-space:pre-wrap;word-break:break-word}
.case .testi .t-by{font-size:11.5px;color:var(--txt-3);margin-top:6px}
.case .tactics{margin-top:12px}
.case .tactics .t-h{font-size:11.5px;font-weight:700;color:var(--txt-3);letter-spacing:.3px;margin-bottom:6px}
.case .tactics ul{margin:0;padding:0;list-style:none}
.case .tactics li{position:relative;padding-left:15px;font-size:13px;line-height:1.62;color:var(--txt);margin-bottom:5px;white-space:pre-wrap;word-break:break-word}
.case .tactics li:before{content:"";position:absolute;left:3px;top:8px;width:5px;height:5px;border-radius:50%;background:var(--acc)}

.shots{display:grid;gap:6px;margin-top:12px}
.shots img{
  width:100%;border-radius:12px;background:var(--solid-2);
  cursor:zoom-in;display:block;object-fit:contain;
}
.shots.n1{grid-template-columns:1fr}
.shots.n1 img{aspect-ratio:auto;max-height:420px}
.shots.n2{grid-template-columns:repeat(2,1fr)}
.shots.n2 img{aspect-ratio:9/16}
.shots.n3{grid-template-columns:repeat(3,1fr)}
.shots.n3 img{aspect-ratio:9/16}

/* ---------------- 物料卡 ---------------- */
.mat{
  position:relative;display:flex;flex-direction:column;overflow:hidden;
  background:var(--solid);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--sh-1);
  transition:box-shadow .24s ease,border-color .24s ease,transform .24s ease;
}
/* 细边做成"面板自己的背景"，只画顶部 3px。理由同工具卡 .tool::after：
   悬停提升合成层时外层圆角裁剪会失效，靠外层裁的细边会按方角涨出去 */
.mat::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  border-radius:calc(var(--r-lg) - 1px);
  background-image:var(--grad);
  background-size:100% 3px;background-repeat:no-repeat;
  opacity:0;transition:opacity .22s ease;
}
.mat:hover{transform:translateY(-2px);border-color:var(--line-3);box-shadow:var(--sh-2)}
.mat:hover::after{opacity:1}

/* ⚠️ 2026-09-29：物料卡把封面加回来了（16:9，跟工具库那次改的比例对齐 ——
   这两张卡本来就是同一套结构，一个 16:9 一个 16/10 并排会一眼看出不齐）。
   无图的物料仍走下面 .bare 那套格式占位块，不等于「又变成有图卡了」。 */
.mat-cover{
  position:relative;aspect-ratio:16/9;overflow:hidden;
  border-radius:calc(var(--r-lg) - 1px) calc(var(--r-lg) - 1px) 0 0;
  background:var(--solid-2);border-bottom:1px solid var(--line);
}
.mat-cover[data-pvopen]{cursor:pointer}
.mat-cover img{width:100%;height:100%;object-fit:cover;display:block;border-radius:inherit;transform:translateZ(0);will-change:transform;transition:transform .34s ease}
.mat:hover .mat-cover img{transform:translateZ(0) scale(1.035)}
.mat-cover.bare{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px}
.mat-cover.bare b{font-size:28px;font-weight:800;letter-spacing:-.6px;line-height:1}
.mat-cover.bare i{font-style:normal;font-size:11.5px;font-weight:600;opacity:.72}
.mat-cover.bare.k-pdf{background:linear-gradient(135deg,#fff2f0,#ffe4e0);color:#c0392b}
.mat-cover.bare.k-doc{background:linear-gradient(135deg,#eff5ff,#dde9ff);color:#1d4ed8}
.mat-cover.bare.k-xls{background:linear-gradient(135deg,#eafaf0,#d7f5e4);color:#0f7a4a}
.mat-cover.bare.k-ppt{background:linear-gradient(135deg,#fff4ea,#ffe5d1);color:#c2610c}
.mat-cover.bare.k-zip{background:linear-gradient(135deg,#f4f1ff,#e8e0ff);color:#6d4bd8}
.mat-cover.bare.k-misc{background:linear-gradient(135deg,#f2f6fc,#e4ecf8);color:#4a5b78}

.mat-body{padding:14px 16px 15px;display:flex;flex-direction:column;flex:1;min-width:0}
.mat-body .card-foot{margin-top:auto}
.mat-meta{
  flex:1;min-width:0;font-size:12px;font-weight:700;color:var(--txt-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
/* 下载按钮不参与等分，避免被压到文字溢出（胜过 .card-foot .btn 的 flex:1） */
.mat .mat-foot .btn{flex:0 0 auto;min-width:104px;white-space:nowrap}
/* 锁定态那枚「某某解锁」：宽度跟下载按钮一致，一排卡片才不会参差不齐 */
.mat.locked .mat-foot .btn{min-width:104px;color:var(--txt-3)}
.mat.locked .mat-cover img{filter:grayscale(.4);opacity:.9}

/* 封面上那两枚角标：右下角张数、左下角锁定。
   都压在半透明深底上而不是浅底 —— 预览图什么颜色都有，浅底会糊进去 */
.mat-cover .mc-count,.mat-cover .mc-lock,.pv-idx{
  position:absolute;z-index:2;display:inline-flex;align-items:center;gap:4px;
  height:20px;padding:0 8px;border-radius:999px;
  background:rgba(15,23,42,.62);color:#fff;
  font-size:11.5px;font-weight:700;letter-spacing:.2px;line-height:1;
}
.mat-cover .mc-count,.pv-idx{right:8px;bottom:8px}
.mat-cover .mc-lock{left:8px;bottom:8px}
.mat-cover .mc-lock svg,.pv-locktip svg{width:12px;height:12px;flex:0 0 auto}

/* ---------------- 物料预览层（2026-09-29 加） ----------------
   结构照灯箱（遮罩 + 盒子），但它必须与灯箱各关各的：灯箱会叠在它上面
   （在预览层里点图放大），一次 ESC 收两层是 bug 不是功能。 */
.matpv{position:fixed;inset:0;z-index:420;display:none;align-items:center;justify-content:center;padding:24px}
.matpv.show{display:flex}
.pv-mask{position:absolute;inset:0;background:rgba(15,23,42,.6)}
.pv-box{
  position:relative;z-index:1;display:flex;flex-direction:column;
  width:min(900px,100%);max-height:min(88vh,860px);overflow:hidden;
  background:var(--solid);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:0 24px 64px -20px rgba(15,23,42,.45);
}
.pv-head{display:flex;align-items:center;gap:12px;padding:14px 16px;border-bottom:1px solid var(--line)}
.pv-htxt{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}
.pv-htxt b{font-size:15px;font-weight:700;color:var(--txt);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pv-htxt > span{display:flex;align-items:center;gap:7px;font-size:12px;font-weight:600;color:var(--txt-3)}
.pv-cat{background:var(--grad-soft);color:var(--acc-d);border:1px solid var(--acc-line);
  padding:1px 8px;border-radius:7px;font-weight:700}
.pv-sep{width:3px;height:3px;border-radius:50%;background:var(--txt-3);opacity:.7}
/* 舞台：预览主体。它是滚动容器 —— PDF 内嵌、长截图、文本都靠它滚 */
.pv-stage{flex:1;min-height:200px;overflow:auto;display:flex;align-items:center;justify-content:center;
  padding:16px;background:var(--solid-2)}
.pv-desc{margin:0;padding:12px 16px 0;font-size:13px;line-height:1.75;color:var(--txt-2)}
.pv-desc:empty{display:none}
.pv-foot{display:flex;align-items:center;justify-content:flex-end;gap:12px;
  padding:14px 16px;border-top:1px solid var(--line)}
.pv-locktip{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;font-weight:700;color:var(--txt-3)}

.pv-media{margin:0;position:relative;display:flex;align-items:center;justify-content:center;max-width:100%}
.pv-media img{max-width:100%;max-height:56vh;display:block;border-radius:var(--r-md);
  cursor:zoom-in;box-shadow:var(--sh-2)}
.pv-media video{max-width:100%;max-height:56vh;display:block;border-radius:var(--r-md);background:#000}
.pv-hint{margin:12px 0 0;font-size:12px;color:var(--txt-3);text-align:center}
.pv-frame{width:100%;height:60vh;max-height:620px;border-radius:var(--r-md);overflow:hidden;
  background:#fff;border:1px solid var(--line)}
.pv-frame iframe{width:100%;height:100%;border:0;display:block}
.pv-text{width:100%;max-height:56vh;overflow:auto;text-align:left;background:var(--solid);
  border:1px solid var(--line);border-radius:var(--r-md);padding:14px 16px}
.pv-text pre{margin:0;font-size:12.5px;line-height:1.8;color:var(--txt);
  white-space:pre-wrap;word-break:break-word;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.pv-loading{font-size:13px;color:var(--txt-3)}
.pv-shotwrap{display:flex;flex-direction:column;align-items:center;gap:12px;width:100%}
.pv-thumbs{display:flex;gap:8px;flex-wrap:wrap;justify-content:center}
.pv-thumb{width:58px;height:58px;padding:0;border-radius:8px;overflow:hidden;cursor:pointer;
  border:2px solid transparent;background:var(--solid-2);transition:border-color .16s ease}
.pv-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.pv-thumb.on{border-color:var(--acc)}
/* 没有任何可渲染画面的那档（Office / 压缩包 / 设计稿且没传预览图）：
   至少让人一眼知道这是什么文件，别给一屏空白 */
.pv-bare{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;
  width:100%;min-height:220px;border-radius:var(--r-md)}
.pv-bare b{font-size:34px;font-weight:800;letter-spacing:-.8px;line-height:1}
.pv-bare i{font-style:normal;font-size:12.5px;font-weight:600;opacity:.75;text-align:center;padding:0 20px}
.pv-bare.k-pdf{background:linear-gradient(135deg,#fff2f0,#ffe4e0);color:#c0392b}
.pv-bare.k-doc{background:linear-gradient(135deg,#eff5ff,#dde9ff);color:#1d4ed8}
.pv-bare.k-xls{background:linear-gradient(135deg,#eafaf0,#d7f5e4);color:#0f7a4a}
.pv-bare.k-ppt{background:linear-gradient(135deg,#fff4ea,#ffe5d1);color:#c2610c}
.pv-bare.k-zip{background:linear-gradient(135deg,#f4f1ff,#e8e0ff);color:#6d4bd8}
.pv-bare.k-misc{background:linear-gradient(135deg,#f2f6fc,#e4ecf8);color:#4a5b78}

/* ---------------- 微信下载引导 ---------------- */
.wxdl{position:fixed;inset:0;z-index:420;display:none;align-items:center;justify-content:center;padding:20px}
.wxdl.show{display:flex}
.wxdl-mask{position:absolute;inset:0;background:rgba(15,23,42,.55)}
.wxdl-box{
  position:relative;z-index:1;width:min(360px,100%);
  background:var(--solid);border-radius:20px;padding:24px 22px 18px;text-align:center;
  box-shadow:var(--sh-3);animation:rise .22s ease;
}
.wxdl-ico{
  display:grid;place-items:center;width:46px;height:46px;margin:0 auto 14px;
  border-radius:15px;color:var(--on-acc);background:var(--grad);
}
.wxdl-box b{display:block;font-size:16px;font-weight:800;letter-spacing:-.2px}
.wxdl-box p{font-size:13px;color:var(--txt-2);line-height:1.75;margin:8px 0 0}
.wxdl-box p em{font-style:normal;font-weight:800;color:var(--acc);padding:0 3px}
.wxdl-file{
  margin-top:14px;padding:10px 12px;border-radius:12px;background:var(--solid-2);
  border:1px solid var(--line);font-size:12.5px;font-weight:700;color:var(--txt-2);
  word-break:break-all;line-height:1.6;
}
.wxdl-acts{display:flex;gap:9px;margin-top:16px}
.wxdl-acts .btn{flex:1}
@keyframes rise{from{opacity:0;transform:translateY(12px) scale(.97)}to{opacity:1;transform:none}}

/* ---------------- 空态 ---------------- */
.empty{
  text-align:center;color:var(--txt-3);font-size:14px;
  padding:56px 22px;line-height:1.9;
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);
}
.empty.soft{background:transparent;border:0;box-shadow:none;padding:34px 12px;font-size:13.5px}
.empty-icon{
  display:grid;place-items:center;width:62px;height:62px;margin:0 auto 16px;
  border-radius:20px;color:var(--acc);
  background:var(--grad-soft);border:1px solid var(--acc-line);
  box-shadow:var(--sh-1);
}
.empty b{display:block;color:var(--txt);font-size:15px;font-weight:800;margin-bottom:4px}

/* ---------------- 保存台 ---------------- */
.tray{position:fixed;inset:0;z-index:350;display:none}
.tray.show{display:block}
.tray-mask{position:absolute;inset:0;background:rgba(15,23,42,.55)}
.tray-box{
  position:absolute;left:0;right:0;bottom:0;max-height:90vh;
  display:flex;flex-direction:column;
  background:var(--solid);border-radius:22px 22px 0 0;
  padding:10px 16px calc(16px + env(safe-area-inset-bottom));
  box-shadow:var(--sh-3);animation:up .26s cubic-bezier(.22,.9,.3,1);
}
@keyframes up{from{transform:translateY(34px);opacity:.5}to{transform:translateY(0);opacity:1}}
.tray-grip{width:40px;height:4px;border-radius:99px;background:var(--line-2);margin:0 auto 10px}
.tray-head{display:flex;align-items:center;gap:10px}
.tray-ico{
  flex:0 0 auto;width:30px;height:30px;border-radius:10px;display:grid;place-items:center;
  background:var(--grad-soft);color:var(--acc);border:1px solid var(--acc-line);
}
.tray-head b{flex:1;min-width:0;font-size:15px;font-weight:800;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tray-head .prog{font-size:13px;font-weight:800;color:var(--acc);font-variant-numeric:tabular-nums}
.tray-bar{height:5px;border-radius:99px;background:var(--acc-soft);overflow:hidden;margin:12px 0}
.tray-bar i{display:block;height:100%;width:0;border-radius:99px;background:var(--grad);transition:width .3s cubic-bezier(.22,.9,.3,1)}
.tray-tip{font-size:12.5px;color:var(--txt-3);line-height:1.75;margin-bottom:12px}
.tray-list{flex:1;overflow:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:12px;padding:2px}
.ti{border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;background:var(--solid)}
.ti img{width:100%;aspect-ratio:1/1;object-fit:cover;background:var(--solid-2)}
.ti figcaption{display:flex;align-items:center;gap:6px;padding:8px 9px;border-top:1px solid var(--line)}
.ti .no{font-size:11.5px;color:var(--txt-4);font-weight:600}
.ti .tick{
  margin-left:auto;border:1px solid var(--line-2);background:var(--solid);color:var(--txt-2);
  border-radius:9px;padding:5px 10px;font-size:12px;font-weight:700;cursor:pointer;transition:.16s;
}
.ti .tick.done{background:var(--grad);color:var(--on-acc);border-color:transparent;box-shadow:none}
.tray-foot{display:flex;gap:8px;margin-top:14px}
.tray-foot .btn{flex:1}

/* ---------------- 灯箱 ---------------- */
.lightbox{position:fixed;inset:0;z-index:400;display:none;align-items:center;justify-content:center;padding:16px}
.lightbox.show{display:flex}
.lb-backdrop{position:absolute;inset:0;background:rgba(15,23,42,.6)}
/* 关键：给弹框一个「确定的」宽高。之前只有 max-*，弹框会跟着当前图
   的原始比例收缩，1 张竖图 / 1 张横图切换时整个框忽大忽小 —— 观感很差。
   现在宽高固定，图片一律在框内 contain 居中，切换图片框体纹丝不动。 */
.lb-box{
  position:relative;z-index:1;
  /* 框放大：后台截图里 12px 的界面文字，框小的时候缩到只剩 5px 根本看不清 */
  width:min(1180px,96vw);height:min(900px,94vh);
  display:flex;flex-direction:column;
  background:var(--solid);border-radius:18px;overflow:hidden;box-shadow:var(--sh-3);
}
.lb-head{display:flex;align-items:center;gap:10px;padding:11px 14px;border-bottom:1px solid var(--line);font-size:13px;font-weight:700;flex:0 0 auto}
.lb-head span:first-child{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lb-nav{display:flex;align-items:center;gap:2px;flex:0 0 auto}
.lb-count{font-size:12px;font-weight:800;color:var(--txt-3);min-width:36px;text-align:center;font-variant-numeric:tabular-nums}
/* 图片舞台：外面这层只负责给左右切换键定位，本身不参与尺寸计算 */
.lb-stagewrap{position:relative;flex:1 1 auto;min-height:0;display:flex}
.lb-stage{flex:1 1 auto;min-width:0;min-height:0;display:flex;flex-direction:column;background:var(--solid-2)}
.lb-imgwrap{flex:1 1 auto;min-height:0;display:flex;align-items:center;justify-content:center;padding:14px 58px}
.lb-stage img{
  width:auto;height:auto;max-width:100%;max-height:100%;
  display:block;border-radius:10px;
  box-shadow:0 18px 42px -24px rgba(15,23,42,.55);
}
/* 原图 1:1：解除「缩到框内」的限制，按截图的原始像素显示。
   后台截图里的按钮名、字段名都是 12px 左右的小字，缩放后必然糊，
   只有 1:1 才真正看得清。框内可拖动/滚动查看超出部分。 */
.lb-stage.zoom .lb-imgwrap{
  overflow:auto;align-items:flex-start;justify-content:flex-start;padding:0;
  cursor:grab;
}
.lb-stage.zoom .lb-imgwrap.drag{cursor:grabbing;user-select:none}
.lb-stage.zoom img{max-width:none;max-height:none;width:auto;height:auto;border-radius:0;box-shadow:none}
/* 底部条：左边放 1:1 开关，右边是保存/翻页提示 */
.lb-tip{
  flex:0 0 auto;display:flex;align-items:center;justify-content:center;gap:10px;
  padding:7px 12px;font-size:12px;color:var(--txt-2);background:var(--solid);
  border-top:1px solid var(--line);text-align:center;
}
.lb-zoombtn{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:5px;
  font:inherit;font-size:12px;font-weight:800;color:var(--acc-d);
  background:var(--acc-soft);border:1px solid var(--acc-line);border-radius:999px;
  padding:4px 11px;cursor:pointer;transition:background .16s var(--ease);
}
.lb-zoombtn:hover{background:var(--acc-line)}
.lb-zoombtn.on{background:var(--acc);border-color:var(--acc);color:var(--on-acc)}
.lb-zoombtn svg{width:12px;height:12px}
.lb-hint{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 左右悬浮切换键：多图时才出现（.lb-box.multi） */
.lb-arrow{
  position:absolute;top:50%;z-index:3;display:none;
  align-items:center;justify-content:center;
  width:46px;height:46px;padding:0;border:none;border-radius:50%;
  font-size:24px;line-height:1;font-weight:700;color:#fff;
  background:rgba(15,23,42,.62);
  box-shadow:0 4px 12px -8px rgba(15,23,42,.45);
  cursor:pointer;transform:translateY(-50%);
  transition:background .16s ease,transform .16s ease;
}
.lb-box.multi .lb-arrow{display:flex}
.lb-arrow:hover{background:var(--acc);transform:translateY(-50%) scale(1.08)}
.lb-arrow:active{transform:translateY(-50%) scale(.94)}
.lb-prev{left:16px}
.lb-next{right:16px}

/* ---------------- Toast ---------------- */
.toast{
  position:fixed;left:50%;bottom:calc(var(--tabh) + 22px + var(--safe-b));
  transform:translateX(-50%) translateY(14px);
  /* 必须高过工具层（.toolview 是 520）：否则在工具页里点分享，
     提示会被工具层整块盖住，看起来像点了没反应 */
  z-index:600;max-width:86vw;text-align:center;
  background:rgba(15,23,42,.96);color:#fff;
  padding:12px 22px;border-radius:14px;font-size:13.5px;font-weight:600;
  opacity:0;pointer-events:none;transition:opacity .22s ease,transform .22s ease;
  box-shadow:0 6px 18px -10px rgba(15,23,42,.45);
}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

/* ============================================================
   后台专用
   ============================================================ */
.login-wrap{min-height:100vh;display:grid;place-items:center;padding:20px;position:relative;z-index:1}
.login-box{
  width:min(400px,100%);text-align:center;
  background:var(--solid);
  border:1px solid var(--line);border-radius:var(--r-xl);
  padding:32px 28px;box-shadow:var(--sh-3);
}
.login-mark{
  display:grid;place-items:center;width:56px;height:56px;margin:0 auto 18px;
  border-radius:18px;color:var(--on-acc);background:var(--grad);box-shadow:var(--sh-brand);
}
.login-box h1{font-size:22px;letter-spacing:-.4px}
.login-box p{font-size:13px;color:var(--txt-3);margin:6px 0 22px}
.login-box .field{margin-bottom:14px;text-align:left}
.login-foot{margin-top:16px;font-size:12.5px}

.stat-row{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:16px}
.stat{
  background:var(--solid);border:1px solid var(--line);border-radius:var(--r-md);
  padding:14px 12px;text-align:center;box-shadow:var(--sh-1);
}
.stat b{
  display:block;font-size:22px;font-weight:800;letter-spacing:-.8px;line-height:1.2;
  font-variant-numeric:tabular-nums;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent;
}
.stat span{display:block;font-size:11.5px;font-weight:600;color:var(--txt-3);margin-top:3px;white-space:nowrap}

.card{padding:18px}
.card-h{display:flex;align-items:center;gap:9px;font-weight:800;font-size:15px;margin-bottom:16px;letter-spacing:-.2px}
.card-h .bullet{width:8px;height:8px;border-radius:50%;background:var(--grad);flex:0 0 auto}
.card-h em{font-style:normal}
.card-h-note{margin-left:auto;font-size:11.5px;font-weight:600;color:var(--txt-4)}

.field{margin-bottom:14px}
.field label{display:flex;align-items:baseline;gap:8px;font-size:12.5px;font-weight:700;color:var(--txt-2);margin-bottom:7px}
.field label em{font-style:normal;font-weight:600;font-size:11.5px;color:var(--txt-4)}
input[type=text],input[type=password],input[type=number],textarea,select{
  width:100%;padding:11px 13px;border-radius:12px;
  border:1px solid var(--line-2);background:var(--solid);color:var(--txt);
  outline:none;font-size:14px;transition:border-color .16s ease,box-shadow .16s ease;
}
input:focus,textarea:focus,select:focus{border-color:var(--acc);box-shadow:0 0 0 3.5px var(--acc-line)}
textarea{resize:vertical;line-height:1.75;min-height:96px}
select{cursor:pointer;appearance:none;background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%237b8dad' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 12px center;padding-right:34px}
input[type=file]{width:100%;padding:9px;border-radius:12px;border:1px solid var(--line-2);background:var(--solid);font-size:13px;cursor:pointer}
input[type=file]::file-selector-button{
  border:0;border-radius:9px;padding:7px 12px;margin-right:10px;cursor:pointer;
  font-weight:700;background:var(--acc-soft);color:var(--acc);
}
.hint{font-size:12px;color:var(--txt-3);line-height:1.75;margin-top:5px}
.hint b{color:var(--txt-2)}
.unit{flex:0 0 auto;font-size:12.5px;font-weight:700;color:var(--txt-3)}

.cols{display:grid;grid-template-columns:1fr;gap:0 14px}
.hstack{display:flex;align-items:center;gap:10px}
.hstack > input{min-width:0}

.form-foot{display:flex;flex-wrap:wrap;gap:10px;margin-top:6px;padding-top:16px;border-top:1px solid var(--line)}
.form-foot .btn:last-child{margin-left:auto}

.drop{
  border:1.5px dashed var(--line-3);border-radius:var(--r-md);
  padding:20px 14px;text-align:center;background:var(--solid-2);cursor:pointer;
  transition:border-color .16s ease,background .16s ease,transform .16s ease;
}
.drop:hover,.drop.over{border-color:var(--acc);background:var(--solid);transform:translateY(-1px)}
.drop .big{display:grid;place-items:center;width:42px;height:42px;margin:0 auto 9px;border-radius:13px;
  font-size:20px;font-weight:700;color:var(--acc);background:var(--acc-soft);opacity:1}
.drop b{display:block;font-size:13.5px;font-weight:700}
.drop span:last-child{display:block;font-size:11.5px;color:var(--txt-4);margin-top:4px}

/* ---------- 朋友圈文案的表情面板（2026-09-28 加） ----------
   文案只有纯文字太素，这里给一组常用 emoji。面板是浮层（absolute），
   展开时不把下面的输入框推开 —— 在弹框里布局跳一下比什么都不给更烦。
   配色一律走变量，日夜两套皮肤自动跟上。 */
.emo-wrap{position:relative;margin-bottom:8px}
.emo-panel{
  position:absolute;z-index:30;top:calc(100% + 6px);left:0;width:min(340px,100%);
  display:none;padding:10px;border:1px solid var(--line);border-radius:12px;
  background:var(--solid);box-shadow:0 14px 32px -16px rgba(15,23,42,.5);
}
.emo-panel.on{display:block}
.emo-tabs{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:9px}
.emo-tab{
  padding:3px 9px;border:1px solid var(--line);border-radius:999px;
  background:transparent;color:var(--txt-3);font-size:12px;cursor:pointer;
  transition:color .14s,border-color .14s,background .14s;
}
.emo-tab:hover{color:var(--txt-2);border-color:var(--line-3)}
.emo-tab.on{border-color:var(--acc);color:var(--acc);background:var(--acc-soft)}
.emo-set{display:none;grid-template-columns:repeat(8,1fr);gap:4px}
.emo-set.on{display:grid}
.emo-cell{
  height:32px;border:0;border-radius:8px;background:transparent;
  font-size:19px;line-height:1;cursor:pointer;transition:background .12s,transform .12s;
}
.emo-cell:hover{background:var(--solid-2);transform:translateY(-1px)}
@media (max-width:520px){
  .emo-panel{width:100%}
  .emo-set{grid-template-columns:repeat(6,1fr)}
}

.thumbs{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:12px}
.thumbs.empty-list{display:none}
.th{position:relative;border:1px solid var(--line);border-radius:12px;overflow:hidden;background:var(--solid)}
.th img{width:100%;aspect-ratio:1/1;object-fit:cover}
.th .th-idx{
  position:absolute;left:6px;top:6px;font-size:11px;font-weight:800;
  padding:2px 7px;border-radius:7px;background:rgba(15,23,42,.62);color:#fff;
}
.th .th-bar{display:flex;border-top:1px solid var(--line)}
.th .th-bar button{flex:1;border:0;background:var(--solid);padding:7px 0;font-size:12px;color:var(--txt-2);cursor:pointer;transition:.14s}
.th .th-bar button:hover{background:var(--solid-2);color:var(--acc)}
.th .th-bar button.del:hover{background:rgba(238,75,75,.08);color:var(--danger)}
.th .th-bar button[disabled]{opacity:.35;cursor:not-allowed}
.th .th-bar button + button{border-left:1px solid var(--line)}
.vid-box{margin-top:12px}
.vid-box video{width:100%;border-radius:12px;background:#0b1524;max-height:240px;display:block}
.vid-box .btn{margin-top:9px}

/* ---------------- 后台：物料库 ---------------- */
.drop.compact{padding:14px 12px}
.drop.compact .big{width:34px;height:34px;font-size:17px;margin-bottom:7px}
.cover-box{
  margin-top:11px;border:1px solid var(--line);border-radius:var(--r-md);
  overflow:hidden;background:var(--solid);
}
/* ⚠️ 2026-09-29：选择器收紧成直接子元素。物料那一栏的封面已经从一个 <img>
   变成一组 .qai 缩略图（它们自带 96px 方形尺寸），不收窄的话这条 16:10
   会顺着后代选择器压到每一张缩略图上，跟 .qai img 的 height:100% 打架。
   其余库（福利 / 教程 / 交付）的封面仍是单张，照旧走这条。 */
.cover-box > img{width:100%;aspect-ratio:16/10;object-fit:cover;display:block;cursor:zoom-in}
.cover-box .btn{margin:10px}
/* 福利封面的预览框单独收到 16:9（2026-09-30），跟前台 .wel-cover 一致。
   上面那条 16:10 是福利 / 教程 / 交付三家共用的历史值 —— 这次只动了福利，
   教程与交付仍是 16:10，所以**不能**直接改那条公共规则，否则等于顺手改了另两库。
   这枚预览存在的唯一意义就是「所见即所得」：比前台矮一档，运营就没法从预览
   判断图被裁掉了多少。 */
#benCoverBox > img{aspect-ratio:16/9}
/* 问答表单的答案配图：一**组**缩略图（后台专用，2026-09-23 晚加）。
   与上面 .cover-box 的单张 16:10 不同 —— 这里一排好几张、长宽比又不定，
   所以统一裁成 96px 方块出缩略图（object-fit:cover），点开才看原始比例。
   移除键常显而不是 hover 才现：运营常常是在平板上传图，没有 hover 这一说。 */
.qa-imglist{display:flex;flex-wrap:wrap;gap:9px;margin-top:11px}
.qa-imglist:empty{margin-top:0}
.qai{position:relative;width:96px;height:96px;border-radius:11px;overflow:hidden;
  border:1px solid var(--line);background:var(--solid-2)}
.qai img{width:100%;height:100%;object-fit:cover;display:block;cursor:zoom-in}
.qai-x{
  position:absolute;top:4px;right:4px;width:20px;height:20px;
  display:grid;place-items:center;padding:0;border:none;border-radius:50%;
  background:rgba(15,23,42,.62);color:#fff;font-size:11px;line-height:1;
  cursor:pointer;opacity:.92;transition:background var(--dur-fast) ease;
}
.qai-x:hover{background:#dc2626;opacity:1}
/* 物料预览图（2026-09-29 加）。缩略图本身直接复用上面那套 .qai / .qai-x
   （同一种东西不必再画一遍），这里只多两样：
     · 容器 .shot-grid —— 间距与 .qa-imglist 一致，但不带 margin-top，
       因为它住在一个已经有内边距的 .cover-box 里；
     · 「主图」角标 —— 顺序决定卡片封面用哪张，而拖拽排序没做（要调顺序
       只能删了重传），不标出来运营根本看不出当前哪张排在最前。 */
.shot-grid{display:flex;flex-wrap:wrap;gap:9px}
.cover-box > .shot-grid{padding:11px}
.shot-grid:empty{display:none}
.shot-first{
  position:absolute;left:4px;bottom:4px;height:18px;padding:0 7px;
  display:inline-flex;align-items:center;border-radius:999px;
  background:var(--grad);color:var(--on-acc);
  font-size:11px;font-weight:800;letter-spacing:.2px;
}
/* 后台列表里的下载门槛 chip（物料行） */
.lv-chip{
  display:inline-block;margin-left:5px;padding:3px 8px;border-radius:8px;
  font-size:11.5px;font-weight:700;vertical-align:middle;
  background:var(--warn-soft);color:var(--warn-t);border:1px solid var(--warn-line);
}
/* 物料行缩略图右下角的张数角标 */
.lr-pics-n{
  position:absolute;right:-2px;bottom:-2px;height:17px;min-width:17px;padding:0 5px;
  display:inline-flex;align-items:center;justify-content:center;border-radius:999px;
  background:rgba(15,23,42,.72);color:#fff;font-size:11px;font-weight:700;line-height:1;
}
.file-chip{
  display:flex;align-items:center;gap:11px;margin-top:11px;padding:11px 12px;
  border:1px solid var(--line);border-radius:var(--r-md);background:var(--solid);
}
.fc-ext{
  flex:0 0 auto;display:grid;place-items:center;width:46px;height:46px;border-radius:11px;
  font-size:12px;font-weight:800;letter-spacing:-.2px;
  background:var(--grad-soft);color:var(--acc-d);border:1px solid var(--acc-line);
}
.fc-main{flex:1;min-width:0}
.fc-main b{display:block;font-size:13.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fc-main i{display:block;font-style:normal;font-size:11.5px;font-weight:600;color:var(--txt-4);margin-top:3px}
.file-chip .btn{flex:0 0 auto}
/* 已发布列表里没有展示图时的格式图标块（与缩略图同尺寸） */
.mat-ico{
  display:grid;place-items:center;width:48px;height:48px;border-radius:11px;
  font-size:12px;font-weight:800;letter-spacing:-.2px;flex:0 0 auto;
  background:var(--grad-soft);color:var(--acc-d);border:1px solid var(--acc-line);
}
/* 列表里「查看文件」：附件列里的一行文字链，不占额外高度 */
.file-link{
  display:inline-block;max-width:100%;vertical-align:baseline;
  font-size:11.5px;font-weight:700;color:var(--acc);text-decoration:none;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.file-link:hover{text-decoration:underline}

/* ---------------- 后台：已发布列表（表头 + 定宽列的数据表） ----------------
   之前每行是一张"卡片"：内容堆成一坨、四个按钮在下面独占一行，
   行与行之间靠间距隔开 —— 所以看着不像列表。
   现在是一条 .lt-head 表头 + 一批 .list-row 数据行，两者共用同一套栅格
   （列宽由 .lt-moments / .lt-cases / .lt-materials 上的 --ltc 变量决定），
   每一列都严格对齐；行高压到 64px 左右，一屏能看 8~10 条。
   手机端把表头收起、行改成纵向堆叠（见小屏媒体查询）。 */
.lt-head{
  display:grid;align-items:center;gap:0 14px;
  padding:11px 18px;background:var(--solid-2);
  border-bottom:1px solid var(--line);
  font-size:12.5px;font-weight:800;letter-spacing:.4px;color:var(--txt-3);
  white-space:nowrap;
}
.lt-head .ta-r{text-align:right}
.lt-head,.list-row{grid-template-columns:var(--ltc,minmax(0,1fr))}
/* 操作列一律用 max-content 由内容自己撑：
   置顶后按钮文案会从「置顶」变「取消置顶」，固定宽度装不下时
   .lr-acts 又是 nowrap，会向左溢出压住状态列的「置顶」徽标。 */
.lt-moments{--ltc:minmax(0,1fr) 116px 100px 88px max-content}
.lt-cases{--ltc:minmax(0,1fr) 132px 132px 88px max-content}
.lt-materials{--ltc:minmax(0,1fr) 116px 176px 88px max-content}
.list-row{
  display:grid;align-items:center;gap:0 14px;
  padding:12px 18px;background:var(--solid);
  border-bottom:1px solid var(--line);
  transition:background .14s ease;
}
.list-row:last-child{border-bottom:0}
.list-row:hover{background:var(--solid-2)}
.list-row.off{opacity:.5}

/* 第一列：缩略图 + 标题一行 + 摘要一行。超长一律省略号，悬浮 title 看全文。
   字号阶梯（与下面的数据列共同构成一套尺度）：
     标题 14.5/15.5 > 数据 13.5/14 > 摘要 12.5/13 > 次级 12/12.5
   原来标题 12px、数据 12.5px、次级 11px 都压在可读下限附近，
   跟 21~25px 的页面标题、13px 的筛选条比明显"小一号"，所以整体上提一档。 */
.lr-main{display:flex;align-items:center;gap:12px;min-width:0}
.lr-txt{flex:1;min-width:0}
.lr-t{display:flex;align-items:center;gap:7px;font-weight:800;font-size:14.5px;line-height:1.45}
.lr-t .nm{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lr-x{
  font-size:12.5px;font-weight:500;color:var(--txt-3);line-height:1.6;margin-top:3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.lr-x:empty{display:none}

/* 数据列（分类 / 素材 / 数据 / 附件） */
.lt-cell{min-width:0;font-size:13.5px;font-weight:700;color:var(--txt-2);line-height:1.5}
.lt-num{font-variant-numeric:tabular-nums}
.lt-sub{
  display:block;margin-top:3px;font-size:12px;font-weight:600;color:var(--txt-4);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.cat-chip{
  display:inline-block;max-width:100%;padding:4px 10px;border-radius:9px;
  font-size:12.5px;font-weight:700;line-height:1.45;vertical-align:middle;
  color:var(--acc-d);background:var(--grad-soft);border:1px solid var(--acc-line);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* 后台列表里的端口 chip：复用产品 chip 的底子，换上端口配色，便于区分 */
.cat-chip.port{color:var(--acc-d);background:var(--grad-soft);border-color:var(--acc-line)}
.cat-chip.port.agent{color:#c98a00;background:rgba(255,184,0,.16);border-color:rgba(255,184,0,.42)}

/* 状态列：置顶 / 隐藏 徽标；都没有时给一条占位横线，列不会塌 */
.lt-status{display:flex;align-items:center;gap:5px;flex-wrap:wrap;min-width:0}
.bdg{
  display:inline-flex;align-items:center;height:23px;padding:0 9px;border-radius:8px;
  font-size:12px;font-weight:800;letter-spacing:.2px;white-space:nowrap;
}
.bdg-top{background:var(--grad);color:var(--on-acc)}
.bdg-hide{background:rgba(24,64,150,.10);color:var(--txt-3)}
.bdg-none{font-size:13px;font-weight:700;color:var(--txt-4)}

/* 操作列：固定在最右一列，文字按钮一行排开。
   不用实心按钮 —— 一屏十几行的话满屏都是按钮，反而更乱。
   内边距按 7px 10px 给，让点击区高度落在 32px 左右（12 px 字号时的舒适下限）。 */
.lr-acts{display:flex;align-items:center;justify-content:flex-end;gap:4px;flex-wrap:nowrap}
.lr-acts .btn{
  padding:7px 10px;font-size:13px;border-radius:9px;
  border-color:transparent;background:transparent;color:var(--txt-2);box-shadow:none;
}
.lr-acts .btn:hover{
  transform:none;background:var(--acc-soft);
  color:var(--acc);border-color:transparent;box-shadow:none;
}
.lr-acts .btn.danger{color:var(--danger)}
.lr-acts .btn.danger:hover{background:rgba(238,75,75,.10);color:var(--danger);border-color:transparent}

/* 行内缩略图：最多露 3 张，多的折成 +N；点任意一张可翻看全部 */
/* position:relative 是给右下角那枚「N 张」角标定位用的（物料行，2026-09-29） */
.lr-pics{position:relative;display:flex;align-items:center;gap:6px;flex:0 0 auto}
.lr-pics img{
  width:48px;height:48px;object-fit:cover;border-radius:11px;
  border:1px solid var(--line);background:var(--solid-2);cursor:zoom-in;
  transition:border-color .16s ease,box-shadow .16s ease;
}
.lr-pics img:hover{border-color:var(--acc);box-shadow:0 4px 12px -8px var(--acc-glow)}
.lr-more{
  display:grid;place-items:center;width:48px;height:48px;border-radius:11px;
  font-size:12.5px;font-weight:800;color:var(--txt-3);font-variant-numeric:tabular-nums;
  background:var(--solid-2);border:1px solid var(--line);
}
/* 发布表单里的缩略图同样支持点击放大 */
.th img{cursor:zoom-in}
.cat-tags{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.cat-tag{
  display:inline-flex;align-items:center;gap:7px;padding:6px 11px;border-radius:10px;
  background:var(--grad-soft);color:var(--acc-d);font-size:12.5px;font-weight:700;
  border:1px solid var(--acc-line);
}
.cat-tag b{cursor:pointer;font-weight:800;opacity:.55;font-style:normal;transition:.14s}
.cat-tag b:hover{opacity:1;color:var(--danger)}

/* ---------------- 后台：工具条 / 筛选条 / 列表卡 ---------------- */
/* 页面默认就是列表：动作按钮全收在工具条右侧 */
.atoolbar{display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap;margin-bottom:16px}
.atb-l{min-width:0;flex:1 1 auto}
.atb-l h1{margin:0;font-size:21px;font-weight:800;letter-spacing:-.4px;line-height:1.25}
.atb-l h1 .gt{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.atb-l p{margin:5px 0 0;font-size:12.5px;color:var(--txt-3);font-weight:500}
.atb-r{display:flex;align-items:center;gap:10px;flex:0 0 auto}

/* 列表卡：内边距交给每一行自己，行分割线才能通到卡片边缘 */
.card.flush{padding:0;overflow:hidden}
.card.flush .card-h{padding:16px 18px;margin-bottom:0;border-bottom:1px solid var(--line)}
.card.flush .card-h .btn.tiny{margin-left:12px}
.card.flush .empty.soft{padding:44px 16px}

.afilters{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.afchip{
  display:inline-flex;align-items:center;gap:6px;
  border:1px solid var(--line-2);background:var(--solid);border-radius:10px;
  padding:7px 12px;font-size:12.5px;font-weight:700;color:var(--txt-2);
  cursor:pointer;font-family:inherit;transition:.16s;
}
.afchip:hover{color:var(--acc);border-color:var(--acc)}
.afchip.active{background:var(--grad);color:var(--on-acc);border-color:transparent;box-shadow:none}
.afchip.active:hover{color:#fff}
.afchip .n{font-variant-numeric:tabular-nums;opacity:.62;font-size:11.5px}
.afchip.active .n{opacity:.84}

.afsearch{
  display:flex;align-items:center;gap:8px;margin-left:auto;flex:0 1 280px;
  height:38px;padding:0 12px;background:var(--solid);
  border:1px solid var(--line-2);border-radius:11px;color:var(--txt-4);
  transition:border-color .16s ease,box-shadow .16s ease;
}
.afsearch:focus-within{border-color:var(--acc);box-shadow:0 0 0 3.5px var(--acc-line)}
.afsearch svg{flex:0 0 auto}
/* 必须显式覆盖全局 input[type=text]（同特异性时会被靠后的全局规则盖掉，
   结果就是"看着像两个搜索框叠在一起"）。这里提到 0,2,1 + 显式 :focus。 */
.afsearch input[type=text]{
  width:100%;min-width:0;border:0;background:transparent;
  padding:0;border-radius:0;font-size:13px;box-shadow:none;
}
.afsearch input[type=text]:focus{border:0;box-shadow:none}

/* ---------------- 后台：弹框 ---------------- */
.modal{position:fixed;inset:0;z-index:360;display:none;align-items:center;justify-content:center;padding:20px}
.modal.show{display:flex}
.modal-mask{
  position:absolute;inset:0;background:rgba(15,23,42,.5);
}
.modal-box{
  position:relative;z-index:1;display:flex;flex-direction:column;
  width:min(880px,94vw);max-height:min(820px,90vh);
  background:var(--solid);border-radius:24px;box-shadow:var(--sh-3);overflow:hidden;
  animation:mpop .24s cubic-bezier(.22,.9,.3,1);
}
.modal-box.small{width:min(520px,94vw)}
@keyframes mpop{
  from{opacity:0;transform:translateY(14px) scale(.98)}
  to{opacity:1;transform:none}
}
.modal-head{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid var(--line);flex:0 0 auto}
.modal-head .mi{
  display:grid;place-items:center;width:38px;height:38px;border-radius:12px;flex:0 0 auto;
  background:var(--grad);color:var(--on-acc);font-size:19px;font-weight:700;box-shadow:var(--sh-brand);
}
.mh-t{min-width:0;flex:1}
.mh-t b{display:block;font-size:16px;font-weight:800;letter-spacing:-.3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mh-t i{display:block;font-style:normal;font-size:12px;color:var(--txt-3);margin-top:2px;font-weight:500;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 内容区自己滚动，底部按钮常驻 */
.modal-body{flex:1 1 auto;min-height:0;overflow:auto;padding:18px 20px;overscroll-behavior:contain}
.modal-foot{
  display:flex;align-items:center;gap:10px;flex:0 0 auto;
  padding:13px 20px;border-top:1px solid var(--line);background:var(--solid-2);
}
.modal-foot .ft-note{margin-right:auto;font-size:12px;color:var(--txt-3);font-weight:600}
.modal-foot .btn.block{flex:1 1 auto}
.mpane{display:none}
.mpane.on{display:block}
.modal .field:last-child{margin-bottom:0}

/* 404 */
.grad{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}

/* ============================================================
   平板
   ============================================================ */
@media (min-width:700px){
  :root{--page:760px}
  .page{padding:20px 20px calc(var(--tabh) + 32px + var(--safe-b))}
  .grid{grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:16px}
  .cols{grid-template-columns:1fr 1fr}
  .stat-row{gap:12px}}

/* ============================================================
   PC / 桌面端 —— 独立设计，不是手机的放大版
   ============================================================ */
@media (min-width:1024px){
  :root{--page:1200px;--gap:18px;--barh:66px;--barpad:28px}

  /* --- 顶栏：单行，Tab 变胶囊，右侧搜索 --- */
  .appbar-in{flex-wrap:nowrap;height:var(--barh);padding:0 var(--barpad);gap:16px}
  .brand{font-size:16.5px}
  /* 品牌位在桌面只剩 logo 一张图（861×202），没有可以让位的文字 ——
     所以「不许被压窄」不是窄桌面专属的补丁，而是每个桌面档都要有的底线：
     logo 按 height:26 渲染，宽 = 26 × 4.262 ≈ 110.8，取 112 兜住它。

     ⚠️ 这条少了会出**假性压扁**：.brand-logo 是 <img>，会撞上本文件那条全局
     img{max-width:100%} —— 品牌块被 flex 压窄到多少，图片就跟着被缩到同宽，
     高度照旧 26、宽度被砍，比例从 4.262 掉到 2.x，看上去就是「logo 被压扁了」。
     给了下限，压力就只能去找 .appbar-end 里那两样会自己收窄的东西。 */
  .brand{min-width:112px}
  /* 桌面顶栏 66 高，logo 给到 26 —— 中文那截约 18px，在一屏里分量够；
     英文行约 3.3px，刚好还能读出是一行字而不是一道灰线。
     26 × 4.26 ≈ 111 宽。旁边没有别的文字可作参照了（「服务市场」已删），
     26 就是「那行英文还认得出来」的下限往上取的一档。 */
  .brand-logo{height:26px}
  .nav{
    order:0;flex:0 0 auto;margin:0 0 0 14px;padding:0;gap:4px;
    background:transparent;border:0;border-radius:0;
  }
  /* 桌面端把 Tab 交回顶栏，底部导航整条撤掉 */
  .client .nav{display:flex}
  .tabbar{display:none}
  .toast{bottom:32px}
  /* 胶囊的内边距与字号跟着视口走（1024 时收到最紧、1200 之后回到 20px / 14.5px）。
     Tab 是 flex:0 0 auto 不缩，窄桌面下横向溢出责任人是它 —— 改用流体区间，
     从 1024 到 1200 连续过渡，不出现「1199 好好的、1200 突然挤爆」的断崖。 */
  .tab{flex:0 0 auto;padding:9px clamp(11px,1.18vw,20px);font-size:clamp(13px,1.06vw,14.5px);border-radius:11px}
  .tab:hover{background:var(--acc-soft);color:var(--acc)}
  .tab.active{background:var(--grad);color:#fff;box-shadow:var(--sh-brand)}
  .tab.active:hover{color:#fff;background:var(--grad)}
  .tab.active i{background:#fff}
  /* 右侧这一组：宽档（1440 起）把压力落在**搜索框**上，时间戳不缩。
     顶栏挤的时候这一组是唯一还让得了位的（品牌块有 112 的下限、Tab 不肯缩），
     所以它必须真的缩得下去 —— 这就是下面那条 min-width:0 的用处。

     ⚠️ 它不能省，而且理由是反直觉的：
     .appbar-end 自己是个 flex 容器，而「更新于」那枚胶囊是 white-space:nowrap，
     于是胶囊的 min-content 就等于整段时间的宽度 —— 组的 min-content 因此等于
     组的 max-content。min-width:auto 拿这个当底线，整组就**永远不肯缩**，
     压力只好回头去顶品牌块与视口（第八个库那轮 1024 档顶栏内容冲到 1061、
     品牌块被压到十几像素，就是这一条惹的）。
     放开之后，组的底线改由**两个孩子自己的下限**决定，所以仍然推不出去：
       搜索框（min-width:128）+ 组内 gap 12 + 时间戳（min-width:72）＝ 212。
     （账在下面 1024~1149 那一段里逐档核过：整组能拿到的最小预算是 1024 档的
      241.1，仍然大于 212。）

     窄档（1024~1439）是镜像的，见下面那一段：那一档搜索框只剩 140~188，
     再缩就只剩个放大镜，于是改成它钉住不缩、时间戳承担全部压力。
     两边是同一条优先级 —— 能不能用 > 显示全不全，谁有富余谁让位；
     只是宽档的搜索框有富余，窄档的时间戳有富余。 */
  .appbar-end{order:0;gap:12px;min-width:0}
  .search{display:flex;flex:0 1 auto;min-width:128px;width:clamp(170px,17vw,320px)}
  .upd{font-size:12.5px;padding:7px 14px;flex:0 0 auto}

  /* --- 页面容器 --- */
  .page{padding:26px 28px 84px}

  /* --- Hero：左文案 / 右数据 --- */
  .hero{
    display:flex;align-items:center;justify-content:space-between;
    gap:32px;padding:24px 28px;margin-bottom:20px;
  }
  .hero h1{font-size:27px;margin-top:12px}
  .hero p{font-size:13.5px;margin-top:6px}
  .kpis{grid-template-columns:repeat(3,minmax(118px,1fr));gap:12px;margin-top:0;flex:0 0 auto}
  .kpi{padding:14px 16px;border-radius:var(--r-lg)}
  .kpi b{font-size:26px}
  .kpi span{font-size:11.5px}

  /* --- 筛选条：桌面也走一排，整页宽度还给了内容区 ----------------
     组与组之间用一道竖细线分开。这条线只在桌面出现 ——
     手机上一换行，属于上一行的竖线会孤零零挂着，反而更乱。 */
  .filterbar{padding:9px 13px;margin-bottom:14px}
  .fb-groups{gap:7px 0}
  .fg{padding:0 14px}
  .fg:first-child{padding-left:0}
  .fg + .fg{border-left:1px solid var(--line-2)}
  .fg-name{font-size:11.5px}
  .fg-btn{padding:6px 12px}
  /* 桌面端 .fg 带 14px 左右内边距，而浮层是相对它的内边距盒定位的 ——
     不补这 14px，浮层和小尖角就会整体偏左，对不齐触发器。 */
  .fg-pop{min-width:264px;left:14px}
  .fg-pop::before{left:5px}
  .fg-pop.right::before{left:auto;right:5px}

  .resultbar{font-size:13px}

  .grid{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:var(--gap)}
  /* 案例库：一排四张竖卡 —— 文字在上、截图落地在下，一屏正好落满一整排。
     朋友圈不用 wide（走上面的多列卡片网格），所以这条只影响案例库。
     窄屏降档（1024~1279 三列）与手机两列写在文件末尾「案例库竖卡」那一节。 */
  .grid.wide{grid-template-columns:repeat(4,minmax(0,1fr))}

  /* --- 卡片：更宽敞、更规整 --- */
  /* 案例库竖卡不再左右分栏（截图要通到卡片两侧），--media-w 这一档左栏宽度随之退役 */
  .post{padding:18px;border-radius:var(--r-lg)}
  .case{padding:0;border-radius:var(--r-lg)}
  .card-title{font-size:17px;margin-top:11px}
  .card-text{font-size:14.5px;line-height:1.8;margin-top:8px}
  .card-text.fold{-webkit-line-clamp:6}
  .card-foot{margin-top:16px;padding-top:15px;gap:9px;flex-wrap:wrap}
  /* 关键：不能用 flex:1 等分（basis 0 会把按钮压到放不下文字）。
     用 basis:auto + min-width:max-content，按钮先取自身内容宽，
     剩余空间再等分；真放不下时靠 wrap 折行，永不溢出。 */
  .card-foot .btn{flex:1 1 auto;min-width:max-content;padding:9px 10px;font-size:13px;gap:6px}
  .card-foot .btn svg{display:block;width:14px;height:14px}
  .pics{gap:8px;margin-top:14px}
  .pics.g1 img{max-height:380px}
  .metric{padding:13px 15px}
  .metric b{font-size:26px}
  .shots{gap:8px;margin-top:14px}
  .shots.n1 img{max-height:460px}

  /* --- 案例库竖卡内部：文字在上 / 截图居中 / 数据收尾 -----------------------------
     朋友圈走的是「多列卡片网格」（.grid.wide 只挂在案例库上，图片仍通栏铺开，
     没有这层结构），所以下面这些规则只对案例库生效 —— .card-body.split 只由 renderCases 生成。

     六个块：标签 1、标题 2、正文 3、**截图 4**、数据 5、按钮 6。
     这一版 order 与 DOM 顺序恰好重合（renderCases 生成的就是这个次序），但还是逐条显式写出来 ——
     块序是这张卡的设计意图，不该靠「DOM 碰巧如此」兜着；哪天真要再调，
     改这一处就够，不必动 client.js。手机端（见文件末尾那一节）用的是同一套 order。

     顺序为什么是「文 → 图 → 数据 → 按钮」：
     · 一排放四张时，先要读到「哪个行业、哪家店」，截图是佐证；
       图压顶的话四张海报并排会先把眼睛抢走，正文被挤成薄薄一层。
     · 四列卡只有 ~330 宽，图压顶要占掉 ~250 高，文字就没位置了 ——
       给它一条 3:2 的带（约 198 高）才拿得到正文三行。
     · 图下面紧跟数据：图说「这个案例长什么样」，数据说「它跑出了什么」——
       两者的因果要挨着读，中间夹正文就把话拆开了。
     · 按钮压在最后收尾：它管的是「拿这张卡去做事」（复制 / 保存 / 转发），
       先把图和两个数看完才落手，放数据下面正好接住视线。

     「不挤」靠四件事，缺一样又回到密密麻麻：
     ① 内边距 12 → 14；② 正文 12.5px 两行 → 13px 三行（且用 min-height 钉住三行高，
       同一排四张的截图带上沿才会对齐）；③ 「N 张截图」标签撤掉 ——
       右下角角标和「保存截图 · 3」已经把张数说了两遍；
     ④ 标签行与标题从 8px 拉到 14px，否则两行贴在一起像一句话。

     ⚠️ 媒体框的 display 必须是 block，不能是 flex：flex 子项在「高度 auto +
     内容全绝对定位」时 aspect-ratio 算不出来，媒体框会塌成 1px。
     这个坑做左右分栏时踩过一次，图压顶那版又踩了一次。 */
  .card-body.split{display:flex;flex-direction:column}
  .card-body.split > .card-media{
    order:4;
    /* margin-top:auto 把这一排剩下的高度全吸走：标题/正文长短不一的那张，
       多出的空白落在图的上方，于是同一排四张的截图带上沿永远齐平；
       图是定比（3:2）的，上沿一齐，数据条与按钮行（5、6）自然也跟着齐，
       最后一行的按钮就贴住了卡片下沿 —— 不必再给谁单独设高。 */
    margin:auto 0 0;position:relative;display:block;
    flex:0 0 auto;align-self:auto;
    width:100%;aspect-ratio:3/2;
    border:0;border-top:1px solid var(--line);
    /* 图不再给卡片收尾（下面还有数据条与按钮），下圆角撤掉 */
    border-radius:0;overflow:hidden;
    background:var(--solid-2);
  }
  .card-body.split > .card-top{order:1;padding:14px 14px 0;gap:5px}
  .card-body.split .tag{font-size:10.5px;padding:3px 8px}
  /* 张数不用再喊第三遍：+N 角标 +「保存截图 · 3」都在说同一件事 */
  .card-body.split .tag-media{display:none}
  /* 标签行 → 标题：8px 挤得两行像一句，拉开到 14px 才分得清「是哪一类」和「是哪一家」 */
  .card-body.split > .card-title{order:2;margin:14px 14px 0;font-size:15px}
  .card-body.split > .card-text{
    order:3;margin:5px 14px 0;font-size:13px;line-height:1.66;
    /* 三行的固定位置：短的那张留白，长的截断 —— 换来整排对齐 */
    min-height:calc(1.66em * 3);
    display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;
  }
  /* --- 数据条（成果块）------------------------------------------------------------
     这一块是整卡的落点：客户看完图，真正会抄走的就是这两组数。
     所以它不能是裸文字 —— 给底色、给边界、给一个大到不必寻找的字号。

     两栏等分，中间一条竖分隔线；标签在上（小、灰、字距放宽），
     数字在下（26px / 800 / 品牌渐变 / tabular-nums）。
     竖排而非「标签 数字」横排是有算过的：卡内宽 297，一栏 148，
     横排放不下「成功促活客户 + 1,204位」（要 ~152），竖排则两样各自独占一行，
     字号才有处分。手机档反过来（见文件末尾）—— 那里是整行横排。

     数字的渐变色来自基础层 .metric b（background:var(--grad) + background-clip:text），
     这里只动字号和字距，别写 color —— 一写就把渐变压成单色，
     不写背景又会因为 color:transparent 变成看不见。 */
  .card-body.split > .metrics{
    order:5;display:flex;margin:12px 14px 0;
    background:var(--solid-2);border:1px solid var(--line);
    border-radius:11px;overflow:hidden;
  }
  .card-body.split > .metrics .metric{
    flex:1 1 0;min-width:0;
    display:flex;flex-direction:column;gap:1px;
    padding:9px 12px 10px;
    /* 基础层那套「每格一块卡片」的底色与边框，在这里由整条提供，格子里不再各来一份 */
    background:none;border:0;border-radius:0;
  }
  .card-body.split > .metrics .metric + .metric{border-left:1px solid var(--line)}
  /* 标签压到 10.5px 让位，把字号全给数字：16.5 → 26px。
     数字一放大，一栏放不放得下就要盯住 —— 回归里 metricRows === 1 钉的就是这个。 */
  .card-body.split > .metrics .metric i{
    font-size:10.5px;font-weight:700;color:var(--txt-3);letter-spacing:.2px;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
  .card-body.split > .metrics .metric b{
    font-size:26px;letter-spacing:-1px;line-height:1.16;
    font-variant-numeric:tabular-nums;white-space:nowrap;
  }
  .card-body.split > .metrics .metric b em{font-size:13px;margin-left:4px}
  .card-body.split > .card-foot{order:8;margin:11px 0 0;padding:10px 14px 12px;gap:6px;flex-wrap:nowrap}
  .card-body.split > .testi{order:6;margin:12px 14px 0}
  .card-body.split > .tactics{order:7;margin:12px 14px 0}
  .card-body.split > .card-foot .btn{
    flex:0 1 auto;min-width:0;padding:7px 10px;font-size:12px;gap:4px;
    white-space:nowrap;overflow:hidden;
  }
  /* 卡宽只有 ~330，三个按钮带图标必然挤成两行 —— 让图标走，按钮文字一个不删 */
  .card-body.split > .card-foot .btn svg{display:none}

  /* 媒体框里所有截图都铺满并叠在一起，只有 .on 那张可见 ——
     切换只改一个 class，opacity 过渡就能给出「换了一张」的反馈。
     不用 display 切换：一是没有过渡可言，二是每次重渲染（筛选、切 Tab）
     首图都要重新淡入一次，整页像在闪。
     框 3:2、截图接近 1:1，所以 cover 才是「满」的；其余几张点右下角角标开灯箱看。 */
  .card-body.split > .card-media > .pics,
  .card-body.split > .card-media > .shots{
    position:absolute;inset:0;display:block;margin:0;height:auto;
  }
  .card-body.split > .card-media > .pics img,
  .card-body.split > .card-media > .shots img{
    display:block;position:absolute;inset:0;
    width:100%;height:100%;max-height:none;
    object-fit:cover;aspect-ratio:auto;border-radius:0;
    /* 指针事件全交给 .card-media 一层收（点图 = 轮播下一张，点角标 = 开灯箱）。
       图片自己不吃事件：几张图是叠在一起的，真让图接点击的话，
       接住的永远是 DOM 里最后那张，拿到的 data-shot 和眼睛看到的对不上。 */
    opacity:0;transition:opacity .22s ease;pointer-events:none;
  }
  .card-body.split > .card-media > .pics img.on,
  .card-body.split > .card-media > .shots img.on{opacity:1}
  /* 多图 → 整块图是「下一张」的点击区；单图 → 仍是「看大图」 */
  .card-body.split > .card-media[data-many]{cursor:pointer}
  /* 回到真容器了，左右箭头这才放出来（基础层为什么收着见那里） */
  .card-body.split > .card-media[data-many] > .shot-nav{display:flex}
  .card-body.split > .card-media:not([data-many]){cursor:zoom-in}
  .card-body.split > .card-media > .p-video{
    position:absolute;inset:0;margin:0;border-radius:0;background:transparent;
  }
  .card-body.split > .card-media > .p-video video{
    width:100%;height:100%;max-height:none;object-fit:cover;
  }
  .card-body.split > .card-media > .vact{margin:0;padding:0 10px 10px;flex-wrap:wrap}

  /* .shot-more 的样式已经整体挪到基础层（手机也要用这枚入口）。
     这里原来那份留在断点里反而更靠后，会把基础层的 cursor:zoom-in 覆盖成
     pointer-events:none，角标就点不动了 —— 所以删掉，不留重复定义。 */

  .mat-body{padding:16px 18px 17px}
  .mat-cover.bare b{font-size:32px}
  .mat .mat-foot .btn{min-width:118px;padding:10px 14px}

  /* --- 保存台：底部抽屉 → 居中浮层 --- */
  .tray-box{
    left:50%;right:auto;bottom:auto;top:50%;
    transform:translate(-50%,-50%);
    width:min(1000px,90vw);max-height:88vh;
    border-radius:24px;padding:22px 24px;
    animation:pop .22s cubic-bezier(.22,.9,.3,1);
  }
  .tray-grip{display:none}
  .tray-list{grid-template-columns:repeat(auto-fill,minmax(162px,1fr));gap:16px}
  .tray-foot{justify-content:flex-end}
  .tray-foot .btn{flex:0 0 auto;min-width:168px}

  /* --- 灯箱：PC 给更大的定框与更舒展的切换键 --- */
  .lb-box{width:min(1280px,94vw);height:min(940px,94vh)}
  .lb-imgwrap{padding:18px 68px}
  .lb-arrow{width:52px;height:52px;font-size:27px}
  .lb-prev{left:20px}
  .lb-next{right:20px}

  /* --- 后台 --- */
  .stat-row{gap:14px;margin-bottom:20px}
  .stat{padding:17px 14px;border-radius:var(--r-lg)}
  .stat b{font-size:26px}
  .stat span{font-size:12px}
  .card{padding:22px 24px}
  /* 列表卡：行自己做内边距，分割线才能通到卡片边缘 */
  .card.flush{padding:0}
  .card.flush .card-h{padding:18px 22px}
  .thumbs{grid-template-columns:repeat(4,1fr)}
  /* PC：整张表再上提一档。
     行高从 ~70px 放到 ~84px，缩略图 56px，字号与页面标题（25px）、
     筛选条（13px）、卡片头（15px）成比例 —— 之前 11.5~12.5px 的字
     在 1200px 宽的页面上显得"小一号"，字和图都不够撑住版面。 */
  .lt-head{padding:11px 22px;font-size:13px}
  .list-row{padding:14px 22px}
  .lr-t{font-size:15.5px}
  .lr-x{font-size:13px}
  .lt-cell{font-size:14px}
  .lt-sub{font-size:12.5px}
  .cat-chip{font-size:13px;padding:5px 11px}
  .bdg{height:24px;font-size:12.5px}
  .bdg-none{font-size:13.5px}
  .lr-acts .btn{padding:8px 12px;font-size:13.5px}
  .lr-pics img{width:56px;height:56px;border-radius:12px}
  .lr-more{width:56px;height:56px;border-radius:12px;font-size:13px}
  .mat-ico{width:56px;height:56px;border-radius:12px;font-size:13px}
  .atoolbar{margin-bottom:20px}
  .atb-l h1{font-size:25px}
  .afilters{gap:10px;margin-bottom:16px}
  .afchip{padding:8px 15px;font-size:13px}
  .card.flush .card-h{padding:18px 22px}
  .login-box{padding:38px 34px}}

@keyframes pop{
  from{opacity:0;transform:translate(-50%,-47%) scale(.975)}
  to{opacity:1;transform:translate(-50%,-50%) scale(1)}
}

/* 宽屏再多一点呼吸感 */
@media (min-width:1440px){
  :root{--page:1480px;--gap:20px;--barpad:32px}
  .page{padding:30px 32px 88px}
  .hero{padding:28px 34px}
  .hero h1{font-size:30px}
  .kpi b{font-size:29px}
  .grid{grid-template-columns:repeat(auto-fill,minmax(328px,1fr))}}

/* 超宽屏：内容居中不拉散 */
@media (min-width:1800px){
  :root{--page:1660px;--gap:24px}
  .grid{grid-template-columns:repeat(auto-fill,minmax(348px,1fr))}}

/* ============================================================
   窄桌面（1024 ~ 1439）：顶栏最挤的一段
   ------------------------------------------------------------
   这一档视口比版心（1200）只宽一点点，九枚 Tab 又是 flex:0 0 auto 不肯缩，
   所以横向最吃紧。导航始终保持单行（和 ≥1440 同一套），不另起第二行；
   只把压力交给右侧那一组：这一档**护住搜索框**（只剩 140~188，再缩就剩放大镜），
   反过来让它不缩、让「更新于」去挨刀。
   （≥1440 是镜像：那边搜索框有 244~320 富余，改成它缩、时间戳不缩。
   同一条优先级：能不能用 > 显示全不全，谁有富余谁让位。） */
@media (min-width:1024px) and (max-width:1439px){
  /* 1. 先舍次要文字：这一档能舍的只剩后台的「ADMIN」小标 */
  .brand-txt em{display:none}
  /* 所有桌面档同一套排布，这一块只管「搜索框 / 时间戳」谁缩谁不缩 */
  /* 4. 搜索框：这一档按视口给个更小的区间，并且钉住不再缩（理由见上面） */
  .search{flex:0 0 auto;width:clamp(140px,15vw,260px)}
  /* 5. 「更新于」那枚胶囊承担这一档的全部压力：允许收窄，但留 72px 下限
        （开头「更新于」三个字还在，看得出那是什么），时间被裁掉是有意的取舍 */
  .upd{
    flex:0 1 auto;min-width:72px;
    font-size:11.5px;padding:6px 10px;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }}

/* ============================================================
   窄桌面的最后一档（1024 ~ 1149）：八个库把顶栏顶出去了
   ------------------------------------------------------------
   第八个库（交付库）进来后，上面那块「窄桌面让位」不够用了 ——
   实测 1024 档顶栏内容冲到 1061，而视口只有 1024，溢出 37px。
   溢出的责任人是「更新于」那枚胶囊：它的右边缘落在 1061，
   而顶栏的右边界在 1014（= 视口 - 两边各 28 的内边距 - 10 的滚动条）。

   为什么不靠「让搜索框自己缩」来解（那本是这套顶栏的设计意图）：
   .search 的宽度是 clamp() 给定的确定值，Chrome 按「指定尺寸」算它的自动最小尺寸，
   于是父组被压窄时它并不跟着收缩，压力全落到 .upd 上，把 .upd 顶到了屏幕外。
   所以这一档必须显式给数，不能指望流式收缩。

   这一档能舍的按老规矩排（字号与文案一个字不动）：
     · 装饰那颗小圆点：整个 1024~1439 都舍掉了（上一个 @media 第 2 条，9 颗共 -99px）；
     · 搜索框：规定宽度的下限从 140 再降到 128（输入框还剩约 68px，能敲字）；
     · 胶囊的内边距：下限 11 → 9（1024 档实际落在 10.44）；
     · 胶囊里图标与文字的间距：7 → 5；胶囊之间的间距：4 → 3；
     · 导航左边距：14 → 10。
   一起算在 1024 档正好把溢出吐干净（数字都是实测，不是估的）：
     品牌块 112 + 两处 gap 32 + 左边距 10 + 胶囊排 562.9 +
     搜索框 153.6 + 组内 gap 12 + 状态胶囊 75.5 = 958 ≤ 958。

   注意「更新于」那枚胶囊在这一档会被压到下限附近（时间被裁掉）——
   这不是新问题，收档之前它在 1024 就已经只能显示到 84px 了。
   让它去挨这一刀是有意的：搜索框是能用/不能用的问题，时间戳是显示全不全的问题。

   上限取 1149：实测 1140~1149 这一小段即使按原规则也只剩 2~15px 余量，
   贴边太紧，一并收进来；1150 往上原规则就有 7px 以上余量、并且随视口线性变宽。
   代价是 1149 → 1150 有一步（每颗胶囊约 6px、搜索框约 40px）——
   只会在拖窗口时看到，定尺（1280 / 1440 / 1920）都不受影响。 */
@media (min-width:1024px) and (max-width:1149px){
  .search{width:clamp(128px,11.6vw,200px)}
  .tab{padding:9px clamp(9px,1.02vw,14px);gap:5px}
  .nav{gap:3px;margin-left:10px}}

/* ============================================================
   页面列封顶的那一段（1256 ~ 1439）：胶囊也不该再变胖
   ------------------------------------------------------------
   --page 在 1024~1439 这一段是钉死的 1200，所以视口过了 1256
   （1256 - 56 的内边距 = 1200）之后，「页面列」实际上就不再变宽了。
   但 Tab 胶囊的内边距与字号、搜索框的宽度都是按 vw 算的 ——
   视口继续变宽，它们继续长，长的全是溢出的部分：
   实测 1366 档顶栏内容已冒出页面列右缘 12px，1439 档冒 37px。
   七个库时代这一段还压得住，第八个库进来就压不住了。
   （观感上不是「字被切掉」，而是「顶栏右端比下面的卡片列多出一截」——
     因为 .appbar-in 是居中的，冒出去的那截落进了左右留白里。）


   做法：把这一段里那三个 vw 表达式换成「1256 档的定值」——
   胶囊内边距 14.8 / 字号 13.31 / 搜索框 188。
     · 左边界 1256 处：1.18vw = 14.82、1.06vw = 13.31、15vw = 188.25，
       与定值几乎相等，所以是连续接上的，不是断崖。
     · 右边界 1439 → 1440 本来就有一步：:root 的 --page 从 1200 跳到 1480、
       --barpad 从 28 跳到 32，整页版心本来就跳一次，胶囊随之变胖是同一次跳。
   1440 及以上不受影响，仍旧按 vw 长大（1920 档内边距正好到 20 的上限）。 */
@media (min-width:1256px) and (max-width:1439px){
  .tab{padding:9px 14.8px;font-size:13.31px}
  .search{width:188px}}

/* ============================================================
   小屏手机微调
   ============================================================ */
@media (max-width:640px){
  :root{--barpad:13px}
  .page{padding:13px 13px calc(var(--tabh) + 24px + var(--safe-b))}
  .appbar-in{padding:9px var(--barpad)}
  /* 品牌位在这一档的账（去掉「服务市场」四字之后实测）：
     品牌块就是 logo 本身 —— 390 上 102 宽，最窄的 320 档也还剩 43px 空隙，
     右侧那枚胶囊用不着被挤。下面两条只当兜底：
     .appbar-end 放开 min-width（否则里面的胶囊缩不下去）、
     .upd 给个下限并允许省略号。 */
  .upd{min-width:96px;overflow:hidden;text-overflow:ellipsis}
  .appbar-end{min-width:0}
  /* 后台的品牌名是「发布后台 + ADMIN」——这一档舍掉那枚拉丁小标，中文名留着 */
  .brand-txt em{display:none}
.hero{padding:22px 18px 18px;border-radius:18px;margin-bottom:13px}
.hero h1{font-size:22px;margin-top:9px}
.hero p{font-size:12px;margin-top:4px}
/* 氛围底的手机收敛：390 宽下 26px 内边距和 210px 签名都显得挤，
   内边距收一档、签名缩到 150 并再淡一点，点阵照旧（它本来就只露一角） */
.hero-sign{width:150px;height:150px;right:-20px;bottom:-26px;opacity:.13}
  .kpis{gap:6px;margin-top:12px}
  .kpi{padding:8px 10px;border-radius:11px}
  .kpi b{font-size:17px}
  .kpi span{font-size:10px}
  .resultbar{margin-bottom:10px}
  .post,.case{padding:15px}
  .card{padding:16px}
  .card-text.fold{-webkit-line-clamp:5}
  .metric{padding:10px 12px}
  .metric b{font-size:22px}
  .card-foot{flex-wrap:wrap}
  .card-foot .btn{flex:1 1 auto;min-width:92px}
  .mat-body{padding:13px 14px 14px}
  .mat-cover.bare b{font-size:24px}
  .mat .mat-foot{margin-top:13px;padding-top:12px}
  .mat .mat-foot .btn{min-width:88px;flex:0 0 auto}
  .mat-meta{font-size:11.5px}
  .stat-row{gap:8px}
  .stat{padding:11px 6px}
  .stat b{font-size:19px}
  .stat span{font-size:10.5px}
  .tray-list{grid-template-columns:repeat(2,1fr)}
  .form-foot .btn:last-child{margin-left:0}
  .thumbs{grid-template-columns:repeat(3,1fr)}
  /* 后台：工具条收成两行，按钮等分铺开 */
  .atoolbar{gap:12px;margin-bottom:13px}
  .atb-l h1{font-size:19px}
  .atb-l p{font-size:12px}
  .atb-r{width:100%;gap:8px}
  .atb-r .btn{flex:1 1 auto;min-width:0}
  .afilters{gap:7px;margin-bottom:11px}
  .afchip{padding:6px 10px;font-size:12px}
  .afsearch{flex:1 1 100%;margin-left:0;height:36px}
  .card.flush .card-h{padding:13px 14px;font-size:14px}
  .card.flush .card-h .btn.tiny{margin-left:8px}
  .card.flush .empty.soft{padding:34px 14px}
  /* 后台列表：手机端收起表头，行改成纵向堆叠 —— 内容一行、元信息一行、按钮一行 */
  .lt-head{display:none}
  .lt-moments .list-row,.lt-cases .list-row,.lt-materials .list-row,.lt-tools .list-row{
    display:flex;flex-wrap:wrap;gap:10px;padding:13px 14px;
  }
  .list-row .lr-main{flex:1 1 100%}
  /* 手机上没有 hover，title 提示点了也没用 —— 摘要放开到 2 行 */
  .list-row .lr-x{
    display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;
    white-space:normal;
  }
  .list-row .lt-cell{flex:1 1 auto}
  .list-row .lt-cell .lt-sub{display:inline;margin:0 0 0 6px}
  .list-row .lt-status{flex:0 0 auto}
  .list-row .lr-acts{
    flex:1 1 100%;justify-content:flex-start;flex-wrap:wrap;gap:6px;
    padding-top:10px;border-top:1px dashed var(--line-2);
  }
  /* 手机上要能点得准，文字按钮恢复成有边框的实体小按钮 */
  .list-row .lr-acts .btn{
    flex:1 1 auto;min-width:0;background:var(--solid);border-color:var(--line-2);color:var(--txt);
  }
  .list-row .lr-acts .btn.danger{color:var(--danger);border-color:rgba(238,75,75,.28)}
  .lr-pics img{width:48px;height:48px}
  .lr-more{width:48px;height:48px}
  .mat-ico{width:48px;height:48px;font-size:12px}
  /* 弹框在手机上从底部升起，接近全屏 */
  .modal{padding:0;align-items:flex-end}
  .modal-box{width:100%;max-width:100%;max-height:92vh;border-radius:22px 22px 0 0}
  .modal-head{padding:14px 15px}
  .modal-head .mi{width:34px;height:34px;font-size:17px;border-radius:11px}
  .modal-body{padding:15px}
  .modal-foot{flex-wrap:wrap;padding:12px 14px calc(12px + var(--safe-b))}
  .modal-foot .ft-note{flex:1 1 100%;margin:0 0 2px}
  .modal-foot .btn{flex:1 1 auto;min-width:0}
  /* 灯箱在小屏上让图片尽量占满，切换键收窄到贴边 */
  .lightbox{padding:10px}
  .lb-box{border-radius:16px}
  .lb-head{padding:10px 12px}
  .lb-imgwrap{padding:12px 56px}
  .lb-arrow{width:40px;height:40px;font-size:21px;background:rgba(15,23,42,.58)}
  .lb-prev{left:8px}
  .lb-next{right:8px}
  /* 物料预览层：小屏贴着底边弹上来（像一张抽屉），比居中浮窗好按得多 ——
     顶部留白全是浪费的，底部那排「下载」才是拇指够得着的地方 */
  .matpv{padding:0;align-items:flex-end}
  .pv-box{width:100%;max-height:92vh;border-radius:16px 16px 0 0;border-bottom:0}
  .pv-head{padding:12px 14px}
  .pv-stage{padding:12px;min-height:180px}
  .pv-media img,.pv-media video{max-height:42vh}
  .pv-frame{height:52vh}
  .pv-text{max-height:42vh}
  .pv-bare{min-height:180px}
  .pv-thumb{width:50px;height:50px}
  .pv-desc{padding:10px 14px 0}
  .pv-foot{padding:12px 14px calc(12px + var(--safe-b))}
  .pv-foot .btn{flex:1 1 auto}}

/* ------------------------------------------------------------
   这里原来还有一档「380 及以下把 logo 收小一号」（24 → 20 高，102 → 85 宽）。
   那时品牌块是「logo + 「服务市场」四个字」，360 上这两样加右侧「更新于」
   胶囊一共 336px，比可用宽度多 12px，只好缩 logo 补那个缺口。
   那四个字删掉之后品牌块只剩 logo 本身（102），跨档实测下来
   连最窄的 320 档都还空着 43px —— 缺口没了，这一档跟着撤掉。
   现在 logo 只有两档：基础 24 / ≥1024 抬到 26。
   （回归里有一条专门盯着它别再回来，所以上面这句刻意不写成选择器的样子。）
   ------------------------------------------------------------ */

/* ============================================================
   交互：仅真鼠标
   ============================================================ */
@media (hover:hover) and (min-width:1024px){
  .post,.case{transition:box-shadow .24s ease,border-color .24s ease,transform .24s ease}
  .post:hover,.case:hover{
    transform:translateY(-3px);
    box-shadow:var(--sh-2);
    border-color:var(--line-3);
  }
  .post:hover::after,.case:hover::after{opacity:1}
  .pics img,.shots img{transition:filter .22s ease}
  .pics img:hover,.shots img:hover{filter:brightness(1.04) saturate(1.05)}
  .ti{transition:box-shadow .2s ease}
  .ti:hover{box-shadow:var(--sh-1)}}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}

/* ============================================================
   工具库 · 卡片 / 弹窗 / 切图器
   ============================================================ */
/* 卡片结构照物料卡来：顶部 16:10 封面图 + 正文（标签行 / 标题 / 描述 / 底部小字 + 按钮）。
   工具头像图直接当封面用；没图时退化成一块带类型图形的封面占位。
   站内 / 站外统一品牌蓝，类型只靠「站内 / 站外」标签和封面占位文字区分。 */
/* PC 列数不在这里定 —— 交给 .grid 那条 auto-fill（minmax 300→328→348 逐档递增）。
   这里原来写着 `grid-template-columns:repeat(3,minmax(0,1fr))`，理由是「排 4 个每张只有
   200px 出头太挤」。那个数字是老容器时代的估算，早就对不上了：真正发生的是
   **宽屏上物料库排 4 张、工具库排 3 张** —— 1920 下物料卡 381px，工具卡 516px，
   同一站里两种卡差出三分之一，工具卡看着就"大一号"。
   物料库用的是 .grid 默认值（它没被任何 ID 覆盖），所以对齐的办法是把这条覆盖删掉，
   而不是给物料库也套一个 3 列。三条 feed 现在共用同一套列数规则：
   1024/1280/1366/1440 都是 3 列同宽，1920 都是 4 列同宽。
   下面那条 align-items:stretch 留着 —— 它是「同一行等高、底部按钮落在一条线上」，
   和列数无关，删了会让参差的描述把按钮顶得高低不齐。 */
#toolFeed{align-items:stretch}
.tool{
  position:relative;display:flex;flex-direction:column;overflow:hidden;
  background:var(--solid);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--sh-1);
  cursor:pointer;
  transition:box-shadow .24s ease,border-color .24s ease,transform .24s ease;
}
/* 悬停时顶部浮出一条品牌色细边，和物料卡一个手感。
   做法：铺满整卡的透明面板，用 background-size 只画顶部 3px。
   —— 悬停时卡片有 transform 会升为合成层，那一刻外层的圆角裁剪会失效，
      细边就会按方角横着涨出去（上两角先露直角）；
   —— 而把细边做成"面板自己的背景"就绕开了这件事：元素背景永远按自己的
      border-radius 裁剪，不走外层 clip，也就不会丢。
      面板必须是整卡高度，圆角才是真正的 20px 弧；直接给一条 3px 高的条子写
      20px 圆角，浏览器会按比例把它压成 1.5px，角上照样是方的。 */
.tool::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  border-radius:calc(var(--r-lg) - 1px);
  background-image:var(--grad);
  background-size:100% 3px;background-repeat:no-repeat;
  opacity:0;transition:opacity .22s ease;
}
.tool:hover{transform:translateY(-2px);box-shadow:var(--sh-2);border-color:var(--line-3)}
.tool:hover::after{opacity:1}

/* 封面：图片铺满整块 16:9 区域（cover，多出来的部分裁掉）。
   只有没传图的占位态才留内边距，放的图标不会贴边。
   顶部两角自己再声明一次圆角：悬停放大时图片会被提升为独立合成层，
   如果圆角只写在卡片外层，提升那一瞬间裁剪会丢，上两角先露直角再变圆。 */
.tool-cover{
  position:relative;aspect-ratio:16/9;overflow:hidden;
  border-radius:calc(var(--r-lg) - 1px) calc(var(--r-lg) - 1px) 0 0;
  display:flex;align-items:center;justify-content:center;
  background:var(--solid-2);
  border-bottom:1px solid var(--line);
}
.tool-cover img{
  width:100%;height:100%;object-fit:cover;object-position:center;display:block;
  /* 图片自己带封面那圈顶部圆角（border-radius:inherit 拿到 cover 的圆角），
     放大时就绝不会画到圆角外面去 —— 不靠外层裁剪，也就没有"裁剪丢失"这回事 */
  border-radius:inherit;
  /* 让图片从一开始就待在独立合成层里：悬停时不会"临时提升图层" */
  transform:translateZ(0);
  will-change:transform;
  transition:transform .34s ease;
}
.tool:hover .tool-cover img{transform:translateZ(0) scale(1.04)}
/* 没传封面图：白底圆角图标 + 类型文字，跟物料卡的「DOC / Word 文件」占位一个路数。
   图标用站内统一的描边 SVG，比 emoji 干净，也不会因系统字体显示成灰扑扑一片。 */
.tool-cover.bare{flex-direction:column;gap:9px;padding:16px;background:var(--solid-2)}
.tc-ico{
  width:58px;height:58px;border-radius:18px;background:var(--solid);color:var(--acc);
  display:grid;place-items:center;
  box-shadow:var(--sh-1);
}
.tc-ico svg{width:30px;height:30px}
.tool-cover.bare i{
  font-style:normal;font-size:11.5px;font-weight:700;letter-spacing:.2px;
  color:var(--txt-3);
}

.tool-body{padding:14px 16px 15px;display:flex;flex-direction:column;flex:1;min-width:0}
/* 描述最多 3 行：工具说明通常比物料长，全放开会把整行卡片顶得很高 */
.tool .card-text{
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;
}
/* 类型标签做成中性白底，和分类标签拉开层级（同物料卡的「N 次下载」） */
.tool-type{background:var(--solid);color:var(--txt-3);border-color:var(--line-2)}
/* 底部小字 + 按钮：小字占满剩余宽度，按钮不参与等分，永远不被压到文字溢出 */
.tool-foot{margin-top:auto}
.tool-meta{
  flex:1;min-width:0;font-size:12px;font-weight:700;color:var(--txt-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.tool .tool-foot .btn{flex:0 0 auto;min-width:104px;white-space:nowrap}

/* PC：一排 3 个工具（列数实际由 .grid 的 auto-fill 决定，见上面的说明）。
   窄窗口（<1024）走 .grid 单列。 */

/* ---------------- 切图器 ---------------- */
.slicer{display:flex;flex-direction:column;gap:16px}
.sl-drop{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  border:1.5px dashed var(--line-3);border-radius:var(--r-lg);padding:34px 20px;cursor:pointer;
  background:var(--solid-2);text-align:center;transition:.2s;
}
.sl-drop:hover{border-color:var(--acc);background:var(--grad-soft)}
.sl-drop.hidden{display:none}
.sl-drop-ico{font-size:34px}
.sl-drop b{font-size:15px;font-weight:800}
.sl-drop i{font-style:normal;font-size:12.5px;color:var(--txt-3)}
.sl-cfg{display:flex;flex-direction:column;gap:14px}
.seg{display:flex;gap:6px;background:var(--solid-2);border:1px solid var(--line);border-radius:12px;padding:4px}
.seg button{flex:1;border:0;background:transparent;padding:9px 6px;border-radius:9px;font-size:13px;font-weight:700;color:var(--txt-2);cursor:pointer;transition:.18s}
.seg button.active{background:var(--solid);color:var(--acc);box-shadow:var(--sh-1)}
.sl-grid2{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.sl-field{display:flex;flex-direction:column;gap:5px;font-size:12.5px;color:var(--txt-2);font-weight:600;text-align:left}
.sl-field input{
  border:1px solid var(--line-2);border-radius:10px;padding:9px 11px;font-size:15px;font-weight:700;
  background:var(--solid);color:var(--txt);width:100%;text-align:center;
}
.sl-field input:focus{outline:none;border-color:var(--acc);box-shadow:0 0 0 3px var(--acc-line)}
.sl-actions{display:flex;gap:10px}
.sl-actions .btn{flex:1;justify-content:center}
.sl-loading{text-align:center;color:var(--txt-3);font-size:13px;padding:6px 0}
.sl-preview{display:grid;grid-template-columns:repeat(var(--cols,3),1fr);gap:6px;background:var(--solid-2);border:1px solid var(--line);border-radius:var(--r-lg);padding:10px}
.sl-cell{position:relative;background:var(--solid);border-radius:8px;overflow:hidden;border:1px solid var(--line)}
/* 预览格子里的画布：加了 max-height 之后，长条片不再按容器宽度等比铺开 ——
   1180×2600 的一条按 900 宽铺就是 2000px 高，三行就把结果区撑到六千像素，
   想「打包下载」得先划过一整屏图。改成限高 320、宽度按原比例让出来：
   形状还是真实形状，格子矮下来了。精确尺寸靠左下角那行字，不靠目测。 */
.sl-cell canvas{display:block;width:auto;max-width:100%;max-height:320px;height:auto;margin:0 auto}
/* 每张的像素尺寸。切分线是自己摆的，光看缩略图看不出「这一刀落在 601 还是 620」 */
.sl-cap{
  position:absolute;left:5px;bottom:5px;padding:1px 6px;border-radius:6px;
  background:rgba(15,23,42,.62);color:#fff;font-size:11px;font-style:normal;font-weight:700;
  font-variant-numeric:tabular-nums;pointer-events:none;max-width:calc(100% - 42px);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.sl-cell-dl{
  position:absolute;right:5px;bottom:5px;width:26px;height:26px;border:0;border-radius:8px;
  background:rgba(15,23,42,.62);color:#fff;font-size:14px;line-height:1;cursor:pointer;opacity:0;transition:.18s;
}
.sl-cell:hover .sl-cell-dl{opacity:1}
.sl-cell-dl:hover{background:var(--acc)}

/* ---------------- 切图器的切割线编辑区 ----------------
   模型变了：上面那排模式只决定「切分线先摆在哪」，真正从哪儿切靠自己拖。
   原来那套「算好 cw/ch 直接均分」对九宫格够用，但长落地页一均分，
   十有八九从标题或按钮中间切开，切出来两条谁也接不上。 */
.sl-edit{display:flex;flex-direction:column;gap:9px}
/* 这一行的高度必须两种状态下完全一样 —— 见页面里那段注释：
   选中时凭空长出一行，会让外框在手指底下跳几个像素 */
.sl-edit-h{display:flex;align-items:center;gap:9px;flex-wrap:wrap;font-size:12.5px;color:var(--txt-3)}
.sl-edit-h b{font-size:13px;font-weight:800;color:var(--txt)}
.sl-edit-tip{min-width:0}
/* 「选中了哪条线 + 它的像素坐标」常驻一行：在设计稿里量好的 y 直接填进来最准 */
.sl-pick{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--txt-3);white-space:nowrap}
.sl-pick-n{font-weight:700;color:var(--txt-2);min-width:0;overflow:hidden;text-overflow:ellipsis}
.sl-pick input{
  flex:0 0 auto;width:76px;border:1px solid var(--line-2);border-radius:8px;padding:3px 7px;
  text-align:center;font-size:13px;font-weight:800;font-variant-numeric:tabular-nums;
  background:var(--solid);color:var(--txt);
}
.sl-pick input:focus{outline:none;border-color:var(--acc);box-shadow:0 0 0 3px var(--acc-line)}
.sl-pick input[disabled]{background:var(--solid-2);color:var(--txt-3);border-style:dashed}
.sl-pick em{font-style:normal}

/* 外框自己滚：长图（落地页那种）不能缩到一屏 —— 缩了之后「切在哪」全靠猜。
   scrollbar-gutter:stable 让滚动条的位置常驻预留：竖条出现/消失时 clientWidth
   不变，画布宽度就不会跟着跳（否则竖条一冒出来，画布就正好宽出十几像素，
   右边的把手会被推出可视区）。老 Safari 不认这条，JS 里还有一次兜底。
   overflow-x:hidden 是有意的：宽度由 JS 按可用宽度算好，横着本来不该出现滚动条 */
.sl-frame{
  position:relative;overflow-y:auto;overflow-x:hidden;scrollbar-gutter:stable;
  max-height:min(58vh,520px);
  border:1px solid var(--line-2);border-radius:var(--r-md);background:var(--solid-2);
}
.sl-frame:focus{outline:none;border-color:var(--acc);box-shadow:0 0 0 3px var(--acc-line)}
.sl-canvas{position:relative;display:block;min-width:200px}
/* 原图只是背景：拖拽和选中都交给上面那层线，所以图片自己不接指针 */
.sl-canvas img{display:block;width:100%;height:auto;pointer-events:none;-webkit-user-drag:none;user-select:none}

/* 切分线分两轴：横线是「满宽 0 高」的一条，竖线是「满高 0 宽」的一条。
   位置是百分比 —— 换窗口宽度时画布宽高都会变，百分比一个都不用重算 */
.sl-line{position:absolute;z-index:2}
.sl-line[data-axis="y"]{left:0;right:0;height:0}
.sl-line[data-axis="x"]{top:0;bottom:0;width:0}
/* 虚线里透出的是底下的图，所以补一圈白晕，压在任何底图上都看得见 */
.sl-line-bar{position:absolute;filter:drop-shadow(0 0 1.5px rgba(255,255,255,.95))}
.sl-line[data-axis="y"] .sl-line-bar{
  left:0;right:0;top:-1px;height:2px;
  background:repeating-linear-gradient(90deg,var(--acc) 0 7px,transparent 7px 13px);
}
.sl-line[data-axis="x"] .sl-line-bar{
  top:0;bottom:0;left:-1px;width:2px;
  background:repeating-linear-gradient(180deg,var(--acc) 0 7px,transparent 7px 13px);
}
/* 命中带：2px 的线太细抓不住。桌面端在图上任意位置按住那条线就能拖。
   touch-action:pan-y 让手机上竖着划仍然是滚外框 —— 要拖线就抓右边的把手 */
.sl-line-hit{position:absolute;touch-action:pan-y}
.sl-line[data-axis="y"] .sl-line-hit{left:0;right:0;top:-8px;height:16px;cursor:ns-resize}
.sl-line[data-axis="x"] .sl-line-hit{top:0;bottom:0;left:-8px;width:16px;cursor:ew-resize}
/* 选中/悬停时虚线变实线：一屏好几条线，得一眼看出正在动的是哪条 */
.sl-line:hover .sl-line-bar,.sl-line.sel .sl-line-bar{background:var(--acc)}
.sl-line.sel{z-index:4}
/* 把手：线上那个写着像素坐标的胶囊，也是手机上最顺手的抓点（touch-action:none）。
   横线的把手钉在线右端；竖线的把手钉在外框上沿（下面那层 sticky 壳），
   因为一条竖线有几千像素高，钉在自己身上滚两下就找不着了 */
.sl-handle{
  position:absolute;height:22px;padding:0 9px;border:0;border-radius:999px;background:var(--acc);color:var(--on-acc);
  font-size:11px;font-weight:800;line-height:22px;font-variant-numeric:tabular-nums;cursor:ns-resize;
  touch-action:none;white-space:nowrap;box-shadow:0 1px 2px rgba(15,23,42,.28);
}
.sl-line[data-axis="y"] .sl-handle{top:-11px;right:3px}
/* sticky 壳：0×0、定在外框上沿 8px 处，胶囊再相对它居中到线上 */
.sl-pin{position:sticky;top:8px;display:block;width:0;height:0}
.sl-line[data-axis="x"] .sl-handle{top:0;left:0;transform:translateX(-50%)}
.sl-line.sel .sl-handle{background:var(--acc-d)}

/* 每段多高多宽。每条线的坐标已经在把手上了，这里不重复列 */
.sl-segs{
  display:flex;flex-direction:column;gap:2px;font-size:12px;color:var(--txt-3);
  line-height:1.7;overflow-wrap:anywhere;font-variant-numeric:tabular-nums;
}
.sl-segs b{color:var(--txt-2);font-weight:800}
.sl-ops{display:flex;gap:8px;flex-wrap:wrap}

/* 小屏：切图工具页的行列输入收成两列 */
@media (max-width:760px){
  .sl-grid2{grid-template-columns:1fr 1fr}
  /* 外框再矮一点：手机上竖屏本来就短，编辑区吃满一屏就看不到下面的结果了 */
  .sl-frame{max-height:min(46vh,420px)}
  /* 手指点的东西不能是 22px。把手加高到 30，命中带也一起放宽 */
  .sl-handle{height:30px;line-height:30px;font-size:12px;padding:0 11px}
  .sl-line[data-axis="y"] .sl-handle{top:-15px}
  .sl-line[data-axis="y"] .sl-line-hit{top:-11px;height:22px}
  .sl-line[data-axis="x"] .sl-line-hit{left:-11px;width:22px}
  .sl-ops .btn{flex:1 1 calc(50% - 4px);justify-content:center}}

/* ---------------- 后台工具库列表 ---------------- */
/* 状态列放宽到能并排放下「显示中 + 置顶」两个徽标，行高才不会被撑开 */
/* 操作列同上：max-content，避免「取消置顶」把列撑破盖住「置顶」徽标 */
.lt-tools{--ltc:minmax(0,1fr) 116px 78px 114px max-content}
/* 工具头像在列表里统一成方形小图，没图时用大号 emoji 兜底 */
.lt-tools .mat-ico{font-size:22px;line-height:1}
.lt-tools .lr-pics img{border-radius:12px}
/* 状态徽标跟后台其它模块统一走蓝色系：显示中=浅蓝、隐藏=灰、置顶=实色渐变 */
.bdg-show{background:var(--acc-soft);color:var(--acc-d)}
/* 分享中：对外发出去的链接还开着，后面的数字是客户打开过几次 */
.bdg-share{background:var(--acc-line);color:#0b6f92}
/* 编辑弹框里的「前台显示」开关 */
.check-row{display:flex;align-items:center;gap:9px;cursor:pointer;font-size:14px;font-weight:600;color:var(--txt-2);user-select:none}
.check-row input{width:17px;height:17px;accent-color:var(--acc);cursor:pointer}

/* 后台：站外 / 站内 两个列表的分段切换 */
.tscopes{max-width:380px;margin-bottom:14px}
.tscopes button{display:flex;align-items:center;justify-content:center;gap:6px}
.tscopes .n{
  min-width:20px;padding:1px 6px;border-radius:20px;
  font-size:11.5px;font-weight:800;font-variant-numeric:tabular-nums;
  background:rgba(24,64,150,.10);color:var(--txt-3);
}
.tscopes button.active .n{background:var(--grad);color:var(--on-acc)}
.atb-tip{
  align-self:center;padding:7px 12px;border-radius:10px;white-space:nowrap;
  font-size:12.5px;font-weight:700;color:var(--txt-3);
  background:var(--solid-2);border:1px dashed var(--line-2);
}
/* 弹框里的只读类型提示（工具类型创建后不可改） */
.ttype{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.ttype-chip{
  display:inline-flex;align-items:center;height:28px;padding:0 12px;border-radius:9px;
  font-size:13px;font-weight:800;white-space:nowrap;
}
/* 类型标签：站内 / 站外 用同一套蓝色，只有文字不同 */
.ttype-chip.self{background:var(--grad-soft);color:var(--acc-d);border:1px solid var(--acc-line)}
.ttype-chip.link{background:var(--grad-soft);color:var(--acc-d);border:1px solid var(--acc-line)}
.ttype-x{font-size:12.5px;font-weight:600;color:var(--txt-3)}
/* 工具列表的说明文字偏长，压缩时省略号收尾，避免和右侧按钮贴在一起 */
.lt-tools .card-h-note{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* 小屏：这行说明跟页面副标题重复，且会把标题挤成两行，直接收起来 */
@media (max-width:640px){
  .lt-tools .card-h>span{white-space:nowrap}
  .lt-tools .card-h-note{display:none}}

/* ============================================================
   工具库 · 手机端适配
   （必须写在上面 .tool/.tool-* 基础规则之后，否则同权重会被基础样式盖回去）
   ============================================================ */
@media (max-width:640px){
  /* 卡片结构与物料卡一致，手机上只把留白收一收，按钮保持通栏好点按 */
  .tool-cover.bare{padding:14px}
  .tc-ico{width:50px;height:50px;border-radius:16px}
  .tc-ico svg{width:26px;height:26px}
  .tool-body{padding:13px 14px 14px}
  .tool .card-text{-webkit-line-clamp:4}
  /* 工具页：预览格子在窄屏上留白小一点，多给图一点空间 */
  .sl-preview{gap:5px;padding:8px}}

/* ============================================================
   站内工具视图（#toolView）
   在本站内打开工具：不新开标签、地址栏不变。
   顶栏本体一行不动（品牌 / 导航 / 搜索原位保留），客户全程看到同一条顶栏、
   同一排导航，感觉是本站换了一块内容，而不是弹出了一层新界面。
   站内工具没有第二行 —— 分享 / 返回这两枚按钮由门户注入到
   工具页自己的标题那一排里（.tp-acts），顶栏自始至终只有一行。
   只有外链工具才会多出第二行「工具名 + 返回」：那种页面不是我们的，
   按钮塞不进去，只能留在顶栏给一个返回口。
   顶栏高度按实际行数由 JS 打开时实测写进 --tv-top。
   ============================================================ */
/* 第二行：平时 display:none 不占位，只有外链工具（.tool-mode）才出现 */
.appbar-tool{
  display:none;
  border-top:1px solid var(--line);
  background:var(--solid-2);
}
.appbar.tool-mode .appbar-tool{display:block}
/* 内层与 .appbar-in 同宽同左右留白：左端跟品牌图标压同一条垂直基线，
   右端跟搜索框右缘对齐——上下两行的两端各自是一条线 */
.appbar-tool-in{
  max-width:var(--page);margin:0 auto;
  padding:8px var(--barpad) 10px;
  display:flex;align-items:center;gap:10px;
}

/* 工具图标：同品牌图标一样大，但从实心渐变块让开（软蓝底 + 描边），
   读起来是「当前打开的工具」，而不是第二个 logo */
.tt-ico{
  flex:0 0 auto;width:36px;height:36px;border-radius:12px;display:grid;place-items:center;
  color:var(--acc);background:var(--grad-soft);border:1px solid var(--acc-line);
}
.tt-ico svg{width:19px;height:19px;display:block}
.tt-name{
  flex:0 1 auto;min-width:0;font-size:16px;font-weight:800;letter-spacing:-.3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}

/* 第二行右侧那一组：外链工具这里只剩一枚返回键，右缘与上面搜索框右缘对齐 */
.tv-acts{flex:0 0 auto;margin-left:auto;display:flex;align-items:center;gap:8px}

/* 返回按钮：手机上是 36px 方按钮（跟品牌图标同高，省地方）；
   1024 以上展开成「← 返回」胶囊，高度 / 圆角 / 描边跟搜索框一致 */
.tv-back{
  flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:36px;padding:0;border-radius:12px;
  border:1px solid var(--line-2);background:var(--solid);color:var(--txt-2);
  font-size:13px;font-weight:700;cursor:pointer;
  transition:color .18s ease,border-color .18s ease,background .18s ease,box-shadow .18s ease,transform .12s ease;
}
.tv-back svg{width:17px;height:17px;display:block;flex:0 0 auto}
.tv-back-txt{display:none}
.tv-back:hover{color:var(--acc);border-color:var(--acc);background:var(--grad-soft)}
.tv-back:active{transform:translateY(1px)}
.tv-back:focus-visible{outline:none;border-color:var(--acc);box-shadow:0 0 0 3.5px var(--acc-line)}

/* 工具内容区：顶边接在顶栏下沿（顶栏那根底边线就当作分界线，不再叠一条） */
.toolview{
  position:fixed;left:0;right:0;bottom:0;
  top:var(--tv-top,var(--barh,66px));
  z-index:520;
  display:flex;flex-direction:column;
  background:var(--bg);
}
.toolview[hidden]{display:none!important}
.tv-body{flex:1;min-height:0;position:relative}
.tv-body iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block;background:var(--bg)}
/* 工具层打开时锁住底层页面滚动 */
body.tv-lock{overflow:hidden}

/* 工具页标题排里那两枚按钮（分享 / 返回）：门户注入进 iframe，
   而工具页引的是同一份样式表，所以规则写在这里两边都生效。
   分享成功后按钮自己变个绿底，免得只有一句一闪而过的提示看不清 */
.tp-acts .btn.done{background:#0fa863;border-color:transparent;color:#fff;filter:none;box-shadow:none}

/* PC：第二行的左右留白照样跟着 --barpad 走，尺寸按 PC 放大，跟第 1 行一个节奏。
   第 1 行原样不动，所以窄屏也不再有「更新时间章跟工具名抢位」的问题 */
@media (min-width:1024px){
  .appbar-tool-in{padding:9px var(--barpad) 14px;gap:12px}
  .tt-ico{width:40px;height:40px;border-radius:13px}
  .tt-ico svg{width:21px;height:21px}
  .tt-name{font-size:18px;letter-spacing:-.4px}
  .tv-back{width:auto;height:40px;padding:0 15px 0 12px;gap:7px;border-radius:12px}
  .tv-back svg{width:16px;height:16px}
  .tv-back-txt{display:inline}}

/* 底部导航在 1024 以下都在（PC 端才整条撤掉），所以这一段不能只写手机：
   平板宽度下工具区同样要让开它，底边顶到它的上边线（+1px 是它的 border-top） */
@media (max-width:1023px){
  .toolview{bottom:calc(var(--tabh) + var(--safe-b) + 1px)}}

/* ============================================================
   产品库 · 列表卡 / 详情页 / 预约留资
   ------------------------------------------------------------
   科技感的来源是「浅蓝纸面 + 网格 + 光环 + 产品徽标」，不再是深色块。
   （第一版封面和详情 Hero 用的是深靛 #042C53 大色块 + 白网格，在满站浅色
   里像贴了张工程蓝图，又暗又冷，被否掉了；现在整条线走浅色。）
   面上永远三层，从下往上：渐变底 → 细网格（径向/线性遮罩淡出）→ 光环。
   焦点是中央那枚「产品徽标」.pc-badge：白底圆角方块 + 身份色线框图标，
   卡片封面 / 详情头部 / 底部 CTA 三处共用同一枚，图形语言不会散。
   图形全部内联 SVG，网格和光环用 CSS 画，零图片请求：
   后台新增产品时就算一张图都不传，卡片也不会塌成一块灰。
   ============================================================ */

/* ---- 1. 产品卡：上图下文竖卡，和工具库同一套范式 ---- */
#prodFeed{align-items:stretch}
.prod{
  position:relative;display:flex;flex-direction:column;overflow:hidden;
  background:var(--solid);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--sh-1);cursor:pointer;
  transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
/* 悬停浮出顶部 3px 身份色细边：做法与工具卡一致（面板自身背景 + 整卡高度，
   这样圆角是真弧、不受外层裁剪丢失影响） */
.prod::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  border-radius:calc(var(--r-lg) - 1px);
  background-image:var(--grad);
  background-size:100% 3px;background-repeat:no-repeat;
  opacity:0;transition:opacity .22s ease;
}
.prod:hover::after{opacity:1}

/* 封面：16:10 浅蓝纸面。有配图就铺满（cover），没配图就走三层纸面 + 徽标 ——
   两种状态高度一致，同一行卡片不会一高一矮 */
.prod-cover{
  position:relative;aspect-ratio:16/10;overflow:hidden;
  border-radius:calc(var(--r-lg) - 1px) calc(var(--r-lg) - 1px) 0 0;
  display:grid;place-items:center;
  /* 第一层：渐变底。刻意比正文白卡深一档（#E3EEFC 起）—— 底太浅的话
     徽标那枚白方块浮在上面几乎没有对比，整张封面看着「洗过」。
     右上角一团白光把面点亮，左下再压一点蓝，斜向才有体积 */
  background:
    radial-gradient(112% 88% at 76% -10%,#fff 0%,rgba(255,255,255,0) 56%),
    linear-gradient(148deg,#E3EEFC 0%,#F5FAFF 48%,#D8E7FA 100%);
  border-bottom:1px solid var(--acc-line);
}
/* 第二层：32px 疏网格。中间清楚、四周淡出，只当纸面质感，不抢徽标。
   格距 28 → 32、透明度 .06 → .05：28px 那版在小卡上排出来像方格练习本，
   疏一格立刻从「练习本」回到「纸」 */
.prod-cover::before{
  content:'';position:absolute;inset:0;
  background-image:
    linear-gradient(to right,rgba(37,99,235,.05) 1px,transparent 1px),
    linear-gradient(to bottom,rgba(37,99,235,.05) 1px,transparent 1px);
  background-size:32px 32px;
  -webkit-mask-image:radial-gradient(circle at 50% 47%,#000 0%,rgba(0,0,0,.34) 46%,rgba(0,0,0,0) 78%);
  mask-image:radial-gradient(circle at 50% 47%,#000 0%,rgba(0,0,0,.34) 46%,rgba(0,0,0,0) 78%);
}
/* 第三层：徽标身后一团柔光 + 一道斜向光带。
   试过「硬线圆环」的三个尺寸（74% / 58% / 46%），问题不在大小 ——
   硬圆环本身就是图纸语言，越描越冷；换成柔光 + 光带，面立刻有体积、
   也不和徽标抢轮廓。徽标自己在 z-index:1 之上，光从它背后透出来 */
.prod-cover::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(52% 56% at 50% 50%,rgba(255,255,255,.95) 0%,rgba(255,255,255,0) 72%),
    linear-gradient(114deg,rgba(255,255,255,0) 28%,rgba(255,255,255,.60) 47%,rgba(255,255,255,0) 68%);
}
/* 有配图时，网格 / 光环 / 徽标全部让位给图片（.bare = 无图） */
.prod-cover:not(.bare)::before,
.prod-cover:not(.bare)::after{content:none}
.prod-cover img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;
  border-radius:inherit;transform:translateZ(0);will-change:transform;
  transition:transform .42s var(--ease);
}
.prod:hover .prod-cover img{transform:translateZ(0) scale(1.04)}

/* 产品徽标：白底圆角方块 + 身份色线框图形。圆角走 26%（≈ iPhone 图标的观感），
   一枚浅投影把方块从纸面上「抬」起来 —— 这是它比原来那根细线管用的地方：
   有实体、有焦点，缩到手机单列也不会糊成一条线 */
.pc-badge{
  position:relative;z-index:1;display:grid;place-items:center;
  width:26%;max-width:88px;aspect-ratio:1;border-radius:24%;
  background:linear-gradient(180deg,#fff 0%,#EAF3FE 100%);
  border:1px solid rgba(37,99,235,.22);
  /* 双层投影：近处一层吃掉边缘（白块才有厚度），远处一层做环境影。
     原来只给了一层 -11px 的大扩散，方块看着是「贴」在纸上的 */
  box-shadow:0 2px 4px -1px rgba(20,66,130,.13),
             0 12px 22px -10px rgba(20,66,130,.34),
             inset 0 1px 0 #fff;
  color:var(--acc);
}
/* 图形占方块的 74%：SVG 自己的 viewBox 留了 1/6 边距，再小一圈图标就"缩"在
   白方块里发虚，这是第一版最明显的问题 */
.pc-wire{width:74%;height:74%;display:block}

.prod-body{padding:14px 16px 15px;display:flex;flex-direction:column;flex:1;min-width:0}
.prod .card-text{
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  color:var(--txt-3);
}
.prod-tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.ptag{
  font-size:11.5px;font-weight:700;line-height:1.5;
  padding:2px 9px;border-radius:999px;white-space:nowrap;
  background:var(--acc-soft);color:var(--acc-d);border:1px solid var(--acc-line);
}
.prod-foot{margin-top:auto;padding-top:12px}
.prod-meta{flex:1;min-width:0;font-size:12px;font-weight:700;color:var(--txt-3)}
/* 「查看详情」不参与等分：桌面端 .card-foot .btn 是 flex:1，按钮会被拉满整行，
   和「N 条案例」挤在一起。这里用 (0,3,0) 盖掉它，跟工具库的「立即使用」一个规格 */
.prod .prod-foot .btn{flex:0 0 auto;min-width:104px;white-space:nowrap}

/* 桌面列数与工具库、物料库一致 —— 三条 feed 都走 .grid 那条 auto-fill，
   所以这里不再写 repeat(3)。原委见工具库那节的注释（宽屏上物料 4 张 / 这两页 3 张，
   卡宽差三分之一）。align-items:stretch 保留：同一行等高，底部按钮才齐。 */.pf-row{display:grid;grid-template-columns:1fr;gap:10px}
.pf-row + .pf-row{margin-top:10px}
.pf{display:block;min-width:0;margin-bottom:10px}
.pf-row .pf{margin-bottom:0}
.pf > span{
  display:block;font-size:11.5px;font-weight:800;color:var(--txt-3);
  letter-spacing:.3px;margin-bottom:6px;
}
.pf input,.pf select,.pf textarea{
  width:100%;font:inherit;font-size:13px;color:var(--txt);
  background:var(--solid-2);border:1px solid var(--line-2);border-radius:var(--r-md);
  padding:10px 12px;
  transition:border-color var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease),
    background var(--dur-fast) var(--ease);
}
.pf textarea{resize:vertical;line-height:1.7}
/* 聚焦环要连 :focus-visible 一起写，并且给足特异性 —— 上一版就是因为
   `.lf input` 被后面的规则反超，手机上点进去看不出焦点在哪 */
.pf input:focus,.pf select:focus,.pf textarea:focus,
.pf input:focus-visible,.pf select:focus-visible,.pf textarea:focus-visible{
  outline:none;border-color:var(--acc-ring);background:var(--solid);
  box-shadow:0 0 0 3px var(--acc-soft);
}
.pf-acts{display:flex;flex-wrap:wrap;gap:11px;align-items:center;margin-top:14px}
.pf-hint{font-size:11.5px;color:var(--txt-3);line-height:1.6}
.pf-hint.ok{color:var(--acc-d);font-weight:700}

/* 详情页那一整套 .pd-* 已经搬去 pd.css（站内招商版），
   这里只剩表单族 .pf-* —— 它是 tool 页与详情页共用的，留在公共表里 */
@media (min-width:700px){
  .pf-row{grid-template-columns:1fr 1fr}}

/* ⚠️ 2026-09-24：这里原有「3. 预约留资弹窗」整节 ——
   .lead / .lead-mask / .lead-box / .lead-head / .lead-sub / .lead-form
   以及在它下面跟着的那批表单样式 .lf / .lf-k / .lead-hint / .lead-acts /
   body.lead-lock 和那段 @media(min-width:1024px)。
   .lf 那几个类只有留资表单这一个用户（全库再没第二个 class="lf"），
   留资下线后它们也没有第二个落点，整节删除。 */

/* ---- 4. 后台：问答库列表列宽 / 重复行 / 图形选择 / 客户提问 ---- */
/* ⚠️ 2026-09-23 晚：这条原来叫 .lt-products（产品库）。产品库整体下线时，
   admin.html 那侧换成了 .lt-qas，但这段列宽定义没跟着改名 —— 结果 .lt-qas
   一个 --ltc 都没有，落到 .lt-head/.list-row 的兜底值 minmax(0,1fr)：
   5 列表头、5 个单元格全挤成竖着的一列（实测 gridTemplateColumns 是单列
   872px）。看上去像「变窄了」，其实是**结构塌了**。
   问答行与旧产品行同构（主列 + 两个 chip 列 + 状态徽标组 + 操作列），
   所以数值沿用，只把名字换成真正在用的那个。 */
.lt-qas{--ltc:minmax(0,1fr) 104px 128px 176px max-content}
/* 客户提问：主列（问题 + 答案摘要）/ 提问人 / 产品·分类 / 状态 + 时间 / 操作。
   ⚠️ .lt-asks 必须在这里有这一行 —— 问答库那张卡就栽在这一处（admin.html
   换了类名、CSS 没跟着改，列表塌成一根竖条）。加新列表时先回来补这一行。 */
.lt-asks{--ltc:minmax(0,1fr) 118px 150px 158px max-content}
/* 问答 / 提问两个卡的标题栏说明都偏长，压缩时省略号收尾（同 .lt-tools 那两行）
   ⚠️ 小屏为什么会把标题挤成竖排：.card-h 是 flex 行，标题「已发布问答」
   在 HTML 里是**裸文本节点**，浏览器给它生成的匿名 flex 项 min-content
   只有 1 个字，于是被右侧的说明 + 按钮一路压到每行 1 字（截图里就是
   「已发 / 布问 / 答」三行）。说明文字本身与页面副标题重复，直接收起来，
   标题再用 nowrap 兜一道，保证它永远只占一行。 */
.lt-qas .card-h-note{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media (max-width:640px){
  .lt-qas .card-h>span{white-space:nowrap}
  .lt-qas .card-h-note{display:none}}
/* 手机端：后台列表统一改成纵向堆叠（与其它列表同一段规则，见 .lt-moments 那一组） */
@media (max-width:640px){
  .lt-qas .list-row,.lt-asks .list-row{
    display:flex;flex-wrap:wrap;gap:10px;padding:13px 14px;
  }}

/* ---- 客户提问（后台）----
   待回答的行给一道暖色左边框：这一页的第一职责是「把没答的答掉」，
   哪几条还没动手，应该扫一眼就看见，而不是逐行读状态徽章。 */
.lt-asks .list-row.ask-wait{border-left:3px solid #f59e0b}
/* ---- 列表 tab（2026-09-24 加）----
   已发布问答 / 客户提问 两份列表互斥显示，一次只出一个。
   不做成上下两摞：每张卡都是几十行的表，摞起来时第二份永远在屏幕外，
   运营要滚过一整屏才知道它存在 —— 用 tab 折起来，两个列表都是「一屏到岸」。
   ★ 灰 = 问答总数（信息），红 = 待回答条数（提醒）。
     红色只留给「该动手了」：把它用在「有 24 条公开问答」上会稀释它的意思，
     过几天运营就学会连红点一起忽略了（所以待回答为 0 时干脆不显示）。 */
.qa-tabs{
  display:flex;align-items:center;gap:6px;margin:14px 0 16px;padding:4px;
  border:1px solid var(--line);border-radius:12px;background:var(--solid-2);
}
.qa-tab{
  display:inline-flex;align-items:center;gap:7px;
  border:0;background:transparent;cursor:pointer;
  padding:9px 15px;border-radius:9px;
  font-size:13.5px;font-weight:700;color:var(--txt-2);
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease);
}
.qa-tab:hover{color:var(--txt)}
.qa-tab.on{background:var(--solid);color:var(--acc-d);box-shadow:var(--sh-1)}
.qa-tab-n{
  min-width:20px;height:20px;padding:0 6px;border-radius:10px;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--solid-2);color:var(--txt-2);
  font-size:11.5px;font-weight:800;font-style:normal;font-variant-numeric:tabular-nums;
}
.qa-tab-n.hot{background:var(--danger);color:#fff}
.qa-tab-n[hidden]{display:none!important}
@media (max-width:640px){
  .qa-tabs{padding:3px}
  .qa-tab{flex:1;justify-content:center;padding:9px 8px}}

/* 弹框里复述一遍问题，运营写答案时不用来回切窗口看题目 */
.ask-ans-q{
  padding:13px 15px;border-radius:13px;margin-bottom:10px;
  background:var(--solid-2);border:1px solid var(--line);
  font-size:14.5px;font-weight:800;line-height:1.65;color:var(--txt);
}
.ask-ans-d{
  padding:11px 14px;border-radius:12px;margin-bottom:14px;
  background:var(--warn-soft);border:1px solid var(--warn-line);
  font-size:13px;line-height:1.8;color:var(--warn-t);white-space:pre-wrap;
}
.ask-ans-d[hidden]{display:none}
.ask-ck{
  display:flex;align-items:center;gap:9px;margin:4px 0 0;
  font-size:13.5px;font-weight:700;color:var(--txt-2);cursor:pointer;
}
.ask-ck input{width:16px;height:16px;flex:0 0 auto;accent-color:var(--acc)}

/* ⚠️ 2026-09-24：这里原有 .lead-phone / .lead-note 两条 —— 留资行里的手机号与备注样式。
   留资那张表随整条链路下线，这两条也没有第二个用户了。 */

/* 能力 / 指标：可增删的重复行 */
.rep{display:flex;flex-direction:column;gap:8px;margin-bottom:10px}
.rep:empty{display:none}
.rep-row{
  display:grid;gap:8px;align-items:center;
  grid-template-columns:minmax(0,1fr) minmax(0,1.3fr) auto;
  grid-template-areas:"a b x";
}
.rep-row input{
  width:100%;min-width:0;
  border:1px solid var(--line-2);border-radius:var(--r-md);
  background:var(--solid);padding:9px 12px;font-size:13.5px;color:var(--txt);
  transition:border-color var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease);
}
.rep-row input::placeholder{color:var(--txt-4)}
.rep-row .r-a{grid-area:a}
.rep-row .r-b{grid-area:b}
.rep-row select{
  width:100%;min-width:0;
  border:1px solid var(--line-2);border-radius:var(--r-md);
  /* ⚠️ 必须用 background-color 而不是 background 简写 —— 简写会把基础 select
     规则里的箭头图 / no-repeat / position 一起重置掉：浅色皮肤箭头直接消失，
     深色皮肤那条只补图不补 repeat 的规则会接管，箭头就以 repeat 平铺，
     整个下拉框被 ▼ 铺满（后台「新建交付方案」实测翻过车）。 */
  background-color:var(--solid);padding:9px 12px;font-size:13.5px;color:var(--txt);
}
.rep-row select:focus,.rep-row select:focus-visible{
  border-color:var(--acc);box-shadow:0 0 0 4px var(--acc-soft);outline:none;
}
.rep-row input:focus,.rep-row input:focus-visible{
  border-color:var(--acc);box-shadow:0 0 0 4px var(--acc-soft);outline:none;
}
.rep-del{
  grid-area:x;width:32px;height:32px;flex:none;
  border:1px solid var(--line-2);border-radius:9px;background:var(--solid);
  color:var(--txt-3);cursor:pointer;font-size:13px;line-height:1;
  transition:color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease);
}
.rep-del:hover{color:var(--danger);border-color:rgba(238,75,75,.35);background:rgba(238,75,75,.06)}

/* ===== 后台 · 核心卖点那层（2026-09-25）=====
   一行 = 一整块（卖点名 + 适配行业 + N 个行业场景），不是「两栏 + 删除键」
   那种通用形状，所以先把 .rep-row 的三列网格撤掉，改回竖排。 */
.rep-row.dsell{
  display:block;padding:12px;
  border:1px solid var(--line-2);border-radius:var(--r-md);background:var(--solid-2);
}
.rep-row.dsell > input,.sc-row input{
  width:100%;min-width:0;
  border:1px solid var(--line-2);border-radius:var(--r-md);
  background:var(--solid);padding:9px 12px;font-size:13.5px;color:var(--txt);
}
.rep-row.dsell > input{margin-top:8px}
.rep-row.dsell > .btn.tiny{margin-top:9px}
.dsell .sell-h{display:flex;align-items:center;gap:8px}
.dsell .r-title{flex:1;min-width:0}

.sell-scenes{display:grid;gap:8px;margin-top:9px}
.sc-row{padding:10px;border-radius:var(--r-sm);background:var(--solid);border:1px solid var(--line)}
.sc-row-h{display:flex;align-items:center;gap:8px}
.sc-row-h .r-ind{flex:1;min-width:0}
.sc-row > input{margin-top:7px}
.sc-ic{display:flex;align-items:center;gap:6px;flex:0 0 auto}
.sc-ic .pv{
  width:30px;height:30px;border-radius:9px;display:grid;place-items:center;
  background:var(--acc-soft);border:1px solid var(--acc-line);color:var(--acc-d);
}
.sc-ic .pv svg{width:17px;height:17px}
.sc-ic select{
  width:auto;padding:6px 8px;font-size:12.5px;
  border:1px solid var(--line-2);border-radius:var(--r-sm);
  background-color:var(--solid);color:var(--txt);  /* 同 .rep-row select：别用 background 简写 */
}
/* 场景那层的删除键不能复用 .rep-del（那会连带把整个卖点删掉） */
.sc-del{
  flex:0 0 auto;width:28px;height:28px;border-radius:8px;line-height:1;font-size:12px;
  border:1px solid var(--line-2);background:var(--solid);color:var(--txt-3);cursor:pointer;
}
.sc-del:hover{color:var(--danger);border-color:rgba(238,75,75,.35);background:rgba(238,75,75,.06)}

/* 招商设置：政策是「档位 → 维度」两层，测算是定长字段组。
   它们都由上面那套平坦重复行演化而来，视觉上保持一致 */
.rep-row.multi{display:flex;flex-wrap:wrap}
.rep-row.multi input{flex:1 1 150px;min-width:0}
.rep-row.multi select{flex:0 1 148px}
.rep-row.multi .rep-del{flex:0 0 auto}

.plan-box{
  border:1px solid var(--line-2);border-radius:var(--r-lg);
  background:var(--solid);padding:14px;margin-bottom:12px;
}
.plan-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:10px}
.plan-head input{
  border:1px solid var(--line-2);border-radius:var(--r-md);
  background:var(--solid);padding:9px 12px;font-size:13.5px;color:var(--txt);min-width:0;
}
.plan-head .pl-n{flex:1 1 160px}
.plan-head .pl-tag{flex:0 1 130px}
.plan-head input::placeholder{color:var(--txt-4)}
.plan-head input:focus,.plan-head input:focus-visible{
  border-color:var(--acc);box-shadow:0 0 0 4px var(--acc-soft);outline:none;
}
.plan-hot{
  display:inline-flex;align-items:center;gap:6px;white-space:nowrap;cursor:pointer;
  font-size:12.5px;font-weight:700;color:var(--txt-3);
}
.plan-hot input{width:auto;flex:0 0 auto}

.plan-items{display:flex;flex-direction:column;gap:8px;margin-bottom:10px}
.plan-item{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.4fr) auto;
  gap:8px;align-items:center;
}
.plan-item input{
  width:100%;min-width:0;
  border:1px solid var(--line-2);border-radius:var(--r-md);
  background:var(--solid);padding:8px 11px;font-size:13px;color:var(--txt);
}
.plan-item input::placeholder{color:var(--txt-4)}
.plan-item input:focus,.plan-item input:focus-visible{
  border-color:var(--acc);box-shadow:0 0 0 4px var(--acc-soft);outline:none;
}
.plan-item .rep-del{width:30px;height:30px;font-size:12px}

.calc-row{
  display:grid;gap:8px;align-items:center;margin-bottom:8px;
  grid-template-columns:auto minmax(0,1.1fr) minmax(0,1fr) minmax(0,.9fr) auto;
}
.calc-row input{
  width:100%;min-width:0;
  border:1px solid var(--line-2);border-radius:var(--r-md);
  background:var(--solid);padding:9px 12px;font-size:13.5px;color:var(--txt);
}
.calc-row input::placeholder{color:var(--txt-4)}
.calc-row input:focus,.calc-row input:focus-visible{
  border-color:var(--acc);box-shadow:0 0 0 4px var(--acc-soft);outline:none;
}
.cc-name{font-size:12.5px;font-weight:700;color:var(--txt-2);white-space:nowrap}
.cc-name em{font-style:normal;font-weight:600;color:var(--txt-4);margin-left:4px}
.cc-range{font-size:11.5px;color:var(--txt-4);white-space:nowrap}

@media (max-width:640px){
  .rep-row{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"a x" "b x"}
  .plan-item{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"k x" "v v"}
  .plan-item .pi-k{grid-area:k}
  .plan-item .pi-v{grid-area:v}
  .plan-item .rep-del{grid-area:x}
  .plan-head .pl-n{flex:1 1 100%}
  .calc-row{grid-template-columns:minmax(0,1fr);gap:6px}
  .cc-name,.cc-range{display:none}}

/* 封面图形四选一：单选按钮藏在卡片里，选中态整块变色 */
.kindpick{display:grid;grid-template-columns:1fr 1fr;gap:8px}
@media (min-width:1024px){
  .kindpick{grid-template-columns:repeat(4,1fr)}}
.kindpick label{position:relative;cursor:pointer;min-width:0}
.kindpick input{position:absolute;opacity:0;width:1px;height:1px;pointer-events:none}
.kp-box{
  display:block;height:100%;background:var(--solid);
  border:1px solid var(--line-2);border-radius:var(--r-md);padding:10px 12px;
  transition:border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease);
}
.kp-box b{display:block;font-size:13.5px;font-weight:800;color:var(--txt)}
.kp-box i{display:block;font-style:normal;font-size:11.5px;font-weight:600;color:var(--txt-3);margin-top:3px}
.kindpick label:hover .kp-box{border-color:var(--acc-ring)}
.kindpick input:checked + .kp-box{
  border-color:var(--acc);background:var(--acc-soft);
  box-shadow:inset 0 0 0 1px var(--acc-line);
}
.kindpick input:checked + .kp-box b{color:var(--acc-d)}
.kindpick input:focus-visible + .kp-box{outline:2px solid var(--acc);outline-offset:2px}

/* ============================================================
   工具分享开关（后台工具行里就那么一个）
   开了 = 代理商在工具页里能看到「分享」，客户打开是一条独立工具页
   ============================================================ */
.sw{
  display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 9px 0 5px;
  border-radius:999px;border:1px solid var(--line-2);background:var(--solid);
  color:var(--txt-3);font-size:12px;font-weight:700;cursor:pointer;white-space:nowrap;
  transition:background .18s,border-color .18s,color .18s;
}
.sw i{
  position:relative;width:24px;height:14px;border-radius:999px;flex:none;
  background:var(--line-2);transition:background .18s;
}
.sw i::after{
  content:'';position:absolute;top:2px;left:2px;width:10px;height:10px;border-radius:50%;
  background:var(--solid);box-shadow:0 1px 2px rgba(16,34,64,.28);transition:transform .18s;
}
.sw b{font-weight:800}
.sw:hover{border-color:var(--acc);color:var(--acc-d)}
.sw.on{background:var(--grad-soft);border-color:var(--acc-ring);color:var(--acc-d)}
.sw.on i{background:var(--acc)}
.sw.on i::after{transform:translateX(10px)}

/* ============================================================
   质感精修 —— 全站通用
   门户 / 工具页 / 后台都引这一份样式表，所以这一节改一次三处一起变。
   ------------------------------------------------------------
   一条硬规矩：这里只写「不随断点变化」的属性 ——
   阴影、描边颜色、动画时长与曲线、悬停位移、聚焦环、字距、玻璃层模糊度。
   凡是会随宽度变的（内边距 / 字号 / 圆角 / 栅格 / 列数 / 显隐）一概不碰。
   原因：这一节在文件最末，同特异性下后写者胜 ——
   只要写了响应式属性，就会反过来盖掉前面所有媒体查询，把手机端布局带歪。
   ============================================================ */

/* --- 1. 顶栏与底部导航：实心白 + 一条细线 --------------------------
   这里原本是一层毛玻璃：模糊半径 26px、饱和度 1.85。
   去掉它有四个连带的好处：不再有雾面感、底下内容不会透上来抢视线、
   滚动时没有实时模糊的开销（Windows 的 Chrome/Edge 上尤其明显，会掉帧）、
   以及背景不会被模糊成一片糊。 */
.appbar{
  background:var(--solid);
  transition:box-shadow var(--dur) var(--ease);
}
.appbar.scrolled{box-shadow:0 1px 2px rgba(15,23,42,.05)}
.tabbar{
  background:var(--solid);
  box-shadow:0 -1px 0 var(--line);
}
/* 注意：这里不能再写 .nav —— 桌面端那一段把 .nav 的底色与边框显式清零
   （PC 顶栏的 Tab 是独立胶囊，容器必须透明）。本节在文件最末、同特异性后写者胜，
   一旦重复声明就会反过来把 PC 顶栏刷出一块底色。 */
/* 原来这里给品牌那块渐变小方块加顶高光（.brand-mark）。
   品牌位换成设计给的 logo 图片之后那个方块没了，这条跟着撤掉；
   admin 的登录页图标与弹框图标还吃同一个变量，保留。 */
.login-mark,.modal-head .mi{box-shadow:var(--sh-brand)}
.upd{transition:border-color var(--dur) var(--ease),color var(--dur) var(--ease)}
.upd:hover{border-color:var(--line-3)}

/* --- 2. 大块面：只留贴边影，取消所有光晕 -------------------------- */
.hero{box-shadow:var(--sh-1)}
.eyebrow{box-shadow:none}
.kpi{border-color:var(--line);box-shadow:none}
.login-box{box-shadow:var(--sh-3)}

/* --- 3. 卡片族：描边更淡、悬停更细腻 ------------------------------ */
.post,.case,.card,.mat,.tool,.stat,.empty{border-color:var(--line)}
.empty{box-shadow:var(--sh-1)}

/* ===== 代理管理 ===== */
.ag-grid{display:grid;grid-template-columns:1.1fr .9fr 1.2fr 1fr .8fr 2fr;gap:10px;align-items:center}
.ag-head{padding:11px 16px;font-size:12.5px;font-weight:700;color:var(--txt-3);border-bottom:1px solid var(--line);background:var(--bg-2)}
/* 表头里挂一行小字补充说明（例：注册申请表的「申请人自报，通过前可改」） */
.ag-head em{display:block;margin-top:2px;font-style:normal;font-weight:500;font-size:11.5px;color:var(--txt-4)}
.ag-row{padding:12px 16px;border-bottom:1px solid var(--line)}
.ag-row:last-child{border-bottom:none}
.ag-ops{display:flex;gap:8px;justify-content:flex-end;flex-wrap:wrap}
.tag-on{color:#16a34a;font-style:normal;font-weight:700}
.tag-off{color:#b91c1c;font-style:normal;font-weight:700}
@media (max-width:760px){.ag-grid{grid-template-columns:1fr 1fr 1fr}.ag-ops{grid-column:1/-1;justify-content:flex-start}}
/* ===== 代理账号管理面板（#209） ===== */
.ag-toolbar{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:16px}
.ag-title{display:flex;align-items:baseline;gap:10px;font-weight:800;font-size:18px;color:var(--txt)}
.ag-title em{font-weight:500;font-size:12.5px;color:var(--txt-3)}
.ag-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:16px}
.ag-stat{background:var(--bg-2);border:1px solid var(--line);border-radius:var(--r-lg);padding:14px 16px}
.ag-stat-n{font-size:26px;font-weight:800;color:var(--txt)}
.ag-stat-l{display:block;margin-top:2px;font-size:12.5px;color:var(--txt-3)}
.btn.xs{height:30px;padding:0 12px;font-size:12.5px;border-radius:9px}
.btn.warn{color:#b45309;border-color:rgba(180,83,9,.28)}
.btn.warn:hover{background:#b45309;color:#fff;border-color:#b45309}
@media (max-width:760px){.ag-stats{grid-template-columns:1fr 1fr 1fr;gap:8px}.ag-stat{padding:11px 8px}.ag-stat-n{font-size:20px}}
.empty-icon{border-radius:20px;box-shadow:none}
/* ===== 新增代理后的"账密结果"面板 ===== */
.ag-creds{background:var(--bg-2);border:1px solid var(--line);border-radius:var(--r-lg);padding:16px}.ag-creds-t{font-weight:700;color:var(--txt);margin-bottom:10px}
.ag-creds pre{margin:0 0 12px;padding:13px 14px;background:#0f172a;color:#e2e8f0;border-radius:11px;
  font:13px/1.7 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap;word-break:break-all}
.ag-creds-btns{display:flex;gap:10px}

/* ===== 分享注册（2026-09-30 加）=====
   后台「代理管理」里那套：注册链接列表 + 注册申请列表 + 生成弹窗。
   全部复用后台已有的 ag-* / card / btn 底座，这里只补这一块特有的格子与条目。 */
.rg-tb{margin:0;padding:12px 16px}
.rg-tb-r{display:flex;align-items:center;gap:10px}
.rg-tb-r .btn.on{background:var(--brand);color:var(--on-acc);border-color:var(--brand)}
/* 注册申请的列：申请人 / 手机 / 渠道 / 时间 / 操作。
   比代理列表少一列（没有账号列 —— 通过之前还没有账号），所以单独一套栅格。 */
/* 六列：申请人 / 手机号 / 申请等级 / 来源渠道 / 提交时间 / 操作。
   2026-09-30 加「申请等级」——等级改成申请人自选之后，
   运营点「通过」之前必须先看见他要的是哪一档。 */
.rg-grid{display:grid;grid-template-columns:1.1fr .9fr 1.2fr 1fr 1.2fr 1.8fr;gap:10px;align-items:center}
.rg-app{padding:12px 16px;border-bottom:1px solid var(--line)}
.rg-app:last-child{border-bottom:none}
.rg-app .sub{display:block;margin-top:3px;font-size:12px;font-weight:500;color:var(--txt-3)}
.rg-badge{display:inline-block;padding:3px 9px;border-radius:999px;font-size:12px;font-weight:800;white-space:nowrap}
.rg-badge.wait{color:#b45309;background:rgba(245,158,11,.15);border:1px solid rgba(245,158,11,.4)}
.rg-badge.ok{color:#16a34a;background:rgba(22,163,74,.13);border:1px solid rgba(22,163,74,.35)}
.rg-badge.no{color:#b91c1c;background:rgba(185,28,28,.11);border:1px solid rgba(185,28,28,.3)}
/* 申请行里那枚等级下拉：待审时可改，通过时以此为准。
   做成 select 而不是静态徽章 —— 运营看一眼、改一下、再点通过，
   中间不用再弹一个「选等级」的窗。 */
.rg-lvsel{
  width:100%;max-width:132px;height:32px;padding:0 8px;border-radius:var(--r-md);
  border:1px solid var(--line-2);background:var(--card);color:var(--txt);
  font-size:12.5px;font-weight:700;font-family:inherit;cursor:pointer;outline:none;
}
.rg-lvsel:focus{border-color:var(--brand);box-shadow:0 0 0 3px rgba(37,99,235,.14)}
@media (max-width:900px){
  .rg-grid{grid-template-columns:1fr 1fr}
  .rg-app .ag-ops{grid-column:1/-1;justify-content:flex-start}
}

/* 生成弹窗里的说明块 */
.rg-tip{
  padding:12px 14px;margin-bottom:16px;border-radius:var(--r-lg);
  background:var(--bg-2);border:1px dashed var(--line-2);
  font-size:12.5px;line-height:1.85;color:var(--txt-3);
}
.rg-tip b{display:block;margin-bottom:2px;font-size:13px;color:var(--txt)}
.rg-tip span{display:block}
.rg-tip strong{color:var(--txt-2)}

/* 新建那一块 */
.rg-new{
  padding:16px;margin-bottom:18px;border-radius:var(--r-lg);
  background:var(--bg-2);border:1px solid var(--line);
}
.rg-check{display:flex;align-items:flex-start;gap:9px;margin:4px 0 12px;cursor:pointer}
.rg-check input{flex:0 0 auto;margin-top:2px;width:16px;height:16px;cursor:pointer}
.rg-check span{font-size:13px;font-weight:700;color:var(--txt)}
.rg-check span em{display:block;margin-top:2px;font-style:normal;font-weight:500;font-size:12px;color:var(--txt-3);line-height:1.6}

.rg-list-h{
  margin-bottom:10px;font-size:12.5px;font-weight:800;color:var(--txt-3);
  letter-spacing:.3px;
}

/* 一条链接 */
.rg-item{
  padding:14px 15px;margin-bottom:10px;border-radius:var(--r-lg);
  background:var(--solid);border:1px solid var(--line);
}
.rg-item.off{opacity:.62}
.rg-item-h{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-bottom:9px}
.rg-item-h b{font-size:14px;font-weight:800;color:var(--txt)}
.rg-url{
  display:block;padding:9px 11px;margin-bottom:9px;border-radius:10px;
  background:var(--bg-2);border:1px solid var(--line);
  font:12.5px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  color:var(--txt-2);word-break:break-all;
}
.rg-stats{display:flex;gap:16px;flex-wrap:wrap;margin-bottom:11px}
.rg-stat{font-size:12.5px;color:var(--txt-3)}
.rg-stat b{font-size:15px;font-weight:800;color:var(--txt);margin-right:4px}
.rg-item-ops{display:flex;gap:8px;flex-wrap:wrap}

/* ===== 代理等级配置（三档卡片编辑器） ===== */
#lvEditor{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;align-items:start}
.lv-card{background:var(--bg-2);border:1px solid var(--line);border-radius:var(--r-lg);padding:14px 14px 16px}
.lv-head{display:flex;align-items:center;gap:9px;margin-bottom:12px}
.lv-dot{flex:0 0 auto;min-width:34px;height:26px;padding:0 8px;display:flex;align-items:center;justify-content:center;
  border-radius:8px;font-size:12.5px;font-weight:800;color:var(--on-acc);background:var(--brand)}
.lv-dot.lv-L2{background:#b45309}
.lv-dot.lv-L3{background:#7c3aed}
.lv-name{flex:1;height:32px;padding:0 10px;font-size:14px;font-weight:700}
.lv-bens{display:flex;flex-direction:column;gap:8px;margin-bottom:10px}
.lv-ben{display:flex;align-items:center;gap:6px}
.lv-ben-in{flex:1;min-width:0;height:30px;padding:0 9px;font-size:13px}
.lv-ben-del{flex:0 0 auto;width:26px;height:26px;padding:0;display:flex;align-items:center;justify-content:center;font-size:12px}
.lv-ben-empty{padding:9px 2px;font-size:12.5px;color:var(--txt-3)}
.lv-ben-add{width:100%;margin-bottom:12px;border-style:dashed}
@media (max-width:900px){#lvEditor{grid-template-columns:1fr}}

/* --- 4. 动画节奏全站一套 ------------------------------------------
   时长与曲线统一之后，「悬停 / 展开 / 变色」到处是同一个手感，
   不再出现这里 0.14s、那里 0.26s 的参差。 */
.post,.case,.mat,.tool{
  transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.btn{
  transition:transform var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease),
    box-shadow var(--dur-fast) var(--ease),filter var(--dur-fast) var(--ease);
}
.chip,.tab{
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease),transform var(--dur-fast) var(--ease);
}
.tabbar-btn{transition:color var(--dur-fast) var(--ease),transform .12s var(--ease)}
.list-row{transition:background var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease)}
.cat-chip{transition:background var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease)}
.lr-pics img{transition:border-color var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease)}
.tool-cover img,.mat-cover img{transition:transform .42s var(--ease)}
.sl-drop,.drop{transition:border-color var(--dur) var(--ease),background var(--dur) var(--ease),transform var(--dur) var(--ease)}
.sw i,.sw i::after{transition-duration:var(--dur-fast);transition-timing-function:var(--ease)}

/* --- 5. 悬停：只在「真鼠标 + 桌面」生效 ---------------------------
   触屏没有 hover，这一整段在手机上本来就不会触发；
   限定条件写全，是为了别让平板上「点一下残留 hover 态」的怪现象出现。 */
@media (hover:hover) and (min-width:1024px){
  .post:hover,.case:hover,.mat:hover,.tool:hover{
    transform:translateY(-2px);
    box-shadow:var(--sh-2);
    border-color:var(--line-3);
  }
  .btn:hover{box-shadow:var(--sh-1)}
  .btn.primary:hover{background:var(--acc-d);box-shadow:var(--sh-1)}
  .pics img:hover,.shots img:hover{filter:brightness(1.04)}
  .lr-pics img:hover{box-shadow:0 4px 12px -8px rgba(15,23,42,.25)}
  .stat:hover{box-shadow:var(--sh-1)}
  .sl-drop:hover{border-color:var(--acc)}}

/* --- 6. 聚焦环：键盘走到哪，一眼能看见 ---------------------------- */
.btn:focus-visible,.chip:focus-visible,.tab:focus-visible,.tabbar-btn:focus-visible,
.link-btn:focus-visible,.cat-chip:focus-visible,.more:focus-visible,.icon-btn:focus-visible,
.s-clear:focus-visible,.sw:focus-visible,.cat-tag b:focus-visible{
  outline:2px solid var(--acc);outline-offset:2px;
}

/* --- 7. 表单聚焦：环稍大、色稍浅，柔和不刺眼 ----------------------
   这里刻意只写低特异性的 input:focus（0,1,1），不写 input[type=text]:focus：
   后者的权重和 .search / .afsearch 里那两条「把内层输入框边框与阴影清零」的
   规则（0,2,1）一样，会靠"后面写"反过来赢，结果就是搜索框里又套一个带框的
   小盒子 —— 也就是原来注释里警告过的「两个搜索框叠在一起」。 */
input:focus,textarea:focus,select:focus,.search:focus-within,.afsearch:focus-within{
  border-color:var(--acc);box-shadow:0 0 0 4px var(--acc-soft);
}

/* --- 8. 字距节奏：大标题再收紧一点点 ------------------------------
   只动大标题。数据类数字（.kpi b / .metric b / .stat b）不碰：
   它们在手机上会掉到 17~22px，字距收到 -1px 就糊成一团了。 */
.hero h1,.tb-title h1{letter-spacing:-.6px}
.card-title{letter-spacing:-.25px}

/* --- 9. 分节小圆点：一圈柔光，不再是硬邦邦一个点 ------------------ */
.card-h .bullet{box-shadow:none}

/* --- 10. 浮层与提示：更圆润 --------------------------------------
   遮罩不再做背景模糊：打开弹窗那一瞬间的实时模糊是肉眼可见的掉帧来源，
   实心半透明遮罩已经足够分层，切换也更快。 */
.tray-box{border-radius:20px 20px 0 0}
.toast{border-radius:14px;box-shadow:0 6px 18px -10px rgba(15,23,42,.45)}

/* --- 11. 后台：表头与状态徽标 ------------------------------------- */
.lt-head{letter-spacing:.5px;background:var(--solid-2)}
.bdg{border-radius:9px}
/* 关着的时候鼠标移上去，滑道也深一档，不至于只有文字在变 */
.sw:hover i{background:var(--line-3)}

/* --- 12. 切图器：工具页里唯一由本文件管的组件 ---------------------- */
.seg button{transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease)}
.sl-cell{border-color:var(--line)}
.sl-preview{border-color:var(--line);box-shadow:inset 0 1px 0 rgba(255,255,255,.6)}
.sl-cell-dl{transition:opacity var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease),transform var(--dur-fast) var(--ease)}
.sl-cell-dl:hover{transform:scale(1.06)}
.sl-field input:focus{border-color:var(--acc);box-shadow:0 0 0 4px var(--acc-soft)}

/* --- 13. 滚动条：细一点、淡一点 ----------------------------------- */
::-webkit-scrollbar-thumb{background:var(--acc-line)}

/* --- 14. 产品库顶部的说明条 -------------------------------------------
   它原来是通往独立招商落地页（/join）的入口，还带悬停上浮。
   招商内容整体并进产品详情页之后，站内本身就是招商阵地，这里没有
   「另一个页面」可去了，于是它降级成一句说明。
   相应地：去掉 transition / :hover / 箭头位移 —— 不指向任何地方的
   东西不该看着像能点。（详情页表单下原来那个出口 .pf-more 一并删掉，
   同一条理由。）组件仍走 --acc：产品库是哪个身份色，这条就是哪个色。 */

/* 放这里而不是做成第 6 个 Tab —— 顶栏与手机底栏都是 5 格正好铺满，
   再加一格会把五个主要用途挤瘦。 */
.coop-strip{
  display:flex;align-items:center;gap:12px;
  margin:0 0 14px;padding:14px 16px;
  border:1px solid var(--acc-line);border-radius:var(--r-lg);
  background:linear-gradient(122deg,var(--acc-soft),rgba(255,255,255,.55));
  color:var(--txt);
}
.cs-ico{
  width:38px;height:38px;border-radius:12px;flex:0 0 auto;
  display:grid;place-items:center;background:var(--acc);color:var(--on-acc);
}
.cs-ico svg{width:19px;height:19px}
.cs-b{flex:1 1 auto;min-width:0;display:grid;gap:2px}
.cs-b b{font-size:14.5px;font-weight:800;letter-spacing:-.2px}
.cs-b em{font-style:normal;font-size:12.5px;color:var(--txt-3)}
/* 不是链接，所以不做成描边胶囊，只留一枚浅底小标 */
.cs-go{
  flex:0 0 auto;font-size:12px;font-weight:800;color:var(--acc-d);
  background:var(--solid);border:1px solid var(--acc-line);
  border-radius:999px;padding:5px 12px;white-space:nowrap;
}
/* 手机上把「查看详情 →」整个收掉：那一行本来就挤，留标题和副句就够 */
@media (max-width:640px){
  .coop-strip{gap:10px;padding:13px 14px}
  .cs-go{display:none}}

/* ============================================================
   福利库（第 6 个 Tab）
   ------------------------------------------------------------
   形态沿用工具库 / 产品库那套「16:10 上图下文竖卡」，不另起卡型。
   和产品卡的差别有两处：纸面的科技图形不一样、卡片正文多一行三档等级徽章。

   纸面为什么不照抄产品卡那套「浅蓝 + 疏网格」：
   两张卡挨在一起时，光靠色相区分（蓝 / 青）在 16:10 那么大一块面积上不够，
   必须让「图形语言」本身不同。所以这里多了一层**同心环**
   （雷达 / 同心圆那套语义），网格也从产品卡的 34px 收紧到 28px ——
   远看是「一圈一圈的同心纹」，不是产品卡那种方方正正的科技纸。

   身份色与 KPI 的排法都不在这里声明 —— 按本项目的约定，
   身份色与新板块的 KPI 排法一律写进文件开头那两段（「每页身份色」与「KPI 排布微差」），
   为的是「置换配色 / 调 KPI 只动那一处」。这一节只管福利库自己的部件。
   ============================================================ */

/* ---------------- 福利卡 ---------------- */
#welFeed{align-items:stretch}
.wel{
  position:relative;display:flex;flex-direction:column;overflow:hidden;
  background:var(--solid);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--sh-1);cursor:pointer;
  transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
/* 悬停浮出的顶部 3px 身份色细边：做法与工具卡 / 产品卡完全一致
   （面板自身背景 + 整卡高度，圆角才是真弧，不受悬停时的合成层影响） */
.wel::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  border-radius:calc(var(--r-lg) - 1px);
  background-image:var(--grad);
  background-size:100% 3px;background-repeat:no-repeat;
  opacity:0;transition:opacity .22s ease;
}
.wel:hover::after{opacity:1}
.wel:hover{transform:translateY(-2px);box-shadow:var(--sh-2);border-color:var(--line-3)}

/* 封面纸面：深色科技纸，三层（深底 + 同心环/网格 + 辉光与暗角）。
   有配图时三层全让位给图片，两种状态高度一致，同一行卡片不会一高一矮。

   ⚠️ 纸面为什么是深的 —— 这是「玫红」唯一能立住的办法：
   玫红是暖色、明度又偏高，铺在浅底上（不管是淡粉还是中性灰），
   一整块面积读下来就是「粉」。这不是色相的问题，是明度关系的问题 ——
     浅底 + 玫红 = 粉；深底 + 玫红 = 光。
   所以纸面沉到深蓝黑（#151C2E → #1E2740），玫红只以「发光刻线」的形式出现：
   深色底上一圈玫红同心环，是雷达刻度、是仪表盘，不会有人管它叫粉色。

   深色纸面在本站不是孤例：产品库早期那套「深靛色面」（--tech-deep）就是这个
   路子，后来产品库改回浅蓝才去掉的。福利库接着用，并把它往「刻度环」推得更远。 */
/* ⚠️ 2026-09-30：封面比例从 16:10 收到 **16:9**，与物料库 / 工具库的封面统一。
   为什么收：这三库的卡是同一套「上图下文竖卡」骨架（.mat / .tool / .wel
   的 body 结构一模一样），封面却一直差一档 —— 物料与工具 16:9、福利 16:10。
   单看一库看不出来，来回切 Tab 或者并排截图就是「一行高一行矮」。
   数值上 16:10 的卡比 16:9 高 6.25%，正好是那种说不出哪里怪、但看着不齐的量。

   详情页首屏那块大封面（.wb-shot）**跟着一起收**：它和列表卡是同一张 cover 图，
   只在列表收、详情不收的话，点进去图会「长高」，等于把刚修好的不一致换个地方重现。
   （这也是本条的代价：详情页 hero 会矮掉约 6%，正文第一屏能多露出一点，可接受。） */
.wel-cover,.wb-shot{
  position:relative;aspect-ratio:16/9;overflow:hidden;
  display:grid;place-items:center;
  background:
    radial-gradient(112% 88% at 76% -10%,rgba(255,255,255,.09) 0%,rgba(255,255,255,0) 56%),
    linear-gradient(148deg,#151C2E 0%,#1E2740 48%,#111726 100%);
  border:1px solid var(--acc-line);
}
/* ⚠️ 列表卡封面自身**不画圆角**（2026-09-30 晚，修「圆角黑边」）：
   原来和物料/工具卡同款写法 —— cover 自绘 15px 圆弧 + 卡片 overflow:hidden
   的 15px 裁剪弧。两条弧看着重合，实际是各自抗锯齿，错开约半像素：
   物料/工具无图时纸面是浅色（--solid-2），浅叠浅看不出来；
   福利无图时是深蓝黑贴白底，这半像素深色漏到白底上，
   就是用户看到的「左上 / 右上圆角黑边」。
   修法：cover 画成方角，弧只由卡片裁剪出（一条弧、一次抗锯齿，没有错位可言）。
   底边那条 border-bottom（--acc-line 玫红 15%）一并去掉 ——
   它压在深纸上发脏（用户嘴里的「底下横线黑边」），深色封面与白 body
   的交界本身就是最清晰的分隔，不需要再描一条线。 */
.wel-cover{
  border-radius:0;border:0;
}
.wb-shot{border-radius:var(--r-md)}
/* 科技图形层：同心环 + 收紧到 28px 的电网格。
   同心环用 repeating-radial-gradient 画，圆心略高于几何中心（46%），
   和徽标的位置对齐；最外圈被 mask 的径向渐隐吃掉，所以看不到生硬的边缘。
   颜色取 --acc-neon（深底专用那支玫红），不是 --acc —— 深底上刻线要更亮。 */
.wel-cover::before,.wb-shot::before{
  content:'';position:absolute;inset:0;
  background-image:
    repeating-radial-gradient(circle at 50% 46%,
      var(--acc-neon) 0 1px,rgba(0,0,0,0) 1px 26px),
    linear-gradient(to right,var(--acc-neon-line) 1px,transparent 1px),
    linear-gradient(to bottom,var(--acc-neon-line) 1px,transparent 1px);
  background-size:auto,28px 28px,28px 28px;
  -webkit-mask-image:radial-gradient(circle at 50% 47%,#000 0%,rgba(0,0,0,.34) 46%,rgba(0,0,0,0) 78%);
  mask-image:radial-gradient(circle at 50% 47%,#000 0%,rgba(0,0,0,.34) 46%,rgba(0,0,0,0) 78%);
}
/* 辉光与暗角：压在图形层之上。
   浅色那版这一层是「柔光」（中间提亮、图形略淡）；深色版正好反过来 ——
   中间给一圈玫红辉光（徽标像在发光），四角压暗角（让深纸面沉下去，
   不是一块平板）。两个渐变是整体换过的，不是只调了个透明度。 */
.wel-cover::after,.wb-shot::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(44% 48% at 50% 48%,rgba(244,63,94,.20) 0%,rgba(244,63,94,0) 72%),
    radial-gradient(122% 104% at 50% 118%,rgba(0,0,0,.46) 0%,rgba(0,0,0,0) 62%);
}
.wel-cover:not(.bare)::before,.wel-cover:not(.bare)::after,
.wb-shot:not(.bare)::before,.wb-shot:not(.bare)::after{content:none}
.wel-cover img,.wb-shot img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;
  transform:translateZ(0);will-change:transform;
  transition:transform .42s var(--ease);
}
/* 图片的圆角各自显式声明（cover 已无圆角，inherit 会拿到 0）：
   值 = 卡片内缘弧（--r-lg 减 1px 边框），与裁剪弧同值 ——
   图片自己带弧 + 父级硬裁双保险，悬停放大也绝不画出弧外。 */
.wel-cover img{border-radius:calc(var(--r-lg) - 1px) calc(var(--r-lg) - 1px) 0 0}
.wb-shot img{border-radius:inherit}
.wel:hover .wel-cover img{transform:translateZ(0) scale(1.04)}

/* 福利徽标：白底圆角方块 + 身份色线框图形。
   缩到手机单列也不会糊成一条线。

   深色纸面上这枚方块是整张卡唯一的「亮点」，所以比浅色版更亮也更厚：
   底色纯白起步，外圈光晕换成 --acc-neon 那支玫红，落影压深。
   产品徽标是「一块白方块贴在纸上」，福利徽标是「一块白方块悬在玫红光里」。
   同心环 + 光环 + 线框图标叠在一起，才是那套「科技感」该有的样子。 */
.wc-badge{
  position:relative;z-index:1;display:grid;place-items:center;
  width:26%;max-width:88px;aspect-ratio:1;border-radius:24%;
  background:linear-gradient(180deg,#fff 0%,#E9EDF4 100%);
  border:1px solid rgba(255,255,255,.20);
  box-shadow:0 0 0 6px var(--acc-neon-line),
             0 6px 16px -6px rgba(0,0,0,.55),
             0 14px 30px -12px rgba(0,0,0,.60),
             inset 0 1px 0 #fff;
  color:var(--acc);
}
.wc-wire{width:74%;height:74%;display:block}
/* 详情页首屏那块封面比卡片大一倍多，徽标跟着放大一档才不会显得空落落 */
.wb-shot .wc-badge{max-width:124px}

/* 封面上的两枚胶囊：分类在左上、折算价值在右上，对角错开不打架。
   都用实色白（不磨砂）—— 换肤时全站的毛玻璃都摘掉了，这里跟着守同一套。
   注意：注释里也别把这个属性的名字写出来，ui-check 有一条是直接扫源码文本的 */
.wel-cat{
  position:absolute;left:10px;top:10px;z-index:2;
  font-size:11px;font-weight:800;letter-spacing:.2px;
  padding:3px 9px;border-radius:999px;white-space:nowrap;
  background:rgba(255,255,255,.94);color:var(--acc-d);
  border:1px solid var(--acc-line);
}
/* 价值留空则整枚不渲染 —— 运营没填就不编一个数给客户看 */
.wel-value{
  position:absolute;right:10px;top:10px;z-index:2;
  font-size:11.5px;font-weight:800;font-variant-numeric:tabular-nums;
  padding:3px 10px;border-radius:999px;white-space:nowrap;
  background:var(--grad);color:var(--on-acc);
  box-shadow:0 2px 8px -3px var(--acc-glow);
}

.wel-body{padding:14px 16px 15px;display:flex;flex-direction:column;flex:1;min-width:0}
.wel .card-text{
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;
  color:var(--txt-3);
}

/* 三档等级徽章 —— 卡片上最要紧的一行：一眼看出「我这档能不能享」。
   可享 = 浅青底 + 深青字（同 .ptag 的克制程度，整卡仍是浅色）;
   不可享 = 灰底 + **虚线**边（虚线是刻意的：不是"没数据"，是"这档确实没有"）。
   flex-wrap：窄卡上换到第二行也不会错位 */
/* margin-top:auto 而不是固定 11px：卡片描述有 1 行的也有 3 行的，
   让「剩余的空间」落在描述与徽章之间，一行里三张卡的徽章才会齐平。
   （只把 footer 钉底的话，徽章会跟着描述长度上下浮动，一行看过去是锯齿） */
.wel-lvs{display:flex;flex-wrap:wrap;gap:6px;margin-top:auto;padding-top:11px}
.lv{
  display:inline-flex;align-items:center;gap:6px;
  font-size:11px;font-weight:700;letter-spacing:.2px;
  padding:3px 9px;border-radius:999px;white-space:nowrap;
  border:1px solid transparent;
}
.lv.on{background:var(--grad-soft);color:var(--acc-d);border-color:var(--acc-line)}
.lv.off{background:var(--solid-2);color:var(--txt-4);border:1px dashed var(--line-2)}
/* 详情页首屏的放大版：够宽，可以把额度一起写进徽章 */
.lv.lg{font-size:12.5px;padding:5px 12px}
.lv.lg em{
  font-style:normal;font-weight:800;opacity:.9;
  border-left:1px solid currentColor;padding-left:7px;margin-left:1px;
}

/* 徽章那一行已经把余量吃掉了（见 .wel-lvs），这里只要一个固定间距，
   两行就一起贴在卡片底部 */ 
.wel-foot{padding-top:12px}
.wel-meta{
  flex:1;min-width:0;font-size:12px;font-weight:700;color:var(--txt-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
/* 「查看福利」不参与等分，和工具库 / 产品库的按钮一个规格 */
.wel .wel-foot .btn{flex:0 0 auto;min-width:104px;white-space:nowrap}

/* ---------------- 福利详情页 ----------------
   刻意不走产品详情页那套通栏大页（#viewProduct + pd.css）：
   福利是「权益说明」，不是招商落地页，用普通 --page 窄柱更合适，
   也就不用碰 pd.css、不会牵动产品详情那套通栏对齐。 */
.wb{display:flex;flex-direction:column;gap:14px}
.wb-hero{
  position:relative;overflow:hidden;
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--sh-1);padding:18px;
}
.wb-hero-top{display:flex;align-items:center;gap:10px;margin-bottom:14px}
.wb-back{
  display:inline-flex;align-items:center;gap:5px;
  border:1px solid var(--line-2);border-radius:10px;background:var(--solid);
  padding:6px 12px;font-size:12.5px;font-weight:700;color:var(--txt-2);cursor:pointer;
  transition:border-color .16s ease,color .16s ease,transform .16s ease;
}
.wb-back:hover{border-color:var(--acc);color:var(--acc);transform:translateY(-1px)}
.wb-back svg{width:14px;height:14px;flex:0 0 auto}
/* 首屏：手机上下堆叠（图在上、文在下，先看图）；PC 才左右分栏 */
.wb-hero-grid{display:grid;grid-template-columns:1fr;gap:15px}
.wb-eyebrow{
  display:inline-flex;align-items:center;
  font-size:11.5px;font-weight:800;letter-spacing:.4px;
  color:var(--acc-d);background:var(--grad-soft);
  border:1px solid var(--acc-line);border-radius:999px;padding:4px 11px;
}
.wb-name{font-size:23px;font-weight:900;letter-spacing:-.5px;margin:11px 0 0;line-height:1.3;word-break:break-word}
.wb-slogan{margin:9px 0 0;font-size:14px;font-weight:700;color:var(--acc-d);line-height:1.6}
.wb-desc{margin:9px 0 0;font-size:13.5px;line-height:1.8;color:var(--txt-2)}
.wb-hero-lvs{display:flex;flex-wrap:wrap;gap:7px;margin-top:14px}
.wb-acts{display:flex;gap:10px;flex-wrap:wrap;margin-top:16px}

/* 六块正文共用的壳 */
.wb-sec{
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--sh-1);padding:17px 18px;
  /* 「查看领取方式」滚到 04 时别把标题顶到顶栏底下 */
  scroll-margin-top:84px;
}
.wb-h{display:flex;align-items:center;gap:10px;margin-bottom:14px}
.wb-h .n{
  flex:0 0 auto;display:grid;place-items:center;
  width:26px;height:26px;border-radius:9px;
  background:var(--grad-soft);border:1px solid var(--acc-line);
  color:var(--acc-d);font-size:12px;font-weight:800;font-variant-numeric:tabular-nums;
}
.wb-h b{font-size:15.5px;font-weight:800;letter-spacing:-.2px}
.wb-h em{margin-left:auto;font-style:normal;font-size:12px;color:var(--txt-4);white-space:nowrap}

/* 01 能解决什么：三组「痛点 → 我们的做法」 */
.wb-pains{display:grid;gap:10px}
.wb-pain{
  display:grid;gap:4px;padding:11px 13px;
  background:var(--solid-2);border:1px solid var(--line);border-radius:var(--r-md);
}
.wb-pain b{font-size:13.5px;font-weight:800;color:var(--txt);line-height:1.6}
.wb-pain span{font-size:12.5px;color:var(--txt-2);line-height:1.7}
/* 箭头用伪元素加，省得文案里混进符号、以后改文案还得小心别删掉它 */
.wb-pain span::before{content:'→ ';color:var(--acc);font-weight:800}

/* 02 包含什么：一份带勾的清单 */
.wb-inc{display:grid;gap:9px}
.wb-inc div{display:flex;gap:9px;align-items:flex-start;font-size:13.5px;color:var(--txt-2);line-height:1.7}
.wb-inc div::before{
  content:'✓';flex:0 0 auto;display:grid;place-items:center;
  width:17px;height:17px;margin-top:3px;border-radius:50%;
  background:var(--acc-soft);border:1px solid var(--acc-line);
  color:var(--acc-d);font-size:10px;font-weight:900;line-height:1;
}

/* 03 适用等级对照 —— 福利库和前面四个库最不一样的地方：
   同一条福利、三档额度不同，必须有一张一眼能比的表。
   数据全部由 levels 推出来，不存第二份 */
.wb-lvtab{display:grid;gap:8px}
.wb-lvrow{
  display:grid;grid-template-columns:1fr auto;gap:10px 14px;align-items:center;
  padding:12px 14px;border-radius:var(--r-md);
  border:1px solid var(--line);background:var(--solid-2);
}
.wb-lvrow.on{
  border-color:var(--acc-line);
  background:linear-gradient(122deg,var(--acc-soft),rgba(255,255,255,.6));
}
.wb-lvrow.off{opacity:.6}
.wb-lvname{display:flex;align-items:center;gap:8px;font-size:13.5px;font-weight:800;min-width:0}
.wb-lvname em{
  font-style:normal;font-size:10.5px;font-weight:800;white-space:nowrap;
  padding:2px 7px;border-radius:999px;
  background:var(--solid);border:1px solid var(--acc-line);color:var(--acc-d);
}
.wb-lvrow.off .wb-lvname em{background:var(--solid);border:1px dashed var(--line-2);color:var(--txt-4)}
.wb-lvq{
  font-size:13px;font-weight:800;color:var(--txt);text-align:right;
  font-variant-numeric:tabular-nums;word-break:break-word;
}
.wb-lvq.no{color:var(--txt-4);font-weight:600}

/* 04 怎么领取：三步 */
.wb-steps{display:grid;gap:11px}
.wb-step{display:grid;grid-template-columns:auto 1fr;gap:11px;align-items:flex-start}
.wb-step .no{
  width:24px;height:24px;border-radius:50%;flex:0 0 auto;
  display:grid;place-items:center;font-size:12px;font-weight:800;
  background:var(--grad);color:var(--on-acc);
}
/* 标题与说明包在 .tx 里再挑 —— 直接写 .wb-step span 会把外层那格也命中，
   文字全变成 block 还多出一条 margin */
.wb-step .tx{min-width:0}
.wb-step .tx b{display:block;font-size:13.5px;font-weight:800;line-height:1.6}
.wb-step .tx span{display:block;font-size:12.5px;color:var(--txt-2);line-height:1.7;margin-top:2px}

/* 05 使用说明 */
.wb-notes{display:grid;gap:8px}
.wb-notes div{display:flex;gap:9px;font-size:13px;color:var(--txt-2);line-height:1.75}
.wb-notes div::before{
  content:'';flex:0 0 auto;width:5px;height:5px;margin-top:9px;border-radius:50%;background:var(--acc);
}

/* 06 常见问题：用原生 <details> 折叠 —— 不用 JS、自带无障碍语义，
   键盘和读屏都直接可用 */
.wb-faqs{display:grid;gap:8px}
.wb-faq{
  border:1px solid var(--line);border-radius:var(--r-md);
  background:var(--solid-2);overflow:hidden;
}
.wb-faq summary{
  list-style:none;cursor:pointer;padding:11px 13px;
  font-size:13.5px;font-weight:700;color:var(--txt);
  display:flex;align-items:center;gap:9px;
}
.wb-faq summary::-webkit-details-marker{display:none}
.wb-faq summary::after{
  content:'＋';margin-left:auto;font-size:14px;font-weight:800;color:var(--acc);flex:0 0 auto;
}
.wb-faq[open] summary::after{content:'－'}
.wb-faq summary:hover{color:var(--acc-d)}
.wb-faq p{margin:0;padding:0 13px 13px;font-size:13px;color:var(--txt-2);line-height:1.78}

/* 底部动作条：吸在视口底部，让「怎么领」随时能点到。
   六块正文很长，滚到第三块想找领取入口时，没有它就得一路划回去。
   z-index 6 只压住本页内容，远低于底部导航（78）与各浮层；
   手机端还要再往上抬一条导航的高度，否则会被 fixed 的 .tabbar 盖住 */
.wb-bar{
  position:sticky;bottom:0;z-index:6;
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  padding:12px 16px;border-radius:var(--r-lg);
  background:var(--surface);border:1px solid var(--line);
  box-shadow:0 -10px 26px -20px rgba(15,23,42,.95);
}
.wb-bar-t{flex:1;min-width:0;font-size:12.5px;color:var(--txt-3);line-height:1.6}
.wb-bar-t b{display:block;font-size:14px;font-weight:800;color:var(--txt)}
@media (max-width:1023px){
  .wb-bar{bottom:calc(var(--tabh) + var(--safe-b) + 8px)}}

/* PC：首屏左右分栏 + 更松的内边距 */
@media (min-width:1024px){
  .wb-hero{padding:22px 24px}
  .wb-sec{padding:20px 22px}
  .wb-hero-grid{grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:26px;align-items:center}
  .wb-name{font-size:27px}}

/* 小屏：卡片与区块都缩一档，内边距收窄 */
@media (max-width:640px){
  .wel-body{padding:12px 14px 13px}
  .wel .card-text{-webkit-line-clamp:3}
  .wc-badge{max-width:64px}
  .wel-cat,.wel-value{font-size:10.5px;padding:2px 8px;left:8px;top:8px}
  .wel-value{left:auto;right:8px}
  .wb-hero,.wb-sec{padding:14px;border-radius:16px}
  .wb-name{font-size:21px;margin-top:9px}
  .wb-h b{font-size:14.5px}
  .wb-h em{display:none}
  .wb-lvrow{padding:10px 12px}
  .wb-bar{padding:10px 12px;border-radius:16px}
  .wb-bar .btn{width:100%}}

/* ============================================================
   福利库 · 后台（第 6 个 Tab）
   ------------------------------------------------------------
   只有两个部件是后台专有的：
     · 列表里那一列「可享等级」—— 直接复用前台那套 .lv 徽章，
       所以后台看到的三枚，和客户在卡片上看到的完全一样；
     · 表单里的三档等级行 —— 这一档能不能享 + 额度多少。
   放在这里而不是前面后台那几节，是因为它们既不属于前台卡、
   也不属于任何一个既有模块。
   ============================================================ */
.lt-benefits{--ltc:minmax(0,1fr) 116px 176px 88px max-content}
.lt-benefits .mat-ico{font-size:22px;line-height:1}
.bl-lvs{display:flex;flex-wrap:wrap;gap:5px}
.bl-lvs .lv{font-size:11px;padding:2px 8px}

/* 三档等级行：等级名 / 可享开关 / 额度。
   三行是写死的，不给增删 —— 代理等级就这三档，不是一份可编辑列表。 */
.ben-lvs{display:grid;gap:8px;margin-bottom:10px}
.ben-lv{
  display:grid;grid-template-columns:96px 108px minmax(0,1fr);
  gap:10px;align-items:center;
  padding:10px 12px;border:1px solid var(--line-2);border-radius:var(--r-md);
  background:var(--solid);
  transition:border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease);
}
/* 开着的那档整行换成浅身份底：三行里哪档可享一眼看出来，
   不用逐行去读右边那个小勾 */
.ben-lv.on{border-color:var(--acc-line);background:linear-gradient(122deg,var(--acc-soft),rgba(255,255,255,.7))}
.ben-lv .bl-n{display:flex;align-items:center;gap:7px;font-size:13.5px;font-weight:800;color:var(--txt)}
.ben-lv .bl-n::before{
  content:'';width:6px;height:6px;border-radius:50%;flex:0 0 auto;background:var(--line-3);
}
.ben-lv.on .bl-n::before{background:var(--acc)}
.ben-lv .bl-q{
  width:100%;min-width:0;
  border:1px solid var(--line-2);border-radius:var(--r-md);
  background:var(--solid);padding:9px 12px;font-size:13.5px;color:var(--txt);
  transition:border-color var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease);
}
.ben-lv .bl-q:focus,.ben-lv .bl-q:focus-visible{
  border-color:var(--acc);box-shadow:0 0 0 4px var(--acc-soft);outline:none;
}
.ben-lv .bl-q::placeholder{color:var(--txt-4)}
/* 关掉可享时额度框只是变淡，**不禁用** —— 先填额度再决定开不开，
   运营的顺序不一定先开开关；直接禁用会让人以为填不进去 */
.ben-lv .bl-q.mute{background:var(--solid-2);color:var(--txt-3)}

/* 封面图形六选一：PC 三列两行，手机两列三行。
   默认那套是 4 列（产品库只有 4 个图形），6 个放进去会剩两个孤块 */
#bKindPick{grid-template-columns:1fr 1fr}
@media (min-width:1024px){
  #bKindPick{grid-template-columns:repeat(3,1fr)}}

/* 后台列表在手机上纵向堆叠（与其它列表同一套做法） */
@media (max-width:640px){
  .lt-benefits .list-row{display:flex;flex-wrap:wrap;gap:10px;padding:13px 14px}
  .ben-lv{grid-template-columns:minmax(0,1fr) auto;gap:8px 10px}
  .ben-lv .bl-q{grid-column:1/-1}}

/* ============================================================
   教程库 · 前台（第七个库）
   ------------------------------------------------------------
   形态沿用「上图下文竖卡」，但封面纸面**刻意不是深色科技纸** ——
   福利库已经把深纸面用掉了，而这两个库在底栏上是挨着的（第 6 / 第 7 格），
   再深一次就分不出来。教程库改走「白纸 + 横排书线 + 装订边」：
   手册本来就是纸，这个意象比任何科技纹路都贴题；
   于是七块内容各有各的纸面：产品库浅蓝网格、福利库深色同心环、教程库白色书页。

   列表按产品分组（.tut-grp）。分组这一层不是装饰 —— 这个库的检索方式就是
   「先找产品、再看这个产品有哪几篇」，齐平铺成一片卡片会把这条路径抹掉。
   ============================================================ */

/* 组间距比卡片间距大一档：同组内的卡片是「兄弟」，组与组是「章节」，
   间距必须能读出这条差别，否则滚下来只是「三排卡片」 */
.tut-groups{display:flex;flex-direction:column;gap:26px}
.tut-grp{display:flex;flex-direction:column;gap:12px}
.tut-grp-h{display:flex;align-items:baseline;gap:10px;padding-bottom:10px;border-bottom:1px solid var(--line)}
.tut-grp-h h2{
  font-size:16px;font-weight:800;letter-spacing:-.3px;min-width:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
/* 产品名前面那一小段身份色短横：一眼看出这一组的归属。
   比给整组套一个色块克制得多，也不会跟卡片顶边那条 3px 线打架 */
.tut-grp-h h2::before{
  content:'';display:inline-block;width:4px;height:15px;border-radius:2px;
  background:var(--grad);margin-right:9px;vertical-align:-2px;
}
.tut-grp-n{margin-left:auto;font-size:12px;font-weight:700;color:var(--txt-4);white-space:nowrap}

/* 教程库走「手册目录」，不走卡片网格：
   手册是按顺序读的，网格里每张卡都在抢视线，反而看不出该先读哪篇；
   目录行把「第几篇 / 讲什么 / 多少步」压成一行，一组能一眼扫完。
   所以这里覆盖掉 .grid 的 auto-fill 多列，改回单列列表 */
#tutFeed{align-items:stretch}
.tut-grid{display:flex;flex-direction:column;gap:8px}

.tut-row{
  display:grid;grid-template-columns:auto auto minmax(0,1fr) auto;
  gap:12px;align-items:center;width:100%;text-align:left;cursor:pointer;
  /* 整行是 <button>：不继承的话字体会掉回浏览器默认的按钮字体 */
  font-family:inherit;color:var(--txt);
  padding:12px 15px;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-md);
  transition:border-color .16s ease,background .16s ease,box-shadow .16s ease;
}
.tut-row:hover{border-color:var(--acc-ring);background:var(--acc-soft);box-shadow:var(--sh-1)}
/* 篇序：目录里「第几篇」本身就是导航，比图标更该被看见 */
.tut-no{
  font-size:16px;font-weight:900;line-height:1;color:var(--txt-4);
  font-variant-numeric:tabular-nums;
}
.tut-row:hover .tut-no{color:var(--acc)}
.tut-ico{
  flex:0 0 auto;width:30px;height:30px;border-radius:9px;display:grid;place-items:center;
  background:var(--acc-soft);color:var(--acc-d);border:1px solid var(--acc-line);
}
.tut-ico svg{width:16px;height:16px}
.tut-main{min-width:0;display:flex;flex-direction:column;gap:3px}
/* 标题单行截断、摘要单行截断：目录行要能一屏扫十条，
   任由标题折两行，一组目录就变成长短不一的段落块 */
.tut-main > b{
  font-size:15.5px;font-weight:800;line-height:1.5;letter-spacing:-.2px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.tut-main > em{
  font-style:normal;font-size:13px;color:var(--txt-3);line-height:1.6;
  display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;
}
.tut-metas{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:2px}
/* 难度色标和置顶章自带配色，别被上面这条通用元信息色冲掉 */
.tut-metas > span:not(.tut-lv):not(.tut-tag-top){font-size:12px;font-weight:600;color:var(--txt-4)}
.tut-tag-top{
  font-size:11px;font-weight:800;color:var(--acc-d);
  background:var(--acc-soft);border:1px solid var(--acc-line);
  border-radius:999px;padding:1px 7px;
}
.tut-go{
  flex:0 0 auto;display:flex;align-items:center;gap:6px;
  font-size:12px;color:var(--txt-4);white-space:nowrap;
}
.tut-go svg{width:14px;height:14px;color:var(--acc)}
/* 窄屏：图标和「N 次查阅」先让位，保证标题不被挤没 */
@media (max-width:560px){
  .tut-row{grid-template-columns:auto minmax(0,1fr) auto;gap:10px;padding:11px 12px}
  .tut-ico{display:none}
  .tut-go > span{display:none}}

/* ---------------- 手册卡片 ---------------- */
.tut{
  position:relative;display:flex;flex-direction:column;overflow:hidden;
  background:var(--solid);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--sh-1);cursor:pointer;
  transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
/* 悬停浮出的顶部 3px 身份色细边：做法与工具卡 / 产品卡 / 福利卡完全一致 */
.tut::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  border-radius:calc(var(--r-lg) - 1px);
  background-image:var(--grad);
  background-size:100% 3px;background-repeat:no-repeat;
  opacity:0;transition:opacity .22s ease;
}
.tut:hover::after{opacity:1}
.tut:hover{transform:translateY(-2px);box-shadow:var(--sh-2);border-color:var(--line-3)}

/* 封面：白纸 + 横排书线。
   ::before 是书线（repeating-linear-gradient 每 22px 一条，右侧渐隐，
   免得线一直顶到卡边显得像表格）；::after 是左侧那道装订边。
   ⚠️ 纸面用近白（#fff → #F4F7FB）而不是纯白：--bg 是 #f8fafc，
   纯白贴上去几乎看不出边界，卡片会散框。 */
.tut-thumb{
  position:relative;aspect-ratio:16/10;overflow:hidden;
  display:grid;place-items:center;
  background:linear-gradient(168deg,var(--solid) 0%,var(--solid-2) 100%);
  border-bottom:1px solid var(--acc-line);
}
.tut-thumb::before{
  content:'';position:absolute;inset:0;
  background-image:repeating-linear-gradient(to bottom,
    var(--acc-line) 0 1px,rgba(0,0,0,0) 1px 22px);
  -webkit-mask-image:radial-gradient(118% 96% at 20% 0%,#000 0%,rgba(0,0,0,.32) 60%,rgba(0,0,0,0) 92%);
  mask-image:radial-gradient(118% 96% at 20% 0%,#000 0%,rgba(0,0,0,.32) 60%,rgba(0,0,0,0) 92%);
}
.tut-thumb::after{
  content:'';position:absolute;left:26px;top:0;bottom:0;width:1px;
  background:linear-gradient(to bottom,transparent,var(--acc-ring) 16%,var(--acc-ring) 84%,transparent);
  opacity:.55;
}
.tut-thumb:not(.bare)::before,.tut-thumb:not(.bare)::after{content:none}
.tut-thumb img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transform:translateZ(0);will-change:transform;transition:transform .42s var(--ease);
}
.tut:hover .tut-thumb img{transform:translateZ(0) scale(1.04)}
/* 无封面时那枚线框类型图标，压在纸面正中 */
.tut-wire{position:relative;z-index:1;width:30%;max-width:72px;color:var(--acc);opacity:.5}

/* 类型胶囊压在左上（白底 + 身份色文字，同 .wel-cat 的克制程度），
   置顶胶囊压在右上，对角错开不打架 */
.tut-type{
  position:absolute;left:10px;top:10px;z-index:2;
  display:inline-flex;align-items:center;gap:5px;
  font-size:11px;font-weight:800;letter-spacing:.2px;
  padding:3px 9px;border-radius:999px;white-space:nowrap;
  background:rgba(255,255,255,.95);color:var(--acc-d);
  border:1px solid var(--acc-line);
}
.tut-type svg{width:13px;height:13px;flex:0 0 auto}
.tut-flag{
  position:absolute;right:10px;top:10px;z-index:2;
  font-size:11px;font-weight:800;letter-spacing:.2px;
  padding:3px 10px;border-radius:999px;white-space:nowrap;
  background:var(--grad);color:var(--on-acc);
  box-shadow:0 2px 8px -3px var(--acc-glow);
}

.tut-body{padding:14px 16px 15px;display:flex;flex-direction:column;flex:1;min-width:0}
.tut .card-text{
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  color:var(--txt-3);
}
/* 元信息一行：难度徽章 + 版本 + 用时 + 几步几图。
   margin-top:auto 与福利卡同理 —— 摘要 1 行的和 2 行的卡片这一行要一起贴底，
   否则一行看过去是锯齿 */
.tut-metas{
  display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;
  margin-top:auto;padding-top:11px;
  font-size:12px;font-weight:600;color:var(--txt-3);
}
.tut-lv{
  font-style:normal;font-size:11.5px;font-weight:800;letter-spacing:.2px;
  padding:2px 9px;border-radius:999px;
  background:var(--acc-soft);color:var(--acc-d);border:1px solid var(--acc-line);
}
/* 三档难度三级浓度：入门最淡、资深最实 —— 不用读字，扫一眼就知道深浅 */
.tut-lv[data-lv="mid"]{background:var(--acc-line);border-color:var(--acc-ring)}
.tut-lv[data-lv="pro"]{background:var(--grad);color:var(--on-acc);border-color:transparent}
.tut-foot{padding-top:12px}
.tut-heat{
  flex:1;min-width:0;font-size:12px;font-weight:700;color:var(--txt-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
/* 「查看手册」不参与等分，和别处那个 104px 的按钮一个规格 */
.tut .tut-foot .btn{flex:0 0 auto;min-width:104px;white-space:nowrap}

/* ---------------- 教程详情页 ----------------
   与福利详情同一套窄柱（--page），不碰产品详情那条通栏大页。
   差别全在正文：福利详情是「条款式」（对照表 + 短步骤），
   教程详情是「说明书式」—— 大号两位段号 + 长正文 + 行内配图。 */
.tw{display:flex;flex-direction:column;gap:14px}
.tw-hero{
  position:relative;overflow:hidden;
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--sh-1);padding:18px;
}
.tw-back{
  display:inline-flex;align-items:center;gap:5px;
  border:1px solid var(--line-2);border-radius:10px;background:var(--solid);
  padding:6px 12px;font-size:12.5px;font-weight:700;color:var(--txt-2);cursor:pointer;
  transition:border-color .16s ease,color .16s ease,transform .16s ease;
}
.tw-back:hover{border-color:var(--acc);color:var(--acc);transform:translateY(-1px)}
.tw-back svg{width:14px;height:14px;flex:0 0 auto}
/* 首屏：手机上下堆叠（封面在上、文在下）；PC 才左右分栏 */
.tw-hero-grid{display:grid;grid-template-columns:1fr;gap:16px;margin-top:14px}
.tw-badges{display:flex;flex-wrap:wrap;align-items:center;gap:7px}
.tw-type{
  display:inline-flex;align-items:center;gap:6px;
  font-size:11.5px;font-weight:800;letter-spacing:.3px;
  color:var(--acc-d);background:var(--grad-soft);
  border:1px solid var(--acc-line);border-radius:999px;padding:4px 11px;
}
.tw-type svg{width:14px;height:14px;flex:0 0 auto}
.tw-prodchip{
  display:inline-flex;align-items:center;
  font-size:11.5px;font-weight:800;
  color:var(--txt-2);background:var(--solid-2);
  border:1px solid var(--line-2);border-radius:999px;padding:4px 11px;
}
.tw-flag{
  font-size:11.5px;font-weight:800;color:#fff;
  background:var(--grad);border-radius:999px;padding:4px 11px;
}
.tw-name{font-size:23px;font-weight:900;letter-spacing:-.5px;margin:11px 0 0;line-height:1.3;word-break:break-word}
.tw-summary{margin:11px 0 0;font-size:15px;line-height:1.9;color:var(--txt-2)}

/* 五个数排成一条分格，而不是一串 tag ——
   步骤 / 难度 / 版本 / 用时 / 查阅在「要不要现在照着做」这件事上是并列权重，
   排成一行小字会被当成备注跳过。
   auto-fit 而不是写死五列：窄屏自动折成两行，不用另写断点 */
.tw-stats{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(74px,1fr));
  gap:1px;margin-top:16px;overflow:hidden;
  background:var(--line);border:1px solid var(--line);border-radius:var(--r-md);
}
.tw-stats div{background:var(--surface);padding:10px 10px;text-align:center;min-width:0}
.tw-stats b{
  display:block;font-size:16px;font-weight:900;letter-spacing:-.3px;
  color:var(--acc-d);font-variant-numeric:tabular-nums;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.tw-stats span{display:block;font-size:11px;font-weight:700;color:var(--txt-4);margin-top:2px}
.tw-acts{display:flex;gap:10px;flex-wrap:wrap;margin-top:16px}

/* 首屏右侧：封面 + 整册附件卡。无封面时是「白纸 + 书线」，
   和卡片封面同一个图形语言（.tut-thumb 那套在这里放大一档复用） */
.tw-cover{
  position:relative;aspect-ratio:16/10;overflow:hidden;
  display:grid;place-items:center;border-radius:var(--r-md);
  background:linear-gradient(168deg,var(--solid) 0%,var(--solid-2) 100%);
  border:1px solid var(--acc-line);
}
.tw-cover::before{
  content:'';position:absolute;inset:0;
  background-image:repeating-linear-gradient(to bottom,
    var(--acc-line) 0 1px,rgba(0,0,0,0) 1px 26px);
  -webkit-mask-image:radial-gradient(118% 96% at 20% 0%,#000 0%,rgba(0,0,0,.32) 60%,rgba(0,0,0,0) 92%);
  mask-image:radial-gradient(118% 96% at 20% 0%,#000 0%,rgba(0,0,0,.32) 60%,rgba(0,0,0,0) 92%);
}
.tw-cover::after{
  content:'';position:absolute;left:34px;top:0;bottom:0;width:1px;
  background:linear-gradient(to bottom,transparent,var(--acc-ring) 16%,var(--acc-ring) 84%,transparent);
  opacity:.55;
}
.tw-cover:not(.bare)::before,.tw-cover:not(.bare)::after{content:none}
.tw-cover img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:inherit}
.tw-wire{position:relative;z-index:1;width:26%;max-width:96px;color:var(--acc);opacity:.5}

/* 整册附件卡：让「这篇有 PDF」在首屏就看得见 —— 否则用户滚完一屏步骤，
   才在底部条上发现有整册，白滚一遍 */
.tw-file{
  display:flex;align-items:center;gap:10px;margin-top:12px;
  padding:11px 13px;border-radius:var(--r-md);
  background:var(--grad-soft);border:1px solid var(--acc-line);
}
.tw-file-ico{
  flex:0 0 auto;width:34px;height:34px;border-radius:10px;
  display:grid;place-items:center;background:var(--solid);color:var(--acc);
  border:1px solid var(--acc-line);
}
.tw-file-ico svg{width:17px;height:17px;display:block}
.tw-file-b{flex:1;min-width:0}
.tw-file-b b{
  display:block;font-size:12.5px;font-weight:800;color:var(--txt);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.tw-file-b em{display:block;font-style:normal;font-size:11px;font-weight:700;color:var(--acc-d);margin-top:2px}

/* ---------------- 正文各段 ---------------- */
.tw-secs{display:flex;flex-direction:column;gap:14px}
.tw-sec{
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--sh-1);padding:16px 18px;
}
.tw-h{display:flex;align-items:center;gap:10px;margin-bottom:14px}
/* 两位段号做成有底的方块，而不是福利库那种纯文字 ——
   这个库通篇在讲「顺序」，段号本身就是导航，得比纯文字重一档 */
.tw-h .n{
  flex:0 0 auto;display:grid;place-items:center;
  min-width:30px;height:26px;padding:0 7px;border-radius:8px;
  background:var(--grad);color:var(--on-acc);
  font-size:12.5px;font-weight:900;letter-spacing:.2px;font-variant-numeric:tabular-nums;
  box-shadow:0 4px 10px -6px var(--acc-glow);
}
.tw-h b{font-size:15.5px;font-weight:800;letter-spacing:-.2px;min-width:0}
.tw-h em{margin-left:auto;font-style:normal;font-size:12px;color:var(--txt-4);white-space:nowrap}

/* 操作步骤：用 ol 但不用浏览器默认序号（字号与位置都控不住），
   自己排「大号两位数字 + 正文」两列。
   数字与正文之间那条竖线是「流程感」的来源 —— 少了它，第一步和第五步
   在视觉上只是一个列表，读不出「先做这个、再做那个」 */
.tw-steps{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.tw-step{display:grid;grid-template-columns:auto minmax(0,1fr);gap:13px}
.tw-n{
  position:relative;width:40px;padding-top:1px;text-align:center;
  font-size:21px;font-weight:900;letter-spacing:-.6px;line-height:1.3;
  color:var(--acc);font-variant-numeric:tabular-nums;
}
/* 连线从数字下沿一直拉到本行末尾；最后一行收掉（否则尾巴会翘在半空） */
.tw-n::after{
  content:'';position:absolute;left:50%;top:31px;bottom:0;width:1px;
  background:var(--acc-line);transform:translateX(-50%);
}
.tw-step:last-child .tw-n::after{content:none}
.tw-b{padding-bottom:30px;min-width:0}
.tw-step:last-child .tw-b{padding-bottom:0}
/* 手册正文：标题 16 / 正文 15.5，比卡片时代的 14 / 13 抬一档。
   步骤里既有点哪儿、又有为什么，字太小代理只会扫标题、跳过说明 */
.tw-b > b{display:block;font-size:16px;font-weight:800;line-height:1.7;letter-spacing:-.2px}
/* pre-line：后台「这一步怎么做」是个多行输入框，换行是运营敲的，
   必须照原样折行。段落间距交给 line-height，不再另加 margin */
.tw-b p{margin:6px 0 0;font-size:15.5px;color:var(--txt-2);line-height:1.95;white-space:pre-line}

/* 步骤配图：点开走灯箱。
   这里**不再**定死 16:10 —— 后台截图的比例从 1.9:1 到 3:1 都有，
   定高 + cover 会把图的下半截（往往是提交按钮、操作结果）直接切掉，
   代理照着做却看不到点哪儿。现在一律按原比例完整显示，
   要看清界面里的字，走灯箱的「原图 1:1」。 */
/* 配图是「插图」不是「主图」：撑满整宽会把一步的文字挤成两行配一块大屏，
   图和字谁都不像主角。限到 520px 居中，视觉重量落回正文；
   要看界面细节走灯箱的放大和「原图 1:1」 */
.tw-shot{
  position:relative;display:block;width:100%;max-width:520px;
  margin:13px auto 0;padding:0;
  overflow:hidden;cursor:zoom-in;line-height:0;
  border:1px solid var(--line-2);border-radius:var(--r-md);background:var(--solid-2);
}
/* <figure> 自带 40px 外边距，会把图和正文撑开一道空档 */
.tw-fig{margin:0}
/* 图注跟着图一起居中、同宽，不然图缩窄后注释还贴着左边 */
.tw-cap{
  display:block;max-width:520px;margin:7px auto 0;
  font-size:12.5px;color:var(--txt-4);line-height:1.65;text-align:center;
}
.tw-shot img{
  display:block;width:100%;height:auto;object-fit:contain;object-position:top center;
  transition:transform .42s var(--ease);
}
.tw-shot:hover img{transform:scale(1.03)}
.tw-zoom{
  position:absolute;right:8px;bottom:8px;
  display:inline-flex;align-items:center;gap:4px;
  font-size:11px;font-weight:800;padding:3px 9px;border-radius:999px;
  background:rgba(255,255,255,.94);color:var(--acc-d);border:1px solid var(--acc-line);
}
.tw-zoom svg{width:12px;height:12px;flex:0 0 auto}
/* 提示行：左边一条身份色竖线 + 淡底，而不是压成灰底小字 ——
   一整步里「提示」常常是最关键的一句，越不起眼越会被跳过 */
.tw-tip{
  display:block;margin-top:10px;padding:8px 12px;
  border-left:3px solid var(--acc);border-radius:0 var(--r-sm) var(--r-sm) 0;
  background:var(--acc-soft);
  font-size:14.5px;color:var(--txt-2);line-height:1.82;
}
.tw-tip i{font-style:normal;font-weight:900;color:var(--acc-d);margin-right:7px;letter-spacing:.3px}
.tw-none{margin:0;font-size:15px;color:var(--txt-3);line-height:1.85}

/* 常见问题：与福利详情同一套（原生 <details>，默认全收起） */
.tw-faqs{display:grid;gap:8px}
.tw-faq{border:1px solid var(--line-2);border-radius:var(--r-md);background:var(--solid-2);overflow:hidden}
.tw-faq summary{
  list-style:none;cursor:pointer;padding:12px 14px;
  font-size:15px;font-weight:700;color:var(--txt);
  display:flex;align-items:flex-start;gap:9px;line-height:1.7;
}
.tw-faq summary::-webkit-details-marker{display:none}
.tw-faq summary::after{
  content:'＋';margin-left:auto;font-size:14px;font-weight:800;color:var(--acc);flex:0 0 auto;
}
.tw-faq[open] summary::after{content:'－'}
.tw-faq summary:hover{color:var(--acc-d)}
.tw-faq p{margin:0;padding:0 14px 14px;font-size:15px;color:var(--txt-2);line-height:1.9}

/* 同产品的其它手册：左侧类型胶囊 / 中间标题 / 右侧规模 / 最右箭头 */
.tw-more{display:grid;gap:8px}
.tw-more-row{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;
  align-items:center;gap:12px;width:100%;text-align:left;
  padding:11px 13px;cursor:pointer;
  background:var(--solid);border:1px solid var(--line-2);border-radius:var(--r-md);
  transition:border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease),transform var(--dur-fast) var(--ease);
}
.tw-more-row:hover{border-color:var(--acc-line);background:var(--grad-soft);transform:translateX(2px)}
.tw-more-ty{
  display:inline-flex;align-items:center;gap:5px;flex:0 0 auto;
  font-size:11px;font-weight:800;color:var(--acc-d);
  background:var(--acc-soft);border:1px solid var(--acc-line);
  border-radius:999px;padding:3px 9px;white-space:nowrap;
}
.tw-more-ty svg{width:12px;height:12px;flex:0 0 auto}
.tw-more-row > b{
  min-width:0;font-size:13.5px;font-weight:800;color:var(--txt);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.tw-more-m{font-size:11.5px;font-weight:700;color:var(--txt-4);white-space:nowrap}
/* 只有直接子级那枚箭头会被选中（类型胶囊里那枚是后代，不是子级） */
.tw-more-row > svg{width:15px;height:15px;flex:0 0 auto;color:var(--txt-4)}
.tw-more-row:hover > svg{color:var(--acc)}

/* 所属产品卡：整张可点，跳到产品详情 */
.tw-prodcard{
  display:flex;align-items:center;gap:13px;width:100%;text-align:left;
  padding:13px 14px;cursor:pointer;
  background:var(--solid);border:1px solid var(--line-2);border-radius:var(--r-md);
  transition:border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease),transform var(--dur-fast) var(--ease);
}
.tw-prodcard:hover{border-color:var(--acc-line);background:var(--grad-soft);transform:translateY(-1px)}
.tw-pdc-ico{
  flex:0 0 auto;width:46px;height:46px;border-radius:13px;overflow:hidden;
  display:grid;place-items:center;
  background:var(--grad-soft);border:1px solid var(--acc-line);color:var(--acc);
}
.tw-pdc-ico img{width:100%;height:100%;object-fit:cover}
.tw-pdc-ico svg{width:22px;height:22px;display:block}
.tw-pdc-b{flex:1;min-width:0}
.tw-pdc-b b{display:block;font-size:14px;font-weight:800;color:var(--txt)}
.tw-pdc-b em{
  font-style:normal;font-size:12.5px;color:var(--txt-2);line-height:1.65;margin-top:3px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.tw-pdc-go{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:5px;
  font-size:12.5px;font-weight:800;color:var(--acc-d);white-space:nowrap;
}
.tw-pdc-go svg{width:15px;height:15px;flex:0 0 auto}

/* 底部动作条：与福利详情同一套（sticky 在视口底，手机端再抬一档底栏高度）。
   步骤一多正文会很长，滚到第 3 步想找整册附件时没有它就还得一路划回去 */
/* .tw-bar 已移除（教程库详情页底部浮动条，2026-09-27） */

/* PC：首屏左右分栏；正文区更松的内边距 */
@media (min-width:1024px){
  .tw-hero{padding:22px 24px}
  .tw-sec{padding:20px 22px}
  /* align-items:start 而不是 center：正文一长，封面居中会让左边文字
     和右边封面错开一大截，读起来像两栏无关的内容 */
  .tw-hero-grid{grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:26px;align-items:start}
  .tw-name{font-size:27px}}

/* 小屏：卡片与区块都缩一档，内边距收窄 */
@media (max-width:640px){
  .tut-groups{gap:22px}
  .tut-grp-h h2{font-size:15px}
  .tut-body{padding:12px 14px 13px}
  .tut-type,.tut-flag{font-size:10.5px;padding:2px 8px;left:8px;top:8px}
  .tut-flag{left:auto;right:8px}
  .tut-thumb::after,.tw-cover::after{left:20px}
  .tw-hero,.tw-sec{padding:14px;border-radius:16px}
  .tw-name{font-size:21px;margin-top:9px}
  .tw-h b{font-size:14.5px}
  .tw-h em{display:none}
  .tw-h .n{min-width:27px;height:24px;font-size:11.5px}
  .tw-stats{grid-template-columns:repeat(3,minmax(0,1fr))}
  .tw-n{width:28px;font-size:15px}
  .tw-step{gap:10px}
  .tw-b{padding-bottom:16px}
  /* 手机上两枚按钮各占一半：单枚按钮缩到左边半截会很难点 */
  .tw-acts .btn{flex:1 1 auto;justify-content:center}
  .tw-more-row{grid-template-columns:minmax(0,1fr) auto auto;gap:9px}
  .tw-more-ty{display:none}
}

/* ============================================================
   教程库 · 后台（第 7 个 Tab）
   ------------------------------------------------------------
   只有两个部件是后台专有的：
     · 列表的「类型 / 操作步骤」列 —— 一格里两层（类型徽章 + 几步骤几问），
       和福利库那列「可享等级 + 谁都能享」是同一个排法；
     · 步骤卡 .rep-row.tstep —— 全站唯一需要**行内配图**的重复行，
       2026-09-24 起做成「一步一张卡」（卡头常驻 + 卡体可收起）。

   .tstep 不复用 .rep-row 的三格骨架（a b x）。它现在是 block 布局的卡片：
   卡头 flex（折叠箭头 / 序号 / 标题 / 动作），卡体 grid（说明框 + 配图）。
   ⚠️ 选择器必须带 .rep-row 前缀 —— 单独写 .tstep 会连容器一起命中
   （容器曾挂这个类，align-items:start 把卡片压回 355px），见下面那段注释。
   ============================================================ */
.lt-tutorials{--ltc:minmax(0,1fr) 132px 150px 88px max-content}
.lt-tutorials .mat-ico{font-size:22px;line-height:1}
/* 「未关联」是一种状态，不是一个分类 —— 用淡色跟真分类名区分开 */
.lt-tutorials .cat-chip.muted{color:var(--txt-4);background:var(--solid-2);border-color:var(--line-2)}

/* ⚠️ 选择器一律写 .rep-row.tstep，不要写成 .tstep：
   #repTuSteps 这个**容器**以前也挂着 tstep，上面那条 align-items:start
   会把每一张卡压回内容宽度 —— 实测 840px 的弹框里卡片只用上 355px，
   说明框塌到 181×62。类名已经从容器上摘掉，选择器也收紧，双重保险。 */
.rep-row.tstep{
  display:block;padding:9px 11px;
  border:1px solid var(--line-2);border-radius:var(--r-lg);background:var(--solid);
}
/* 卡头常驻：收起卡体之后，哪一步叫什么仍然一眼看得见 */
.rep-row.tstep .ts-hd{display:flex;align-items:center;gap:8px;min-width:0}
.rep-row.tstep .ts-fold{
  flex:none;width:22px;height:22px;padding:0;cursor:pointer;
  border:1px solid var(--line-2);border-radius:7px;background:var(--solid);color:var(--txt-3);
  display:grid;place-items:center;
  transition:color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease);
}
.rep-row.tstep .ts-fold:hover{color:var(--acc);border-color:var(--acc);background:var(--acc-soft)}
.rep-row.tstep .ts-fold svg{width:9px;height:9px;display:block;transition:transform var(--dur-fast) var(--ease)}
.rep-row.tstep.fold .ts-fold svg{transform:rotate(-90deg)}
.rep-row.tstep .ts-n{
  flex:none;font-size:12px;font-weight:800;color:var(--txt-4);
  font-variant-numeric:tabular-nums;letter-spacing:.4px;
}
.rep-row.tstep .ts-hd .r-a{flex:1 1 auto;min-width:0}
.rep-row.tstep .ts-acts{flex:none;display:flex;align-items:center;gap:4px}
.rep-row.tstep .ts-act svg{width:11px;height:11px;display:block;margin:0 auto}
/* 卡里那颗删除按钮跟旁边三颗动作键同规格（.rep-del 默认是 32px，在这儿偏大） */
.rep-row.tstep .rep-del{width:26px;height:26px;font-size:12px;flex:none}
/* 步骤卡之间的间距比普通重复行松一档：它是卡片，不是一行表格 */
.rep-steps{gap:10px}
/* 「＋ 加一步」与「全部收起」并排 */
.rep-acts{display:flex;align-items:center;gap:8px;margin-top:8px}
.rep-row.tstep .ts-act{
  width:26px;height:26px;padding:0;cursor:pointer;
  border:1px solid var(--line-2);border-radius:8px;background:var(--solid);color:var(--txt-3);
  font-size:12px;line-height:1;
  transition:color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease);
}
.rep-row.tstep .ts-act:hover{color:var(--acc);border-color:var(--acc);background:var(--acc-soft)}
/* 到头了那两个箭头要显式不可用，不能是「点了没反应」 */
.rep-row.tstep .ts-act:disabled{opacity:.32;cursor:default}
.rep-row.tstep .ts-act:disabled:hover{color:var(--txt-3);border-color:var(--line-2);background:var(--solid)}
/* 收起后补一句摘要：不然「内容还在不在」只能点开才知道 */
.rep-row.tstep .ts-sum{display:none}
.rep-row.tstep.fold .ts-sum{
  display:block;margin-top:6px;font-size:12px;color:var(--txt-4);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* 卡体：说明框吃满余量，配图靠右 */
.rep-row.tstep .ts-bd{
  display:grid;grid-template-columns:minmax(0,1fr) 124px;gap:10px;
  margin-top:9px;align-items:start;
}
.rep-row.tstep .ts-bd-l{display:grid;gap:7px;min-width:0}
.rep-row.tstep.fold .ts-bd{display:none}

.rep-row.tstep .ts-img{
  width:124px;height:94px;padding:0;cursor:pointer;
  border:1px dashed var(--line-3);border-radius:var(--r-md);
  background:var(--solid-2);color:var(--txt-4);
  font-size:12px;font-weight:700;line-height:1;
  display:grid;place-items:center;overflow:hidden;
  transition:border-color var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease);
}
.rep-row.tstep .ts-img:hover{border-color:var(--acc);color:var(--acc);background:var(--acc-soft)}
/* 已经有图时换成实线边、白底 —— 空位和已填位一眼分得开 */
.rep-row.tstep .ts-img.has{border-style:solid;border-color:var(--line-2);background:var(--solid)}
.rep-row.tstep .ts-img img{width:100%;height:100%;object-fit:cover;display:block}

/* 这一步说明是 300 字的 textarea，基础样式只覆盖了 input / select，这里补齐。
   默认 4 行（老样子是 2 行 / 56px —— 300 字在里面要滚好几屏，
   运营宁可去 Word 里写好再贴回来）。纵向可拉：想再高可以自己拉。 */
.rep-row.tstep textarea{
  width:100%;min-width:0;resize:vertical;min-height:92px;
  border:1px solid var(--line-2);border-radius:var(--r-md);
  background:var(--solid);padding:9px 12px;font-size:13.5px;color:var(--txt);
  font-family:inherit;line-height:1.55;
  transition:border-color var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease);
}
.rep-row.tstep textarea::placeholder{color:var(--txt-4)}
.rep-row.tstep textarea:focus,.rep-row.tstep textarea:focus-visible{
  border-color:var(--acc);box-shadow:0 0 0 4px var(--acc-soft);outline:none;
}
/* 那一栏提醒小字比正文轻一档，视觉上不当正文读 */
.rep-row.tstep .r-c{font-size:12.5px}
/* 卡片里不再有 .rep-row 那套 a / b 区域，内部一律回到自动流 */
.rep-row.tstep .ts-hd .r-a,.rep-row.tstep .ts-bd-l .r-b,.rep-row.tstep .ts-bd-l .r-c{grid-area:auto}

@media (max-width:640px){
  .lt-tutorials .list-row{display:flex;flex-wrap:wrap;gap:10px;padding:13px 14px}
  /* 手机上配图不再并排：说明框本来就不宽，再让出 124px 就只剩一条缝了 */
  .rep-row.tstep .ts-bd{grid-template-columns:minmax(0,1fr)}
  .rep-row.tstep .ts-img{width:100%;height:150px}
  .rep-row.tstep .ts-hd{flex-wrap:wrap}
  .rep-row.tstep .ts-hd .r-a{flex:1 1 60%}}

/* ============================================================
   交付库 · 后台（第 8 个 Tab）
   ------------------------------------------------------------
   列表那五列与教程库同宽（第一列吃掉余量、后面四列定宽），
   所以 .lt-deliveries 直接沿用 .lt-tutorials 的列宽表 —— 两库同构，
   并排放在两个 Tab 里来回切时列不会跳。

   表单侧的四种重复行都长在同一个骨架上：
     .dr-main 是纵向的一组输入（每行两三个字段）
     .rep-del 固定在最右一列
   inds 那行最宽（六栏），所以它单独有一条 .dind：
   第一排两个下拉/输入并排，下面四排各占一行。
   ============================================================ */
.lt-deliveries{--ltc:minmax(0,1fr) 132px 150px 88px max-content}
.lt-deliveries .mat-ico{font-size:19px;line-height:1;font-weight:800;color:var(--txt-3)}
.lt-deliveries .cat-chip.muted{color:var(--txt-4);background:var(--solid-2);border-color:var(--line-2)}
/* 行业徽章在列表里是「密集并列」的，比默认 chip 收一档内距 —— 一行摆三枚不换行 */
.lt-deliveries .lt-cell .cat-chip{padding:2px 7px;font-size:11px;margin:0 4px 2px 0}

/* 四种行共用的骨架。区域名沿用 .rep-row 那套（a b x），
   但把 b 的位置换成 .dr-main 一整块 —— 里面每行都是自动流，不再吃网格区域 */
.dind,.dqa,.dtalk,.dstep{
  grid-template-columns:minmax(0,1fr) 32px;
  grid-template-areas:"m x";
  align-items:start;
  gap:10px;
}
.dind .dr-main,.dqa .dr-main,.dtalk .dr-main,.dstep .dr-main{
  grid-area:m;display:grid;gap:6px;min-width:0;
}
.dind .rep-del,.dqa .rep-del,.dtalk .rep-del,.dstep .rep-del{margin-top:2px}

/* 行内那些输入：基础样式只覆盖了 .rep-row input / select，
   textarea 与 select 的焦点态要在这里补齐 */
.dind input,.dind select,.dind textarea,
.dqa input,.dqa textarea,.dtalk input,.dtalk textarea,.dstep input,.dstep textarea{
  width:100%;min-width:0;
  border:1px solid var(--line-2);border-radius:var(--r-md);
  /* ⚠️ select 不能用 background 简写（会重置箭头图/no-repeat/position，
     深色皮肤下箭头平铺满框）—— 同 .rep-row select 那条注释 */
  background-color:var(--solid);padding:9px 12px;font-size:13.5px;color:var(--txt);
  font-family:inherit;line-height:1.55;
  transition:border-color var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease);
}
.dind textarea,.dqa textarea,.dtalk textarea,.dstep textarea{resize:vertical;min-height:52px}
.dind input::placeholder,.dind textarea::placeholder,
.dqa input::placeholder,.dqa textarea::placeholder,
.dtalk input::placeholder,.dtalk textarea::placeholder,
.dstep input::placeholder,.dstep textarea::placeholder{color:var(--txt-4)}
.dind input:focus,.dind select:focus,.dind textarea:focus,
.dqa input:focus,.dqa textarea:focus,
.dtalk input:focus,.dtalk textarea:focus,
.dstep input:focus,.dstep textarea:focus{
  border-color:var(--acc);box-shadow:0 0 0 4px var(--acc-soft);outline:none;
}

/* 适用客户那行的第一排：一级下拉 + 二级自由文本并排。
   一级给固定一点（下拉里是 33 个名字，太窄会全被截成「安全消防…」），
   二级吃掉剩下的 —— 它是「、」分隔的多个名字，越长越好写。
   这一行在后台编辑器里；对用户叫「适用客户」，数据仍按行业口径存（一级行业名）。
   类名 .dind 是 delivery-industry 的老名字，保留不改（改它要动 admin.js 与套件） */
.dind .dr-2{display:grid;grid-template-columns:minmax(0,190px) minmax(0,1fr);gap:8px}
/* 这一块在后台是**全站最宽**的一行：一级 + 二级 + 结果 + 两段背景 + 三条「动作→结果」
   + 旧字段 fix + 可以这么说。所以正文那几段统一收一档字号，
   免得一行撑出一个半屏高。
   ⚠️ 2026-09-18 多了 gain（结果）与三条 acts。结果那栏走身份色字 ——
   它在后台是这一块唯一「这一段要说什么」的开关，值得比别的输入框显眼 */
.dind .r-who,.dind .r-pain{font-size:13px}
.dind .r-fix,.dind .r-line{font-size:13px}
.dind .r-gain{font-size:13px;font-weight:700;color:var(--acc-d)}
/* 「怎么做」三行：每行是「做什么 → 做完拿到什么」两栏 + 中间一枚箭头。
   箭头是纯排版（aria-hidden），不参与朗读 —— 它是给眼睛看的因果提示。
   两栏等宽（不用 190/1fr 那种）：这两栏的内容重量是一样的 */
.dind .dr-acts-h{
  margin-top:2px;font-size:11.5px;font-weight:800;letter-spacing:.3px;color:var(--txt-4);
}
.dind .dr-acts{display:grid;gap:6px}
.dind .dr-act{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);gap:8px;align-items:center}
.dind .act-arrow{font-size:13px;font-weight:900;color:var(--acc);line-height:1}
.dind .r-do,.dind .r-get{font-size:13px}

/* 供方那一块的第一排，和上面「适用客户」正好**反过来**：
   交付库是「190px 固定下拉 + 余量给自由文本」；这里供方名才是长的那一头
   （「华东 · 星禾传播」这种），城市只是一个短词。
   照抄 .dr-2 会把长度放反 —— 名字被截成省略号，城市白占半屏。
   ⚠️ 这条必须写在下面那个 @media 之前：手机端要用的
   `.dind .dr-2{grid-template-columns:minmax(0,1fr)}` 与它同权重，
   靠「后出现者胜」才压得住，写到媒体查询后面就失效了。 */
.dsup .dr-2{grid-template-columns:minmax(0,1fr) minmax(0,150px)}

/* 落地步骤的第一排：序号 + 标题。序号是 DOM 位置推出来的，加删后要重编 */
.dstep .dr-3{display:grid;grid-template-columns:30px minmax(0,1fr);gap:8px;align-items:center}
/* 提醒小字比正文轻一档，视觉上不当正文读（与教程库的 .tstep .r-c 同一条规矩） */
.dstep .r-c{font-size:12.5px}

@media (max-width:640px){
  .lt-deliveries .list-row{display:flex;flex-wrap:wrap;gap:10px;padding:13px 14px}
  /* 手机上这一块摆不下：一级与二级各占一行，正文各段照旧一行一段。
     三条「动作 → 结果」也收成一栏（两栏各 150px 时两边都只剩几个字） */
  .dind .dr-2{grid-template-columns:minmax(0,1fr)}
  .dind .dr-act{grid-template-columns:minmax(0,1fr)}
  .dind .act-arrow{display:none}
  /* 行末的删除键挪到右上角，正文独占整行 */
  .dind,.dqa,.dtalk,.dstep{
    display:flex;flex-wrap:wrap;align-items:flex-start;gap:8px;
    grid-template-columns:none;grid-template-areas:none;
  }
  .dind .dr-main,.dqa .dr-main,.dtalk .dr-main,.dstep .dr-main{flex:1 1 100%}
  .dind .rep-del,.dqa .rep-del,.dtalk .rep-del,.dstep .rep-del{
    flex:0 0 auto;margin:0 0 0 auto;align-self:flex-start;
  }}



/* ============================================================================
   案例库竖卡 · 窄屏降档与手机形态
   ----------------------------------------------------------------------------
   桌面那套（≥1024：一排四张、文字在上、截图居中、数据条收尾）写在上面 PC 断点里；
   这一节补三档，四段一起才是完整的列数阶梯：

     ≥1280     一排 4 张   ← 上面 PC 断点里那条
     1024~1279 一排 3 张   ← 本节的 @media
     600~1023  一排 2 张   ← 本节的 @media（平板）
     ≤599      一排 1 张   ← 本节末尾那条（手机）

   1024~1279 为什么退到 3 列：1200 宽下每张只剩 ~230，三个按钮（复制/保存/转发）
   再加两项指标会挤成两行，卡片反而变高 —— 少一列比挤一列好看。

   手机为什么从 2 列退回 1 列（2026-09-15 改）：
   这一档的内容宽是「视口 − 35，且不超过 721」，两列时每张卡只有（721 − 11）/ 2 = 355
   封顶，往下 390 只剩 172、320 只剩 137 —— 137 宽里连「成功促活客户」六个字都放不下，
   数据条被迫退成「一行一个 19px」，按钮被迫折成两行。单列之后卡宽 285~564，
   数据条和按钮都能回到和 PC / 平板同一套排法，两个特例一起撤掉了（见本节末尾）。

   ⚠️ 本节**故意放在整个文件的最后**，不是随手搁的：
      · 和上面 ≥1024 那块相比，选择器权重完全一样（.grid.wide 对 .grid.wide、
        .card-body.split 对 .card-body.split），全靠源码顺序取胜 ——
        挪到前面去，降档会静默失效，页面看着「没坏」，只是宽度不够时列数不对；
      · 更要命的是手机这条：PC 之后的几个 max-width 块里有 `.post,.case{padding:15px}`，
        和手机块的 `.case{padding:0}` 权重一样却排在后面，会把它悄悄盖掉 ——
        卡片留 15px 内边距，截图就通不到卡片两侧，一整排的观感全没了。
   ============================================================================ */
@media (min-width:1024px) and (max-width:1279px){
  .grid.wide{grid-template-columns:repeat(3,minmax(0,1fr))}}

@media (max-width:1023px){
  /* 手机上一排两张：案例截图接近正方形，缩到 170 出头还看得清；
     换成两张横卡的话图只剩 ~104px，还不如这样。 */
  .grid.wide{grid-template-columns:repeat(2,minmax(0,1fr));gap:11px}
  /* 竖卡的内边距由各信息块自己带（图要通到卡片两侧），卡片本身必须归零 */
  .case{padding:0}

  /* 基础层把 .card-media 设成 display:contents（图片按 DOM 顺序流动）。
     这里把它变回真容器：只有真容器才撑得起 3:2 的框、也才通得到卡片两侧。
     块序与 PC 完全一致 —— 标签 1、标题 2、正文 3、截图 4、数据 5、按钮 6
     （见上面 PC 那块的总述）。 */
  .case .card-body,
  .case .card-body.split{display:flex;flex-direction:column}
  .case .card-body > .card-media{
    display:block;order:4;position:relative;aspect-ratio:3/2;overflow:hidden;
    margin:auto 0 0;border:0;border-top:1px solid var(--line);
    border-radius:0;
    background:var(--solid-2);
  }
  .case .card-body > .card-media > .pics,
  .case .card-body > .card-media > .shots{display:block;position:absolute;inset:0;margin:0;height:auto}
  /* 与 PC 同一套：几张图叠起来，只有 .on 那张可见（理由见 PC 那块） */
  .case .card-body > .card-media img{
    display:block;position:absolute;inset:0;width:100%;height:100%;
    object-fit:cover;aspect-ratio:auto;border-radius:0;
    opacity:0;transition:opacity .22s ease;pointer-events:none;
  }
  .case .card-body > .card-media img.on{opacity:1}
  .case .card-body > .card-media[data-many]{cursor:pointer}
  .case .card-body > .card-media:not([data-many]){cursor:zoom-in}
  /* 手机这端同样放出来：图片在这里也是只露出一张，箭头是唯一看得见的「能翻」提示 */
  .case .card-body > .card-media[data-many] > .shot-nav{display:flex}
  .case .card-body > .card-top{order:1;padding:12px 12px 0;gap:4px}
  /* 「3 张截图」那枚标签全档都收着（PC 那条也在收）：右下角角标 +「保存截图 · 3」
     已经把张数说了两遍，同一件事不必喊第三遍。 */
  .case .card-body > .card-top .tag-media{display:none}
  .case .card-body .tag{font-size:10.5px;padding:3px 7px}
  .case .card-body > .card-title{order:2;margin:12px 12px 0;font-size:14px}
  .case .card-body > .card-text{
    order:3;margin:4px 12px 0;font-size:12.5px;line-height:1.62;
    min-height:calc(1.62em * 3);
    display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;
  }
  /* --- 数据条（1024 以下）-----------------------------------------------------
     卡宽从 277（600 视口的两列）到 563（599 视口的单列），最窄那一档每栏
     也有 ~126 宽 —— 24px 的「1,204位」只要 89。所以这儿能照 PC 那套排：
     两栏等分 + 竖分隔线 + 标签在上、数字在下。
     手机（≤599）改单列之前，320~599 还得开一条「一行一个、数字 19px」的后门；
     现在卡宽上来了，后门撤掉，整档只剩这一种排法。

     ⚠️ 皮（background / border）必须在这里再写一遍：PC 那条是
     `.card-body.split > .metrics`，1024 以下根本不匹配，而媒体查询之间不继承。
     ⚠️ `.metric` 的 display / background / border 同理 ——
     基础层那个 .metric 是「一格一张卡片」（有底色有边框、display 是默认的 block），
     不重写就会变成两行各套一个圆角框（这个坑刚踩过）。 */
  .case .card-body > .metrics{
    order:5;display:flex;margin:10px 12px 0;padding:0;border-radius:10px;
    background:var(--solid-2);border:1px solid var(--line);
    /* 兜底：万一以后两个数变长（比如「1,234万次」），宁可裁掉也不让它顶破卡片 */
    overflow:hidden;
  }
  .case .card-body > .metrics .metric{
    flex:1 1 0;min-width:0;
    display:flex;flex-direction:column;gap:1px;
    padding:9px 10px 10px;
    background:none;border:0;border-radius:0;
  }
  .case .card-body > .metrics .metric + .metric{border-left:1px solid var(--line)}
  .case .card-body > .metrics .metric i{
    font-size:10px;font-weight:700;color:var(--txt-3);letter-spacing:.2px;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
  /* 比 PC（26px）收一档：这一档最窄的卡是 600 视口的两列（277 宽），
     每栏只有 ~126；26px 的「1,204位」要 89，扣掉格子内边距就没呼吸了。 */
  .case .card-body > .metrics .metric b{font-size:24px;letter-spacing:-.6px}
  .case .card-body > .card-foot{order:8;margin:10px 0 0;padding:9px 12px 11px;gap:5px;flex-wrap:wrap}
  .case .card-body > .testi{order:6;margin:10px 12px 0}
  .case .card-body > .tactics{order:7;margin:10px 12px 0}
  /* 按钮贴着内容排（flex:0 1 auto），和 PC 同一条规矩：一行排不下时由 flex-wrap
     自己折行，而不是把某一枚压扁或裁字。
     原来这里是 flex:1 1 0（三枚平分）外加一条「保存截图挪到第二行整行」的特例 ——
     那是给 172 宽的手机卡写的。手机改单列之后最窄的卡也有 277（600 视口），
     三枚并排只要 218（70 + 90 + 46 + 两个 6px 间距），特例没有存在的理由，
     留着只会让平板白白高一截、和 PC 的观感也对不上。 */
  .case .card-body > .card-foot .btn{
    flex:0 1 auto;min-width:0;padding:7px 9px;font-size:11.5px;white-space:nowrap;
  }
  .case .card-body > .card-foot .btn svg{display:none}}

/* ------------------------------------------------------------
   手机（≤599）：案例库从一排两张退回**一排一张**。
   门槛为什么是 600 —— 和上面那条两栏数据条用的是同一个 600，两处口径一致：
   两列布局下卡宽 =（视口 − 35 − 11）/ 2，且内容宽还有 721 的上限，
   所以 600 时每张卡 277，已经是「还看得清」的下限；再往下 390 → 172、
   320 → 137，卡片整体太小，而客户看的就是那张图。

   单列之后卡宽 285（320 视口）~ 564（599），宽到足够走 PC / 平板那一套，
   于是本节原先那两条特例一并撤掉：
     · 数据条「一行一个指标、19px」→ 回到两栏竖排 24px（理由已不成立）；
     · 「保存截图」占整行 → 三枚按钮回到一行（218 宽而已）。
   ------------------------------------------------------------ */
@media (max-width:599px){
  .grid.wide{grid-template-columns:minmax(0,1fr)}}

/* ============================================================
   交付库（第八个库）
   ------------------------------------------------------------
   条目是「功能」，不是「内容」。⚠️ 列表 2026-09-18 从**清单行**改成了**卡片**
   （用户要求「卡片形式试一下新的ui」）。原先那条理由（「功能没有可看的图，
   清单行一屏能扫 6~8 条」）只考虑了密度，漏了一件事：清单行左列铺满 1300px、
   右列那三行小字贴在最右边，扫过去只剩「一列名字」，认不出哪条方案厚、哪条薄。
   卡片把名称 / 摘要 / 客户 / 规模压成四行，三列并排一屏仍有 6 条可见量。
   材质没变（白面 / 一像素描边 / 同一套圆角 / 悬停浮出顶边 3px 身份色 /
   底栏按钮贴底），所以它不会显得不是一家 —— 与教程卡同一套做法。

   ⚠️ 2026-09-24 分组由两级收成一级：原来 .dlv-cat（产品分类）在外、
   .dlv-prod（产品）在内、左侧挂一条细竖线表「谁属于谁」。产品分类那一级
   删掉之后，产品自己就是组标题 —— 竖线随父亲一起去掉（没人可归属了），
   产品名接过原来 .dlv-cat h2 那一套：大字 + 身份色短横 + 底部分隔线。

   内页（.dv-*）比其它库的详情页长得多：六段，其中「适用客户」一格
   就是一类客户。所以比别处多两样东西：四条段锚点、以及更明确的分段。
   ⚠️ 内页版式 2026-09-17 因「文字太密、层级分不清」重排过，规矩见下面
   内页那一段开头的注释（四档层级 + 行宽 ≤65 字）。
   ============================================================ */

/* ---------------- 列表 ---------------- */
.dlv-groups{display:flex;flex-direction:column;gap:30px}
.dlv-grp{display:flex;flex-direction:column;gap:16px}

/* 一组 = 一个产品（原先外面还套一层产品分类，2026-09-24 已删）。
   产品名就是这一组的标题，规矩与教程库的组标题同一套。 */
.dlv-prod{display:flex;flex-direction:column;gap:14px}

.dlv-prod-h{display:flex;align-items:baseline;gap:10px;padding-bottom:10px;border-bottom:1px solid var(--line)}
.dlv-prod-name{
  font-size:17px;font-weight:800;letter-spacing:-.3px;min-width:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
/* 产品名前面那一小段身份色短横：与教程库的组标题同一套语言 */
.dlv-prod-name::before{
  content:'';display:inline-block;width:4px;height:16px;border-radius:2px;
  background:var(--grad);margin-right:9px;vertical-align:-2px;
}
.dlv-prod-n{margin-left:auto;font-size:12px;font-weight:700;color:var(--txt-4);white-space:nowrap}
/* 卡片网格。列数交给 auto-fill（与其余七个库同一条规矩：
   ui-check.js 有一条守门断言钉着「PC 栅格必须 auto-fill，不许瀑布流」）。
   下限 330px 比教程卡宽一档：这里的摘要要留住三行、客户徽章要横排成一排，
   卡片一窄就先折行再截断，扫起来反而比清单行还碎。
   间距走全站的 --gap（1440 档 18px），不另立一套。
   align-items:stretch 让同一行的卡等高 —— 不等高的话一行里三张卡的下沿参差。 */
.dlv-grid{
  display:grid;gap:var(--gap);align-items:stretch;
  grid-template-columns:repeat(auto-fill,minmax(330px,1fr));
}

/* 交付卡：名称 → 摘要 → 客户 → 规模，四行从上到下各管一件事。
   材质与其它七个库逐条对齐（白面 + 1px 描边 + --r-lg 圆角 + --sh-1 贴边阴影 +
   悬停抬升 2px + 顶边浮出 3px 身份色线）—— 与 .prod / .tool / .tut / .mat 是同一套。
   ⚠️ 2026-09-18 这张卡**改过两版**，第二版（现在这版）是回到全站这套：
     中间那版照着参考站（微盟 GEO 落地页）做过「无描边 + 20px 圆角 +
     浅蓝整面渐变 + 柔光阴影 + 蓝字链」，用户当场否掉 ——
     原话「交付库的卡片太丑了，按我们自己的设计来」，并说明**参考站是给他改内页
     内容详情的，不是改列表卡片的**。
   教训写在这儿免得下次重犯：一个站里八个库的卡片长得不一样，本身就是问题；
   参考站的视觉可以借，但不能借到「同一站两张卡不是一家」的程度。
   顺带一提，那版为了配浅蓝面，还专门定过 --dlv-ink / --dlv-card-bg 等六个令牌，
   现在一并删掉了 —— 卡片回到白面，就该用全站那两档灰。 */
.dlv-card{
  position:relative;display:flex;flex-direction:column;overflow:hidden;
  background:var(--solid);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--sh-1);cursor:pointer;
  transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
/* 顶边那条 3px 身份色是**悬停才浮出**的（background-size 只取 3px 高），不是常驻 ——
   常驻的话一屏 6 张卡就有 6 条色线，页面会吵。做法与 .prod 一致。 */
.dlv-card::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  border-radius:calc(var(--r-lg) - 1px);
  background-image:var(--grad);
  background-size:100% 3px;background-repeat:no-repeat;
  opacity:0;transition:opacity .22s ease;
}
.dlv-card:hover::after{opacity:1}
.dlv-card:hover{transform:translateY(-2px);box-shadow:var(--sh-2);border-color:var(--line-3)}

/* 卡片封面横幅（2026-09-25）：列表里一眼认出这条功能。
   高度写死 104px 而不是跟着比例走 —— 三列卡片同宽但图的高矮不一定一致，
   不锁高会让同一行的卡片底边参差。没有封面的条目不渲染，不留空槽。 */
/* 封面 16:9（2026-09-30 由写死 height:104px 改来）：
   原来封顶 104px 是把任何比例的图都裁成一条窄横幅，横图上下被切掉大半；
   改按宽度走 16/9 后，同一行卡片封面高度一致（都随列宽走），
   没封面的老条目本来就不渲染 .dlc-cov，不受影响 */
.dlc-cov{position:relative;aspect-ratio:16/9;width:100%;flex:0 0 auto;background:var(--solid-2);overflow:hidden}
.dlc-cov img{width:100%;height:100%;object-fit:cover;display:block}
/* 右上角压一枚卖点数：与教程卡封面那枚 .tut-flag 同一待遇（白字压深渐变） */
.dlc-cov-n{
  position:absolute;right:9px;top:9px;
  padding:3px 9px;border-radius:999px;
  background:linear-gradient(135deg,var(--acc-d) 0%,var(--acc) 100%);
  color:#fff;font-size:10.5px;font-weight:800;letter-spacing:.2px;
}

.dlc-body{padding:14px 16px 15px;display:flex;flex-direction:column;flex:1;min-width:0}
.dlc-top{display:flex;align-items:flex-start;gap:8px;min-width:0}
/* 名称给两行、封顶再截。三列时一行放不下「手机号精准触达」这类名字，
   直接省略号会砍掉后半截意思 —— 名字是这一页唯一的检索目标，宁可占两行 */
.dlc-name{
  margin:0;flex:1;min-width:0;
  font-size:16px;font-weight:900;letter-spacing:-.3px;line-height:1.45;
  color:var(--txt);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
/* 置顶走实心深渐变（读数：白字压在浅端 --acc-2(#159dff) 上只有 2.88:1，糊的，
   所以用 --acc-d → #2a5ae8，两端 6.45:1 与 5.64:1 都过线），
   与教程卡封面右上那枚 .tut-flag 同一种待遇 */
.dlc-flag{
  flex:0 0 auto;margin-top:2px;
  font-size:10.5px;font-weight:800;letter-spacing:.2px;color:#fff;
  background:linear-gradient(135deg,var(--acc-d) 0%,#2a5ae8 100%);
  border-radius:999px;padding:2px 8px;
}
/* 摘要三行封顶：两行的卡和三行的卡同高（等高靠 grid 的 stretch），
   所以封顶只是防「一条摘要拖垮整行」，不是省空间。
   色回全站那档 --txt-3（与 .tut .card-text 同一条）：卡片回到白面之后，
   当初「浅蓝面上必须把小字加深」的理由就不成立了 —— 与别处不一样反而是个错 */
.dlc-sum{
  margin:7px 0 0;font-size:12.5px;color:var(--txt-3);line-height:1.75;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;
}
/* 客户徽章：列表上最有信息量的一行 ——「这个功能帮得了谁」正是代理商扫列表时在找的。
   2026-09-17 从 dr-ind(行业) 改成 dr-cli(客户)，2026-09-18 随卡片改成 dlc-cli：
   数据还是行业口径的键，但对用户我们管这叫「适用客户」，不该再顶着行业的名。
   底回 --acc-soft（身份色 9% 淡底）+ --acc-line 描边：与产品库、工具库那些胶囊同一档，
   中间那版为了配浅蓝卡面才用过半透明白底，一并撤掉 */
.dlc-clis{display:flex;flex-wrap:wrap;gap:5px;margin-top:11px}
.dlc-cli{
  font-size:11px;font-weight:700;color:var(--acc-d);
  background:var(--acc-soft);border:1px solid var(--acc-line);
  border-radius:999px;padding:2px 8px;white-space:nowrap;
}
/* 「还有 N 个」与「客户待补」都退回中性色：一个是省略号，一个是空缺，
   都不该抢身份色。空缺用虚线边，跟「有内容」一眼分得开 */
.dlc-cli.more,.dlc-cli.none{color:var(--txt-4);background:var(--solid-2);border-color:var(--line-2)}
.dlc-cli.none{border-style:dashed}
/* 底栏复用全站的 .card-foot：那条分隔线、内边距、窄屏折行都从那一处来
   （与教程卡「card-foot tut-foot」同一套做法，不另画一条线）。
   这里只改三件事：贴卡底（margin-top:auto）、间距松一档、按钮不参与等分。
   margin-top:auto 是为了**一行三张卡的下沿齐平** —— 摘要两行的卡和三行的卡，
   这一行要一起贴底，否则滚下来一排卡片的下沿是锯齿。
   ⚠️ 中间那版在浅蓝卡面上覆盖过一次 border-top-color（浅蓝比白深，全站那条
   压上去几乎看不见）；现在卡面回到白，那条覆盖一并撤掉，用 .card-foot 原样 */
.dlc-foot{margin-top:auto;flex-wrap:wrap;align-items:flex-end;gap:12px}
.dlc-stats{display:flex;flex-wrap:wrap;gap:3px 14px;min-width:0}
/* 规模数字走**内页那一套**：大号身份色数字 + 小号灰标签。
   这一条是改卡片时留下的最有用的一条 —— 列表和内页从此说同一句话，
   卡上写「3 条异议」，点进去 02 段就是 3 条；数字用 tabular-nums 让三张卡的数字列能对上 */
.dlc-stat{
  display:inline-flex;align-items:baseline;gap:3px;
  font-size:11px;font-weight:700;color:var(--txt-3);white-space:nowrap;
}
.dlc-stat b{
  font-size:16px;font-weight:900;letter-spacing:-.4px;line-height:1.1;
  color:var(--acc-d);font-variant-numeric:tabular-nums;
}
/* 「看方案」不参与等分，与别处那枚小按钮同一规格（.btn.sm.primary + 104px 最小宽）。
   ⚠️ 中间那版把它改成过参考站那种「蓝字链 + 右箭头」（无底、无内边距、箭头在右），
   现在随卡片一起回到实心按钮，箭头也回到文字**前面**（client.js 里对调回去了）。
   也不需要任何 `display:block` 覆盖：全站那条 `.btn svg{display:none}`
   （窄屏藏图标）对实心按钮本来就成立，照它走就行 */
.dlc-foot .btn{flex:0 0 auto;margin-left:auto;min-width:104px;white-space:nowrap}

/* ---------------- 内页 ----------------
   ⚠️ 2026-09-18 第二次重排。第一版（09-17）只做了「限行宽 + 拉级差」，
   用户看下来还是那句「看不懂、没有一点设计感」。复盘下来病根不在密度，在**没有版式**：
     · 五段是五个一模一样的白盒子，段与段之间只靠 18px 空隙分；
     · 01~04 内部又都是同一个形状 ——「一行小灰标签 + 一段灰字」；
     · 字号全挤在 11~18px 之间，标题和正文只差 2~3px，扫过去没有落点。
   这一版改的是**结构**，不是参数：

   ① 抬头升格成「封面带」：标题 34px + 顶边一条 3px 渐变线（全站 KPI 卡同一招），
      下面压一行**规模数字**（4 类客户 / 3 条异议 / 2 段话术 / 4 步落地），
      主按钮推在最右。进页面第一眼就知道「这条方案有多大、给谁用」。
   ② 段头从「白盒子里一条底线」改成**整幅章头带**：01 段用实心深渐变（它是核心块，
      全页只有它有这个待遇），02~05 用身份色淡底。段的边界从此是**色块**，不靠猜。
   ③ 每一段各有各的**形状**，不再同构：
      01 客户作战卡（头带客户名；四行按「中性 / 灰底 / 白 / 身份色」分档）
      02 对话块（灰底问句带大引号 + 身份色左边线答句）
      03 话术卡（小方块标记 + 场景名 + 复制键）
      04 流程（42px 大方块序号 + 贯通竖线）
      05 入口条（自适应列，不摆空列）
   ④ 层级四档重新定标 —— 旧的四档只差 2~3px，等于没有层级：
      段标题   19px/900          （01 段是白字压在渐变带上）
      条目标题 17px/900 客户名 · 15.5px/900 流程步名 · 15px/900 话术场景名
      字段标签 11.5px/900 字距 .4px
      行内标记 11px/900 胶囊
      正文一律 13.5px/1.95 最深一档色；只有两处抬到 14.5px ——
      「可以这么说」与话术正文，这两处是**要开口念出来的**，比别处大一号有理由。
   ⑤ 吸顶锚点条带段号（01…04）。落点留白按实测条高算（条底 = 顶栏 + 8 + 48），
      所以 scroll-margin-top 给顶栏 + 76，不靠猜。

   ⚠️ 01 段的实心渐变**不是 `--grad`**，是 `--acc-d → --acc` 的深渐变。
   原因：`--grad` 的浅端是 --acc-2(#159dff)，白字压在上面的对比度只有 2.88:1；
   章头带又宽又矮，135° 走到右端已经是浅端 —— 白字会直接糊掉。
   深渐变两端（#1b4ee4 / #2a5ae8）配白字是 6.45:1 与 5.64:1，都过线。
   `--grad` 仍旧只用在**小面积**（锚点段号、顶边细线）和**大字号**上。 */
.dv{display:flex;flex-direction:column;gap:20px}
/* ⚠️ 详情页容器**钉在 1120**（内容区 1080），不跟着全站的 --page 走。
   --page 在 1440 之后会放到 1480 / 1660，交付详情页跟着变宽的结果是：
   场景卡两列网格被拉到 700+ 一列，每行四五十个字，「四行照着说」被摊平成
   一整片灰字；抬头那句摘要更是能排到 90 字一行。
   1080 是定稿草图（_preview/dlv-detail-tpl.html 的 .wrap）的宽度：
   两列场景卡各 ~509，正文行宽落在 ~38 字，是这个版式算好的数。 */
@media (min-width:1024px){
  #viewDelivery{max-width:1120px;margin:0 auto;padding:0 20px}
}
.dv-head{
  position:relative;overflow:hidden;
  background:var(--surface);border:1px solid var(--line);
  border-radius:20px;box-shadow:var(--sh-1);padding:20px 22px 18px;
}
/* 顶边那条 3px 渐变线：和全站 KPI 卡同一招，所以不像新加的东西 */
.dv-head::before{
  content:'';position:absolute;left:0;right:0;top:0;height:3px;background:var(--grad);
}
.dv-back{
  display:inline-flex;align-items:center;gap:5px;
  border:1px solid var(--line-2);border-radius:10px;background:var(--solid);
  padding:6px 12px;font-size:12.5px;font-weight:700;color:var(--txt-2);cursor:pointer;
  transition:border-color .16s ease,color .16s ease,transform .16s ease;
}
.dv-back:hover{border-color:var(--acc);color:var(--acc);transform:translateY(-1px)}
.dv-back svg{width:14px;height:14px;flex:0 0 auto}
.dv-eyebrow{
  display:flex;flex-wrap:wrap;align-items:center;gap:7px;margin-top:16px;
  font-size:12px;font-weight:700;color:var(--txt-4);
}
/* 产品 pill：草图规格 —— 28 高、999 圆角、12.5/800、身份色淡底 */
.dv-prod{
  display:inline-flex;align-items:center;gap:7px;height:28px;
  font-size:12.5px;font-weight:800;letter-spacing:.2px;
  color:var(--acc-d);background:var(--acc-soft);
  border:1px solid var(--acc-line);border-radius:999px;padding:0 12px;
}
.dv-prod::before{
  content:'';width:6px;height:6px;border-radius:50%;background:var(--acc);flex:0 0 auto;
}
.dv-sep{color:var(--line-3)}
.dv-top{font-size:10.5px;font-weight:800;color:var(--on-acc);background:var(--grad);border-radius:999px;padding:3px 9px}
/* 标题是这一页最大的一档字：它得压得住下面整页内容。
   ⚠️ 这里原来挂了 max-width:26ch —— 26ch 只有 ~430px，在双臂 hero 里会把左栏
   压成一根柱子（封面反倒被撑到 800+）。草图里标题不限宽，靠 1.15fr 的栅格定宽。 */
.dv-title{
  font-size:31px;font-weight:900;letter-spacing:-1px;
  margin:16px 0 0;line-height:1.22;word-break:break-word;
}
/* 摘要限宽 52ch：抬头是「一句话说清这是什么」，铺满整栏就变成两行长句了 */
.dv-sum{margin:14px 0 0;font-size:15.5px;line-height:1.85;color:var(--txt-2);max-width:52ch}
/* 亮点胶囊：草图规格 —— 6/12 内边距、999 圆角、淡底描边、12.5/700 */
.dv-tags{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}
.dv-tags span{
  display:inline-flex;align-items:center;gap:6px;
  font-size:12.5px;font-weight:700;color:var(--txt-2);
  background:var(--solid-2);border:1px solid var(--line);border-radius:999px;padding:6px 12px;
}
.dv-tags span b{color:var(--acc-d)}
/* 抬头骨架：窄屏一栏叠（右栏退化成通栏的规模带），宽屏左右并排（见 1024 那档）。
   加这层骨架是因为标题只有 ~600px 宽，而卡片有 1300 ——
   剩下那 700px 光靠留白压不住，右边得摆点东西，「抬头右半空一大块白」是上一版最显眼的空洞 */
.dv-head-main{display:flex;flex-direction:column}
.dv-head-l{min-width:0}
.dv-head-r{min-width:0;display:flex;flex-direction:column}
/* 规模数字带：窄屏这一档是通栏的一条，各格之间一条细竖线 */
/* 抬头封面（2026-09-25）：这条功能长什么样，进页面第一眼看到。
   没有封面的老条目不渲染这个盒子，不留空槽。 */
/* 封面：草图规格 —— 圆角 20、身份色淡底 + 大投影。
   ⚠️ 比例 2026-09-30 由 16/11 统一到 **16/9**：同一张封面在列表卡上是
   16:9、点进来变成 16/11，等于同一张图被裁掉两次且裁法不同 ——
   卡片上看到的构图和详情里看到的对不上，视觉上就是「比例不对」。
   全站封面只留一个比例，卡片与详情同源同裁。
   （原来写 16/11 的理由是「右栏 ~443 宽时圆角和比例偏小」，但那只和
     圆角 20 有关，与比例无关：宽度定死了，16/11 比 16/9 只多 23px 高。） */
.dv-cover{
  position:relative;
  border-radius:20px;overflow:hidden;border:1px solid var(--line);
  background:var(--grad-soft);aspect-ratio:16/9;box-shadow:var(--sh-2);
}
.dv-cover img{width:100%;height:100%;object-fit:cover;display:block}
/* 右上角「可覆盖平台 N 个」角标（草图 .cover .badge） */
.dv-cover-badge{
  position:absolute;right:12px;top:12px;
  padding:5px 11px;border-radius:999px;
  background:rgba(255,255,255,.92);color:var(--acc-d);
  font-size:11.5px;font-weight:900;
}

/* 可覆盖平台：抬头底部一条独立带子（草图 .plats）。
   只展示名字不存图 —— 平台换 logo 没人会回来改 */
.dv-plats{
  display:flex;flex-wrap:wrap;align-items:center;gap:16px;
  margin-top:26px;padding-top:18px;border-top:1px solid var(--line);
}
.dv-plats-t{font-size:12.5px;font-weight:800;color:var(--txt-3);white-space:nowrap}
.dv-plats-t b{color:var(--txt)}
.dv-plats-list{display:flex;flex-wrap:wrap;gap:9px}
.dv-plat{
  display:inline-flex;align-items:center;gap:7px;
  padding:5px 11px 5px 5px;border-radius:999px;
  background:var(--solid);border:1px solid var(--line);
  font-size:12.5px;font-weight:700;color:var(--txt-2);
}
.dv-plat i{
  width:22px;height:22px;border-radius:7px;display:grid;place-items:center;
  background:var(--grad-soft);border:1px solid var(--acc-line);
  color:var(--acc-d);font-size:11px;font-weight:900;font-style:normal;
}

.dv-stats{
  display:flex;flex-wrap:wrap;align-items:center;
  margin-top:18px;padding-top:16px;border-top:1px solid var(--line);
}
.dv-stat{display:flex;flex-direction:column;gap:3px;padding:0 20px;border-left:1px solid var(--line)}
.dv-stat:first-child{padding-left:0;border-left:0}
.dv-stat b{
  font-size:24px;font-weight:900;line-height:1;letter-spacing:-.8px;
  color:var(--acc-d);font-variant-numeric:tabular-nums;
}
.dv-stat span{font-size:11.5px;font-weight:800;letter-spacing:.3px;color:var(--txt-3)}
/* 按钮行：草图规格 —— 上间距 22、间距 10、按钮 44 高 / 13 圆角 / 14.5px 800。
   44 是这一页唯一的手指热区尺寸：整页只有这一处可点，就得做得像一枚按钮 */
.dv-acts{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:22px}
.dv-acts .btn{
  height:44px;padding:0 18px;border-radius:13px;
  font-size:14.5px;font-weight:800;
}
.dv-acts .btn.primary{
  padding:0 20px;
  /* 草图那枚主按钮带一枚大投影（0 14px 30px -16px），是首屏唯一的"重量" */
  box-shadow:0 14px 30px -16px var(--acc-glow);
}
/* 抬头这枚主按钮走**深渐变**，不是全站的 `.btn.primary`（那条用的是 --grad）。
   理由同 01 段的章头带：按钮有 170px 宽，--grad 的浅端 #159dff 会占掉右半截，
   白字压上去只剩 2.88:1 —— 字还在，但是糊的。深渐变两端都过 5.5:1。 */
.dv-acts .btn.primary{background:linear-gradient(135deg,var(--acc-d) 0%,var(--acc) 100%)}

/* ===== 卖点导航条（草图 .nav）=====
   六个卖点一页铺下来有几千像素高，没有这条就只能一路滚。
   吸在顶栏下面：滚到哪一段都能直接跳到另一个卖点，不用先回到顶部。
   ⚠️ 这不是最早那版「适用客户 / 客户会怎么问 / 话术清单 / 怎么落地」的段锚点条
   （那条随 2~6 段一起删了），这条只跳**卖点**。 */
.dv-sellnav{
  position:sticky;top:var(--hdr-h);z-index:40;
  background:var(--solid);border:1px solid var(--line);
  border-radius:14px;box-shadow:var(--sh-1);
}
.dv-sellnav-in{
  display:flex;gap:8px;overflow-x:auto;padding:10px 14px;scrollbar-width:none;
}
.dv-sellnav-in::-webkit-scrollbar{display:none}
.dv-sellnav button{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:7px;height:32px;padding:0 13px;
  border-radius:9px;background:var(--solid-2);border:1px solid var(--line);
  color:var(--txt-2);font-family:inherit;font-size:12.5px;font-weight:700;
  white-space:nowrap;cursor:pointer;
  transition:color .16s ease,border-color .16s ease,background .16s ease;
}
.dv-sellnav button:hover{color:var(--acc-d);border-color:var(--acc-line);background:var(--acc-soft)}
.dv-sellnav button i{font-style:normal;font-weight:900;color:var(--acc);font-size:11.5px}

/* 一段 = 一张卡 + 一条**章头带**。带子跨满整卡宽度、顶角跟着卡圆角走，
   所以段与段的边界是一条有颜色的横带，而不是两个白盒子之间的空隙。
   卡片自己不再留 padding —— 内边距由带子（.dv-sec-h）和正文壳（.dv-sec-b）各管一半 */
.dv-sec{
  background:var(--surface);border:1px solid var(--line);
  border-radius:20px;box-shadow:var(--sh-1);overflow:hidden;
  /* 从锚点跳过来的落点留白：顶栏 + 吸顶的锚点条（条高 48、距顶栏 8）再留一点余量 */
  scroll-margin-top:calc(var(--hdr-h) + 76px);
}
/* 章头带：大号段号 + 竖线 + 段名 + 计数胶囊 */
.dv-sec-h{
  display:flex;align-items:center;gap:0;
  padding:15px 22px;
  background:var(--grad-soft);
  border-bottom:1px solid var(--acc-line);
}
.dv-sec-h i{
  flex:0 0 auto;font-style:normal;
  font-size:26px;font-weight:900;line-height:1;
  letter-spacing:-1px;color:var(--acc);font-variant-numeric:tabular-nums;
}
.dv-sec-h h2{
  margin:0 0 0 14px;padding-left:14px;border-left:1px solid var(--acc-line);
  font-size:19px;font-weight:900;letter-spacing:-.5px;min-width:0;
}
.dv-core-tag{
  flex:0 0 auto;margin-left:11px;
  font-size:10.5px;font-weight:900;letter-spacing:.5px;
  color:var(--on-acc);background:var(--acc);border-radius:6px;padding:2px 8px;
}
.dv-sec-n{
  margin-left:auto;flex:0 0 auto;
  font-size:11.5px;font-weight:800;color:var(--acc-d);white-space:nowrap;
  background:var(--solid);border:1px solid var(--acc-line);border-radius:999px;padding:4px 11px;
}
/* 01 段是这一库的核心：全页唯一一条**实心深渐变**章头带。
   用深渐变而不是 --grad，理由见本块顶上的注释（白字在 --acc-2 上只有 1.9:1） */
.dv-core .dv-sec-h{
  background:linear-gradient(135deg,var(--acc-d) 0%,var(--acc) 100%);
  border-bottom-color:transparent;
}
.dv-core .dv-sec-h i{color:#fff}
.dv-core .dv-sec-h h2{border-left-color:rgba(255,255,255,.4);color:#fff}
.dv-core .dv-core-tag{background:rgba(255,255,255,.24);color:#fff}
.dv-core .dv-sec-n{
  background:rgba(255,255,255,.18);border-color:rgba(255,255,255,.4);color:#fff;
}
/* ⚠️ 左右不留内边距：卖点块自己带描边和圆角，再让 .dv-sec-b 缩进一次，
   卡边和块边会叠成一条 2px 的重线；草图里 .sell 也是直接铺满内容宽的。
   段说明那一行靠自己的 margin 对齐到 24，跟章头带的 24 对齐。 */
.dv-sec-b{padding:18px 0 24px}
/* 段说明退成一小行：它是「怎么用这一段」的旁白，不是内容，别跟正文抢重量 */
/* 段说明：左侧一条身份色竖线当"引导"，文字与卡内文字同一条基线 ——
   之前没这层的时候它贴着段容器左缘（0 padding），看起来像吊在页面边上的孤行 */
.dv-sec-tip{
  margin:0 24px 22px;padding:2px 0 2px 13px;
  border-left:3px solid var(--acc);border-radius:1px;
  font-size:13.5px;color:var(--txt-3);line-height:1.8;max-width:72ch;
}
/* ===== 核心卖点（2026-09-25 新增，详情页主体）=====
   一个卖点一块：章头是「序号 + 卖点名 + 适配行业」，下面按行业铺场景卡。
   场景卡把后台那四行（定向谁 / 推送什么 / 客户原本 / 结果）竖着排开 ——
   合成一整段长句时扫不出重点，拆成四行就能照着说。
   颜色只走 --acc 一支：图标、序号、结果行高亮都跟着库身份色，
   四套色系自动反相，不会出现「一个行业一个颜色」。 */
/* 卖点块间距 34：草图 .sell{margin:0 0 34px}。块与块之间要的是「一段打法结束了」
   的分隔感，太近会读成一整片 */
.dv-sells{display:grid;gap:34px}
.dv-sell{
  border:1px solid var(--line);border-radius:20px;background:var(--solid);
  box-shadow:var(--sh-1);overflow:hidden;
  scroll-margin-top:calc(var(--hdr-h) + 66px);
}
/* 卖点头：草图 .sell-h —— 18 间距、22/24/18 内边距、身份色淡底自上而下渐隐。
   底边不再描线：下面场景卡自己有描边，两层线叠着会显脏 */
.dvs-h{
  display:flex;gap:18px;align-items:flex-start;
  padding:22px 24px 18px;
  background:linear-gradient(180deg,var(--grad-soft),transparent);
}
.dvs-no{
  flex:0 0 auto;width:56px;height:56px;border-radius:16px;background:var(--grad);color:#fff;
  display:grid;place-items:center;font-size:22px;font-weight:900;letter-spacing:-1px;
  box-shadow:0 12px 26px -14px var(--acc-glow);
}
.dvs-t{flex:1;min-width:0}
.dvs-k{font-size:11.5px;font-weight:800;letter-spacing:1px;color:var(--acc)}
.dvs-t h3{margin:5px 0 0;font-size:24px;font-weight:900;letter-spacing:-.5px;line-height:1.3}
.dvs-inds{display:flex;flex-wrap:wrap;align-items:center;gap:7px;margin-top:12px}
.dvs-inds .lb{font-size:11.5px;font-weight:800;color:var(--txt-3);margin-right:2px}
.dvs-inds span:not(.lb){
  padding:5px 11px;border-radius:999px;background:var(--acc-soft);
  border:1px solid var(--acc-line);color:var(--acc-d);
  font-size:12.5px;font-weight:800;
}

/* 场景网格：草图 .scenes —— 14 间距、0/24/24 内边距 */
.dvs-scenes{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;padding:0 24px 24px}
.dv-sc{
  border:1px solid var(--line);border-radius:16px;background:var(--solid-2);overflow:hidden;
  transition:transform .18s ease,box-shadow .18s ease;
}
.dv-sc:hover{transform:translateY(-2px);box-shadow:var(--sh-2)}
.dvsc-h{display:flex;align-items:center;gap:11px;padding:13px 15px;background:var(--solid);border-bottom:1px solid var(--line)}
.dvsc-h .pic{
  flex:0 0 auto;width:38px;height:38px;border-radius:12px;display:grid;place-items:center;
  background:var(--grad-soft);border:1px solid var(--acc-line);color:var(--acc-d);
}
.dvsc-h .pic svg{width:21px;height:21px}
/* 行业名：一屏十几张卡，眼睛第一下要落的是「这张卡是哪类客户」——
   所以不做成普通黑字，做成一颗身份色胶囊（淡底 + 描边 + 深身份色字），
   跟下面四行的灰字拉开一整档重量 */
.dvsc-h b{
  font-size:16.5px;font-weight:900;letter-spacing:-.2px;color:var(--acc-d);
  background:var(--acc-soft);border:1px solid var(--acc-line);
  border-radius:999px;padding:4px 13px;white-space:nowrap;
}
.dvsc-h .tag{margin-left:auto;font-size:11.5px;font-weight:800;color:var(--txt-3)}
.dvsc-b{display:grid;gap:9px;padding:12px 15px 14px}
.dvsc-b .row{display:grid;grid-template-columns:20px auto 1fr;gap:10px;align-items:start;font-size:13.5px}
.dvsc-b .k{font-size:12px;font-weight:800;color:var(--txt-3);line-height:20px;white-space:nowrap}
.dvsc-b .v{color:var(--txt-2);line-height:1.7}
.dvsc-b .row.push .v{color:var(--txt);font-weight:700}
.dvsc-b .row.worry .v{color:var(--txt-3);font-style:italic}
/* 序号格：草图 .step .n —— 20×20 圆角 6 的小方片。
   ⚠️ 之前这条样式整个漏掉了，序号就是个光秃秃的数字，
   四行之间没有「第几步」的锚点，扫读时抓不住顺序 */
.dvsc-b .n{
  width:20px;height:20px;border-radius:6px;display:grid;place-items:center;
  font-size:11px;font-weight:900;font-variant-numeric:tabular-nums;
  background:var(--acc-soft);color:var(--acc-d);border:1px solid var(--acc-line);
}
/* 成交行：草图 .step.win —— 走**成功色**而不是身份色。
   前四行里身份色已经用了三次（序号格、图标、行业胶囊），
   最后一行再用同一支颜色就只是「又一块浅底」，读不出「成了」；
   换成绿底 + 深绿字，一屏十几张卡时眼睛直接落在这一行上。
   负 margin 让它从卡内边距里探出去一点，块感更完整 */
.dvsc-b .row.win{
  background:var(--ok-soft);border:1px solid var(--ok-line);
  border-radius:10px;margin:2px -6px -2px;padding:8px 10px;
}
.dvsc-b .row.win .v{color:var(--ok-t);font-weight:800}
.dvsc-f{display:flex;gap:8px;padding:0 15px 13px}
.dvsc-copy{
  flex:1;justify-content:center;
  display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 11px;border-radius:9px;
  border:1px dashed var(--line-2);background:transparent;color:var(--txt-3);
  font-size:12.5px;font-weight:700;cursor:pointer;
  transition:border-color .16s ease,color .16s ease,background .16s ease;
}
.dvsc-copy svg{width:13px;height:13px}
.dvsc-copy:hover{border-style:solid;border-color:var(--acc-line);background:var(--acc-soft);color:var(--acc-d)}

/* PC：抬头按草图 .hero .wrap 的双臂栅格 —— 1.15fr / .85fr、间距 38、
   上下 44 / 38。左栏文案、右栏封面，两侧各占该占的比例。
   ⚠️ 之前这里写的是 flex 双臂：右栏 flex:0 0 auto 且没有宽度上限，
   封面的**图片固有宽度**（802px）会反过来把右栏撑到 800+，
   左栏只剩 432（正好是标题 max-width:26ch 的宽度）——整个 hero 是反的。
   栅格用 fr 分，两边谁都撑不动谁。 */
@media (min-width:1024px){
  .dv-head{padding:44px 38px 38px}
  .dv-title{font-size:40px;letter-spacing:-1px;line-height:1.2}
  .dv-head-main{
    display:grid;grid-template-columns:1.15fr .85fr;
    gap:38px;align-items:center;
  }
  .dv-head-l{min-width:0}
  .dv-head-r{min-width:0;display:block}
  .dv-sec-h{padding:16px 24px}
  .dv-sec-h h2{font-size:22px}
}

/* 01 / 02 / 03 段排两列：这三段原来单列通栏，13px 字一行 80~90 字，
   是「文字太密」最重的地方。两列之后每列 ~640px，客户卡正文落到 ~37 字 */

/* 场景卡：宽屏两列（一排两张行业场景，一眼能横着比）；
   900 以下单列 —— 两列时每张卡只有 ~330px，四行文字会被挤成窄条 */
@media (max-width:900px){
  .dvs-scenes{grid-template-columns:minmax(0,1fr)}}
@media (max-width:640px){
  .dvs-h{padding:16px 15px 13px;gap:13px}
  .dvs-no{width:44px;height:44px;font-size:18px;border-radius:13px}
  .dvs-t h3{font-size:18px}
  .dvs-inds{gap:6px;margin-top:10px}
  .dvs-scenes{padding:0 15px 16px;gap:12px}
  .dvsc-h{padding:11px 13px;gap:9px}
  .dvsc-h .pic{width:34px;height:34px;border-radius:11px}
  .dvsc-h .pic svg{width:19px;height:19px}
  .dvsc-h b{font-size:15px;padding:3px 11px}
  .dvsc-b{padding:11px 13px 12px;gap:8px}
  .dvsc-b .row{grid-template-columns:20px auto 1fr;gap:8px;font-size:13px}
  .dvsc-b .k{font-size:11.5px}
  .dvsc-f{padding:0 13px 12px}
  .dv-sells{gap:22px}
  .dv-sec-tip{margin:0 15px 18px}}

/* 窄屏：左栏折回正文上方。88px 的左栏在手机上会把正文挤成一根柱子，
   折上去之后标签仍然自成一行、仍然比正文小一号，层级不丢 */

/* 小屏：清单行把右侧那一列折到下面（横排），区块与卡片都缩一档 */
@media (max-width:640px){
  .dlv-groups{gap:24px}
  .dlv-prod-name{font-size:15.5px}
  /* 手机上单列。⚠️ 必须显式写 minmax(0,1fr) 而不是靠 auto-fill 自己收：
     视口窄到 330px 以下时 auto-fill 的死下限会把卡片顶出屏幕外（横向溢出）。
     间距 12px（桌面是 --gap 那档）—— 手机上屏幕就 390 宽，桌面那个间距会把卡片压窄。
     中间有一版卡是无描边的，那时间距还不能小于 12px（两卡之间只剩阴影在分界）；
     现在卡片恢复了 1px 描边，间距只按「手机上舒服」来定 */
  .dlv-grid{grid-template-columns:minmax(0,1fr);gap:12px}
  .dlc-body{padding:15px 15px 14px}
  .dlc-name{font-size:15px}
  .dlc-sum{-webkit-line-clamp:4}
  .dlc-foot{gap:10px}
  /* 手机上那枚「看方案」**通栏**：三处规模数字 + 一枚 104px 按钮在 352px 里挤不下，
     与其让按钮折到右半截，不如给它整行 —— 实心按钮本来就该是「一块」，
     通栏之后点击热区也跟着变大。
     ⚠️ 2026-09-18 中间它随卡片改成过蓝字链，那时**改成不通栏**是对的
     （一条 12.5px 的文字链拉满整行会变成「字在左、一路空白到右边」）；
     现在回到实心按钮，通栏这条也跟着回来了。两件事是绑在一起的，别只改一半 */
  .dlc-foot .btn{width:100%;justify-content:center;margin-left:0}
  .dv-head,.dv-sec{border-radius:16px}
  .dv-head{padding:15px 14px 14px}
  .dv-title{font-size:24px;letter-spacing:-.7px;margin-top:10px}
  .dv-sum{font-size:13.5px}
  /* 规模数字条在手机上折行：每格给 50%，竖线只管分栏不再管分格 */
  .dv-stats{margin-top:15px;padding-top:14px;row-gap:14px}
  .dv-stat{padding:0 14px}
  .dv-stat:first-child{padding-left:0}
  .dv-stat b{font-size:20px}
  .dv-acts{margin-left:0;padding-left:0;width:100%}
  .dv-sec-h{padding:13px 14px}
  .dv-sec-h i{font-size:22px}
  .dv-sec-h h2{font-size:16.5px;margin-left:11px;padding-left:11px}
  /* 左右同样不留内边距：卖点块自带描边，缩进一次会叠出重线（同上） */
  .dv-sec-b{padding:15px 0 18px}
  /* 手机上两枚按钮各占一半：缩到左边半截会很难点 */
  .dv-acts .btn{flex:1 1 auto;justify-content:center}
  .dv-sec{scroll-margin-top:calc(var(--hdr-h) + 66px)}}

/* ==================== 教程库：产品分类卡 + 产品手册页 ====================
   2026-09-20 改的两级结构：首页一个产品一张卡，点进去是「左目录 + 右正文」。
   原来那套「产品 chips + 类型 chips + 手册卡片网格」三层筛掉了一层 ——
   卡片本身就是分类，再叠筛选条等于让用户把同一件事做两遍。 */

/* ---------- 首页：产品分类卡 ---------- */
/* 每张卡自带一组强调色（--ac / --ac2）：顶部细条、图标底、悬浮描边、主按钮
   都从这两个变量取，一个产品一个色，扫一眼就能分辨。
   色值写成实色而不是 rgba 半透明：图标块和主按钮都是实心底 + 白图标/白字，
   深浅两套主题下都不用各配一份对比色。 */
.tpc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(310px,1fr));gap:14px}
.tpc[data-hue="0"]{--ac:#2563eb;--ac2:#60a5fa;--ac-soft:rgba(37,99,235,.10);--ac-ring:rgba(37,99,235,.26)}
.tpc[data-hue="1"]{--ac:#7c3aed;--ac2:#a78bfa;--ac-soft:rgba(124,58,237,.10);--ac-ring:rgba(124,58,237,.26)}
.tpc[data-hue="2"]{--ac:#0d9488;--ac2:#2dd4bf;--ac-soft:rgba(13,148,136,.10);--ac-ring:rgba(13,148,136,.26)}
.tpc[data-hue="3"]{--ac:#d97706;--ac2:#f59e0b;--ac-soft:rgba(217,119,6,.10);--ac-ring:rgba(217,119,6,.26)}
.tpc[data-hue="4"]{--ac:#e11d48;--ac2:#f43f5e;--ac-soft:rgba(225,29,72,.10);--ac-ring:rgba(225,29,72,.26)}
.tpc{
  position:relative;overflow:hidden;height:100%;
  display:flex;flex-direction:column;gap:11px;
  width:100%;text-align:left;cursor:pointer;font-family:inherit;color:var(--txt);
  padding:15px 15px 13px;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-lg);
  transition:border-color .18s ease,box-shadow .18s ease,transform .18s ease;
}
.tpc:hover{border-color:var(--ac-ring);box-shadow:var(--sh-2);transform:translateY(-3px)}
.tpc:focus-visible{outline:2px solid var(--ac);outline-offset:2px}
/* 顶部 3px 色条：静止时压到半透明（一排卡不至于花成彩带），
   鼠标落上去才亮满 —— 悬停反馈有了，平时也不抢标题 */
.tpc-bar{
  position:absolute;left:0;right:0;top:0;height:3px;
  background:linear-gradient(90deg,var(--ac),var(--ac2));opacity:.45;
  transition:opacity .18s ease;
}
.tpc:hover .tpc-bar,.tpc:focus-visible .tpc-bar{opacity:1}

.tpc-hd{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:12px;align-items:start}
.tpc-ico{
  width:44px;height:44px;border-radius:12px;overflow:hidden;
  display:grid;place-items:center;color:#fff;
  background:linear-gradient(135deg,var(--ac),var(--ac2));
  box-shadow:0 4px 12px -4px var(--ac-ring);
}
.tpc-ico img{display:block;width:100%;height:100%;object-fit:cover}
.tpc-ico svg{width:22px;height:22px}
.tpc-hd-t{min-width:0;display:flex;flex-direction:column;gap:3px}
.tpc-hd-t b{font-size:16.5px;font-weight:800;letter-spacing:-.2px;line-height:1.35}
.tpc-hd-t em{
  font-style:normal;font-size:13px;color:var(--txt-3);line-height:1.55;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.tpc-cat{
  flex:0 0 auto;align-self:start;font-size:11.5px;font-weight:800;white-space:nowrap;
  color:var(--ac);background:var(--ac-soft);border:1px solid var(--ac-ring);
  padding:3px 9px;border-radius:999px;
}

/* 篇名行：整行可点，直接进那一篇。箭头平时藏起来，悬停才滑出来 ——
   不然三行都挂个箭头，卡面全是尖角 */
.tpc-prev{display:flex;flex-direction:column;gap:1px}
.tpc-line{
  display:flex;align-items:center;gap:9px;width:100%;min-width:0;
  font-family:inherit;font-size:13px;color:var(--txt-2);text-align:left;
  background:none;border:0;cursor:pointer;margin:0 -7px;padding:5px 7px;border-radius:9px;
  transition:background .15s ease,color .15s ease;
}
.tpc-line i{
  flex:0 0 auto;font-style:normal;font-size:11.5px;font-weight:900;color:var(--txt-4);
  font-variant-numeric:tabular-nums;
}
.tpc-line > span{
  flex:1 1 auto;min-width:0;line-height:1.5;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.tpc-line svg{
  flex:0 0 auto;width:13px;height:13px;color:var(--ac);
  opacity:0;transform:translateX(-4px);transition:opacity .15s ease,transform .15s ease;
}
.tpc-line:hover{background:var(--ac-soft);color:var(--txt)}
.tpc-line:hover i{color:var(--ac)}
.tpc-line:hover svg{opacity:1;transform:none}
.tpc-more{font-size:12px;color:var(--txt-4);padding:3px 7px 0}

/* 底栏：规模 chips 在左，按钮在右。margin-top:auto 把底栏压到卡底 ——
   同一行的卡高度不齐时，底栏仍然对齐 */
.tpc-ft{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin-top:auto;padding-top:11px;border-top:1px solid var(--line);
}
.tpc-chips{display:flex;gap:6px;flex-wrap:wrap;min-width:0}
.tpc-chips i{
  font-style:normal;font-size:11.5px;font-weight:800;color:var(--txt-2);
  background:var(--solid-2);border:1px solid var(--line);
  padding:3px 9px;border-radius:8px;font-variant-numeric:tabular-nums;
}
/* 产品卡上的端口 pill：客户端 / 代理端。占满一行排在规模 chips 上方，
   让代理商在卡片上就看清这款产品有哪端教程 */
.tpc-ports{display:flex;gap:5px;flex-wrap:wrap;flex:1 1 100%;order:-1}
.pchip{
  font-size:11px;font-weight:800;color:var(--acc-d);
  background:var(--acc-soft);border:1px solid var(--ac-ring);
  padding:2px 8px;border-radius:7px;white-space:nowrap;
}
.pchip.agent{color:#c98a00;background:rgba(255,184,0,.16);border-color:rgba(255,184,0,.42)}
.tpc-btns{margin-left:auto;display:flex;gap:7px;flex:0 0 auto}
.tpc-btn{
  display:inline-flex;align-items:center;gap:5px;flex:0 0 auto;
  font-family:inherit;font-size:12.5px;font-weight:800;white-space:nowrap;
  text-decoration:none;cursor:pointer;padding:7px 12px;border-radius:9px;
  border:1px solid transparent;
  transition:filter .15s ease,color .15s ease,background .15s ease,border-color .15s ease;
}
.tpc-btn svg{width:13px;height:13px}
.tpc-btn.go{
  color:var(--on-acc);background:linear-gradient(135deg,var(--ac),var(--ac2));
  box-shadow:0 3px 10px -4px var(--ac-ring);
}
.tpc-btn.go:hover{filter:brightness(1.08)}
.tpc-btn.sub{color:var(--txt-2);background:var(--solid-2);border-color:var(--line)}
.tpc-btn.sub:hover{color:var(--ac);background:var(--ac-soft);border-color:var(--ac-ring)}
@media (max-width:560px){
  .tpc-grid{grid-template-columns:1fr}
  .tpc-btns{margin-left:0;width:100%}
  .tpc-btn{flex:1 1 auto;justify-content:center}}

/* ---------- 第二级：产品手册页（左目录 + 右正文） ---------- */
.tb-top{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  padding-bottom:12px;margin-bottom:14px;border-bottom:1px solid var(--line);
}
.tb-back{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:6px;cursor:pointer;
  border:1px solid var(--line-2);border-radius:999px;background:var(--solid);
  padding:6px 13px;font-size:13px;font-weight:700;color:var(--txt-2);
  transition:color .16s ease,border-color .16s ease;
}
.tb-back svg{width:14px;height:14px}
.tb-back:hover{color:var(--acc-d);border-color:var(--acc-ring)}
.tb-top-b{display:flex;align-items:baseline;gap:9px;min-width:0}
.tb-top-b b{font-size:17px;font-weight:900;letter-spacing:-.3px}
.tb-top-b span{font-size:12.5px;color:var(--txt-4);white-space:nowrap}
/* 窄屏的下拉目录：宽屏隐藏（那边左侧常驻目录更顺手） */
.tb-pick{margin-left:auto;display:none;min-width:0}
.tb-pick select{
  font-family:inherit;font-size:13.5px;color:var(--txt);
  border:1px solid var(--line-2);border-radius:10px;
  background-color:var(--solid);  /* 同 .rep-row select：别用 background 简写 */
  padding:7px 10px;max-width:100%;
}
.tb-grid{display:grid;grid-template-columns:238px minmax(0,1fr);gap:18px;align-items:start}
/* 目录吸顶：一篇手册能滚好几屏，换下一篇不该先滚回顶部 */
.tb-nav{position:sticky;top:calc(var(--hdr-h) + 12px)}
.tb-nav-in{
  display:flex;flex-direction:column;gap:2px;
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);padding:8px;
}
/* 手册页目录里的端口分段：客户端教程 / 代理端教程 两段，
   段间一条细分隔线，段标题带篇数 chip */
.tb-sec{display:flex;flex-direction:column;gap:2px}
.tb-sec + .tb-sec{margin-top:8px;padding-top:8px;border-top:1px solid var(--line)}
.tb-sec-h{
  display:flex;align-items:center;gap:7px;padding:3px 10px 5px;
  font-size:12px;font-weight:900;color:var(--txt-2);letter-spacing:.3px;
}
.tb-sec-h span{
  font-size:11px;font-weight:800;color:var(--txt-4);
  background:var(--solid-2);border-radius:6px;padding:1px 7px;
  font-variant-numeric:tabular-nums;
}
.tb-row{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:9px;align-items:center;
  width:100%;text-align:left;cursor:pointer;font-family:inherit;color:var(--txt-2);
  padding:9px 10px;border:0;background:transparent;border-radius:9px;
  transition:background .14s ease,color .14s ease;
}
.tb-row i{
  font-style:normal;font-size:12px;font-weight:900;color:var(--txt-4);
  font-variant-numeric:tabular-nums;
}
.tb-row b{
  font-size:13.5px;font-weight:700;line-height:1.5;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.tb-row span{font-size:11.5px;color:var(--txt-4);white-space:nowrap}
.tb-row:hover{background:var(--solid-2)}
.tb-row.on{background:var(--acc-soft);color:var(--acc-d)}
.tb-row.on i{color:var(--acc)}
/* 正文就是原来那套 .tw-hero / .tw-secs / .tw-bar，容器换成 flex column 即可 */
.tb-doc{display:flex;flex-direction:column;gap:14px;min-width:0}
@media (max-width:900px){
  .tb-grid{grid-template-columns:minmax(0,1fr);gap:0}
  .tb-nav{display:none}
  .tb-pick{display:block}}

/* ============================================================
   后台 · 展示开关（哪个库在前台开放）
   ============================================================ */
.ag-tb-r{margin-left:auto;display:flex;align-items:center;gap:10px}
.libs-count{
  font-size:12.5px;font-weight:800;color:var(--txt-3);
  padding:4px 10px;border-radius:999px;background:var(--solid-2);
  border:1px solid var(--line);white-space:nowrap;
}
.libs-tip{
  font-size:12.5px;line-height:1.75;color:var(--txt-3);
  padding:10px 13px;margin-bottom:12px;
  border:1px dashed var(--line-2);border-radius:var(--r-lg);background:var(--solid);
}
.libs-head{
  display:grid;grid-template-columns:110px minmax(0,1fr) 108px;
  gap:10px;padding:9px 14px;background:var(--solid-2);
  font-size:12px;font-weight:800;color:var(--txt-4);
  border-bottom:1px solid var(--line);
}
.libs-head .libs-sw{text-align:right}
.lib-row{
  display:grid;grid-template-columns:110px minmax(0,1fr) 108px;
  gap:10px;align-items:center;padding:11px 14px;
  border-top:1px solid var(--line);transition:background .16s ease;
}
.lib-row:first-child{border-top:0}
.lib-row:hover{background:var(--solid-2)}
.lib-name{font-size:14px;font-weight:800;letter-spacing:-.2px}
.lib-note{font-size:12.5px;color:var(--txt-3);line-height:1.6}
.lib-sw{justify-self:end}
/* 关掉的整行压暗：一眼扫过去就知道哪几个库现在是收着的 */
.lib-row.off .lib-name,.lib-row.off .lib-note{color:var(--txt-4)}
.lib-row.off{background:var(--solid)}

/* ---- 导航设置：一块面板两件事，各带一个小标题 ---- */
.nv-sub{margin-top:18px}
.nv-sub:first-child{margin-top:0}
.nv-sub-h{
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin:0 0 10px;
}
.nv-sub-h b{
  font-size:14.5px;font-weight:900;letter-spacing:-.2px;color:var(--txt);
  padding-left:11px;position:relative;
}
/* 竖线跟侧边栏那颗 bullet 同一个语言：这是面板里的第二级标题 */
.nv-sub-h b::before{
  content:'';position:absolute;left:0;top:3px;bottom:3px;width:3px;
  border-radius:2px;background:var(--acc);
}
.nv-sub-h span{font-size:12.5px;color:var(--txt-3);line-height:1.6}

/* 改名行：第三列要放输入框，比开关那版的 108px 宽一档 */
.libs-head.nm,.lib-row.nm{grid-template-columns:110px minmax(0,1fr) 176px}
.lib-name-in{
  width:100%;height:34px;padding:0 10px;
  font:inherit;font-size:13px;font-weight:700;
  color:var(--txt);background:var(--solid-2);
  border:1px solid var(--line-2);border-radius:var(--r-sm);
  outline:none;transition:border-color .16s ease,background .16s ease;
}
.lib-name-in:focus{border-color:var(--acc);background:var(--solid);box-shadow:0 0 0 3px var(--acc-soft)}
.lib-name-in::placeholder{color:var(--txt-4);font-weight:600}
/* 改过名的行：把内置默认名摆出来，免得改完忘了原来叫什么 */
.lib-def{
  display:block;margin-top:2px;font-size:11.5px;font-weight:600;
  font-style:normal;color:var(--txt-4);letter-spacing:0;
}

@media (max-width:640px){
  .libs-head{display:none}
  .lib-row{grid-template-columns:minmax(0,1fr) auto;gap:8px 10px}
  .lib-note{grid-column:1 / -1;order:3}
  .lib-row.nm{grid-template-columns:minmax(0,1fr);gap:8px}
  .lib-row.nm .lib-sw{justify-self:stretch}
}

/* ==================== 后台侧边导航（admin.html 重做 2026-09-22） ====================
   结构：#adminView > .admin-shell > (.sidebar + .admin-main > .topbar + .page)
   顶栏横向导航改为左侧固定侧栏。（2026-09-23 晚由深蓝渐变改浅色，理由见下方 .sidebar） */
#adminView{height:100vh}
.admin-shell{display:flex;height:100vh;overflow:hidden}

/* 侧栏（2026-09-23 晚改成浅色）。
   ★ 为什么换掉深蓝渐变：整站是浅色（--bg #f8fafc 的内容区 + 白卡片），
     唯独侧栏一整条深蓝，左右两块明度差太大，眼睛每次扫过去都被拽一下；
     而且深色面板上的白字只有「选中/未选中」两档对比，层次做不出来。
     换成白底之后才有「未选中=石板灰 / 悬停=浅蓝底 / 选中=蓝字 + 左色条」
     三级层次，跟右侧白卡片也是同一套语言。
   ★ 品牌色一律写死 #2563eb 系列（--brand / --brand-d），不跟 --acc 走：
     --acc 会随前台 Tab 换色，后台侧栏是常驻框架，跟着变就失去身份锚点。 */
.sidebar{
  flex:0 0 244px;width:244px;height:100%;
  display:flex;flex-direction:column;
  background:var(--solid);color:var(--txt-2);position:relative;z-index:30;
  box-shadow:2px 0 18px -14px rgba(15,23,42,.22);
}
/* 与内容区之间那道 1px 分界：深底时它是白色半透明，浅底换成中性描边 */
.sidebar::after{content:'';position:absolute;top:0;right:0;width:1px;height:100%;background:var(--line)}
/* ⚠️ 2026-09-23 晚：品牌行原来比侧栏本身还宽 —— logo 按 26 高渲染宽 111，
   加上「发布后台 ADMIN」117，合计 239 > 侧栏可用 204（244 减左右各 20）。
   .sb-name 又是 nowrap 不让位，于是文字直接越过侧栏右边界压到顶栏标题上
   （实测 brand.scrollWidth = 259，name 右边界 259 > 侧栏 244）。
   两处一起改：
     1) logo 用 content-box + flex:0 0 auto 锁住 4.262 的比例 —— 不被 flex 压扁；
        原先为深底垫的那层白胶囊在浅底上已经不需要了（这枚 861×202 的整幅
        字标本来就是深灰字、给浅底设计的），垫白反而变成一块白斑。
     2) .sb-name 改成块级 + 省略号：以后往品牌行再加字只会截断，不会再溢出。
        原先它同时是 flex 容器又挂着 nowrap，文字既排不了队也收不了窄。 */
.sb-brand{display:flex;align-items:center;gap:10px;padding:18px 16px 14px;min-height:62px;min-width:0}
.sb-logo{flex:0 0 auto;height:21px;width:auto;box-sizing:content-box}
.sb-name{
  flex:1 1 auto;min-width:0;
  font-weight:800;font-size:16px;letter-spacing:.2px;color:var(--txt);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.sb-name em{font-style:normal;font-size:10px;font-weight:700;letter-spacing:1.6px;color:var(--txt-3);margin-left:7px}
.sb-nav{flex:1 1 auto;overflow-y:auto;padding:4px 12px 12px}
.sb-nav::-webkit-scrollbar{width:6px}
.sb-nav::-webkit-scrollbar-thumb{background:rgba(15,23,42,.14);border-radius:3px}
.sb-group{font-size:11px;font-weight:700;letter-spacing:1.5px;color:var(--txt-3);padding:16px 12px 7px}
.sb-item{
  position:relative;display:flex;align-items:center;gap:11px;width:100%;
  padding:10px 12px;margin:2px 0;border:1px solid transparent;border-radius:11px;
  background:transparent;cursor:pointer;text-align:left;
  color:var(--txt-2);font-size:14px;font-weight:600;line-height:1.2;font-family:inherit;
  transition:background .16s,color .16s,border-color .16s;
}
.sb-item .ic{width:18px;height:18px;flex:0 0 auto;stroke:currentColor;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;opacity:.85}
.sb-item span{flex:1 1 auto;min-width:0}
/* 悬停：浅蓝底 + 加深文字，不换白字 —— 浅底上换白字等于把字擦掉 */
.sb-item:hover{background:rgba(37,99,235,.06);color:var(--acc-d)}
/* 选中：蓝字 + 浅蓝渐变底 + 左侧品牌色条。三处同时给，扫视时第一眼就能定位 */
.sb-item.active{
  background:linear-gradient(90deg,rgba(37,99,235,.11),rgba(37,99,235,.03));
  border-color:rgba(37,99,235,.16);color:#1d4ed8;font-weight:700;
  box-shadow:0 6px 16px -12px rgba(37,99,235,.9);
}
.sb-item.active::before{content:'';position:absolute;left:0;top:50%;transform:translateY(-50%);width:3px;height:20px;border-radius:0 3px 3px 0;background:#2563eb}
.sb-item.active .ic{opacity:1}
.sb-item[hidden]{display:none!important}
.sb-foot{padding:14px 18px 18px;border-top:1px solid var(--line)}
.sb-ver{font-size:11.5px;color:var(--txt-3);font-weight:500}

/* 主区域 */
.admin-main{flex:1 1 auto;min-width:0;height:100%;display:flex;flex-direction:column;background:var(--bg)}
.topbar{
  flex:0 0 auto;height:60px;display:flex;align-items:center;justify-content:space-between;
  padding:0 22px;background:var(--solid);border-bottom:1px solid var(--line);position:relative;z-index:10;
}
.topbar-lead{display:flex;align-items:center;gap:12px;min-width:0}
/* 标题色跟 --txt 走，不写死：后台没有自己的夜色覆盖段，
   写死 #0f172a 在三套深色系里就是「深字压深底」，顶栏标题直接隐身
   （2026-09-25 修：前台选了星渊/极光/曜石，后台跟着进夜色时看不清）。 */
.topbar-title{font-size:17px;font-weight:800;letter-spacing:-.2px;color:var(--txt)}
.topbar-end{display:flex;align-items:center;gap:10px}
.sb-toggle{display:none;align-items:center;justify-content:center;width:38px;height:38px;border:1px solid var(--line);border-radius:10px;background:var(--solid);cursor:pointer;color:var(--txt-2)}
.sb-toggle svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round}

/* 内容区：铺满、去掉底部 tab 留白 */
#adminView .page{
  max-width:none;margin:0;flex:1 1 auto;overflow:auto;
  padding:22px clamp(20px,3vw,40px) 40px;
}

/* 移动端：侧栏变抽屉 + 顶栏汉堡 */
@media (max-width:900px){
  /* 抽屉阴影跟着浅色侧栏一起换中性色：深底那版是 rgba(8,20,50,.6)，
     压在白面板上是一块发青的暗边，看着像没渲染完 */
  .sidebar{position:fixed;top:0;left:0;bottom:0;transform:translateX(-100%);transition:transform .26s ease;box-shadow:12px 0 34px -12px rgba(15,23,42,.28)}
  .admin-shell.nav-open .sidebar{transform:none}
  .sb-toggle{display:inline-flex}
  .topbar{padding:0 14px}
  #adminView .page{padding:16px 14px 32px}}

/* ============================================================================
   色系（skin）
   ----------------------------------------------------------------------------
   四套色系，客户在前端自己选、存在本地；运营在后台设「默认色系」，
   没选过的人进来就用后台那套（由 server.js 写进 cookie，首屏不闪）。

     云锦 dawn    · 现在的这套：中性冷白 + 每页一支身份色（默认）
     星渊 abyss   · 深蓝黑 + 细网格 + 霓虹描边，AI 科技感最强
     极光 aurora  · 深蓝底 + 大面积柔光斑缓慢漂移 + 玻璃卡面
     曜石 obsidian· 中性石墨，几乎不带光，最接近现在的克制感

   用法：html[data-skin="星渊"] 由 JS 写在 <html> 上，本段只负责换变量。
   ⚠️ 加色系请照着下面三块各写一份，别去翻别处 —— 结构（DOM）与脚本都不用动。
   ⚠️ 深色系唯一必须动结构的地方是「白字压在身份色上」：那 28 处已经统一走
      --on-acc，深色系里它反转成深色字，不用逐个改。
   ============================================================================ */

/* ---------- 0. 三套夜色共用：文字反相 + 身份色提亮 ---------- */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]){
  color-scheme:dark;
  --txt:#e9eefb;--txt-2:#a9b7d4;--txt-3:#7d8db0;--txt-4:#5b6a8c;
  --brand:#3b82f6;--brand-2:#93c5fd;--brand-d:#60a5fa;
  --ok:#34d399;--danger:#f87171;
  /* 徽章那套绿在深底上也要反过来：淡绿底改成半透明、字改用亮绿 */
  --ok-soft:rgba(52,211,153,.16);--ok-t:#6ee7b7;--ok-line:rgba(52,211,153,.32);
  --warn-soft:rgba(251,191,36,.12);--warn-t:#fcd34d;--warn-line:rgba(251,191,36,.30);
  /* 身份色整体提亮之后，压在它上面的白字就读不清了 —— 反转成深色字。
     28 处（主按钮 / 激活胶囊 / 步骤序号 / 等级徽章 / KPI 大字…）一次跟着变 */
  --on-acc:#06101f;
  /* 深底上的 9% 淡底几乎看不见，四档浓度整体抬高 */
  --sa:16%;--sl:30%;--sr:40%;--sg:52%;
  --neon:1;
}
/* 夜间身份色：九支各自提亮一档。
   提亮不是拍脑袋 —— 每一支都按「在 #0d1424 上过 4.5:1」挑的（--ct 那列是写字用的，
   要求最严；--c1/--c2 是填充块和大字，过 3:1 即可）。色相一支没动，
   所以「这是哪个库」仍然一眼认得出。 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) body[data-tab="moments"]   {--c1:#10b981;--c2:#6ee7b7;--ct:#4ade80}
/* ↓ 案例库：2026-09-30 由紫 #8b5cf6 换成暖金（浅色那支的同色系提亮档，
      说明见文件开头 body[data-tab="cases"] 那段）。深色档实测
      --c1 7.06:1 / --ct 10.52:1（底取三套深色系里**最亮**的 --solid-2 #22262e，
      比注释里说的 #0d1424 更严），旧紫只有 3.58:1 —— 这次换色在夜里是明确变好的一头。 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) body[data-tab="cases"]     {--c1:#f59e0b;--c2:#fde68a;--ct:#fcd34d}
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) body[data-tab="materials"] {--c1:#14b8a6;--c2:#7ff0e2;--ct:#5eead4}
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) body[data-tab="tools"]     {--c1:#38bdf8;--c2:#bae6fd;--ct:#7dd3fc}
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) body[data-tab="qa"]        {--c1:#3b82f6;--c2:#bfdbfe;--ct:#93c5fd}
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) body[data-tab="tutorials"] {--c1:#6366f1;--c2:#c7d2fe;--ct:#a5b4fc}
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) body[data-tab="deliveries"]{--c1:#5b8cff;--c2:#bfdbfe;--ct:#a8c4ff}
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) body[data-tab="benefits"]  {--c1:#f43f5e;--c2:#fecdd3;--ct:#fda4af;
  /* 封面本来就是深底，夜里要更亮更纯，否则整块发闷 */
  --acc-neon:rgba(244,63,94,.62);--acc-neon-line:rgba(244,63,94,.30);}
/* 个人中心没有自己的库身份色，走品牌蓝；夜里同样要提亮一档，
   否则它比旁边九个库的胶囊都暗一截，看着像「没选中」。 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) body[data-tab="me"]       {--c1:#5b8cff;--c2:#a8c4ff;--ct:#bfdbfe}

/* 夜色里的后台侧栏：选中态/悬停那几条是给浅底调的品牌蓝（#1d4ed8 / rgba(37,99,235,…)），
   压在深底上对比不够，按同一色相提亮一档；滚动条拇指同理。
   （顶栏标题、汉堡按钮已改成跟 --txt/--txt-2，走变量自动反相，不用这里管。） */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .sb-item.active{
  color:#bfdbfe;
  background:linear-gradient(90deg,rgba(96,165,250,.20),rgba(96,165,250,.05));
  border-color:rgba(96,165,250,.32);
  box-shadow:0 6px 16px -12px rgba(59,130,246,.9);
}
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .sb-item.active::before{background:#60a5fa}
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .sb-item:hover{background:rgba(96,165,250,.10);color:#dbe7ff}
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .sb-nav::-webkit-scrollbar-thumb{background:rgba(150,193,255,.22)}

/* ---------- 1. 星渊 ---------- */
html[data-skin="abyss"]{
  --bg:#060a13;
  --solid:#0d1424;      /* 卡片 / 弹窗的面 */
  --surface:#111a2e;    /* 卡片里再垫一层的小面板 */
  --solid-2:#16203a;    /* 输入框 / 胶囊底 */
  --line:rgba(150,193,255,.13);
  --line-2:rgba(150,193,255,.20);
  --line-3:rgba(150,193,255,.30);
  /* 浅色那套「往下投的柔光」在深底上等于没有，层次改由「边框提亮 + 内侧高光」表达 */
  --sh-1:0 1px 0 rgba(255,255,255,.03) inset,0 2px 10px -6px rgba(0,0,0,.6);
  --sh-2:0 1px 0 rgba(255,255,255,.04) inset,0 10px 28px -18px rgba(0,0,0,.9);
  --sh-3:0 20px 50px -26px rgba(0,0,0,.95);
  --sh-brand:0 1px 0 rgba(255,255,255,.06) inset;
  --sh-brand-2:0 6px 18px -10px var(--acc-glow);
  --glass:14px;--grid-c:rgba(120,175,255,.055);--orb:1;--img-b:.94;
}
/* ---------- 2. 极光 ---------- */
html[data-skin="aurora"]{
  --bg:#070a18;
  --solid:#0f1528;
  --surface:#151d38;
  --solid-2:#1a2242;
  --line:rgba(255,255,255,.10);
  --line-2:rgba(255,255,255,.16);
  --line-3:rgba(255,255,255,.24);
  --sh-1:0 1px 0 rgba(255,255,255,.06) inset,0 8px 24px -14px rgba(0,0,0,.7);
  --sh-2:0 1px 0 rgba(255,255,255,.07) inset,0 16px 40px -22px rgba(0,0,0,.9);
  --sh-3:0 30px 70px -30px rgba(0,0,0,1);
  --sh-brand:0 1px 0 rgba(255,255,255,.08) inset;
  --sh-brand-2:0 8px 22px -10px var(--acc-glow);
  --glass:22px;--grid-c:rgba(255,255,255,.035);--orb:1;--img-b:.95;
}
/* ---------- 3. 曜石 ---------- */
html[data-skin="obsidian"]{
  --bg:#0e1014;
  --solid:#171b21;
  --surface:#1b1f26;
  --solid-2:#22262e;
  --line:rgba(255,255,255,.07);
  --line-2:rgba(255,255,255,.12);
  --line-3:rgba(255,255,255,.20);
  --sh-1:0 1px 2px rgba(0,0,0,.5);
  --sh-2:0 2px 8px -4px rgba(0,0,0,.7);
  --sh-3:0 18px 40px -24px rgba(0,0,0,.9);
  --sh-brand:0 1px 2px rgba(0,0,0,.55);
  --sh-brand-2:0 4px 12px -8px var(--acc-glow);
  /* 这套刻意不带光：没有网格、没有光斑、发光只留三分之一 */
  --neon:.34;--glass:0px;--grid-c:transparent;--orb:0;--img-b:.96;
}

/* ---------- 4. 夜色里才打开的那几层氛围 ---------- */
/* 背景网格 + 三颗光斑。云锦下 --orb:0 / --grid-c:transparent，等于完全关闭，
   和现在这套「干净的中性底」一模一样；只有深色系才把开关拨上去。 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .bg-grid{
  display:block;
  position:absolute;inset:0;
  background-image:
    linear-gradient(var(--grid-c) 1px,transparent 1px),
    linear-gradient(90deg,var(--grid-c) 1px,transparent 1px);
  background-size:var(--grid-size) var(--grid-size);
  mask-image:radial-gradient(120% 90% at 50% 0%,#000 30%,transparent 78%);
}
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .bg-orb{
  display:block;position:absolute;border-radius:50%;
  filter:blur(90px);opacity:var(--orb);animation:drift 26s ease-in-out infinite;
}
@keyframes drift{
  0%,100%{transform:translate3d(0,0,0) scale(1)}
  50%{transform:translate3d(40px,54px,0) scale(1.08)}
}
@media (prefers-reduced-motion:reduce){
  html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .bg-orb{animation:none}}
html[data-skin="abyss"]  .o1{width:560px;height:560px;top:-180px;left:-120px;background:radial-gradient(circle,color-mix(in srgb,var(--acc) 34%,transparent),transparent 66%)}
html[data-skin="abyss"]  .o2{width:480px;height:480px;top:180px;right:-160px;animation-delay:-8s;background:radial-gradient(circle,rgba(56,189,248,.24),transparent 66%)}
html[data-skin="abyss"]  .o3{width:420px;height:420px;bottom:-160px;left:34%;animation-delay:-15s;background:radial-gradient(circle,rgba(129,140,248,.20),transparent 66%)}
html[data-skin="aurora"] .o1{width:620px;height:620px;top:-220px;left:-140px;animation-duration:18s;background:radial-gradient(circle,rgba(34,211,238,.52),transparent 62%);filter:blur(80px)}
html[data-skin="aurora"] .o2{width:540px;height:540px;top:140px;right:-180px;animation-duration:18s;animation-delay:-6s;background:radial-gradient(circle,rgba(167,139,250,.52),transparent 62%);filter:blur(80px)}
html[data-skin="aurora"] .o3{width:480px;height:480px;bottom:-180px;left:32%;animation-duration:18s;animation-delay:-12s;background:radial-gradient(circle,rgba(59,130,246,.46),transparent 62%);filter:blur(80px)}

/* ---------- 5. 夜色里的结构微调（只动这几处，其余全靠变量） ---------- */
/* 顶栏 / 底栏做成半透明玻璃：夜里压住下面滚过去的内容，比一整条实色更轻 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .appbar,
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .tabbar,
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .topbar{
  background:color-mix(in srgb,var(--bg) 74%,transparent);
  backdrop-filter:blur(var(--glass));
}
/* 底栏两端那两条渐隐跟着玻璃走：比本体略实一点（84% vs 74%），
   这样它盖得住下面滑过去的图标，又不至于在玻璃条上留下一块死板的实色。
   不写这一组的话，它就还是基础层的 var(--solid) —— 夜里是深色，看着像两道黑杠。 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .tabbar::before{
  background:linear-gradient(to right,color-mix(in srgb,var(--bg) 84%,transparent) 26%,transparent);
}
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .tabbar::after{
  background:linear-gradient(to left,color-mix(in srgb,var(--bg) 84%,transparent) 26%,transparent);
}
/* 顶栏下沿那道身份色细线：夜里唯一留着的「发光」提示 */
html:is([data-skin="abyss"],[data-skin="aurora"]) .appbar{
  box-shadow:0 1px 0 0 color-mix(in srgb,var(--acc) calc(var(--neon) * 18%),transparent);
}
/* Hero / 卡片：内侧高光 + 悬停时身份色描边发光 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .hero,
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .qa-hero{
  position:relative;
}
/* 问答库的搜索 hero 自带一层写死的浅色底（#f4f8ff→#fff），夜里不覆盖它
   就是一大块白补丁，白字压在上面直接看不见 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .qa-hero{
  background:
    radial-gradient(880px 400px at 50% -32%, color-mix(in srgb,var(--acc) 24%,transparent), transparent 66%),
    radial-gradient(560px 320px at 90% 116%, rgba(0,194,255,.14), transparent 70%),
    linear-gradient(180deg,var(--solid),var(--bg) 68%);
}
/* 七库 hero 的氛围底在夜里要整体加强一档：柔光 17%→26% / 15%→20%，
   底从「卡面→卡面」换成「卡面→页面底」——夜里卡面与页面底本来就分得开，
   过渡到 --bg 才压得住下面滚过去的深色内容，不会浮着一块浅色补丁 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .hero{
  background:
    radial-gradient(760px 320px at 20% -46%, color-mix(in srgb,var(--acc) 26%,transparent), transparent 68%),
    radial-gradient(520px 280px at 94% 122%, color-mix(in srgb,var(--acc-2) 20%,transparent), transparent 72%),
    linear-gradient(180deg, var(--solid), var(--bg) 66%);
}
/* 点阵在夜里太亮会抢正文，透明度压到一半 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .hero::before{
  background-image:radial-gradient(color-mix(in srgb,var(--acc) 12%,transparent) 1px,transparent 1px);
}
/* 图形签名在夜里本来就更显（底暗对比大），整体再淡一档 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .hero-sign{opacity:.11}
html:is([data-skin="abyss"],[data-skin="aurora"]) .hero::after,
html:is([data-skin="abyss"],[data-skin="aurora"]) .qa-hero::after{
  content:"";position:absolute;left:0;right:0;top:0;height:1px;pointer-events:none;
  background:linear-gradient(90deg,transparent,var(--acc-ring),transparent);
  opacity:var(--neon);
}
/* KPI 那几个渐变大字：background-clip:text 之后 text-shadow 不起作用，用 drop-shadow */
html:is([data-skin="abyss"],[data-skin="aurora"]) .kpi b,
html:is([data-skin="abyss"],[data-skin="aurora"]) .hero h1 .gt{
  filter:drop-shadow(0 0 14px var(--acc-glow));
}
/* 图片：亮图在深底上会「发飘」，压一点亮度；logo 反而要提亮一点 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) img{filter:brightness(var(--img-b))}
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .brand-logo,
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .sb-logo{filter:brightness(1.12)}
/* 遮罩类（灯箱 / 弹窗 / 引导层）在夜里要更深，否则压不住底下的内容 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .lb-backdrop,
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .qam-mask,
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .modal-mask,
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .tray-mask,
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .wxdl-mask{
  background:rgba(2,5,12,.78);
}
/* 输入类控件：placeholder 用 --txt-4，深底上它太暗会看不见，抬一档 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) input::placeholder,
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) textarea::placeholder{color:var(--txt-3)}
/* 下拉浮层里的搜索图标等次要图形跟着文字一起提亮 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) select{
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238ba0c4' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}
/* 切换色系时的过渡：整套变量一起换会有一次突变，给个短过渡抹掉棱角。
   尊重系统的「减少动态效果」设置 */
@media (prefers-reduced-motion:no-preference){
  html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) body,
  html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .appbar,
  html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .card,
  html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .hero,
  html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .kpi{
    transition:background-color .28s ease,border-color .28s ease,box-shadow .28s ease;
  }}

/* ---------- 6. 色系选择器（顶栏那枚按钮 + 浮层） ----------
   客户从这里换色系。浮层里四套各带一块色卡，不用切过去试就知道是亮是暗。
   样式全走变量，所以四套色系里它自己也是同一副样子，只是跟着变。 */
.appbar-end{position:relative}
.skin-btn{
  flex:0 0 auto;height:38px;display:inline-flex;align-items:center;gap:6px;cursor:pointer;
  padding:0 11px;border-radius:12px;border:1px solid var(--line-2);
  background:var(--solid-2);color:var(--txt-2);
  font-size:13px;font-weight:700;transition:color .16s,border-color .16s,box-shadow .16s;
}
.skin-btn svg{width:16px;height:16px;display:block}
.skin-btn:hover{color:var(--acc-d);border-color:var(--acc)}
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .skin-btn:hover{box-shadow:0 0 0 3px var(--acc-soft)}
/* 手机上顶栏地方紧，只留图标，文字撤掉（aria-label / title 仍可读） */
@media (max-width:1023px){
  .skin-btn{padding:0 9px}
  .skin-btn-t{display:none}}
.skin-pop{
  position:absolute;right:0;top:calc(100% + 8px);z-index:120;
  width:264px;max-width:calc(100vw - 28px);
  border:1px solid var(--line);border-radius:var(--r-lg);
  background:var(--solid);box-shadow:var(--sh-3);
  padding:8px;
}
/* 深色系下浮层要更实一点：它压在内容上，半透明会把下面的字透上来 */
html:is([data-skin="abyss"],[data-skin="aurora"],[data-skin="obsidian"]) .skin-pop{
  background:color-mix(in srgb,var(--solid) 92%,#000);
  backdrop-filter:blur(var(--glass));
}
.skin-pop-h{
  display:flex;align-items:baseline;gap:8px;padding:6px 8px 8px;
  font-size:12px;font-weight:800;color:var(--txt-2);
}
.skin-pop-h em{font-style:normal;font-size:11px;font-weight:600;color:var(--txt-4);margin-left:auto}
.skin-item{
  width:100%;display:flex;align-items:center;gap:10px;cursor:pointer;text-align:left;
  border:1px solid transparent;background:transparent;border-radius:12px;padding:8px;
  transition:background .16s,border-color .16s;
}
.skin-item:hover{background:var(--solid-2)}
.skin-item.on{border-color:var(--acc-line);background:var(--acc-soft)}
.skin-sw{
  flex:0 0 auto;width:44px;height:28px;border-radius:8px;
  border:1px solid var(--line-2);box-shadow:var(--sh-1);
}
.skin-t{display:grid;gap:1px;min-width:0}
.skin-t b{font-size:13.5px;font-weight:800;color:var(--txt)}
.skin-t em{font-style:normal;font-size:11px;font-weight:600;color:var(--txt-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.skin-ok{
  flex:0 0 auto;width:18px;height:18px;border-radius:50%;margin-left:auto;
  display:grid;place-items:center;font-size:11px;font-weight:800;
  color:var(--on-acc);background:var(--grad);opacity:0;transition:opacity .16s;
}
.skin-item.on .skin-ok{opacity:1}

/* ---------- 后台「站点设置」那一页 ----------
   只有这一页用得上，所以集中放在文件末尾，不混进通用表单那一截。
   素材：
   · .site-card / .site-body   卡片与内边距（比 .card 默认那套松一点，表单多）
   · .site-img / .si-*         Logo、Favicon 的「预览 + 上传」行
   · .site-check               开关行（沿用 .libs-sw 那枚 checkbox 的观感）
   ⚠️ 预览框要压**深背**：Logo 很可能是透明底深色字，白底预览看不清，
      给一层棋盘底又太吵，所以统一用页面底色 + 描边，并给 icon 那种方图
      单独一个 32px 的小框（模拟浏览器标签上的实际大小）。 */
.site-card{margin-bottom:14px}
.site-body{padding:16px 18px 18px}
.site-img{display:flex;gap:14px;align-items:flex-start;flex-wrap:wrap}
.si-prev{
  flex:0 0 auto;display:grid;place-items:center;overflow:hidden;
  border:1px solid var(--line-2);border-radius:12px;background:var(--bg);
}
.si-prev.logo{min-width:150px;height:56px;padding:6px 10px}
.si-prev.logo img{max-height:40px;max-width:130px;width:auto;height:auto;display:block}
.si-prev.icon{width:48px;height:48px}
.si-prev.icon img{width:32px;height:32px;object-fit:contain;display:block}
.si-none{font-size:10px;font-weight:700;color:var(--txt-4);text-align:center;line-height:1.3}
.si-act{flex:1 1 220px;min-width:0;display:grid;gap:7px}
.si-path{
  font-size:11.5px;font-weight:600;color:var(--txt-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.site-check{
  display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  padding:11px 13px;border:1px solid var(--line);border-radius:12px;
  background:var(--solid-2);cursor:pointer;user-select:none;
}
.site-check input{
  flex:0 0 auto;width:17px;height:17px;margin:0;cursor:pointer;
  accent-color:var(--acc);
}
.site-check > span{font-size:13.5px;font-weight:700;color:var(--txt)}
.site-check > em{font-style:normal;font-size:11.5px;font-weight:600;color:var(--txt-4)}
/* ============================================================
   平台公告（2026-10-09 加）
   ------------------------------------------------------------
   公告跨前后台：前台是个人中心的折叠清单（骨架在 auth.css 的 .nc-list），
   后台是「公告管理」面板（.nc-head / .nc-row）。
   ⚠️ 标签色标 .nc-tag 与置顶徽章 .nc-pin 两边共用，所以放在 app.css ——
      前台与后台都引这个文件，写在哪边的文件里另一边就取不到。
   ============================================================ */

/* ---------- 未读红标 ----------
   挂在「个人中心」入口右上角：顶栏 .tab 与移动端底栏 .tabbar-btn 上各一枚。
   ⚠️ .tab 本身没有 position:relative，这里必须补 —— 少了它红标会飘到
      上一个定位祖先（顶栏容器）的角上，看起来像挂在「问答库」上。
   ⚠️ 隐藏用 [hidden] 显式压掉 display：.tab / .tabbar-btn 的 CSS 都给了
      display，会盖掉 hidden 属性（与退役 Tab 是同一个坑）。 */
.tab { position: relative; }
.ndot {
  position: absolute; top: -3px; right: -3px; z-index: 2;
  min-width: 17px; height: 17px; padding: 0 5px; box-sizing: border-box;
  border-radius: 999px; background: linear-gradient(135deg, #ff6b6b, #e11d48);
  color: #fff; font-size: 10.5px; font-weight: 800; line-height: 17px; text-align: center;
  box-shadow: 0 0 0 2px var(--solid), 0 2px 6px -2px rgba(225, 29, 72, .7);
  font-variant-numeric: tabular-nums; pointer-events: none;
}
.tabbar-btn .ndot { top: -1px; right: 4px; box-shadow: 0 0 0 2px var(--bg), 0 2px 6px -2px rgba(225, 29, 72, .7); }
.ndot[hidden] { display: none !important; }

/* ---------- 标签色标 / 置顶徽章（前后台共用） ---------- */
.nc-tag {
  flex: 0 0 auto; font-size: 11px; font-weight: 800; padding: 2px 7px; border-radius: 6px;
  background: var(--solid-2); color: var(--txt-3);
}
.nc-tag.imp { background: linear-gradient(135deg, #fff1f0, #ffe4e2); color: #b42318; }
.nc-tag.act { background: linear-gradient(135deg, #eef4ff, #e6eeff); color: #3538cd; }
.nc-tag.upd { background: linear-gradient(135deg, #ecfdf3, #dcfce7); color: #027a48; }
.nc-pin {
  flex: 0 0 auto; font-size: 11px; font-weight: 800; color: #b54708;
  background: #fffaeb; border: 1px solid #fedf89; border-radius: 6px; padding: 2px 6px;
}
/* 深色皮肤：浅底换成半透明、文字提亮。与等级卡那套覆盖同一条理由 ——
   上面那组值是按白底配的，夜里浅底块会自己发光、深字会糊进黑底。 */
html:is([data-skin="abyss"], [data-skin="aurora"], [data-skin="obsidian"]) .nc-tag.imp {
  background: rgba(225, 29, 72, .16); color: #fda29b;
}
html:is([data-skin="abyss"], [data-skin="aurora"], [data-skin="obsidian"]) .nc-tag.act {
  background: rgba(79, 110, 247, .16); color: #a5b8ff;
}
html:is([data-skin="abyss"], [data-skin="aurora"], [data-skin="obsidian"]) .nc-tag.upd {
  background: rgba(2, 122, 72, .18); color: #6ee7a8;
}
html:is([data-skin="abyss"], [data-skin="aurora"], [data-skin="obsidian"]) .nc-pin {
  background: rgba(245, 158, 11, .16); color: #fcd34d; border-color: rgba(245, 158, 11, .34);
}

/* ============================================================
   后台「公告管理」面板
   ------------------------------------------------------------
   列表骨架照着「导航设置」的 .lib-row 那套来的：一张没有边框的 flush 卡片，
   行与行之间靠细分隔线，不靠卡片 —— 公告一行能读完，套卡片反而臃肿。
   ============================================================ */
.nc-head {
  display: grid; grid-template-columns: 1fr 78px 108px 150px; gap: 10px;
  padding: 9px 14px; font-size: 11.5px; font-weight: 800; color: var(--txt-4);
  border-bottom: 1px solid var(--line); letter-spacing: .3px;
}
.nc-row {
  display: grid; grid-template-columns: 1fr 78px 108px 150px; gap: 10px; align-items: center;
  padding: 11px 14px; border-bottom: 1px solid var(--line); cursor: pointer;
  transition: background .16s;
}
.nc-row:last-child { border-bottom: 0; }
.nc-row:hover { background: var(--solid-2); }
.nc-row.off { opacity: .55; }
.nc-row.on { background: var(--acc-soft); }
.nc-row .nc-t {
  min-width: 0; font-size: 13.5px; font-weight: 700; color: var(--txt);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  display: flex; align-items: center; gap: 7px;
}
.nc-row .nc-at { font-size: 12px; color: var(--txt-4); font-variant-numeric: tabular-nums; }
.nc-row .nc-c { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.nc-row .nc-n { font-style: normal; font-size: 11.5px; font-weight: 600; color: var(--txt-4); }
.nc-empty { padding: 26px 14px; text-align: center; font-size: 13.5px; color: var(--txt-4); }

/* 表单尾部：两个开关 + 已读人数 + 三个按钮 */
.nc-sw { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; margin: 4px 0 16px; }
.nc-sw label {
  display: inline-flex; align-items: center; gap: 7px; margin: 0;
  font-size: 13px; font-weight: 700; color: var(--txt); cursor: pointer;
}
.nc-sw input { flex: 0 0 auto; width: 16px; height: 16px; margin: 0; accent-color: var(--acc); cursor: pointer; }
.nc-sw .nc-read { font-size: 12px; font-weight: 600; color: var(--txt-4); }
.nc-act { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

@media (max-width: 900px) {
  /* 窄屏把「发布」那一列收掉：日期是运营次要信息，标题不能被它挤没 */
  .nc-head, .nc-row { grid-template-columns: 1fr 70px 130px; }
  .nc-head .nc-at, .nc-row .nc-at { display: none; }
}
