/* =============================================================
   SQB PULSE —— 商业脉冲中枢
   设计系统 v2.0
   基调：明亮 / 通透 / 轻薄玻璃 / 品牌渐变
   -------------------------------------------------------------
   本文件只负责「结构与排版」，颜色一律走语义变量：
   换主题时由 assets/css/theme.css 覆盖变量即可，不必改这里。
   ============================================================= */

/* 数字输入框：全站统一隐藏浏览器自带的上下增减箭头（金额/排序一律手动输入） */
input[type="number"]{appearance:textfield;-moz-appearance:textfield}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button{
  -webkit-appearance:none;appearance:none;margin:0;opacity:0;pointer-events:none
}

:root{
  /* ---------- 语义色：亮色基线 ---------- */
  --bg:#f4f7fd;              /* 页面底色 */
  --bg-1:#f4f7fd;            /* logo 墙左右遮罩渐隐底色（各主题须随 --bg 覆盖） */
  --bg-2:#e9effb;            /* 底色渐层 */
  --bg-3:#ffffff;            /* 卡片实底 */
  --surface:rgba(255,255,255,.78);   /* 玻璃表面 */
  --surface-2:rgba(255,255,255,.94); /* 表面（悬停/强调） */
  --surface-3:rgba(16,32,72,.035);   /* 极浅填充（代码块等） */
  --line:rgba(16,32,72,.10);
  --line-2:rgba(16,32,72,.20);
  --line-3:rgba(16,32,72,.30);

  --ink:#101c3a;             /* 主文字 */
  --ink-2:#3d4c72;           /* 次级文字 */
  /* 顶栏一级菜单专用墨色：仿收钱吧官网顶栏的深藏青 #002742（15px/700）。
     各节日主题在 theme.css 里用 `[data-theme]{--nav-ink:var(--ink)}` 统一改回自己的主文字色，
     这样换主题时顶栏不会留在一块死板的深藏青上。 */
  --nav-ink:#002742;
  --muted:#4f5e78;           /* 弱文字（加深至 ≥4.5:1 对比度，整改 #13） */
  --dim:#5b6c88;             /* 最弱文字（同上） */
  --on-media:#ffffff;        /* 压在图片/视频上的文字 */

  /* ---------- 品牌色 ---------- */
  --brand:#2b6bff;
  --brand-2:#6f5bff;
  --brand-3:#a34fd8;
  --accent:#0e8fbf;          /* 青 */
  --accent-2:#12a86a;        /* 绿 */
  --gold:#c8901a;

  --grad:linear-gradient(100deg,#2b6bff 0%,#6f5bff 34%,#a34fd8 66%,#e0509a 100%);
  --grad-soft:linear-gradient(100deg,rgba(43,107,255,.12),rgba(111,91,255,.10),rgba(224,80,154,.09));

  /* ---------- 覆盖层 ---------- */
  --nav-bg:rgba(255,255,255,.82);
  --sheet-bg:rgba(255,255,255,.97);
  /* 顶栏大面板配色（产品矩阵 / 行业动态等所有带分组栏目共用）：
     **所有栏目同一套规则** —— 面板整体白底、满宽展开，层次只靠细线与激活项表达：
       · 面板底  = --mega-bg    纯白（二级行、三级内容区同一底色）；
       · 分区    = --line 细线（.mega__lv2 底边 / .mega__lv3 顶边）；
       · 按钮    = 白底描边圆角药丸（.mega__lv2item 与 .mega__card--text 同一套规则）；
       · 激活项  = 品牌蓝填充白字。
     悬停/激活统一走品牌蓝淡底 --mega-head-bg-on。 */
  --mega-bg:#ffffff;                    /* 面板底色：纯白实底（所有栏目统一） */
  --mega-head-bg:#f4f6fa;               /* 二级项悬停药丸 / 图标占位瓦片底（中性浅灰） */
  --mega-head-bg-on:rgba(43,107,255,.10);/* 二级/三级悬停激活（品牌蓝淡底） */
  --overlay:rgba(12,20,42,.62);
  --media-bg:#0b1020;

  /* ------------------------------------------------------------------
     非颜色差异维度（主题可覆写）
     ----------------------------------------------------------
     只换颜色做不出辨识度：改造前 17/18 个主题的 --bg 都压在 95%~98% 近白区间，
     访客肉眼分不出来。真正让人「感觉到过节」的是下面这些非颜色轴，
     它们都只需在 [data-theme="…"] 里给一行值就生效：
       形状 --radius-mul    圆角倍率（0.6=方正硬朗 / 1.6=圆润童趣）
       光晕 --aura-a/b/c    背景三团环境光（56vw 大尺度，存在感极强）
       纹理 --bg-texture    可平铺的小图案（星点 / 格纹 / 斜纹）
       质感 --grid-op/--grid-line/--noise-op  科技网格与胶片颗粒的强度
     ⚠️ 全站字号一律用 px 与 clamp(px,vw,px)、零 rem，
        所以「根字号缩放」这条路在本项目行不通，别再尝试改用 rem 来实现字号倍率。
     ------------------------------------------------------------------ */
  --radius-mul:1;

  /* 环境光晕：原本写死在 .cosmos__aurora--a/b/c 里的蓝紫，红底/暖色主题上会脏 */
  --aura-a:rgba(43,107,255,.30);
  --aura-b:rgba(111,91,255,.24);
  --aura-c:rgba(224,80,154,.16);
  --aura-op:.5;

  /* 平铺纹理（默认不铺）+ 网格 / 颗粒质感 */
  --bg-texture:none;
  --tex-op:0;
  --tex-size:120px 120px;
  --grid-op:.5;
  --grid-line:rgba(43,107,255,.055);
  --noise-op:.025;

  --radius:calc(22px * var(--radius-mul));
  --radius-sm:calc(14px * var(--radius-mul));
  --radius-pill:999px;

  --shadow-glow:0 0 0 1px rgba(16,32,72,.05), 0 26px 60px -30px rgba(43,107,255,.42);
  --shadow-card:0 22px 50px -30px rgba(18,34,78,.30);
  --shadow-soft:0 10px 30px -18px rgba(18,34,78,.28);
  --shadow-drop:0 40px 80px -40px rgba(18,34,78,.34);

  --maxw:1140px;
  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);

  --nav-h:74px;

  /* 全站字号上限：任何文字都不得大于 logo（.brand 直接取这个值）。
     大标题等用 min(var(--fs-cap), 原尺寸) 收口 —— 保留响应式缩放，但永远不越过 logo。 */
  --fs-max:22px;            /* logo 字号（导航/品牌文字上限） */
  --fs-cap:64px;             /* 内容标题/指标字号上限（整改 #11：与 logo 解耦，恢复层级） */

  /* 主题可选的顶部彩带（节日主题会点亮它） */
  --ribbon:none;

  /* 全站是亮色主题，必须显式声明：
     不声明时 Windows/浏览器深色模式会把「文本光标（I 形指针）」和下拉弹层画成白色，
     白底输入框上就看不见光标，像是失效了 */
  color-scheme:light;
}

/* 文本光标统一处理：
   ① 插入符用主文字色；② I 形鼠标指针必须自定义 —— 它由操作系统绘制，
   Windows 深色模式下系统把 I 形指针画成白色，页面声明 color-scheme:light
   也管不到它，白底输入框上就「消失」。这里用 SVG 换成深色工字指针
   （白色描边打底，深浅背景都可见），热点居中 (12,12)。 */
input,textarea,select,[contenteditable="true"],[contenteditable=""]{
  caret-color:var(--ink);
  cursor:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='white' stroke-width='4.4' stroke-linecap='round'%3E%3Cpath d='M9.4 3.4h5.2M9.4 20.6h5.2M12 5v14'/%3E%3C/g%3E%3Cg fill='none' stroke='%23101c3a' stroke-width='1.8' stroke-linecap='round'%3E%3Cpath d='M9.4 3.4h5.2M9.4 20.6h5.2M12 5v14'/%3E%3C/g%3E%3C/svg%3E") 12 12, text;
  caret-shape:bar;
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;background:var(--bg);scrollbar-gutter:stable}
/* ⚠️ 2026-10-21：跨页滚动条槽位一致（消除短论坛→长主站整页往右抖的割裂感）。
   根因：站点全局 ::-webkit-scrollbar{width:10px}（pulse.css:131）在部分 Chrome 版本里只在
   「真有滚动」时才让出 10px，导致短页（论坛）比长页（主站）宽 10px、跨页整页左右抖一下。
   修法：滚动容器是 body（body{overflow-x:hidden} 把 overflow-y 算成 auto），给 body 加
   overflow-y:scroll ——「scroll」会永远渲染滚动条槽位（不滚动时为空置/禁用态），
   有/无滚动的页面可用宽度恒定一致，跨版本 100% 可靠（不依赖 scrollbar-gutter 支持度）。
   同时保留 scrollbar-gutter:stable 作为更优层：支持的浏览器在短页不显示滚动条也能预留槽位。
   代价：短页（论坛/登录）右下角会常驻一个禁用态滚动条——这是保证宽度一致、消除抖动的必要代价。 */
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:"Inter","SF Pro Display","PingFang SC","HarmonyOS Sans SC","Microsoft YaHei",system-ui,-apple-system,sans-serif;
  font-size:16px;line-height:1.7;letter-spacing:.01em;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;overflow-y:scroll;scroll-behavior:smooth;scrollbar-gutter:stable;
}
body.is-locked{overflow:hidden}
img,video,svg{max-width:100%;display:block}
/* height 属性（img_dim 输出的宽高声明）在 max-width 压缩宽度后必须等比放开，
   否则移动端「宽被压、高锁死」图片会拉变形；CSS 类里显式给了高度的会覆盖这条 */
img{height:auto}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
::selection{background:rgba(43,107,255,.22);color:var(--ink)}

/* 无障碍：只给屏幕阅读器的文本（如页面唯一 h1 的兜底） */
.sr-only{
  position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}

/* 滚动条 */
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:var(--bg-2)}
::-webkit-scrollbar-thumb{background:linear-gradient(180deg,#8fb4ff,#b6a6ff);border-radius:10px;border:3px solid var(--bg-2)}
::-webkit-scrollbar-thumb:hover{background:linear-gradient(180deg,#6f9dff,#a08cff)}

/* =============================================================
   氛围底：柔光 / 网格 / 噪点
   注意：画布星场只服务于暗色主题，亮色下默认隐藏，
   需要它的主题会在 theme.css 里显式打开（.cosmos canvas{display:block}）。
   ============================================================= */
.cosmos{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;
  background:radial-gradient(120% 80% at 12% -10%,var(--bg-3),transparent 60%),
             linear-gradient(180deg,var(--bg),var(--bg-2));
}
.cosmos canvas{position:absolute;inset:0;width:100%;height:100%;display:none}
/* 主题平铺纹理。用 ::after 而不是新增 DOM 节点，改主题不需要动 layout.php。
   默认 --tex-op:0 —— 不铺纹样的主题这里完全不参与渲染。 */
.cosmos::after{
  content:"";position:absolute;inset:0;
  background-image:var(--bg-texture);
  background-size:var(--tex-size);
  background-repeat:repeat;
  opacity:var(--tex-op);
}
.cosmos__aurora{
  position:absolute;border-radius:50%;filter:blur(90px);opacity:var(--aura-op);
  animation:drift 26s var(--ease) infinite alternate;
}
.cosmos__aurora--a{width:56vw;height:56vw;left:-14vw;top:-16vw;background:radial-gradient(circle at 40% 40%,var(--aura-a),transparent 62%)}
.cosmos__aurora--b{width:48vw;height:48vw;right:-12vw;top:6vh;background:radial-gradient(circle at 50% 50%,var(--aura-b),transparent 64%);animation-delay:-8s}
.cosmos__aurora--c{width:52vw;height:52vw;left:22vw;bottom:-24vw;background:radial-gradient(circle at 50% 50%,var(--aura-c),transparent 66%);animation-delay:-16s}
@keyframes drift{
  0%{transform:translate3d(0,0,0) scale(1)}
  50%{transform:translate3d(4vw,-3vh,0) scale(1.14)}
  100%{transform:translate3d(-3vw,4vh,0) scale(1.04)}
}
.cosmos__grid{
  position:absolute;inset:0;opacity:var(--grid-op);
  background-image:linear-gradient(var(--grid-line) 1px,transparent 1px),
                   linear-gradient(90deg,var(--grid-line) 1px,transparent 1px);
  background-size:78px 78px;
  mask-image:radial-gradient(ellipse 130% 80% at 50% 0%,#000 12%,transparent 76%);
  -webkit-mask-image:radial-gradient(ellipse 130% 80% at 50% 0%,#000 12%,transparent 76%);
}
.cosmos__noise{
  position:absolute;inset:0;opacity:var(--noise-op);mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* 指针光晕 */
/* 2026-10-20 二十批：指针光晕的裁剪层。
   pulse.js 用 JS 写 transform:translate(cx-260,cy-260) 让光晕跟鼠标走。
   fixed + transform 的元素会自建包含块，逃出 html{overflow-x:hidden} 的裁剪 ——
   鼠标移到视口右侧时光晕会撑出横向滚动条（窄屏尤其明显）。
   外面套一层 fixed + overflow:hidden 的包裹层，把光晕的溢出部分裁掉，
   既不产生滚动条，也不影响光晕跟着鼠标跑。 */
.pointer-glow-wrap{position:fixed;inset:0;z-index:1;pointer-events:none;overflow:hidden}
.pointer-glow{
  position:absolute;width:520px;height:520px;left:0;top:0;pointer-events:none;
  border-radius:50%;transform:translate(-50%,-50%);
  background:radial-gradient(circle,rgba(43,107,255,.10),rgba(111,91,255,.05) 42%,transparent 68%);
  transition:opacity .5s ease;opacity:0;
}
body.has-pointer .pointer-glow{opacity:1}

/* 顶部彩带：仅节日主题点亮（--ribbon 非 none 时） */
.ribbon{position:fixed;left:0;right:0;top:0;height:3px;z-index:70;pointer-events:none;background:var(--ribbon)}

/* 顶部柔光 */
.scanline{
  position:fixed;left:0;right:0;top:0;height:180px;z-index:2;pointer-events:none;
  background:linear-gradient(180deg,rgba(43,107,255,.05),transparent);
  opacity:.9;
}

/* =============================================================
   排版
   ============================================================= */
.wrap{width:min(var(--maxw),calc(100% - 48px));margin-inline:auto;position:relative}
.wrap--wide{width:min(1480px,calc(100% - 40px))}
main{position:relative;z-index:3}

h1,h2,h3,h4{margin:0;font-weight:400;line-height:1.08;letter-spacing:-.02em}
.h-display{font-size:clamp(20px,2.9vw,44px);font-weight:400;line-height:.96;letter-spacing:-.045em}
.h1{font-size:clamp(17px,2.05vw,28px);letter-spacing:-.03em}
.h2{font-size:clamp(23px,2.5vw,36px);letter-spacing:-.028em}
.h3{font-size:clamp(19px,1.8vw,24px);letter-spacing:-.02em}
.lead{font-size:clamp(15px,1.3vw,18px);color:var(--ink-2);max-width:56ch}
.small{font-size:14px;color:var(--muted)}
.mono{font-family:"SFMono-Regular",ui-monospace,"JetBrains Mono",Menlo,Consolas,monospace;font-variant-numeric:tabular-nums}

.grad-text{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.glow-text{text-shadow:none}
.hair{height:1px;background:linear-gradient(90deg,transparent,var(--line-2),transparent);border:0;margin:0}

/* =============================================================
   导航
   ============================================================= */
.nav{
  position:fixed;left:0;right:0;top:0;z-index:60;height:var(--nav-h);
  display:flex;align-items:center;
  transition:background .4s var(--ease),backdrop-filter .4s var(--ease),border-color .4s var(--ease),box-shadow .4s var(--ease);
  border-bottom:1px solid transparent;
}
.nav.is-stuck{
  background:var(--nav-bg);backdrop-filter:blur(22px) saturate(180%);
  border-bottom-color:var(--line);box-shadow:var(--shadow-soft);
}
.nav__inner{display:flex;align-items:center;gap:34px;width:min(var(--maxw),calc(100% - 48px));margin-inline:auto}
.brand{display:flex;align-items:center;gap:12px;font-weight:400;letter-spacing:-.02em;font-size:var(--fs-max);color:var(--ink);white-space:nowrap}
.brand__mark{
  width:34px;height:34px;border-radius:11px;position:relative;display:grid;place-items:center;
  background:var(--grad);box-shadow:0 10px 24px -10px rgba(43,107,255,.75);
  font-size:15px;font-weight:400;color:#fff;
}
.brand__mark::after{content:"";position:absolute;inset:0;border-radius:inherit;border:1px solid rgba(255,255,255,.45);mix-blend-mode:overlay}
/* 后台上传了站点 logo 时，用它替换首字母块。
   站长 2026-10-19 定调：**纯原图，只限制高度** —— 不加圆角、不加边框、不加投影、
   不加渐变底色、不加内高光环（::after），宽度按原图比例自适应。
   圆角/描边/阴影都是给「首字母方块」那套兜底图形用的，真 logo 一律不套。 */
.brand__mark--img{
  width:auto;height:34px;max-width:none;
  border-radius:0;background:none;box-shadow:none;padding:0;overflow:visible;display:block;
}
.brand__mark--img::after{display:none}
/* img 自身也只锁高度：高度撑满 34px、宽度按原比例走；
   max-width 只是「极端宽幅 logo 别把整条导航顶爆」的安全阀（不是美化），
   触发时由 object-fit:contain 等比收进框内，绝不变形。 */
.brand__mark--img img{
  width:auto;height:100%;max-width:min(300px,44vw);
  object-fit:contain;border-radius:0;display:block;
}
/* 站点 logo 的「蓄力 → 爆发」旋转（2026-10-20 站长定稿）：
     **平时完全静止**，隔一段时间才动一次 —— 逆时针慢转 45° 蓄力 → 顺时针快转 720° 爆发
     → 停在 720°（整两圈 = 视觉 0°）→ 再次静止等下一轮。
   动效本体在 assets/js/logo_spin.js（Web Animations API）：CSS 关键帧的百分比是相对
   总时长的，间隔一变动作就被一起拉伸，做不到「动作恒定 3 秒 + 静止 N 秒」。
   这里只留转起来所需的舞台属性；无 JS 时 logo 保持静止（正是默认状态），
   系统开了「减少动态效果」时 JS 也不会启动。 */
.brand__mark--img img.logo-spin{
  transform-origin:50% 50%;will-change:transform;
}
.brand__sub{font-size:11px;letter-spacing:.3em;color:var(--dim);text-transform:uppercase;font-weight:400}

/* 一级菜单紧贴 logo 左侧排列（仿源站：logo → 导航 → 右侧留白给 CTA），
   原来这里 margin-left:auto 把导航推到了最右，与源站布局相反。
   间距：logo 与首项留 30px（源站容器 gap:30px），项与项之间靠行内边距 12px
   形成约 24px 视觉间隔 —— 之前媒体查询把 gap 压成 0、内边距压成 5px，
   菜单挤成一团，这里是基准值，中屏由媒体查询按比例回收。 */
.nav__links{display:flex;align-items:center;gap:0}
.nav__link{
  position:relative;padding:9px 12px;border-radius:var(--radius-pill);
  /* 字重 400：导航项的层级靠「字号 15px + 深藏青墨色 + 轻微负字距」表达，
     达到源站 700 的同等视觉分量。
     （2026-10-31：原先依赖的「排版总闸」已按站长要求取消，这里改成本组件自己声明 400，
       取消总闸后导航观感不变。） */
  font-size:15px;font-weight:400;color:var(--nav-ink);letter-spacing:.01em;
  transition:color .25s,background .25s;
}
.nav__link:hover{color:var(--brand);background:var(--surface-3)}
.nav__link.is-active{color:var(--nav-ink)}
.nav__link.is-active::after{
  content:"";position:absolute;left:15px;right:15px;bottom:2px;height:2px;border-radius:2px;background:var(--grad);
}

/* 一级菜单 + 二级下拉 */
.nav__item{position:relative}
.nav__item>.nav__link{display:inline-flex;align-items:center;gap:7px}
.nav__item--mega>.nav__link{
  appearance:none;-webkit-appearance:none;border:0;background:transparent;cursor:pointer;
  /* 不能用 font:inherit;color:inherit —— 那是「继承父级 .nav__item 的初始值」，
     会把 .nav__link 上的 15px/700/--nav-ink 一并重置回 400 与 --ink，
     表现为产品矩阵、行业动态这两个 <button> 触发器比其它一级链接更细更浅。
     改成逐项显式赋值，与 <a> 版 .nav__link 保持完全一致。 */
  font-family:inherit;font-size:15px;font-weight:400;color:var(--nav-ink);letter-spacing:.01em;
}
.nav__caret{
  width:6px;height:6px;flex:0 0 auto;border-right:1.4px solid currentColor;border-bottom:1.4px solid currentColor;
  transform:rotate(45deg) translate(-1px,-1px);opacity:.55;
  transition:transform .35s var(--ease-out),opacity .3s;
}
.nav__item:hover .nav__caret{transform:rotate(225deg) translate(-1px,1px);opacity:1}
.nav__item.is-active>.nav__link{color:var(--ink);background:var(--surface-3)}
.nav__item.is-active>.nav__link::after{
  content:"";position:absolute;left:15px;right:15px;bottom:2px;height:2px;border-radius:2px;background:var(--grad);
}
/* 旧版多列下拉（.drop / .drop__*）已随顶栏收敛一并删除：
   一级菜单现在只有「纯链接」与「.nav__item--mega 大面板」两种形态，
   规则定义在 views/site/partials/nav_shell.php 一处（2026-10-19）。 */
/* 顶栏大面板（产品矩阵 / 行业动态等所有带分组栏目共用）——借鉴收钱吧官网：
   悬停一级菜单 → 白色面板紧贴顶栏下沿「自上而下」展开（translate-y + opacity，300ms），
   高度自适应内容（不再整屏铺白）；**所有栏目同一套规则**：
   面板整体白底，二级分组横排在上（多分组可点 Tab 切换三级行，单分组作标题占位），
   三级内容横排在下（图标卡 / 文字药丸），层次靠细线与激活项品牌蓝表达。 */
.nav__item--mega{position:relative;align-self:stretch;display:flex;align-items:center}
.nav__inner{align-self:stretch}
.nav__links{align-self:stretch}
.nav__item--mega>.nav__link{position:relative;z-index:1}
/* 面板展开时：导航条同步变纯白、与面板连成一体；只有「当前展开的这一项」
   换品牌色 + 箭头翻转——悬停别的栏目时，其它一级菜单纹丝不动 */
.nav.is-mega-open{ background:var(--mega-bg);border-bottom-color:transparent;box-shadow:none; }
.nav__item--mega.is-open>.nav__link,
.nav__item--mega:focus-within>.nav__link{ color:var(--brand); }
.nav__item--mega.is-open>.nav__link .nav__caret,
.nav__item--mega:focus-within>.nav__link .nav__caret{ transform:rotate(180deg);opacity:1; }
/* 面板容器：fixed 到顶栏下沿；自身不吃鼠标事件。
   底色统一为白色，横向铺满全屏；高度随内容自适应。所有栏目同一套底色规则。 */
.mega{
  position:fixed;left:0;right:0;top:var(--nav-h);z-index:50;
  display:flex;justify-content:center;padding:0;   /* 去掉左右留白 → 色带贴边满屏 */
  /* 底色统一为白（--mega-bg）：一套顶栏下所有栏目的二级面板必须同一套底色规则，
     不再因「多分组有浅灰蓝带 / 单分组纯白」而出现两种底色。
     二级行与三级内容区的层次改由细线（.mega__lv2 底边）与激活项（品牌蓝填充药丸）表达。 */
  background:var(--mega-bg);
  box-shadow:var(--shadow-drop);
  pointer-events:none;
  opacity:0;visibility:hidden;transform:translateY(-12px);
  transition:opacity .3s var(--ease),transform .3s var(--ease-out),visibility .3s;
}
.nav__item--mega.is-open .mega,
.nav__item--mega:focus-within .mega,
.nav__item--mega:hover .mega{
  opacity:1;visibility:visible;transform:translateY(0);
}
/* 内容容器：全宽，内部靠 .mega__lv2 / .mega__lv3row 的居中排版限宽居中。
   不再自绘白卡（底色已由 .mega / .mega__lv3 分层提供），故透明 + 直角 + 无投影。
   仅当内容超过 max-height 才滚动，且滚动条已隐藏（滚轮仍可滚）。 */
.mega__panel{
  width:100%;              /* 去掉 max-width：不再限宽，色带横向满屏 */
  max-height:calc(100dvh - var(--nav-h) - 20px);
  overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;
  /* 滚动条不占布局宽度：切换三级行时内容区宽度恒定 → 不再左右跳动、右缘不再闪现滚动条 */
  scrollbar-width:none;-ms-overflow-style:none;
  background:transparent;  /* 底色分层：白在 .mega，浅灰蓝在 .mega__lv3 */
  border-radius:0;         /* 满屏色块底部取直角，与截图一致 */
  box-shadow:none;
  pointer-events:auto;   /* 容器不吃事件，卡片吃——离开卡片即收起 */
}
.mega__panel::-webkit-scrollbar{width:0;height:0;display:none}   /* Chrome/Safari：隐藏滚动条，滚轮仍可滚 */
/* 二级横带：白底（与面板同色），底部一根细线切开三级区。
   ⚠️ 统一规则：**所有**带二级菜单的一级栏目都渲染这一行，与分组数量无关。
      · 多分组（产品矩阵）→ 可点 Tab（button），悬停/点按切换下方三级行；
      · 单分组（行业动态）→ 可点链接（a，无 data-gkey），点击直接跳转。
      两种形态共用下方同一套按钮规则 → 底色、高度、分界线对所有一级栏目完全一致。 */
.mega__lv2{
  display:flex;flex-wrap:wrap;justify-content:center;gap:2px 8px;   /* 收紧二级项纵横间距 */
  padding:6px 24px 5px;      /* 收紧二级行上下留白 → 与顶栏 / 三级区更贴近 */
  border-bottom:1px solid var(--line);
}
/* ── 子菜单按钮（同一套规则，全栏目通用）────────────────────────────
   访客视角：产品矩阵（多分组）的 lv2 分组 Tab 与行业动态（单分组）的 lv3 内容条目
   都是「一级栏目下的二级菜单按钮」，外观必须完全一致 —— 白底描边圆角药丸，
   悬停品牌蓝淡底，激活品牌蓝填充白字。不再允许 lv2 / lv3 各自一套样式。 */
.mega__lv2item,
.mega__card--text{
  display:inline-flex;align-items:center;justify-content:center;
  padding:7px 14px;border:1px solid var(--line);border-radius:10px;background:#fff;
  font:inherit;font-size:14px;line-height:1.4;font-weight:400;color:var(--nav-ink);
  white-space:nowrap;text-decoration:none;cursor:pointer;
  transition:color .2s var(--ease),background .2s var(--ease),border-color .2s var(--ease),box-shadow .2s var(--ease);
}
.mega__lv2item:hover,
.mega__card--text:hover{
  color:var(--brand);background:var(--mega-head-bg-on);border-color:rgba(43,107,255,.32);
}
/* 激活项：品牌蓝填充 + 白字（与未激活「白底描边」形成统一、清晰的对比） */
.mega__lv2item.is-active,
.mega__card--text.is-active{
  color:#fff;background:var(--brand);border-color:var(--brand);
  box-shadow:0 2px 10px -4px rgba(16,32,72,.22);
}
/* 三级内容区（.mega__lv3）：多分组栏目的内容行容器（单分组栏目已不渲染此层）。
.mega__lv3{
  background:var(--mega-bg);   /* 与面板同色：所有栏目统一白底 */
  border-top:1px solid var(--line);
}
.mega__lv2 + .mega__lv3{border-top:0}   /* 有二级行时避免出现双线 */
/* 三级行：横向排列；同一时刻只显示激活行（自上而下淡入） */
.mega__lv3row{display:none}
.mega__lv3row.is-active{
  display:flex;flex-wrap:wrap;align-items:stretch;justify-content:center;gap:10px;   /* 收紧卡片间距 */
  padding:14px 24px 16px;      /* 收紧三级区上下留白 → 与二级行更贴近 */
  animation:megaRowIn .34s var(--ease-out);
}
@keyframes megaRowIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
/* 三级卡片基类（图标卡 / 文字药丸共用）。
   ⚠️ 文字药丸（.mega__card--text）的完整外观已并入上方 .mega__lv2item 统一规则，
   此处不再重复定义底色/描边/内距，避免两套规则互相覆盖。 */
.mega__card{text-decoration:none;color:var(--nav-ink);
  transition:background .2s var(--ease),color .2s var(--ease),border-color .2s var(--ease);}
/* 图标卡悬停：品牌蓝淡底（与文字药丸同一套悬停语言） */
.mega__card--icon:hover{background:var(--mega-head-bg-on);color:var(--brand)}
/* 三级图标卡片（佳能式）：缩微图瓦片 + 标题，横向排列。
   没配图的子项用首字占位瓦片，保证一行整齐划一（不会一半图一半字）。 */
.mega__card--icon{
  display:flex;flex-direction:column;align-items:center;gap:7px;
  width:96px;padding:10px 6px;text-align:center;   /* 收窄卡片宽度与内距 */
}
.mega__cardimg{
  width:72px;height:72px;object-fit:contain;display:grid;place-items:center;
  background:#fff;border:1px solid var(--line);border-radius:11px;   /* 缩小缩微图 */
}
.mega__cardimg--ph{background:var(--mega-head-bg);color:var(--brand);font-size:26px;font-weight:600}
.mega__card--icon span{font-size:12.5px;line-height:1.3;white-space:nowrap}
.nav__cta{display:flex;align-items:center;gap:12px;margin-left:auto}
.nav__burger{display:none;width:42px;height:42px;border:1px solid var(--line);border-radius:12px;place-items:center;background:var(--surface)}

/* 全球站点切换器（仿 shouqianba.com 顶栏 Global 切换器），位于计算器按钮左侧。
   注意：这是收钱吧海外分公司 / 子品牌网站入口（AiMT Horizon / MUWE / Bayarlah），非语言切换。 */
.nav__lang{position:relative}
.nav__lang-trigger{
  display:inline-flex;align-items:center;gap:6px;height:42px;padding:0 10px;
  background:transparent;border:1px solid transparent;border-radius:10px;color:var(--brand);
  font-size:14px;font-weight:600;cursor:pointer;white-space:nowrap;
  transition:background .2s,opacity .2s,border-color .2s;
}
/* 悬停 / 展开时按钮点亮：沿用顶栏二级菜单的「品牌蓝淡底」激活态
   （与 .mega__card:hover / .mega__lv2item:hover 同款 token），
   改由 JS 切换 .is-open 驱动，避开实测未生效的 CSS :hover。 */
.nav__lang.is-open .nav__lang-trigger{
  background:var(--mega-head-bg-on);
  border-color:rgba(43,107,255,.45);
  color:var(--brand);
}
.nav__lang.is-open .nav__lang-globe,
.nav__lang.is-open .nav__caret{color:var(--brand)}
.nav__lang-trigger:focus-visible{outline:0;box-shadow:0 0 0 4px rgba(43,107,255,.22);border-radius:10px}
.nav__lang-globe{color:var(--brand);flex:none}
.nav__lang-text{letter-spacing:.02em}
.nav__lang .nav__caret{margin-left:1px;opacity:.7}
/* 悬停即展开（鼠标移到 Global 切换器上自动弹出，无需点击）；键盘聚焦也可达。
   .is-open 仍保留给点击 / 触屏作兜底，但不影响悬停主行为。 */
.nav__lang:hover .nav__caret,
.nav__lang:focus-within .nav__caret,
.nav__lang.is-open .nav__caret{transform:rotate(225deg) translate(-1px,1px);opacity:1}
.nav__lang-menu{
  position:absolute;top:calc(100% + 12px);right:0;z-index:60;
  min-width:0;width:max-content;max-width:280px;padding:6px;
  background:var(--surface);border:1px solid var(--line);border-radius:14px;
  box-shadow:var(--shadow-drop);backdrop-filter:blur(18px);
  opacity:0;visibility:hidden;transform:translateY(-8px);
  transition:opacity .26s var(--ease),transform .26s var(--ease-out),visibility .26s;
}
/* 透明桥：填平触发器与菜单之间的 12px 间隙，鼠标下移途中不丢 :hover */
.nav__lang-menu::before{content:"";position:absolute;top:-12px;left:0;right:0;height:12px}
.nav__lang:hover .nav__lang-menu,
.nav__lang:focus-within .nav__lang-menu,
.nav__lang.is-open .nav__lang-menu{opacity:1;visibility:visible;transform:translateY(0)}
.nav__lang-item{
  display:flex;align-items:center;gap:10px;padding:7px 10px;border-radius:10px;
  text-decoration:none;color:var(--ink);transition:background .2s;
}
/* 悬停品牌蓝淡底：与 .mega__card:hover / .nav__lang-trigger 展开态同款 token。
   原用 var(--surface-2)，亮色主题下与菜单底 --surface 都是白色半透明，视觉上看不出变化。 */
.nav__lang-item:hover{background:var(--mega-head-bg-on);color:var(--brand)}
/* logo 现为真实图片（图标或横版字标），按固定高度自适应宽度，不裁切 */
.nav__lang-logo{
  flex:none;width:auto;height:22px;max-width:118px;object-fit:contain;display:block;
  border-radius:6px;
}
.nav__lang-texts{display:flex;flex-direction:column;gap:1px;min-width:0}
.nav__lang-label{font-size:14px;font-weight:600;line-height:1.25}
.nav__lang-sub{font-size:12px;color:var(--ink-2)}
/* 2026-10-31「移动端 Global 怎么体现」——站长定案：分三档降级，不再一刀切隐藏。
   >1120px   完整形态「🌐 Global ∨」（桌面原样）
   821~1120  紧凑图标形态：只留地球图标的 42×42 方形按钮（藏字型与下拉箭头，
             保住 ≥42px 触控热区），菜单仍右对齐不溢出；触屏点按展开（见 pulse.js）
   ≤820px    顶栏彻底不占位置，改由移动端抽屉里的「全球站点」分组承接（.sheet__global） */
@media (max-width:1120px){
  .nav__lang-trigger{width:42px;padding:0;justify-content:center;gap:0}
  .nav__lang-text,.nav__lang .nav__caret{display:none}
}
@media (max-width:820px){
  .nav__lang{display:none}
}

/* ---- 移动端抽屉里的「全球站点」入口（承接顶栏 Global，≤820px 才出现） ---- */
.sheet__global{display:none}
@media (max-width:820px){
  .sheet__global{display:block}
  .sheet__global .sheet__sub a{display:flex;align-items:baseline;gap:8px}
  .sheet__global .sheet__region{font-style:normal;font-size:12px;color:var(--dim)}
}

/* 移动端抽屉：半透明遮罩（z-index 在 .nav 之下，导航条与汉堡始终可见可点）
   + 顶部滑出面板。点遮罩空白处 / 面板右上 × / ESC / 再点汉堡，都能收起。 */
.sheet{
  position:fixed;inset:0;z-index:55;
  /* 横向 + 底部安全留白：手机上菜单面板不再顶满左右边缘，呈悬浮卡片 */
  padding:calc(var(--nav-h) + 10px) 18px 18px;
  background:var(--overlay);backdrop-filter:blur(6px);
  opacity:0;visibility:hidden;
  transition:opacity .35s var(--ease),visibility 0s linear .35s;
}
.sheet.is-open{opacity:1;visibility:visible;transition:opacity .35s var(--ease)}
.sheet__panel{
  /* 宽度贴合菜单文字：左对齐 + 内容自适应，仅兜底不超过可视宽度 */
  width:max-content;max-width:calc(100% - 36px);margin:0;
  max-height:calc(100dvh - var(--nav-h) - 52px);
  overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;
  background:var(--sheet-bg);backdrop-filter:blur(20px);
  border:1px solid var(--line);border-radius:22px;
  padding:16px 28px 28px;box-shadow:var(--shadow-drop);
  display:flex;flex-direction:column;gap:6px;
  transform:translateY(-104%);transition:transform .5s var(--ease-out);
}
.sheet.is-open .sheet__panel{transform:none}
.sheet__close{
  align-self:flex-end;width:40px;height:40px;margin:-4px -12px 2px 0;
  display:grid;place-items:center;flex:0 0 auto;
  border:1px solid var(--line);border-radius:12px;
  background:var(--surface);color:var(--ink);cursor:pointer;
  transition:transform .2s var(--ease),background .3s;
}
.sheet__close:hover{background:var(--surface-3)}
.sheet__close:active{transform:scale(.92)}
/* 2026-10-12：26px 在手机上撑得离谱，压回正常导航字号 */
.sheet a{font-size:17px;font-weight:400;padding:13px 0;border-bottom:1px solid var(--line);letter-spacing:-.01em}

/* 抽屉里的二级分组 */
.sheet__grp{border-bottom:1px solid var(--line)}
.sheet__grp>summary{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  font-size:17px;font-weight:400;letter-spacing:-.01em;padding:13px 0;cursor:pointer;list-style:none;
}
.sheet__grp>summary::-webkit-details-marker{display:none}
.sheet__plus{position:relative;width:18px;height:18px;flex:0 0 auto;color:var(--dim)}
.sheet__plus::before,.sheet__plus::after{
  content:"";position:absolute;left:50%;top:50%;background:currentColor;border-radius:2px;transform:translate(-50%,-50%);
}
.sheet__plus::before{width:14px;height:1.6px}
.sheet__plus::after{width:1.6px;height:14px;transition:transform .3s,opacity .3s}
.sheet__grp[open] .sheet__plus::after{transform:translate(-50%,-50%) scaleY(0);opacity:0}
.sheet__sub{display:grid;gap:2px;padding:2px 0 18px}
.sheet__sub a{
  font-size:14.5px !important;font-weight:400 !important;padding:8px 0 !important;
  border-bottom:0 !important;color:var(--ink-2);
}
.sheet__sub a:hover{color:var(--ink)}
.sheet__all{color:var(--brand) !important}
.sheet__glabel{font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--dim);padding:14px 0 4px}

/* ── 抽屉里的目录树（产品矩阵：分组 → 条目）──────────────────────────
   2026-10-28 站长令：产品矩阵这一级菜单不再跳独立落地页，
   手机上点开就地展开成目录树，手机那么窄的屏幕平铺几十行根本没法看。
   层级表达用三件套：缩进（位置差）+ 左侧竖线（从属符号）+ 色彩差异（主/次/弱）。
   竖线与色彩都挂在 [open] 上，收起即消失，不留空条。 */
.sheet__tree{padding:2px 0 18px;display:grid;gap:2px}
/* 分组标题（树的第二层）：比一级菜单小一号、用次级墨色 —— 颜色上就矮一头。
   ⚠️ 不用 font-weight 加粗：层级靠「墨色深浅 + 字号差 + 左侧竖线 + 缩进」共同表达。
      （原注释提到的「排版总闸」已于 2026-10-31 按站长要求取消，此处仍是 400，无需改动。） */
.tree__sum{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:9px 0 9px 14px;cursor:pointer;list-style:none;
  border-left:2px solid var(--line-2);
  transition:border-color .25s var(--ease),color .25s var(--ease);
}
.tree__sum::-webkit-details-marker{display:none}
.tree__name{font-size:15px;color:var(--ink-2);letter-spacing:-.01em;transition:color .25s var(--ease)}
.tree__node[open]>.tree__sum{border-left-color:var(--brand)}
.tree__node[open]>.tree__sum .tree__name{color:var(--brand)}
.tree__plus{position:relative;width:16px;height:16px;flex:0 0 auto;color:var(--dim);transition:transform .3s var(--ease)}
.tree__plus::before,.tree__plus::after{
  content:"";position:absolute;left:50%;top:50%;background:currentColor;border-radius:2px;transform:translate(-50%,-50%);
}
.tree__plus::before{width:12px;height:1.5px}
.tree__plus::after{width:1.5px;height:12px;transition:transform .3s,opacity .3s}
.tree__node[open]>.tree__sum .tree__plus::after{transform:translate(-50%,-50%) scaleY(0);opacity:0}
.tree__node[open]>.tree__sum .tree__plus{transform:rotate(90deg)}
/* 条目（树的第三层）：再缩进一级、字号更小、用最弱墨色 —— 三个层级色彩各差一档 */
.tree__list{list-style:none;margin:0;padding:2px 0 8px 16px;border-left:2px solid var(--line);margin-left:14px}
.tree__node[open]>.tree__list{border-left-color:var(--line-2)}
.tree__item{margin:0}
.tree__link{
  display:block;font-size:14px !important;font-weight:400 !important;
  padding:8px 0 8px 12px !important;border-bottom:0 !important;
  color:var(--dim);letter-spacing:-.005em;
  transition:color .22s var(--ease),padding-left .22s var(--ease);
}
.tree__link:hover{color:var(--ink);padding-left:16px !important}

/* =============================================================
   按钮
   ============================================================= */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  height:50px;padding:0 26px;border-radius:var(--radius-pill);
  font-size:15px;font-weight:400;letter-spacing:.01em;white-space:nowrap;
  transition:transform .35s var(--ease-out),box-shadow .35s var(--ease),background .35s,color .35s,border-color .35s;
  position:relative;overflow:hidden;
}
.btn:hover{transform:translateY(-2px)}
.btn--primary{background:var(--grad);color:#fff;box-shadow:0 16px 34px -16px rgba(43,107,255,.75)}
.btn--primary:hover{box-shadow:0 22px 44px -18px rgba(43,107,255,.85)}
.btn--primary::after{
  content:"";position:absolute;inset:0;background:linear-gradient(100deg,transparent 20%,rgba(255,255,255,.45),transparent 80%);
  transform:translateX(-120%);transition:transform .8s var(--ease)
}
.btn--primary:hover::after{transform:translateX(120%)}
.btn--ghost{border:1px solid var(--line-2);color:var(--ink);background:var(--surface);backdrop-filter:blur(10px)}
.btn--ghost:hover{border-color:var(--line-3);background:var(--surface-2);box-shadow:var(--shadow-soft)}
.btn--dark{background:var(--ink);color:#fff}
.btn--sm{height:42px;padding:0 20px;font-size:14px}

.link-arrow{display:inline-flex;align-items:center;gap:8px;font-weight:400;color:var(--ink-2);transition:color .3s,gap .3s}
.link-arrow:hover{color:var(--brand);gap:12px}

/* =============================================================
   卡片 / 玻璃
   ============================================================= */
.glass{
  position:relative;border-radius:var(--radius);border:1px solid var(--line);
  background:var(--surface);
  backdrop-filter:blur(18px);overflow:hidden;box-shadow:var(--shadow-soft);
}
.card{
  position:relative;border-radius:var(--radius);border:1px solid var(--line);
  background:var(--surface);
  padding:30px;overflow:hidden;transition:transform .5s var(--ease-out),border-color .5s,box-shadow .5s;
  box-shadow:var(--shadow-soft);
}
.card:hover{border-color:var(--line-2);transform:translateY(-4px);box-shadow:var(--shadow-card)}
.card__glow{
  position:absolute;width:240px;height:240px;border-radius:50%;filter:blur(60px);opacity:0;
  transition:opacity .6s ease;pointer-events:none;background:radial-gradient(circle,rgba(43,107,255,.28),transparent 70%);
}
.card:hover .card__glow{opacity:.7}
.card__idx{font-size:12px;letter-spacing:.24em;color:var(--dim);font-weight:400}

.tilt{transform-style:preserve-3d;will-change:transform}
.tilt__inner{transform:translateZ(40px)}

/* =============================================================
   区块骨架
   ============================================================= */
/* 每个区块自带上下内边距，两块紧邻时这两段会直接相加（原先是 140+140 = 280px），
   页面节奏就被撕成一段段半屏空白。这里改成「半档」：相邻两块拼起来正好
   是一条完整的呼吸线，段落之间只呼吸一次。
   2026-10-14 用户要求「紧凑简洁」：半档再收一档（1440 实测接缝 ~50~120px），
   别改回大值——回归 tools/check_blk_gap.js 盯着每一处接缝。 */
.blk{position:relative;padding:clamp(24px,2.3vw,38px) 0}
.blk--tight{padding:clamp(12px,1.1vw,18px) 0}
.blk--flush{padding:0}
.sec-head{display:flex;align-items:flex-end;justify-content:space-between;gap:32px;margin-bottom:40px}
.sec-head__l{max-width:62ch}
.sec-head .h2{margin-top:12px}
.sec-head p{margin:14px 0 0;color:var(--ink-2)}
.sec-head--center{flex-direction:column;align-items:center;text-align:center}
.sec-head--center .sec-head__l{max-width:70ch}

/* =====================================================================
   2026-10-17 十七批：传统文章标题列表（.artlist）
   站长要求「删除所有分组，文章列表采用一行一行传统文章标题样式」。
   不用卡片、不用图标、不用分组 —— 就是一列标题行：序号 + 标题 + 摘要 + 箭头。
   整行可点，hover 时序号与箭头染色、行底扫过一条淡色高亮。
   ===================================================================== */
.artlist{list-style:none;margin:0;padding:0;border-top:1px solid var(--line)}
/* 产品矩阵分组手风琴（2026-10-28）：原来是 <div class="mxgrp"> + 平铺 <ul class="artlist">，
   分组多时一屏几十行看不下去。改为 <details> 手风琴 —— 默认收起，点分组标题才展开。
   标题行做成可点的整行（带 + 号），展开后 45° 旋转成 ×。
   移动端尤其需要：顶栏汉堡抽屉里的矩阵是竖向长列表，全展开根本没法扫读。 */
.mxgrp{border-top:1px solid var(--line);margin:0}
.mxgrp:last-of-type{border-bottom:1px solid var(--line)}
.mxgrp__sum{
  display:flex;align-items:center;gap:14px;cursor:pointer;list-style:none;
  padding:16px 6px;position:relative;
  transition:background .3s var(--ease-out),padding-left .3s var(--ease-out);
}
.mxgrp__sum::-webkit-details-marker{display:none}
.mxgrp__sum::marker{content:""}
.mxgrp__sum:hover{background:var(--bg-2);padding-left:12px}
.mxgrp__sum:hover .mxgrp__name{color:var(--brand)}
.mxgrp__name{
  flex:1 1 auto;min-width:0;font-size:16px;font-weight:600;line-height:1.5;color:var(--ink);
  letter-spacing:-.01em;transition:color .3s;
}
/* 展开指示：两条线交叉成 +，展开后旋转 45° 成 × */
.mxgrp__plus{
  flex:0 0 auto;position:relative;width:14px;height:14px;
}
.mxgrp__plus::before,.mxgrp__plus::after{
  content:"";position:absolute;inset:0;margin:auto;background:var(--dim);border-radius:2px;
  transition:transform .3s var(--ease-out),background .3s;
}
.mxgrp__plus::before{width:14px;height:2px}
.mxgrp__plus::after{width:2px;height:14px}
.mxgrp[open] .mxgrp__plus::before{transform:rotate(45deg)}
.mxgrp[open] .mxgrp__plus::after{transform:rotate(45deg)}
.mxgrp[open] .mxgrp__plus::before,.mxgrp[open] .mxgrp__plus::after{background:var(--brand)}
/* 层级视觉隔离（2026-10-28 二改，站长令）：
   分组标题是一级、组内条目是三级，原来两者贴在同一条基线上，
   展开后看不出条目属于哪个分组。做法（三处，都只作用在 .mxgrp 内，
   不影响 solutions.php 那个独立用 .artlist 的列表页）：
     ① 组内整体左缩进 —— 位置差直接把层级说清楚
     ② 左侧一条竖线（--line-2）—— 竖线是「从属于」的通用视觉符号
     ③ 极淡底色（--bg-2）—— 把「组内」整体收成一个块
   收起时 .mxgrp__body 不渲染，竖线与底色一并消失，不会留下空条。 */
.mxgrp[open] .mxgrp__body{
  margin:0 0 4px 14px;
  padding:2px 0 2px 16px;
  border-left:2px solid var(--line-2);
  background:var(--bg-2);
}
/* 组内条目自身不再画上边框 —— 竖线已经承担了分隔，再加横线会显得碎。
   同时把条目左缩进，与分组标题拉开明确的层级距离。 */
.mxgrp .artlist{border-top:0}
.mxgrp .artlist__row{border-bottom:1px solid var(--line)}
.mxgrp .artlist__row:last-child{border-bottom:0}
.mxgrp__body{padding-bottom:6px}
/* 层级色彩差异（2026-10-28 三改，站长令）：
   目录树三级各用一档墨色，一眼能分出「分组标题 / 条目」谁高谁低：
     · 分组标题 = --ink（主墨色，最重）—— 它是这一层的入口
     · 条目     = --ink-2（次墨色）—— 从属于分组
   悬停时条目提回主墨色并染品牌色，保持可点感。
   ⚠️ 不用 font-weight 区分层级：层级改由「墨色深浅 + 字号 + 竖线缩进」三者共同表达。
      （原注释提到的「排版总闸」已于 2026-10-31 按站长要求取消，此处仍维持 400。） */
.mxgrp .artlist__title{color:var(--ink-2);font-size:15.5px}
.mxgrp .artlist__link:hover .artlist__title{color:var(--brand)}
@media (prefers-reduced-motion:reduce){
  .mxgrp__sum,.mxgrp__name,.mxgrp__plus::before,.mxgrp__plus::after{transition:none}
}
.artlist__row{border-bottom:1px solid var(--line)}
.artlist__link{
  position:relative;display:flex;align-items:center;gap:clamp(14px,2vw,28px);
  padding:clamp(15px,1.5vw,21px) clamp(6px,1vw,14px);
  text-decoration:none;color:inherit;
  transition:background .35s var(--ease-out),padding-left .35s var(--ease-out);
}
/* 悬停高亮：从左往右扫过一条淡色，比整块换底色更轻 */
.artlist__link::before{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:0;
  background:linear-gradient(90deg,rgba(43,107,255,.07),rgba(43,107,255,0) 72%);
  transition:opacity .35s var(--ease-out);
}
.artlist__link:hover{background:var(--bg-2)}
.artlist__link:hover::before{opacity:1}
/* 序号：等宽数字、颜色收暗，只作定位锚点不抢标题 */
.artlist__no{
  flex:0 0 auto;min-width:2.6em;font-size:12.5px;letter-spacing:.14em;
  color:var(--dim);font-variant-numeric:tabular-nums;
  transition:color .3s;
}
.artlist__body{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:5px}
.artlist__title{
  font-size:clamp(16px,1.5vw,19px);line-height:1.5;letter-spacing:-.015em;color:var(--ink);
  transition:color .3s;
}
.artlist__link:hover .artlist__title{color:var(--brand)}
.artlist__link:hover .artlist__no{color:var(--brand)}
/* 摘要：单行省略，长文案不会把行撑成两座山 */
.artlist__desc{
  display:block;font-size:13.5px;line-height:1.7;color:var(--ink-2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  max-width:min(72ch,100%);
}
/* 箭头：平时淡着，悬停右移并染品牌色 */
.artlist__go{
  flex:0 0 auto;font-size:15px;color:var(--dim);
  transition:transform .35s var(--ease-out),color .3s;
}
.artlist__link:hover .artlist__go{transform:translateX(4px);color:var(--brand)}
@media (prefers-reduced-motion:reduce){
  .artlist__link,.artlist__link::before,.artlist__no,.artlist__title,.artlist__go{transition:none}
}
.divider-glow{
  height:1px;background:linear-gradient(90deg,transparent,rgba(43,107,255,.4),rgba(224,80,154,.3),transparent);
}

/* =============================================================
   主视觉
   ============================================================= */
.hero{position:relative;min-height:100svh;display:flex;align-items:center;padding:calc(var(--nav-h) + 60px) 0 90px;overflow:hidden}
.hero__halo{
  position:absolute;left:50%;top:52%;transform:translate(-50%,-50%);
  width:min(1050px,100vw);aspect-ratio:1;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(43,107,255,.16),rgba(111,91,255,.09) 38%,transparent 66%);
  filter:blur(30px);
}
.hero__ring{
  position:absolute;left:50%;top:52%;transform:translate(-50%,-50%);
  border-radius:50%;border:1px solid rgba(43,107,255,.14);pointer-events:none;
}
.hero__ring--1{width:min(760px,92vw);aspect-ratio:1;animation:spin 46s linear infinite}
.hero__ring--2{width:min(1080px,120vw);aspect-ratio:1;border-style:dashed;border-color:rgba(43,107,255,.10);animation:spin 76s linear infinite reverse}
.hero__ring--1::after{content:"";position:absolute;top:-4px;left:50%;width:8px;height:8px;border-radius:50%;background:var(--accent);box-shadow:0 0 18px 4px rgba(14,143,191,.55)}
.hero__ring--2::after{content:"";position:absolute;bottom:8%;right:6%;width:10px;height:10px;border-radius:50%;background:var(--brand-3);box-shadow:0 0 20px 5px rgba(163,79,216,.5)}
@keyframes spin{to{transform:translate(-50%,-50%) rotate(360deg)}}

.hero__grid{display:grid;gap:54px;align-items:center;position:relative;z-index:2}
.hero__grid--split{grid-template-columns:minmax(0,.95fr) minmax(0,1.15fr)}

/* 图文舞台 */
.stage{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);gap:64px;align-items:center}
.stage--rev{direction:rtl}
.stage--rev>*{direction:ltr}
.stage__copy,.stage__media{min-width:0}

/* -------------------------------------------------------------
   行业方案：左右交替的行业带
   ------------------------------------------------------------- */
.sectors{display:grid;gap:22px}
/* 2026-10-17 十六批：原来 sector 是「左图右文」整宽大卡，一条占满 1200px、
   高度 264px+，17 条要把列表页拉出好几屏 —— 站长批注「那么大一片区域就显示
   这么点内容，太不协调」。改为三列紧凑卡：一屏能看到多行业，信息密度上来。 */
@media (min-width:1081px){
  .sectors{grid-template-columns:repeat(3,1fr);gap:18px}
}
@media (min-width:721px) and (max-width:1080px){
  .sectors{grid-template-columns:repeat(2,1fr);gap:18px}
}
@media (max-width:720px){
  .sectors{grid-template-columns:1fr;gap:14px}
}
.sector{
  display:flex;flex-direction:column;
  border-radius:20px;overflow:hidden;border:1px solid var(--line);
  background:var(--surface);
  box-shadow:var(--shadow-soft);
  transition:border-color .5s,transform .5s var(--ease-out),box-shadow .5s;
}
.sector:hover{border-color:var(--line-2);transform:translateY(-3px);box-shadow:var(--shadow-card)}
/* 紧凑卡不再左右翻转 —— 网格里格子必须对齐，翻转会让标题忽左忽右 */
.sector--rev .sector__media{order:0}
.sector--rev .sector__copy{order:0}
.sector__media{position:relative;display:block;overflow:hidden;background:var(--bg-2)}
/* ---- 2026-10-17 十五批：图版改为「图标展台」 ----
   原来 .sector__media 里铺满 cover 实拍图。但复刻来的行业方案 cover 全是源站
   同一张共用占位图，铺满就是一大块灰蓝色纯色块（17 屏全是它）。
   现在改成：品牌色浅底 + 细网格纹 + 居中大图标，17 个行业各有自己的图标，
   视觉上既干净又能一眼分辨。 */
/* 紧凑卡：图区与图标同高，序号并入文案行，不留大片空白 */
.sector__plate{
  position:relative;z-index:1;display:flex;flex-direction:row;
  align-items:center;gap:0;padding:16px 20px 0;
  background:
    radial-gradient(120% 90% at 50% 8%,rgba(2,123,255,.10),rgba(2,123,255,0) 62%),
    linear-gradient(180deg,var(--surface) 0%,var(--bg-2) 100%);
}
/* 细网格纹：给浅底一点「台面」的质感，避免纯色发空 */
.sector__plate::before{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.5;
  background-image:linear-gradient(rgba(2,123,255,.07) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(2,123,255,.07) 1px,transparent 1px);
  background-size:34px 34px;
  -webkit-mask-image:radial-gradient(75% 70% at 50% 45%,#000 30%,transparent 100%);
          mask-image:radial-gradient(75% 70% at 50% 45%,#000 30%,transparent 100%);
}
/* 紧凑卡里序号放到文案那一行，图区只留图标 */
.sector__idx{
  position:relative;z-index:2;order:-1;font-size:12px;letter-spacing:.26em;
  color:var(--dim);font-variant-numeric:tabular-nums;
}
/* 图标：紧凑卡里收成 64px 托 + 34px 图标（源站原图是 18px 深色线稿，
   少于 30px 就只剩一个墨点） */
.sector__ico{
  position:relative;z-index:2;display:inline-flex;align-items:center;justify-content:center;
  flex:0 0 auto;width:52px;height:52px;border-radius:15px;
  background:var(--surface);border:1px solid var(--line);
  box-shadow:0 8px 22px rgba(8,20,50,.06);
  transition:transform .55s var(--ease-out),border-color .45s,box-shadow .45s;
}
.sector__ico img{width:30px;height:30px;object-fit:contain}
.sector:hover .sector__ico{
  transform:translateY(-3px) scale(1.04);
  border-color:var(--brand);
  box-shadow:0 14px 32px rgba(2,123,255,.16);
}
.sector__veil{display:none}
.sector__copy{display:flex;flex-direction:column;gap:7px;padding:10px 20px 18px}
/* 序号与标题同行：省下一整行高度，卡片更紧凑 */
.sector__copy .sector__idx{order:-1;margin-bottom:1px}
.sector__cat{font-size:11px;letter-spacing:.26em;text-transform:uppercase;color:var(--brand)}
/* 紧凑卡标题压到一档，避免一行放不下就折成三行 */
.sector__copy h3{font-size:clamp(17px,1.35vw,20px);letter-spacing:-.02em;line-height:1.4}
.sector__copy p{margin:0;color:var(--ink-2);font-size:15.5px;max-width:46ch}
/* 行业方案一句话摘要：两行截断，卡片高度整齐 */
.sector__desc{
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  color:var(--ink-2);font-size:14px;line-height:1.7;
}
.sector__copy .link-arrow{margin-top:6px}

/* 站内通用行动箱 */
.portalbox{display:flex;align-items:center;justify-content:space-between;gap:40px;flex-wrap:wrap;
  padding:clamp(26px,3.2vw,44px);border-radius:28px}
.hero__title{margin:20px 0 0}
/* 分栏主视觉：标题被挤到左半栏，单独收一档字号，否则中文字数一多就会折行 */
.hero__grid--split .hero__title{font-size:clamp(19px,2.4vw,40px)}
/* 2026-10-20：后台「标题字号」（extra.title_size，像素）—— 值写到 h1 的 --hero-fs，
   没设置时上面两条默认规则原样生效；窄屏按 0.62 收一档，中文长行不溢出。
   两条选择器分别压过 .hero__title / .hero__grid--split .hero__title（同特异性靠后胜出）。 */
.hero__title[style*="--hero-fs"],
.hero__grid--split .hero__title[style*="--hero-fs"]{font-size:var(--hero-fs)}
@media (max-width:900px){
  .hero__title[style*="--hero-fs"],
  .hero__grid--split .hero__title[style*="--hero-fs"]{font-size:calc(var(--hero-fs) * .62)}
}
@media (min-width:1081px){
  /* 大标题的换行由编辑者在后台手动控制，桌面端不再让浏览器自作主张折行 */
  .hero__title .line span{white-space:nowrap}
}
/* ⚠️ .line 的 overflow:hidden 是 riseIn 入场动画的裁布，但 line-height:.96 的行盒
   比微软雅黑的字面框（升部1.06em+降部0.27em=1.33em）矮，汉字底部笔画会探到行盒
   外 ~0.07em（39px 字号约 2.5px，「数/光/据」这类字底被裁一刀）。
   解法：向下扩出裁布范围（padding-bottom），再用等量负 margin 抵消占位，
   行距视觉不变；入场起始位移同步加大到 130%，保证动画第一帧仍完全藏在裁布外。 */
.hero__title .line{display:block;overflow:hidden;padding-bottom:.24em;margin-bottom:-.24em}
.hero__title .line span{display:block;transform:translateY(130%);animation:riseIn 1.1s var(--ease-out) forwards}
.hero__title .line:nth-child(2) span{animation-delay:.12s}
.hero__title .line:nth-child(3) span{animation-delay:.24s}
@keyframes riseIn{to{transform:none}}
.hero__lead{margin-top:20px;font-size:clamp(15px,1.35vw,18px);color:var(--ink-2);max-width:52ch}
.hero__actions{display:flex;flex-wrap:wrap;gap:14px;margin-top:30px}
.hero__micro{display:flex;flex-wrap:wrap;gap:26px;margin-top:32px;padding-top:20px;border-top:1px solid var(--line)}
.hero__micro div{display:flex;flex-direction:column;gap:2px}
.hero__micro b{font-size:22px;font-weight:400;letter-spacing:-.02em}
.hero__micro span{font-size:12px;color:var(--dim);letter-spacing:.16em;text-transform:uppercase}
/* 计数数字也是 <span>，会被上面那条「说明文字」样式命中：
   按 <b> 的字体还原，并且**不自己画渐变**（background:none + color:inherit）——
   这样数字与后缀共用父级 <b class="grad-text"> 的那一整条渐变，不会出现两段拼接的色差。 */
.hero__micro b .cnt,
.hero__micro b .counter{
  font-size:inherit;font-weight:400;letter-spacing:inherit;text-transform:none;
  background:none;color:inherit;font-variant-numeric:tabular-nums;
}
/* 数字定宽：.cnt::before 用 data-w（终值）撑住宽度，计数器绝对定位盖在上面。
   好处是 0 → 1000 生长的过程**不会把后面几组推着左右晃**，数字仍从左逐位长出来。
   用伪元素而非真实节点，DOM 文本保持「1000万+」，复制与读屏都干净。 */
.hero__micro .cnt{position:relative;display:inline-block;text-align:left}
.hero__micro .cnt::before{content:attr(data-w);visibility:hidden}
/* ⚠️ 绝对定位的数字拿不到父级 <b> 的 background-clip:text（裁剪只覆盖常规流里的文字），
   必须自己带一份渐变，否则就是「文字透明 + 没有背景 = 数字凭空消失」。 */
.hero__micro .cnt .counter{
  position:absolute;left:0;top:0;white-space:nowrap;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent;
}

/* -------------------------------------------------------------
   hero 右侧：视频预览窗
   发光外框 + 封面/预览视频 + 居中浮动胶囊按钮
   窗内是视频画面，始终按「深底浅字」处理，不随主题反转
   ------------------------------------------------------------- */
.vstage{position:relative;margin:0;perspective:1400px}
.vstage__glow{
  position:absolute;inset:-16% -12%;border-radius:50%;filter:blur(72px);z-index:0;opacity:.55;
  background:radial-gradient(circle at 28% 26%,rgba(43,107,255,.45),transparent 62%),
             radial-gradient(circle at 78% 74%,rgba(224,80,154,.35),transparent 64%);
  animation:vsBreathe 11s ease-in-out infinite;
}
@keyframes vsBreathe{0%,100%{opacity:.45;transform:scale(.98)}50%{opacity:.7;transform:scale(1.03)}}

.vstage__frame{
  position:relative;z-index:1;aspect-ratio:16/10;border-radius:26px;overflow:hidden;background:var(--media-bg);
  border:1px solid rgba(255,255,255,.5);
  box-shadow:0 0 0 7px rgba(43,107,255,.07),
             0 34px 70px -30px rgba(43,107,255,.55),
             0 0 70px -28px rgba(163,79,216,.4);
  transform-style:preserve-3d;
}
/* 玻璃罩：左上高光，让画面像嵌在一块玻璃后面 */
.vstage__frame::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:4;
  background:linear-gradient(152deg,rgba(255,255,255,.22),rgba(255,255,255,.04) 34%,transparent 58%);
  mix-blend-mode:screen;
}
.vstage__media{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;z-index:1}

/* 暗角 + 底部渐隐，保证按钮与说明始终可读 */
.vstage__veil{
  position:absolute;inset:0;z-index:2;pointer-events:none;
  background:radial-gradient(120% 96% at 50% 44%,transparent 44%,rgba(5,10,24,.45) 100%),
             linear-gradient(180deg,transparent 42%,rgba(5,10,24,.6));
}
/* 缓慢横扫的扫描线，暗示「正在运行」 */
.vstage__scan{
  position:absolute;top:0;bottom:0;width:36%;z-index:3;pointer-events:none;opacity:.45;
  background:linear-gradient(100deg,transparent,rgba(160,200,255,.16) 45%,rgba(255,255,255,.26) 50%,rgba(160,200,255,.16) 55%,transparent);
  animation:vsScan 7.5s ease-in-out infinite;
}
@keyframes vsScan{0%{transform:translateX(-130%)}55%,100%{transform:translateX(300%)}}

/* 居中浮动胶囊按钮 */
.vstage__cta{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:6;
  display:inline-flex;align-items:center;gap:11px;
  height:54px;padding:0 24px 0 8px;border-radius:var(--radius-pill);
  font-size:15px;font-weight:400;color:#fff;white-space:nowrap;cursor:pointer;text-decoration:none;
  background:rgba(12,18,36,.55);border:1px solid rgba(255,255,255,.34);
  backdrop-filter:blur(16px) saturate(150%);
  box-shadow:0 18px 40px -16px rgba(0,0,0,.6),inset 0 1px 0 rgba(255,255,255,.26);
  transition:transform .4s var(--ease-out),background .4s,border-color .4s,box-shadow .4s;
}
.vstage__cta:hover{
  transform:translate(-50%,-50%) scale(1.045);background:rgba(20,28,56,.68);
  border-color:rgba(255,255,255,.55);box-shadow:0 24px 50px -16px rgba(43,107,255,.7),inset 0 1px 0 rgba(255,255,255,.32);
}
/* 无视频时按钮退化为纯链接，没有圆形播放键，左右内边距要对称 */
.vstage__cta--link{padding:0 26px;gap:14px}
.vstage__play{
  width:38px;height:38px;border-radius:50%;display:grid;place-items:center;flex:0 0 auto;
  background:var(--grad);color:#fff;position:relative;box-shadow:0 0 0 1px rgba(255,255,255,.3) inset;
}
.vstage__play::after{
  content:"";position:absolute;inset:0;border-radius:inherit;border:1px solid rgba(255,255,255,.6);
  animation:vsPulse 2.6s ease-out infinite;
}
@keyframes vsPulse{0%{transform:scale(1);opacity:.7}70%{transform:scale(1.75);opacity:0}100%{opacity:0}}

.vstage__caption{
  position:absolute;left:24px;bottom:20px;z-index:6;
  font-size:12.5px;color:rgba(255,255,255,.88);letter-spacing:.06em;
  display:inline-flex;align-items:center;gap:9px;
}
.vstage__caption::before{
  content:"";width:7px;height:7px;border-radius:50%;background:var(--accent-2);
  box-shadow:0 0 12px 3px rgba(18,168,106,.6);
}

/* 灯箱：点击后在原窗口放大、带声播放 */
.vlight{position:fixed;inset:0;z-index:1000;display:grid;place-items:center;padding:24px}
.vlight[hidden]{display:none}
.vlight__backdrop{position:absolute;inset:0;background:var(--overlay);backdrop-filter:blur(16px);animation:vsFade .35s ease}
.vlight__box{
  position:relative;width:min(1120px,100%);border-radius:22px;overflow:hidden;
  border:1px solid rgba(255,255,255,.24);background:var(--media-bg);
  box-shadow:0 40px 100px -40px rgba(12,20,42,.7),0 0 0 8px rgba(255,255,255,.06);
  animation:vsPop .42s var(--ease-out);
}
.vlight__stage{aspect-ratio:16/9;background:var(--media-bg)}
.vlight__stage video,.vlight__stage img{width:100%;height:100%;display:block;object-fit:contain;background:var(--media-bg)}
.vlight__meta{padding:12px 20px;border-top:1px solid rgba(255,255,255,.12);font-size:13px;color:rgba(255,255,255,.82);background:rgba(255,255,255,.03)}
.vlight__x{
  position:absolute;right:12px;top:12px;z-index:3;width:38px;height:38px;border-radius:50%;
  display:grid;place-items:center;color:#fff;background:rgba(12,18,36,.6);border:1px solid rgba(255,255,255,.24);
  backdrop-filter:blur(10px);transition:background .3s,transform .3s;
}
.vlight__x:hover{background:rgba(255,255,255,.2);transform:rotate(90deg)}
@keyframes vsFade{from{opacity:0}to{opacity:1}}
@keyframes vsPop{from{opacity:0;transform:translateY(18px) scale(.965)}to{opacity:1;transform:none}}

/* =============================================================
   能力环绕轨道
   ============================================================= */
/* 容器放大（640→900）：节点变大后，外环半径 38% + 半个节点宽不能超出容器边界，
   所以要把轨道一起放大，否则节点会溢出方块并互相压叠 */
.orbit{position:relative;aspect-ratio:1;max-width:900px;margin-inline:auto;container-type:size}
/* 上下多留白：悬停放大一倍时，最上方的节点会向外探出轨道方块约 90px，
   没有这段留白就会压到区块标题上（.blk 默认只有 24~38px）。 */
.blk--orbit{padding-block:clamp(48px,7vw,92px)}
.orbit__core{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:132px;height:132px;border-radius:36px;display:grid;place-items:center;text-align:center;
  background:var(--grad);box-shadow:0 24px 60px -20px rgba(111,91,255,.7);z-index:3;
}
.orbit__core b{font-size:34px;font-weight:400;color:#fff;letter-spacing:-.03em}
.orbit__core span{font-size:10px;letter-spacing:.28em;color:rgba(255,255,255,.9);text-transform:uppercase}
.orbit__track{position:absolute;inset:12%;border-radius:50%;border:1px dashed var(--line-2)}
.orbit__track--2{inset:26%}
.orbit__node{
  position:absolute;left:50%;top:50%;width:clamp(150px,19vw,200px);
  margin:0;   /* 居中改由 transform 的 translate(-50%,-50%) 负责：节点放大后不再依赖写死的偏移值 */
  border-radius:20px;padding:16px 12px;text-align:center;
  background:var(--surface-2);
  border:1px solid var(--line);backdrop-filter:blur(14px);box-shadow:var(--shadow-soft);
  /* 极角定位：先旋转到角度，再向外推 r%，最后反向旋转保持文字水平。
     最前面的 translate(-50%,-50%) 把节点自身中心对到极点上（取代原来写死的 margin 偏移），
     这样节点尺寸怎么改都自动居中。 */
  transform:translate(-50%,-50%) rotate(calc(var(--a) * 1deg)) translate(calc(var(--r) * 1cqw)) rotate(calc(var(--a) * -1deg));
  transition:transform .6s var(--ease-out),border-color .4s,box-shadow .4s;
}
/* 悬停放大一倍（--s 由 @property 注册为 <number>，可平滑过渡）。
   z-index 抬高：放大后的节点会盖住邻近节点，必须浮到最上层才不像被压住。
   想小一点就改 --s（如 1.6）；节点放大后仍以自身中心为基准，不会跑偏。 */
.orbit__node:hover{--s:2;z-index:4;border-color:transparent;box-shadow:0 16px 34px -16px rgba(17,26,46,.22)}
/* 链接型节点：去掉默认链接样式，强化可点击反馈（新窗口打开时同样适用） */
a.orbit__node{color:inherit;text-decoration:none;cursor:pointer}
a.orbit__node:hover{border-color:transparent;box-shadow:0 16px 34px -16px rgba(17,26,46,.22)}
.orbit__node i{display:grid;place-items:center;width:38px;height:38px;margin:0 auto 10px;border-radius:12px;background:var(--grad-soft);border:1px solid var(--line);font-size:17px}
.orbit__node b{display:block;font-size:13.5px;font-weight:400}
.orbit__node span{font-size:11px;color:var(--dim)}
/* 有图节点（2026-10-21 能力环绕改用真实配图）：
   用 .orbit__node.orbit__node--pic 提高权重，确保覆盖上面的基础 i 规则。
   图片满幅铺满整张卡（不留白边），名称浮在图片底部。
   为保证白字在任何底图上都看得清，名称层自带「由下而上的深色渐变遮罩 + 文字投影」。 */
.orbit__node.orbit__node--pic{padding:0;overflow:hidden;border:0}
.orbit__node.orbit__node--pic i{width:100%;max-width:none;height:auto;aspect-ratio:1/1;margin:0;
  border-radius:0;border:0;background:var(--surface-2);font-size:17px}
.orbit__node.orbit__node--pic i img{width:100%;height:100%;object-fit:cover;display:block;border-radius:0}
.orbit__node.orbit__node--pic b{
  position:absolute;left:0;right:0;bottom:0;z-index:2;
  padding:30px 12px 13px;
  font-size:14px;color:#fff;line-height:1.35;
  text-shadow:0 1px 3px rgba(0,0,0,.8),0 0 14px rgba(0,0,0,.5);
  background:linear-gradient(to top,rgba(8,12,24,.88) 0%,rgba(8,12,24,.6) 44%,rgba(8,12,24,0) 100%);
}

/* =============================================================
   能力环绕：动态特效（2026-10-19）
   -------------------------------------------------------------
   ① 公转：所有节点共用同一个自定义属性 --spin（0deg → 360deg，72s 一圈）。
      节点定位公式是「转到极角 → 向外推 → 反向转回来保持文字水平」，
      把 --spin 加进这两次旋转里，节点就绕着核心慢慢走，而文字始终水平。
      用 @property 注册成 <angle> 才能参与动画；不支持的旧浏览器只是不转，
      仍是原来的静态圆环（scale/旋转都写了兜底值，不会错位）。
   ② 轨道：两圈虚线反向慢转，像能量在环上流动。
   ③ 核心：呼吸光晕，呼应站点主渐变色。
   ④ 入场：节点按 --i 错峰淡入（90ms 一档）。
      填充模式特意用 backwards（不是 both）—— 动画结束后 --s 交还给普通声明，
      悬停放大才不会被动画的终值压住。
   ============================================================= */
@property --spin{syntax:'<angle>';inherits:true;initial-value:0deg}
@property --s{syntax:'<number>';inherits:false;initial-value:1}
@keyframes orbit-spin{from{--spin:0deg}to{--spin:360deg}}
@keyframes orbit-track{to{transform:rotate(360deg)}}
@keyframes orbit-halo{
  0%,100%{opacity:.38;transform:scale(1)}
  50%    {opacity:.8;transform:scale(1.07)}
}
@keyframes orbit-node-in{from{opacity:0;--s:.86}to{opacity:1;--s:1}}
.orbit{--spin:0deg;animation:orbit-spin 72s linear infinite}
/* 鼠标进入环绕区就暂停公转 —— 不然节点一直在走，想点某一项永远点不准。
   离开后从当前角度继续（animation-play-state 不重置相位）。 */
.orbit:hover{animation-play-state:paused}
.orbit__track{animation:orbit-track 96s linear infinite reverse}
.orbit__track--2{animation-duration:64s;animation-direction:normal}
.orbit__core::after{
  content:'';position:absolute;inset:-18px;border-radius:50%;z-index:-1;
  background:radial-gradient(circle,rgba(111,91,255,.4),transparent 68%);
  animation:orbit-halo 3.8s var(--ease) infinite;
}
/* 中心核换成上传图片时：纯图片，去掉渐变底与紫色光晕，按原圆角裁切 */
.orbit__core.orbit__core--img{background:none;box-shadow:none}
.orbit__core.orbit__core--img::after{display:none}
.orbit__core.orbit__core--img img{width:100%;height:100%;object-fit:cover;display:block;border-radius:inherit;
  box-shadow:0 22px 54px -22px rgba(17,26,46,.4)}
.orbit__node{
  transform:translate(-50%,-50%) rotate(calc(var(--a) * 1deg + var(--spin,0deg))) translate(calc(var(--r) * 1cqw))
            rotate(calc(var(--a) * -1deg - var(--spin,0deg))) scale(var(--s,1));
  transition:--s .4s var(--ease),border-color .4s,box-shadow .4s;
  animation:orbit-node-in .7s var(--ease-out) backwards;
  animation-delay:calc(var(--i,0) * 90ms);
}

/* =============================================================
   粘性滚动叙事
   ============================================================= */
.narr{position:relative}
/* 展示区不再比正文更宽：之前 1480px 让右侧演示面板比左侧文案宽出近 40%，
   两者摆在一起比例失衡。现在与站点主容器同宽，左右两栏等分。 */
.narr>.wrap{width:min(var(--maxw),calc(100% - 48px))}
/* 2026-10-16 对齐收钱吧官网：右列更宽、左右间隙收紧，演示图放大 */
.narr__grid{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:32px;align-items:stretch}
.narr__steps{padding:14vh 0}
/* 步骤的可见性有两档：
   · 无 JS / JS 未就绪 —— 全部半透明铺开（就是一份普通的分段文案，可读可滚动）；
   · .narr.is-live（脚本已接管）—— 非当前步骤整块退场（opacity/visibility 双关，
     连透明度 34% 的「幽灵文字」都没有），屏幕上只呈当前这一条。
     2026-10-16 用户反馈：「屏幕没有仅显示一个条目区块的内容，总会有其他内容混入」。
   退场时 visibility 延后 .5s 生效，先把淡出动画播完再真正摘掉，避免硬切。 */
.narr__step{min-height:62vh;display:flex;flex-direction:column;justify-content:center;opacity:.34;transition:opacity .5s var(--ease),transform .5s var(--ease),visibility 0s linear .5s;padding-left:clamp(0px,4vw,56px)}
.narr__step.is-active{opacity:1;visibility:visible;transition-delay:0s}
.narr.is-live .narr__step{opacity:0;visibility:hidden;transform:translateY(16px);pointer-events:none}
.narr.is-live .narr__step.is-active{opacity:1;visibility:visible;transform:none;pointer-events:auto;transition-delay:0s}
.narr__step h3{font-size:clamp(27px,3vw,44px);line-height:1.22;letter-spacing:-.03em}
.narr__step p{margin:16px 0 0;color:var(--ink-2);max-width:40ch}
.narr__tags{display:flex;flex-wrap:wrap;gap:14px 18px;margin-top:26px;list-style:none;padding:0}
/* 渠道图标瓦片：上彩色方块、下文字（对齐收钱吧官网渠道图标墙） */
.narr__tags li.tag--ico{display:flex;flex-direction:column;align-items:center;gap:7px;padding:0;border:0;background:none;border-radius:0}
.narr__tags li.tag--ico i{
  display:grid;place-items:center;width:44px;height:44px;border-radius:12px;
  background:var(--ico-bg,var(--grad));color:#fff;font-style:normal;
  font-size:18px;font-weight:400;box-shadow:0 6px 14px -6px rgba(20,30,60,.25);
}
.narr__tags li.tag--ico span{font-size:12px;color:var(--ink-2)}
/* 后台配了真图标（银行 / 渠道 logo 之类）时替换掉色块文字；白底保证透明 PNG 看得清 */
.narr__tags li.tag--ico i img{width:100%;height:100%;object-fit:contain;background:#fff;border-radius:inherit;padding:4px}
.narr__tags li{font-size:13px;padding:7px 15px;border-radius:var(--radius-pill);border:1px solid var(--line);background:var(--surface);color:var(--ink-2)}

.narr__visual{position:relative}
/* 粘性展示位：铺满「导航以下的可用视口」。
   高度 = 视口 − 导航 − 上下呼吸（各 20px）；--narr-h 同时用于垂直居中偏移，
   保证任何视口下都完整落在屏内（导航是 fixed，所以可用区从 --nav-h 起算）。
   这里刻意不画底、不描边、不投影：演示内容直接浮在页面背景上，
   和收钱吧官网一样「无边框」——少一层画框，内容也就不再显得缩在盒子里。 */
.narr__frame{
  --narr-h:min(880px,calc(100svh - var(--nav-h) - 40px));
  position:sticky;
  top:calc(var(--nav-h) + (100svh - var(--nav-h) - var(--narr-h)) / 2);
  height:var(--narr-h);
  /* --narr-h 允许被 pulse.js 就地改写：横版动画（如 1080×713 的银行帧）套在竖高画框里，
     contain 之后宽度贴合、上下留出近一半空白，看起来就比竖版动画小一大截。
     脚本按「当前动画的内容宽高比」把画框压低到内容高度，画面就顶到框边。
     过渡让切步骤时的高度变化是滑过去的，不是跳过去的。 */
  transition:height .5s var(--ease),top .5s var(--ease),width .5s var(--ease);
  /* 内容比画框更「竖」时脚本会把画框收窄到内容比例（免得 contain 左右留白），
     收窄后居中摆，别贴着左栏文字 */
  margin-inline:auto;
}
.narr__layer{position:absolute;inset:0;z-index:2;display:grid;place-items:center;opacity:0;transform:scale(.96);transition:opacity .8s var(--ease),transform .8s var(--ease)}
.narr__layer.is-active{opacity:1;transform:none}
.narr__layer img{max-width:97%;max-height:96%;width:auto;border-radius:18px}
/* 演示区的取景不在这里写死。
   六支 Lottie 的画布尺寸各不相同（690×920 / 700×800 / 600×600 / 700×700 /
   680×906 / 1080×713），四周还留着大片空白：按画布原样 contain 播放，真正能看见的
   内容只占画框一半左右。改由 pulse.js 读 assets/anim/bounds.json（离线实测的
   「每支动画真实绘制范围」）去换 SVG 的 viewBox，内容最大化且永不溢出。 */
.narr__anim{position:absolute;inset:0;display:grid;place-items:center;opacity:0;transition:opacity .6s ease}
.narr__anim.is-ready{opacity:1}
.narr__anim svg{width:100%;height:100%;display:block}
.narr__anim.is-ready ~ img{opacity:0 !important}
.narr__step-img{display:none}
/* 861~1080px：保持双栏叙事，但收紧步高与节奏（2026-10-16 对齐收钱吧官网——
   原来 ≤1080px 直接砍掉右侧演示区，导致同宽视口下中间一片空洞） */
@media (min-width:861px) and (max-width:1080px){
  .narr__grid{gap:26px}
  .narr__steps{padding:6vh 0}
  .narr__step{min-height:48vh}
}
/* ≤860px：单列，右栏演示区收进步骤内，小图放大一档 */
@media (max-width:860px){
  .narr__grid{grid-template-columns:1fr;gap:0}
  .narr__visual{display:none}
  .narr__steps{padding:20px 0}
  .narr__step{min-height:auto;padding:38px 0;border-bottom:1px solid var(--line);padding-left:0}
  /* 单列下每一步都要读得到，撤掉「只留当前步」的退场规则 */
  .narr.is-live .narr__step{opacity:1;visibility:visible;transform:none;pointer-events:auto}
  .narr__step-img{display:block;margin-top:24px;border-radius:18px;border:1px solid var(--line);max-height:min(60vh,460px);object-fit:contain;background:var(--bg-3)}
}

/* =============================================================
   巨型数字
   ============================================================= */
.metrics{display:grid;grid-template-columns:repeat(4,1fr);gap:22px}
.metric{position:relative;padding:34px 28px;border-radius:var(--radius);border:1px solid var(--line);background:var(--surface);overflow:hidden;box-shadow:var(--shadow-soft)}
.metric::after{content:"";position:absolute;left:28px;right:28px;bottom:0;height:2px;background:var(--grad);opacity:.6}
.metric b{display:block;white-space:nowrap;line-height:1.05;font-size:clamp(38px,4.4vw,62px);font-weight:400;letter-spacing:-.045em;color:var(--ink)}
/* 渐变只作用在计数字元素上：父级 background-clip:text 不会为子级文字上色，会变透明 */
.metric b .counter{background:linear-gradient(180deg,var(--ink),var(--brand));-webkit-background-clip:text;background-clip:text;color:transparent;text-shadow:none}
/* 只作用于直接子级说明文字，避免命中 <b> 内的计数字元素 */
.metric>span{display:block;margin-top:12px;font-size:13.5px;color:var(--muted);letter-spacing:.06em}

/* =============================================================
   终端展示
   ============================================================= */
.rail{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
.device{padding:0;overflow:hidden;border-radius:var(--radius);border:1px solid var(--line);background:var(--surface);box-shadow:var(--shadow-soft);transition:transform .5s var(--ease-out),box-shadow .5s,border-color .5s}
.device:hover{transform:translateY(-4px);box-shadow:var(--shadow-card);border-color:var(--line-2)}
.device__media{
  position:relative;aspect-ratio:4/3;overflow:hidden;
  /* 终端配图都是白底产品图，亮色展台 + 完整显示 */
  background:linear-gradient(180deg,#ffffff 0%,#f4f7fc 62%,#e8edf7 100%);
  border-bottom:1px solid var(--line);
}
.device__media img{width:100%;height:100%;object-fit:contain;padding:18px;transition:transform .9s var(--ease-out)}
.device:hover .device__media img{transform:scale(1.05)}
.device__body{padding:24px 26px 30px}
.device__tag{font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:var(--dim)}
.device__body h3{margin:12px 0 8px;font-size:20px}
.device__body p{margin:0;color:var(--muted);font-size:14.5px}

/* =============================================================
   案例 / 洞察
   ============================================================= */
.casegrid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
/* 恰好 4 张时一排摆满，避免第二行留一个空洞 */
.casegrid--4{grid-template-columns:repeat(4,1fr)}
/* 产品矩阵分组：单张限宽、两张两列，避免被 3 列网格撑成窄条或最后一行孤张 */
.casegrid--1{grid-template-columns:minmax(0,360px)}
.casegrid--2{grid-template-columns:repeat(2,minmax(0,1fr))}
/* ------------------------------------------------------------------
   行业图标卡 icard（2026-10-17 十五批）
   为什么不用 casecard 铺图：复刻来的行业方案 cover 全指向源站同一张共用
   占位图，当满卡背景时会糊成一大块灰蓝色色块，页面看着像没做完。
   改成源站导航同款 —— 每行业一枚专属图标 + 标题 + 摘要 + 明确的行动入口。
   ------------------------------------------------------------------ */
.icard{
  position:relative;display:flex;flex-direction:column;gap:0;
  padding:26px 24px 22px;border-radius:var(--radius);
  border:1px solid var(--line);background:var(--bg-3);
  box-shadow:var(--shadow-soft);
  transition:transform .45s var(--ease-out),border-color .45s,box-shadow .45s;
  overflow:hidden;
}
/* 右上角那层极淡的品牌色晕，悬停时把视线往标题引 */
.icard::before{
  content:"";position:absolute;right:-46px;top:-46px;width:132px;height:132px;border-radius:50%;
  background:radial-gradient(circle,rgba(2,123,255,.09),rgba(2,123,255,0) 68%);
  transition:transform .55s var(--ease-out);pointer-events:none;
}
.icard:hover{transform:translateY(-6px);border-color:var(--brand);box-shadow:var(--shadow-card)}
.icard:hover::before{transform:scale(1.35)}
.icard>*{position:relative;z-index:1}
/* 序号：等宽数字，弱化成边角信息 */
.icard__no{
  font-size:11.5px;letter-spacing:.2em;color:var(--dim);
  font-variant-numeric:tabular-nums;margin-bottom:14px;
}
/* 图标：浅色圆角底托，避免小图标直接漂在白卡片上显得单薄 */
.icard__ico{
  display:inline-flex;align-items:center;justify-content:center;
  width:46px;height:46px;border-radius:13px;margin-bottom:14px;
  background:var(--surface-3);border:1px solid var(--line);
  transition:border-color .45s,background .45s;
}
.icard__ico img{width:26px;height:26px;object-fit:contain}
.icard:hover .icard__ico{border-color:var(--brand);background:rgba(2,123,255,.06)}
.icard__title{
  margin:0 0 9px;font-size:19px;line-height:1.45;letter-spacing:-.01em;color:var(--ink);
  transition:color .35s;
}
.icard:hover .icard__title{color:var(--brand)}
/* 摘要：两行截断，卡片高度不被长文案拉散 */
.icard__desc{
  margin:0 0 16px;font-size:13.5px;line-height:1.8;color:var(--ink-2);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  min-height:calc(1.8em * 2);
}
/* 行动入口：默认弱，悬停才亮 —— 保持卡片安静，不抢标题 */
.icard__go{
  display:inline-flex;align-items:center;gap:6px;margin-top:auto;
  font-size:12.5px;letter-spacing:.04em;color:var(--dim);transition:color .35s,gap .35s;
}
.icard:hover .icard__go{color:var(--brand);gap:9px}
.icard__go i{font-style:normal;transition:transform .35s var(--ease-out)}
.icard:hover .icard__go i{transform:translateX(2px)}
/* 卡片：图片做底，上面压一层白色渐隐，正文落在下半部的白底上 —— 亮色底也清楚可读 */
.casecard{position:relative;border-radius:var(--radius);overflow:hidden;border:1px solid var(--line);min-height:290px;display:flex;flex-direction:column;justify-content:flex-end;padding:28px;transition:transform .5s var(--ease-out),border-color .5s,box-shadow .5s;background:var(--bg-3);box-shadow:var(--shadow-soft)}
.casecard:hover{transform:translateY(-5px);border-color:var(--line-2);box-shadow:var(--shadow-card)}
.casecard__bg{position:absolute;inset:0;object-fit:cover;width:100%;height:100%;opacity:1;transition:transform .9s var(--ease-out)}
.casecard:hover .casecard__bg{transform:scale(1.06)}
.casecard::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(255,255,255,.55) 0%,rgba(255,255,255,.86) 42%,rgba(255,255,255,.97) 68%,#fff 100%)}
.casecard>*{position:relative;z-index:2}
.casecard__cat{font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--brand)}
.casecard h3{margin:10px 0 8px;font-size:21px;letter-spacing:-.02em;color:var(--ink);text-shadow:none}
.casecard p{margin:0;font-size:14px;color:var(--ink-2);opacity:1;text-shadow:none}

/* 亮色展台卡：素材里的产品图几乎都是「白底 / 浅底」截图与实拍，
   直接铺满会糊成一块灰。这类卡片改成「上亮下白」——上面完整展示产品，下面放标题。 */
.casecard--plate .casecard__bg{
  object-fit:contain;opacity:1;
  background:linear-gradient(180deg,#ffffff 0%,#f4f7fc 62%,#e8edf7 100%);
  padding:18px 20px 132px;
}
.casecard--plate::after{
  background:linear-gradient(180deg,rgba(255,255,255,0) 34%,rgba(255,255,255,.86) 66%,#fff 100%);
}

.stream{display:grid;gap:2px}
.stream__row{display:grid;grid-template-columns:150px 1fr auto;gap:26px;align-items:center;padding:13px 18px;border-radius:16px;border:1px solid transparent;transition:background .4s,border-color .4s,transform .4s var(--ease-out)}
.stream__row:hover{background:var(--surface);border-color:var(--line);transform:translateX(6px);box-shadow:var(--shadow-soft)}
.stream__date{font-size:13px;color:var(--dim);letter-spacing:.08em}
/* 列表行里的分类名可点（点它进该分类，而不是进文章） */
[data-cat-href]{cursor:pointer;transition:color .25s}
[data-cat-href]:hover{color:var(--brand);text-decoration:underline}
.stream__row h3{font-size:19px;letter-spacing:-.02em}
.stream__row p{margin:4px 0 0;font-size:14px;color:var(--muted);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.stream__row .go{width:34px;height:34px;border-radius:50%;border:1px solid var(--line);display:grid;place-items:center;transition:background .4s,border-color .4s,color .4s;color:var(--ink-2)}
.stream__row:hover .go{background:var(--grad);border-color:transparent;color:#fff}

/* 博客置顶徽标与分类小标（三十四批） */
.pinbadge{display:inline-block;margin-right:8px;padding:1px 8px;border-radius:999px;background:var(--grad);color:#fff;font-size:11px;font-style:normal;letter-spacing:.05em;vertical-align:2px}
.stream__cat{margin-left:10px;font-size:12px;font-weight:400;color:var(--dim);letter-spacing:.02em}
.postcat{color:var(--dim);text-decoration:none;border-bottom:1px dotted var(--line)}
.postcat:hover{color:var(--brand)}

/* 合作品牌光环 */
.aura{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:14px}
.aura__cell{display:grid;place-items:center;height:92px;border-radius:16px;border:1px solid var(--line);background:var(--bg-3);transition:background .4s,border-color .4s,transform .4s,box-shadow .4s;box-shadow:var(--shadow-soft)}
.aura__cell:hover{border-color:var(--line-2);transform:translateY(-3px);box-shadow:var(--shadow-card)}
.aura__cell img{max-height:38px;width:auto;filter:grayscale(1);opacity:.5;transition:filter .4s,opacity .4s}
.aura__cell:hover img{filter:none;opacity:1}

/* 客户 Logo 墙：三行无限滚动，每行内容双份拼接，位移 -50% 无缝循环 */
.lgwall{position:relative;padding:6px 0}
.lgwall__rows{display:flex;flex-direction:column;gap:clamp(10px,1.6vw,22px)}
/* 掩码只裁横向；上方留 40px 给悬停提示框，负外距抵消占位（每行高度不变） */
.lgwall__mask{
  overflow:hidden;padding:40px 0 0;margin-top:-40px;
  /* 左右边缘渐隐：用 mask 的 alpha 渐变（而非色块叠加）。logo 在边缘淡出到透明，
     透出背后任意背景——浅色实底、深空动态星空背景都能自然融合，不再有色差边界。
     这是修复「深空主题两侧色差块」的正确手段（旧版 --bg-1 色块叠加方案已废弃）。 */
  -webkit-mask-image:linear-gradient(90deg, transparent 0, #000 clamp(28px,5vw,90px), #000 calc(100% - clamp(28px,5vw,90px)), transparent 100%);
          mask-image:linear-gradient(90deg, transparent 0, #000 clamp(28px,5vw,90px), #000 calc(100% - clamp(28px,5vw,90px)), transparent 100%);
}
/* 中间排反向：同速同向的三排像一块布平移，反向的中间排出编织感 */
.lgwall__mask--rev .lgwall__track{animation-direction:reverse}
.lgwall__track{
  display:flex;align-items:center;width:max-content;
  animation:lgScroll var(--lg-speed,40s) linear infinite;
}
.lgwall--pause:hover .lgwall__track{animation-play-state:paused}
@keyframes lgScroll{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}
.lgcell{position:relative;flex:0 0 auto;display:grid;place-items:center;height:64px;padding:0 clamp(20px,3vw,40px)}
.lgcell__a{display:grid;place-items:center;height:100%;text-decoration:none}
.lgcell__a--plain{cursor:default}
.lgcell img{height:44px;width:auto;max-width:180px;object-fit:contain;transition:transform .35s var(--ease),opacity .35s;opacity:.82}
.lgcell__a:hover img{transform:scale(1.08);opacity:1}
.lgcell__name{font-weight:400;font-size:15px;color:var(--ink-2);white-space:nowrap}
/* 悬停浮出的品牌名：绝对定位在单元格上方，掩码只裁横向不裁它 */
.lgcell__tip{
  position:absolute;left:50%;bottom:calc(100% + 8px);z-index:3;
  transform:translate(-50%,4px);transform-origin:50% 100%;
  max-width:220px;padding:6px 11px;border-radius:9px;
  background:var(--ink-1,#1b2431);color:#fff;
  font-size:12.5px;line-height:1.3;font-weight:400;letter-spacing:.02em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  box-shadow:0 8px 22px -6px rgba(16,24,40,.35);
  opacity:0;pointer-events:none;
  transition:opacity .22s var(--ease),transform .22s var(--ease);
}
.lgcell__tip::after{
  content:"";position:absolute;top:100%;left:50%;transform:translateX(-50%);
  border:5px solid transparent;border-top-color:var(--ink-1,#1b2431);
}
.lgcell:hover .lgcell__tip,.lgcell__a:focus-visible ~ .lgcell__tip{opacity:1;transform:translate(-50%,0)}
@media (max-width:640px){
  .lgcell{height:52px;padding:0 16px}
  .lgcell img{height:34px;max-width:130px}
  .lgcell__name{font-size:13px}
  .lgcell__tip{bottom:calc(100% + 6px);font-size:11.5px;padding:5px 9px}
}
@media (prefers-reduced-motion:reduce){
  .lgwall__track{animation:none}
  .lgwall__mask{overflow-x:auto}
}

/* 传送门 CTA */
.portal{position:relative;text-align:center;padding:clamp(52px,5.4vw,84px) 0;overflow:hidden}
.portal__hole{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:min(880px,92vw);aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,rgba(43,107,255,.20),rgba(111,91,255,.11) 40%,transparent 68%);
  filter:blur(24px);animation:holePulse 8s var(--ease) infinite alternate;
}
@keyframes holePulse{to{transform:translate(-50%,-50%) scale(1.16);opacity:.85}}
.portal__ring{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);border-radius:50%;border:1px solid rgba(43,107,255,.16)}
.portal__ring--a{width:min(560px,80vw);aspect-ratio:1;animation:ringOut 7s var(--ease) infinite}
.portal__ring--b{width:min(560px,80vw);aspect-ratio:1;animation:ringOut 7s var(--ease) infinite 3.5s}
@keyframes ringOut{0%{transform:translate(-50%,-50%) scale(.55);opacity:.9}100%{transform:translate(-50%,-50%) scale(1.5);opacity:0}}

/* =============================================================
   内页
   ============================================================= */
/* 顶部与「简介→分类条」之间的留白原来太浪费（+64px / 44px），压缩到贴合导航 */
/* 2026-10-18 十八批：净间距 18px 太贴顶栏（站长圈红），提到 44px
   2026-11-01 站长令统一：改取 --sp-head（= 顶栏高 + 面包屑带 + 全站统一呼吸间距），
   不再写死数值；移动端只需在 :root 里调 --crumbs-gap，各页自动跟随。 */
.phead{position:relative;padding:var(--sp-head) 0 14px}
.phead h1{margin:0}
.phead p{margin:8px 0 0;max-width:64ch;color:var(--ink-2);font-size:15px}
/* 页头首行：标题+简介在左（2026-10-20 二十批：右侧的栏目搜索框已下线，留位给 AI 问一问入口） */
.phead__top{display:flex;align-items:flex-start;justify-content:space-between;gap:16px 40px;flex-wrap:wrap}
/* 页头里的 chips 是收尾元素：它自带的 40px 下外边距会捅到 .wrap 外面、落进
   phead 的底部内边距里，让「页头 → 第一个区块」的接缝凭空多出 40px。 */
.phead .chips{margin-bottom:0}

/* 2026-10-20 四十六批：列表页顶部模块 = 宏观数据看板时的外层。
   看板自身是深色 HUD 面板（.sb），跟页面白底之间要有一圈留白，不能贴死。
   上留白让开固定导航高度，下留白接列表流。 */
.lhead__board{padding:calc(var(--nav-h) + 20px) 0 0}
.lhead__board .sb{margin-bottom:16px}
@media (max-width:900px){
  .lhead__board{padding-top:calc(var(--nav-h) + 12px)}
}
/* 2026-10-20 二十批：修 .phead__beam 横向溢出。
   原来这里写的是 transform:translateX(-50%)，但 fx.css 在 pulse.css 之后加载，
   .fx-para 的 transform:translate3d(0,var(--fx-py),0) 同特异性把它整个覆盖掉了 ——
   少了居中的 -50%，光束就从 left:50% 直接往右铺，页面因此多出 260px 横向滚动。
   改用「自身宽度的一半」做负 margin 让它居中：水平居中不再依赖 transform，
   transform 就留给 fx-para 做 Y 轴视差，两条规则互不覆盖。
   width 与 margin-left 同步缩放（900px ↔ -450px，90vw ↔ -45vw），任意视口都精确居中。
   ⚠️ 这里用 max() 不是 min()：min() 在两个负值里取「更负的」那个，
   窄屏下会选 -450px 而不是 -45vw，导致光束大幅左偏。max() 才是「绝对值更小者」。 */
.phead__beam{position:absolute;left:50%;top:0;width:min(900px,90vw);margin-left:max(-450px,-45vw);height:420px;pointer-events:none;
  background:radial-gradient(60% 70% at 50% 0%,rgba(43,107,255,.14),transparent 70%);filter:blur(20px)}

/* 区块自带整屏主视觉时，这里只负责让出固定导航的高度（原来还兼面包屑的位置） */
.phead__pad{padding:var(--sp-head) 0 0}

.article{max-width:820px;margin-inline:auto;font-size:16.5px;line-height:1.85;color:var(--ink-2)}

/* P3-7：知识库长文档轻量折叠——超长正文默认收起到 1100px，底部渐隐，点「展开全文」展开 */
.kb-article-fold{max-height:1100px;overflow:hidden;position:relative}
.kb-article-fold::after{content:"";position:absolute;left:0;right:0;bottom:0;height:140px;
  background:linear-gradient(to bottom, rgba(244,247,253,0), var(--bg))}
.kb-fold-btn{display:block;margin:18px auto 0;font:inherit;font-size:14px;color:var(--brand);
  background:none;border:0;cursor:pointer;padding:8px 16px}
.kb-fold-btn[hidden]{display:none}
.article h2{margin:40px 0 14px;font-size:25px;color:var(--ink)}
.article h3{margin:30px 0 12px;font-size:19px;color:var(--ink)}
.article p{margin:0 0 16px}
.article img{border-radius:18px;margin:26px 0;border:1px solid var(--line);max-width:100%;height:auto}
/* 编辑器存进来的旧文可能带 width/height 属性：宽度被 max-width 压缩后高度必须跟着
   等比缩，否则移动端会出现「宽被压、高锁死」的拉伸变形（见 2026-10-12 反馈） */
.article img[height],.article img[width]{height:auto}

/* =====================================================================
   2026-10-17 十六批：文章详情页首屏（.dochero）
   源站方案/产品页的首屏是「左：超大两行标题 + 描述 + 申请开通圆钮；
   右：案例图轮播」。本站原本只有一条普通页头，站长对比后判为
   「同一个产品文档，展示效果天差地别」。这里按源站结构复刻。
   ===================================================================== */
.dochero{position:relative;padding:var(--sp-head) 0 clamp(30px,4vw,60px);overflow:hidden}
.dochero__glow{position:absolute;left:50%;top:calc(var(--nav-h) * -0.4);transform:translateX(-50%);
  width:min(1100px,96vw);height:520px;pointer-events:none;
  background:radial-gradient(58% 66% at 50% 20%,rgba(2,123,255,.16),transparent 72%);filter:blur(24px)}
/* 四十三批：推荐区宽度向正文看齐——.wrap 全宽 1140，而正文 .article 只有 820，
   两栏左右顶满显得中部空荡。这里把推荐区收窄到 860 居中，跟正文几乎同宽，
   视觉上「首屏一条线、正文一条线」对齐。 */
.dochero__wrap{display:grid;gap:clamp(26px,3.6vw,54px);align-items:center;
  width:min(860px,calc(100% - 48px));margin-inline:auto}
/* 2026-11-11：文章详情页的「面包屑 → 首行内容」间距必须是常量，不能交给垂直居中。
   以前所有 .dochero 都 align-items:center，左栏（meta + 标题 + 摘要）高度随标题
   字数档位、摘要行数、meta 有无而变，右栏单图封面高度又随图片原始比例而变，
   (行高 - 左栏高) / 2 就成了面包屑下方那块忽大忽小的空白
   —— 实测同版式两篇分别 50px / 60px，无 meta 的文章还要再多 17px。
   详情页加 .dochero--top 改顶部对齐：左栏恒从 --sp-head 起
   （= 顶栏 + 面包屑带 + 全站统一的 34px 呼吸），顶部间距从此与内容无关；
   右栏仍单独居中，封面观感不变。
   列表页页头是「短标题垂直居中配大图」，需要居中版式，故不挂这个类
   （由 reco_zone 的 $recoCenter 开关控制，默认 false = 详情页版式）。 */
.dochero--top .dochero__wrap{align-items:start}
.dochero--top .dochero__r{align-self:center}
/* 有轮播图才两栏；没图就单栏（硬件页等没有 hero_gallery 的文章不至于留半屏空白） */
@media (min-width:900px){
  .dochero--split .dochero__wrap{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
}
.dochero__l{position:relative;z-index:2;max-width:none;min-width:0}
/* meta 行（日期 / 作者 / 客户名 / 分类）原来是内联 style，散在各调用方里；
   收成一份类，改行距不用再逐页找。 */
.dochero__meta{margin:0 0 14px;font-size:12.5px;letter-spacing:.1em;color:var(--dim)}
/* 标题：源站 48/58px、行高 62/75px。站长总闸禁加粗，所以只放大不加重。 */
.dochero__h{margin:0;font-size:clamp(27px,4.1vw,54px);line-height:1.16;letter-spacing:-.035em;color:var(--ink)}
.dochero__h span{display:block}
/* 摘要行宽：40ch 在左栏里只占六成宽，几个字就折行、右侧一片空白；
   放宽到 36em——两栏模式下恰好撑满左栏（约 400px），单栏模式下也不至于拉满全宽。 */
.dochero__lead{margin:18px 0 0;max-width:36em;color:var(--ink-2);font-size:clamp(15px,1.2vw,17.5px);line-height:1.85}
.dochero__cta{display:inline-flex;align-items:center;gap:8px;margin-top:26px;
  height:38px;padding:0 20px;border-radius:999px;background:var(--brand);color:#fff;
  font-size:15px;transition:background .35s,box-shadow .35s,transform .35s var(--ease-out)}
.dochero__cta:hover{background:var(--ink);box-shadow:0 12px 28px rgba(2,123,255,.26);transform:translateY(-2px)}
.dochero__arrow{transition:transform .35s var(--ease-out)}
.dochero__cta:hover .dochero__arrow{transform:translateX(3px)}

/* ------------------------------------------------------------------
   四十三批：推荐区标题特效（后台「标题特效」下拉选择，类名挂在 .dochero__h 上）
   渐变字：background-clip:text；标题里的两行 <span> 是 display:block，
   透明色继承即可整体吃进渐变。发光/描边同理不用改结构。
   ------------------------------------------------------------------ */
.dochero__h--grad-blue{background:linear-gradient(94deg,#027bff 4%,#7a3cff 58%,#c44bff);-webkit-background-clip:text;background-clip:text;color:transparent}
.dochero__h--grad-gold{background:linear-gradient(94deg,#f7b500 4%,#ff7a00 58%,#ff4d4d);-webkit-background-clip:text;background-clip:text;color:transparent}
.dochero__h--grad-teal{background:linear-gradient(94deg,#00b8a9 4%,#027bff 78%);-webkit-background-clip:text;background-clip:text;color:transparent}
.dochero__h--grad-ink{background:linear-gradient(180deg,#43506b 8%,#0b1322 82%);-webkit-background-clip:text;background-clip:text;color:transparent}
/* 2026-10-21：渐变字底部补 0.18em 背景区。
   背景裁剪文字的渐变只画到元素背景盒，而 .hero__title 行高 0.96em 比汉字墨迹低约
   2.3px（实测：基线 35.68 + 墨迹下伸 6 = 41.68 > 盒 39.36）——字底没渐变可吃，
   看上去像被裁了一点点。padding 把背景盒撑到盖住字体下伸部（负 margin 抵消布局），
   .line 的 overflow:hidden + .24em padding 吸收后不会真裁。 */
.dochero__h--grad-blue,.dochero__h--grad-gold,.dochero__h--grad-teal,.dochero__h--grad-ink{
  padding-bottom:.18em;margin-bottom:-.18em}
/* 霓虹发光：字色跟随主题主文字色（--ink）—— 早期写死 #fff，在 dawn 等亮色
   主题上是白字白底，等于「填了不生效」（2026-10-19 修复，深空主题下 --ink
   本身就是亮色，不受影响）。 */
.dochero__h--neon{color:var(--ink);
  text-shadow:0 0 7px rgba(2,123,255,.85),0 0 22px rgba(2,123,255,.5),0 0 52px rgba(2,123,255,.28)}
.dochero__h--outline{color:transparent;-webkit-text-stroke:1.6px var(--ink)}

/* 案例图轮播：卡片叠放 + 淡入切换，圆角投影对齐源站那张 528x340 的图 */
.dochero__r{position:relative;z-index:2;min-width:0}
/* 2026-11-11：封面统一比例，--reco-ratio 由 reco_zone 从 RecoFields::COVER_RATIO 下发。
   单图 / 轮播 / 视频共用这一份，object-fit:cover 居中强制裁剪（原图不落盘改动）。 */
.docshot{position:relative;width:100%;aspect-ratio:var(--reco-ratio,550/340);border-radius:14px}
.docshot__i{position:absolute;inset:0;margin:0;border-radius:14px;overflow:hidden;
  opacity:0;transform:translateY(10px) scale(.985);pointer-events:none;
  transition:opacity .7s var(--ease-out),transform .7s var(--ease-out);
  box-shadow:0 25px 36px -24px rgba(0,0,0,.28)}
.docshot__i.is-on{opacity:1;transform:none;pointer-events:auto;z-index:2}
.docshot__i img{width:100%;height:100%;object-fit:cover;object-position:center;display:block}
/* ------------------------------------------------------------------
   2026-11-11：推荐区标题字号 = 全站统一默认值 + 单篇可覆盖
   字号值由 reco_zone 从 RecoFields::effectiveSize() 取，始终写成标题的
   --reco-fs（默认 SIZE_DEFAULT，后台填 20–120 时只改这一篇）。
   以前按标题字数分 mid/long 档，同类文章标题忽大忽小，已取消；
   下面 .dochero__h 的 clamp 只作「没有 --reco-fs」时的兜底。
   窄屏按 0.68 收一档，避免统一字号在手机上折太多行。
   ------------------------------------------------------------------ */
.dochero__h[style*="--reco-fs"]{font-size:var(--reco-fs)}
@media (max-width:900px){
  .dochero__h[style*="--reco-fs"]{font-size:calc(var(--reco-fs) * .68)}
}

/* 推荐区关闭时正文成为页面首块：原本 --sp-head 顶距由 .dochero 提供，
   整块撤掉后必须在这里补回，否则正文被 fixed 顶栏压住、绝对定位的
   .breadcrumbs 会浮在正文中间（2026-11-11 截图反馈）。
   只改 padding-top，.blk--tight 的左右/底部节奏保持不变。 */
.article-body--nohero{padding-top:var(--sp-head)}
/* 单图自适应高度已下线（2026-11-11）：原来单图按原图比例自然显示、不裁切，
   导致不同文章的封面高度差几十像素，正文起点跟着漂。现在单图与轮播/视频
   完全同构，一律 .docshot 的 --reco-ratio + object-fit:cover 强制裁剪。 */
.docshot__dots{position:absolute;left:16px;bottom:14px;z-index:3;display:flex;gap:7px}
.docshot__dot{width:9px;height:9px;padding:0;border-radius:50%;cursor:pointer;
  border:1px solid rgba(255,255,255,.85);background:rgba(255,255,255,.32);
  transition:background .3s,transform .3s}
.docshot__dot.is-on{background:#fff;transform:scale(1.15)}

/* ------------------------------------------------------------------
   复刻文档正文精修（2026-10-17 十五批）
   源站 27 篇文档原样搬过来后，整篇是「一串纯文字 + 一堆大图」：
   标题与正文同字号同色、段落间距均匀、图随手贴、没有层级。
   这里只做版式层（不动内容、不动 HTML），让长文能读：
     · h2 变成可定位的章节头：左侧品牌色竖条 + 上方留白加大
     · h3 加浅底，与正文拉开
     · 正文图片居中、去浮边、悬停轻微放大（原来贴边铺满，像截图堆）
     · 列表与引用补足可读性
   ------------------------------------------------------------------ */
/* h2 章节头 */
.article--doc h2{
  position:relative;margin:52px 0 18px;padding-left:16px;
  font-size:26px;line-height:1.45;letter-spacing:-.02em;color:var(--ink);
}
.article--doc h2::before{
  content:"";position:absolute;left:0;top:.16em;bottom:.16em;width:4px;border-radius:3px;
  background:linear-gradient(180deg,var(--brand),rgba(2,123,255,.28));
}
/* h2 之前的分隔：把长文切成一段段，眼睛能歇 */
.article--doc h2::after{
  content:"";display:block;height:1px;margin:18px 0 0;padding:0;
  background:linear-gradient(90deg,var(--line),transparent);
}
.article--doc h2:first-child{margin-top:8px}
/* h3：浅底小节头。宽度按内容走，别拉成一条通栏按钮 */
.article--doc h3{
  display:inline-block;margin:30px 0 4px;padding:9px 16px;border-radius:10px;
  font-size:17px;line-height:1.5;color:var(--ink);
  background:var(--surface-3);border:1px solid var(--line);
}
/* h3 后面紧跟的那段说明：跟标题贴紧，别被标题的下边距推远 */
.article--doc h3+ p{margin-top:0}
/* 痛点小标题（源站「核心痛点 1」）：这是问题陈述不是章节名，
   去掉 h2 的装饰竖条，改成红色系的问题标签，视觉上和「解决方案」区分开 */
.article--doc h2.doc-pain::before{display:none}
.article--doc h2.doc-pain::after{display:none}
.article--doc h2.doc-pain{
  display:inline-block;margin:44px 0 6px;padding:7px 14px;border-radius:8px;
  font-size:14px;line-height:1.4;letter-spacing:.04em;color:#c0392b;
  background:rgba(192,57,43,.07);border:1px solid rgba(192,57,43,.2);
}
/* 痛点下面那句是问题陈述：抬成 lead，比正文重一档 */
.article--doc h2.doc-pain+p{
  font-size:19px;line-height:1.7;color:var(--ink);font-weight:400;
  margin-bottom:26px;
}
/* h4 以下按正文强调处理 */
.article--doc h4,.article--doc h5,.article--doc h6{
  margin:26px 0 10px;font-size:16px;color:var(--ink);letter-spacing:.01em;
}
/* 段落：略放宽行距，长段落不挤 */
.article--doc p{margin:0 0 18px;line-height:1.95}
/* 列表：项目符号换成品牌色方点，视觉上比默认圆点整齐 */
.article--doc ul,.article--doc ol{margin:0 0 20px;padding-left:24px}
.article--doc li{margin:8px 0;line-height:1.9}
.article--doc ul li::marker{color:var(--brand)}
.article--doc ol li::marker{color:var(--dim);font-variant-numeric:tabular-nums}
/* 图片：源站图几乎都是整幅界面截图，贴边铺满会显得杂乱。
   居中 + 轻投影 + 悬停微放大，读起来像「插图」而不是「截图堆」。 */
.article--doc img{
  display:block;margin:28px auto;max-width:100%;height:auto;
  border-radius:16px;border:1px solid var(--line);
  box-shadow:0 6px 22px rgba(8,20,50,.06);
  transition:transform .5s var(--ease-out),box-shadow .5s;
}
.article--doc img:hover{transform:scale(1.012);box-shadow:0 12px 34px rgba(8,20,50,.1)}
.article--doc figure{margin:30px auto;text-align:center}
.article--doc figure img{margin:0 auto}
.article--doc figcaption{
  margin-top:12px;font-size:13px;color:var(--dim);text-align:center;letter-spacing:.02em;
}
/* 引用块 */
.article--doc blockquote{
  margin:26px 0;padding:16px 20px;border-left:3px solid var(--brand);
  border-radius:0 12px 12px 0;background:var(--surface-3);
  color:var(--ink-2);font-size:15.5px;line-height:1.85;
}
.article--doc blockquote p:last-child{margin-bottom:0}
/* 首段导语：源站首段通常是整篇概述，抬成 lead 更好读 */
.article--doc > p:first-child{
  font-size:17px;line-height:1.95;color:var(--ink);
}
/* 表格：正文里的表加圆角与斑马纹，别再是一堆横线。
   宽表格在移动端不再被 body{overflow-x:hidden} 裁掉——改为表格自身横向滚动：
   display:block + width:max-content 让表格按内容展开，max-width:100% 收口到正文宽度，
   overflow-x:auto 在窄屏内独立滚动，右边几列看得到了。 */
.article--doc table{
  display:block;width:max-content;max-width:100%;
  margin:30px 0;border:1px solid var(--line);border-radius:14px;overflow-x:auto;
  -webkit-overflow-scrolling:touch;
  font-size:14.5px;background:var(--surface);
}
.article--doc th{
  background:var(--surface-3);color:var(--ink);font-weight:400;
  letter-spacing:.02em;border-bottom:1px solid var(--line);
}
.article--doc th,.article--doc td{padding:12px 16px;border-bottom:1px solid var(--line)}
.article--doc tbody tr:last-child td{border-bottom:0}
.article--doc tbody tr:nth-child(even){background:rgba(2,123,255,.022)}
/* 链接：正文里的链接要有可点感 */
.article--doc a{color:var(--brand);border-bottom:1px solid rgba(2,123,255,.32);transition:border-color .3s}
.article--doc a:hover{border-bottom-color:var(--brand)}

/* ------------------------------------------------------------------
   抖音视频（编辑器「插入抖音视频」写出的 .dyv 容器）
   --------------------------------------------------------------
   iframe 只负责铺满，**横竖屏由容器的宽高比决定** —— 所以这里不写死任何尺寸，
   统一交给 aspect-ratio，靠 data-ratio 切三档：竖屏 9/16（默认，抖音主力）、
   横屏 16/9、方形 1/1。宽度上限护住桌面端：竖屏最多 400px 并居中，
   不给它撑满 820px 的正文宽度（那会变成一根顶天立地的柱子）；
   移动端自动退化成「满宽 + 按比例算高」。
   ---- */
.dyv{position:relative;margin:30px auto;width:100%;max-width:min(400px,100%);
  aspect-ratio:9/16;background:#0c0d12;border:1px solid var(--line);border-radius:18px;overflow:hidden}
.dyv[data-ratio="16/9"]{aspect-ratio:16/9;max-width:100%}
.dyv[data-ratio="1/1"]{aspect-ratio:1/1;max-width:min(560px,100%)}
.dyv iframe{display:block;width:100%;height:100%;border:0;background:transparent}
/* 老浏览器不认 aspect-ratio 时给个兜底高度，总比塌成 0 高、只剩一条黑边强 */
@supports not (aspect-ratio:9/16){
  .dyv{height:min(178vw,712px)}
  .dyv[data-ratio="16/9"]{height:min(56vw,460px)}
  .dyv[data-ratio="1/1"]{height:min(100vw,560px)}
}
.article blockquote{margin:30px 0;padding:22px 26px;border-left:3px solid var(--brand);background:rgba(43,107,255,.06);border-radius:0 14px 14px 0;color:var(--ink)}
.article ul,.article ol{padding-left:22px}
.article a{color:var(--brand);border-bottom:1px solid rgba(43,107,255,.35)}
/* 转载来源条：采集入库的文章/帖子顶部都有，注明原文与链接 */
.feed-src{margin:0 0 26px !important;padding:10px 16px;border:1px dashed var(--line);border-radius:12px;
  background:var(--surface-2);font-size:13.5px;line-height:1.7;color:var(--dim);word-break:break-all}
.feed-src a{color:var(--brand);border-bottom:1px solid rgba(43,107,255,.35)}
.fpost__body .feed-src{margin:0 0 16px !important;padding:8px 14px;font-size:13px;border-radius:10px}
/* 列表/详情页里标注「转载」的小角标 */
.feed-flag{display:inline-block;margin-left:8px;padding:1px 8px;border:1px solid var(--line);border-radius:99px;
  font-size:11px;font-weight:400;letter-spacing:.05em;color:var(--dim);vertical-align:middle}
.article code{background:var(--surface-3);padding:2px 7px;border-radius:6px;font-size:14px}
/* 正文补齐：富文本编辑器能产出的其它标签也得有像样的排版 */
.article h1{margin:0 0 22px;font-size:34px;color:var(--ink)}
.article h4{margin:32px 0 12px;font-size:18px;color:var(--ink)}
.article strong{color:var(--ink)}
.article li{margin:8px 0}
.article figure{margin:30px 0}
.article figure img{margin:0;width:100%;height:auto}
.article figcaption{margin-top:10px;font-size:13.5px;color:var(--dim);text-align:center}
.article hr{border:0;height:1px;background:var(--line);margin:44px 0}
.article pre{margin:26px 0;padding:18px 20px;border:1px solid var(--line);border-radius:14px;background:var(--surface-3);overflow:auto}
.article pre code{background:none;padding:0;font-size:13.5px}
.article table{width:100%;border-collapse:collapse;margin:28px 0;font-size:15px}
.article th,.article td{border:1px solid var(--line);padding:10px 14px;text-align:left}
.article th{background:var(--surface-3);color:var(--ink);font-weight:400}
/* 页脚富文本里的表格（2026-10-17 十五批）：页脚是独立容器，不带 .article，
   之前表格零样式 → 单元格无边框、整张表挤成一行「表头 1 表头 2」纯文本。
   页脚前台与后台「页脚导航」编辑 iframe（复用同一份 pulse.css）一并生效。 */
.footer table,.fedit table{width:100%;border-collapse:collapse;margin:16px 0;font-size:14px}
.footer th,.footer td,.fedit th,.fedit td{border:1px solid var(--line);padding:8px 11px;text-align:left;vertical-align:top}
.footer th,.fedit th{background:var(--surface-3);color:var(--ink);font-weight:400}
.footer table img,.fedit table img{max-width:100%;height:auto}
/* 窄屏：页脚富文本里的两栏表格（站长手排的「左资料 / 右声明」）改成上下两栏。
   ⚠️ 表格单元格右对齐是站长在编辑器里手打的内联 style（text-align:right），
   转块级后不覆盖它，右栏文字会贴着屏幕右边、把左栏挤成一条 ——
   所以这里必须显式把 td 及其内联右对齐一起拉回左对齐。 */
@media (max-width:820px){
  .footer table,.fedit table{display:block;width:100%;border-collapse:collapse}
  .footer table tbody,.footer table tr,.fedit table tbody,.fedit table tr{display:block;width:100%}
  .footer table td,.footer table th,.fedit table td,.fedit table th{
    display:block;width:100%;max-width:100%;
    border:0;padding:2px 0;text-align:left !important;
  }
  /* 内联 text-align:right / div 的右对齐一并复位（内联样式优先级最高，只能 !important 压） */
  .footer table td > div,.footer table td > span,.fedit table td > div,.fedit table td > span{text-align:left !important}
  /* 2026-10-20：上下两栏之间留出间距。
     之前 td 的 padding 只有 2px，两栏几乎贴死在一起。
     这里只用 margin 拉开 —— 不画分隔线，因为站长在编辑器里给 td 手写了内联
     style="border:0px"（内联优先级最高），要画线必须 !important 覆盖，
     既加重样式又容易在站长下次编辑时被冲掉；纯 margin 不覆盖任何东西。 */
  .footer table td + td,.fedit table td + td{margin-top:18px}
}
.article--lede{margin-top:4px}
/* 区块正文里的富文本（2026-10-17 十二批）：表格/列表插在 lead 位置时不能撑破版式 */
.article--embed{margin:0}
.article--embed>*:first-child{margin-top:0}
.article--embed>*:last-child{margin-bottom:0}
.article--embed p{font-size:inherit;line-height:inherit;color:inherit}
/* 文章封面：与正文同宽，居中 */
.artcover{max-width:820px;margin:0 auto 46px;border-radius:var(--radius);overflow:hidden;
  border:1px solid var(--line);box-shadow:var(--shadow-card)}
.artcover img{width:100%;height:auto;display:block}

.pager{display:flex;justify-content:space-between;gap:20px;margin-top:70px;padding-top:34px;border-top:1px solid var(--line)}

/* 筛选 */
.chips{display:flex;flex-wrap:wrap;gap:9px;margin-bottom:20px}
.chip{padding:9px 18px;border-radius:var(--radius-pill);border:1px solid var(--line);font-size:14px;color:var(--ink-2);background:var(--surface);transition:all .3s}
.chip:hover{border-color:var(--line-2);color:var(--ink)}
.chip.is-active{background:var(--grad);color:#fff;border-color:transparent;box-shadow:var(--shadow-soft)}

/* 分类条折叠：分类太多时默认只露一行，「更多分类 ▾」展开（pulse.js chipFold 量高决定是否出现） */
.chips[data-fold]{position:relative;padding-right:112px}
.chips[data-fold].is-folded{max-height:44px;overflow:hidden}
.chips .chip--toggle{position:absolute;right:0;top:0;cursor:pointer;user-select:none;white-space:nowrap}

/* =============================================================
   页脚
   ============================================================= */
.footer{position:relative;z-index:3;padding:80px 0 40px;border-top:1px solid var(--line);background:linear-gradient(180deg,transparent,rgba(43,107,255,.05))}
.footer__top{display:grid;grid-template-columns:1.6fr repeat(3,1fr);gap:44px}
/* 页脚链接区：左「扫码关注」（带二维码）/ 右「快捷入口」（纯文字链接，列优先分列排布）。
   两组左右横向排布、顶部对齐；快捷入口不输出分组标题（后台不带二维码的友情链接即归入此列）。
   移动端（≤768px）自动堆叠为上下两区。 */
.flinks{display:flex;flex-wrap:wrap;gap:48px;align-items:flex-start;margin-bottom:36px;--flinks-h:114px}
/* 左：扫码关注（二维码图上文下，同组可横排多张） */
.flinks__qr{display:flex;flex-direction:column;gap:14px}
.flinks__qr .flinks__row{display:flex;flex-wrap:wrap;gap:22px 28px;align-items:flex-start}
/* 右：快捷入口（纯文字超链接，列优先网格：先填满一列再换下一列，每列 4 条）。
   高度对齐：不给行距硬算，而是 min-height 锁到与左栏二维码块同高（--flinks-h），
   再用 align-content:space-between 让 4 行自动均匀撑满 —— 这样文字行数、
   图注行高、字体变化时都不会再错位。 */
.flinks__nav{display:grid;grid-auto-flow:column;grid-template-rows:repeat(4,auto);grid-auto-columns:max-content;justify-items:start;align-content:space-between;column-gap:30px;min-height:var(--flinks-h,114px);min-width:176px}
/* width:fit-content 让每条链接只包裹文字本身，点击热区不再横跨整行（鼠标离文字很远也能点中的问题即此） */
.flink--nav{display:block;width:fit-content;color:var(--ink-2);font-size:14px;line-height:1.42;text-decoration:none;transition:color .25s}
.flink--nav:hover{color:var(--brand);text-decoration:underline}
/* 没有链接地址的条目（含「空白占位」）：前台一律当纯文本处理 ——
   不下划线、不变色、不可点、字重跟随全局总闸保持 400（2026-10-31 站长令）。
   ⚠️ 必须连 :hover 一起按住：.flink--nav:hover 的特异性（0,2,0）高于
      .flink--nav--static（0,1,0），只写静态态的话鼠标一移上去还是会变蓝加下划线。 */
.flink--nav--static,
.flink--nav--static:hover{color:var(--muted);text-decoration:none;cursor:default;font-weight:400}
/* 带二维码但没填地址的那一组同理：图注不跟着 hover 变墨色 */
.flink--qr.flink--static{cursor:default}
.flink--qr.flink--static:hover .flink__t{color:var(--dim)}
/* 页脚联系信息（后台「页脚联系信息」分组单独编辑）：放在友情链接行的最右侧。
   margin-left:auto 吸收掉行内剩余空间、把整块推到行尾 —— 填补「二维码 +
   快捷入口」之后的空白，让整行两端都有落点、不再一头沉（2026-10-29 站长令）。 */
.flinks__info{
  margin-left:auto;display:flex;flex-direction:column;gap:5px;
  max-width:36ch;color:var(--ink-2);font-size:14px;line-height:1.5;
}
.flinks__info-line{margin:0}
/* 三行（公司名 / 地址 / 电话微信）字号与墨色完全一致，与右侧「快捷入口」
   文字链接同为 14px / --ink-2 —— 首行不再单独放大（2026-10-29 站长要求） */
/* 该站没有友情链接、只剩联系信息时：不要把它孤零零顶到行尾（那是从一头沉
   变成另一头沉），改为左对齐，与上面的区块保持同一条起始线 */
.flinks--info-only .flinks__info{margin-left:0}
/* 扫码位：图上文下。图注显式锁定行高，使二维码块总高恒为
   85(图)+8(间距)+21(图注) = 114px，与右栏 --flinks-h 一致（改字体也不会错位） */
.flink--qr{display:inline-flex;flex-direction:column;align-items:center;gap:8px;color:var(--ink-2);text-decoration:none;text-align:center}
.flink__t{font-size:12.5px;line-height:21px;color:var(--dim);letter-spacing:.02em}
.flink--qr:hover .flink__t{color:var(--ink-2)}
.flink__qr{display:block;height:85px;width:auto;border-radius:8px;background:#fff;padding:5px;box-shadow:0 1px 8px rgba(0,0,0,.14)}
/* 移动端：上下堆叠，文字链接列占满整行 */
@media (max-width:768px){
  .flinks{gap:30px 22px}
  .flinks__nav{min-width:0;flex:1 1 100%}
  /* 窄屏：联系信息不再被推到行尾（那会孤零零贴在右边），
     改为独占一整行、左对齐，与上面两块竖向堆叠 */
  .flinks__info{margin-left:0;flex:1 1 100%;max-width:none}
}

/* 页脚底部（版权/声明富文本）与上方「扫码关注 + 快捷入口」区的视觉隔离。
   2026-10-28 站长令：两块之间原本毫无分隔，视觉上黏成一片。
   · 分隔线走 var(--line)，深空暗色等主题自动适配（无需为每个主题单独写死颜色）。
   · 用 --line-2 稍强一档：--line 在 dawn 下是 rgba(16,32,72,.10)，偏弱，
     在浅底上几乎看不见，这里用 line-2 并配合 padding 留白保证可辨识。
   · 只加在 .footer__legal 上，不动 footer_html 富文本内部结构（后台可编辑内容）。 */
.footer__legal{
  margin-top:34px;
  padding-top:8px;
  border-top:1px solid var(--line-2);
}
/* 版权富文本是后台生成的裸 <table>，浏览器给表格默认 margin-top:16px，
   再叠上单元格自身的间距 —— 合计把首行文字推到离分隔线 33px 之远，
   站长看着像「线下面空了一大片」。这里把表格的外边距归零，
   让文字紧贴分隔线（上下留白由 .footer__legal 控制）。
   2026-10-29：单元格内边距改为四向全部归零（见下方规则）—— 站长要求
   文字与表格边框之间不留间距。只影响 .footer__legal 内的表格，不动其它页面的表格。 */
.footer__legal > table,
.footer__legal > span > table,
.footer__legal table{
  margin-top:0;
  margin-bottom:0;
}
.footer__legal td,
.footer__legal th{
  /* 四个方向全部归零：base 的 .footer td 给了横向 11px，只清纵向是没用的 */
  padding:0;
}
/* 窄屏（≤820px）那条 .footer table td{padding:2px 0} 特异性(0,1,2)高于
   .footer__legal td(0,1,1)，会把纵向 2px 又塞回来 —— 这里提权压掉，
   保证四个方向在窄屏下同样是 0。 */
.footer .footer__legal td,
.footer .footer__legal th{
  padding:0;
}
.footer__legal td{
  vertical-align:top;
}
/* 2026-10-29 站长令（定稿）：页脚两栏与上方「友情链接」行对齐 ——
     「声明」贴页脚容器左边缘（与上方二维码左缘齐）；
     「备案号」的**左端**落在上方「联系信息」块的左边缘那条竖线上
     （站长用红线标的即这条线），而不是贴到页面最右边。
   实现：表格铺满整行 + table-layout:fixed，第二列宽度取 --footer-col2-w
   （由 pulse.js 实测 .flinks__info 的真实宽度写入，回落 231px），
   第一列自动吃掉剩余空间 —— 于是第二列左端 = 容器右端 − 联系信息宽度，
   正好与联系信息左端重合。
   ⚠️ 两处都需 !important：
     · 嵌套 table 内联写死了 541.052px / 316.281px（不释放就撑不住列宽控制）
     · 备案号所在 td 内联 text-align:right（这里改左对齐，与上行列首对齐）
   移动端（≤820px）走下方竖排规则（width:100% + margin:0），不受影响。 */
.footer__legal table{
  width:100% !important;
  max-width:100%;
  table-layout:fixed;
}
.footer__legal tr > td + td{
  width:var(--footer-col2-w, 231px);
}
.footer__legal td{
  text-align:left !important;
}
/* 2026-10-29 站长令（定稿）：页脚「声明 / 违规内容举报 / 备案号」三块 ——
   PC 端一行横排、移动端竖排多行，「以富文本编辑器里排的样子为准」。
   因此桌面端这里**不动排版结构**：各列宽度（内联 901 / 351 / 281 / 202px）与
   对齐方式（左 / 居中 / 右）都是站长在编辑器里定的，内联样式优先，CSS 不干预；
   只把 base 给单元格的 padding 归零（见上方规则）。
   （此前曾误把三块强制竖排到所有屏宽，与编辑器不一致，已撤销。） */
/* 窄屏（≤820px）：竖排多行。base 的 .footer table td{display:block} 已经转块级，
   但同在媒体查询里的两条特异性 (0,2,2) 规则会干扰 ——
     .footer table td{padding:2px 0}          （1701-1704 行）
     .footer table td + td{margin-top:18px}   （1712 行，为「左右两栏」留的间距，
                                                竖排后变成多余行距，把三行撑到 35px）
   这里提权压掉，并把编辑器的内联宽度与居中/右对齐一并收口成左对齐。 */
@media (max-width:820px){
  .footer__legal table,
  .footer__legal tbody,
  .footer__legal tr,
  .footer__legal td,
  .footer__legal th{
    display:block;
    width:100% !important;
    max-width:100%;
    border:0;
    margin:0 !important;
    padding:0 !important;
    text-align:left !important;
  }
}
/* 无友情链接时（.flinks 不存在），这条分隔线没有上下文的对比对象，
   只需留住页脚自身的呼吸感，不要再多一条线把页脚切成两半。
   修饰类由 PHP 直接判定（$flinks 为空时加 --sole），不依赖 :has() 的浏览器支持。 */
.footer__legal--sole{
  margin-top:0;
  padding-top:0;
  border-top:0;
}

.footer__brand p{margin:20px 0 0;color:var(--muted);font-size:14.5px;max-width:36ch}
.footer__col h4{font-size:13px;letter-spacing:.2em;text-transform:uppercase;color:var(--dim);margin:0 0 18px;font-weight:400}
.footer__col a{display:block;padding:6px 0;color:var(--ink-2);font-size:14.5px;transition:color .3s,transform .3s}
.footer__col a:hover{color:var(--brand);transform:translateX(3px)}
.footer__bottom{margin-top:60px;padding-top:26px;border-top:1px solid var(--line);display:flex;flex-wrap:wrap;gap:16px;justify-content:space-between;color:var(--dim);font-size:13px}

/* =============================================================
   揭示动画
   ============================================================= */
html.js [data-reveal]{opacity:0;transform:translateY(34px);transition:opacity .9s var(--ease-out),transform .9s var(--ease-out)}
/* 2026-10-31 移动端：34px 大位移 + 0.9s 长动画在低端机上鬼影明显（日期行/标题半透明叠印），
   移动端缩小位移、缩短时长，仅保留轻量渐入。 */
@media (max-width:720px){
  html.js [data-reveal]{transform:translateY(12px);transition:opacity .5s var(--ease-out),transform .5s var(--ease-out)}
}
/* 可见态特异性必须高于「html.js [data-reveal]」(0,2,1)，故加 html.js 前缀成 (0,3,1)，
   否则加了 .is-in 仍被隐藏规则压制 → 整页内容不可见（2026-10-20 整改回归修复） */
html.js [data-reveal].is-in{opacity:1;transform:none}
[data-reveal][data-delay="1"]{transition-delay:.08s}
[data-reveal][data-delay="2"]{transition-delay:.16s}
[data-reveal][data-delay="3"]{transition-delay:.24s}
[data-reveal][data-delay="4"]{transition-delay:.32s}
[data-reveal][data-delay="5"]{transition-delay:.4s}

.counter{font-variant-numeric:tabular-nums}

/* 顶部进度条 */
.progress{position:fixed;left:0;top:0;height:2px;z-index:80;background:var(--grad);width:0;transition:width .1s linear}

/* =============================================================
   首页公告弹窗
   -------------------------------------------------------------
   颜色一律走语义变量，换主题（含深色）自动跟着变；
   结构上「外框定尺寸、内部自己滚」，长公告在小屏上也不会把按钮顶出屏幕。
   ============================================================= */
.notice{position:fixed;inset:0;z-index:95;display:grid;place-items:center;padding:24px}
.notice[hidden]{display:none}
.notice__veil{
  position:absolute;inset:0;background:var(--overlay);backdrop-filter:blur(14px);
  opacity:0;transition:opacity .34s var(--ease);
}
.notice.is-open .notice__veil{opacity:1}
.notice__box{
  position:relative;z-index:1;width:min(560px,100%);max-height:min(86svh,780px);
  display:flex;flex-direction:column;overflow:hidden;
  border-radius:var(--radius);border:1px solid var(--line-2);
  background:var(--surface-2);backdrop-filter:blur(22px);
  box-shadow:var(--shadow-drop);
  opacity:0;transform:translateY(20px) scale(.965);
  transition:opacity .38s var(--ease-out),transform .38s var(--ease-out);
}
.notice.is-open .notice__box{opacity:1;transform:none}
.notice__box::before{
  content:"";position:absolute;left:0;right:0;top:0;height:3px;background:var(--grad);z-index:2;
}
.notice__x{
  position:absolute;right:12px;top:12px;z-index:3;width:38px;height:38px;border-radius:50%;
  display:grid;place-items:center;font-size:15px;line-height:1;
  color:var(--ink-2);background:var(--surface);border:1px solid var(--line-2);
  backdrop-filter:blur(10px);transition:background .3s,transform .3s,color .3s;
}
.notice__x:hover{color:var(--ink);background:var(--surface-2);transform:rotate(90deg)}

.notice__media{flex:0 0 auto;overflow:hidden;background:var(--bg-3)}
.notice__media[hidden]{display:none}
.notice__media img{width:100%;height:auto;max-height:40svh;object-fit:cover;display:block}

.notice__body{
  flex:1 1 auto;min-height:0;overflow:auto;overscroll-behavior:contain;
  padding:30px 30px 24px;display:grid;gap:12px;align-content:start;
}
.notice__kicker{
  font-size:11px;font-weight:400;letter-spacing:.24em;text-transform:uppercase;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent;
}
.notice__kicker[hidden]{display:none}
.notice__title{
  margin:0;font-size:clamp(21px,2.3vw,26px);font-weight:400;letter-spacing:-.02em;line-height:1.32;color:var(--ink);
}
.notice__title[hidden]{display:none}
.notice__text{font-size:15px;line-height:1.82;color:var(--ink-2);min-width:0}
.notice__text>*:first-child{margin-top:0}
.notice__text>*:last-child{margin-bottom:0}
.notice__text p{margin:0 0 12px}
.notice__text ul,.notice__text ol{margin:0 0 12px;padding-left:1.25em;display:grid;gap:6px}
.notice__text li::marker{color:var(--brand)}
.notice__text a{color:var(--brand);text-decoration:underline;text-underline-offset:3px}
.notice__text strong,.notice__text b{color:var(--ink);font-weight:400}
.notice__text img{max-width:100%;height:auto;border-radius:var(--radius-sm);display:block;margin:12px 0}
.notice__text h1,.notice__text h2,.notice__text h3,.notice__text h4{
  margin:16px 0 8px;color:var(--ink);font-weight:400;line-height:1.35;
}
.notice__text blockquote{
  margin:12px 0;padding:10px 16px;border-left:3px solid var(--brand);
  background:var(--surface-3);border-radius:0 var(--radius-sm) var(--radius-sm) 0;color:var(--ink-2);
}
.notice__text code{
  font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:.92em;
  padding:2px 6px;border-radius:6px;background:var(--surface-3);color:var(--ink);
}
.notice__text table{width:100%;border-collapse:collapse;margin:12px 0;font-size:14px}
.notice__text th,.notice__text td{border:1px solid var(--line-2);padding:8px 10px;text-align:left}

.notice__act{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding-top:18px;margin-top:2px;border-top:1px solid var(--line);
}
.notice__act .btn{height:46px;padding:0 24px;font-size:14.5px}
.notice__act .btn[hidden]{display:none}
/* 「不再提示」做成弱化文字按钮：想读公告的人点不到它，想安静的人一眼能找到 */
.notice__mute{
  margin-left:auto;background:none;border:0;padding:6px 2px;cursor:pointer;
  font-size:12.5px;color:var(--dim);text-decoration:underline;text-underline-offset:3px;
  transition:color .3s;
}
.notice__mute:hover{color:var(--ink-2)}
.notice__mute[hidden]{display:none}

@media (max-width:520px){
  .notice{padding:14px}
  .notice__body{padding:26px 20px 20px}
  .notice__box{max-height:min(88svh,780px)}
  .notice__act .btn{width:100%}
  .notice__mute{margin-left:0;align-self:center}
}

/* =============================================================
   响应式
   ============================================================= */
/* 顶栏挤压档：链接强制单行不折行、间距收紧。
   2026-10-16 逐宽度实测（探针强制显示三颗 CTA 后量真实需求），修了三处「静默裁切」：
     ① 下限 861 → 821：821 才有导航链接（≤820 换汉堡），旧下限把 821~860 整段漏在档外，
        导航用宽松 padding（宽 597px），需 959px 而可用只有 773px → 溢出 186px；
     ② 上限 1600 → 取消：容器 --maxw 封顶 1140px，1601+ 反而退回宽松档，
        需 1199px → 溢出 59px（1920 屏同样）；
     ③ 821~1019、821~919 再各让一颗 CTA 出去（见下）。
   溢出之所以一直没被发现：body 有 overflow-x:hidden，超出部分被静默裁掉，
   既不报错也不出滚动条。 */
.nav__links .nav__link, .nav__item > .nav__link { white-space: nowrap; }
.nav__links { flex-wrap: nowrap; }
.nav__cta .btn, .nav__ask { white-space: nowrap; }
@media (min-width:821px) and (max-width:1120px){
  /* 2026-10-16 新增第 8 个一级导航项「渠道合作」后重校：
     links 由 7 项 449px 涨到 8 项 509px，本档最坏宽度（821 / 1024，需 810~1013px）溢出 37px。
     ⚠️ 论坛与主站共用本档，但论坛的字体栈让按钮各宽 2~4px（cta 合计 +15px），
        所以达标线按**论坛**算：行内边距 8→5px（省 48px）+ inner gap 12→6px（省 12px）
        + cta gap 8→6px（省 4px）共 64px，两站都留出 ≥12px 余量。
     ⚠️ 改任何一项都要重跑 tools/check_nav_fit.js（28 宽度 × 两站）
     2026-10-19：logo 与首项间距由 6px 提到 16px、菜单项内边距 5→7px，
     菜单不再挤成一团；多出的宽度从 cta 侧（gap 6→4、内边距 9→8）回收。 */
  .nav__inner{gap:16px}
  .nav__links{gap:0}
  .nav__link,.nav__item>.nav__link{padding:9px 7px;font-size:13px}
  .nav__cta{gap:4px}
  .nav__cta .btn--sm{height:36px;padding:0 8px;font-size:12px}
}
@media (min-width:1121px){
  /* 同上：宽松档在 1121~1155px 溢出 35px（论坛 6px 余量更少），
     行内边距 11→7px + inner gap 20→14px + cta gap 8→6px 压出 64px。
     ≥1160px 本来就有余量，收紧 4px 肉眼无感，换来全宽度无死角。
     2026-10-19 仿源站改回 15px（原先压到 13.5px，导致顶栏比二级菜单还小）。
     间距：logo→首项 30px（对齐源站容器 gap:30px）、项间视觉间隔 26px
     （内边距 13px×2）。宽度从 cta 侧（gap 6→4、内边距 12→10）回收。 */
  .nav__inner{gap:30px}
  .nav__links{gap:0}
  .nav__link,.nav__item>.nav__link{padding:9px 13px;font-size:15px}
  .nav__cta{gap:4px}
  .nav__cta .btn--sm{height:36px;padding:0 10px;font-size:12.5px}
}
/* 821~1023px：「问一问」让位（导航 + 三颗 CTA 需要 960px，1024 宽才有 976px）；
   821~919px：再把「电话」ghost 也让出去，只留主 CTA。
   ⚠️ 这两条的 display:none 必须写在文件下方 .nav__ask{display:inline-flex} / .btn--ghost
   基础规则之后，否则同特异性下会被基础规则吃掉（详见该处注释）。实际写法见下方「问一问档位」。 */
@media (min-width:821px) and (max-width:919px){ .nav__cta .btn--ghost{display:none} }
@media (max-width:1080px){
  .footer__top{grid-template-columns:1fr 1fr}
  .metrics{grid-template-columns:repeat(2,1fr)}
  .rail{grid-template-columns:1fr 1fr}
  .casegrid,.casegrid--4{grid-template-columns:1fr 1fr}
  /* icard 摘要两行、标题可折两行，比 casecard 更矮，1080 档仍排两列 */
  /* narr 单列化下移到 860px：861~1080px 保持双栏（对齐收钱吧官网，1080 宽视口不该丢大图） */
  .narr__steps{padding:8vh 0}
  .narr__step{min-height:52vh}
  /* 窄屏：每一步都预留等高插槽（槽内放静态帧），激活时槽内交叉淡入动画。
     插槽高度恒定，切换步骤不会改变布局，避免高亮步骤被顶偏 */
  /* 槽位高度不再写死：以前固定 min(54vh,340px)，近正方形的框套竖长的动画，
     contain 之后左右各空出一大片，移动端一眼就看出「没铺满」。
     现在由 pulse.js 按当前动画的内容比例改写 height，下面的值只作无 JS 兜底。 */
  .narr__step-anim{position:relative;width:100%;margin-top:24px;padding:14px;border-radius:20px;border:1px solid var(--line);
    display:grid;place-items:center;overflow:hidden;
    height:min(54vh,340px);
    transition:height .5s var(--ease);
    background:var(--bg-3)}
  .narr__step-anim>img{width:100%;height:100%;object-fit:contain;margin:0;border:0;border-radius:14px;background:transparent}
  .narr__step-anim svg{width:100%;height:100%;display:block}
  .hero__grid{gap:44px}
  .hero__grid--split{grid-template-columns:1fr;gap:38px}
  .stage{grid-template-columns:1fr;gap:38px}
  .stage--rev{direction:ltr}
  .sector{grid-template-columns:1fr}
  .sector--rev .sector__media{order:0}
  .sector--rev .sector__copy{order:0}
  .sector__media{min-height:230px}
  .sector__veil,.sector--rev .sector__veil{background:linear-gradient(180deg,rgba(8,14,32,.06),rgba(8,14,32,.5))}
}
@media (max-width:820px){
  :root{--nav-h:66px}
  .nav__links{display:none}
  .nav__burger{display:grid}
  /* 2026-10-12：移动端也要露出「联系顾问」「商家入驻」两颗按钮（原来藏了 ghost），
     靠压缩间距 + 缩小按钮保证 logo + 双按钮 + 汉堡在窄屏一行放得下 */
  .nav__inner{gap:12px}
  .nav__cta{gap:8px;margin-left:auto}
  .nav__cta .btn--sm{height:38px;padding:0 13px;font-size:13px}
  .nav__burger{width:40px;height:40px}
  /* 安全网：品牌再长也不许把后面的按钮挤出屏幕。
     允许 .brand 收缩、站名走省略号——比「溢出后被 body 的 overflow-x:hidden 静默裁掉」好。 */
  .brand{min-width:0}
  .brand > span:not(.brand__mark){min-width:0;overflow:hidden;text-overflow:ellipsis}
  .hero{min-height:auto;padding:calc(var(--nav-h) + 56px) 0 70px}
  .sec-head{flex-direction:column;align-items:flex-start;gap:18px}
  .stream__row{grid-template-columns:1fr;gap:10px}
  .stream__row .go{display:none}
  .rail,.casegrid,.casegrid--4{grid-template-columns:1fr}
  .footer__top{grid-template-columns:1fr;gap:34px}
  /* 移动端改为普通网格：必须解除 size 容器，否则高度不参与布局会塌成 0 */
  .orbit{aspect-ratio:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:14px;max-width:none;container-type:normal}
  .orbit__core,.orbit__track,.orbit__ring{display:none}
  /* 用 relative 而非 static：同样脱离绝对极角定位、回到网格流，
     但能为「名称浮层」提供定位基准（static 会让浮层跑到轨道容器上去）。
     注意必须把基础规则的 left/top:50% 清掉 —— relative 也会吃这两个偏移，
     不清的话每个节点会被整体推到右边（偏右的真正原因）。 */
  .orbit__node{position:relative;left:auto;top:auto;margin:0;width:auto;transform:none !important}
  /* 视频预览窗：窄屏保持完整可见，按钮收小 */
  .vstage__frame{border-radius:20px;box-shadow:0 0 0 4px rgba(43,107,255,.07),0 24px 50px -24px rgba(43,107,255,.6)}
  .vstage__cta{height:46px;padding:0 18px 0 7px;font-size:13.5px;gap:9px}
  .vstage__play{width:32px;height:32px}
  .vstage__glow{inset:-10% -6%;filter:blur(52px)}
  .vstage__caption{left:16px;bottom:14px;font-size:11.5px}
  .vlight{padding:14px}
}
@media (max-width:520px){
  /* 窄屏：logo + 电话 + 主按钮 + 汉堡要挤进一行 —— 左右边距收到 16px、
     logo 与按钮整体再缩一档，否则汉堡会被顶出屏幕外（2026-10-12 实测） */
  :root{--fs-max:19px}   /* 上限跟着 logo 一起缩，保证 logo 仍是最大家（必须 :root，见文件末说明） */
  .nav__inner{width:calc(100% - 32px)}
  .brand{gap:9px}
  .brand__mark{width:30px;height:30px}
  /* 真 logo：只降高度，宽度仍按原图比例（不套方块、不加圆角） */
  .brand__mark--img{width:auto;height:28px}
  .nav__cta{gap:6px}
  .nav__cta .btn--sm{height:36px;padding:0 11px;font-size:12.5px}
  .nav__burger{width:38px;height:38px}
  .metrics{grid-template-columns:1fr}
  .hero__micro{gap:18px}
  .vstage__frame{aspect-ratio:4/3}
}
@media (max-width:350px){
  /* 极窄屏（320 老设备）：再压一档保住汉堡按钮 */
  :root{--fs-max:17px}
  .nav__inner{width:calc(100% - 24px);gap:10px}
  .brand{gap:8px}
  .brand__mark{width:26px;height:26px;border-radius:9px}
  .brand__mark--img{width:auto;height:24px;border-radius:0}
  .nav__cta{gap:5px}
  .nav__cta .btn--sm{height:34px;padding:0 9px;font-size:12px}
  .nav__burger{width:36px;height:36px}
}
/* 手机档（≤480px）：上面那行「logo + 电话 + 主按钮 + 汉堡」在数学上放不下 ——
   2026-10-16 实测 390 宽视口：可用 358px，实际需要 449px（logo 202 + 电话 110 +
   主按钮 75 + 汉堡 38 + 三处间距 18），差 91px。body 有 overflow-x:hidden，
   溢出部分被静默裁掉：主按钮只露一半、汉堡整个看不见 —— 等于手机上打不开菜单。
   主站与 bbs 同源同病（360/390/430 逐项一致）。
   修法：把「电话」这颗低频 ghost 收进 481~820 档，手机只留 logo + 主 CTA + 汉堡；
   电话仍可从页脚与正文的联系入口点到，颗粒度损失最小。 */
@media (max-width:480px){
  .nav__cta .btn--ghost{display:none}
}

@media (prefers-reduced-motion:reduce){
  *{animation:none !important;transition:none !important}
  /* 同样加 html.js 前缀，否则开启「减少动态」的用户仍会被隐藏规则压制成空白 */
  html.js [data-reveal]{opacity:1;transform:none}
  html.js [data-reveal].is-in{opacity:1;transform:none}
}

/* 主标题第二行渐变高亮（默认档）。后台选了「标题特效」时，内层 span 会带上
   .dochero__h--* 档位类 —— 用 :not() 守卫把默认渐变让出来，避免两套效果打架
   （2026-10-19，档位类与内容页推荐区标题同一套）。 */
.hero__title .line:last-child span:not([class*="dochero__h--"]){background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.hero__title .line:only-child span:not([class*="dochero__h--"]){color:var(--ink)}

/* =============================================================
   同行论坛
   -------------------------------------------------------------
   和主站同一套语义色变量：换肤、节日主题都会一并跟着走。
   类名统一 fm 前缀，避免和主站已有的卡片、列表样式打架。
   ============================================================= */
/* 极简页头：只让出固定导航的高度，不渲染任何可见内容（首页的 h1 走 sr-only） */
.fmpad{padding:calc(var(--nav-h) + 10px) 0 0}
.fmpad--tight{padding:calc(var(--nav-h) + 30px) 0 26px}

.fmhead{padding:calc(var(--nav-h) + 46px) 0 26px}
.fmhead--sec{padding:calc(var(--nav-h) + 34px) 0 24px}
/* 板块页大标题：与全站 h1 同档（2026-10-14 用户要求大幅缩小，勿调回 4.4vw） */
.fmhead h1{font-size:clamp(19px,2.1vw,28px);letter-spacing:-.02em}
.fmhead p{margin:14px 0 0;color:var(--ink-2);max-width:74ch}

/* 板块页头：左边板块名，右边一颗显眼的发帖主按钮 */
.fmbtop{display:flex;align-items:flex-end;justify-content:space-between;gap:28px;flex-wrap:wrap}
.fmbtop__t{min-width:0}
.fmbtop__nav{display:flex;align-items:center;flex-wrap:wrap;gap:14px;margin-top:16px;
  font-size:13.5px;color:var(--dim)}
.fmbtop__nav b{color:var(--ink-2);font-weight:400}
.fmcta{display:inline-flex;align-items:center;gap:9px;padding:15px 30px;border-radius:var(--radius-pill);
  background:var(--grad);color:#fff;font-size:16px;font-weight:400;white-space:nowrap;
  box-shadow:0 16px 34px -14px rgba(43,107,255,.75);
  transition:transform .2s ease,box-shadow .25s ease}
.fmcta:hover{transform:translateY(-2px);box-shadow:0 22px 40px -14px rgba(43,107,255,.85)}
.fmcta__i{font-size:19px;line-height:1;font-weight:400}
.fmhead__stats{display:flex;flex-wrap:wrap;gap:10px;margin-top:20px}
.fmstat{padding:8px 14px;border:1px solid var(--line);border-radius:var(--radius-pill);
  background:var(--surface);font-size:13px;color:var(--ink-2)}
.fmstat b{color:var(--ink);font-weight:400}

.fmnav{display:flex;flex-wrap:wrap;gap:8px;margin-top:22px}
.fmnav a{padding:8px 16px;border:1px solid var(--line);border-radius:var(--radius-pill);
  font-size:13.5px;color:var(--ink-2);background:var(--surface);transition:all .25s}
.fmnav a:hover{border-color:var(--line-2);color:var(--ink)}
.fmnav a.is-on{background:var(--grad);color:#fff;border-color:transparent}

.fmbody{padding:0 0 96px}
.fmsec{margin-top:34px}
.fmsec__head{display:flex;align-items:center;justify-content:space-between;gap:20px;margin-bottom:16px}
.fmsec__head h2{font-size:20px}
.fmsec__head .hint{font-size:13px;color:var(--dim)}

.fmcard{border:1px solid var(--line);border-radius:var(--radius);background:var(--bg-3);
  box-shadow:var(--shadow-soft);overflow:hidden}
.fmcard + .fmcard{margin-top:14px}

.fboard{display:flex;align-items:center;gap:20px;padding:20px 22px;transition:background .25s}
.fboard:hover{background:var(--surface-2)}
.fboard__t{flex:1;min-width:0}
.fboard__t b{display:block;font-size:16.5px;color:var(--ink)}
.fboard__t span{display:block;margin-top:5px;font-size:13px;color:var(--muted)}
.fboard__n{text-align:right;font-size:12.5px;color:var(--dim);white-space:nowrap}
.fboard__n b{display:block;font-size:17px;color:var(--ink)}

.frow{display:flex;align-items:flex-start;gap:14px;padding:16px 20px;border-top:1px solid var(--line)}
.fmcard > .frow:first-child{border-top:0}
.frow:hover{background:var(--surface-2)}
.frow__main{flex:1;min-width:0}
.frow__main a.t{font-size:15.5px;color:var(--ink);font-weight:400;line-height:1.5}
.frow__main a.t:hover{color:var(--brand)}
.fmeta{margin-top:7px;display:flex;flex-wrap:wrap;gap:12px;font-size:12.5px;color:var(--dim)}
.frow__n{text-align:right;font-size:12px;color:var(--dim);white-space:nowrap;min-width:86px}
.frow__n b{display:block;font-size:15px;color:var(--ink-2)}

.fpill{display:inline-flex;align-items:center;gap:5px;height:20px;padding:0 9px;border-radius:999px;
  font-size:11.5px;line-height:1;border:1px solid var(--line-2);color:var(--muted);vertical-align:1px}
.fpill--pin{background:var(--grad);border-color:transparent;color:#fff}
.fpill--lock{border-color:var(--line-2)}
.fpill--role{background:var(--grad-soft);border-color:transparent;color:var(--brand)}
.fpill--wait{color:#a4650c;border-color:rgba(200,144,26,.4);background:rgba(200,144,26,.10)}

.fpost{display:flex;gap:16px;padding:22px 0;border-top:1px solid var(--line)}
.fpost:first-child{border-top:0}
.favt{width:42px;height:42px;flex:0 0 42px;border-radius:50%;display:grid;place-items:center;
  background:var(--grad);color:#fff;font-size:16px;font-weight:400}
.favt--guest{background:linear-gradient(100deg,#7d8db4,#a8b3cc)}
.fpost__b{flex:1;min-width:0}
.fpost__h{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.fpost__h b{font-size:14.5px;color:var(--ink)}
.fpost__h time{font-size:12.5px;color:var(--dim)}
.fpost__body{margin-top:12px;font-size:15.5px;line-height:1.85;color:var(--ink-2);word-break:break-word}
.fpost__body p{margin:0 0 12px}
.fpost__body img{max-width:100%;height:auto;border-radius:12px;margin:10px 0;display:block}
.fpost__body video{max-width:100%;border-radius:12px;margin:10px 0;background:#000}
.fpost__body a{color:var(--brand);text-decoration:underline}
.fpost__body blockquote{margin:14px 0;padding:12px 16px;border-left:3px solid var(--line-2);
  background:var(--surface-3);border-radius:0 10px 10px 0;color:var(--ink-2)}
.fpost__body pre{overflow:auto;padding:14px 16px;border-radius:12px;background:var(--surface-3);font-size:13.5px}
.fpost__body code{font-family:ui-monospace,Consolas,monospace;font-size:13.5px}
.fpost__body ul,.fpost__body ol{margin:0 0 12px;padding-left:22px}

.finp,.ftxa{width:100%;border:1px solid var(--line-2);border-radius:var(--radius-sm);
  background:var(--bg-3);color:var(--ink);font:inherit;padding:12px 14px;transition:border-color .2s,box-shadow .2s}
.finp:focus,.ftxa:focus{outline:0;border-color:var(--brand);box-shadow:0 0 0 3px rgba(43,107,255,.14)}
.ftxa{min-height:190px;line-height:1.8;resize:vertical}
.flabel{display:block;font-size:13.5px;color:var(--ink-2);margin-bottom:8px;font-weight:400}
.fform{display:grid;gap:18px}
.fform__row{display:grid;gap:18px;grid-template-columns:1fr 1fr}
.fhint{font-size:12.5px;color:var(--dim);margin-top:8px}

.fcomposer{border:1px solid var(--line);border-radius:var(--radius);background:var(--bg-3);
  box-shadow:var(--shadow-soft);padding:22px}
.fcomposer__bar{display:flex;align-items:center;justify-content:space-between;gap:16px;
  margin-top:16px;flex-wrap:wrap}
.fcomposer__tools{display:flex;gap:8px;flex-wrap:wrap}
.fcomposer__tools button{height:38px;padding:0 14px;border-radius:10px;border:1px solid var(--line-2);
  background:var(--surface);font-size:13px;color:var(--ink-2);cursor:pointer;transition:all .2s}
.fcomposer__tools button:hover{border-color:var(--line-3);color:var(--ink)}
.fmedia{display:flex;gap:10px;flex-wrap:wrap;margin-top:12px}
.fmedia img,.fmedia video{height:74px;width:auto;border-radius:10px;border:1px solid var(--line)}

.fempty{padding:56px 24px;text-align:center;color:var(--dim);font-size:14px}
.fempty b{display:block;font-size:16px;color:var(--ink-2);margin-bottom:8px}

.fpager{display:flex;gap:8px;justify-content:center;margin-top:26px;flex-wrap:wrap}
.fpager a,.fpager span{padding:8px 14px;border-radius:10px;border:1px solid var(--line);
  font-size:13.5px;color:var(--ink-2);background:var(--surface)}
.fpager .is-on{background:var(--grad);color:#fff;border-color:transparent}

.fauth{max-width:460px;margin-inline:auto}
.fauth .fmcard{padding:30px 28px}
.fauth h1{font-size:26px;margin-bottom:8px}
.fauth .hint{font-size:13.5px;color:var(--muted)}
.fcap{display:flex;align-items:center;gap:12px}
.fcap img{border-radius:10px;border:1px solid var(--line);cursor:pointer;display:block}

.fflash{margin:0 auto 20px;max-width:760px;padding:12px 16px;border-radius:12px;font-size:14px;
  border:1px solid var(--line-2);background:var(--surface)}
.fflash--warn{border-color:rgba(200,144,26,.45);background:rgba(200,144,26,.10);color:#8a5a08}

/* .rsbadge 已删（2026-10-18 三十批）：业务员站不再显示「返回主站」浮动角标 */

/* 全站隐藏面包屑（2026-10-18 三十二批，站长令）：透明字 + 1px 裁切，
   肉眼不可见、不占布局，但留在 DOM 里供爬虫读结构化路径 */
.srcrumbs{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0;color:transparent;font-size:12px;line-height:1.6}
.srcrumbs a{color:transparent;text-decoration:none}
.srcrumbs__sep{color:transparent;margin:0 6px}

/* 可见面包屑（整改 #1）：内页顶部层级线索，克制的小字灰链；知识库页用自己的 .kbcrumbs，这里隐藏避免重复 */
/* 面包屑（整改 #1，2026-10-20 定位修正）：前台顶栏是 fixed（height:var(--nav-h)），
   页面首块各自用 padding-top:calc(var(--nav-h)+X) 让位。若面包屑走普通流排在 <main> 最前，
   会从 y=0 开始被压在固定顶栏下面、与 logo 重叠。
   改法：相对 main 绝对定位在「顶栏下 + 12px」，正好落在页头预留白里，不撑双重留白、不压顶栏。
   极少数首块留白不足的页头（论坛 .fmpad/.lhead__board）由 main.has-crumbs 补点上方空间。 */
.breadcrumbs{position:absolute;top:calc(var(--nav-h) + var(--crumbs-top));left:0;right:0;z-index:4;
  display:flex;flex-wrap:wrap;align-items:center;gap:6px;
  max-width:var(--maxw);margin:0 auto;padding:0 24px;font-size:13px;line-height:1.5;color:var(--muted)}
/* 有面包屑时，首块统一让到 --sp-head；无面包屑时用各自的默认顶距（见 .lhead__board）。 */
main.has-crumbs .lhead__board,
main.has-crumbs .fmpad{padding-top:var(--sp-head)}
.breadcrumbs__sep{color:var(--dim);margin:0 2px}
.breadcrumbs__lk{color:var(--ink-2);text-decoration:none;transition:color .2s}
.breadcrumbs__lk:hover{color:var(--brand)}
.breadcrumbs__now{color:var(--muted);font-weight:400}

@media (max-width:720px){
  .fform__row{grid-template-columns:1fr}
  .frow__n{display:none}
  .fboard__n{display:none}
  .fpost{gap:12px}
  .favt{width:36px;height:36px;flex:0 0 36px;font-size:14px}
}


/* =============================================================
   功能扩展（2026-10-14）：论坛站内搜索 + 附件下载卡片
   —— 与动效无关的实体功能，不放在可开关的 fx.css 里
   ============================================================= */

/* 论坛搜索条（首页 / 板块页 / 搜索页共用） */
.fmsearch{display:flex;gap:10px;align-items:center;max-width:560px}
.fmsearch .finp{flex:1;min-width:0}
.fmsearch--sm{max-width:380px}
.fmsearch mark,.frow mark{
  background:linear-gradient(100deg,rgba(43,107,255,.18),rgba(163,79,216,.18));
  color:var(--brand);border-radius:3px;padding:0 2px;
}
/* 搜索结果里的正文摘要（两行截断） */
.fsnip{margin-top:6px;font-size:13px;color:var(--muted);line-height:1.7;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* 附件下载卡片（编辑器插入的 .attach，前后台共用此结构） */
.attach{
  display:inline-flex;align-items:center;gap:12px;max-width:100%;
  margin:6px 0;padding:12px 18px 12px 14px;
  border:1px solid var(--line);border-radius:var(--radius-sm);
  background:var(--surface);color:var(--ink);text-decoration:none;
  box-shadow:var(--shadow-soft);transition:border-color .25s,transform .25s,box-shadow .25s;
}
.attach:hover{border-color:var(--brand);transform:translateY(-2px);box-shadow:var(--shadow-card)}
.attach__ic{
  flex:none;width:40px;height:40px;display:grid;place-items:center;
  border-radius:10px;background:var(--grad-soft);font-size:19px;
}
.attach__t{font-weight:400;font-size:14.5px;word-break:break-all;line-height:1.4}
.attach__s{flex:none;font-size:12px;color:var(--dim);white-space:nowrap}
.attach__dl{flex:none;color:var(--brand);font-size:12.5px;font-weight:400;margin-left:4px}

/* 返回顶部小按钮（右下角悬浮，滚过一屏才出现）
   纯功能，不进 fx.css —— 关掉视觉增强层也必须还在 */
.totop{
  position:fixed;right:18px;bottom:18px;z-index:60;
  width:44px;height:44px;display:grid;place-items:center;
  border-radius:var(--radius-pill);border:1px solid var(--line-2);
  background:var(--surface-2);backdrop-filter:blur(12px);
  color:var(--ink-2);box-shadow:var(--shadow-soft);cursor:pointer;
  opacity:0;transform:translateY(10px) scale(.9);
  transition:opacity .3s var(--ease-out),transform .3s var(--ease-out),color .25s,border-color .25s,box-shadow .25s;
}
.totop[hidden]{display:none}
.totop.is-on{opacity:1;transform:none}
.totop:hover{color:var(--brand);border-color:var(--brand);transform:translateY(-2px);box-shadow:var(--shadow-card)}
.totop:focus-visible{outline:0;border-color:var(--brand);box-shadow:0 0 0 4px rgba(43,107,255,.18)}
.totop svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2.1;
  stroke-linecap:round;stroke-linejoin:round}
@media (max-width:720px){
  .totop{right:12px;bottom:12px;width:40px;height:40px}
  .totop svg{width:16px;height:16px}
}

/* 移动端右下浮动入口（2026-10-26 调整）：
   ① 问一问（AI 问答）从「返回顶部上方一档」移到「界面中部高度」（top:50%），更顺手；
   ② 其上方新增「商业洞察计算器」入口 .calcfab（算 字青蓝圆钮），点击进 /calculator。
   两者皆仅 ≤720px 显示（PC 沿用顶栏/抽屉入口）；/ask 与 /calculator 页
   各自不渲染指向自身的入口（见 views/site/layout.php）。
   保留：品牌红金渐变 + 呼吸光环（站长 10-21 要的「美化显眼」）；纯 CSS 入场，不依赖 JS。 */
.askfab{
  position:fixed;right:10px;top:50%;z-index:60;
  display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;
  border-radius:50%;border:0;
  background:var(--grad);
  color:#fff;
  box-shadow:0 10px 24px -6px rgba(43,107,255,.55), inset 0 1px 0 rgba(255,255,255,.25);
  font-size:18px;line-height:1;text-decoration:none;
  animation:askfab-in .45s var(--ease-out) .3s both;
  transition:transform .22s var(--ease-out), box-shadow .22s var(--ease-out);
}
/* 外圈呼吸光环：暗夜里的「AI 在线」 */
.askfab::before{content:"";position:absolute;inset:-4px;border-radius:50%;
  border:1.5px solid rgba(43,107,255,.45);animation:askfab-halo 2.4s var(--ease-out) infinite}
@keyframes askfab-halo{0%{transform:scale(.85);opacity:.9}70%{transform:scale(1.3);opacity:0}100%{transform:scale(1.3);opacity:0}}
@keyframes askfab-in{from{opacity:0;transform:translateY(10px) scale(.9)}to{opacity:1;transform:none}}
.askfab:hover{transform:translateY(-2px);box-shadow:0 14px 30px -6px rgba(43,107,255,.65), inset 0 1px 0 rgba(255,255,255,.25)}
.askfab:active{transform:scale(.94)}
.askfab:focus-visible{outline:0;box-shadow:0 0 0 4px rgba(43,107,255,.25)}

/* 「商业洞察计算器」浮动入口：界面中部高度再上移 58px（44 钮 + 14 间距），位于问一问上方 */
.calcfab{
  position:fixed;right:10px;top:calc(50% - 58px);z-index:60;
  display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;
  border-radius:50%;border:0;
  background:linear-gradient(135deg,#1f9bbf 0%,#1565a0 100%);
  color:#fff;
  box-shadow:0 10px 24px -6px rgba(31,155,191,.5), inset 0 1px 0 rgba(255,255,255,.25);
  font-size:18px;line-height:1;text-decoration:none;
  animation:askfab-in .45s var(--ease-out) .3s both;
  transition:transform .22s var(--ease-out), box-shadow .22s var(--ease-out);
}
.calcfab::before{content:"";position:absolute;inset:-4px;border-radius:50%;
  border:1.5px solid rgba(31,155,191,.45);animation:askfab-halo 2.4s var(--ease-out) infinite}
.calcfab:hover{transform:translateY(-2px);box-shadow:0 14px 30px -6px rgba(31,155,191,.6), inset 0 1px 0 rgba(255,255,255,.25)}
.calcfab:active{transform:scale(.94)}
.calcfab:focus-visible{outline:0;box-shadow:0 0 0 4px rgba(31,155,191,.25)}

/* PC 端「AI 问一问」悬浮入口（2026-10-26 末次调整 · hybrid 形态）：
   ① 「AI」两字横向（顶部小标，不再竖排）；
   ② 「问一问」三字竖向（下方竖排，writing-mode）；
   ③ 钉在**左侧**边缘——浏览器扩展侧栏/插件工具条多在右侧，贴右边会被盖住，左侧干净；
      整体窄身（宽度仅约 34px）钉在左缘留白区，正文居中容器不压内容。
   默认隐藏，仅 ≥1024px 显示（避免与移动端浮标重复）。 */
.askfloat{
  position:fixed;left:0;top:30%;z-index:60;
  display:none;                 /* 默认隐藏，PC 媒体查询内才显示 */
  flex-direction:column;align-items:center;gap:5px;
  padding:11px 8px;border-radius:0 14px 14px 0;   /* 朝页面内（右）一侧圆角 */
  background:linear-gradient(135deg,#253a68 0%,#152344 100%);
  color:#fff;text-decoration:none;white-space:nowrap;
  box-shadow:0 10px 24px -8px rgba(16,28,58,.5), inset 0 1px 0 rgba(255,255,255,.12);
  transition:transform .26s var(--ease-out), box-shadow .26s var(--ease-out);
}
.askfloat__ai{font-size:11px;font-weight:700;letter-spacing:.06em;line-height:1;opacity:.95} /* 横向小标 */
.askfloat__txt{writing-mode:vertical-rl;text-orientation:upright;font-size:14px;font-weight:600;letter-spacing:.2em;line-height:1.12} /* 竖向 */
.askfloat:hover{transform:translateX(3px);box-shadow:0 14px 28px -8px rgba(16,28,58,.6), inset 0 1px 0 rgba(255,255,255,.16)}
.askfloat:active{transform:translateX(1px)}
.askfloat:focus-visible{outline:0;box-shadow:0 0 0 4px rgba(43,107,255,.30)}
@media (min-width:1024px){.askfloat{display:inline-flex}}

/* PC 端隐藏（同特异性，放基础规则之后避免被 .askfab/.calcfab 反压） */
@media (min-width:721px){.askfab,.calcfab{display:none}}

/* 常见问题 FAQ（2026-10-26）：玻璃卡 + 品牌渐变序号 + 展开旋转标记，贴合站点主题 */
.faq{display:flex;flex-direction:column;gap:12px}
.faq__item{
  background:var(--surface);border:1px solid var(--line-2);border-left:3px solid transparent;
  border-radius:var(--radius-sm);overflow:hidden;
  transition:border-color .22s var(--ease-out),box-shadow .22s var(--ease-out),transform .22s var(--ease-out);
}
.faq__item[open]{border-left-color:var(--brand);box-shadow:var(--shadow-card)}
.faq__item:hover{transform:translateY(-1px);box-shadow:var(--shadow-soft)}
.faq__q{
  display:flex;align-items:center;gap:12px;cursor:pointer;list-style:none;
  padding:15px 18px;font-weight:600;color:var(--ink);
}
.faq__q::-webkit-details-marker{display:none}
.faq__no{
  flex:0 0 auto;min-width:28px;height:28px;padding:0 8px;border-radius:999px;
  display:inline-flex;align-items:center;justify-content:center;
  font:600 12.5px/1 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:#fff;
  background:var(--grad);
}
.faq__qt{flex:1 1 auto;min-width:0}
.faq__ic{flex:0 0 auto;width:18px;height:18px;color:var(--brand);
  fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;
  transition:transform .25s var(--ease-out)}
.faq__item[open] .faq__ic{transform:rotate(45deg)}
.faq__a{padding:0 18px 16px 58px;color:var(--dim);line-height:1.75}
@media (max-width:560px){.faq__a{padding-left:18px}}

/* 2026-10-20 二十批：栏目搜索条下线，改为「问 AI」引导条。
   原 .csearch* 一整套规则随之下线（页面不再有搜索输入框）。
   新的 .cqbar 只在 URL 带 ?q= 时出现（多半是搜索引擎收录的老链接），
   把访客从「没搜到」引到 AI 问答去 —— 那边是自然语言检索，比关键词框更准。 */
.cqbar{margin:14px 0 0;padding:11px 15px;border-radius:var(--radius-sm);
  background:var(--surface-2);border:1px solid var(--line-2);
  display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.cqbar__t{margin:0;font-size:13.5px;color:var(--ink-2);flex:1 1 auto;min-width:0}
.cqbar__t b{color:var(--brand)}
.cqbar__go{flex:none;font-size:13px;color:var(--brand);text-decoration:none;white-space:nowrap;
  padding:4px 12px;border-radius:999px;border:1px solid var(--brand);transition:background .18s var(--ease-out)}
.cqbar__go:hover{background:rgba(43,107,255,.08)}
.cqbar__meta{margin:14px 0 0;font-size:13px;color:var(--ink-2);display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.cqbar__meta b{color:var(--brand)}
.cqbar__meta .cqbar__go{padding:3px 11px;font-size:12.5px}

/* 论坛首页：搜索条收进「板块」标题行，压扁到一行文字的高度
   （.fmsearch--head 只作用于首页头部；板块页 .fmbtop__nav 里的那条保持原样） */
.fmsec__head{flex-wrap:wrap;row-gap:8px}
.fmsearch--head{flex:0 1 360px;min-width:220px}
.fmsearch--head .finp{padding:7px 12px;font-size:13.5px}
.fmsearch--head .btn--sm{height:auto;padding:8px 16px;font-size:13.5px}
@media (max-width:720px){
  .fmsearch--head{flex:1 1 100%;order:3}   /* 手机上搜索条单独一行，不挤登录入口 */
}

/* =============================================================
   站内问答（/ask）
   -------------------------------------------------------------
   「AI 生成」徽标走品牌渐变实底 —— 合规要求标识必须显著，
   不能用浅色小字糊弄过去，这里刻意做得比正文更抢眼。
   ============================================================= */

/* 页头入口：桌面显示，窄屏让位给 CTA（改从抽屉菜单进）
   2026-10-21：改成「墨蓝 AI 胶囊」——顶栏是浅色玻璃底，一颗深色高对比 pill
   最抓眼，又不和右侧主 CTA 的品牌渐变撞色；扫光 + 星星旋转 + 绿色呼吸点
   三处小动效，暗示「AI 在线、点我有回应」。 */
.nav__ask{display:inline-flex;align-items:center;gap:8px;height:42px;padding:0 19px;
  border-radius:var(--radius-pill);position:relative;overflow:hidden;
  background:linear-gradient(135deg,#253a68 0%,#152344 58%,#0e1830 100%);
  border:1px solid rgba(255,255,255,.16);
  color:#fff;font-size:14px;font-weight:600;letter-spacing:.02em;text-decoration:none;
  box-shadow:0 8px 20px -8px rgba(16,28,58,.55), inset 0 1px 0 rgba(255,255,255,.12);
  transition:all .28s var(--ease-out)}
.nav__ask svg{color:#93b4ff;flex:none;transition:transform .45s var(--ease-out)}
.nav__ask::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(115deg,transparent 34%,rgba(255,255,255,.22) 50%,transparent 66%);
  transform:translateX(-130%)}
.nav__ask:hover{transform:translateY(-2px);
  box-shadow:0 13px 26px -8px rgba(16,28,58,.62), inset 0 1px 0 rgba(255,255,255,.16)}
.nav__ask:hover svg{transform:rotate(96deg) scale(1.1)}
.nav__ask:hover::after{transform:translateX(130%);transition:transform .7s var(--ease-out)}
.nav__ask:active{transform:translateY(0)}
.nav__ask:focus-visible{outline:0;box-shadow:0 0 0 4px rgba(43,107,255,.30)}
/* 绿色呼吸点：AI 在线 */
.nav__ask-dot{position:relative;width:6px;height:6px;border-radius:50%;background:#4ade80;flex:none;
  box-shadow:0 0 6px rgba(74,222,128,.8)}
.nav__ask-dot::after{content:"";position:absolute;inset:-3px;border-radius:50%;
  border:1px solid rgba(74,222,128,.65);animation:askdot-pulse 2s var(--ease-out) infinite}
@keyframes askdot-pulse{0%{transform:scale(.6);opacity:1}100%{transform:scale(1.6);opacity:0}}
@media (prefers-reduced-motion:reduce){.nav__ask-dot::after{animation:none;opacity:0}}

/* 「商业洞察计算器」PC 顶栏入口（2026-10-26）：与 .nav__ask 同形态，青蓝渐变呼应移动端 .calcfab 浮标；
   受后台「前端菜单 → 顶栏显示计算器」开关控制；≤1023px 隐藏（与 .nav__ask 一致，移动端用浮标）。 */
.nav__calc{display:inline-flex;align-items:center;gap:8px;height:42px;padding:0 19px;
  border-radius:var(--radius-pill);position:relative;overflow:hidden;
  background:linear-gradient(135deg,#1f9bbf 0%,#1565a0 100%);
  border:1px solid rgba(255,255,255,.16);
  color:#fff;font-size:14px;font-weight:600;letter-spacing:.02em;text-decoration:none;
  box-shadow:0 8px 20px -8px rgba(21,101,160,.55), inset 0 1px 0 rgba(255,255,255,.12);
  transition:all .28s var(--ease-out)}
.nav__calc:hover{transform:translateY(-2px);
  box-shadow:0 13px 26px -8px rgba(21,101,160,.62), inset 0 1px 0 rgba(255,255,255,.16)}
.nav__calc:active{transform:translateY(0)}
.nav__calc:focus-visible{outline:0;box-shadow:0 0 0 4px rgba(31,155,191,.30)}
@media (max-width:1023px){.nav__calc{display:none}}

.sheet__ask{display:flex;align-items:center;gap:11px;margin:0 0 12px;padding:15px 18px;
  border-radius:16px;position:relative;overflow:hidden;
  background:var(--grad);color:#fff;font-size:15.5px;font-weight:600;
  text-decoration:none;box-shadow:0 14px 30px -12px rgba(43,107,255,.65), inset 0 1px 0 rgba(255,255,255,.22);
  transition:transform .22s var(--ease-out), box-shadow .22s var(--ease-out)}
.sheet__ask svg{flex:none;color:#fff}
.sheet__ask::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(115deg,transparent 34%,rgba(255,255,255,.26) 50%,transparent 66%);
  transform:translateX(-130%)}
.sheet__ask:active{transform:scale(.98)}
.sheet__ask:active::after{transform:translateX(130%);transition:transform .7s var(--ease-out)}
.sheet__ask-ai{margin-left:auto;flex:none;font-size:11px;font-weight:700;letter-spacing:.1em;
  padding:3px 10px;border-radius:99px;background:rgba(255,255,255,.22);border:1px solid rgba(255,255,255,.38)}
/* 「问一问」的显示档位 —— 必须紧跟上面 1481 行的基础规则之后（层叠顺序说了算）。
   ⚠️ 基础规则 .nav__ask{display:inline-flex} 是无条件的、同特异性的；
   任何写在它前面的 display:none 都会被它吃掉。这个坑真实存在过：
   2026-10-16 实测 821~1010px 段「问一问」一直顶着，把 CTA 挤出容器右缘（960 宽超出 32px）。
   档位：≥1024px 显示；≤1023px 隐藏 —— 含手机的 ≤820 档（那里换汉堡，AI 入口走
   抽屉里的 .sheet__ask）。 */
@media (max-width:1023px){.nav__ask{display:none}}

/* 问一问页页头（标题+简介）已按站长令 2026-10-24 整块删除，
   页面直接从聊天窗开始；旧 .phead--ask 瘦身样式一并移除。
   页头没了之后聊天窗会顶进固定导航底下（实测「新对话」按钮 y=30 被导航底 74 盖住），
   用 blk--ask 补一个「导航高度 + 呼吸位」的顶距。 */
.blk--ask{padding-top:calc(var(--nav-h) + 14px)}
/* 2026-10-24 站长令：对话框尽量抵满页面宽度。
   原 .wrap 封顶 1140px、两侧各留 24px——宽屏下对话框缩在中间一圈，两边大片空白；
   对话页容器放开到全宽（只留 12px 呼吸位），不再有 1140 上限。
   注意只改问一问页的容器，别动全局 .wrap（首页/文章页排版依赖它）。 */
.blk--ask .wrap{width:calc(100% - 24px)}

/* =============================================================
   站内问答（/ask）· 聊天窗形态（2026-10-21）
   -------------------------------------------------------------
   旧版是「搜索框逻辑」：输入框在顶部，答案渲染在它下方，
   回答一长，再提问就得返回上方找输入框。
   现改为聊天窗：对话记录在上方 .ask__stage 内滚动，
   输入区 .ask__composer 常驻底部，回答多长都能接着问。

   2026-10-24 修复（小窗口看不到输入框）：min-height 写死 520/440px，
   在矮视口（实测 690×626 窗口）下会盖过「视口高 − 顶部偏移」的计算高度，
   卡片被撑高、输入区整个滚出首屏。现改为 min(基准, 视口适配高度)——
   卡片底部恒等于视口底 −20px，输入区永远落在首屏内。
   ============================================================= */
.ask{
  display:flex;flex-direction:column;
  /* 2026-10-31 站长令：去掉固定高度与内部滚动条——
     对话框随内容自然撑高，超长回答整页滚动展示，框内不再出现滚动条。
     （ask.js 里 fitStage() 写入的 --ask-top 已不再被消费，保留无害。） */
  border:0;border-radius:var(--radius);
  background:var(--bg-3);
}

/* ---- 对话区：随内容自然撑高，整页滚动（不再框内滚动，2026-10-31） ----
   2026-10-24（三次）站长令：内边距收窄，宽度尽量给文本 */
.ask__stage{
  padding:0 14px 14px;display:flex;flex-direction:column;gap:14px;
}

/* P3-9：移动端「问一问」底部留白，避免正文贴底或被浮钮遮挡 */
@media (max-width:767px){
  .blk--ask{padding-bottom:calc(env(safe-area-inset-bottom, 0px) + 24px)}
  .ask{padding-bottom:calc(env(safe-area-inset-bottom, 0px) + 20px)}
}

/* ---- 空态：还没开口时，先打招呼再给几个能问的（2026-10-24 压缩，给小窗口让位） ---- */
.ask__hello{display:flex;flex-direction:column;align-items:center;justify-content:center;
  flex:1 1 auto;text-align:center;padding:22px 12px 4px}
.ask__hello[hidden]{display:none}
.ask__hello-t{margin:0 0 6px;font-size:18px;font-weight:600;color:var(--ink)}
.ask__hello-s{margin:0 0 16px;font-size:13.5px;color:var(--muted);max-width:50ch;line-height:1.75}
.ask__chips{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px}
.ask__chips-label{font-size:13px;color:var(--muted)}
.chip--btn{font:inherit;font-size:13.5px;padding:7px 15px;cursor:pointer}

/* ---- 对话流 ----
   2026-10-24（三次）站长令：消息去一切边框/底色/阴影装饰——
   AI 回答通栏纯文本（零 padding 零边框），面积全给内容；
   问句只保留渐变底以区分说话人（无阴影）。 */
.ask__log{display:flex;flex-direction:column;gap:14px}
.ask__log:empty{display:none}
.ask-msg{padding:10px 0;border-radius:var(--radius-sm);max-width:100%;
  line-height:1.8;font-size:15px;position:relative;word-break:break-word;
  animation:ask-msg-in .3s var(--ease-out) both}
@keyframes ask-msg-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.ask-msg{animation:none}}
.ask-msg--me{align-self:flex-end;max-width:76ch;background:var(--grad);color:#fff;padding:8px 14px}
.ask-msg--me p{margin:0}
.ask-msg--ai{align-self:flex-start;width:100%;background:transparent;border:0;
  box-shadow:none;padding:0}
.ask-msg--ai p{margin:0 0 10px}
.ask-msg--ai p:last-child{margin-bottom:0}
.ask-msg--ai ul{margin:0 0 10px;padding-left:22px}
.ask-msg--ai b{font-weight:400}

.ask-badge{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;font-weight:400;
  padding:3px 10px;border-radius:var(--radius-pill);background:var(--grad);color:#fff;
  letter-spacing:.02em;margin-bottom:6px}
.ask-src{margin-left:8px;font-size:11.5px;color:var(--muted)}
.ask-caret{display:inline-block;width:7px;height:16px;vertical-align:-3px;margin-left:2px;
  background:var(--brand);border-radius:1px;animation:ask-blink 1s steps(1) infinite}
@keyframes ask-blink{0%,50%{opacity:1}51%,100%{opacity:0}}
@media (prefers-reduced-motion:reduce){.ask-caret{animation:none;opacity:1}}

/* 2026-10-29：每条 AI 回答下的「答案有误？」入口（所有人可见；登录用户可提交正确说法，访客仅标记） */
.ask-correct{margin-top:10px}
.ask-correct__btn{font-size:12px;color:var(--muted);background:none;border:1px solid var(--line);
  border-radius:var(--radius-pill);padding:3px 12px;cursor:pointer;transition:all .2s var(--ease-out)}
.ask-correct__btn:hover{color:var(--brand);border-color:var(--brand)}
.ask-correct__form{margin-top:9px;display:flex;flex-direction:column;gap:8px}
.ask-correct__ta{width:100%;min-height:64px;resize:vertical;font:inherit;font-size:13px;line-height:1.6;
  padding:9px 12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--surface);color:var(--ink)}
.ask-correct__ta:focus{outline:none;border-color:var(--brand)}
.ask-correct__acts{display:flex;gap:8px;align-items:center}
.ask-correct__msg{margin:0;font-size:12.5px;color:var(--muted)}
.ask-correct__done{padding-top:8px}
.ask-correct__note{margin:0;font-size:13px;line-height:1.6;color:var(--brand)}

.ask-tip{margin:0 0 12px;padding:9px 13px;border-radius:var(--radius-sm);font-size:13px;
  background:rgba(200,144,26,.10);border:1px solid rgba(200,144,26,.30);color:#8a6412}

.ask-refs{margin-top:14px;padding-top:13px;border-top:1px dashed var(--line-2);
  display:flex;flex-direction:column;gap:7px}
.ask-refs__t{font-size:12.5px;color:var(--muted);margin-bottom:1px}
.ask-ref{display:flex;align-items:center;gap:11px;padding:10px 13px;font-size:14px;
  border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--surface-3);
  color:var(--ink);text-decoration:none;transition:all .25s var(--ease-out)}
.ask-ref:hover{border-color:var(--line-2);background:var(--surface-2);transform:translateX(2px)}
.ask-ref i{flex:none;font-style:normal;font-size:11.5px;color:var(--brand);
  background:var(--grad-soft);padding:2px 9px;border-radius:var(--radius-pill)}
.ask-ref b{flex:1 1 auto;min-width:0;font-weight:400;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.ask-ref > span{flex:none;color:var(--muted)}

/* ---- 输入区：常驻卡片底部，回答多长都不用返回上方 ---- */
.ask__composer{flex:none;padding:14px 26px 16px;border-top:1px solid var(--line);
  background:var(--surface)}
.ask__form{display:flex;align-items:center;gap:10px;padding:7px 7px 7px 18px;
  border:1px solid var(--line-2);border-radius:var(--radius-pill);background:var(--bg-3);
  transition:all .25s}
.ask__form:focus-within{border-color:var(--brand);box-shadow:0 0 0 3px rgba(43,107,255,.14)}
.ask__ico{display:inline-flex;flex:none;color:var(--muted)}
.ask__input{flex:1 1 auto;min-width:0;border:0;background:transparent;font:inherit;
  font-size:15px;color:var(--ink);height:38px;line-height:38px;padding:0}
.ask__input:focus{outline:0}
.ask__input::placeholder{color:var(--dim)}
.ask__send{flex:none;display:inline-flex;align-items:center;height:38px;border-radius:var(--radius-pill);padding-left:20px;padding-right:20px}

/* 免责声明：已移出对话卡片，作为卡片下方的独立说明块（仅下拉可见） */
.ask__foot{margin:24px 2px 0;font-size:12.5px;color:var(--muted);line-height:1.75;max-width:80ch}
.ask__disclaimer{margin:0}
.ask-note{padding:22px 26px;border-radius:var(--radius-sm);border:1px dashed var(--line-2);
  background:var(--surface);max-width:76ch}
.ask-note b{display:block;font-size:16px;margin-bottom:8px}
.ask-note p{margin:0;font-size:14px;color:var(--ink-2);line-height:1.8}

@media (max-width:720px){
  .ask{border-radius:var(--radius-sm)}
  .ask__stage{padding:0 10px 10px}
  .ask__composer{padding:11px 16px 13px}
  .ask-msg{font-size:14.5px;max-width:100%}
  .ask-msg--me{padding:7px 12px}
  .ask__form{padding:6px 6px 6px 14px}
  .ask__hello{padding:14px 4px 2px}
  .ask__hello-t{font-size:16px}
  .ask__chips{gap:6px}
  .chip--btn{font-size:13px}
}

/* =============================================================
   知识库 · 语雀形态（左侧目录树 + 右侧文档）
   -------------------------------------------------------------
   布局：.kbshell 两列栅格，侧栏 sticky 吸顶并独立滚动；
   目录树默认只展开「当前所在那一支」，用户手动展开的记在 localStorage。
   ============================================================= */
.kbshell{display:grid;grid-template-columns:270px 1fr;gap:28px;align-items:start;padding:22px 0 56px}
/* 目录页删掉了顶部 .phead 横幅 —— .phead 原本用 padding-top 让开 fixed 导航，
   这里必须补回来，否则树和文档会被顶栏压住 */
.kbshell--flush{padding-top:calc(var(--nav-h) + 18px)}
/* 搜索框不再独立成行，嵌进「本目录文档」标题行右端（.kbdochead 左右布局） */
/* 2026-10-20 二十批：KB 页原 .kbmain > .csearch 规则随搜索框一并退役 */
.kbdochead{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:14px}
.kbdochead .kbtitle{margin:0}
/* 2026-10-20 二十批：KB 标题行右侧的搜索框随搜索框一并退役 */
/* 有搜索词时「命中 N 条」独占一整行，落回列表上方 */
/* 2026-10-20 二十批：KB 标题行右侧的搜索框随搜索框一并退役 */
/* 正文页文档头：面包屑 + 标题 + 更新时间收在内容列顶部（原页级横幅已删） */
.kbdock{margin-bottom:20px}
.kbdock__title{margin:12px 0 0;font-size:var(--fs-max);font-weight:400;line-height:1.35;
  color:var(--ink);letter-spacing:-.01em}
.kbside{
  position:sticky;top:calc(var(--nav-h) + 14px);
  max-height:calc(100vh - var(--nav-h) - 36px);overflow:auto;
  border:1px solid var(--line);border-radius:16px;background:var(--surface);padding:10px;
}
.kbmain{min-width:0}
.kbsec{margin-bottom:30px}
.kbtitle{margin:0 0 14px;font-size:15px;font-weight:400;color:var(--ink);letter-spacing:-.01em}

/* 目录树 */
/* 移动端抽屉外壳（2026-10-27）：≤900px 时整棵树收进一个「目录」选项框，
   点开从底部升起成抽屉，一屏慢慢挑；桌面端这套外壳全部隐藏，树照常驻左侧栏。
   —— 之前手机上 .kbside 永远 order:-1 顶在最上面、还限高 320px 滚动，
   首屏被一大块目录树占满，正文要往下翻很远才看得到。 */
.kbtree__pick{display:none}
.kbtree__mask{display:none}
.kbtree__panelhead{display:none}
.kbtree__filter{margin-bottom:6px}
.kbtree__q{width:100%;height:32px;padding:0 10px;border-radius:9px;border:1px solid var(--line);
  background:var(--bg-3);color:var(--ink);font-size:12.5px;outline:none}
.kbtree__q:focus{border-color:var(--brand)}
.kbtree__empty{font-size:12.5px;color:var(--dim);padding:6px 4px}
.kbtree__row{display:flex;align-items:center;gap:1px;border-radius:8px;transition:background .18s}
.kbtree__row:hover{background:var(--surface-3)}
.kbtree__row.is-active{background:rgba(43,107,255,.10)}
.kbtree__row.is-active .kbtree__name{color:var(--brand);font-weight:400}
/* 展开标记：裸的加号（收起）/ 减号（展开），不画边框、不铺底色。
   2026-10-16：原来用 ▸ / ▾ 字符，只有 10px、细得像灰点，站长要求换成加减号并做大；
   随后又明确「加减号不要做边框」——所以只有两道杠，方块只是点击热区（24×24）。
   两道杠都用伪元素画，展开时竖杠 scaleY(0) 收掉 → 加号变减号是一条动画而非字符跳变。
   开关态只读 aria-expanded（服务端与 JS 都只维护这个属性），无 JS 时标记依然正确。 */
.kbtree__caret{flex:none;position:relative;width:24px;height:24px;margin-right:1px;padding:0;
  border:0;background:none;color:var(--ink-2);cursor:pointer;transition:color .18s}
.kbtree__caret::before,.kbtree__caret::after{content:"";position:absolute;left:50%;top:50%;
  border-radius:2px;background:currentColor;transform:translate(-50%,-50%)}
.kbtree__caret::before{width:14px;height:2px}
.kbtree__caret::after{width:2px;height:14px;
  transition:transform .22s var(--ease),opacity .22s var(--ease)}
.kbtree__caret[aria-expanded="true"]::after{transform:translate(-50%,-50%) scaleY(0);opacity:0}
.kbtree__caret:hover{color:var(--brand)}
.kbtree__caret[aria-expanded="true"]{color:var(--brand)}
.kbtree__caret:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:6px}
/* 叶子节点：同宽占位（保证层级对齐），只留一颗淡点做视觉锚，不画加减号。
   ⚠️ span 是 inline，宽高不生效，必须 inline-block，否则占位塌成 0 宽、层级缩进错位 */
.kbtree__caret--leaf{display:inline-block;cursor:default;width:24px;height:24px;margin-right:1px;
  background:none}
.kbtree__caret--leaf::before{width:4px;height:4px;border-radius:50%;background:var(--dim);opacity:.5}
.kbtree__caret--leaf::after{display:none}
/* 叶子的占位 span 不可点，别跟着行 hover 变色装作按钮 */
.kbtree__caret--leaf:hover{color:var(--dim)}
.kbtree__link{flex:1;min-width:0;display:flex;align-items:center;gap:8px;
  padding:5px 8px 5px 2px;color:var(--ink-2);font-size:13px;text-decoration:none}
.kbtree__link:hover{color:var(--ink)}
.kbtree__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kbtree__num{flex:none;margin-left:auto;font-size:11px;color:var(--dim)}
.kbtree__item.is-filtered{display:none}
.kbtree__item.is-hit>.kbtree__row .kbtree__name{color:var(--brand)}
/* 目录级权限：受限目录仍占位显示，但点了先进解锁页。
   锁图标只画在「自己被设了策略」的那一级；子孙用 is-inh（文字变淡）表示继承受限。 */
.kbtree__lock{flex:none;color:var(--dim);opacity:.75}
.kbtree__item.is-inh > .kbtree__row .kbtree__name{color:var(--muted)}
.kbtree__item.is-inh > .kbtree__row .kbtree__lock{display:none}

/* 目录卡片（首页按目录浏览 / 目录页子目录） */
.kbcat{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:10px}
.kbcat__c{display:flex;align-items:baseline;justify-content:space-between;gap:10px;padding:12px 14px;
  border:1px solid var(--line);border-radius:12px;background:var(--bg-3);text-decoration:none;
  transition:border-color .25s,transform .25s var(--ease-out),box-shadow .25s}
.kbcat__c:hover{border-color:var(--brand);transform:translateY(-2px);box-shadow:var(--shadow-soft)}
.kbcat__n{font-size:14px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kbcat__m{flex:none;font-size:12px;color:var(--dim)}
.kbcat__c.is-locked .kbcat__m{color:var(--muted)}
.kbcat__lk{flex:none;margin-left:5px;color:var(--dim);vertical-align:-1px}

/* 文档列表
   ⚠️ 2026-10-27 站长报「文章列表之间没有视觉分割」：
   原来 .kbdoc 只有 hover 时才显出边框和底色（border:1px solid transparent），
   静态看就是一坨连续文字，条目之间毫无边界。
   改成：常态就有一条细分隔线（用 --line，暗色下也看得见），
   悬停再叠一层浅底 + 整圈边框，形成「行 → 可点击行」的层次。 */
.kbdocs{display:flex;flex-direction:column;gap:0}
.kbdoc{display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  padding:12px 14px;border-radius:10px;text-decoration:none;
  border:1px solid transparent;border-bottom-color:var(--line);
  transition:background .2s,border-color .2s}
.kbdoc:last-child{border-bottom-color:transparent}
.kbdoc:hover{background:var(--surface);border-color:var(--line-2)}
.kbdoc__t{font-size:14.5px;color:var(--ink);font-weight:400}
.kbdoc__p{flex:none;max-width:38%;font-size:11.5px;color:var(--dim);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 2026-10-27：「最近更新」列表按最后修改时间排序，把日期显示出来才看得出顺序。
   日期 + 目录路径收进 .kbdoc__meta 一列，日期用等宽数字，视觉上不抢标题。 */
.kbdoc__meta{flex:none;display:flex;align-items:baseline;gap:10px;max-width:52%;
  min-width:0}
.kbdoc__time{flex:none;font-size:11.5px;color:var(--dim);font-variant-numeric:tabular-nums;
  letter-spacing:.02em}
.kbdoc__meta .kbdoc__p{max-width:100%}

/* 面包屑 / 正文元信息 */
.kbcrumbs{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:0 0 10px;font-size:12.5px;color:var(--muted)}
.kbcrumbs a{color:var(--muted);text-decoration:none}
.kbcrumbs a:hover{color:var(--brand)}
.kbcrumbs__sep{color:var(--line-3)}
.kbcrumbs__now{color:var(--ink)}
.kbmeta{margin:10px 0 0;font-size:12px;color:var(--dim)}
.kbask{margin:14px 0 0}
.kbmeta a{color:var(--brand);text-decoration:none}

/* 目录页 / 正文页的页头比栏目页矮一点，让正文早点露出来 */
.phead--kb{padding-top:calc(var(--nav-h) + 26px)}

/* ---- 目录级权限：解锁页 ---- */
.kblock{border:1px solid var(--line);border-radius:16px;background:var(--surface);padding:26px 26px 22px}
.kblock--lock{max-width:520px;margin:0 auto;text-align:left}
.kblock__lock{display:block;margin:0 0 14px;color:var(--brand)}
.kblock--lock .kbtitle{margin-bottom:8px;font-size:16px}
.kbhint{margin:0 0 18px;font-size:13.5px;line-height:1.75;color:var(--muted)}
.kberr{margin:0 0 14px;padding:9px 12px;border-radius:10px;font-size:13px;
  color:var(--danger,#c2410c);background:rgba(204,65,12,.08);border:1px solid rgba(204,65,12,.22)}
.kbunlock{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.kbunlock .inp{flex:1 1 160px;min-width:0}
.kbunlock__pwd{flex:1 1 220px}
.kbunlock .btn{flex:none}
.kbunlock__alt{margin:14px 0 0;font-size:12.5px;color:var(--dim)}
.kbunlock__alt a{color:var(--brand);text-decoration:none}


@media (max-width:900px){
  .kbshell{grid-template-columns:1fr;gap:16px}
  .kbside{position:static;max-height:none;order:-1}
  .kbdoc{flex-direction:column;gap:2px}
  .kbdoc__p{max-width:100%}
  /* 移动端条目竖排：日期与目录路径仍并排一行，别各占一行把列表撑高 */
  .kbdoc__meta{max-width:100%;gap:8px}

  /* 目录树收成「目录」选项框 + 底部抽屉（2026-10-27）
     原来这里是一整块常驻的目录树（order:-1 顶在最前 + 限高 320px 滚动），
     手机首屏大半被它吃掉，正文被挤到屏外。改成：只留一个选项框，
     点开才从底部升起抽屉，树的展开/过滤逻辑照旧在抽屉里跑。 */
  .kbside{border:0;background:none;padding:0}
  .kbtree{background:none;border:0;padding:0}

  .kbtree__pick{
    display:flex;align-items:center;gap:10px;width:100%;
    padding:11px 14px;border:1px solid var(--line);border-radius:12px;
    background:var(--surface);color:var(--ink-2);font-size:14px;text-align:left;
    transition:border-color .2s,background .2s;
  }
  .kbtree__pick:hover{border-color:var(--line-2)}
  .kbtree__pick-ico{flex:none;color:var(--brand)}
  .kbtree__pick-txt{flex:1;min-width:0;display:flex;align-items:baseline;gap:8px}
  .kbtree__pick-k{flex:none;font-size:12px;color:var(--dim)}
  .kbtree__pick-v{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink)}
  /* 箭头：CSS 画的两条边，展开时旋转 180° */
  .kbtree__pick-arrow{flex:none;width:8px;height:8px;margin-right:2px;
    border-right:1.5px solid var(--dim);border-bottom:1.5px solid var(--dim);
    transform:rotate(45deg) translateY(-2px);transition:transform .25s var(--ease)}
  .kbtree.is-open .kbtree__pick-arrow{transform:rotate(225deg) translateY(-2px)}

  /* 遮罩 */
  .kbtree__mask{display:block;position:fixed;inset:0;z-index:96;
    background:var(--overlay);opacity:0;visibility:hidden;transition:opacity .3s,visibility .3s}
  .kbtree.is-open .kbtree__mask{opacity:1;visibility:visible}

  /* 抽屉本体：从底部升起，最高 78vh，内部可独立滚动 */
  .kbtree__panel{
    display:flex;flex-direction:column;
    position:fixed;left:0;right:0;bottom:0;z-index:97;
    max-height:78vh;max-height:78dvh;
    background:var(--bg-3);border-top:1px solid var(--line);
    border-radius:18px 18px 0 0;box-shadow:0 -18px 50px -20px rgba(0,0,0,.45);
    transform:translateY(100%);visibility:hidden;
    transition:transform .32s var(--ease-out),visibility .32s;
    overscroll-behavior:contain;
  }
  .kbtree.is-open .kbtree__panel{transform:translateY(0);visibility:visible}
  /* 抽屉打开时给 main 解除层叠上下文（z-index:auto）。
     ⚠️ main{position:relative;z-index:3} 会创建层叠上下文，抽屉的 z-index:96/97
     被困在这个上下文里，实际排到全站根上下文 —— 而顶栏 nav 是根上下文的 z-index:60，
     于是遮罩被顶栏压住、点不到（2026-10-27 实测拦下 pointer event）。
     解除后抽屉与顶栏在同一层比较（97 > 60），遮罩才盖得住顶栏。 */
  body.is-kbdrawer main{z-index:auto}
  /* 管理员浮钮（z-index:9999）会浮在抽屉之上，挡内容 —— 抽屉开着时先藏起 */
  body.is-kbdrawer .fx-edit{display:none}
  .kbtree__panelhead{
    display:flex;align-items:center;justify-content:space-between;gap:12px;
    flex:none;padding:14px 16px 10px;border-bottom:1px solid var(--line);
  }
  .kbtree__paneltitle{font-size:14px;color:var(--ink)}
  .kbtree__panelclose{
    flex:none;width:30px;height:30px;display:grid;place-items:center;
    border:1px solid var(--line);border-radius:9px;color:var(--ink-2);
  }
  .kbtree__panelclose:hover{background:var(--surface-3);color:var(--ink)}
  .kbtree__panelbody{
    flex:1 1 auto;min-height:0;overflow:auto;-webkit-overflow-scrolling:touch;
    overscroll-behavior:contain;padding:10px 12px 20px;
  }
  /* 抽屉里树自己滚，别再叠一层限高 */
  .kbtree__list{max-height:none;overflow:visible}
}

/* =============================================================
   字号上限（放在文件最后以压过前面的定义）
   -------------------------------------------------------------
   业务规则：logo（.brand）是全站最大的「导航/品牌」字。
   做法：内容标题/指标用 --fs-cap 收口（默认 64px，与 logo 的 --fs-max 解耦，整改 #11），
   普通文字 min(--fs-cap, 原尺寸) 恢复真实层级；logo 仍由 --fs-max 约束。
   窄屏在断点里覆盖 --fs-max 以同步缩 logo（见下方 :root 覆盖）。
   ⚠️ 断点里覆盖必须写 :root{--fs-max:…}，不能写 html{--fs-max:…} ——
   变量定义在 :root（特异性 0,1,0）上，html（0,0,1）永远压不过它，那条会变死规则
   （2026-10-16 实测发现 ≤520 / ≤350 两档缩 logo 一直没生效：320~520 全档仍是 22px）。 */
.h-display{font-size:min(var(--fs-cap),clamp(20px,2.9vw,44px))}
.h1{font-size:min(var(--fs-cap),clamp(17px,2.05vw,28px))}
.h2{font-size:min(var(--fs-cap),clamp(23px,2.5vw,36px))}
.h3{font-size:min(var(--fs-cap),clamp(19px,1.8vw,24px))}

.hero__title{font-size:min(var(--fs-cap),clamp(20px,2.9vw,44px))}
.hero__grid--split .hero__title{font-size:min(var(--fs-cap),clamp(19px,2.4vw,40px))}
.hero__micro b{font-size:min(var(--fs-cap),22px)}
.phead h1{font-size:min(var(--fs-cap),clamp(16px,1.7vw,20px));font-weight:400}

.sector__copy h3{font-size:min(var(--fs-cap),clamp(20px,2.1vw,27px))}
.narr__step h3{font-size:min(var(--fs-cap),clamp(24px,2.6vw,38px))}
.metric b{font-size:min(var(--fs-cap),clamp(38px,4.4vw,62px))}
.orbit__core b{font-size:min(var(--fs-cap),34px)}
.device__body h3{font-size:min(var(--fs-cap),20px)}
.casecard h3{font-size:min(var(--fs-cap),21px)}
.notice__title{font-size:min(var(--fs-cap),clamp(21px,2.3vw,26px))}
.fmhead h1{font-size:min(var(--fs-cap),clamp(19px,2.1vw,28px))}

/* 文章列表行：不黑体、不加粗、字号明显小于 logo */
.stream__row h3{font-size:min(var(--fs-cap),16px);font-weight:400;letter-spacing:0}

/* =============================================================================
   排版总闸 —— 全站不使用加粗（2026-10-17 站长指令：「全站的所有文本都不要使用
   加粗，正常字体是怎样就怎样」）

   前面所有组件的 font-weight 已逐条改成 400；这条只做兜底，压两类漏网：
     · 浏览器给 h1~h6 / b / strong / th 的默认 bold(700) —— 没人写过规则也会粗；
     · 富文本编辑器存进正文的行内 style="font-weight:700" —— 只有 !important 盖得住。

   ⚠️ 用 * 通配是刻意的：各处分散写的话，伪元素图标、WYSIWYG 内容、第三方注入的
      行内样式会一次漏一个，历史上已经返工过两轮（这次一次性收死）。
   ⚠️ 图标字体是单字重设计，不受影响；字号不受此规则约束（本次只改字重）。
   ========================================================================== */
/* ==========================================================================
   产品独立单页（2026-10-18 十九批）
   源站产品页是「独立单页」：全宽渐变首屏 + 板块各自配色，与站点背景融成一片。
   文章模式（.article 白底容器）做不出这套视觉语言，所以产品/硬件页只要挂了
   区块就走这里（见 views/site/page.php 的 $articleBody 分流）。
   区块类型：product_hero / product_tabs / product_section
   ========================================================================== */
/* 图高总闸（2026-10-18 十九批补 3）：站长素材以 **16:9 横图** 为主。
   正确做法 = 固定高度、宽度按原始比例反推、卡片贴身包住（见 .psec__shot），
   这样 16:9 图就是 533×300 整块，不会出现「宽窗里竖图两边大片白边」。
   --pimg-h：板块图固定高（16:9 → 宽约 533px）
   --phero-h：首屏图上限，由 --pimg-h 派生（右栏主视觉，比配图大 40%）
   改图大小只改 --pimg-h 一处，首屏自动跟随。

   ── 全站页首顶距（2026-11-01 站长令统一：面包屑与下方内容的间距全站一个值）──
   --crumbs-top：面包屑横带距 fixed 顶栏底的距离（即 .breadcrumbs 的 top）
   --crumbs-h  ：面包屑横带自身高度（13px 字号 × 1.5 行高 ≈ 20px）
   --crumbs-gap：面包屑底 → 下方第一个内容元素的呼吸间距（全站唯一开关）
   --sp-head   ：页头顶距 = 顶栏高 + 面包屑上距 + 面包屑高 + 呼吸间距
   所有文章详情 / 单页 / 列表 / 计算器页的页头一律取 var(--sp-head)，
   不许各自写死 calc(var(--nav-h) + XXpx)，否则必然各页松紧不一。
   --sp-sec-y ：单页区块纵向节奏（区块上下 padding 统一 72px）
   要调全站页首松紧，只改 --crumbs-gap 一处。 */
:root{--pimg-h:min(34vh,300px);--phero-h:calc(var(--pimg-h) * 1.4);
  --crumbs-top:12px;--crumbs-h:20px;--crumbs-gap:34px;
  --sp-head:calc(var(--nav-h) + var(--crumbs-top) + var(--crumbs-h) + var(--crumbs-gap));
  --sp-sec-y:72px}
/* 移动端：面包屑同样悬浮，呼吸间距放大到 40px（等效顶距 ≈ nav-h + 72px）。
   ⚠️ 必须放在上面 :root 之后 —— 同为 :root 选择器、媒体查询不增加优先级，靠后者胜；
   放在前面会被上面的 --crumbs-gap 反压失效（此为 2026-10-31 已踩过的顺序坑）。 */
@media (max-width:720px){:root{--crumbs-gap:40px}}
.phero{position:relative;overflow:hidden;padding:var(--sp-head) 0 48px;
  background:linear-gradient(180deg,var(--surface-2) 0%,var(--bg) 100%)}
/* 2026-10-18 十九批补：光晕原本写死 rgba(2,123,255) 蓝色，切到国庆红/端午绿主题
   会「蓝斑突兀」；改用 color-mix 从 --brand/--brand-2 现算，任何主题自动跟随。 */
.phero__glow{position:absolute;left:-8%;right:-8%;top:-30%;height:78%;pointer-events:none;
  background:radial-gradient(58% 52% at 22% 34%,
               color-mix(in srgb,var(--brand) 16%,transparent),transparent 70%),
             radial-gradient(44% 44% at 82% 22%,
               color-mix(in srgb,var(--brand-2) 13%,transparent),transparent 70%)}
/* 顶对齐（2026-10-18 十九批补 4）：原来 center 会把左栏标题往下推一百多px
   （右图一高、左栏整体下沉，首屏看起来空）。源站是标题贴着页首走。 */
.phero__wrap{position:relative;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.92fr);
  gap:56px;align-items:start}
.phero__h{font-size:clamp(34px,4.4vw,62px);line-height:1.08;letter-spacing:-.02em;margin:0}
.phero__lead{margin:20px 0 0;font-size:17px;line-height:1.75;color:var(--dim);max-width:34em}
.phero__acts{display:flex;gap:14px;margin-top:34px;flex-wrap:wrap}
.phero__r{position:relative}
/* 首屏图：右栏宽图，宽度撑满、高度自动（16:9 在 560px 栏里约 315px 高），
   只在过高时才被 --phero-h 压住（contain 不裁切）。 */
.phero__img{width:100%;height:auto;border-radius:24px;box-shadow:var(--shadow-drop);
  display:block;max-height:var(--phero-h);object-fit:contain}
.phero__float{position:absolute;width:74px;height:74px;border-radius:18px;background:var(--surface);
  box-shadow:var(--shadow-soft);padding:12px}
.phero__float--1{left:-24px;top:14%}
.phero__float--2{right:-16px;bottom:12%}

/* 能力导航条：吸顶 + 滚动高亮（JS 见 product_tabs.php 内联） */
.ptabs{position:sticky;top:var(--nav-h);z-index:20;
  background:color-mix(in srgb,var(--bg) 88%,transparent);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line)}
.ptabs__cap{font-size:13px;color:var(--dim);padding-top:10px}
/* 2026-10-18 十九批补 2：站长令——不要胖按钮，纯文本 + 高亮下划线（同源站导航语汇）。
   高度只留一行文字，美观靠：选中变主题色 + 底部 2px 圆角短杠 + hover 变色。 */
.ptabs__row{display:flex;gap:30px;overflow-x:auto;padding:10px 0 0;scrollbar-width:none}
.ptabs__row::-webkit-scrollbar{display:none}
.ptab{position:relative;display:inline-flex;align-items:center;justify-content:center;
  padding:7px 2px 10px;color:var(--ink-2);text-decoration:none;transition:color .2s}
.ptab::after{content:"";position:absolute;left:50%;bottom:0;width:0;height:2px;
  border-radius:2px;background:var(--brand);transform:translateX(-50%);transition:width .22s}
.ptab:hover{color:var(--brand)}
.ptab.is-on{color:var(--brand);font-weight:400}
.ptab.is-on::after{width:100%}
.ptab__t{font-size:14px;white-space:nowrap}

/* 能力板块 */
.psec{padding:var(--sp-sec-y) 0;scroll-margin-top:calc(var(--nav-h) + 78px)}
.psec--tint{background:var(--surface-2)}
.psec__wrap{display:grid;grid-template-columns:minmax(0,.88fr) minmax(0,1.12fr);gap:56px;align-items:center}
/* 版式自动（2026-10-18 十九批补）：方图 → 左右分栏；横图 → 上下通栏。
   .psec--auto 是「还没量到比例」的暂存态：先单列、图组先隐身，
   JS 量完换成 --split / --stack 并加 .ps-auto-done 放行，用户看不到跳版。 */
.psec--auto .psec__wrap{grid-template-columns:1fr;gap:28px}
.psec--auto:not(.ps-auto-done) .psec__shots{opacity:0}
.psec--stack .psec__wrap{grid-template-columns:1fr;gap:30px;max-width:1080px;margin:0 auto}
.psec--stack .psec__copy{max-width:820px}
.psec--stack .psec__shots{flex-direction:column;width:100%}
/* 通栏图（2026-10-18 十九批补 4，站长令：处理掉多余白边，原图什么比例就什么比例）
   —— 宽度撑满卡片、高度按原始比例走，不再 max-height 限高（一限高 contain
   就在两边垫出白边）。卡也贴身。 */
.psec--stack .psec__shot{width:100%}
.psec--stack .psec__shot img{width:100%;height:auto;max-width:100%;display:block}
.psec__h{font-size:clamp(26px,2.6vw,38px);line-height:1.22;margin:0}
.psec__lead{margin:18px 0 0;font-size:16px;line-height:1.8;color:var(--dim)}
.psec__body{margin-top:16px;font-size:15.5px;line-height:1.8}
.psec__more{display:inline-flex;align-items:center;gap:8px;margin-top:24px;color:var(--brand);text-decoration:none}
/* 图组：flex 居中换行，卡片贴身包住图片（不放宽到格子，否则两边空一大截） */
.psec__shots{display:flex;flex-wrap:wrap;gap:16px;justify-content:center}
.psec__shot{flex:0 1 auto;margin:0;border-radius:18px;overflow:hidden;
  background:var(--surface);box-shadow:var(--shadow-card)}
.psec__shot img{display:block;height:var(--pimg-h);width:auto;max-width:100%;
  object-fit:contain;background:var(--surface)}
@media (max-width:900px){
  /* 窄屏单列，图片给矮一点，留出正文空间 */
  :root{--pimg-h:min(30vh,220px)}
  .phero__wrap{grid-template-columns:1fr;gap:34px}
  .phero__float{display:none}
  .psec{padding:56px 0}
  .psec__wrap{grid-template-columns:1fr;gap:28px}
}
/* 排版总闸（2026-10-17 站长指令「全站文本一律不加粗」）已于 2026-10-31 应站长要求取消：
   原先这里是一条 `*, *::before, *::after { font-weight: 400 !important; }`，
   它把全站字重强行压平为 400 —— 包括 b / strong / th 的浏览器默认粗体，
   以及各处显式写下的 500 / 600 / 700（写了也白写，所以历史上反复返工）。
   取消后：字重回归层叠规则 —— 各处显式声明照常生效，没写的地方沿用浏览器默认值。
   各组件里原本显式声明的 font-weight:400 不受影响（它们本来就是 400）。
   若要恢复全站禁粗，把下面这一行前面的 XX 去掉即可：
   XX *, *::before, *::after { font-weight: 400 !important; }
*/

/* =============================================================
   三十六批新增：三个「自助建站式」预设区块 + 就地编辑浮钮
   ============================================================= */
.sec-head--row{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;flex-wrap:wrap}

/* ---- 幻灯片 ---- */
.st-slider{position:relative;background:#0a0f1e}
.st-slider__stage{position:relative;height:clamp(380px,52vw,620px);overflow:hidden}
.st-slider__slide{position:absolute;inset:0;margin:0;opacity:0;transition:opacity .9s var(--ease, ease);pointer-events:none}
.st-slider__slide.is-on{opacity:1;pointer-events:auto}
.st-slider__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.st-slider__veil{position:absolute;inset:0;background:linear-gradient(180deg,rgba(6,10,20,.15),rgba(6,10,20,.72))}
.st-slider__cap{position:absolute;left:0;right:0;bottom:0;padding-bottom:clamp(30px,5vw,64px);display:grid;gap:10px;justify-items:start;color:#fff}
.st-slider__t{font-size:clamp(28px,4.4vw,58px);line-height:1.15;letter-spacing:-.01em}
.st-slider__s{font-size:clamp(15px,1.6vw,20px);opacity:.92}
.st-slider__d{font-size:clamp(13px,1.2vw,15.5px);opacity:.78;max-width:56ch}
.st-slider__btn{margin-top:6px}
.st-slider__nav{position:absolute;top:50%;transform:translateY(-50%);width:44px;height:44px;border:0;border-radius:50%;
  background:rgba(10,15,30,.4);color:#fff;font-size:24px;line-height:1;cursor:pointer;backdrop-filter:blur(4px);transition:background .25s}
.st-slider__nav:hover{background:rgba(10,15,30,.72)}
.st-slider__nav--prev{left:18px}
.st-slider__nav--next{right:18px}
.st-slider__dots{position:absolute;left:50%;transform:translateX(-50%);bottom:16px;display:flex;gap:8px}
.st-slider__dots button{width:9px;height:9px;padding:0;border:0;border-radius:50%;background:rgba(255,255,255,.42);cursor:pointer;transition:all .25s}
.st-slider__dots button.is-on{background:#fff;width:24px;border-radius:5px}

/* ---- 短视频 ---- */
.st-video__card{position:relative;display:block;width:min(920px,100%);margin:0 auto;border:0;padding:0;cursor:pointer;
  background:linear-gradient(135deg,#2b6bff,#7a4dff);border-radius:20px;overflow:hidden;aspect-ratio:16/9;
  box-shadow:0 24px 60px -28px rgba(43,107,255,.55)}
.st-video__card--tall{width:min(420px,100%);aspect-ratio:9/16}
.st-video__poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .6s var(--ease, ease)}
.st-video__card:hover .st-video__poster{transform:scale(1.04)}
.st-video__ph{position:absolute;inset:0;display:grid;place-items:center;color:rgba(255,255,255,.9);font-size:clamp(60px,10vw,120px)}
.st-video__play{position:absolute;inset:0;margin:auto;width:74px;height:74px;border-radius:50%;background:rgba(255,255,255,.92);
  display:grid;place-items:center;box-shadow:0 12px 34px -10px rgba(0,0,0,.5);transition:transform .3s var(--ease, ease)}
.st-video__card:hover .st-video__play{transform:scale(1.08)}
.st-video__play svg{width:34px;height:34px;fill:#1b2a4a;margin-left:4px}
.st-video__lb{position:fixed;inset:0;z-index:1000;background:rgba(5,8,16,.82);backdrop-filter:blur(6px);display:grid;place-items:center;padding:20px}
.st-video__lb[hidden]{display:none}
.st-video__lbin{position:relative;width:min(1080px,100%)}
.st-video__frame{width:100%;aspect-ratio:16/9;border:0;border-radius:14px;background:#000;display:block}
.st-video__card--tall ~ .st-video__lb .st-video__frame{aspect-ratio:9/16;width:min(420px,100%);margin-inline:auto}
.st-video__lbx{position:absolute;top:-44px;right:0;width:36px;height:36px;border:0;border-radius:50%;background:rgba(255,255,255,.16);color:#fff;font-size:15px;cursor:pointer}
.st-video__lbx:hover{background:rgba(255,255,255,.3)}

/* ---- 左右循环滑动 ---- */
.st-carousel__arrows{display:inline-flex;gap:8px}
.st-carousel__nav{width:40px;height:40px;border:1px solid var(--line-2,#ced6e6);border-radius:50%;background:var(--surface,#fff);
  color:var(--ink-2,#3d4a63);font-size:21px;line-height:1;cursor:pointer;transition:all .25s var(--ease, ease)}
.st-carousel__nav:hover{border-color:var(--blue,#2b6bff);color:var(--blue,#2b6bff);transform:translateY(-1px)}
.st-carousel__rail{display:flex;gap:16px;overflow-x:auto;scroll-snap-type:x mandatory;padding:4px 2px 14px;
  scrollbar-width:none;-ms-overflow-style:none}
.st-carousel__rail::-webkit-scrollbar{display:none}
.st-carousel__card{flex:0 0 min(300px,78vw);scroll-snap-align:start;display:grid;border:1px solid var(--line,#e5e9f2);
  border-radius:16px;overflow:hidden;background:var(--surface,#fff);text-decoration:none;color:inherit;
  transition:transform .3s var(--ease, ease),box-shadow .3s var(--ease, ease)}
.st-carousel__card:hover{transform:translateY(-4px);box-shadow:0 18px 40px -22px rgba(17,26,46,.4)}
.st-carousel__media{position:relative;display:block;aspect-ratio:16/10;background:linear-gradient(135deg,#eef2fb,#dfe7f7)}
.st-carousel__media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.st-carousel__ph{position:absolute;inset:0;display:grid;place-items:center;font-size:44px;color:#b6c2d9}
.st-carousel__body{display:grid;gap:4px;padding:14px 16px 16px}
.st-carousel__body b{font-size:15.5px}
.st-carousel__body em{font-style:normal;font-size:13px;color:var(--muted,#6b7891);line-height:1.55}

/* ---- 前台就地编辑浮钮（仅后台登录时注入，见 partials/blocks.php） ----
   .fx-zone 必须**生成盒子**才能成为 mouseenter 的命中目标：
   display:contents 不生成盒子，浏览器 hit-testing 命中的是子元素、事件路径不含
   .fx-zone，mouseenter 永远不触发。
   position:relative 不产生位移、不改变子元素的布局流。但仅此仍不够 ——
   区块内 .hero 等元素自带 z-index 会建立层叠上下文，把没有 z-index 的外壳
   压到子元素之下，mouseenter 依旧不触发（实测 over 有、enter 无）。
   isolation:isolate 让外壳自成一个层叠上下文，子元素的 z-index 再高也只在
   自己的上下文里排序，不会把外壳挤下去。 */
.fx-zone{position:relative;isolation:isolate}
/* 按钮本体：JS 在钉不到合法落点时会置 hidden，这里再用 [hidden] 兜一层，
   避免极端情况下（如 JS 未跑完）留下一个透明但吃点击的幽灵按钮 */
.fx-edit{position:fixed;z-index:9999;display:flex;align-items:center;gap:6px;padding:5px 12px;
  border:0;border-radius:999px;
  background:#111a2e;color:#fff;font-size:12.5px;line-height:1.4;cursor:pointer;
  box-shadow:0 10px 26px -10px rgba(17,26,46,.6);
  opacity:0;pointer-events:none;transition:opacity .18s}
.fx-edit[hidden]{display:none}
.fx-edit.is-on{opacity:1;pointer-events:auto}
.fx-edit:hover{background:#2b6bff}
.fx-zone.is-hot{outline:2px dashed rgba(43,107,255,.85);outline-offset:-2px}

/* ---- 三十八批续七 · 推荐区封面：视频形态 ---- */
.docshot--video{position:relative;width:100%;aspect-ratio:var(--reco-ratio,550/340);border-radius:14px;overflow:hidden;background:#0b1020}
.docshot__vid{position:absolute;inset:0;width:100%;height:100%;border:0;display:block;object-fit:cover}
