/* ============================================================
   AI中枢 NovaHub · 设计系统 base.css
   移动端优先 · 强手机适配 · 蓝紫渐变科技风
   ============================================================ */

:root{
  --primary:#4F5DFF;         /* 主蓝（v1.70.7 对齐交互原型 #4F5DFF） */
  --primary-2:#7C4DFF;       /* 主蓝渐变副色（蓝→紫） */
  --primary-deep:#2A3EB1;
  --violet:#7C4DFF;          /* 紫 */
  --cyan:#00B4FF;
  --grad-main:linear-gradient(135deg,#4F5DFF 0%,#8B5CF6 100%);
  --grad-hero:linear-gradient(180deg,#EEF1FF 0%,#F7F8FF 40%,#FFFFFF 100%);
  --grad-text:linear-gradient(90deg,#4F5DFF,#8B5CF6 55%,#00B4FF);
  --grad-card:linear-gradient(150deg,#4F5DFF 0%,#8B5CF6 100%);
  --bg:#F6F7FB; --bg-soft:#EEF1FA; --card:#FFFFFF;
  --ink:#16192B; --ink-2:#4A4F6A; --ink-3:#8A90AB; --line:#E7EAF6;
  --ok:#0FB37B; --warn:#F59E0B; --err:#EF4444; --info:#4F5DFF;
  /* ============================================================
     v1.65.0 设计令牌补全：修复「引用了从未定义的变量」导致样式静默失效。
     经全站扫描（93 个已定义 / 96 个被引用），确认以下 23 个变量被使用但未定义，
     其中 8 个是**无回退值**的裸引用（真正失效），其余 15 个虽写了回退值，
     但统一在此定义可让主题调色更收敛、也便于将来做整体换肤。
     ⚠ 本节只做「新增定义」，不改动任何既有选择器 —— 回滚风险为零。
     ============================================================ */
  /* 1) --ink-1：全站 30 处引用，此前只在 admin.css 的 .adm-wrap 作用域内定义，
        前台页面全部取不到值。补为比 --ink 更深一档的「标题墨色」。 */
  --ink-1:#0E1120;
  /* 2) 语义别名组：前台误用后台专属命名（--text-*/--border/--bg-2 等）时兜底 */
  --text-1:var(--ink);       --text-2:var(--ink-2);     --text-3:var(--ink-3);
  --border:var(--line);      --border-2:var(--line);
  --bg-2:var(--bg-soft);     --bg-3:#E9EDF9;
  --bg-card:var(--card);     --bg-input:#FFFFFF;
  /* 3) 品牌色别名与浅色档（pills / 标签底色 / 分组标号） */
  --brand:var(--primary);
  --primary-soft:rgba(79,93,255,.10);
  --primary-50:#EEF2FF;
  --case-c:var(--primary);
  /* 4) 状态色别名（与 --err/--ok/--warn 同值，兼容旧写法） */
  --danger:var(--err);       --red:var(--err);
  --orange:var(--warn);      --green:var(--ok);
  /* 5) 阴影/时长别名（--shadow-lg ≡ --shadow-l；--dur 缺省等同 --dur-mid） */
  --shadow-lg:var(--shadow-l);
  --dur:var(--dur-mid);
  /* 6) 动态视口高（chat 全屏输入区用；旧浏览器无 --vvh 时由 fallback 兜底） */
  --vvh:100vh;
  /* v1.65.0 hero 主标题字号：此前各业务页 42/30/28px 三口径并存，现统一为一档 */
  --fs-hero:clamp(28px,5vw,42px);
  --shadow-s:0 2px 8px rgba(35,46,143,.06);
  --shadow-m:0 8px 24px rgba(35,46,143,.10);
  --shadow-l:0 16px 48px rgba(35,46,143,.16);
  /* v1.45.60 发光 token：主按钮/强调元素的品牌微光，替代散落的 30+ 种手写高饱和阴影 */
  --glow-s:0 4px 12px rgba(80,70,255,.16);
  --glow-m:0 8px 20px rgba(80,70,255,.22);
  --glow-l:0 12px 28px rgba(80,70,255,.28);
  /* 圆角语义档位：--r-s 小元素（标签/图标容器/输入框） · --r-m 卡片容器（默认）
     · --r-l 面板/弹窗（.card/.modal 已接入） · --r-xl 大区域。全站卡片容器统一 --r-m。 */
  --r-s:10px; --r-m:14px; --r-l:20px; --r-xl:28px;
  /* v1.45.59 间距 token：4px 递进制，全站 gap/padding 统一以此为基准，
     消除此前 2~44px 的碎片化（5/6/7/9/11px 等中间值一律就近收敛）。 */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:24px; --sp-6:32px;
  /* v1.45.86 修复：动效 token 此前自引用（var(--dur-fast) 指向自身）导致无效，全站 transition 失效。
     现改为真实时长基准（快/中/慢三档），并补齐此前缺失的 --ease 缓动曲线。 */
  --dur-fast:.15s; --dur-mid:.22s; --dur-slow:.32s;
  --ease:cubic-bezier(.22,1,.3,1);
  /* v1.45.61 字号 token：常用文字档位基准（rem，基于 16px 根字号） */
  --fs-xs:.72rem; --fs-sm:.8rem; --fs-md:.9rem; --fs-lg:1rem; --fs-xl:1.15rem;
  /* v1.45.86 响应式断点规范（移动端优先，全站统一三档）：
     ① <=900px 平板/窄桌面　② <=640px 手机　③ <=480px 小屏。
     新增媒体查询请收敛到这三档，避免 520/560/760/860 等碎片断点。 */
  --bp-tablet:900px; --bp-mobile:640px; --bp-mini:480px;
  --nav-h:64px;
  --font:-apple-system,BlinkMacSystemFont,"PingFang SC","HarmonyOS Sans SC","MiSans","Noto Sans SC","Microsoft YaHei",sans-serif;
  --mono:"SF Mono","JetBrains Mono",Consolas,monospace;
}

*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
html{font-size:16px;scroll-behavior:smooth}
@media(max-width:480px){html{font-size:15px}}
body{font-family:var(--font);color:var(--ink);background:var(--bg);line-height:1.6;
  -webkit-font-smoothing:antialiased;overflow-x:hidden}
a{color:inherit;text-decoration:none}
img,svg{display:block;max-width:100%}
/* v1.70.3 统一线性图标兜底：icon()（JS）/ nh_icon()（PHP）生成的 svg 统一携带 .icg 标记类。
   当图标落进没有任何尺寸规则的容器（p/span/h4/告警条/表格单元格…）时，
   此前会按 SVG 默认尺寸（约 300×150 或撑满容器宽）渲染成「巨型图标」。
   现兜底为 1em：随所在文字缩放、随基线对齐，行为与图标字体一致。
   用 :where() 把特异性压到 0 —— 任何 .xxx svg 级别的既有规则（.btn svg /
   .kpi i svg / .empty svg…）与手写 svg（自带 width 属性）都不受影响。 */
svg:where(.icg){width:1em;height:1em;display:inline-block;vertical-align:-.125em;flex:none}
button{font-family:inherit;cursor:pointer;border:none;background:none}
input,textarea,select{font-family:inherit;font-size:inherit;color:inherit;outline:none}
ul,ol{list-style:none}
::selection{background:rgba(79,93,255,.18)}
:focus-visible{outline:2px solid var(--primary);outline-offset:2px;border-radius:6px}
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-thumb{background:#C9CFE8;border-radius:8px}
::-webkit-scrollbar-thumb:hover{background:#AAB4D8}
::-webkit-scrollbar-track{background:transparent}
*{scrollbar-width:thin;scrollbar-color:#C9CFE8 transparent}
.grad-text{background:var(--grad-text);-webkit-background-clip:text;background-clip:text;color:transparent}

/* ---------- 容器 ---------- */
.container{width:100%;max-width:min(100%,1600px);margin:0 auto;padding:0 24px}
@media(max-width:900px){.container{padding:0 20px}}
@media(max-width:768px){.container{padding:0 16px}}

/* ---------- 顶部导航 ---------- */
.nav{position:fixed;top:0;left:0;right:0;z-index:900;height:var(--nav-h);
  display:flex;align-items:center;background:rgba(255,255,255,.82);
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  border-bottom:1px solid rgba(231,234,246,.8);transition:box-shadow var(--dur-slow)}
.nav.scrolled{box-shadow:var(--shadow-s)}
/* ⚠ 手机端必须摘掉 .nav 的 backdrop-filter：
   带 filter/backdrop-filter 的元素会成为 position:fixed 后代的「包含块」，
   抽屉（.nav-links）就会以 390×64 的导航条为参照，inset:0 算不出满屏高度。
   摘掉后抽屉恢复以视口为参照（导航条本身改为不透明底，视觉等价）。 */
@media(max-width:900px){
  .nav{background:#fff;backdrop-filter:none;-webkit-backdrop-filter:none}
}
/* ⚠ 给 .nav-inner 抬层级：抽屉（z-index:1）在 .nav 内，遮罩在 body 上（z-index:0 但
   在更高层叠上下文），不给 .nav-inner 更高层级的话，抽屉会压住品牌区与汉堡按钮。 */
.nav-inner{width:100%;max-width:min(100%,1440px);margin:0 auto;padding:0 24px;
  display:flex;align-items:center;gap:20px;position:relative;z-index:2}
.brand{display:flex;align-items:center;gap:10px;font-weight:800;font-size:1.15rem;letter-spacing:.5px;flex-shrink:0}
.brand .logo{width:34px;height:34px;border-radius:10px;background:var(--grad-main);
  display:flex;align-items:center;justify-content:center;box-shadow:var(--glow-s)}
.brand .logo svg{width:20px;height:20px}
.brand small{font-weight:600;color:var(--ink-3);font-size:.74rem;display:block;letter-spacing:1px}
.nav-links{display:flex;gap:6px;margin-left:12px;flex:1;min-width:0;overflow:hidden}
.nav-links a{padding:8px 12px;border-radius:10px;font-size:.93rem;color:var(--ink-2);
  font-weight:500;transition:var(--dur-mid);white-space:nowrap;flex-shrink:1}
@media(max-width:1440px){.nav-links a{padding:8px 9px;font-size:.88rem}}
.nav-links a:hover{color:var(--primary);background:rgba(79,93,255,.07)}
.nav-links a.active{color:var(--primary);background:rgba(79,93,255,.1);font-weight:700}
/* 核心入口（场景中心 / AI 工具箱）：九个同级菜单里，这两个是产品主菜。
   不靠"加粗变色"抢戏（那会盖过当前页高亮），只加
   ① 一个 4px 的主色圆点（非激活态也常亮，作为"这是重点"的轻提示）
   ② 略微加深的字色。
   激活态仍走 .active 的底色，圆点保留 —— 两套信号不冲突。 */
.nav-links a.nav-core{color:var(--ink);font-weight:600}
.nav-links a.nav-core .nl-tx{position:relative}
.nav-links a.nav-core .nl-tx::after{
  content:'';position:absolute;right:-9px;top:3px;width:4px;height:4px;border-radius:50%;
  background:var(--grad-main);opacity:.9;
}
/* v1.71.54 一级直链核心标记（视觉工坊）：比下拉内更醒目 ——
   加粗 + 主色描边微底 + 6px 带微光圆点，一眼从「首页/AI对话」里认出「视觉工坊」。
   v1.71.92 直链包进 .nl-top 子网格，子选择器同步改写（.nl-top 桌面端 display:contents 无感）。 */
.nl-top{display:contents}
.nl-top > a.nav-core{font-weight:700;color:var(--ink);border:1px solid rgba(79,93,255,.24);
  background:rgba(79,93,255,.05)}
.nl-top > a.nav-core .nl-tx::after{
  width:6px;height:6px;top:2px;right:-10px;
  box-shadow:0 0 6px rgba(79,93,255,.85),0 0 12px rgba(139,92,246,.5);
}
.nl-top > a.nav-core:hover{background:rgba(79,93,255,.12);border-color:rgba(79,93,255,.45)}
.nl-top > a.nav-core.active{background:var(--grad-main);color:#fff;border-color:transparent;font-weight:700}
.nl-top > a.nav-core.active .nl-tx::after{background:#fff;box-shadow:0 0 6px rgba(255,255,255,.9)}
/* v1.35.0 导航分组化：
   · .nav-sep 桌面端是组间竖分隔符（1px 淡线），移动端隐藏
   · .nav-grp-tx 组标题仅在移动端抽屉显示（横跨两列的小灰字）
   · .nav-service「AI 服务超市」增值入口：桌面端加主色描边胶囊感，一眼识别「找我们做」 */
.nav-sep{width:1px;height:18px;background:var(--line);flex:0 0 auto;align-self:center;margin:0 4px}
.nav-grp-tx{display:none}
.nav-links a.nav-service{color:var(--primary);border:1px solid rgba(79,93,255,.28);background:rgba(79,93,255,.05);font-weight:650}
.nav-links a.nav-service:hover{background:rgba(79,93,255,.12)}
.nav-links a.nav-service.active{background:var(--grad-main);color:#fff;border-color:transparent}
.nav-act{display:flex;align-items:center;gap:10px;flex-shrink:0;margin-left:auto}

/* ---------- 桌面端分组下拉菜单（v1.42.1） ---------- */
/* v1.43.2 关键修复：桌面端 .nav-links 摘掉 overflow:hidden。
   它原本高度只有导航条的 38px，会把 absolute 定位的下拉面板（在按钮下方 200px+）
   整个裁掉——用户点分组按钮时状态变了、面板却永远看不见（v1.42.1 起就存在）。
   移动端（≤900px）不受影响：抽屉模式有自己的覆盖规则。 */
@media(min-width:901px){
  .nav-links{overflow:visible}
}
/* 中窄桌面（901~1080px）空间收紧：避免摘掉裁剪后菜单压到右侧按钮区 */
@media(min-width:901px) and (max-width:1080px){
  .nav-inner{gap:12px;padding:0 16px}
  .brand small{display:none}
  .nav-links{gap:2px;margin-left:6px}
  .nav-act{gap:8px}
}
.nav-drop{position:relative;flex-shrink:0}
.nav-drop-btn{display:flex;align-items:center;gap:5px;padding:8px 12px;border-radius:10px;
  font-size:.93rem;font-weight:600;color:var(--ink-2);transition:var(--dur-mid);white-space:nowrap;cursor:pointer}
.nav-drop-btn:hover{color:var(--primary);background:rgba(79,93,255,.07)}
.nav-drop.on .nav-drop-btn{color:var(--primary);background:rgba(79,93,255,.09)}
.nd-caret{width:14px;height:14px;color:var(--ink-3);transition:transform .22s var(--ease);flex-shrink:0}
.nav-drop.open .nd-caret{transform:rotate(180deg)}
.nav-drop-panel{position:absolute;top:calc(100% + 8px);left:50%;transform:translateX(-50%) translateY(-6px);
  min-width:180px;background:#fff;border:1px solid var(--line);border-radius:14px;
  box-shadow:var(--shadow-l);padding:6px;opacity:0;pointer-events:none;visibility:hidden;
  transition:var(--dur-mid) var(--ease);z-index:940}
.nav-drop.open .nav-drop-panel{opacity:1;pointer-events:auto;visibility:visible;transform:translateX(-50%) translateY(0)}
/* 二级菜单项：横向图标+文字（区别于移动端抽屉的纵向卡片） */
.nav-drop-panel .nl-sub{display:flex;align-items:center;gap:10px;padding:9px 12px;border-radius:10px;
  font-size:.88rem;font-weight:550;color:var(--ink-2);white-space:nowrap;transition:var(--dur-fast)}
.nav-drop-panel .nl-sub:hover{background:var(--bg-soft);color:var(--ink)}
.nav-drop-panel .nl-sub.active{color:var(--primary);background:rgba(79,93,255,.09);font-weight:700}
.nav-drop-panel .nl-ic{width:18px;height:18px;display:grid;place-items:center;color:var(--primary);flex-shrink:0}
.nav-drop-panel .nl-ic svg{width:17px;height:17px}
/* 二级项的核心标识圆点复用 .nav-core 的 ::after，此处给足间距 */
.nav-drop-panel .nav-core .nl-tx{position:relative}
.nav-drop-panel .nav-core .nl-tx::after{content:'';position:absolute;right:-9px;top:3px;width:4px;height:4px;
  border-radius:50%;background:var(--grad-main);opacity:.9}

/* ---------- 手机端：右上角浮层菜单（两列网格 · 超紧凑） ----------
   演进：整屏下拉 → 右侧半屏抽屉 → 右上角两列小浮层。
   8 个菜单项若竖排，面板高度必然 330px+，挡内容；改为 2 列 × 4 行后高度减半。
   宽度用「固定 232px，窄屏降为 100% 内缩」而非百分比：
   百分比会让面板在不同机型上忽宽忽窄（242/223/198px），视觉不稳定，
   且小屏上过窄会挤压两列文字。 */
.nav-mask{display:none}
@media(max-width:900px){
  .nav-mask{
    display:block;position:fixed;inset:0;z-index:890;background:rgba(18,22,45,.34);
    backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);
    opacity:0;pointer-events:none;transition:opacity .28s var(--ease);
  }
  .nav-mask.show{opacity:1;pointer-events:auto}
  .nav-links{
    position:fixed;top:calc(var(--nav-h) + 4px);right:6px;left:auto;bottom:auto;
    /* v1.70.0 232 → 250px：两列各 115px。实测 232px 时单项横向可点区仅 108px，
       且文字与左右边缘几乎贴死（padding 只有 4px），因此加宽容器 + 加大内边距。 */
    width:250px;max-width:calc(100vw - 12px);
    max-height:calc(80vh - var(--nav-h));max-height:calc(80dvh - var(--nav-h));
    /* v1.70.14 收紧行距：格子透明底时相邻格的内边距会与 gap 叠成大空白带，
       gap 5→3px、容器 padding 6→5px，配合单项 min-height 52→42px 一并收紧 */
    display:grid;grid-template-columns:1fr 1fr;gap:3px;margin:0;
    background:#fff;border:1px solid var(--line);border-radius:14px;
    padding:5px;
    box-shadow:var(--shadow-l);
    transform:translateY(-6px) scale(.96);transform-origin:top right;
    /* ⚠ 收起态必须同时具备「三件套」，缺一不可：
       opacity:0  只解决「看不见」，元素依然参与命中测试；
       pointer-events:none 才是真正让它点不到的关键；
       visibility:hidden 兜底（部分浏览器/辅助技术会忽略透明元素上的指针事件规则）。
       历史 bug：早期只写了 opacity:0，导致菜单收起后那块 232×239 的区域仍然
       拦截点击 —— 用户点首页 hero 上的空白处会被带到 /scene、/docs 等页面
       （实测 8 个菜单项里 7 个可点，其中「首页」因为 href="/" 与当前页相同
       看不出跳转，最具迷惑性）。 */
    opacity:0;pointer-events:none;visibility:hidden;
    z-index:1;overflow-y:auto;overscroll-behavior:contain;
    transition:transform .24s var(--ease),opacity .18s var(--ease),visibility 0s linear .24s;
  }
  /* 展开态：覆盖上一行的 visibility 延迟，保证立刻可交互 */
  .nav-links.open{
    transform:translateY(0) scale(1);opacity:1;pointer-events:auto;visibility:visible;
    transition:transform .24s var(--ease),opacity .18s var(--ease),visibility 0s;
  }
  /* v1.71.92 手机端抽屉整齐化：
     · .nl-top 顶级直链（首页/对话/工坊 3 项）独立 3 列子网格整行排列，
       消除「2 列网格 2+1 断裂、第 3 项半行右空」；
     · .nl-span2 奇数项分组的末项横跨整行（JS 渲染时按组内项数奇偶打标）。 */
  .nl-top{display:grid;grid-column:1 / -1;grid-template-columns:repeat(3,1fr);gap:3px}
  .nav-links a.nl-span2{grid-column:1 / -1;flex-direction:row;gap:8px;min-height:40px}
  /* 两列网格：图标在上、文字在下，纵向排列让窄格子也能放长词 */
  .nav-links a{
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
    /* v1.70.14 行距收紧：格子平时透明，上下 padding 会叠加成视觉空白带，
       min-height 52→42px、纵向 padding 9→5px（横向保留 9px 呼吸不挤字） */
    padding:5px 9px;min-height:42px;
    font-size:.75rem;font-weight:650;line-height:1.15;border-radius:10px;color:var(--ink-2);
    transition:.16s;text-align:center;white-space:nowrap;
  }
  .nav-links a:hover{background:rgba(79,93,255,.07);color:var(--primary)}
  .nav-links a.active{background:var(--grad-main);color:#fff;box-shadow:var(--glow-m)}
  .nav-links a.active .nl-ic{color:#fff}
  /* 图标已在上方，底座收敛为纯图标（省空间，格子更透气） */
  .nl-ic{width:19px;height:19px;flex:0 0 auto;display:grid;place-items:center;background:none;color:inherit}
  .nl-ic svg{width:17px;height:17px}
  .nav-links a:not(.active) .nl-ic{color:var(--primary)}
  .nl-tx{max-width:100%;overflow:hidden;text-overflow:ellipsis}
  .nl-ar{display:none}
  /* v1.35.0 移动端：组标题横跨两列、组间分隔符隐藏 */
  .nav-sep{display:none}
  /* v1.42.1 移动端：分组下拉展平 —— .nav-drop 与 .nav-drop-panel 用 display:contents
     让二级项 .nl-sub 直接参与抽屉两列网格；分组按钮 .nav-drop-btn 变为横跨两列的组标题 */
  .nav-drop{display:contents}
  /* v1.45.33 修复登录/全站「输入框误触跳转」+ v1.45.33b 修复菜单项隐形：
     .nav-drop-panel 在移动端用 display:contents 展平进抽屉两列网格。
     ⚠ 注意：桌面端基础规则（本文件上方 .nav-drop-panel）显式写了
     opacity:0 / pointer-events:none / visibility:hidden，它同样命中移动端；
     display:contents 只是让面板自身不生成盒，「继承」照常发生 ——
     visibility / pointer-events 都是可继承属性，二级项 .nl-sub 会把
     hidden / none 一并继承过去：菜单项集体隐形且点不到（v1.45.33 首发版
     只写了 display:contents 就踩了这个坑，手机抽屉分组下全空白）。
     因此这里必须显式翻回 visibility:visible / opacity:1；
     而 pointer-events 用 inherit 而不是 auto：
     · auto（旧版写法）→ 收起态也 force 可点，透明浮层拦截登录输入框点击（误触 bug）；
     · inherit → 跟随抽屉状态：收起 none（不拦截点击）✓ / 展开 auto（菜单可点）✓。 */
  .nav-drop-panel{display:contents;position:static;transform:none;visibility:visible;opacity:1;pointer-events:inherit}
  .nav-drop-btn{
    display:block;grid-column:1 / -1;font-size:.66rem;font-weight:700;letter-spacing:1px;
    color:var(--ink-3);padding:4px 8px 1px;margin-top:2px;text-transform:uppercase;
    text-align:left;border-radius:0;cursor:default;pointer-events:none;
  }
  .nav-drop-btn:hover{color:var(--ink-3);background:none}
  .nav-drop.on .nav-drop-btn{color:var(--ink-3);background:none}
  .nav-drop-btn .nd-caret{display:none}
  .nav-drop-panel .nl-sub{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;
    padding:5px 9px;min-height:42px;font-size:.75rem;font-weight:650;line-height:1.15;border-radius:10px;
    color:var(--ink-2);white-space:nowrap;transition:.16s}
  .nav-drop-panel .nl-sub .nl-ic{width:19px;height:19px;color:var(--primary)}
  .nav-drop-panel .nl-sub .nl-ic svg{width:17px;height:17px}
  .nav-drop-panel .nl-sub.active{background:var(--grad-main);color:#fff;font-weight:650}
  .nav-drop-panel .nl-sub.active .nl-ic{color:#fff}
  .nav-drop-panel .nav-core .nl-tx::after{display:none}
  .nav-grp-tx{
    display:block;grid-column:1 / -1;font-size:.66rem;font-weight:700;letter-spacing:1px;
    color:var(--ink-3);padding:4px 8px 1px;margin-top:2px;text-transform:uppercase;
  }
  .nav-grp-tx:first-child{margin-top:0}
  .nav-links a.nav-service{border:none;background:none}
  .nav-links a.nav-service.active{background:var(--grad-main);color:#fff}
  /* ===== v1.70.0 消除「孤立半格」 =====
     问题：`.nav-drop-panel{display:contents}` 展平后，各组二级项直接参与 .nav-links 的两列网格。
     实测 390px 下有两处「左列孤零零一格、右侧整片留白」：
       · 产品能力组 7 项（奇数）→ 末行只剩「Ads」占左半格，右边 118px 空白；
       · 增值服务组 3 项（奇数）→ 末行只剩「Idle Fish」占左半格，右边 118px 空白。
     这正是用户反馈的「底部菜单太过于紧凑、左右空余站位」。

     ⚠ 选择器语义（实测踩坑记录，勿凭直觉改）：
     nth-child 的计数范围是**父元素，不是整个网格**。组标题 .nav-drop-btn 与同组的
     .nl-sub 都要在 .nav-drop-panel 内部编号，所以组内第 k 项的序号就是 k：
       · 7 项组末项 → nth-child(7) → odd；3 项组末项 → nth-child(3) → odd；
       · 4 项组末项 → nth-child(4) → even（且它是右列，本就不需要处理）。
     即 `:last-child:nth-child(odd)` 才精确命中「奇数项组的末项」。
     （首版误按「组标题占 1 个序号」推导成 even，实测 last0/last1 全部不命中，
       唯独 4 项组的 Help 被误判命中横跨整行 —— 已按实测修正为 odd。） */
  .nav-drop-panel .nl-sub:last-child:nth-child(odd){
    grid-column:1 / -1;flex-direction:row;gap:9px;justify-content:center;
  }
  /* 手机端：头像组靠左、☰ 在最后贴右缘 */
  .nav-burger{display:flex!important;order:2}
  .nav-act{margin-left:auto;order:1}
  .nav-inner{gap:12px}
  /* 抽屉打开时锁定背景滚动 */
  body.nav-lock{overflow:hidden}

  /* ===== v1.70.0 头像菜单移动端网格化 =====
     问题：移动端 .user-menu-panel 只是从 260px 单列变成「全宽 fixed」，9 个 .ump-item
     依旧一列竖排 —— 实测 390×844 下面板高 455px，占掉 54% 屏幕高度，要滑很久才到底。

     方案：只把 .ump-body 改为网格（⚠ 不能给 .user-menu-panel 设 grid ——
     head / body / foot 是三个兄弟块，设成 grid 会让它们各占一格而错位）。
     每格「图标在上、文字在下」，箭头隐藏。

     为什么选 2 列而不是 3 列（实测对比）：
       .ump-body 实际项数 = 8（管理员含「管理后台」）或 7（普通用户）。
       · 3 列 → 管理员 3+3+2，末行右侧又空一格（与 nav 的孤立格是同一类问题），
              且单格 115px 宽、标题"API 密钥"换行，panel 实测高 338px；
       · 2 列 → 管理员 4 行、普通用户 3 行 + 1 满行，**无孤立格**，
              单格约 143px 宽足够容纳最长文案，panel 实测高约 305px。
       2 列在「高度、无孤立格、文字不换行」三项上全面优于 3 列。

     桌面端（≥901px）保持原 260px 单列，不受影响。 */
  .user-menu-panel{position:fixed;top:calc(var(--nav-h) + 4px);right:6px;left:auto;
    width:min(304px,calc(100vw - 12px));max-width:none;padding:9px;border-radius:16px}
  .ump-head{padding:9px 9px 11px;margin-bottom:5px}
  .ump-body{display:grid;grid-template-columns:1fr 1fr;gap:5px;padding:0}
  /* 每格：图标 + 文案横向排列，最小高度 38px（比原竖排 62px 矮，4 行也不显臃肿） */
  .ump-item{flex-direction:row;gap:8px;padding:8px 10px;min-height:38px;
    justify-content:flex-start;text-align:left;font-size:.8rem;font-weight:650;line-height:1.2;
    position:relative}
  /* 组内项数为奇数时末项横跨整行，消除「孤立半格」（与 nav 同一手法）。
     nth-child 在父元素（.ump-body）内计数，8 项 → 末项序号 8 → even，
     故这里用 odd 时需排除；-8 项的末项本身在右列，无需跨行，而 7 项（普通用户）
     末项在左列 → 用 :nth-child(odd) 命中。 */
  .ump-body .ump-item:last-child:nth-child(odd){grid-column:1 / -1;justify-content:center}
  /* 网格里左右箭头无意义，隐藏后文字能占满格子宽度 */
  .ump-ar{display:none}
  /* 角标必须绝对定位，否则会作为 flex 子项把格子撑高、挤歪图标与文字 */
  .ump-notif-badge{position:absolute;top:5px;right:7px;min-width:16px;height:16px;padding:0 4px;font-size:.62rem}
  /* 底部「退出登录」保持横向一行，与上方网格区分开 */
  .ump-foot .ump-item{flex-direction:row;min-height:auto;justify-content:center;font-size:.82rem;padding:10px;grid-column:auto}
  .ump-foot .ump-item:last-child:nth-child(odd){grid-column:auto}
}
/* 极窄屏（≤350px）：250px 固定宽会显得偏满，降到 226px 保持「小浮层」观感 */
@media(max-width:350px){
  .nav-links{width:226px}
}
/* 桌面端：同一套 DOM 不显示图标/箭头（隐藏后菜单项宽度与旧版一致，零回归）
   —— 但二级下拉面板里的图标保留（v1.42.1 分组菜单需要图标辅助识别） */
@media(min-width:901px){
  .nav-links a .nl-ic,.nav-links a .nl-ar{display:none}
  .nav-links a .nl-tx{flex:0 0 auto}
  .nav-drop-panel .nl-ic{display:grid}
}
.nav-burger{display:none;width:40px;height:40px;border-radius:10px;align-items:center;
  justify-content:center;color:var(--ink);transition:background var(--dur-mid)}
.nav-burger:active{background:rgba(79,93,255,.08)}
.nav-burger svg{width:22px;height:22px}
/* 三杠 → ✕ 开合动画 */
.nav-burger svg path{transform-box:fill-box;transform-origin:center;transition:transform .28s cubic-bezier(.22,1,.3,1),opacity var(--dur-mid)}
.nav-burger.open svg{transform:rotate(90deg);transition:transform .28s}
.nav-burger.open svg path:nth-child(1){transform:translateY(5px) rotate(45deg)}
.nav-burger.open svg path:nth-child(2){opacity:0}
.nav-burger.open svg path:nth-child(3){transform:translateY(-5px) rotate(-45deg)}
.nav-ghost{padding:8px 18px;border-radius:999px;font-size:.92rem;color:var(--ink-2);font-weight:600}
.nav-ghost:hover{color:var(--primary)}
/* 响应式显示工具类：hide-m 移动端隐藏 / hide-d 桌面端隐藏 */
@media(max-width:760px){.hide-m{display:none!important}}
@media(min-width:761px){.hide-d{display:none!important}}
.user-chip{display:flex;align-items:center;gap:8px;padding:5px 12px 5px 5px;border-radius:999px;
  border:1px solid var(--line);background:#fff;transition:var(--dur-mid);max-width:180px;cursor:pointer;position:relative}
.user-chip:hover{border-color:var(--primary);box-shadow:var(--shadow-s)}
.avatar{width:30px;height:30px;border-radius:50%;background:var(--grad-main);color:#fff;
  display:flex;align-items:center;justify-content:center;font-weight:700;font-size:.8rem;flex-shrink:0;
  object-fit:cover}
.user-chip span{font-size:.88rem;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media(max-width:420px){.user-chip span{display:none}.user-chip{padding:4px}}

/* ---------- 头像下拉菜单（v1.42.1） ---------- */
.user-menu{position:relative;flex-shrink:0}
.uc-caret{width:14px;height:14px;color:var(--ink-3);transition:transform .22s var(--ease);flex-shrink:0}
.user-menu.open .uc-caret{transform:rotate(180deg)}
.user-menu-panel{position:absolute;top:calc(100% + 10px);right:0;width:260px;max-width:calc(100vw - 24px);
  background:#fff;border:1px solid var(--line);border-radius:16px;box-shadow:var(--shadow-l);
  padding:8px;opacity:0;transform:translateY(-8px) scale(.98);transform-origin:top right;
  pointer-events:none;transition:var(--dur-mid) var(--ease);z-index:950}
.user-menu.open .user-menu-panel{opacity:1;transform:translateY(0) scale(1);pointer-events:auto}
.ump-head{display:flex;align-items:center;gap:12px;padding:10px 10px 12px;border-bottom:1px solid var(--line);margin-bottom:6px}
.ump-head .avatar{width:40px;height:40px;font-size:1.05rem}
.ump-id{min-width:0}
.ump-id b{display:block;font-size:.95rem;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ump-id span{display:block;font-size:.74rem;color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ump-body{padding:2px 0}
.ump-item{display:flex;align-items:center;gap:10px;width:100%;padding:9px 10px;border-radius:10px;
  font-size:.88rem;font-weight:550;color:var(--ink-2);text-align:left;transition:var(--dur-fast);cursor:pointer}
.ump-item:hover{background:var(--bg-soft);color:var(--ink)}
.ump-ic{font-size:1rem;line-height:1;flex-shrink:0;display:inline-flex;align-items:center}
.ump-ic svg{width:17px;height:17px}
.ump-ar{margin-left:auto;color:var(--ink-3);font-size:1rem;line-height:1}
.ump-admin{color:var(--primary)}
.ump-foot{border-top:1px solid var(--line);margin-top:6px;padding-top:6px}
.ump-logout{color:var(--err)}
.ump-logout:hover{background:rgba(239,68,68,.08);color:var(--err)}
/* v1.44.5 未读消息角标 */
.nav-msg-dot{position:absolute;top:-2px;right:-2px;width:9px;height:9px;border-radius:50%;
  background:#EF4444;border:2px solid #fff;flex-shrink:0}
.ump-notif-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;
  padding:0 5px;border-radius:999px;background:#EF4444;color:#fff;font-size:.68rem;font-weight:700;flex-shrink:0}
/* v1.70.0 删除原 @media(max-width:420px){.user-menu-panel{position:fixed;top:var(--nav-h);
   right:8px;left:8px;width:auto;max-width:none}} —— 它会把头像面板强制拉成「左右各 8px
   的全宽条」（实测 390px 下宽 374px），既与 ≤900px 段新写的 min(304px,...) 冲突
   （同优先级 + 源码靠后 → 这里赢），又让 head/body 被迫撑到 356px、每格 176px 过宽，
   面板高度也难以压下来。≤900px 段的规则已完整覆盖移动端定位，此处不再需要。
   ≤480px 只需补一条「极窄屏再收一点」的微调，见下方。 */
@media(max-width:480px){
  .user-menu-panel{width:min(296px,calc(100vw - 12px))}
  .ump-item{font-size:.76rem;gap:7px;padding:8px 9px}
}

/* ---------- v1.70.0 回到顶部悬浮按钮 ----------
   原来只有页脚里的 .footer-top 内联按钮：「首页近 6000px 长，滑到底才看得到入口」
   体感很差；而 chat 页根本不渲染页脚 → 对话页完全没有回到顶部。
   现在改为右侧悬浮圆钮，滚动超过一定距离自动淡入。
   chat 页由 JS 跳过（该页是 100dvh 内部滚动容器，已有「回到底部」按钮，职责不同）。 */
.scroll-top{position:fixed;right:20px;bottom:calc(24px + env(safe-area-inset-bottom,0px));z-index:800;
  width:44px;height:44px;border-radius:50%;background:#fff;color:var(--primary);
  border:1px solid var(--line);box-shadow:var(--shadow-m);
  display:flex;align-items:center;justify-content:center;cursor:pointer;
  transition:opacity var(--dur-mid) var(--ease),transform var(--dur-mid) var(--ease),
             box-shadow var(--dur-fast),border-color var(--dur-fast)}
.scroll-top svg{width:19px;height:19px}
.scroll-top:hover{border-color:var(--primary);box-shadow:var(--shadow-l);transform:translateY(-2px)}
.scroll-top:active{transform:scale(.94)}
/* ⚠ 必须用 [hidden] 显式覆盖 display：hidden 属性只是 UA 样式 display:none，
   而上面写了 display:flex，作者样式优先级更高会把 hidden 覆盖掉（本版验证码 74px
   死空白就是同一个坑），因此这里必须显式写 !important。 */
.scroll-top[hidden]{display:none!important}
@media(max-width:640px){
  .scroll-top{right:14px;bottom:calc(18px + env(safe-area-inset-bottom,0px));width:42px;height:42px}
  .scroll-top svg{width:18px;height:18px}
}
/* 尊重系统「减少动态效果」偏好：不做位移动画 */
@media(prefers-reduced-motion:reduce){
  .scroll-top{transition:opacity var(--dur-fast) linear}
  .scroll-top:hover{transform:none}
}

/* ---------- 按钮 ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:11px 22px;border-radius:12px;font-weight:700;font-size:.95rem;
  transition:var(--dur-mid) var(--ease);border:1px solid transparent;white-space:nowrap;user-select:none;
  min-height:44px}
.btn svg{width:16px;height:16px;flex:none}
.btn:active{transform:scale(.97)}
.btn-primary{background:var(--grad-main);color:#fff;box-shadow:var(--glow-m)}
.btn-primary:hover{box-shadow:var(--glow-l);transform:translateY(-1px)}
.btn-ghost{background:#fff;border-color:var(--line);color:var(--ink-2)}
.btn-ghost:hover{border-color:var(--primary);color:var(--primary)}
/* v1.66.0 超小号按钮：用于对话流内联操作（重试/继续生成），不抢视觉焦点 */
.btn-xs{padding:5px 12px;min-height:30px;font-size:.82rem;border-radius:9px;gap:5px}
.btn-xs svg{width:13px;height:13px}
.btn-soft{background:rgba(79,93,255,.09);color:var(--primary)}
.btn-soft:hover{background:rgba(79,93,255,.16)}
/* v1.61.0：网关用量维度切换按钮的选中态 */
.btn-soft.cur{background:var(--primary);color:#fff}
.btn-danger{background:rgba(239,68,68,.1);color:var(--err)}
.btn-danger:hover{background:rgba(239,68,68,.18)}
.btn-danger-soft{background:rgba(239,68,68,.09);color:#DC2626;border:1px solid rgba(239,68,68,.3)}
.btn-danger-soft:hover{background:rgba(239,68,68,.16)}
.btn-ok{background:var(--ok);color:#fff}
.btn-lg{padding:14px 30px;font-size:1.05rem;border-radius:14px;min-height:48px}
.btn-sm{padding:7px 14px;font-size:.85rem;border-radius:9px;min-height:40px}
.btn-blk{width:100%}
.btn[disabled]{opacity:.55;pointer-events:none}
/* v1.45.86 触控目标：手机上按钮/Tabs/表单提交保持 ≥44px 可点高度（iOS/Android 无障碍建议值），
   桌面不受影响；小尺寸按钮至少 40px，避免误触。 */
@media(max-width:640px){
  .btn{min-height:44px}
  .btn-sm{min-height:40px}
}

/* ---------- 徽章 / 标签 ---------- */
.tag{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:999px;
  font-size:.75rem;font-weight:600;background:rgba(79,93,255,.1);color:var(--primary)}
.tag svg{width:13px;height:13px;flex-shrink:0}
.tag.violet{background:rgba(124,77,255,.12);color:var(--violet)}
.tag.ok{background:rgba(15,179,123,.12);color:var(--ok)}
.tag.warn{background:rgba(245,158,11,.14);color:#B45309}
.tag.err{background:rgba(239,68,68,.12);color:var(--err)}
.tag.gray{background:#F0F2F9;color:var(--ink-3)}
/* v1.57.0 聚合虚拟模型徽标：全站统一的「⚡聚合」视觉标识，
   背景用主色渐变弱化，配闪电点缀，与普通模型选项形成一眼可辨的区分 */
.tag.agg{background:linear-gradient(135deg,rgba(79,93,255,.14),rgba(124,77,255,.14));
  color:var(--primary);border:1px solid rgba(79,93,255,.22)}
.tag.agg::before{content:'⚡';font-size:.72rem;line-height:1}
.dot{width:7px;height:7px;border-radius:50%;background:currentColor;display:inline-block}

/* v1.58.0 模型聚合网关「能力分组」折叠视图 */
.mg-group{border:1px solid var(--line);border-radius:12px;margin-bottom:10px;overflow:hidden;background:var(--card)}
.mg-group-hd{display:flex;align-items:center;gap:10px;width:100%;padding:14px 16px;background:var(--bg-2);
  border:none;cursor:pointer;text-align:left;font-size:.95rem;transition:background var(--dur)}
.mg-group-hd:hover{background:var(--bg-3,var(--bg-2))}
.mg-g-arrow{color:var(--ink-3);font-size:.85rem;transition:transform .2s;flex:0 0 auto}
.mg-group.open .mg-g-arrow{transform:rotate(90deg)}
.mg-g-ic{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;
  border-radius:8px;background:linear-gradient(135deg,rgba(79,93,255,.12),rgba(124,77,255,.12));color:var(--primary);flex:0 0 auto}
.mg-g-name{font-weight:700;color:var(--ink-1)}
.mg-g-count{margin-left:auto;font-size:.76rem;color:var(--ink-3);display:flex;align-items:center;gap:6px}
.mg-group-bd{max-height:0;overflow:hidden;transition:max-height .25s ease}
.mg-sub{padding:12px 16px}
.mg-sub + .mg-sub{border-top:1px dashed var(--line)}
.mg-sub-hd{font-size:.86rem;font-weight:700;color:var(--ink-2);margin-bottom:10px;display:flex;align-items:center;gap:6px}
.tbl-mini{font-size:.82rem}
.tbl-mini th,.tbl-mini td{padding:9px 10px}


/* ---------- 卡片 ---------- */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r-l);box-shadow:var(--shadow-s)}
.card-hov{transition:var(--dur-slow) cubic-bezier(.22,1,.3,1)}
.card-hov:hover{transform:translateY(-5px);box-shadow:var(--shadow-m);border-color:rgba(79,93,255,.35)}

/* ---------- 输入 ---------- */
.field{margin-bottom:16px}
.field label{display:block;font-size:.86rem;font-weight:600;color:var(--ink-2);margin-bottom:7px}
/* v1.70.8 全局表单控件统一：默认 1px 浅描边、聚焦 1.5px 品牌描边 + 轻光环，
   与首页/对话页输入框保持同一套视觉语言。 */
.input{width:100%;padding:12px 14px;border:1px solid var(--line);border-radius:12px;
  background:#fff;transition:var(--dur-mid);font-size:.95rem}
.input:hover{border-color:#D5DAEE}
.input:focus{border-color:var(--primary);box-shadow:0 0 0 3px rgba(79,93,255,.11)}
.input::placeholder{color:#B0B6CE}
.input:disabled,.input[readonly]{background:var(--bg);color:var(--ink-3);cursor:not-allowed}
textarea.input{resize:vertical;min-height:90px;line-height:1.6}
select.input{appearance:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238A90AB' stroke-width='2.4'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 12px center;padding-right:34px}
/* 原生 input[type=text/email/password/...] 未挂 .input 类时的兜底（auth/user 等页历史写法） */
input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=hidden]):not([type=range]):not([type=submit]):not([type=button]):not(.input):not([class*=no-style]){
  transition:border-color var(--dur-mid),box-shadow var(--dur-mid)}
input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=hidden]):not(.input):not([class*=no-style]):focus{
  border-color:var(--primary)}
.input-lg{padding:14px 16px;font-size:1rem;border-radius:14px}
.switch{position:relative;width:42px;height:24px;background:#D7DBEE;border-radius:99px;transition:.25s;flex-shrink:0;cursor:pointer}
.switch::after{content:"";position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;background:#fff;transition:.25s;box-shadow:var(--shadow-s)}
.switch.on{background:var(--primary)}
.switch.on::after{left:21px}

/* ---------- 表格 ---------- */
.table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;border-radius:var(--r-m);border:1px solid var(--line);background:#fff}
table.tbl{width:100%;border-collapse:collapse;font-size:.88rem;min-width:640px}
.tbl th{background:#F4F6FC;color:var(--ink-3);font-weight:600;text-align:left;padding:11px 14px;
  white-space:nowrap;font-size:.8rem;letter-spacing:.3px}
.tbl td{padding:12px 14px;border-top:1px solid var(--line);color:var(--ink-2);vertical-align:middle}
.tbl tr:hover td{background:#FAFBFF}
.tbl .strong{color:var(--ink);font-weight:700}

/* ---------- 分页 ---------- */
.pager{display:flex;gap:8px;align-items:center;justify-content:flex-end;margin-top:14px;flex-wrap:wrap}
.pager button{min-width:34px;height:34px;border-radius:9px;border:1px solid var(--line);
  background:#fff;color:var(--ink-2);font-weight:600;font-size:.85rem}
.pager button.cur{background:var(--grad-main);color:#fff;border-color:transparent}
.pager button[disabled]{opacity:.4}

/* ---------- 空状态 ---------- */
.empty{padding:48px 20px;text-align:center;color:var(--ink-3)}
.empty svg{width:64px;height:64px;margin:0 auto 14px;opacity:.5}
.empty p{font-size:.92rem}

/* ---------- Toast ---------- */
#toasts{position:fixed;top:76px;left:50%;transform:translateX(-50%);z-index:2000;
  display:flex;flex-direction:column;gap:10px;align-items:center;width:max-content;max-width:92vw}
.toast{padding:11px 20px;border-radius:12px;background:#1E2235;color:#fff;font-size:.9rem;
  font-weight:600;box-shadow:var(--shadow-l);display:flex;gap:8px;align-items:center;
  animation:toastIn var(--dur-slow) cubic-bezier(.22,1,.3,1);max-width:92vw}
.toast .toast-ic{display:flex;flex-shrink:0}
.toast .toast-ic svg{width:17px;height:17px}
.toast.ok{background:linear-gradient(135deg,#0FB37B,#0E9F6E)}
.toast.err{background:linear-gradient(135deg,#EF4444,#DC2626)}
.toast.info{background:linear-gradient(135deg,#4F5DFF,#8B5CF6)}
@keyframes toastIn{from{opacity:0;transform:translateY(-14px) scale(.94)}to{opacity:1;transform:none}}
.toast.out{animation:toastOut var(--dur-slow) forwards}
@keyframes toastOut{to{opacity:0;transform:translateY(-10px) scale(.96)}}

/* ---------- 弹窗 ---------- */
.modal-mask{position:fixed;inset:0;background:rgba(18,22,48,.5);backdrop-filter:blur(6px);
  z-index:1500;display:flex;align-items:center;justify-content:center;padding:20px;
  opacity:0;pointer-events:none;transition:.25s}
.modal-mask.show{opacity:1;pointer-events:auto}
.modal{background:#fff;border-radius:var(--r-l);width:100%;max-width:520px;max-height:88vh;
  overflow:auto;overscroll-behavior:contain;box-shadow:var(--shadow-l);transform:translateY(24px) scale(.97);transition:.28s cubic-bezier(.22,1,.3,1);
  scrollbar-width:thin;scrollbar-color:#C3C9E9 transparent}
.modal::-webkit-scrollbar{width:6px}
.modal::-webkit-scrollbar-track{background:transparent}
.modal::-webkit-scrollbar-thumb{background:#C3C9E9;border-radius:3px}
.modal::-webkit-scrollbar-thumb:hover{background:#9AA3D6}
.modal-mask.show .modal{transform:none}
.modal-head{display:flex;align-items:center;justify-content:space-between;padding:18px 22px 0}
.modal-head h3{font-size:1.1rem;font-weight:800}
.modal-x{width:32px;height:32px;border-radius:9px;display:flex;align-items:center;justify-content:center;color:var(--ink-3)}
.modal-x:hover{background:var(--bg-soft);color:var(--ink)}
.modal-body{padding:18px 22px 22px}
/* 弹窗内图标条目（模型选择/列表类弹窗通用）：SVG 无固有尺寸会撑满容器，必须显式约束 */
.modal .mi{display:flex;align-items:flex-start;gap:11px;padding:11px 12px;border-radius:11px;cursor:pointer;transition:var(--dur-fast)}
.modal .mi:hover{background:var(--bg-soft)}
.modal .mi.cur{background:rgba(79,93,255,.08)}
.modal .mi.off{opacity:.5;cursor:not-allowed}
.modal .mi.off:hover{background:transparent}
.modal .mi .ic{width:34px;height:34px;border-radius:9px;display:flex;align-items:center;justify-content:center;flex-shrink:0;color:#fff;overflow:hidden;margin-top:2px}
.modal .mi .ic svg{width:17px;height:17px;flex-shrink:0}
/* v1.44.7 品牌官方 Logo 徽标：通用方块容器，内含 SVG 官方图标；回落分类图标时带 cat 类 */
.brand-logo{width:34px;height:34px;border-radius:9px;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;color:#fff;overflow:hidden}
.brand-logo svg{width:60%;height:60%;flex-shrink:0}
.brand-logo.cat svg{width:50%;height:50%}
/* v1.70.8 真实品牌 Logo（本地采集）：白底浅描边容器，图片 contain 铺满；
   图片加载成功 → 隐藏 SVG 兜底；失败/未加载 → 显示内联 SVG 兜底，保证永不裸奔。 */
.brand-logo.real{background:#fff;border:1px solid var(--line);position:relative}
.brand-logo.real img{width:100%;height:100%;object-fit:contain;padding:11%;border-radius:inherit;position:relative;z-index:1}
.brand-logo.real .svg-fb{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff;border-radius:inherit;z-index:0}
.brand-logo.real .svg-fb svg{width:58%;height:58%}
.brand-logo.real.has-img .svg-fb{display:none}
.modal .mi b{font-size:.9rem;display:block;line-height:1.35}
.modal .mi small{color:var(--ink-3);font-size:.76rem;display:block;min-width:0;line-height:1.5;margin-top:1px}
/* 模型选择条：文本列 + 右侧价格列 */
.modal .mi .mi-txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.modal .mi .mi-right{margin-left:auto;flex-shrink:0;display:flex;flex-direction:column;align-items:flex-end;gap:4px;padding-left:8px}
.modal .mi .mi-tags{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}
.modal .mi .mi-tags i{font-style:normal;font-size:.66rem;font-weight:600;color:var(--ink-3);
  background:#F3F4FA;border-radius:5px;padding:1px 7px}
.modal .mi .tag{margin:0;white-space:nowrap}
.modal .mi .tag.warn{background:rgba(245,158,11,.14);color:#B45309}
.modal .mi .tag.gen{background:rgba(79,93,255,.12);color:#4F5DFF}
/* v1.71.41 视觉工坊入口（对话/首页模型选择器顶部）：与 .mi 同构的渐变引导卡，
   点击跳转 /studio；视觉模型已从对话列表移除，此处作为唯一入口引导 */
.mm-studio-entry{margin:2px 0 10px;display:flex;align-items:center;gap:11px;padding:11px 12px;border-radius:11px;cursor:pointer;
  background:linear-gradient(135deg,rgba(79,93,255,.10),rgba(139,92,246,.10));border:1px dashed rgba(79,93,255,.35);transition:var(--dur-fast)}
.mm-studio-entry:hover{background:linear-gradient(135deg,rgba(79,93,255,.16),rgba(139,92,246,.16));border-color:rgba(79,93,255,.6)}
.mm-studio-entry b{font-size:.9rem;display:block;line-height:1.35}
.mm-studio-entry small{color:var(--ink-3);font-size:.76rem;display:block;min-width:0;line-height:1.5;margin-top:1px}
.mm-studio-entry .st-logi{width:34px;height:34px;border-radius:9px;display:flex;align-items:center;justify-content:center;flex-shrink:0;color:#fff;margin-top:2px;
  background:linear-gradient(135deg,#4F5DFF,#8B5CF6)}
.mm-studio-entry .st-logi svg{width:18px;height:18px;flex-shrink:0}
.mm-studio-entry .tag{margin-left:auto;flex-shrink:0;white-space:nowrap;background:rgba(79,93,255,.12);color:#4F5DFF}
/* chat.js 里入口卡复用了 .mi 结构，需额外对齐 */
.mm-studio-entry .mi{padding:0;border-radius:0;background:transparent}
.mm-studio-entry .mi:hover{background:transparent}
.mm-studio-entry .mi .mi-right{flex-direction:row}
/* v1.70.6 模型详情卡：hover/选中时在列表项下方展开三行推导字段（消耗速度/思考强度/上下文窗口）。
   列表项为 flex，详情卡作为最后一个子元素独占整行；默认收起，hover 或 .cur 时展开。 */
.modal .mi{flex-wrap:wrap}
.modal .mi .mp-detail{display:none;flex-basis:100%;margin:6px 0 2px 45px;padding:8px 10px;
  background:var(--bg-soft, #F3F4FA);border-radius:9px;font-size:.72rem;color:var(--ink-2)}
.modal .mi:hover .mp-detail,.modal .mi.cur .mp-detail{display:flex;flex-direction:column;gap:4px}
.modal .mi .mp-detail .mp-row{display:flex;align-items:center;gap:10px}
.modal .mi .mp-detail .mp-k{flex-shrink:0;width:64px;font-weight:700;color:var(--ink-3);font-size:.68rem}
.modal .mi .mp-detail .mp-v{font-weight:600;color:var(--ink-1)}
/* v1.70.7 深度思考开关行：从输入区 chip 迁入模型面板顶部（.mp-deep + .tswitch 拨杆），
   对齐交互原型。对话页模型弹窗与首页模型下拉共用同一套样式。 */
.mp-deep{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:10px;cursor:pointer;transition:var(--dur-fast)}
.mp-deep:hover{background:#F3F5FF}
.mp-deep .ic{width:30px;height:30px;border-radius:8px;background:#EEF1FF;color:var(--primary);display:flex;align-items:center;justify-content:center;flex:none;transition:.2s}
.mp-deep.on .ic{background:var(--grad-main);color:#fff;box-shadow:0 2px 8px rgba(79,93,255,.35)}
.mp-deep .ic svg{width:17px;height:17px}
.mp-deep-txt{min-width:0}
.mp-deep-txt b{font-size:.82rem;display:block;line-height:1.3}
.mp-deep-txt span{font-size:.72rem;color:var(--ink-3);display:block;margin-top:1px;line-height:1.4}
.mp-deep.on .mp-deep-txt b{color:var(--primary)}
.mp-deep.disabled{opacity:.5;cursor:not-allowed}
.tswitch{margin-left:auto;width:38px;height:22px;border-radius:22px;background:#D9DCE8;position:relative;flex:none;transition:.25s}
.tswitch i{position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.22);transition:.25s}
.tswitch.on{background:var(--grad-main);animation:deepGlow 1.8s ease-in-out infinite}
.tswitch.on i{left:18px}
@keyframes deepGlow{0%,100%{box-shadow:0 0 0 0 rgba(79,93,255,.35),0 2px 10px rgba(79,93,255,.4)}50%{box-shadow:0 0 0 5px rgba(79,93,255,0),0 2px 14px rgba(124,77,255,.5)}}
.mp-div{height:1px;background:var(--line);margin:5px 6px}
/* v1.45.22 模型选择器按四大能力大类分组 */
.modal .mm-group{margin:2px 0}
.modal .mm-group+.mm-group{margin-top:8px;padding-top:8px;border-top:1px solid var(--bg-soft)}
.modal .mm-group-h{display:flex;align-items:center;gap:6px;padding:6px 12px 4px;font-size:.72rem;font-weight:700;color:var(--ink-2);letter-spacing:.02em}
.modal .mm-group-h small{font-size:.68rem;font-weight:600;color:var(--ink-3);background:#F3F4FA;border-radius:8px;padding:1px 7px}
@media(max-width:640px){
  .modal .mi{padding:9px 10px;gap:9px}
  .modal .mi .ic{width:29px;height:29px;border-radius:8px}
  .modal .mi .ic svg{width:15px;height:15px}
  .modal .mi b{font-size:.82rem}
  .modal .mi small{font-size:.7rem}
  .modal .mi .mi-tags i{font-size:.62rem;padding:1px 6px}
  .modal .mi .mp-detail{margin-left:0;margin-top:8px}
}
@media(max-width:480px){.modal-mask{padding:0;align-items:flex-end}.modal{max-width:none;border-radius:20px 20px 0 0;max-height:92vh;padding-bottom:env(safe-area-inset-bottom)}}

/* ---------- 动效 ---------- */
/* v1.84.0 渐进增强兜底：.reveal 的初始隐藏态仅在启用 JS 时生效（<html> 带 .js 类）。
   无 JS / JS 在 initReveal 前报错时，内容默认完全可见，避免「区块空白看不见」的硬失效。
   .js 类由 header.php 在 <head> 开头同步注入，对 JS 用户时序与原来一致（无回归/无闪烁）。 */
.js .reveal{opacity:0;transform:translateY(26px)}
.js .reveal.in{opacity:1;transform:none;transition:opacity .7s ease var(--rd,0ms),transform .7s cubic-bezier(.22,1,.3,1) var(--rd,0ms)}
/* 无 .js 时强制终态可见（双保险，覆盖任何遗漏的 .reveal 元素） */
.reveal{opacity:1;transform:none}
@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-12px)}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.45}}
@keyframes spin{to{transform:rotate(360deg)}}
.spinner{width:18px;height:18px;border:2.5px solid rgba(255,255,255,.35);border-top-color:#fff;
  border-radius:50%;animation:spin .7s linear infinite;display:inline-block}
.spinner.dark{border-color:rgba(79,93,255,.25);border-top-color:var(--primary)}
@keyframes blink{0%,100%{opacity:1}50%{opacity:0}}
.caret{display:inline-block;width:2px;height:1em;background:var(--primary);vertical-align:-.15em;
  margin-left:2px;animation:blink 1s infinite}

/* ---------- 页脚 ----------
   v1.70.4 三段式浅色改版（对齐主流云厂商页脚结构）：
   ① .foot-promo 服务承诺带（图标+标题+副文 ×4，移动端 2×2）；
   ② .footer-grid 品牌列 + 4 组链接 —— 组用 <details open> 承载：
     桌面端锁定展开 + 禁用 summary 点击；移动端（≤520）同样展开，
     链接组一排两个（2×2 网格）铺开，一份 DOM 两端形态，无 JS 参与；
   ③ .footer-bar 版权栏（© + 协议/备案），样式适配浅色。
   配色与站点浅色基调（--bg:#F6F7FB）一致：底色 #F7F9FC、墨色文字、
   主色渐变只出现在品牌 logo/竖条/图标容器等点缀处。 */
.footer{
  background:#F7F9FC;color:var(--ink-2);padding:0;margin-top:0;position:relative;
  border-top:1px solid var(--line);
}
/* 顶部缝合线：由深色版的高光渐隐改为浅色版的主色渐隐，衔接上方区块 */
.footer::before{
  content:'';position:absolute;left:0;right:0;top:-1px;height:2px;z-index:2;
  background:linear-gradient(90deg,transparent,rgba(124,77,255,.5) 20%,rgba(79,93,255,.6) 50%,rgba(124,77,255,.4) 80%,transparent);
}
.footer>.container{position:relative;z-index:1}

/* ① 服务承诺带 */
.foot-promo{padding:34px 0 24px}
.foot-promo-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
.fp-item{display:flex;align-items:center;gap:14px;min-width:0}
.fp-ic{
  width:46px;height:46px;flex:none;border-radius:14px;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(135deg,rgba(79,93,255,.10),rgba(124,77,255,.10));color:var(--primary);
}
.fp-ic svg{width:22px;height:22px}
.fp-tx{min-width:0}
.fp-tx b{display:block;font-size:.95rem;color:var(--ink);font-weight:750;margin-bottom:3px}
.fp-tx p{margin:0;font-size:.8rem;color:var(--ink-3);line-height:1.5}

/* ② 链接区：品牌列 + 4 组（details open，桌面锁展开） */
.footer-grid{display:grid;grid-template-columns:1.5fr 1fr 1fr 1fr 1.25fr;gap:32px;padding:24px 0 40px}
.footer .brand{color:var(--ink);margin-bottom:14px}
.footer .brand small{font-size:.75rem;margin-left:3px;letter-spacing:.5px;color:var(--ink-3)}
.footer .slogan{font-size:.86rem;line-height:1.8;max-width:300px;color:var(--ink-3)}
.ft-grp summary{
  list-style:none;cursor:default;
  pointer-events:none;   /* 桌面锁定展开：details 已 open，禁掉 summary 点击防误折叠 */
  font-size:.95rem;font-weight:750;color:var(--ink);margin-bottom:16px;
  display:flex;align-items:center;justify-content:space-between;
  position:relative;padding-left:13px;
}
.ft-grp summary::-webkit-details-marker{display:none}
.ft-grp summary::before{content:'';position:absolute;left:0;top:50%;transform:translateY(-50%);width:3px;height:15px;
  border-radius:99px;background:var(--grad-main)}
/* 折叠箭头：仅移动端手风琴态显示（桌面 none） */
.ft-grp summary::after{
  content:'';width:8px;height:8px;flex:none;margin-left:8px;display:none;
  border-right:2px solid var(--ink-3);border-bottom:2px solid var(--ink-3);
  transform:rotate(45deg) translateY(-2px);transition:transform .2s;
}
.ft-links a{display:block;font-size:.86rem;margin-bottom:12px;color:var(--ink-2);transition:var(--dur-mid)}
.ft-links a:hover{color:var(--primary)}
.ft-c-line{margin:0 0 10px;font-size:.84rem;color:var(--ink-2);line-height:1.6}
.footer-social{display:flex;gap:10px;margin-top:14px}
.footer-social a{width:36px;height:36px;border-radius:10px;background:rgba(79,93,255,.08);color:var(--ink-2);
  display:flex;align-items:center;justify-content:center;margin:0;transition:.22s}
.footer-social a:hover{background:var(--primary);color:#fff;transform:translateY(-2px)}
.footer-social svg{width:17px;height:17px}

/* ③ 版权栏 */
.footer-bar{
  border-top:1px solid var(--line);padding:20px 0 24px;font-size:.78rem;
  color:var(--ink-3);display:flex;justify-content:space-between;align-items:center;gap:14px;flex-wrap:wrap;
}
.footer-bar .fb-copy b{color:var(--ink-2);font-weight:650}
.footer-bar a{display:inline-block;margin:0;padding:7px 3px;color:var(--ink-3)}
.footer-bar a:hover{color:var(--primary)}
.footer-bar .fb-legal{display:inline-flex;align-items:center;flex-wrap:wrap}
.footer-bar .fb-legal i{font-style:normal;color:#C6CADB;margin:0 4px;font-size:.7rem}

/* ---- ≤860：承诺带 2×2；链接组 2×2（品牌列通栏） ---- */
@media(max-width:860px){
  .foot-promo{padding:26px 0 18px}
  .foot-promo-grid{grid-template-columns:1fr 1fr;gap:14px}
  .footer-grid{grid-template-columns:1fr 1fr;gap:20px 26px;padding:18px 0 32px}
  .footer-brand-col{grid-column:1/-1}
}

/* ---- 手机端（≤520）：链接组展开两列 + 承诺带紧凑 ----
   ⚠ 本块必须放在上面所有 .footer 与 .ft-* 基础规则【之后】（同权重靠后者胜，
   旧版深色页脚已实测踩过次序坑）。v1.70.5 起：移动端不再用手风琴折叠，
   改为全部展开 + 一排两个链接组（2×2 网格），summary 锁展开、隐藏折叠箭头，
   组间以 grid gap 留白分隔，整体规整一致。 */
@media (max-width:520px){
  /* 品牌列隐藏：顶部导航已有品牌标识，页脚不重复（桌面端仍展示） */
  .footer-brand-col{display:none}
  .footer{padding:0}
  /* 承诺带：图标容器缩小、两列更紧凑 */
  .foot-promo{padding:20px 0 6px}
  .foot-promo-grid{gap:10px 14px}
  .fp-item{gap:10px}
  .fp-ic{width:38px;height:38px;border-radius:11px}
  .fp-ic svg{width:18px;height:18px}
  .fp-tx b{font-size:.82rem;margin-bottom:1px}
  .fp-tx p{font-size:.7rem}
  /* 链接区：展开态，一排两个链接组（2×2 网格），组间用 gap 留白 */
  .footer-grid{grid-template-columns:1fr 1fr;gap:20px 18px;padding:14px 0 22px}
  .ft-grp{border-bottom:0}
  .ft-grp summary{
    cursor:default;pointer-events:none;   /* 移动端也锁定展开，禁折叠 */
    font-size:.85rem;margin-bottom:12px;padding:0;
  }
  .ft-grp summary::before{height:13px}
  .ft-grp summary::after{display:none}     /* 去掉折叠箭头 */
  .ft-grp .ft-links{padding:0}
  .ft-links a{margin-bottom:10px;padding:0;font-size:.8rem}
  .ft-c-line{margin-bottom:8px;font-size:.78rem}
  .footer-social{margin:6px 0 0}
  /* 版权栏：居中 + 紧凑（沿用旧策略：去横线靠留白） */
  .footer-bar{border-top:0;justify-content:center;text-align:center;padding:12px 0;font-size:.7rem;gap:4px}
  .footer-bar a{padding:4px 3px}
}

/* ---------- 工具类 ---------- */
.row{display:flex;align-items:center;gap:10px}
.between{display:flex;align-items:center;justify-content:space-between;gap:10px}
.wrap{flex-wrap:wrap}
.muted{color:var(--ink-3);font-size:.85rem}
.mono{font-family:var(--mono)}
.ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hide{display:none!important}
.divider{height:1px;background:var(--line);margin:18px 0}
.badge-num{min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:var(--err);
  color:#fff;font-size:.7rem;font-weight:700;display:inline-flex;align-items:center;justify-content:center}

/* 无独立 hero 页面的顶部留白（agents / pricing / docs 等直接 section 开头的页面）：
   桌面端在导航下留 40px，移动端收紧为 16px，全局统一紧凑节奏。
   ⚠ v1.70.18 修复：原选择器 `.page-hero-gap` 与下方 `.section`（padding:54px 0）同特异性，
   且 `.section` 定义在后、胜出，把 padding-top 压成 54px —— 导航高 64px，导致
   agents/pricing/docs 的 hero kicker（AGENTS / PRICING）被顶到导航正下方、内容被遮挡。
   改为 `.section.page-hero-gap`（双类，特异性 0-2-0 > 0-1-0）稳定压过 `.section`。 */
.section.page-hero-gap{padding-top:calc(var(--nav-h) + 40px)}
@media(max-width:640px){.section.page-hero-gap{padding-top:calc(var(--nav-h) + 16px)}}

/* ==================== v1.45.59 通用 Section 布局（全站共享） ====================
   原先 .section / .sec-head 定义在 index.css（仅首页加载），导致 earn/idle/scene 等
   其他页面的 <section class="section"> 拿不到统一纵向 padding，各页区块节奏参差。
   此处上移到 base.css，全站共享统一节奏；首页专属的区块背景装饰（.sec-soft 等）
   仍留在 index.css 不动。 */
.section{padding:54px 0}
@media(max-width:768px){.section{padding:34px 0}}
/* v1.70.10 移动端纵向紧缩：相邻 section 首尾相接的视觉空白从 176px 收敛到 60px */
@media(max-width:640px){.section{padding:30px 0}}
@media(max-width:380px){.section{padding:26px 0}}
.sec-head{text-align:center;max-width:660px;margin:0 auto 32px}
.sec-head .kicker{display:inline-block;padding:6px 15px;border-radius:999px;background:rgba(79,93,255,.08);
  color:var(--primary);font-size:.78rem;font-weight:700;letter-spacing:.5px;margin-bottom:16px}
.sec-head h2{font-size:clamp(1.5rem,4vw,2.2rem);font-weight:900;letter-spacing:-.5px;line-height:1.3;margin-bottom:12px}
.sec-head p{color:var(--ink-2);font-size:.98rem;line-height:1.75}

/* ==================== v1.14.0 多模态产出卡片（对话页 / 场景页共用） ====================
   由 common.js 的 mediaTags() 生成，class 前缀统一 md-media-*。
   原先只有场景页的 .sc-video（深色剧场风），对话页的视频/音频根本没有样式可依
   （因为压根没渲染出来）。此处定义一套通用样式，两个页面都能用。 */
.md-media{
  margin:12px 0;border-radius:var(--r-m);overflow:hidden;
  background:var(--bg-soft);border:1px solid var(--line);
}
/* 视频：限宽居中，竖屏短剧最常见的画幅不至于在桌面端撑成巨幕 */
.md-media-video video{
  width:100%;max-width:100%;max-height:min(62vh,520px);display:block;
  background:#000;border-radius:var(--r-m) var(--r-m) 0 0;
}
.md-media-audio audio{width:100%;display:block;padding:12px 12px 4px;box-sizing:border-box}
.md-media-bar{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:8px 12px;font-size:.78rem;
}
.md-media-name{
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  color:var(--ink-3);font-family:var(--mono);flex:1;min-width:0;
}
.md-media-dl{
  flex:0 0 auto;font-size:.78rem;font-weight:650;text-decoration:none;
  padding:5px 13px;border-radius:999px;color:var(--primary);
  background:color-mix(in srgb, var(--primary) 11%, transparent);transition:.16s;
  display:inline-flex;align-items:center;gap:5px;
}
.md-media-dl svg{width:14px;height:14px}
.md-media-dl:hover{background:color-mix(in srgb, var(--primary) 20%, transparent)}

/* 3D 模型卡片 */
.md-media-3d{background:linear-gradient(160deg,rgba(124,77,255,.07),rgba(79,93,255,.05))}
.md-3d-head{display:flex;align-items:center;gap:8px;padding:10px 12px;font-size:.82rem;font-weight:650}
.md-3d-ic{font-size:1.05rem;line-height:1;display:inline-flex;align-items:center}
.md-3d-ic svg{width:17px;height:17px}
.md-3d-title{flex:0 0 auto}
.md-3d-name{
  margin-left:auto;font-family:var(--mono);font-size:.74rem;font-weight:400;
  color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:52%;
}
.md-3d-view{
  margin:0 12px;border-radius:var(--r-s,10px);overflow:hidden;
  background:radial-gradient(circle at 50% 38%,rgba(124,77,255,.14),transparent 68%);
}
.md-3d-fallback{
  padding:38px 16px;text-align:center;font-size:.8rem;line-height:1.7;color:var(--ink-3);
}
.md-3d-fallback svg{width:20px;height:20px;vertical-align:-4px;margin-right:3px}
.md-3d-foot{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:9px 12px;font-size:.76rem;
}
.md-3d-tip{color:var(--ink-3);font-size:.74rem}

/* 移动端：3D 预览高度收窄，避免一屏只能看到一个模型 */
@media (max-width:640px){
  .md-media-3d model-viewer{height:230px!important}
  .md-3d-name{max-width:44%}
  .md-media video{max-height:52vh}
}

/* ==================== v1.33.0 媒体异步任务进度卡片 ====================
   由 common.js 的 mediaTaskCard() 生成，class 前缀 md-media-task / mdt-*。
   占位卡片展示「生成中」状态与进度条，轮询完成后被替换为最终媒体卡片。 */
.md-media-task{
  padding:14px 16px;background:linear-gradient(160deg,rgba(0,180,255,.06),rgba(79,93,255,.05));
}
.mdt-head{display:flex;align-items:center;gap:9px;font-size:.86rem;font-weight:650}
.mdt-ic{font-size:1.15rem;line-height:1;display:inline-flex;align-items:center}
.mdt-ic svg{width:18px;height:18px}
.mdt-title{flex:0 0 auto}
.mdt-state{margin-left:auto;font-size:.78rem;font-weight:550;color:var(--primary)}
.mdt-head.err .mdt-state{color:var(--err)}
.mdt-bar{
  height:7px;margin:12px 0 9px;border-radius:999px;overflow:hidden;
  background:color-mix(in srgb, var(--primary) 12%, transparent);
}
.mdt-fill{
  height:100%;width:0;border-radius:999px;
  background:linear-gradient(90deg,var(--primary),color-mix(in srgb, var(--primary) 55%, #7C4DFF));
  transition:width .5s ease;
}
.mdt-foot{font-size:.76rem;color:var(--ink-3);line-height:1.55}
/* v1.39.0：媒体任务操作按钮（取消 / 失败重试） */
.mdt-foot{display:flex;align-items:center;gap:10px;justify-content:space-between}
.mdt-acts{display:flex;gap:8px;flex:0 0 auto}
.mdt-btn{
  padding:4px 12px;border:1px solid color-mix(in srgb, var(--primary) 35%, transparent);
  border-radius:999px;background:transparent;color:var(--primary);
  font-size:.76rem;font-weight:600;cursor:pointer;line-height:1.5;
  transition:background var(--dur-mid),color var(--dur-mid);
}
.mdt-btn:hover{background:color-mix(in srgb, var(--primary) 10%, transparent)}
.mdt-btn:disabled{opacity:.5;cursor:not-allowed}
.mdt-cancel{color:var(--ink-2);border-color:color-mix(in srgb, var(--ink-2) 35%, transparent)}
.mdt-cancel:hover{background:color-mix(in srgb, var(--ink-2) 8%, transparent)}
.mdt-retry{color:var(--err);border-color:color-mix(in srgb, var(--err) 40%, transparent)}
.mdt-retry:hover{background:color-mix(in srgb, var(--err) 10%, transparent)}
/* v1.61.0：上游故障自动切换提示条（解释「为什么进度没倒退但状态变了」） */
.mdt-reroute{
  flex:1 1 auto;min-width:0;color:var(--warn,#F59E0B);font-weight:550;
  display:inline-flex;align-items:center;gap:5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.mdt-reroute::before{content:'';flex:0 0 auto;width:6px;height:6px;border-radius:50%;background:currentColor;animation:mdt-pulse 1.4s ease-in-out infinite}
@keyframes mdt-pulse{0%,100%{opacity:.35}50%{opacity:1}}

/* v1.56.0 虚拟模型技能标签（弱化描边式 tag，跨站复用） */
.tag.ghost{background:color-mix(in srgb, var(--primary,#4F5DFF) 8%, transparent);color:var(--primary,#4F5DFF);border:1px solid color-mix(in srgb, var(--primary,#4F5DFF) 22%, transparent)}

/* ============================================================
   v1.65.0 统一 kicker 基类
   此前 ad/help/history/kb/seo/earn/idle/service 八处各写一份近似重复的
   「小标签」样式（字号 12 或 11.5、字距 .16em 或 .18em 混用）。
   新页面请直接复用 .kicker；老页面的 .xx-kicker 保持原样不动
   （归零改动面），仅在数值上把 .18em 收敛为 .16em。
   ============================================================ */
.kicker{
  display:inline-block;font-size:12px;font-weight:800;letter-spacing:.16em;
  color:var(--primary);background:rgba(79,93,255,.08);
  border-radius:999px;padding:6px 14px;line-height:1.4;
}

/* ============================================================
   v1.65.0 全站动效降级兜底（prefers-reduced-motion）
   base.css 自身含 7 个 @keyframes 与 .reveal 入场动画，此前完全没有降级处理，
   而 scene/tool/tools/templates 四页各自写过——统一提到基类，一处生效全站。
   对「前庭功能障碍」用户，动画会引发不适，这里把时长压到近乎瞬时即可。
   ============================================================ */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    scroll-behavior:auto !important;
  }
  /* 入场动画直接落到终态，避免「元素停在 opacity:0」导致内容看不见 */
  .reveal{opacity:1 !important;transform:none !important}
}

/* ============================================================
   v1.71.50 全站 LaTeX 公式样式（从 chat.css 上移，跨页面统一）
   场景页/工具箱/历史/工坊等复用 renderMd 的页面也能正确渲染数学公式。
   与 chat.css 的 .msg-bubble .latex 同源，避免「对话页有样式、其他页裸文本」。
   ============================================================ */
.latex{
  font-family:"Cambria Math","STIX Two Math","Times New Roman",Georgia,serif;
  font-style:italic;padding:0 .12em;color:var(--ink);letter-spacing:.01em;
}
.latex-block{
  display:block;text-align:center;margin:.7em 0;padding:.5em .3em;
  background:var(--bg-soft,#f5f6fb);border-radius:10px;overflow-x:auto;
  font-size:1.02em;-webkit-overflow-scrolling:touch;
}

/* ============================================================
   v1.71.59 统一骨架屏 + 加载态组件（P5 前端体验深化）
   ------------------------------------------------------------
   此前骨架屏散落在 scene/tools/checkout 三页、样式口径不一，
   且多数列表页在数据未返回时只有白屏或光秃秃的 spinner。
   这里上提一套全局组件，一处定义、全站复用：

     · .skel          通用骨架块（卡片/列表占位）
     · .skel-line     行级骨架（标题/段落占位，可控制宽度）
     · .skel-avatar   圆形骨架（头像占位）
     · .skel-btn      按钮骨架（操作区占位）
     · .skel-row      列表行骨架容器（flex 布局：头像+文本）
     · .btn.is-loading 按钮加载态（禁用 + 内置 spinner，点击防重）

   无障碍约定：
     · 骨架元素一律 `aria-hidden="true"`（纯装饰，不进读屏流）；
     · 承载骨架的容器加 `role="status" aria-live="polite"`，
       数据就绪替换为真实内容时读屏会自动播报；
     · 加载中的按钮加 `aria-busy="true"`，就绪后移除。

   动效：统一 shimmer（左→右高光扫过），并受全局
   prefers-reduced-motion 兜底自动降级为静态占位。
   ============================================================ */
.skel,.skel-line,.skel-avatar,.skel-btn{
  position:relative;overflow:hidden;border-radius:8px;
  background:#E9EDF8;
}
/* 统一的 shimmer 高光扫过 */
.skel::after,.skel-line::after,.skel-avatar::after,.skel-btn::after{
  content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.75),transparent);
  animation:skelShimmer 1.3s ease-in-out infinite;
}
@keyframes skelShimmer{100%{transform:translateX(100%)}}
/* 通用骨架块 */
.skel{height:96px;width:100%}
/* 行级骨架：默认一条短横线，可内联 width 覆盖 */
.skel-line{height:13px;width:100%;margin:8px 0}
.skel-line.w60{width:60%}.skel-line.w40{width:40%}.skel-line.w80{width:80%}
/* 圆形骨架 */
.skel-avatar{width:40px;height:40px;border-radius:50%;flex:none}
/* 按钮骨架 */
.skel-btn{height:38px;width:96px;border-radius:999px;flex:none}
/* 列表行骨架容器 */
.skel-row{display:flex;align-items:center;gap:12px;padding:12px 14px}
.skel-row .skel-col{flex:1;min-width:0}
/* 按钮加载态：禁用点击 + 内置 spinner，替代「点了没反应」的悬空感 */
.btn.is-loading{position:relative;pointer-events:none;opacity:.78}
.btn.is-loading::before{
  content:"";width:15px;height:15px;margin-right:8px;vertical-align:-2px;
  display:inline-block;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;
  border-radius:50%;animation:spin .7s linear infinite;
}
/* 深色/描边按钮的 spinner 取主色，避免白底白圈看不见 */
.btn.ghost.is-loading::before,.btn.outline.is-loading::before{
  border-color:rgba(79,93,255,.25);border-top-color:var(--primary)
}
/* 骨架屏在 reduced-motion 下退化为静态占位（去掉扫过动画） */
@media (prefers-reduced-motion:reduce){
  .skel::after,.skel-line::after,.skel-avatar::after,.skel-btn::after{animation:none;transform:none;background:none}
}

/* ============================================================
   v1.71.98 全站输出组件（自 chat.css 下沉）
   —— 代码卡 / 表格包裹 / 图片下载 / 语法高亮 token。
   此前这些规则只存在于 chat.css，场景中心/AI超市/工具箱/视觉页
   使用公共 renderMd 输出的同类结构无样式可用（「裸奔」根源）。
   选择器与 chat.css 同名同规则：对话页两文件叠加无副作用（后者覆盖同名），
   其余页面自此获得完整输出体验。
   ============================================================ */
/* 代码卡：语言标签 + 操作（复制/下载/>30 行折叠） */
.code-block{margin:.6em 0}
.code-block pre{margin:0;border-top-left-radius:0;border-top-right-radius:0}
.code-bar{display:flex;align-items:center;justify-content:space-between;background:#1B2050;color:#9AA4E0;
  border-radius:12px 12px 0 0;padding:6px 12px;font-size:.72rem;font-family:var(--mono)}
.code-bar .code-tools{display:flex;gap:6px;align-items:center}
.code-copy,.code-dl,.code-expand{background:rgba(255,255,255,.1);color:#DCE2FF;border:1px solid rgba(255,255,255,.16);
  border-radius:7px;padding:3px 10px;font-size:.72rem;cursor:pointer;transition:background .18s}
.code-copy:hover,.code-dl:hover,.code-expand:hover{background:rgba(255,255,255,.22)}
/* 长代码折叠：默认只显示前 ~22 行，展开后全显，底部渐隐提示还有更多 */
.code-block.collapsed pre{max-height:360px;overflow:hidden;position:relative}
.code-block.collapsed pre::after{content:"";position:absolute;left:0;right:0;bottom:0;height:72px;
  background:linear-gradient(transparent,#101430);pointer-events:none}
/* 语法高亮 token（highlightCode 输出） */
.tok-kw{color:#C792EA;font-weight:600}
.tok-str{color:#C3E88D}
.tok-com{color:#7A85B8;font-style:italic}
.tok-num{color:#F78C6C}
/* 表格：窄屏横向滚动容器 + 全站统一表样（renderMd 输出 .tbl-wrap>.md-table） */
.tbl-wrap{overflow-x:auto;border:1px solid var(--line);border-radius:12px;margin:.6em 0;-webkit-overflow-scrolling:touch}
.md-table{border-collapse:collapse;width:100%;font-size:.86rem;min-width:360px}
.md-table th{background:var(--bg-soft);font-weight:700;text-align:left;padding:9px 13px;white-space:nowrap;color:var(--ink)}
.md-table td{padding:8px 13px;border-top:1px solid var(--line);line-height:1.6}
.md-table tbody tr:nth-child(even){background:rgba(79,93,255,.035)}
.md-table tbody tr:hover{background:rgba(79,93,255,.06)}
/* v1.71.99 表格工具条（renderMd 输出 .tbl-box>.tbl-bar+.tbl-wrap）：复制 CSV/MD · 下载 .csv */
.tbl-box{border:1px solid var(--line);border-radius:12px;margin:.6em 0;overflow:hidden}
.tbl-box .tbl-wrap{border:0;border-radius:0;margin:0}
.tbl-bar{display:flex;align-items:center;gap:8px;padding:6px 10px;background:var(--bg-soft);
  border-bottom:1px solid var(--line);font-size:.75rem;color:var(--ink-3)}
.tbl-bar-name{display:inline-flex;align-items:center;gap:5px;font-weight:600}
.tbl-bar-name svg{color:var(--brand)}
.tbl-bar-tools{margin-left:auto;display:inline-flex;gap:6px;flex-wrap:wrap}
.tbl-act{border:1px solid var(--line);background:var(--bg);color:var(--ink-2);border-radius:8px;
  padding:3px 9px;font-size:.72rem;cursor:pointer;transition:all .18s;line-height:1.5}
.tbl-act:hover{border-color:var(--brand);color:var(--brand)}
/* 图片：悬停/触屏显示右上角下载钮 */
.img-wrap{position:relative;display:inline-block;max-width:100%;margin:6px 0}
.img-wrap .md-img{margin:0}
img.md-img{max-width:100%;border-radius:12px;margin:6px 0;display:block}
.img-dl{position:absolute;top:8px;right:8px;width:28px;height:28px;border-radius:9px;background:rgba(15,23,42,.55);
  backdrop-filter:blur(4px);color:#fff;display:none;align-items:center;justify-content:center;transition:background .18s}
.img-wrap:hover .img-dl,.img-wrap:active .img-dl{display:flex}
.img-dl:hover{background:rgba(79,93,255,.9)}
.md-img.img-err{min-height:110px;width:100%;background:var(--bg-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='46' height='46' viewBox='0 0 24 24' fill='none' stroke='%23A6ACCB' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='3' width='18' height='18' rx='3'/%3E%3Ccircle cx='9' cy='9' r='2'/%3E%3Cpath d='m21 15-4.5-4.5L8 19'/%3E%3C/svg%3E") center/46px no-repeat;border-radius:12px}
.img-wrap:has(.img-err) .img-dl{display:none}

/* v1.71.98 深度思考卡（自 chat.css 下沉）：场景中心/AI超市接入 reasoning 事件后同样式呈现 */
.reasoning-box{border:1px solid rgba(79,93,255,.18);background:rgba(79,93,255,.05);border-radius:12px;margin:0 0 10px;overflow:hidden}
.reasoning-head{display:flex;align-items:center;gap:7px;padding:9px 13px;cursor:pointer;user-select:none;color:var(--primary);font-size:.82rem;font-weight:600}
.reasoning-head svg{flex:none}
.reasoning-head .reasoning-toggle{margin-left:auto;font-size:.72rem;color:var(--ink-3);font-weight:500}
.reasoning-head .reasoning-toggle::after{content:'收起'}
.reasoning-box.collapsed .reasoning-toggle::after{content:'展开'}
.reasoning-body{padding:2px 13px 12px;color:var(--ink-2);font-size:.86rem;line-height:1.7;border-top:1px dashed rgba(79,93,255,.15);white-space:pre-wrap;word-break:break-word}
.reasoning-box.collapsed .reasoning-body{display:none}
