/* ================================================================
   LuneMind 全站共享基础层 · site.css
   ---------------------------------------------------------------
   作用：统一「页面外壳」——设计令牌、响应式 Header、活跃导航、
        焦点可见、可读对比度、容器宽度、可访问性。
   载入位置：必须在每个页面内联 <style> 之后引入，
        这样同等特异度下本文件的规则优先生效（后加载者胜）。
   注意：本文件不定义任何页面业务样式，只管外壳与通用规范。

   ── 2026-09-12 改版要点 ──
   1) 全站唯一容器 --cw-page：header / 正文 / 页脚共用同一条左对齐线。
      此前 nav 用 1200、数据页 1120、资讯页 880、首页 960 四套宽度并存，
      同一视口下正文左边缘出现 120/208/288/328 四种值（实测极差 208px），
      这正是「头部与内容对不齐」的根因。改为单一容器后极差为 0。
   2) Header 由 space-between 改为三轨网格：Logo 左、导航组真正居中、
      汉堡/头像靠右。此前导航组被推到右侧，与 Logo 之间空出 500px+。
   3) 首屏 hero 不再参与滚动动画：.reveal 初始 opacity:0 + 下移 20px，
      会让首屏空白最长 3 秒并造成实际间距偏移 20px。
   ================================================================ */

/* ---------- 1. 设计令牌（覆盖各页面内联的默认值，统一口径） ---------- */
:root{
  /* ★ 基础表面与文字色：全站唯一真源（2026-10-07 收敛）。
     这 8 个变量此前 site.css **一个都没有**，于是 9 个文件各自 `:root` 写了一遍
     （about / methodology / models / news / predict / sources / track-record /
       profile / tools-ui.css），8 处值完全相同、纯重复。
     它们是全站出现最多的颜色，不该由每个页面各自声明。
     ★ 为什么之前没被 site.css 顶掉：不是层叠顺序问题（`<link site.css>` 确实在
       内联 `<style>` 之后加载），而是 site.css 压根没定义这几个名字 ——
       「没定义」不是「被覆盖」，两者要分清。
     login.html 是**唯一例外**：它是暗色主题（--text:#e8e2d6 / --text2:#9a948a），
       必须保留自己的定义，见该文件内的说明。 */
  --bg:#fafaf8;      /* 页面底色（米白） */
  --bg2:#f4f4f1;     /* 次级表面（卡片内区块、输入框） */
  --bg3:#eeeee9;     /* 三级表面（更深一层的分隔） */
  --line:rgba(20,20,20,.10);   /* 常规描边：原 .08 在米白底上几乎看不见，卡片像没有轮廓 */
  --line2:rgba(20,20,20,.15);  /* 强调描边 */
  --text:#1a1a1a;    /* 主文字   15.9:1 on --bg */
  /* ★ 2026-10-17 用户实测：「有的文本很浅，看不清楚，更不想阅读」。
     合规只是下限（AA=4.5:1），**观感**是另一回事：12–13px 的小字配 #555，
     在米白底上虽然「合法」，但细笔画已经发虚。整体压深一档：
       #333(10.9:1) → #2d2d2d(11.9:1)   次级：正文说明、表格内容
       #555( 7.1:1) → #4a4a4a( 8.8:1)   辅助：单位、时间、脚注、标签
     仍保持与主文字(#1a1a1a)的三级层次，不是把所有字糊成一样黑。 */
  --text2:#2d2d2d;   /* 次级文字 11.9:1 */
  --text3:#4a4a4a;   /* 辅助文字  8.8:1 */

  /* 文字用金：#9a7d3c 在米白底上对比度仅 3.7:1，不达标 → 加深为棕金。
     ★ 2026-10-17 再压深一档：#7d6224 实测 5.23:1（**合规但偏淡**）——
     而全站有 475 处金色文字（徽章/标签/链接/单位），它们是用户所说
     「有的文本很浅、看不清」贡献最大的一类。压到 #70571d = 6.84:1，
     仍是可辨认的棕金（未变成棕色），白字压在这块金上对比也更足。 */
  --gold:#70571d;
  /* 装饰用金（线条、图标、徽章描边）保留原色，不参与正文对比度判定 */
  --gold-decor:#9a7d3c;
  --gold-dim:rgba(125,98,36,0.10);
  --gold-dim-strong:rgba(125,98,36,0.16);

  /* ── 弹层专用令牌（账户下拉，以及后续的悬浮面板/气泡）──
     为什么不能直接用 --bg：--bg 是「页面背景」语义，每个页面按自己的主题定义它。
     首页把 --bg 定义成夜空黑 #08080a（hero 用），于是展开后的浅色页面上，
     账户下拉渲染成一块黑底面板（2026-09-13 用户截图）。
     弹层是浮在内容之上的独立表面：它的底色应当跟随「它所在的表面」，
     所以这里给一组独立令牌，默认取浅色（全站绝大多数页面是浅色），
     深色页面/深色状态在各自页面里显式覆盖。 */
  --pop-bg:#ffffff;
  --pop-line:rgba(20,20,20,0.12);
  --pop-text:#3a3a3a;
  --pop-text-strong:#1a1a1a;
  --pop-text-dim:#4a4a4a;   /* 2026-10-17 与 --text3 对齐（弹层里的说明/占位原来偏浅） */
  --pop-gold:#7d6224;
  --pop-hover:rgba(125,98,36,0.10);
  --pop-shadow:var(--shadow-2);   /* 统一暖黑双层（原为单层纯黑，发灰） */
  /* 浅色毛玻璃材质（纸感转译）：白雾而非黑玻璃。仅轻弹层（下拉/气泡）使用，
     模态与深色场景保持实底。@supports 不满足时回退 --pop-bg 实底。 */
  --pop-bg-glass:rgba(255,255,255,.86);
  --pop-blur:blur(16px) saturate(1.15);

  /* ── 头部控件令牌（账户胶囊）──
     与 --pop-* 同一个道理：账户胶囊坐在「导航栏」上，而导航栏的主题由
     **它背后的表面**决定，不由页面主题决定。
     曾用 var(--text)：首页 :root 的 --text 是夜空 hero 用的浅象牙 #e8e2d6，
     但首页展开后导航栏变成浅色实底（.nav.solid），浅字压浅底 →
     对比度 1.24:1，肉眼就是「文字虚化、糊了」（2026-09-13 用户截图）。
     这里给胶囊一组独立令牌，默认取浅色页面值（全站绝大多数页面成立），
     深色导航在各自页面里显式覆盖 —— 与 --pop-* 完全同一模式，
     新增头部控件一律引用这组令牌，不得再读 --text/--line2。 */
  --chip-text:#1a1a1a;
  --chip-line:rgba(20,20,20,0.14);
  --chip-gold:#7d6224;
  --chip-gold-dim:rgba(125,98,36,0.10);
  --chip-gold-line:rgba(125,98,36,0.28);
  --chip-hover-bg:rgba(125,98,36,0.10);

  /* ── 容器：全站只有这一条对齐线 ──
     header 的内容、正文的左边缘、页脚的第一列，全部落在同一条竖线上。
     任何新的横向区块都必须复用 --cw-page，不要再引入第二套宽度。 */
  --cw-page:1120px;
  --gutter:24px;          /* 小屏最小安全边距 */
  --nav-h:60px;           /* 固定导航高度（供各页计算 padding-top） */
  /* ── 页内目录（左侧竖排轨）的两个尺寸令牌 ──
     2026-10-17：首页与预测页的目录本来是两份 CSS，各写了一个数（150/172），
     于是同一站里两张页面的栏宽、行距、当前态全不一样（用户截图「这俩对不上」）。
     现在栏宽与它到正文的间隙只在这里定义一次；正文让位量 = 两者之和，
     由各页用 calc() 拼出来，**不允许再出现 150 / 166 / 172 / 196 这类字面量**。 */
  --toc-w:172px;          /* 竖排轨宽度（三字标题 + 十二字标签都放得下） */
  --toc-gap:24px;         /* 轨右缘到正文左缘的间隙 */
  /* 小屏导航是 52px（见各页 @media max-width:768px 里的 .nav{height:52px}）。
     下面这档把「导航高 + 页头上方留白」固化成两个语义值，
     各页的 .page-header padding-top 引用它们 —— 数值与改动前逐个一致
     （桌面 90/100/104px、小屏 90/100px 保持原样），只是把「为什么是这个数」
     从魔法数字变成「导航高 + 额外呼吸」的可读表达式。
     ⚠ 小屏那档必须与 768px 断点里的 .nav{height} 同步改，两者是同一个量。 */
  --nav-h-sm:52px;

  /* ── 字体统一（2026-09-27 v7，用户原话：「文字字体不一，不要搞各种字体、艺术体」）──
     根因：各页 :root 各自定义了三套字体 ——
       --serif = 'Cormorant Garamond','Noto Serif SC',Georgia,serif
       --mono  = 'JetBrains Mono','SF Mono',monospace
     用户机器上这些字体统统没装，于是回退成：页面大标题 → 宋体（serif 兜底）、
     日期数字 → Consolas（monospace 兜底）、正文 → 微软雅黑。一屏三套字体，
     这正是「艺术体」「字体不一」的来源。
     改法：**在令牌源头收敛**。本文件在每个页面内联 <style> 之后加载，
     同名变量此处覆盖即全站生效，各页引用点（var(--serif)/var(--mono)）零改动。
     变量名保留 —— 它们现在是「语义槽位」而不是「字体差异」：
       --serif 语义降级为标题字重场景，与正文同族；
       --mono 语义保留给数字/日期，用 tabular-nums 保证等宽对齐（见下方规则）。 */
  --sans:system-ui,-apple-system,'Segoe UI','PingFang SC','Hiragino Sans GB','Microsoft YaHei',sans-serif;
  --serif:var(--sans);
  --mono:var(--sans);
}
/* 消费 --mono 的数字场景：中文字体的 ASCII 数字多为比例宽度，
   等宽对齐改由 font-variant-nums 承担（原本是靠 monospace 字体隐式获得的）。 */
.news-date,.news-src-name,.m-mv,.m-price-unit,.r-num,.r-score,.kpi-num,.funnel-val,.stat-num,.tl-date,.confidence-badge{
  font-variant-numeric:tabular-nums;
}

/* 统一的流式内边距：宽度足够时居中留白，窄屏时退化为 gutter。
   用 padding 而不是 max-width + margin:auto，是为了避免
   「max-width 与 padding 叠加」导致内容区比预期窄 96px。 */
.nav,
.page-header,
.section,
.footer,
.data-band{
  padding-left:max(var(--gutter), calc((100% - var(--cw-page)) / 2));
  padding-right:max(var(--gutter), calc((100% - var(--cw-page)) / 2));
}

/* 旧的 max-width / margin:auto 一律失效，避免与上面的流式内边距打架 */
.page-header,
.section,
body.page-data .page-header,
body.page-data .section{
  max-width:none;
  margin-left:0;
  margin-right:0;
}
/* 正文段落仍限制行长，保证可读性（约 40 个汉字/行） */
.page-header p,
body.page-data .page-header p{max-width:660px}

/* ---------- 2. 可访问性基础 ---------- */

/* 跳转到主内容：键盘用户第一个可聚焦元素 */
.skip-link{
  position:fixed;left:16px;top:-80px;z-index:3000;
  background:#1f1a28;color:#fafaf8;text-decoration:none;
  padding:var(--sp-2) 20px;border-radius:0 0 10px 10px;
  font-size:var(--fs-note);font-weight:600;letter-spacing:1px;
  transition:top .18s ease;
}
.skip-link:focus,.skip-link:focus-visible{top:0;outline:2px solid var(--gold);outline-offset:2px}

/* 全站统一焦点框：任何可交互元素键盘聚焦时必须可见 */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible{
  outline:2px solid var(--gold);
  outline-offset:2px;
  border-radius:4px;
}
/* 鼠标点击不出现焦点框，但键盘一定出现 */
a:focus:not(:focus-visible),
button:focus:not(:focus-visible){outline:none}

/* 尊重「减少动态效果」系统设置 */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    scroll-behavior:auto !important;
  }
}

/* ---------- 3. 首屏不得等待滚动动画 ---------- */
/* .reveal 的初始态是 opacity:0 + translateY(20px)。放在首屏会造成：
   ① 页面首屏空白（最长等 3 秒兜底计时器）② 内容实际位置比设计位置低 20px，
   滚动前后跳动。因此 hero 直接以最终状态渲染；下方的滚动动画保持不变。 */
.page-header.reveal,
.reveal.is-first-screen{
  opacity:1 !important;
  transform:none !important;
}

/* ---------- 4. 响应式 Header ---------- */
/* 三轨网格：左轨与右轨等宽（1fr），中轨按内容自适应，
   因此导航组在数学上位于容器正中，与 Logo 的视觉重量平衡。 */
.nav{
  display:grid;
  grid-template-columns:1fr auto 1fr;
  align-items:center;
}
.nav-brand{grid-column:1;justify-self:start;flex:0 0 auto;min-width:0;
  display:flex;align-items:center;gap:var(--sp-2);text-decoration:none;cursor:pointer;
  /* 2026-10-17：logo 只有 22px 高，手机上是块「看起来能点、其实很难点中」的区域。
     上下补 12px 内边距把热区做到 46px，视觉位置一个像素不动。 */
  padding:var(--sp-3) 0}
/* 品牌字与月牙真源（2026-10-11 R4）：此前 14 个页面各带一份 .nav-brand 内联规则、
   月牙描边硬编码出 5 种颜色（#a8884a×10 / #c2a878 / #9a7d3c / #1a1a1a×2 —— 两页月牙是黑的），
   首页品牌字还是斜体 —— 9-27「不要搞各种字体、艺术体」裁决的漏网残留。
   现在全站一处定义：正体 700；月牙色走各页 --gold 令牌
   （首页深底浅金 / 子页浅底深金自动成立；CSS 规则优先于 SVG presentation attribute）。
   首页因品牌字压在夜空 hero 上，仅在本页内联保留 color 覆盖（--ltext）。 */
.nav-brand svg{width:18px;height:18px;flex:0 0 auto}
.nav-brand svg path{stroke:var(--gold)}
.nav-brand span{white-space:nowrap;font-size:var(--fs-lead);font-weight:700;color:var(--text);letter-spacing:.5px}
.nav-items{grid-column:2;justify-self:center;min-width:0}
/* 右轨：账户入口 + 汉堡按钮。左右两轨同为 1fr，中轨因此真正居中。
   2026-09-12 修：账户区此前是 .nav-items（中轨）的最后一个子元素，
   34px 头像 + 8px 间距把 6 个文字导航整体向左推了约 21px ——
   这就是「导航看着重心不在中间」的根因。现移入独立右轨。 */
.nav-actions{grid-column:3;justify-self:end;display:flex;align-items:center;gap:var(--sp-45);min-width:0}   /* V20：12px 仍偏挤（用户二轮反馈「搜索框和账户控件距离太近」），改 20px（--sp-45） */

/* ── V17 导航基础样式（唯一真源）─────────────────────────────────────────
   历史原因：.nav / .nav-item 的基础样式一直散在各页面自己的 <style> 里，
   2026-10-14 新增的四个页面（compare / model-event / dashboard / share-growth）
   复用了 nav 的 HTML 却没带样式 → 导航链接露出浏览器默认下划线、无间距字色
   （2026-10-14 用户实测截图）。把基础规则提升到这里：
   · 新页面天然生效；
   · 旧页面仍有本地副本，规则同值 —— 页面 <style> 在 site.css 之后加载，
     同特异度下副本胜出，值相同故视觉零变化（渐进收敛，不一次动 20+ 页）。 */
/* ★ 作用域 .page-data：首页（hero 页，无该类）的 .nav 是 position:sticky 且
   其 site.css 引用在页面 <style> 之后 —— 不加作用域会把首页导航拽成 fixed
   顶到视口（ui-batch-f「导航在折叠线下」断言实测抓到）。数据页 body 都带
   .page-data，规则只服务它们与四个新页。 */
.page-data .nav{position:fixed;top:0;left:0;right:0;z-index:100;height:60px;background:rgba(250,250,248,0.92);backdrop-filter:blur(20px);border-bottom:1px solid var(--line)}
/* ★ V20 关键修复（2026-10-15）：上面这行原本写死 `padding:0 48px`，特异性 (0,2,0)
   高于本文件 §nav 的全站流式内边距规则
   `.nav{padding-left/right:max(var(--gutter), calc((100% - var(--cw-page)) / 2))}`
   （--cw-page:1120px）—— 结果把 6 个 body.page-data 页面的导航内容盒从 1120px
   撑到 1344px：**窗口越宽、「最后一个导航项 ↔ 搜索按钮」的空隙越大**，
   而且导航与页面正文（.section 仍是 1120px 居中列）左边缘错位。
   直连线上逐页实测（1440 宽）：10 个非 page-data 页 = 内容盒 1120px / 空隙 154–162px；
   6 个 page-data 页（models、predict、compare、dashboard、model-event、share-growth）
   = 1344px / 264–266px，1860 宽时空隙涨到 476px。用户三轮反馈的「模型和预测页
   搜索图标离得很远」即此。删掉 padding 声明即回到与全站一致的流式内边距（窄屏自动
   退化为 --gutter，与 .section/.footer 同步）。 */
/* ★ V19 不加 display:flex —— 导航是 grid 三列（.nav{display:grid;grid-template-columns:1fr auto 1fr}，见本文件 §nav）：nav-items 靠 grid-column:2 + justify-self:center 严格居中、nav-actions 靠 grid-column:3 + justify-self:end 贴右。V17 我给 page-data 页加 display:flex 后这些 grid 属性全部失效，布局退化成 flex space-between —— 实测「最后导航项↔搜索按钮」间距 187px vs news 页 166px、items 宽度差 15px（2026-10-14 用户截图对比 + 本地量测证据），导航视觉不统一。回到 grid 即天然一致。 */
.page-data .nav-items{display:flex;gap:4px}
.page-data .nav-item{padding:8px var(--sp-45);font-size:var(--fs-body);font-weight:600;letter-spacing:3px;color:var(--text2);text-decoration:none;transition:background-color .3s,color .3s,border-color .3s,box-shadow .3s,transform .3s,opacity .3s,fill .3s,stroke .3s;cursor:pointer;}
.page-data .nav-item:hover{color:var(--gold);opacity:1}
.page-data .nav-item.active{color:var(--gold);opacity:1}   /* V17：sp-1(4px) 太挤——搜索按钮与账户胶囊几乎贴上（2026-10-14 用户实测） */
.nav-menu-btn{grid-column:auto;justify-self:auto}

/* ── V14.3 全局搜索按钮（导航右轨，账户入口左侧）─────────────────────────
   与汉堡按钮同一条纪律：只读 --chip-*（导航栏控件配色跟导航栏走，
   不跟页面主题走）。桌面常显；窄屏由媒体查询决定显隐（见下方）。 */
.nav-search-btn{
  display:flex;align-items:center;justify-content:center;
  width:44px;height:44px;flex:0 0 44px;
  border:1px solid var(--chip-line);border-radius:10px;
  background:transparent;color:var(--chip-text);cursor:pointer;
  transition:border-color .2s,color .2s;
}
.nav-search-btn:hover{border-color:var(--gold);color:var(--gold)}
.nav-search-btn svg{width:18px;height:18px}
.nav-search-btn kbd{
  display:none;   /* 桌面显示快捷键提示由面板底部承载，按钮上不放，避免右轨拥挤 */
}
@media(max-width:1080px){
  .nav-search-btn kbd{display:none}
}
/* ═══ V14.3 搜索面板（全站一份，由 site.js 注入 body）═══ */
.lm-search-overlay{
  position:fixed;inset:0;z-index:400;
  background:color-mix(in srgb, var(--pop-bg) 55%, transparent);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  display:flex;align-items:flex-start;justify-content:center;
  padding:max(12vh,60px) var(--sp-4) var(--sp-4);
}
.lm-search-overlay[hidden]{display:none}
.lm-search-panel{
  width:min(640px,100%);max-height:min(70vh,640px);
  display:flex;flex-direction:column;
  background:var(--pop-bg);border:1px solid var(--pop-line);border-radius:16px;
  box-shadow:var(--pop-shadow);overflow:hidden;
}
.lm-search-head{
  display:flex;align-items:center;gap:var(--sp-3);
  padding:var(--sp-4) var(--sp-4) var(--sp-3);
  border-bottom:1px solid var(--pop-line);
}
.lm-search-head svg{width:20px;height:20px;color:var(--pop-text-dim);flex:0 0 auto}
.lm-search-input{
  flex:1;min-width:0;border:none;outline:none;background:transparent;
  font-size:var(--fs-sub);color:var(--pop-text-strong);
}
.lm-search-input::placeholder{color:var(--pop-text-dim)}
.lm-search-esc{
  font-family:var(--mono);font-size:var(--fs-micro);color:var(--pop-text-dim);
  border:1px solid var(--pop-line);border-radius:6px;padding:2px 8px;flex:0 0 auto;
}
.lm-search-list{flex:1;overflow-y:auto;padding:var(--sp-2)}
.lm-search-state{
  padding:var(--sp-6) var(--sp-4);text-align:center;
  color:var(--pop-text-dim);font-size:var(--fs-note);line-height:1.7;
}
.lm-search-group{
  display:flex;align-items:baseline;gap:var(--sp-2);
  padding:var(--sp-2) var(--sp-3) var(--sp-1);
  font-size:var(--fs-micro);font-weight:700;letter-spacing:1px;color:var(--gold);
}
.lm-search-src{font-weight:400;letter-spacing:0;color:var(--pop-text-dim)}
.lm-search-item{
  display:grid;grid-template-columns:1fr auto;gap:2px var(--sp-3);
  padding:var(--sp-2) var(--sp-3);border-radius:10px;
  text-decoration:none;color:inherit;
}
.lm-search-item.on{background:var(--surface2,rgba(20,20,20,.05))}
.lm-search-item:hover{background:var(--surface2,rgba(20,20,20,.05))}
.lm-search-t{font-size:var(--fs-note);font-weight:600;color:var(--pop-text-strong);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lm-search-s{grid-column:1;font-size:var(--fs-micro);color:var(--pop-text-dim);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lm-search-d{grid-row:1/3;grid-column:2;align-self:center;
  font-family:var(--mono);font-size:var(--fs-micro);color:var(--pop-text-dim);
  font-variant-numeric:tabular-nums}
.lm-search-foot{
  padding:var(--sp-2) var(--sp-4);border-top:1px solid var(--pop-line);
  font-size:var(--fs-micro);color:var(--pop-text-dim);
  display:flex;justify-content:space-between;gap:var(--sp-3);flex-wrap:wrap;
}
@media(prefers-reduced-motion:reduce){.nav-search-btn{transition:none}}

/* 汉堡按钮（由 site.js 注入，默认桌面隐藏）
   同样只读 --chip-*：它是导航栏上的控件，配色跟着导航栏走，
   不能跟着页面主题走（首页 --text 是夜空 hero 的浅象牙）。 */
.nav-menu-btn{
  display:none;
  align-items:center;justify-content:center;
  width:44px;height:44px;flex:0 0 44px;
  border:1px solid var(--chip-line);border-radius:10px;
  background:transparent;color:var(--chip-text);cursor:pointer;
  transition:background .2s,border-color .2s;
}
.nav-menu-btn:hover{background:var(--chip-hover-bg);border-color:var(--chip-gold)}
.nav-menu-btn svg{width:20px;height:20px;stroke:currentColor}

/* 桌面宽屏：保持原有宽松间距 */
@media (min-width:1201px){
  .nav-item{padding:8px 20px !important;letter-spacing:2px;font-size:var(--fs-body)}
}
/* 1024～1200：收紧间距，防止溢出 */
@media (max-width:1200px){
  .nav-item{padding:8px var(--sp-3) !important;letter-spacing:1.5px;font-size:var(--fs-body)}
  :root{--cw-page:100%}
}
/* 900～1024：进一步收紧 */
@media (max-width:1024px){
  .nav-item{padding:8px var(--sp-2) !important;letter-spacing:.5px;font-size:var(--fs-note)}
}
/* ≤900：折叠为汉堡菜单（只隐藏链接，保留用户头像入口） */
@media (max-width:900px){
  .nav .nav-item{display:none}
  .nav-menu-btn{display:flex}
  /* 链接隐藏后，头像与汉堡按钮一起靠右，避免头像孤零零居中 */
  .nav-items{justify-self:end}
}
/* ≤768：进一步压缩外壳与主体内边距 */
@media (max-width:768px){
  .nav{height:54px}
  .nav-brand span{font-size:var(--fs-body)}
  :root{--gutter:18px}
}

/* ---------- 5. 移动端抽屉菜单（由 site.js 注入） ----------
   抽屉是**浮在全屏之上的独立表面**（position:fixed;inset:0），按红线 17
   必须用弹层令牌 --pop-*，不得读页面级 --bg/--line/--text ——
   --bg 是「页面背景」语义：首页把它定义成夜空黑 #08080a，
   会在浅色内容区弹出一块黑抽屉；而 discover-ai.html 根本没有 --text，
   那里的抽屉链接会退化成「深字压深底」（不可读）。
   改用 --pop-* 后：浅色页得浅抽屉，深色页得深抽屉，自动成立。 */
.nav-drawer{
  position:fixed;inset:0;z-index:2000;
  background:rgba(20,18,24,.42);
  backdrop-filter:blur(2px);
  opacity:0;visibility:hidden;transition:opacity .22s ease,visibility .22s;
}
.nav-drawer.open{opacity:1;visibility:visible}
.nav-drawer-panel{
  position:absolute;top:0;right:0;bottom:0;
  width:min(84vw,320px);background:var(--pop-bg);
  border-left:1px solid var(--pop-line);
  padding:var(--sp-45) var(--sp-45) 32px;overflow-y:auto;
  transform:translateX(100%);transition:transform .26s cubic-bezier(.22,.7,.3,1);
  box-shadow:-8px 0 32px rgba(0,0,0,.24);
}
.nav-drawer.open .nav-drawer-panel{transform:translateX(0)}
.nav-drawer-head{
  display:flex;align-items:center;justify-content:space-between;
  margin-bottom:var(--sp-4);padding-bottom:var(--sp-3);border-bottom:1px solid var(--pop-line);
}
.nav-drawer-head strong{font-size:var(--fs-lead);letter-spacing:1px;color:var(--pop-text-strong)}
.nav-drawer-close{
  width:40px;height:40px;display:flex;align-items:center;justify-content:center;
  border:1px solid var(--pop-line);border-radius:9px;background:transparent;
  cursor:pointer;font-size:var(--fs-lead);color:var(--pop-text);
}
.nav-drawer-links{display:flex;flex-direction:column;gap:2px;margin-bottom:var(--sp-45)}
.nav-drawer-links a{
  display:flex;align-items:center;justify-content:space-between;
  padding:var(--sp-3) 12px;border-radius:9px;text-decoration:none;
  color:var(--pop-text);font-size:var(--fs-body);font-weight:600;letter-spacing:1px;
  min-height:44px;transition:background .2s,color .2s;
}
.nav-drawer-links a:hover{background:var(--pop-hover)}
.nav-drawer-links a[aria-current="page"]{color:var(--pop-gold);background:var(--pop-hover)}
.nav-drawer-sep{height:1px;background:var(--pop-line);margin:16px 0}
.nav-drawer-group-label{
  font-size:var(--fs-micro);letter-spacing:2px;color:var(--pop-text-dim);
  text-transform:uppercase;margin-bottom:8px;padding-left:12px;
}
.nav-drawer-legal{display:flex;flex-direction:column;gap:2px}
.nav-drawer-legal a{
  padding:var(--sp-2) 12px;border-radius:8px;text-decoration:none;
  color:var(--pop-text-dim);font-size:var(--fs-note);min-height:40px;display:flex;align-items:center;
}
.nav-drawer-legal a:hover{background:var(--pop-hover);color:var(--pop-text)}

/* ---------- 6. 活跃导航：颜色 + 底色 + 下划线，三重区分 ---------- */
.nav-item.active{
  color:var(--gold) !important;
  opacity:1 !important;
  font-weight:700;
  background:var(--gold-dim);
  border-radius:8px;
  box-shadow:inset 0 -2px 0 var(--gold);
}

/* ---------- 7. 页脚：与正文同一条对齐线 ---------- */
@media (max-width:768px){
  .footer-main-links,.footer-legal-links{gap:var(--sp-3) var(--sp-4) !important}
}
.footer-main-links a,.footer-legal-links a{
  display:inline-flex;align-items:center;min-height:32px;
}

/* ---------- 8. 辅助文字最小字号与点击区 ---------- */
/* 正文不低于 15px（页面基准），辅助说明不低于 13px */
.footer-icp,.footer-copyright,.m-released,.rank-help{font-size:var(--fs-micro)}

/* 通用：小徽章/标签统一可核验感的排版基线 */
.lm-tag{
  display:inline-flex;align-items:center;gap:4px;
  font-size:var(--fs-micro);letter-spacing:.5px;padding:2px 8px;border-radius:6px;
  border:1px solid var(--line2);color:var(--text3);background:var(--bg2);
  white-space:nowrap;
}

/* ---------- 9. 名称可核验徽章：三态语义 ---------- */
/* api      —— 本次在线匹配到接口 ID，名称可回溯（绿）
   baseline —— 基线收录，来自最近一次成功的在线核验（中性，不制造焦虑）
   seed     —— 仅有本地收录、无在线来源（琥珀，提示需以官方公告为准） */
.m-name-badge.baseline{color:var(--text3);background:var(--bg2);border:1px solid var(--line2)}

/* ---------- 10. 账户区（导航右轨，2026-09-12 重做） ---------- */
/* 改版前的问题（用户反馈「个人的那个图标很突兀，放在旁边很不搭」）：
   ① 形态：全站唯一的实心金圆（#9a7d3c + 白字），周围全是描边/幽灵态元素，
      视觉重量失衡，看着像多出来的第 7 个导航项；
   ② 几何：塞在中轨里把导航组整体推离中心（见 .nav-actions 注释）；
   ③ 配色：下拉面板硬编码 #fff/#555/#333，hover 变红 #e74c3c，与全站金色体系冲突。
   现在：账户入口是「头像 + 用户名 + 箭头」的浅描边胶囊，语言与导航一致；
   下拉改用主题变量与金色 hover；保留原有全部 id，认证逻辑无需重写。
    注意：≤900px 只隐藏 .nav-item，本区块必须保留 —— 整块隐藏会让用户在
   所有窄屏设备上失去登录入口。
   配色：只读 --chip-* 头部控件令牌（默认浅色）。**不得**读页面级
   --text/--line2/--gold —— 首页那两个变量是给夜空 hero 用的浅色值，
   导航栏在展开态是浅色实底，会导致文字整片糊掉（2026-09-13）。 */
.user-avatar-wrap{position:relative;min-width:0}

/* 账户按钮：默认只有 1px 描边；hover 或展开时才上金色 */
.user-btn{
  display:inline-flex;align-items:center;gap:8px;
  height:38px;max-width:200px;padding:0 12px 0 var(--sp-1);
  border:1px solid var(--chip-line);border-radius:999px;
  background:transparent;color:var(--chip-text);
  font-family:var(--sans);font-size:var(--fs-note);font-weight:600;letter-spacing:.5px;
  cursor:pointer;user-select:none;
  text-decoration:none;   /* 公开页（about / sources）用的是 <a> 版本 */
  transition:border-color .2s,background .2s,color .2s;
}
.user-btn:hover,
.user-btn[aria-expanded="true"]{border-color:var(--chip-gold);background:var(--chip-hover-bg);color:var(--chip-gold)}

/* 头像：实心金 → 浅底 + 同色系描边，视觉重量降下来，不再抢导航 */
.user-avatar{
  flex:0 0 26px;width:26px;height:26px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--chip-gold-dim);color:var(--chip-gold);
  border:1px solid var(--chip-gold-line);
  font-size:var(--fs-micro);font-weight:700;line-height:1;
}
.user-avatar svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:1.7}
.user-btn-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:104px}
.user-btn-caret{
  flex:0 0 10px;width:10px;height:10px;
  stroke:currentColor;fill:none;stroke-width:2;opacity:.6;
  transition:transform .2s;
}
.user-btn[aria-expanded="true"] .user-btn-caret{transform:rotate(180deg)}

/* ≤1200px：导航已开始收紧，账户按钮退化为纯图标（保持 38px 可点区域），
   避免与 6 个导航项争抢宽度 */
@media (max-width:1200px){
  .user-btn{width:38px;padding:0;justify-content:center}
  .user-btn-name,.user-btn-caret{display:none}
}

/* 下拉面板：弹层令牌 + 金色 hover，带小箭头与展开动画 */
.user-dropdown{
  position:absolute;top:calc(100% + 10px);right:0;z-index:220;
  min-width:200px;padding:var(--sp-1);
  background:var(--pop-bg);border:1px solid var(--pop-line);border-radius:var(--r-card);
  box-shadow:var(--pop-shadow);
  transform-origin:top right;
  opacity:0;visibility:hidden;transform:translateY(-6px) scale(.98);
  pointer-events:none;
  transition:opacity .18s ease,transform .18s ease,visibility .18s;
}
.user-dropdown::before{
  content:"";position:absolute;top:-5px;right:20px;width:9px;height:9px;
  background:var(--pop-bg);border-left:1px solid var(--pop-line);border-top:1px solid var(--pop-line);
  transform:rotate(45deg);
}
/* 浅色毛玻璃（不支持 backdrop-filter 的浏览器回退上方实底 --pop-bg）：
   面板与指示小箭头必须同材质，否则实底箭头会从毛玻璃面板上「掉下来」。 */
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))) {
  .user-dropdown{
    background:var(--pop-bg-glass);
    -webkit-backdrop-filter:var(--pop-blur);
    backdrop-filter:var(--pop-blur);
  }
  .user-dropdown::before{background:var(--pop-bg-glass)}
}
.user-dropdown.open{opacity:1;visibility:visible;transform:none;pointer-events:auto}
/* 用户名已在胶囊上显示，这里只放身份标记（管理员/称号），无标记时整行隐藏 */
/* ★ 弹层的排版必须由弹层自己声明，不得继承页面 body ——
   与 --pop-* / --chip-* 同一个道理：弹层是浮在内容之上的独立表面，
   它的字体规格不该随「它盖住的那一页」变。
   2026-09-14 用户截图：首页账户下拉的文字比别的页面细一号。真机实测（Chromium）：
     首页        body{font-weight:300}          → 下拉条目 300 / .user-info 行高 normal
     资讯/模型等  body{font-weight:500;lh:1.7}   → 下拉条目 500 / 行高 21.2px
     AI 指南      body{font-weight:400}          → 下拉条目 400
   三个页面三种字重 —— 因为旧写法把 font-weight / line-height 全留给了继承。
   现在把这两项钉在组件上（取全站多数页面的 500 / 1.7）。 */
.user-info{
  display:flex;align-items:center;gap:var(--sp-1);flex-wrap:wrap;
  padding:8px 12px;margin-bottom:4px;
  border-bottom:1px solid var(--pop-line);
  font-size:var(--fs-micro);font-weight:500;line-height:1.7;color:var(--pop-text-dim);letter-spacing:.5px;
}
.user-menu-item{
  display:block;width:100%;padding:var(--sp-2) 12px;
  border:none;background:none;border-radius:var(--r-btn);
  font-family:var(--sans);font-size:var(--fs-note);font-weight:500;color:var(--pop-text);
  cursor:pointer;text-align:left;line-height:1.4;letter-spacing:.5px;text-decoration:none;
  transition:background .15s,color .15s;
}
.user-menu-item:hover{background:var(--pop-hover);color:var(--pop-gold)}
/* ★★ 2026-10-25（F16）：「账户与安全」「退出登录」原来是 <div onclick>，
   `<div>` 不参与 Tab 序列 → **键盘用户根本无法退出登录**。
   现在改成 <button type="button">，天然可聚焦、可回车触发。
   同时去掉容器上的 role="menu"/"menuitem"：声明了 menu 角色却不实现
   它的键盘模型（方向键 / Home / End / Esc 回焦点），比不声明更糟 ——
   读屏软件会告诉用户"这是菜单，用方向键"，而方向键其实什么都不做。
   保留可见焦点环：能 Tab 到但看不见在哪，等于没有。 */
.user-menu-item:focus-visible{outline:2px solid var(--pop-gold);outline-offset:-2px;background:var(--pop-hover);color:var(--pop-gold)}
.admin-badge{display:inline-block;font-size:var(--fs-micro);background:var(--gold-dim);color:var(--gold);padding:1px var(--sp-2);border-radius:6px;font-weight:700;vertical-align:middle;border:1px solid rgba(125,98,36,.28)}
/* 下拉里的身份标记跟随弹层配色：全局 .admin-badge 用的是页面金（浅色页上成立），
   在深色弹层上会变成「深棕底 + 深棕字」。作用域限定在 .user-dropdown 内。 */
.user-dropdown .admin-badge{background:var(--pop-hover);color:var(--pop-gold);border-color:var(--pop-line)}
/* 通用隐藏类：账户下拉等组件依赖它，缺了会导致菜单常驻展开 */
.hidden{display:none!important}

/* ---------- 11. 统一视觉标尺：圆角 / 字号下限 ---------- */
/* 审核发现的问题（2026-09-12）：同一站内卡片圆角出现 6/10/12/14 四种值，
   徽章圆角出现 3/4/6/9/10/12/20 七种值，辅助字号低到 8.3px（.52rem）——
   这些不是设计取向，而是各页各自演化后失同步。这里给出唯一标尺，
   后续新增组件只允许引用这些变量，不得再写魔法数字。 */
:root{
  --r-card:12px;   /* 卡片、面板 */
  --r-tag:6px;     /* 标签、徽章（非胶囊） */
  --r-btn:8px;     /* 按钮、输入框 */
  /* 字号令牌**不在本块**：全站唯一真源是下方 §17 的 --fs-micro…--fs-page（12→36px）。
     这里曾另立一个同值的 --fs-xs=.75rem，与 --fs-micro 构成「同一语义两把尺子」，
     2026-09-26 已并入 --fs-micro 并删除。 */
}

/* 卡片圆角归一：models 网格 r6、tools 排行 r12、predict 卡 r12 / 面板 r10、
   discover 工具卡 r10 → 统一为 --r-card。 */
.model-grid,
.rank,
.predict-card,
.agi-panel,
.tool-card{
  border-radius:var(--r-card);
}

/* 标签类圆角归一：m-spec r3、m-name-badge r4、news-tag r3、rk-diff r9 等 → --r-tag。
   胶囊型（agi-stage-badge / update-badge / rk-price）保持全圆角，
   因为「胶囊」在这里承担「状态」语义，与「标签」区分是有意的。 */
.m-spec,
.m-name-badge,
.news-tag,
.lm-tag,
.rk-kind,
.rk-diff,
.aiq-fb-tag,
.idea-cat,
.scenario-tag,
.hb-daily-tag{
  border-radius:var(--r-tag);
}

/* ---------- 12. 统一空状态 ---------- */
/* 审核发现空状态有 5 种写法：内容区居中块、虚线左对齐、裸 <p>（无容器）、
   渐变虚线卡、裸 div。读者在不同页面看到的「没有内容」提示形态完全不同。
   统一为一套：虚线上边框容器 + 可选图标 + 标题 + 说明 + 可选动作。
   用法：
     <div class="empty-state">
       <svg class="empty-state-icon">…</svg>
       <p class="empty-state-title">该分类暂无内容</p>
       <p class="empty-state-hint">换个分类，或稍后刷新</p>
     </div> */
.empty-state{
  grid-column:1/-1;
  text-align:center;
  padding:48px 24px;
  border:1px dashed var(--line2);
  border-radius:var(--r-card);
  background:var(--bg2);
  color:var(--text3);
}
.empty-state-icon{
  display:block;margin:0 auto var(--sp-3);
  width:44px;height:44px;
  stroke:var(--line2);fill:none;stroke-width:1.2;
  opacity:.8;
}
.empty-state-title{
  font-size:var(--fs-body);font-weight:600;color:var(--text2);margin-bottom:var(--sp-1);
}
.empty-state-hint{
  font-size:var(--fs-micro);line-height:1.8;color:var(--text3);
  max-width:420px;margin:0 auto;
}
.empty-state-action{margin-top:16px}

/* 行内变体：用于「网格里有内容、但当前筛选结果为空」的说明条
   （models 页勾选「仅看在线核验」后一张不剩的场景）。
   它需要解释原因，属于左对齐长文本，套居中的大图标空态反而不合适 ——
   但仍复用同一套容器令牌（虚线 + --r-card + --bg2），
   避免同一站里演化出第 6 种「没有内容」的写法。 */
.empty-state.is-inline{text-align:left;padding:12px 16px;margin-top:var(--sp-3)}
.empty-state.is-inline .empty-state-title{font-size:var(--fs-note);margin-bottom:4px}
.empty-state.is-inline .empty-state-hint{max-width:none;margin:0;text-align:left}

/* ---------- 13. 统一返回顶部 ---------- */
/* news / models / predict / tools / ai-homepage 各自实现了一遍（36px 与 44px
   两种尺寸、浅底与金底两种配色），其余 7 个页面则完全没有。
   这里给出唯一实现；缺失页面的按钮由 site.js 注入。
   注意：首页在深色首屏上是金色实体按钮（设计取向），它自己的样式块
   在本文件之后重新覆盖，不受此处影响。 */
.back-top{
  position:fixed;bottom:32px;right:32px;z-index:99;
  width:40px;height:40px;border-radius:50%;
  background:rgba(250,250,248,.94);
  border:1px solid var(--line2);
  display:flex;align-items:center;justify-content:center;
  cursor:pointer;
  box-shadow:0 4px 16px rgba(0,0,0,.07);
  opacity:0;transform:translateY(12px);pointer-events:none;
  transition:opacity .3s,transform .3s,border-color .2s,background .2s;
}
.back-top.show{opacity:1;transform:translateY(0);pointer-events:auto}
.back-top:hover{background:var(--bg);border-color:var(--gold);transform:translateY(-2px)}
.back-top svg{width:16px;height:16px;stroke:var(--text2);fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.back-top:hover svg{stroke:var(--gold)}
@media (max-width:600px){
  .back-top{bottom:20px;right:16px;width:42px;height:42px}
}

/* ---------- 14. 可横向滚动的表格容器 ---------- */
/* 窄屏下宽表格会把整个页面撑出横向滚动条。把表格包进本容器后，
   只有表格自己滚动，页面宽度不受影响。 */
.table-scroll{
  overflow-x:auto;
  -webkit-overflow-scrolling:touch;
  margin:16px 0 24px;
}
.table-scroll>table{min-width:560px;margin:0}

/* ================================================================
   15. 标记与状态：NEW / HOT / 活点
   ----------------------------------------------------------------
   2026-09-23 制定。规范见 docs/LUNEMIND-VISUAL-SYSTEM.md，改这里必须同步改那份。

   为什么推倒重来（用户原话：「HOT 跟 NEW 做的也太丑了吧 …… 一眼 AI 生成」）：
   旧写法是 `linear-gradient(135deg,#f2d377,#c9a24a)` + `box-shadow` + `border-radius`
   —— 渐变、阴影、圆角三件套，是「AI 生成」最常见的一张脸。
   真正的问题是：**用「贴纸」替代了「排版」**。标记本该先靠字重、字距、颜色、
   位置站住，动效只是最后那层「这里有个新东西」的提示。

   三条硬约束（每条都有理由，别绕过）：
   ① 只动画 transform / opacity。不动画 width/height/padding/box-shadow ——
      后者逐帧触发布局或重绘，在长列表里会掉帧。
   ② 循环动效周期 ≥ 1.8s，且**复合动效的各层必须用不同周期**。
      同周期叠加 = 机械感；不同周期叠加 ⇒ 视觉上永不重复，
      这正是「真实燃烧」的观感来源。
   ③ 标记文字用 --fs-micro（12px），不得更小 —— 这是本文件 §8 定的下限，
      旧写法的小徽章用了 .66rem（10.5px），连自己的规则都没守住。
   ================================================================ */

:root{
  /* ── 余烬色阶：HOT 专用 ──
     火是**语义色**不是装饰色，它必须一眼读成「热」。
     刻意不用金色：金渐变是全站主色，标记再用金就变成「满屏金」——
     **标记与被标记的东西同色，等于没标记**。暖赭/琥珀与棕金同属暖色系
     但明确区分，读起来是「余烬」而不是「塑料金」。
     对比度：#8a3d0c on #fafaf8 = 6.7:1（AA 要求 4.5:1）。 */
  --mk-ember:#b45309;                    /* 焰体 · 暖赭 */
  --mk-ember-core:#f59e0b;               /* 焰心 · 琥珀 */
  --mk-ember-ink:#8a3d0c;                /* 文字 · 深陶土 */
  --mk-ember-veil:rgba(180,83,9,0.07);   /* 底雾（极浅暖底） */
  --mk-ember-line:rgba(180,83,9,0.18);
  --mk-ember-line-strong:rgba(180,83,9,0.32);

  /* ── 收录色：NEW 专用 ──
     NEW 标的是「本站收录」，是资产不是促销 —— 所以用**深而闷的墨金**，
     不用高亮渐变，也不用站点主色的明金（标记与被标记的东西同色 = 没标记）。
     ★ v4（2026-09-25）起标记改成**纯排版**（方点 + 文字），两个值换了角色：
       --mk-new-bg   作**装饰色**：6×6 方点 + 卡片顶部 2px 强调线（不参与文字对比度判定）
       --mk-new-ink  作**文字色**：必须过 WCAG AA（正常文本 4.5:1）
     为什么 ink 必须换：旧值 #fffdf6 是「深色实底上的暖白」，挪到浅色卡面上只有
     1.03:1（实测）—— 完全不可读。这正是「标记从色块改成文字」时必须一起改的东西。 */
  --mk-new-bg:#8a6b28;    /* 4.77:1 on #fafaf8 · 仅作装饰：方点 / 卡片顶线 / 说明句左竖条 */
  --mk-new-ink:#6f5319;   /* 6.86:1 on #fafaf8 · 标记文字，过 AA */
  /* ★ 2026-09-26 新增（标记改成「与 .lm-hot 同构」的胶囊之后）：
     底雾与描边**必须半透明** —— 不透明实底色块才叫贴纸，9% 的底雾是「有底但仍是排版」。
     .lm-new 的规则里只允许出现 --mk-new-veil，**不许**出现 --mk-new-bg 当底色（K2 会拦）。 */
  --mk-new-veil:rgba(138,107,40,0.09);   /* 底雾（极浅墨金底） */
  --mk-new-line:rgba(138,107,40,0.30);   /* 描边（1px 胶囊边框 / 说明句外框） */

  /* ── 语义色：状态专用 ──
     替代 #27ae60 / #e67e22 这类 Flat UI / Bootstrap 默认值
     （全站实测命中 7 个默认色，是「AI dashboard」最典型的配色特征）。
     取值压低饱和度、与棕金体系同调。
     不用纯红：本站是中国站点，红在金融语境里是「涨」；
     「机会/挑战」不是市场涨跌，用绿/赭不会与之冲突。 */
  --sem-open:#2f6f4f;                    /* 机会 · 深松绿 */
  --sem-watch:#9a5b16;                   /* 挑战 · 赭黄 */
  --sem-error:#a8493a;                   /* 失败/错误 · 砖红（通用 UI 反馈，不涉市场涨跌） */

  /* ── 类别色盘：发现 AI 的 9 张场景卡专用 ──
     症状②在发现页最严重：9 张卡各持一个 Flat UI 默认色
     （#e74c3c #9b59b6 #3498db #1abc9c #f39c12 #e67e22 #2ecc71 #34495e #d35400），
     一眼就是「AI dashboard 模板」。
     ★ 而且它们同时是**不达标的**：.scenario-tool-link 拿 --card-color 当**文字色**
     （.76rem/600 ≈ 12.2px，够不上 WCAG 的「大号文字」豁免），需 4.5:1 ——
     实测旧值 9 个里 8 个不达标（最低 1.95:1，就是 #2ecc71）。
     所以这不是审美问题，是可访问性缺陷，静音只是顺带。
     新值统一压到 L*≈36-42% / S*≈38-48%：读起来是「颜料」而不是「屏幕霓虹」，
     色相保留、类别仍两两可辨，且全部 ≥4.77:1（逐个实测，见行末）。 */
  --cat-art:#a8493a;    --cat-art-bg:rgba(168,73,58,.10);     /* 音乐创作 · 赤陶    4.96:1 */
  --cat-video:#6d4f86;  --cat-video-bg:rgba(109,79,134,.10);   /* 视频创作 · 紫墨    5.82:1 */
  --cat-write:#3f6088;  --cat-write-bg:rgba(63,96,136,.10);    /* 写作与小说 · 靛蓝  5.62:1 */
  --cat-code:#2f6f68;   --cat-code-bg:rgba(47,111,104,.10);    /* 代码编程 · 松绿    5.10:1 */
  --cat-doc:#83641a;    --cat-doc-bg:rgba(131,100,26,.10);     /* 办公文档 · 赭金    4.85:1 */
  --cat-study:#a15527;  --cat-study-bg:rgba(161,85,39,.10);    /* 学习助手 · 陶橙    4.77:1 */
  --cat-life:#4f7043;   --cat-life-bg:rgba(79,112,67,.10);     /* 生活管家 · 苔绿    4.93:1 */
  --cat-trans:#3b5060;  --cat-trans-bg:rgba(59,80,96,.10);     /* 翻译与跨文化 · 石板 7.20:1 */
  --cat-biz:#8c4630;    --cat-biz-bg:rgba(140,70,48,.10);      /* 商业提效 · 砖红    5.98:1 */
}

/* ---------- 15.1 HOT：火焰标记 ---------- */
/* 形态：11×14px 的火苗 + HOT 字样，坐在标题之前。
   底雾 + 1px 暖描边，**没有 box-shadow** —— 阴影是「贴纸感」的主要来源。 */
.lm-hot{
  display:inline-flex;align-items:center;gap:var(--sp-1);
  vertical-align:middle;margin-right:var(--sp-2);
  padding:2px var(--sp-2) 2px var(--sp-1);
  border-radius:999px;
  background:var(--mk-ember-veil);
  border:1px solid var(--mk-ember-line);
  font-family:var(--sans);
  font-size:var(--fs-micro);
  font-weight:800;letter-spacing:1.4px;line-height:1.5;
  color:var(--mk-ember-ink);
  white-space:nowrap;
  transition:background .2s ease,border-color .2s ease;
}
/* 悬停整行时暖底加深半档：这是「这条重要」的**反馈**，
   不是又一处持续动效 —— 界面上的持续动效越多，每个的信息量就越低。 */
.focus-item:hover .lm-hot,
.monthly-item:hover .lm-hot{
  background:rgba(180,83,9,0.12);
  border-color:var(--mk-ember-line-strong);
}

.lm-flame{
  position:relative;flex:0 0 11px;width:11px;height:14px;
  display:inline-block;
}
.lm-flame svg{display:block;width:100%;height:100%;overflow:visible}
/* transform-origin 100% = 底部：火焰从底部往上烧。
   transform-box:fill-box 让 SVG 子元素的 transform-origin 以自身包围盒为准
   （不设的话百分比是相对 SVG 视口，火焰会绕着画布中心缩放 —— 看着像「抖」）。 */
.lm-flame .fl-body{
  fill:var(--mk-ember);
  transform-box:fill-box;transform-origin:50% 100%;
  animation:lmFlameBody 2.6s cubic-bezier(.44,.06,.52,.94) infinite;
}
.lm-flame .fl-core{
  fill:var(--mk-ember-core);
  transform-box:fill-box;transform-origin:50% 100%;
  animation:lmFlameCore 1.9s cubic-bezier(.44,.06,.52,.94) infinite;
}
/* ★★ v4（2026-09-25）：**删掉第三层「光晕」**（依据 P5「浅色底上不放外发光」）。
   光晕原本是 `radial-gradient(rgba(245,158,11,.34) → 透明)` + 3.4s 呼吸，它做两件坏事：
     ① 颜色是**临时值**：琥珀 245,158,11 不在任何令牌里 —— 违反 P2「一色一义」，
        它让暖色从「两个真源」悄悄变成三个；
     ② 外发光在浅色底上只有一个作用：把元素**阴影化**。这是模板感 / 「AI 化」
        最大的指纹，也正是用户这次看到的东西。
   底下两层 `.fl-body` / `.fl-core` **保留**：它们用的是 --mk-ember / --mk-ember-core
   令牌色，而且「最热的那条在动」本身就是注意力信号（与 .lm-live-dot 同类），
   不是纯装饰。周期 2.6s / 1.9s 互不相同且均 ≥1.8s（§56.4 不变量）依旧成立。 */
@keyframes lmFlameBody{
  0%,100%{transform:scale(1,1) skewX(0deg)}
  18%{transform:scale(.96,1.08) skewX(-3deg)}
  38%{transform:scale(1.03,.95) skewX(2deg)}
  58%{transform:scale(.98,1.05) skewX(-1.5deg)}
  78%{transform:scale(1.02,.98) skewX(1deg)}
}
@keyframes lmFlameCore{
  0%,100%{transform:scale(1,1);opacity:.95}
  30%{transform:scale(.9,1.14);opacity:1}
  62%{transform:scale(1.06,.9);opacity:.85}
}

/* ---------- 15.2 NEW：收录标记 ---------- */
/* ★★ 2026-09-26 回修（用户原话：「这个 new 标签太不明显」）。
   v4（2026-09-25）为治「贴纸感」把标记削成了「6×6 方点 + 裸文字」。那三处改动
   **仍然有效、必须保留**：
     ① 删掉 4.2s 扫光 + 3.1s 呼吸描边 —— 它们答不上 P3 那句「省掉了用户哪次判断」，
        25 张卡 × 2 条 = 一屏 50 处持续噪声；
     ② 删掉切角（clip-path）与不透明实心底 —— 那才是「芥末色贴纸」；
     ③ 从卡片右上角移进厂商行 —— 那里本是厂商发布日期（.m-released）的位置，
        「本站收录日」与「厂商发布日」两个口径挤在一角，读者会把一个当成另一个。
   ★ 但 v4 **砍过头了**：把「不该是贴纸」执行成了「什么都不给」。
     12px 已是辅助文字的下限，再没有底色、没有描边 —— 结果是同一行里
     HOT（火焰标，§15.1：7% 底雾 + 1px 描边 + 胶囊）一眼能看见，
     NEW 却读成了厂商名前面的一颗装饰点。两个同类标记，待遇必须对等。

   现在：**与 .lm-hot 同构的胶囊**（9% 底雾 + 1px 描边 + 999px 圆角），
   字号升到 --fs-note（13px）、字重 800、字距 1.4px，文字色仍是收录墨金。
   与 v3 那版「实底切角贴纸」的差别是**结构性**的：
     · 底是 9% 半透明（不是不透明实底）—— 有底，但仍是排版，不是贴纸；
     · 坐在厂商行里（不抢右上角的发布日）；
     · 无 clip-path、无外发光、无任何动画。
   卡片顶部强调线一并加粗到 3px：视线扫过时「这张卡是新的」必须先成立。
   ★ 定义同时进版面（见 §15.4 .mark-legend）—— 只在 hover 出现的 title
     不算「告诉用户」，触屏设备上根本没有 hover。 */
.lm-new{
  display:inline-flex;align-items:center;vertical-align:middle;
  padding:2px var(--sp-2) 2px var(--sp-2);border-radius:999px;
  background:var(--mk-new-veil);
  border:1px solid var(--mk-new-line);
  font-family:var(--sans);
  font-size:var(--fs-note);
  font-weight:800;letter-spacing:1.4px;line-height:1.5;
  color:var(--mk-new-ink);
  white-space:nowrap;
  /* 标记后面必须留出气口：它坐在厂商名之前（NEW OPENAI），不留间距会读成「NEWOPENAI」。 */
  margin-right:var(--sp-2);
}
/* 收录色方点：用 background 而不是 border —— 6px 见方时 1px 描边会吃掉一半面积。 */
.lm-new::before{
  content:"";flex:0 0 6px;width:6px;height:6px;margin-right:var(--sp-1);
  background:var(--mk-new-bg);
}
/* ★ 卡片顶部 3px 收录强调线已删（2026-10-09，用户实测否决）：
   NEW 卡有金顶线、非 NEW 卡没有 —— 在 gap:1px 共享边线网格里，读者看到的是
   「有的卡有边、有的没边，毫无规律」（用户原话）。NEW 信号由徽章本身承载
   （文字 + 底雾 + 图例，双通道已达标），顶线是纯装饰增量，删掉后网格边缘
   恢复唯一语法：灰色共享分隔线，一张卡一层边。 */
/* 行内变体：标记跟在标题后面（预测页「新加入的预测」）。
   **同一个标记组件在两种位置出现，外观必须一致** —— 否则读者会以为是两回事。
   v4 起基类本身已经是 inline-flex，所以这里只剩位置差，不再重复任何外观属性。 */
.lm-new-inline{
  margin-left:var(--sp-2);
}

/* ---------- 15.3 活点：全站唯一的「实时」语法 ---------- */
/* 改版前同一颗呼吸点在 5 个文件里各定义一遍（.ub-dot / .pulse-dot /
   .agi-stage-dot + 两处内联 style），连 @keyframes pulse 都复制了 5 份。
   同一颗点复制到所有地方，读者很快学会忽略它 —— 动效要稀缺才有信息量。

   改用「雷达涟漪」（一圈从中心扩散淡出的细环）替代纯 opacity 呼吸：
   涟漪多一层「刚刚发生了什么」的方向感，而且全站共用一套定义。 */
.lm-live-dot{
  position:relative;
  display:inline-block;flex:0 0 6px;
  width:6px;height:6px;border-radius:50%;
  background:var(--gold-decor);
  vertical-align:middle;
  animation:lmPulse 2.4s ease-in-out infinite;
}
.lm-live-dot::after{
  content:"";position:absolute;inset:-3px;border-radius:50%;
  border:1px solid var(--gold-decor);
  opacity:0;
  animation:lmLive 2.4s ease-out infinite;
}
@keyframes lmPulse{
  0%,100%{opacity:1}
  50%{opacity:.38}
}
@keyframes lmLive{
  0%{transform:scale(.6);opacity:.55}
  70%,100%{transform:scale(1.5);opacity:0}
}
/* 「数据陈旧」态：点停在琥珀色且**停止呼吸**。
   状态语义靠「停」来表达 —— 一个永远在跳的点无法区分「实时」和「早就坏了」。
   涟漪伪元素也要一起停，否则停了实心点还在扩散圈，等于没停。 */
.update-badge.warn .lm-live-dot{
  background:var(--sem-watch);
  animation:none;
}
.update-badge.warn .lm-live-dot::after{
  animation:none;opacity:0;
}

/* ---------- 15.4 标记说明（legend）：把「这个标记是什么意思」写进版面 ---------- */
/* 起因（用户原话）：「用户不知道什么时候才是 new，不如刚加入或者发布多少天自动消失啥的，
   你要给用户知道 new 的标签的定义」。

   要点：**一个只在 hover 时出现的 title 不算「告诉用户」** —— 触屏设备上根本不存在
   hover，键盘用户也不一定摸得到。所以定义必须进版面：标记本体 + 一句人话，
   坐在列表标题下方。
   ★ 天数一律从 site.js 的 LM_NEW.DAYS 读（单一真源），页面不得写死 ——
     两处各写一份，改窗口时必然只改一处。

   ★★ 2026-09-26 提权（用户原话：「我觉得要说清楚，一般 new 标签什么时候会添加，
      添加多久后会消失」）。这里暴露的真问题是**上一版写成了「一行 13px 灰字」**：
      它确实回答了那两个问题，但在一屏灰色元信息里根本读不到 —— 等于没告诉。
      改法有两层，`句子` 与 `形态` 都要动：
       ① 句子拆成**三问三答**（什么时候加 / 什么时候消失 / 标的是哪个日期），
          用收录墨金把问句提出来当锚点，读者扫一眼就知道这里有答案；
       ② 形态从「一条分隔线 + 灰字」升级成**暖底提示块**（9% 底雾 + 1px 描边 +
          左侧 3px 收录色竖条）。同页脚注区块（models.html 底部那份「数据来源与
          更新机制」）本来就是这个语法，所以这不是新装饰，是把已有语法用对位置。 */
.mark-legend{
  display:flex;align-items:flex-start;gap:var(--sp-2);
  margin:0 0 var(--sp-45);padding:var(--sp-3) 16px var(--sp-3) var(--sp-4);
  border:1px solid var(--mk-new-line);
  border-left:3px solid var(--mk-new-bg);
  border-radius:0 6px 6px 0;
  background:var(--mk-new-veil);
  font-size:var(--fs-note);color:var(--ink-aux);line-height:1.95;
}
.mark-legend b{color:var(--text);font-weight:700}
/* 三个问句是这段话的锚点：扫一眼就知道「这里回答了三个问题」。 */
.mark-legend .q{color:var(--mk-new-ink);font-weight:700;letter-spacing:.3px}
/* 标记坐在说明句前面时，**不能按基线对齐** —— 胶囊自带上下内边距，基线对齐会让它
   看起来往下掉；这里改成与第一行文字顶部对齐（1px 是胶囊边框的视觉补偿）。
   同时撤掉标记自带的外边距 —— 间距由 flex gap 统一管，两边都算会变成 17px。 */
.mark-legend .lm-new{align-self:flex-start;margin-right:0;margin-top:1px}

/* ================================================================
   16. 焦点列表的排版升格：日期列 → 时间戳
   ----------------------------------------------------------------
   用户原话：「焦点里面的时间能不能加粗一下，跟其他的不搭」。

   旧写法 .78rem + 浅灰(--ltext2) + 500 字重，紧挨着 1rem / 500 / 近黑的标题 ——
   读起来是「一串发虚的小数字」，视线扫过去抓不住。
   时间轴的锚点必须比内容更「实」，否则读者无法沿日期扫描。 */
.focus-date,
.monthly-date{
  font-family:var(--mono);
  font-size:var(--fs-note);
  font-weight:700;                        /* 500 → 700 */
  color:var(--ltext);                     /* 浅灰 --ltext2 → 正文墨色 */
  /* 等宽数字：09.22 与 10.03 在比例数字下宽度不同，一列日期会参差不齐。
     这一条是「看起来专业」和「看起来拼装」的分界。 */
  font-variant-numeric:tabular-nums;
  letter-spacing:.5px;
  /* 右对齐并紧贴列右缘的细线：结构感来自留白，不来自框线 */
  align-self:stretch;
  display:flex;align-items:center;justify-content:flex-end;
  padding-right:var(--sp-3);
  border-right:1px solid var(--lline);
}
/* 兜底：不在 grid 里的用法（如详情页的单条引用）不应被拉伸 */
.focus-date:not(.focus-item > *),
.monthly-date:not(.monthly-item > *){
  align-self:auto;border-right:none;padding-right:0;
}

/* ================================================================
   17. 排版标尺 · 间距标尺 · 交互标尺（2026-09-23 v3）
   ----------------------------------------------------------------
   起因（用户原话）：「整体网站UI视觉看起来比较单调和枯燥，基本纯信息」
                    「有些文本根本看不清楚」……「缺少细节打磨」

   「单调」不是审美判断，是对 6 个主页面做真机实测后得到的两组数字：

   ① **字号阶梯的中间是空的。**
      正文区有 11 个字号档挤在 12–15px 之间：
      12 / 12.2 / 12.5 / 12.8 / 13.1 / 13.4 / 13.6 / 13.8 / 14.1 / 14.4 / 14.7 / 15.2
      人眼对字号的辨别阈值约 1.15 倍（0.3px 的差在 15px 尺度上根本看不见），
      所以那些"层级"在视觉上**并不存在** —— 整页读起来是一块平地。
      而在这之上直接跳到 24px / 38.4px / 48px，中间**完全断层**：
      「卡片标题」与「正文」之间没有任何一档可用，于是全站只好把它们设为同号，
      这就是"基本纯信息、分不出主次"的直接来由。

   ② **区块之间的垂直间距没有比例关系。**
      实测首页 56 / 80 / 88 / 236 / 937 / 1494 px，发现页 663 / 669 / 898 / 1480 px。
      「节奏」来自间距的**比例**，全写魔法数字就只有堆叠，没有呼吸。

   本节给出的规则（新增组件只允许引用这些令牌，不得再写魔法数字）：
   ★ 相邻字号档至少相差 1.2 倍 —— 层级感来自「能分辨的差」，不来自「档位多」。
   ★ 补齐 --fs-sub（22px）：这一档旧状**完全缺失**，是「卡片标题与正文分不开」的根因。
   ★ 间距只用 --sp-1…--sp-8（4px 基数）。
   ★ 过渡只用 --dur-* 与 --ease，保证全站手感一致。
   ================================================================ */
:root{
  /* 字号阶梯（相邻档 ≈1.2–1.33 倍，每一跳肉眼可见） */
  --fs-micro:.75rem;      /* 12px · 微标签 / eyebrow / 角标（辅助文字下限，全站唯一真源） */
  --fs-note:.8125rem;     /* 13px · 说明、元信息、表注 */
  --fs-body:.9375rem;     /* 15px · 正文基准（各页 body 现用值，不变） */
  --fs-lead:1.0625rem;    /* 17px · 导语、卡片标题 */
  --fs-sub:1.375rem;      /* 22px · ★ 旧状缺失的这一档：区块内小标题 */
  --fs-block:1.75rem;     /* 28px · 区块标题 */
  --fs-page:2.25rem;      /* 36px · 大号数字展示（KPI 数字、指标数） */
  /* ★ 新增这一档的原因：--fs-page 此前被「页级标题」和「大号数字」两种语义共用，
     而这两者需要的值不同 —— 标题要 ~40px（页内视觉锚点，见下方 §17.1 的决策），
     KPI 数字 36px 就够（再大就抢走卡片本身的重量）。
     结果是：标题写成 clamp(…,2.6rem) 的字面量、数字写 var(--fs-page)，
     同一个「页级」语义在 6 个页面里有 4 套公式（2.6rem / 3rem / 1.85rem / 1.9rem）。
     拆开之后各自有唯一真源，阶梯也仍然连续（28 → 36 → 40）。 */
  --fs-page-title:2.6rem;  /* 40px · 页级标题（.page-header h1） */

  /* 间距标尺（4px 基数，9 级）
     ★ --sp-45 是后补的一级：原 8 级是 4/8/12/16/24/32/48/72，**跳过了 20px**。
       而 10–20px 恰恰是卡片内边距、区块间距用得最多的区间 ——
       实测那一段挤着 7 个不同值（10/11/13/14/15/17/18，共 385 处），
       14 与 16、10 与 12、18 与 20 在视觉上分辨不出来，读者只会觉得「节奏不匀」。
       刻度缺了这一档，大家就会去写字面量：这不是纪律问题，是尺子不够用。
       （实测 --sp-* 全站被引用 18 次，而 padding/margin/gap 的 px 字面量 1294 处。）
     命名用 sp-45 而不是插队重排编号：重排会让所有既有引用指向不同值，
     那是最容易出「改一处、另一处悄悄变了」的做法。 */
  --sp-1:4px;  --sp-2:8px;  --sp-3:12px; --sp-4:16px;
  --sp-45:20px; --sp-5:24px; --sp-6:32px; --sp-7:48px; --sp-8:72px;

  /* 交互标尺：全站只此一套手感。
     旧状各页各写 .2s / .22s / .26s / .3s / .35s / .4s 六种时长、四种缓动，
     同一站里 hover 的快慢都不一样 —— 这是「拼装感」最容易被忽略的一处。 */
  --ease:cubic-bezier(.22,.7,.3,1);

  /* 阴影三层（2026-10-09，UI 质感轮）：暖黑基调（35,28,18）与纸感底同源，
     不用纯黑 —— 纯黑阴影在米白上发灰发脏。
     --shadow-1 悬浮卡 / --shadow-2 弹层 / --shadow-3 模态。只按层级取用，
     同层不得混用两档；这是「深度」的唯一表达（外发光仍禁）。 */
  --shadow-1:0 1px 2px rgba(35,28,18,.05), 0 8px 24px rgba(35,28,18,.08);
  --shadow-2:0 2px 6px rgba(35,28,18,.07), 0 16px 40px rgba(35,28,18,.12);
  --shadow-3:0 8px 24px rgba(35,28,18,.16), 0 24px 64px rgba(35,28,18,.20);
  --dur-fast:.16s;
  --dur:.24s;
  --dur-slow:.42s;
}

/* ---------- 15.5 变化标记总规范（2026-10-08，§3.2.5）----------
   把 §15.1–15.4 已经在做的事显式化成规则，约束未来的新增标记。
   现有范本（不要改坏它们）：
     NEW   文字徽章（.lm-new）+ title + 页面 legend + 自动消失 —— §15.2/15.4
     HOT   火焰（.lm-flame）+ 呼吸动效 —— §15.1
     LIVE  呼吸点（.lm-live-dot）——「实时」用动/停表达，§15.3
     进/出 「新进榜 N / 已下榜 N」文字 + 金/灰框（models.html .bc-tag）
     完成  ✓ 字符 + 删除线 + 金底（tools .aiq-cb/.aiq-ri.done，三通道）

   ★ 三级语义（借 awesome-ai 的 ⭐/🔥/🆕 分级思路，符号不必照搬）：
     一级「首次/新增」   —— NEW 徽章。只在收录窗口内存在，到期自动消失；
                            没有变化就不显示（V3 铁律，不存在「常驻 NEW」）。
     二级「活跃/进行中」 —— 动效类（呼吸/火焰）。必须真的在动；
                            reduced-motion 下退为静态时不能丢失语义（§上方动效降级）。
     三级「方向/幅度」   —— 数字优先（tabular-nums，± 号），符号辅助（↑↓ / ✓△）。

   ★★ 双通道铁律（WCAG 1.4.1）：**颜色永远不是唯一的通道**。
     每个变化标记必须同时具备 颜色 之外的至少一种区分手段：
     文字（NEW / 头条 / 已下榜）、符号（✓ △ ↑↓）、形状（实心/空心）、动效（呼吸/停）。
     写新标记时自问一句：把页面转成灰度，用户还分得出这两态吗？分不出 = 不合格。

   ★ 图例义务：进版面的标记（不是 hover title）必须在页面上有自己的定义
     （§15.4 的先例）。新增标记 = 同时新增 legend 行。 */

/* ---------- 17.1 页级标题：统一，但**不缩小** ---------- */
/* 旧状 6 个页面各写各的（41.6 / 46.4 / 48 / 38.4 / 18.4 / 16 px），
   同一个语义有六种取值 —— 这是「失同步」，要修。
   ★ 但修法是**统一到同一档**，不是把它们集体调小。
     先试过收到 36px，渲染复核后否掉了：一个小站点里，页级标题往往是
     全页**仅有的视觉锚点**，把它压小只会让页面更平、更像一份纯文本文档，
     而用户提的恰恰是「单调枯燥、基本纯信息」。层级不是靠压小标题得来的，
     是靠**补上中间档**（见 17.2 的 --fs-sub）与建立阶梯关系得来的。
   现在：页级标题统一到 ~40px 一档（内页 H1 与首页区块标题视觉相当）。 */
.page-header h1{
  font-size:clamp(1.9rem,1rem + 2.6vw,var(--fs-page-title));
  line-height:1.18;
  letter-spacing:-.4px;
}

/* ---------- 17.2 eyebrow：一个「结构」而不是一句「小字」 ---------- */
/* eyebrow（EXPLORE / MODELS / TOOLS …）是页面里第一个被看到的东西，
   旧状它是一行 12px 的浅色小字，与正文同重，读者扫过去抓不住。
   这里给它一条 18px 的短横线 —— 这是编辑式排版的经典手法：
   **零装饰、零渐变，纯排版**，但立刻把「这是一个分节」变成可看见的结构。
   ★ 用 ::before 而不是背景图：不引入额外请求，也不受 background 继承影响。 */
.sec-eyebrow,
.section-eyebrow,
.eyebrow{
  display:flex;align-items:center;gap:var(--sp-2);
  font-size:var(--fs-micro);
  font-weight:700;
  letter-spacing:3px;
  text-transform:uppercase;
}
.sec-eyebrow::before,
.section-eyebrow::before,
.eyebrow::before{
  content:"";flex:0 0 18px;height:1px;
  background:currentColor;opacity:.55;
}

/* ---------- 17.3 区块间距：只给令牌，不改既有版式 ---------- */
/* ★ 这里**刻意不写** `.section + .section{margin-top:…}` 这类全局规则。
   试过，是负优化：各页 .section 自带 padding（首页 88px、内页 80px），
   再叠一层 48px margin 会把节间距从 176px 推到 224px —— 页面不会更有节奏，
   只会更空。间距的节奏要靠**同一页内**的取值成比例（--sp-5 / --sp-6 / --sp-7），
   而不是把所有页面都加上同一层外边距。
   规则：同一页里的节间距，只在 --sp-5(24) / --sp-6(32) / --sp-7(48) / --sp-8(72)
   四档里取，且相邻节的间距值不得出现 1px 级的随意差（那是"没设计"的信号）。 */

/* ================================================================
   18. 可读性修复：辅助文字色与「不许用 opacity 表达次要」
   ----------------------------------------------------------------
   真机实测 6 个页面共 **79 处**文字不达 WCAG AA（正常文本需 4.5:1）。
   逐条追根因，只有两类，且都不是"忘了改某个颜色"：

   ★ 根因一：用 `opacity` 表达「次要」。
     实测命中三处：`.agi-step{opacity:.55}`（未激活的时间线阶段）、
     `.footer-icp{opacity:.85}`、`.footer-copyright{opacity:.6}`。
     为什么这是错的：**不透明度是乘性的** —— 它把前景色朝着"它背后真实的底色"
     拉近，前景与底色的距离同时被压缩。
       #444 在 #fafaf8 上本来是 8.5:1；乘 .6 之后合成出 #a8a8a3，
       对比度掉到 3.28:1 —— 一个字都没改，只是"淡了一点"，就从达标变成不达标。
     正解：**「次要」用颜色深浅表达，不用透明度表达**。要弱化就给一个更浅的
     灰（仍 ≥4.5:1），要强调就加深。透明度只用于「正在消失」的过程（过渡动画），
     不用于「已经稳定」的静态文字。

   ★ 根因二：同一个语义（辅助文字）在三套取值之间各自为政，且都不达标：
       --lgold   #9a7d3c → 3.7:1   （首页 --focus-tag / 发现页 eyebrow……）
       --lgold2  #b89456 → 2.8:1   （发现页 prompt 区 eyebrow）
       --ltext3  #777    → 4.3:1   （发现页第三级文字，仍差一点）
     这是"两把尺子"：site.css 早把全站正文金定成 #7d6224（5.5:1），
     但这几个页面级令牌是**在 site.css 之前**写死的，从未被收敛。
     正解：给出两个达标的辅助色令牌 ——
       --ink-aux   #6b6b6b  在 #fafaf8 上 5.7:1（灰阶辅助文字）
       --ink-gold  #7d6224  在 #fafaf8 上 5.5:1（金色辅助文字）
     页面级 --lgold/--lgold2/--ltext3 不得再低于这两个值。

   ★ 本节只覆盖**浅色表面**上的元素。深色表面（首页夜空首屏、发现页深色 hero）
     各自已有显式覆盖，不受影响 —— 深底上的语义色不能直接搬浅底值（§3.3 已记）。
   ================================================================ */
:root{
  --ink-aux:#4a4a4a;    /* 灰阶辅助文字 8.8:1（2026-10-17 与 --text3 对齐；原 5.1:1 偏淡） */
  --ink-aux-warm:#5a5248; /* 暖灰辅助文字 7.35:1 on #fafaf8 —— tools 页说明文字的既有用色，比 --ink-aux 更暖更深，收进令牌以免它在 3 个规则里各写一遍 */
  --ink-gold:#70571d;   /* 金色辅助文字 6.84:1（= 全站 --gold 的同一个值，同一把尺子） */

  /* ── 语义色（2026-10-08）──
     ★ 为什么这组也要令牌化：这四个色在改动前以**裸 hex** 散落 16 处
       （tools-ui.css 13 处、models.html 2 处、profile.html 3 处），
       语义稳定但没有名字 —— 「这个红是警告还是错误」「这个绿是成功还是已拥有」
       全靠读代码里的选择器名去猜。改一次色要翻 16 个地方，且没有任何机制
       阻止下一个文件重新写一个近似值。
     ★ 命名按**语义**不按外观：读者看到 --sem-danger 就知道它表示「出错」，
       不会因为将来调色而让名字说谎。
     ★ 半透明版本（--*-soft）用于同色系的浅底/边框，与不透明版同源。
     实测对比度（在 #fafaf8 上，2026-10-08 核算）：
       --sem-danger       #9a4f40  5.63:1  ✓
       --sem-danger-strong#8c3226  7.73:1  ✓
       --sem-ok           #257049  5.75:1  ✓
       --sem-info         #3f6b8a  5.46:1  ✓
       --sem-live         #1A7D45  4.95:1  ✓
     ★ --sem-live 由原 #27ae60 加深而来：旧值只有 2.75:1，不达 AA，
       而它用在「签到完成」「同伴激活」这类**文字**上，必须加深。
       同色系的 rgba(39,174,96,.xx) 背景不变（半透明底色不受文字对比度约束）。 */
  --sem-danger:#9a4f40;    --sem-danger-soft:rgba(154,79,64,.10);   /* 错误 / 判错 / 陷阱提示 */
  --sem-danger-strong:#8c3226;  /* 更高一级的警示（数据陈旧横幅、critical 徽章） */
  --sem-ok:#257049;         --sem-ok-soft:rgba(37,112,73,.10);       /* 正确 / 命中 / 已拥有 */
  --sem-info:#3f6b8a;       --sem-info-soft:rgba(63,107,138,.10);    /* 中性信息 / 评分 A 档 / 折叠说明 */
  --sem-live:#1A7D45;       --sem-live-soft:rgba(39,174,96,.12);     /* 「进行中」：签到完成、同伴激活 */
}

/* ================================================================
   ★ 厂商识别色盘（2026-09-26，视觉升级轮）
   ----------------------------------------------------------------
   用途**只有一个**：模型卡左缘那条 3px 的厂商色标（`var(--vc)` 由
   models.html 的 `.model-card::before` 消费）。它回答的是
   「这 25 张卡里哪几张是同门的」—— 扫一列卡时同厂商自然成组，
   不必逐张去读那行 12px 的灰色厂商名。

   ★ 边界（不看清楚会走错路）：
     ① 它**不是文字色**。全站辅助文字仍只有 --ink-aux / --ink-gold 两个真源（§60.2），
        厂商色一个字都不许用。「类别需要可区分」与「层级需要分主次」是两个问题，
        混用同一套色，两个问题都会答错。
     ② 它**不是装饰**。3px 条只在真能区分时才画；未命中的厂商一律走中性灰
        （--line2），绝不为了「画面丰富」硬凑一个颜色。
     ③ 选色标准：与米白底 #fafaf8 对比 ≥3:1（看得见），且彼此明度/色相拉开。
   ================================================================ */
:root{
  --v-openai:#2f6b57;    --v-anthropic:#a3492f;  --v-google:#3f6b8a;
  --v-meta:#4a5a8a;      --v-xai:#4a4a4a;        --v-alibaba:#96602f;
  --v-tencent:#3f7a8a;   --v-deepseek:#3a5a9a;   --v-zhipu:#6b4a8a;
  --v-moonshot:#5a4a7a;  --v-ant:#2f7a6b;        --v-xiaomi:#9a5a2f;
  --v-minimax:#9a3f4a;   --v-stepfun:#3f6b6b;    --v-nvidia:#4a7a2f;
  --v-meituan:#9a8a2f;
}
.model-card[data-v="openai"]{--vc:var(--v-openai)}
.model-card[data-v="anthropic"]{--vc:var(--v-anthropic)}
.model-card[data-v="google"]{--vc:var(--v-google)}
.model-card[data-v="meta"]{--vc:var(--v-meta)}
.model-card[data-v="xai"]{--vc:var(--v-xai)}
.model-card[data-v="alibaba"]{--vc:var(--v-alibaba)}
.model-card[data-v="tencent"]{--vc:var(--v-tencent)}
.model-card[data-v="deepseek"]{--vc:var(--v-deepseek)}
.model-card[data-v="zhipu"]{--vc:var(--v-zhipu)}
.model-card[data-v="moonshot"]{--vc:var(--v-moonshot)}
.model-card[data-v="ant"]{--vc:var(--v-ant)}
.model-card[data-v="xiaomi"]{--vc:var(--v-xiaomi)}
.model-card[data-v="minimax"]{--vc:var(--v-minimax)}
.model-card[data-v="stepfun"]{--vc:var(--v-stepfun)}
.model-card[data-v="nvidia"]{--vc:var(--v-nvidia)}
.model-card[data-v="meituan"]{--vc:var(--v-meituan)}

/* 18.1 页脚：合规备案号与版权行是**必读信息**，不是装饰 */
.footer-icp,
.footer-copyright{
  opacity:1;                 /* ★ 撤掉 opacity —— 它正是这两行看不清的原因 */
  color:var(--ink-aux);
}
.footer-icp:hover{color:var(--ink-gold)}

/* 18.2 eyebrow 与代码片段 */
.sec-eyebrow,
.section-eyebrow{color:var(--ink-gold)}
.sec-eyebrow em,
.section-eyebrow em{font-style:normal;color:var(--ink-gold)}

/* 行内 code：旧状用浅金（3.74:1）。改深金，同时保留「这是代码」的语义 */
code{
  color:var(--ink-gold);
  background:rgba(125,98,36,.07);
  border:1px solid rgba(125,98,36,.14);
  border-radius:var(--r-tag);
  padding:1px var(--sp-1);
  font-family:var(--mono);
  font-size:.92em;
}

/* 18.3 通用：浅色表面上的标签/元信息不得低于辅助色下限。
   注意只给**颜色**，不夺页面自己的字号与间距 —— 那是各页的业务决定。 */
.m-released,
.rank-help,
.gl-note,
.lm-meta{color:var(--ink-aux)}

/* ================================================================
   19. v8 终版视觉收敛层（2026-09-27）
   ----------------------------------------------------------------
   设计文档：docs/LUNEMIND-VISUAL-V8.md（改动理由逐条在那边，不重复）。
   本层全部是「基线 + 统一」，零新装饰：不新增颜色、不新增动效、不加渐变。
   红线自查：无外发光、无 clip-path、无 <12px 字号、无 opacity 表达次要、
   字号全部引用 --fs-*（V 系列守卫语义不变）。
   ================================================================ */
/* ★ 阴影令牌已并入 §16.5 的 :root（--shadow-1/2/3，暖黑三档）。
   此处原有一份旧的 --shadow-1/--shadow-2（冷灰单层），因写在文件更靠后
   曾把新令牌静默覆盖（U3 的暖黑阴影因此没生效过）—— 同键双定义已清，
   阴影唯一真源见 --shadow-1: 定义处。 */

/* 19.1 全局等宽数字：此前靠 §0 的 11 个选择器点状维护，新增组件必漏。
   tabular-nums 只影响数字宽度、对汉字零影响，body 级开启是唯一不漏的办法。 */
body{font-variant-numeric:tabular-nums}

/* 19.2 文字选区：拖选露出「这个站有自己的颜色」，全站一次生效 */
::selection{background:var(--gold-dim-strong);color:var(--text)}

/* 19.3 滚动条：默认灰蓝立体款与米白纸面最违和。细、灰、圆角，hover 加深 */
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:rgba(20,20,20,.18);border-radius:999px;border:2px solid transparent;background-clip:padding-box}
::-webkit-scrollbar-thumb:hover{background:rgba(20,20,20,.28);background-clip:padding-box}
*{scrollbar-width:thin;scrollbar-color:rgba(20,20,20,.28) transparent}

/* 19.4 链接排版：只影响已带下划线的链接，把默认贴字的线抬离基线 */
a{text-underline-offset:3px;text-decoration-thickness:1px}

/* 19.5 卡片 hover 统一语言：translateY(-1px) + --shadow-1。
   资讯页 .hl-card 是去卡化设计（发丝线 + 悬停细轨），不参与——它不是卡片。
   ★ .model-card 也不参与（2026-10-09）：models 页的模型卡住在 gap:1px +
     overflow:hidden 的共享边线网格里 —— translateY(-1px) 会让卡片与上下邻卡
     的接缝错位 1px（实测截图：分隔线断线/双线，读者看到「混乱没规律」），
     外阴影也会被网格容器裁掉。模型卡的 hover 在页面内自持（背景提亮一档）。 */
.predict-card:hover,
.tool-card:hover,
.person-card:hover,
.agi-panel:hover{box-shadow:var(--shadow-1)}
.predict-card:hover,
.tool-card:hover,
.person-card:hover{transform:translateY(-1px)}
/* hover 过渡只动 transform/box-shadow，沿用全站交互标尺（§17） */
.predict-card,
.tool-card,
.person-card,
.agi-panel{transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease),background var(--dur) var(--ease)}

/* 19.6 「信息条」容器语法统一：.as-of（状态行，news 灰底）与 .stats-bar
   （统计带，news 金雾底）此前是两种容器 —— 同页并存会被读成两种语义。
   统一为：--bg2 底 + 1px --line + --r-btn；对齐方式各页自持。 */
.as-of,
.stats-bar{
  background:var(--bg2);
  border:1px solid var(--line);
  border-radius:var(--r-btn);
}
/* news 的 .scope-note 负上边距清零：负 margin 会把折叠标题提进上一区块
   （§47.2 同类的重叠隐患），间距交给前一个区块的下边距管。 */
.scope-note{margin-top:0}

/* 19.7 分段控件可访问性修复：.scope-btn.active 白字压金底 #9a7d3c = 3.7:1
   不达 AA。改与 .nav-item.active 同构（金雾底 + 达标金字 + 1px 金描边），
   对比度 ≈5.2:1。非激活态不动。 */
.scope-btn.active{
  color:var(--ink-gold);
  background:var(--gold-dim-strong);
  box-shadow:inset 0 0 0 1px var(--chip-gold-line);
  font-weight:700;
}

/* 19.8 表格基线：表头全站生效（thead 只出现在数据表里，无误伤面）；
   斑马纹/行线仍限定 .table-scroll（methodology 的 tbody th 行头表不参与）。
   页面自有类（.storage-table 等）特异度更高，同值不冲突、异值保留页面个性。 */
thead th{
  background:var(--bg2);
  font-weight:600;
  letter-spacing:.5px;
  color:var(--text2);
  padding:var(--sp-2) var(--sp-3);
  text-align:left;
}
.table-scroll tbody td{padding:var(--sp-3) var(--sp-3)}
.table-scroll tbody tr:nth-child(even){background:rgba(20,20,20,.015)}
.table-scroll tbody tr{border-bottom:1px solid var(--line)}

/* 19.9 页头节奏统一：h1 / eyebrow 的下边距收敛到间距标尺档位 */
.page-header h1{margin-bottom:var(--sp-4)}
.page-header .eyebrow{margin-bottom:var(--sp-3)}
.page-header p{color:var(--text2)}

/* 19.10 页脚间距走标尺；不加任何装饰（页脚的功能是「安静地结束」） */
.footer{padding-top:var(--sp-7);padding-bottom:var(--sp-6)}
.footer-main-links{gap:var(--sp-2) var(--sp-5)}

/* ── 19.11 页脚布局唯一真源（2026-10-15）────────────────────────────────
   问题：页脚样式原本散在 tools-ui.css 与 15 个页面的 <style> 里，site.css
   一份都没有 ⇒ 只引 site.css 的 10 个页面（compare/dashboard/model-event/
   share-growth 与 V21 的 replay/wall/atlas/workbench/health/prediction）
   页脚是**裸 HTML**：没有居中、没有分隔线、链接容器 display:block 让链接
   挤成一串文字（用户实测「跟其他页面底部不一致，ui 很丑」的真正根因 ——
   上一轮只改了类名，没验证这些类在共享 CSS 里是否真的存在）。

   为什么放这里就一定生效：全站 HTML 都是「先 <style> 后 <link site.css>」，
   同特异度下 site.css 在文档顺序中靠后 ⇒ 本块自动覆盖各页本地副本，
   10 个坏页也同时修好，不需要逐页改。
   ★ 刻意**不写**的几项（有更权威的来源，写了反而会打架）：
     · padding  —— 水平留给 §正文流的流式内边距，垂直留给上面的 19.10；
     · gap      —— 留给上面的 19.10 与 ≤768px 的 !important 媒体查询；
     · .footer-icp / .footer-copyright 的 color —— 留给 §18.1
       （那两行是必读的合规信息，颜色由它定，避免这里把它压暗）。
   ══════════════════════════════════════════════════════════════════ */
.footer{text-align:center;border-top:1px solid var(--line)}
.footer-brand{font-size:var(--fs-lead);font-weight:600;color:var(--text2);margin-bottom:var(--sp-45);letter-spacing:0.5px}
.footer-main-links{display:flex;justify-content:center;margin-bottom:var(--sp-4);flex-wrap:wrap}
.footer-legal-links{display:flex;gap:var(--sp-3) var(--sp-45);justify-content:center;margin-bottom:var(--sp-5);flex-wrap:wrap}
.footer-main-links a,
.footer-legal-links a{color:var(--text2);text-decoration:none;letter-spacing:1px;transition:color .3s;font-weight:500}
.footer-main-links a{font-size:var(--fs-note)}
.footer-legal-links a{font-size:var(--fs-micro)}
.footer-main-links a:hover,
.footer-legal-links a:hover{color:var(--gold)}
.footer-icp{margin:0 var(--sp-2);text-decoration:none;letter-spacing:1px;font-weight:500;
  /* 2026-10-17：备案号只有 15px 高 —— 手机上是个很难点中的目标。
     留出上下 4px 的内边距把可点区域抬到 23px，视觉位置不变。 */
  display:inline-block;padding:var(--sp-1) 2px}
.footer-icp-wrap{margin-top:var(--sp-45);padding-top:var(--sp-4);border-top:1px solid var(--line)}
.footer-copyright{letter-spacing:0.5px;margin-bottom:var(--sp-2)}


/* ================================================================
   §20 全站动效底座（2026-10-10 v12 Motion，设计文档 docs/LUNEMIND-MOTION-DESIGN-2026-10-10.md）
   ----------------------------------------------------------------
   M3 柱条生长：.js-grow 容器内的柱条默认压平（scaleY 0），进入视口后
   site.js 加 .grown 立起 —— transform 不改布局高度，inline height 仍是真值。
   ★ .js-grow 由 site.js 在运行时补挂？不 —— 类写在 HTML 里，但所有隐藏规则
   都要求 html.js 前缀（site.js 第一行挂上）：site.js 挂了，观察器就一定在，
   不存在「类在、动画没人触发」的隐形死局；site.js 没挂（禁 JS），一切静态可见。
   ================================================================ */
@media(prefers-reduced-motion:no-preference){
  .js .js-grow .bar-fill,.js .js-grow .topic-bar{transform:scaleY(0);transform-origin:bottom;
    transition:transform .55s var(--ease)}
  .js .js-grow.grown .bar-fill,.js .js-grow.grown .topic-bar{transform:none}
}
/* 全站 reduced-motion 兜底（各页已有分散实现，这里是最后一道闸）：
   动画可以没有，内容永远不许消失。 */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important}
}

/* M5 stagger 入场（2026-10-11）：容器挂 data-stagger，子元素进入视口依次浮现。
   与 M3 同一防护模式：全部规则挂 html.js 前缀 —— JS 挂了才可能有过渡，
   JS 没挂内容直接可见；reduced-motion 由下方全站兜底块覆盖。
   R5（2026-10-11 用户截图实证）：预隐藏 `> *` 会把「加载中」占位也吞掉 ——
   数据未到时用户看到一整块空白。data-st-skip = 预隐藏豁免，加载态永远可见。 */
@media(prefers-reduced-motion:no-preference){
  .js [data-stagger] > *:not([data-st-skip]){opacity:0;transform:translateY(14px);
    transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease)}
  .js [data-stagger].staggered > *{opacity:1;transform:none}
}

/* V13.3 导航「我的关注」未读角标（auth.js 更新；0 未读时 hidden） */
.nav-watch-badge{display:inline-block;min-width:16px;padding:1px 4px;margin-left:8px;
  border-radius:9px;background:#b03a2e;color:#fff;font-size:12px;font-weight:700;
  line-height:1.5;text-align:center;font-variant-numeric:tabular-nums;vertical-align:1px}
.nav-watch-badge[hidden]{display:none}

/* ── 异步区块加载占位（R5，2026-10-11）────────────────────────
   真源：models/news 的加载 spinner 原是各页内联样式的复制品。统一成一处，
   并永远带 data-st-skip（见上方 M5 注释：加载态绝不允许被预隐藏吞成空白）。
   reduced-motion 时 ring 不转，但「加载中」文字仍承担告知职责。 */
/* ── V17 骨架屏（2026-10-14 用户反馈：等待期「只显示空白」没有 loading 观感）──
   骨架不用 reveal/stagger 门控（那套入场动画存在时序竞争，正是「空白」的来源之一），
   容器一渲染骨架就可见；微光用既有 --sheen 动画语义，周期 ≥1.8s。 */
.lm-skel{position:relative;overflow:hidden;background:rgba(20,20,20,.065);border-radius:8px}
/* ★ V19：原 4% 不透明度在米白底上几乎不可见 —— 用户把骨架描述成「空白」
   （2026-10-14 二轮反馈「偶现空白」）。加深到 6.5% 并配一行文字提示，
   让「正在加载」这件事有明确说法。 */
.lm-skel-hint{display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-3) 0 var(--sp-2);
  color:var(--text3);font-size:var(--fs-note)}
.lm-skel-hint::before{content:"";width:14px;height:14px;border:2px solid var(--gold);
  border-top-color:transparent;border-radius:50%;animation:lm-spin .8s linear infinite;flex:0 0 auto}
.lm-skel::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(20,20,20,.05),transparent);
  animation:lm-skel-sweep 1.8s ease-in-out infinite}
@keyframes lm-skel-sweep{to{transform:translateX(100%)}}
@media(prefers-reduced-motion:reduce){.lm-skel::after{animation:none}}
/* 新闻条骨架：日期块 + 标题行 + 两行摘要 */
.lm-skel-news{display:grid;grid-template-columns:52px 1fr;gap:var(--sp-3);
  padding:var(--sp-4) 0;border-bottom:1px solid var(--line2)}
.lm-skel-news .sk-a{height:14px}
.lm-skel-news .sk-t{height:18px;max-width:70%}
.lm-skel-news .sk-d{height:12px;margin-top:8px;max-width:92%}
.lm-skel-news .sk-d2{height:12px;margin-top:var(--sp-1);max-width:60%}
/* 领奖台卡骨架：维度行 + 名字行 + 两行说明 */
.lm-skel-podium{display:flex;flex-direction:column;gap:var(--sp-2);
  padding:var(--sp-4);border:1px solid var(--line2);border-radius:14px}
.lm-skel-podium .sk-a{height:12px;width:72px}
.lm-skel-podium .sk-t{height:22px;width:55%}
.lm-skel-podium .sk-d{height:12px;width:90%}
.lm-skel-podium .sk-d2{height:12px;width:70%}
/* 加载失败：说明 + 重试按钮（绝不静默空白） */
.lm-load-fail{padding:var(--sp-5) var(--sp-4);text-align:center;color:var(--text3);
  border:1px dashed var(--line2);border-radius:12px;font-size:var(--fs-note);line-height:1.9}
.lm-load-fail button{margin-top:var(--sp-3);padding:var(--sp-2) var(--sp-4);border-radius:10px;
  border:1px solid var(--gold);background:var(--gold);color:#fff;font-size:var(--fs-note);
  font-weight:600;cursor:pointer}
.lm-load-fail button:hover{filter:brightness(1.06)}
.lm-loading{grid-column:1/-1;padding:48px 0;text-align:center;
  color:var(--text3,#8a8a85);font-size:var(--fs-body,var(--fs-body))}
.lm-loading::before{content:"";display:block;width:24px;height:24px;margin:0 auto 12px;
  border:2px solid var(--gold,#9a7d3c);border-top-color:transparent;border-radius:50%;
  animation:lm-spin .8s linear infinite}
@keyframes lm-spin{to{transform:rotate(360deg)}}

/* ── 偏好升格提示条（V13.1，tools-app.js 注入，跨 4 页共享故放这里）──
   固定底条、两个明确动作、只出现一次（localStorage lm_prefs_migrated_v1 守）。 */
.lm-migrate{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);z-index:320;
  display:flex;align-items:center;gap:var(--sp-4);flex-wrap:wrap;justify-content:center;
  max-width:min(680px,calc(100vw - 32px));padding:var(--sp-3) var(--sp-4);
  background:var(--pop-bg);border:1px solid var(--pop-line);border-radius:14px;
  box-shadow:var(--pop-shadow);color:var(--pop-text-strong);
  font-size:var(--fs-note);line-height:1.6}
.lm-migrate-t{font-weight:600}
.lm-migrate-s{display:block;font-weight:400;color:var(--pop-text-dim);font-size:var(--fs-micro)}
.lm-migrate-btns{display:flex;gap:var(--sp-2);flex:0 0 auto}
.lm-migrate-btn{padding:8px 16px;border-radius:10px;border:1px solid var(--pop-line);
  background:transparent;color:var(--pop-text-strong);font-size:var(--fs-note);font-weight:600;
  cursor:pointer;transition:background-color .2s,border-color .2s,color .2s}
.lm-migrate-btn:hover{border-color:var(--pop-gold);background:var(--pop-hover)}
.lm-migrate-btn.yes{background:var(--pop-gold);border-color:var(--pop-gold);color:#fff}
.lm-migrate-btn.yes:hover{filter:brightness(1.06)}
.lm-migrate-btn:disabled{opacity:.6;cursor:default}
@media(prefers-reduced-motion:reduce){.lm-migrate-btn{transition:none}}

/* ══════════════════════════════════════════════════════════════════════════════
   V21–V25 共享组件（唯一真源）—— 2026-10-16 全量重做视觉
   ──────────────────────────────────────────────────────────────────────────────
   用户实测：「深入观察跳转的几个页面跟其他页面不是一个层次，太粗糙」。
   复查后确认病根不在配色，而在**几何**：
     · 站内数据页（news/models/predict/track-record/methodology）内容列统一是
       **880px / 左右 48px / 顶部 calc(--nav-h + 60px)**，而我给这 6 个新页写了 1120px
       ⇒ 更宽、更散、更「文档化」，与全站不是同一把尺子；
     · 头部自造了一套 .lmx-eyebrow/.lmx-h1/.lmx-lede，而站内是 .eyebrow（带 18px
       短横线的结构件）+ .page-header h1 的 clamp 字号 —— 自造的那套自然差一档；
     · KPI 是「浮起来的圆角小卡」，而站内是**分段数据带**（1px 发丝线分割、数字在上、
       等宽数字）—— 这才是本站自己长出来的样子；
     · 卡片是 --line2 粗描边 + 14px 圆角，站内是 1px --line + --r-card(12px)。
   这一版全部换成站内语言：列宽 / 头部 / 数据带 / 卡片几何与站内一致；
   字号一律 --fs-*，圆角一律 --r-*，数字 tabular-nums。
   ══════════════════════════════════════════════════════════════════════════ */
.lmx-wrap{max-width:880px;margin:0 auto;padding:calc(var(--nav-h) + 60px) 48px var(--sp-8)}
/* 两栏工具页（证据工作台：左选证据 / 右出提纲）需要更宽的列，单独放行 ——
   与 sources.html(900) / about.html(820) 一样属「同族不同宽」，不是另立一套。 */
.lmx-wrap.wide{max-width:1120px}

/* ── 页头：与站内 .page-header 同一套几何（eyebrow 用共享 .eyebrow，自带短横线）── */
.lmx-head{padding-bottom:var(--sp-6)}
.lmx-head .eyebrow{color:var(--gold);margin-bottom:var(--sp-1)}
.lmx-head h1{font-size:clamp(1.9rem,1rem + 2.6vw,var(--fs-page-title));font-weight:700;
  line-height:1.18;letter-spacing:-.4px;color:var(--text);margin-bottom:var(--sp-2)}
.lmx-head p{font-size:var(--fs-body);color:var(--text2);line-height:1.8;max-width:640px}

.lmx-sec{margin-top:var(--sp-7)}
.lmx-sec-title{font-size:var(--fs-lead);font-weight:700;color:var(--text);letter-spacing:-.3px;
  margin-bottom:var(--sp-2);display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.lmx-sec-note{font-size:var(--fs-micro);color:var(--text3);line-height:1.85;margin-bottom:var(--sp-3)}
.lmx-card{background:var(--bg);border:1px solid var(--line);border-radius:var(--r-card);padding:var(--sp-45)}
.lmx-grid{display:grid;gap:var(--sp-3)}

/* ── KPI 数据带：站内 .kpi-strip 的同款几何（1px 发丝线分割、数字在上）──
   ★ 列宽用 minmax(0,1fr) 而不是 minmax(150px,1fr)：880 列宽（内容 784px）下
     5 张卡按 150px 最小宽度差 1px 放不下，会折成「4 张 + 1 张孤行」——
     信任墙截图实测。minmax(0,1fr) 让列数恒等于卡片数，永不折行；
     小屏由下面的 @media(≤768px) 切成两列。 */
.lmx-kpi{display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:1px;
  background:var(--line);border:1px solid var(--line);border-radius:var(--r-card);overflow:hidden;
  margin:var(--sp-3) 0 0}
.lmx-kpi-i{background:var(--bg);padding:var(--sp-4) var(--sp-4) var(--sp-3)}
.lmx-kpi-v{font-family:var(--mono);font-size:var(--fs-page);font-weight:700;color:var(--text);
  line-height:1.05;letter-spacing:-1px;font-variant-numeric:tabular-nums}
.lmx-kpi-u{font-size:var(--fs-micro);font-weight:400;color:var(--text3);margin-left:2px;letter-spacing:0}
.lmx-kpi-l{font-size:var(--fs-micro);font-weight:700;color:var(--text2);letter-spacing:.5px;margin-top:var(--sp-2)}
.lmx-kpi-h{font-size:var(--fs-micro);color:var(--text3);line-height:1.7;margin-top:1px}

.lmx-btn{display:inline-flex;align-items:center;gap:var(--sp-1);padding:var(--sp-2) var(--sp-4);border-radius:var(--r-btn);
  border:1px solid var(--line2);background:transparent;color:var(--text2);font-size:var(--fs-note);font-weight:600;
  cursor:pointer;text-decoration:none;transition:border-color .2s,color .2s,background-color .2s;font-family:inherit}
.lmx-btn:hover{border-color:var(--gold-decor);color:var(--gold);background:var(--gold-dim)}
.lmx-btn.primary{background:var(--gold);border-color:var(--gold);color:#fff}
.lmx-btn.primary:hover{color:#fff;background:var(--gold);opacity:.92}
.lmx-btn[disabled]{opacity:.45;cursor:not-allowed}
.lmx-btn[disabled]:hover{border-color:var(--line2);color:var(--text2);background:transparent}
.lmx-actions{display:flex;gap:var(--sp-2);flex-wrap:wrap;align-items:center;margin:var(--sp-3) 0}

.lmx-chip{display:inline-flex;align-items:center;gap:var(--sp-1);padding:0 var(--sp-2);border-radius:999px;
  font-size:var(--fs-micro);font-weight:700;line-height:1.9;border:1px solid var(--line2);color:var(--text3);background:transparent}
.lmx-chip.gold{border-color:var(--gold-dim-strong);color:var(--gold);background:var(--gold-dim)}
.lmx-chip.ok{color:#356b41;border-color:rgba(53,107,65,.38);background:rgba(63,122,74,.08)}
.lmx-chip.warn{color:#8a5c22;border-color:rgba(138,92,34,.38);background:rgba(154,106,47,.08)}
.lmx-chip.bad{color:#a4433a;border-color:rgba(164,67,58,.32);background:rgba(164,67,58,.07)}

.lmx-state{background:var(--bg2);border:1px dashed var(--line2);border-radius:var(--r-card);
  padding:var(--sp-5) var(--sp-4);text-align:center;color:var(--text3);font-size:var(--fs-note);line-height:1.95}
.lmx-state b{color:var(--text2)}
.lmx-state.partial{border-style:solid;border-color:rgba(154,106,47,.35);background:rgba(154,106,47,.05);text-align:left}
.lmx-hint{font-size:var(--fs-micro);color:var(--text3);line-height:1.85}
.lmx-mono{font-family:var(--mono);font-variant-numeric:tabular-nums}
.lmx-row{display:flex;align-items:baseline;gap:var(--sp-2);flex-wrap:wrap}
.lmx-tag{font-size:var(--fs-micro);color:var(--text3);font-family:var(--mono);white-space:nowrap}
.lmx-link{color:var(--gold);text-decoration:none}
.lmx-link:hover{text-decoration:underline}

.lmx-table{width:100%;border-collapse:collapse;font-size:var(--fs-note)}
.lmx-table th{text-align:left;font-size:var(--fs-micro);color:var(--text2);font-weight:700;letter-spacing:.4px;
  background:var(--bg2);padding:var(--sp-2) var(--sp-3);border-bottom:1px solid var(--line);white-space:nowrap}
.lmx-table td{padding:var(--sp-2) var(--sp-3);border-bottom:1px solid var(--line);color:var(--text2);vertical-align:top}
.lmx-table tr:last-child td{border-bottom:none}
.lmx-table .num{text-align:right;font-variant-numeric:tabular-nums;font-family:var(--mono);white-space:nowrap}
.lmx-table .miss{color:var(--text3);text-align:right;font-family:var(--mono)}

/* ── 「来源与方法」折叠：做成一个安静的开关，不是裸边框方块 ── */
.lmx-fold{border:1px solid var(--line);border-radius:var(--r-btn);background:var(--bg2)}
.lmx-fold summary{cursor:pointer;font-size:var(--fs-micro);font-weight:600;color:var(--text2);list-style:none;
  display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-2) var(--sp-3);transition:color .2s}
.lmx-fold summary::-webkit-details-marker{display:none}
.lmx-fold summary::before{content:"";flex:0 0 auto;width:0;height:0;border-left:5px solid currentColor;
  border-top:4px solid transparent;border-bottom:4px solid transparent;transition:transform .2s var(--ease)}
.lmx-fold[open] summary::before{transform:rotate(90deg)}
.lmx-fold summary:hover{color:var(--gold)}
.lmx-fold .lmx-hint{padding:0 var(--sp-3) var(--sp-3);margin-top:0}

.lmx-proof{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;
  border:1px solid var(--line2);color:var(--text3);font-size:var(--fs-micro);cursor:pointer;background:transparent;
  line-height:1;vertical-align:middle;margin-left:var(--sp-1);font-family:inherit}
.lmx-proof:hover{border-color:var(--gold);color:var(--gold)}

.lmx-band{display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-2) 0;border-bottom:1px solid var(--line);flex-wrap:wrap}
.lmx-band:last-child{border-bottom:none}
.lmx-band-v{flex:0 0 92px;font-size:var(--fs-note);font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lmx-band-track{flex:1;display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;min-width:0}
.lmx-node{display:inline-flex;align-items:center;gap:var(--sp-1);font-size:var(--fs-micro);color:var(--text2);
  border:1px solid var(--line2);border-radius:999px;padding:0 var(--sp-2);text-decoration:none;white-space:nowrap;line-height:1.9}
.lmx-node:hover{border-color:var(--gold-decor);color:var(--gold)}
.lmx-node i{width:6px;height:6px;border-radius:50%;background:var(--gold-decor);display:inline-block}
.lmx-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}

/* ── 「继续深入」互链（共享）─────────────────────────────────────────────────
   新页之间的横向导航；做成一排卡片：名称 + 一句「你能得到什么」，整卡可点。 */
.lmx-deep{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:var(--sp-2)}
.lmx-deep-i{position:relative;display:flex;flex-direction:column;gap:var(--sp-1);padding:var(--sp-3);
  background:var(--bg);border:1px solid var(--line);border-radius:var(--r-card);text-decoration:none;
  transition:border-color .2s var(--ease),transform .2s var(--ease)}
.lmx-deep-i:hover{border-color:var(--gold-decor);transform:translateY(-1px)}
.lmx-deep-i b{font-size:var(--fs-note);color:var(--text);font-weight:600}
.lmx-deep-i span{font-size:var(--fs-micro);color:var(--text3);line-height:1.7}
.lmx-deep-i i{position:absolute;right:var(--sp-3);top:var(--sp-3);font-style:normal;color:var(--text3);font-size:var(--fs-micro)}
.lmx-deep-t{font-size:var(--fs-micro);font-weight:700;letter-spacing:.4px;color:var(--text3);margin-bottom:var(--sp-2)}

@media (max-width:768px){
  .lmx-wrap{padding:calc(var(--nav-h-sm) + 38px) 20px 60px}
  .lmx-band-v{flex-basis:100%}
  .lmx-kpi{grid-template-columns:1fr 1fr}
}

/* ── 页内目录（page-toc）：一个组件，一份数字 ────────────────────────────────
   2026-10-16 用户：「首页加一下几个栏目的导航栏，就跟预测页面一样」——
     当时预测页有一份私有的 .lab-toc，我把它「复制」到 site.css 给首页用，
     于是同一站里长出了两份目录 CSS。
   2026-10-17 用户贴了两张截图问「这俩怎么对不上」。实测（1440×900）：

     项目            首页 .page-toc.side      预测页 .lab-toc
     栏左缘          156                      160
     栏宽            150                      172
     文字左缘        175                      172
     行距            36.5                     38.1
     字距            .2px                     .5px
     当前项          金雾底 + 700             只有金轨 + 600
     正文左缘        326                      356          ← 换页时整页文字横跳 30px
     吸顶位置        导航下 88px              导航下 16px

   现在的规则只有一条：**视觉只在 site.css 写一次，页面只声明「我占哪一列」**。
     · 栏宽 = --toc-w，轨与正文的间隙 = --toc-gap；
     · 正文让位量 = calc(流向内边距 + --toc-w + --toc-gap)，任何页面不得再写字面量；
     · 预测页用网格第一列（sticky，天然不遮正文），首页用 fixed 贴同一条 gutter 线
       （首页的 .main-content 里还躺着导航/资讯条/页脚，改成网格会连它们一起挪，
        收益为零、风险不小 —— 位置由 JS 夹取，见 initHomeToc 的 place()）。
   窄屏形态：正文上方一条胶囊横条，**不吸顶**（悬停会盖住滚过的标题，实测翻车）。 */
.page-toc{
  display:flex;gap:2px;align-items:center;overflow-x:auto;-webkit-overflow-scrolling:touch;
  box-sizing:border-box;width:max-content;max-width:100%;margin:0 0 var(--sp-4);
  padding:var(--sp-1) var(--sp-2);
  background:rgba(255,255,255,.94);border:1px solid var(--line);border-radius:999px;
  scrollbar-width:none}
.page-toc::-webkit-scrollbar{display:none}
/* 横条目录溢出时的边缘渐隐（2026-10-18）：
   768 宽度下 11 个标签放不下，scrollbar 被隐藏了，最后一项被切掉半个字 ——
   没有任何提示说明「还能往右滑」。渐隐只在真的溢出时出现（JS 打 .is-overflow），
   并且随滑动方向换边：能右滑→淡右缘；滑到底→淡左缘；两边都有→两边淡。 */
@media (max-width:1199px){
  .page-toc.is-overflow.at-start:not(.at-end){
    -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 32px),transparent);
    mask-image:linear-gradient(to right,#000 calc(100% - 32px),transparent)}
  .page-toc.is-overflow.at-end:not(.at-start){
    -webkit-mask-image:linear-gradient(to left,#000 calc(100% - 32px),transparent);
    mask-image:linear-gradient(to left,#000 calc(100% - 32px),transparent)}
  .page-toc.is-overflow:not(.at-start):not(.at-end){
    -webkit-mask-image:linear-gradient(to right,transparent,#000 32px,#000 calc(100% - 32px),transparent);
    mask-image:linear-gradient(to right,transparent,#000 32px,#000 calc(100% - 32px),transparent)}
}
.page-toc[hidden]{display:none}
.page-toc a{flex:none;padding:var(--sp-1) var(--sp-4);border-radius:999px;font-size:var(--fs-micro);
  font-weight:600;color:var(--text3);text-decoration:none;letter-spacing:.4px;white-space:nowrap;
  line-height:1.7;
  transition:color var(--dur-fast) var(--ease),background-color var(--dur-fast) var(--ease)}
.page-toc a:hover{color:var(--text)}
.page-toc a.is-cur{color:var(--gold);background:var(--gold-dim);font-weight:700}
/* 锚点落位要让开吸顶的站内导航，否则标题被压在下面 */
.page-toc-target,.js-toc-target{scroll-margin-top:calc(var(--nav-h) + var(--sp-4))}

/* ── 桌面竖排轨（≥1200px：低于它列内已无 --toc-w 可让，退回横条）──
   当前项为什么不再用「金雾底胶囊」：竖排轨已经有 2px 金色导轨在指示位置，
   再叠一层底色就成了按钮，不再是目录；金轨 + 金字 + 600 已经足够辨认。 */
@media (min-width:1200px){
  .page-toc.side{
    position:sticky;top:calc(var(--nav-h) + var(--sp-4));
    display:flex;flex-direction:column;align-items:stretch;gap:0;
    width:var(--toc-w);max-width:none;margin:0;padding:0;
    background:none;border:0;border-radius:0;
    max-height:calc(100vh - var(--nav-h) - var(--sp-6) * 2);
    overflow-x:hidden;overflow-y:auto;scrollbar-width:none;z-index:5}
  .page-toc.side::-webkit-scrollbar{display:none}
  .page-toc.side a{flex:none;text-align:left;border-radius:0 999px 999px 0;
    padding:var(--sp-2) var(--sp-3);border-left:2px solid var(--line);
    font-size:var(--fs-note);font-weight:500;letter-spacing:.5px;line-height:1.7;
    color:var(--text2);overflow:hidden;text-overflow:ellipsis}
  .page-toc.side a:hover{background:var(--bg2);color:var(--text);border-left-color:var(--text3)}
  .page-toc.side a.is-cur{background:none;color:var(--gold);border-left-color:var(--gold);font-weight:600}

  /* 会滑的那根金线：由 site.js 的 paintBar 定位（transform/height 过渡，无布局抖动）。
     ★ 只有 JS 跑起来（加上 .has-cur-ind）时，逐条金轨才压成灰线 —— 否则没脚本
       的用户会一根金线都看不到。这是「渐进增强」，不是「JavaScript 才能看」。 */
  .page-toc .toc-cur{display:none}
  .page-toc.side .toc-cur{
    display:block;position:absolute;left:0;top:0;width:2px;
    background:var(--gold);pointer-events:none;
    transition:transform .3s var(--ease),height .3s var(--ease)}
  .page-toc.side.has-cur-ind a.is-cur{border-left-color:var(--line)}

  /* 预测页那种「目录就是正文第一列」的版式：给它所在的容器加 .toc-layout 即可。
     ★ 为什么把这些规则也收在 site.css：页面里一旦允许写 .page-toc 选择器，
       两份样式就又有了滋生的土壤（这次就是这么长歪的）。页面只加一个类名。 */
  .toc-layout{display:grid;grid-template-columns:var(--toc-w) minmax(0,1fr);
    column-gap:var(--toc-gap);align-items:start}
  .toc-layout > :not(.page-toc){grid-column:2}
  .toc-layout > .page-toc{grid-column:1;grid-row:1 / span 30;align-self:start}

  /* 有左侧目录的页面：页头与正文落在同一条左缘上。
     原来页头在 gutter（160）、正文在 356 —— 同一屏里标题孤零零地挂在正文左边
     196px 处，像两块不相干的内容；首页的标题本来就在 356，两页对比更明显。 */
  body.has-toc-rail .page-header{
    padding-left:calc(max(var(--gutter), (100% - var(--cw-page)) / 2) + var(--toc-w) + var(--toc-gap))}

  /* 首页：目录贴 gutter 线固定，正文让出 --toc-w + --toc-gap
     ★★ 2026-10-27（用户报「目录飞到上面压住导航」）：这里原来是
        `position:fixed` 但**没有 top** —— 位置全靠 JS 的 place() 写内联值。
        于是"JS 还没跑"或"跑的时候布局还没定"的那一小段，top:auto 会让浏览器把
        这个 fixed 元素放回它的**静态位置**（视口坐标等于首次布局时 #secExplore 的 top），
        页面上就是目录跑到最上面、压在品牌名上。
        两条保险：
          ① 给一个 CSS 兜底 top（导航下方 16px，吸顶态的正确位置）——
             即便 JS 完全失败，它也只会贴在导航下面，不会飞到顶上；
          ② 默认 opacity:0，place() 成功写进正确的 top 之后才加 .is-placed 显形 ——
             宁可晚一帧出现，也不要先出现在错的地方再跳过去。 */
  .home .page-toc.side{
    position:fixed;z-index:55;
    top:calc(var(--nav-h) + var(--sp-4));
    opacity:0;
    left:max(var(--gutter), calc((100% - var(--cw-page)) / 2))}
  .home .page-toc.side.is-placed{opacity:1}
  .home .main-content > .section{
    padding-left:calc(max(var(--gutter), (100% - var(--cw-page)) / 2) + var(--toc-w) + var(--toc-gap))}
  /* 竖排没有横条了，锚点只需让开站内导航 */
  .home .page-toc-target{scroll-margin-top:calc(var(--nav-h) + var(--sp-4))}
}
@media (max-width:768px){
  .page-toc-target,.js-toc-target{scroll-margin-top:calc(var(--nav-h-sm) + var(--sp-4))}
}

/* ── 导航直接拖（2026-10-18 修正：上一版要先进"编辑模式"，用户根本拖不动）──
   现在导航项本身就能拖，所以只需要三个状态：
     ① 平时：鼠标悬停时给 grab 光标（暗示"可以动"）；
     ② 拖动中：整项抬起 + 浅金底 + 抓手光标；
     ③ 拖动期间禁掉文字选中，避免拖一半变成选词。 */
.nav-items .nav-item{cursor:grab}
body.nav-dragging{user-select:none}
body.nav-dragging .nav-items .nav-item{cursor:grabbing}
.nav-items .nav-item.is-dragging{
  cursor:grabbing;
  background:var(--gold-dim);
  box-shadow:0 6px 18px rgba(40,30,15,.16);
  border-radius:6px;
  position:relative;
  z-index:3;
}

/* ── S01 按压反馈（2026-10-20）──────────────────────────────────────────
   文档里的共用规格：按下 100ms 内要有"点到了"的确认，且不移动周边布局。
   只加 transform、不改各组件既有的 transition / border 规则 ——
   一次全局的 transition 覆盖会把这些组件各自的手感一起抹平。 */
@media (prefers-reduced-motion: no-preference){
  button:not(:disabled):active,
  .btn:not(:disabled):active,
  a.btn:active,
  .chip:active,
  .g-cat:active { transform: scale(.98); }
}

/* ── 全站轻提示 LM_TOAST（2026-10-20，P0 改成右上）────────────────────
   ★ 为什么改位置：用户实测「提示不明显、而且过于偏下」。
     第一版固定在视口**底部居中**，而触发它的动作多数发生在右上（账户菜单）
     与卡片内部 —— 视线要跨整屏才能看到，等于没反馈。
     现在固定在**导航下沿右侧**，与账户菜单同一视觉列：出现的位置就是用户
     刚才看的位置。
   ★ 类型只由左侧圆形图标承担（✓ / !），不再整条染色，也不再加左缘色条 ——
     小卡片上叠三层色会抢走页面主色。
   ★ 移动端（≤640）改成导航下**整宽条**：小屏上角标太小，整宽才像系统提示。
   配色走 --pop-*（共享组件不读页面级主题变量）；连点只保留最新一条。 */
.lm-toast{
  position:fixed; right:var(--gutter); top:calc(var(--nav-h) + var(--sp-3));
  z-index:1200; max-width:min(72vw, 24em);
  display:flex; align-items:center; gap:var(--sp-2);
  padding:var(--sp-3) var(--sp-4);
  background:var(--pop-bg); border:1px solid var(--pop-line);
  border-radius:var(--r-card); box-shadow:var(--pop-shadow);
  color:var(--pop-text-strong);
  font-size:var(--fs-note); line-height:1.6; text-align:left;
  opacity:0; transform:translateY(calc(-1 * var(--sp-2)));
  pointer-events:none;
  transition:opacity .16s ease, transform .16s ease;
}
.lm-toast.is-on{ opacity:1; transform:translateY(0); pointer-events:auto; cursor:pointer; }
.lm-toast-ic{
  flex:0 0 auto; width:1.2em; height:1.2em; line-height:1.2em;
  border-radius:50%; text-align:center; font-weight:700; font-size:var(--fs-micro);
  color:#fff; background:var(--pop-line);
}
.lm-toast-ic:empty{ display:none; }
.lm-toast.is-ok .lm-toast-ic{ background:var(--sem-ok); }
.lm-toast.is-error .lm-toast-ic{ background:var(--sem-danger); }
.lm-toast-tx{ min-width:0; }
@media (max-width:640px){
  .lm-toast{
    left:var(--gutter); right:var(--gutter); max-width:none;
    top:calc(var(--nav-h) + var(--sp-2));
  }
}
@media (prefers-reduced-motion: reduce){
  .lm-toast{ transition:none; }
}
/* 菜单项就地反馈：反馈出现在触发点本身（见 site.js 的 navOrderReset）。
   只改文字色与字重，不加背景 —— 菜单项整行变绿会比"没反馈"更吵。 */
.user-menu-item.is-done{ color:var(--sem-ok); font-weight:600; }
