/* ============================================================
   学习中心 · 组件样式 components.css v1.1（设计系统组独占写域）
   依赖：tokens.css + base.css（按此顺序先引入）
   目录：
     1. 内容语义类（契约 §3.3）：.formula(.f) / .code / .callout / .fig / .term
        + 讲义补充类 .label / .lede / .meta
     2. 全站壳：顶栏 / 侧栏 / 内容区 / AI 助教抽屉(lc-chat-*) / 移动端 tabbar
     3. 学习卡（正反面翻转 + 滑动打分）
     4. 模块卡 / 进度环 / 热力图
     5. 测验选项
     6. 聊天消息区与输入区（lc-chat-*）
     7. 标签 pill / 空状态 / 杂项
     8. legacy 卡片正文兼容层（旧类官方样式 + 深色覆盖补丁）
   ============================================================ */

/* ============ 1. 内容语义类（契约 §3.3）============ */

/* ---- .formula 公式块 ----
   兼容现有 442 卡的手写公式 HTML，非 LaTeX。旧卡正文保留原类名
   class="f"，与 .formula 完全同款（选择器并列）；.frac/.den 为独立
   结构选择器，不要求 .formula/.f 祖先（存量卡有裸 .frac）。
   · <b> 约定为下标强调（承 v1 卡片页写法）
   · <i> 为变量斜体；<sub>/<sup> 正常
   · 分数：<span class="frac"><span>分子</span><span class="den">分母</span></span>
   · span.label：公式右侧弱化小注释（条件/编号）
   KaTeX 属二期，本轮不引入。 */
.formula,.f{margin:var(--sp-4) 0;padding:11px var(--sp-4);
  background:var(--surface-2);border:1px solid var(--line);
  border-left:3px solid var(--dm);border-radius:0 var(--r-sm) var(--r-sm) 0;
  font-family:var(--font-math);font-size:16.5px;letter-spacing:.2px;
  color:var(--text-1);text-align:center;overflow-x:auto}
.formula b,.f b{font-weight:400;font-size:.7em;vertical-align:sub;
  color:var(--brand-ink);font-style:normal;letter-spacing:0}
.formula i,.f i{font-style:italic;color:var(--brand-ink)}
.formula sub,.f sub{font-size:.7em}
.frac{display:inline-block;vertical-align:-.55em;text-align:center;margin:0 3px}
.frac>span{display:block;line-height:1.15;padding:0 5px}
.frac .den{border-top:1.4px solid currentColor}
.formula .label,.f .label{float:right;margin-left:12px;
  font-family:var(--font-sans);font-size:var(--fs-xs);font-style:normal;
  font-weight:400;color:var(--text-3);letter-spacing:0;line-height:2}
/* 行内小公式（句中变量组合）*/
.formula-inline{font-family:var(--font-math);font-style:italic;color:var(--brand-ink);
  white-space:nowrap}

/* ---- 讲义补充类（契约 v1.1 §3.3 批准）：article header 内 ---- */
article header .lede{font-family:var(--font-serif);font-size:var(--fs-lg);
  color:var(--text-3);line-height:1.75;margin:var(--sp-2) 0 var(--sp-3);max-width:60ch}
article header .meta{display:flex;gap:var(--sp-3);flex-wrap:wrap;
  font:var(--fs-xs)/1.6 var(--font-mono);color:var(--text-3);margin-bottom:var(--sp-2)}

/* ---- .code 代码块（契约：<pre class="code" data-lang="python">）----
   双主题固定深色编辑器质感（--code-* 不随主题翻转）。 */
pre.code{position:relative;margin:var(--sp-4) 0;padding:var(--sp-4);
  padding-top:calc(var(--sp-4) + 14px);
  background:var(--code-bg);border:1px solid var(--code-line);border-radius:var(--r-md);
  color:var(--code-ink);font:12.5px/1.65 var(--font-mono);
  overflow-x:auto;white-space:pre;tab-size:2}
pre.code code{background:none;color:inherit;padding:0;font:inherit;white-space:pre}
pre.code::before{content:attr(data-lang);position:absolute;top:8px;right:12px;
  font:var(--fs-xs) var(--font-mono);color:var(--code-muted);text-transform:lowercase}
/* 复制按钮由 JS 注入 <button class="code-copy">，样式在此备好 */
.code-copy{position:absolute;top:6px;left:10px;background:transparent;
  border:1px solid var(--code-line);color:var(--code-muted);
  border-radius:var(--r-xs);padding:2px 10px;font-size:var(--fs-xs);cursor:pointer}
.code-copy:hover{color:var(--code-ink);border-color:var(--code-muted)}

/* ---- .callout 要点框（data-variant: info | warn | key）---- */
.callout{--co:var(--brand);--co-soft:var(--brand-soft);
  margin:var(--sp-4) 0;padding:10px 14px;font-size:var(--fs-base);
  background:var(--co-soft);color:var(--text-1);
  border-left:4px solid var(--co);border-radius:0 var(--r-sm) var(--r-sm) 0}
.callout[data-variant="warn"]{--co:var(--warn);--co-soft:var(--warn-soft)}
.callout[data-variant="key"]{--co:var(--ochre);--co-soft:var(--mark-bg);color:var(--mark-ink)}
.callout>b:first-child,.callout>.co-title{color:var(--co);font-weight:800}
.callout[data-variant="key"]>b:first-child{color:var(--mark-ink)}
.callout p:last-child{margin-bottom:0}
/* 嵌套 callout：内层收窄、去底色，避免叠成深色块 */
.callout .callout{margin:var(--sp-2) 0 0;padding:6px 12px;background:transparent;
  border-left-width:3px;border-radius:0;font-size:var(--fs-sm)}

/* ---- .fig SVG 示意图容器 ----
   SVG 内禁止写死 fill/stroke 字面量，用下列语义类换肤。 */
.fig{margin:var(--sp-4) 0}
.fig .fig-body{background:var(--surface-2);border:1px solid var(--line);
  border-radius:var(--r-md);padding:var(--sp-4);display:grid;place-items:center;
  overflow-x:auto}
.fig svg{max-width:100%;height:auto}
.fig figcaption{font-size:var(--fs-sm);color:var(--text-3);text-align:center;
  margin-top:var(--sp-2)}
.fig svg text{font-family:var(--font-sans)}
.fig svg .s-ink{stroke:var(--text-1)}    .fig svg .s-line{stroke:var(--line-strong)}
.fig svg .s-brand{stroke:var(--dm)}      .fig svg .s-accent{stroke:var(--accent)}
.fig svg .s-warn{stroke:var(--warn)}     .fig svg .s-ok{stroke:var(--ok)}
.fig svg .f-ink{fill:var(--text-1)}      .fig svg .f-muted{fill:var(--text-3)}
.fig svg .f-surface{fill:var(--surface)} .fig svg .f-brand{fill:var(--dm)}
.fig svg .f-soft{fill:var(--brand-soft)} .fig svg .f-none{fill:none}

/* ---- .term 术语（点击可唤聊天解释，行为由 chat.js 挂）---- */
.term{cursor:help;color:var(--text-1);font-weight:600;
  text-decoration:underline dotted color-mix(in srgb,var(--accent) 65%,transparent);
  text-decoration-thickness:1.5px;text-underline-offset:3px}
.term:hover,.term:focus-visible{color:var(--accent);
  background:color-mix(in srgb,var(--accent) 10%,transparent);border-radius:3px}

/* ============ 2. 全站壳 ============ */

/* ---- 顶栏 ---- */
.topbar{position:sticky;top:0;z-index:var(--z-topbar);display:flex;align-items:center;
  gap:var(--sp-3);height:56px;padding:0 var(--sp-4);
  border-bottom:1px solid color-mix(in srgb,var(--line) 70%,transparent)}
.site-brand{font-size:var(--fs-md);font-weight:800;color:var(--text-1);
  white-space:nowrap;text-decoration:none}
.site-brand:hover{text-decoration:none;color:var(--dm)}
.searchbox{display:flex;align-items:center;gap:8px;min-height:36px;max-width:420px;
  flex:1;padding:0 14px;border-radius:var(--r-full);cursor:pointer;text-align:left;
  background:var(--surface-3);border:1px solid var(--line);
  color:var(--text-3);font-size:var(--fs-sm)}
.searchbox:hover{border-color:var(--line-strong)}
.searchbox kbd{margin-left:auto}
.nav-burger{display:none}

/* ---- 骨架：侧栏 + 内容 ---- */
.shell{display:flex;min-height:calc(100dvh - 56px)}
.sidebar{width:248px;flex:none;position:sticky;top:56px;height:calc(100dvh - 56px);
  overflow-y:auto;padding:var(--sp-4) var(--sp-3);
  border-right:1px solid var(--line);background:var(--bg)}
.nav-group{font-size:var(--fs-xs);color:var(--text-3);font-weight:700;
  letter-spacing:1px;margin:var(--sp-4) 10px var(--sp-1)}
.nav-link{display:flex;align-items:center;gap:var(--sp-2);min-height:40px;
  padding:6px 10px;border-radius:var(--r-sm);margin:2px 0;
  color:var(--text-2);font-size:var(--fs-sm);text-decoration:none;cursor:pointer}
.nav-link:hover{background:var(--surface-2);text-decoration:none}
.nav-link.on{background:var(--brand-soft);color:var(--dm);font-weight:700}
.nav-link .nl-ic{width:20px;text-align:center;flex:none;font-size:15px}
.nav-link .nl-n{margin-left:auto;font:var(--fs-xs) var(--font-mono);color:var(--text-3)}
.content{flex:1;min-width:0;padding:var(--sp-6) var(--sp-7) var(--sp-10)}
.content>.page-enter,main.page-enter{animation:pageIn var(--t-base) var(--ease-out)}
@keyframes pageIn{from{opacity:0;transform:translateY(8px)}}
/* 遮罩：≤768px 侧栏抽屉用（壳组 shell.js 切 .show）*/
.scrim{position:fixed;inset:0;z-index:calc(var(--z-sidebar) - 1);
  background:rgba(20,16,8,.35);opacity:0;pointer-events:none;
  transition:opacity var(--t-base) linear}
.scrim.show{opacity:1;pointer-events:auto}
/* ≥1440px 聊天抽屉可钉住：内容让位不被盖 */
@media (min-width:1440px){
  body.chat-pinned .content{margin-right:420px}
  body.chat-pinned .lc-chat-drawer{box-shadow:none;width:420px}
}

/* 内容宽度档（页面在 .content 内套一层即可）*/
.w-dash{max-width:1240px;margin:0 auto}
.w-domain{max-width:1080px;margin:0 auto}
.w-card{max-width:560px;margin:0 auto}
.w-read{max-width:780px;margin:0 auto}
.w-quiz{max-width:640px;margin:0 auto}

/* ---- AI 助教抽屉（聊天组 chat.js 真实类名：lc-chat-*）----
   开合由 JS 切 .lc-chat-drawer--open（transform 105%↔0），CSS 只管
   定位与 transform 过渡。非模态：不锁滚动；遮罩仅 ≤768px 显示。 */
.lc-chat-drawer{position:fixed;top:0;right:0;bottom:0;z-index:var(--z-chat);
  width:clamp(380px,30vw,420px);max-width:100vw;
  display:flex;flex-direction:column;
  background:var(--surface);border-left:1px solid var(--line);box-shadow:var(--shadow-3);
  transform:translateX(105%);transition:transform var(--t-slow) var(--ease-out)}
.lc-chat-drawer--open{transform:translateX(0)}
.lc-chat-backdrop{position:fixed;inset:0;z-index:calc(var(--z-chat) - 1);
  background:rgba(20,16,8,.35)}
@media (min-width:769px){.lc-chat-backdrop{display:none}} /* 桌面非模态 */
.lc-chat-fab{position:fixed;right:18px;bottom:calc(18px + env(safe-area-inset-bottom));
  z-index:calc(var(--z-chat) - 2);width:52px;height:52px;border-radius:var(--r-full);
  border:none;background:var(--dm);color:var(--on-solid);font-size:22px;
  display:grid;place-items:center;cursor:pointer;box-shadow:var(--shadow-2);
  transition:transform var(--t-fast) var(--ease-spring),box-shadow var(--t-fast)}
.lc-chat-fab:hover{transform:translateY(-2px);box-shadow:var(--shadow-3)}
.lc-chat-fab:active{transform:scale(.94)}

/* 头部 */
.lc-chat-head{display:flex;align-items:center;gap:var(--sp-2);flex:none;
  min-height:52px;padding:0 var(--sp-3) 0 var(--sp-4);border-bottom:1px solid var(--line)}
.lc-chat-title{flex:1;min-width:0;font-weight:800;font-size:var(--fs-md);
  color:var(--text-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lc-chat-head-actions{display:flex;gap:2px;flex:none}
/* 变体可不带基类单独使用，故并列覆盖 */
.lc-chat-btn,.lc-chat-btn-new,.lc-chat-btn-sessions,
.lc-chat-btn-settings,.lc-chat-btn-close{
  position:relative;width:38px;height:38px;border:none;
  border-radius:var(--r-sm);background:transparent;color:var(--text-2);
  font-size:16px;display:grid;place-items:center;cursor:pointer}
.lc-chat-btn::before,.lc-chat-btn-new::before,.lc-chat-btn-sessions::before,
.lc-chat-btn-settings::before,.lc-chat-btn-close::before{
  content:"";position:absolute;inset:-4px} /* 热区 ≥44 */
.lc-chat-btn:hover,.lc-chat-btn-new:hover,.lc-chat-btn-sessions:hover,
.lc-chat-btn-settings:hover{background:var(--surface-2);color:var(--text-1)}
.lc-chat-btn-close:hover{background:var(--bad-soft);color:var(--bad)}

/* 设置面板 */
.lc-chat-settings{flex:none;max-height:60%;overflow-y:auto;
  padding:var(--sp-3) var(--sp-4);background:var(--surface-2);
  border-bottom:1px solid var(--line)}
.lc-chat-field{margin-bottom:var(--sp-3)}
.lc-chat-field-label{display:block;font-size:var(--fs-xs);font-weight:700;
  color:var(--text-3);margin-bottom:4px}
.lc-chat-input{width:100%;min-height:38px;padding:7px 10px;font-size:var(--fs-sm)}
.lc-chat-input-endpoint,.lc-chat-input-model,.lc-chat-input-key{
  font-family:var(--font-mono);font-size:var(--fs-xs)}
.lc-chat-settings-actions{display:flex;gap:var(--sp-2);align-items:center;
  flex-wrap:wrap;margin-top:var(--sp-2)}
.lc-chat-test,.lc-chat-save{min-height:38px;padding:0 var(--sp-3);
  border-radius:var(--r-sm);font-size:var(--fs-sm);font-weight:700;cursor:pointer}
.lc-chat-test{background:transparent;color:var(--dm);border:1px solid var(--line-strong)}
.lc-chat-test:hover{background:color-mix(in srgb,var(--dm) 8%,transparent)}
.lc-chat-save{background:var(--dm);color:var(--on-solid);border:none}
.lc-chat-save:active{transform:scale(.97)}
.lc-chat-test-result{font-size:var(--fs-xs);font-weight:700}
.lc-chat-test-result--ok{color:var(--ok)}
.lc-chat-test-result--err{color:var(--bad)}
.lc-chat-settings-note{margin-top:var(--sp-2);font-size:var(--fs-xs);
  color:var(--text-3);line-height:1.7}

/* 会话列表 */
.lc-chat-sessions{flex:none;max-height:50%;display:flex;flex-direction:column;
  background:var(--surface-2);border-bottom:1px solid var(--line)}
.lc-chat-session-list{overflow-y:auto;padding:var(--sp-2)}
.lc-chat-session-item{display:flex;align-items:center;gap:2px;
  border-radius:var(--r-sm)}
.lc-chat-session-item:hover{background:var(--surface-3)}
.lc-chat-session-item--active{background:var(--brand-soft)}
.lc-chat-session-open{flex:1;min-width:0;min-height:44px;text-align:left;
  background:none;border:none;padding:6px 10px;cursor:pointer}
.lc-chat-session-title{font-size:var(--fs-sm);font-weight:600;color:var(--text-1);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lc-chat-session-meta{font-size:var(--fs-xs);color:var(--text-3);margin-top:1px}
.lc-chat-session-del{flex:none;width:36px;height:36px;border:none;
  border-radius:var(--r-sm);background:transparent;color:var(--text-3);
  cursor:pointer;font-size:13px}
.lc-chat-session-del:hover{background:var(--bad-soft);color:var(--bad)}
.lc-chat-session-empty{padding:var(--sp-4);text-align:center;
  font-size:var(--fs-sm);color:var(--text-3)}

/* 上下文 pill（"正在看：xxx"）*/
.lc-chat-context{display:flex;align-items:center;gap:var(--sp-1);flex:none;
  margin:var(--sp-2) var(--sp-4) 0;padding:3px 6px 3px 12px;
  border-radius:var(--r-full);background:var(--accent-soft);
  font-size:var(--fs-xs);color:var(--accent)}
.lc-chat-context-label{flex:1;min-width:0;font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lc-chat-context-clear{position:relative;flex:none;width:22px;height:22px;
  border:none;border-radius:var(--r-full);background:transparent;color:inherit;
  font-size:12px;cursor:pointer;display:grid;place-items:center}
.lc-chat-context-clear::before{content:"";position:absolute;inset:-11px} /* 热区 */
.lc-chat-context-clear:hover{background:color-mix(in srgb,var(--accent) 18%,transparent)}

/* 模式条（讲透它/考考我/面试官）*/
.lc-chat-modes{display:flex;gap:var(--sp-2);flex-wrap:wrap;flex:none;
  padding:var(--sp-2) var(--sp-4)}
.lc-chat-mode{display:inline-flex;align-items:center;min-height:28px;position:relative;
  padding:2px 12px;border-radius:var(--r-full);border:1px solid transparent;
  font-size:var(--fs-xs);font-weight:700;cursor:pointer;color:var(--dm);
  background:color-mix(in srgb,var(--dm) 12%,var(--surface))}
.lc-chat-mode::before{content:"";position:absolute;inset:-8px} /* 触控热区 ≥44（审计 18·P2-5）*/
.lc-chat-mode:hover{border-color:var(--dm)}
.lc-chat-mode[aria-pressed="true"]{background:var(--dm);color:var(--on-solid)}

/* ---- 移动端底部 tabbar（≤768px 显示）---- */
.tabbar{display:none}
@media (max-width:768px){
  .tabbar{position:fixed;left:0;right:0;bottom:0;z-index:var(--z-topbar);
    display:flex;border-top:1px solid var(--line);
    padding:4px 0 calc(4px + env(safe-area-inset-bottom))}
  .tab{flex:1;display:flex;flex-direction:column;align-items:center;gap:1px;
    min-height:48px;justify-content:center;font-size:11px;color:var(--text-3);
    text-decoration:none;cursor:pointer}
  .tab:hover{text-decoration:none}
  .tab .tb-ic{font-size:20px;line-height:1.2}
  .tab.on{color:var(--dm);font-weight:700}
}

/* ---- 响应式：侧栏三档 ---- */
@media (max-width:1024px) and (min-width:769px){ /* 图标栏 */
  .sidebar{width:64px;padding:var(--sp-4) var(--sp-2)}
  .sidebar .nav-group,.sidebar .nav-link .nl-tx,.sidebar .nav-link .nl-n{display:none}
  .nav-link{justify-content:center;padding:6px}
  .content{padding:var(--sp-6) var(--sp-5) var(--sp-10)}
}
@media (max-width:768px){ /* 抽屉 */
  .nav-burger{display:grid}
  .searchbox{max-width:none}
  .searchbox kbd{display:none}
  .sidebar{position:fixed;top:0;left:0;bottom:0;z-index:var(--z-sidebar);
    width:min(300px,84vw);height:100dvh;background:var(--surface);
    box-shadow:var(--shadow-3);transform:translateX(-103%);visibility:hidden;
    transition:transform var(--t-slow) var(--ease-out),visibility 0s var(--t-slow)}
  .sidebar.open{transform:none;visibility:visible;transition-delay:0s}
  .content{padding:var(--sp-4) var(--sp-4) calc(72px + env(safe-area-inset-bottom))}
  /* 手机全屏（开合动画仍由 chat.js 控 transform）；100dvh 防 iOS 地址栏收放跳动，
     键盘顶起 composer 的 visualViewport 逻辑归聊天组（审计 18·P2-4）*/
  .lc-chat-drawer{width:100vw;top:auto;bottom:0;height:100dvh;border-left:none}
  .lc-chat-fab{bottom:calc(72px + env(safe-area-inset-bottom))} /* 让开 tabbar */
  /* 聊天输入手机档 16px 防 iOS 聚焦自动放大（类选择器优先级高于 base 的元素级规则）*/
  .lc-chat-textarea,.lc-chat-input{font-size:16px}
}

/* ============ 3. 学习卡 ============ */
.card-stage{perspective:1400px;max-width:560px;margin:0 auto;padding:var(--sp-2)}
.study-card{display:grid;position:relative;transform-style:preserve-3d;
  min-height:380px;cursor:grab;
  transition:transform var(--t-flip) var(--ease-flip)}
.study-card.flip{transform:rotateY(180deg)}
.study-card.dragging{transition:none;cursor:grabbing}
.face{grid-area:1/1;backface-visibility:hidden;-webkit-backface-visibility:hidden;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);
  padding:var(--sp-5) var(--sp-5) var(--sp-6);box-shadow:var(--edge-top),var(--shadow-2);
  display:flex;flex-direction:column;overflow:hidden}
.face.back{transform:rotateY(180deg);
  background:linear-gradient(160deg,
    color-mix(in srgb,var(--brand-soft) 55%,var(--surface)),
    color-mix(in srgb,var(--accent-soft) 45%,var(--surface)))}
.tagrow{display:flex;gap:var(--sp-1);flex-wrap:wrap;margin-bottom:var(--sp-2)}
.card-q{font-size:var(--fs-xl);font-weight:800;line-height:1.4;
  color:var(--text-1);margin:var(--sp-1) 0 var(--sp-3)}
.card-body{font-size:var(--fs-md);color:var(--text-2);line-height:1.75;
  flex:1;overflow-y:auto;min-height:0}
.card-body p{margin-bottom:9px}
.card-body b,.card-body strong{color:var(--text-1)}
.keypoint{margin-top:var(--sp-3);background:var(--mark-bg);color:var(--mark-ink);
  border-left:4px solid var(--ochre);border-radius:0 var(--r-sm) var(--r-sm) 0;
  padding:10px 14px;font-size:var(--fs-base);flex:none}
.keypoint b{color:var(--mark-ink)}
.amark{font-size:var(--fs-xs);font-weight:800;color:var(--accent);
  margin-bottom:var(--sp-2);flex:none}
.flip-tip{text-align:center;font-size:var(--fs-xs);color:var(--text-3);
  margin-top:var(--sp-3);flex:none}
/* 卡片状态徽标（active/outdated/deprecated，契约 §3.1）*/
.card-status{font-size:var(--fs-xs);font-weight:700;padding:1px 9px;
  border-radius:var(--r-full);flex:none}
.card-status[data-s="outdated"]{background:var(--warn-soft);color:var(--warn)}
.card-status[data-s="deprecated"]{background:var(--bad-soft);color:var(--bad)}

/* 滑动图章：拖动时 JS 按 |位移| 调 opacity */
.stamp{position:absolute;top:18px;z-index:2;font-size:var(--fs-lg);font-weight:900;
  padding:4px 14px;border:3px solid;border-radius:var(--r-sm);
  opacity:0;pointer-events:none;background:var(--surface)}
.stamp-know{right:18px;color:var(--ok);border-color:var(--ok);transform:rotate(-12deg)}
.stamp-rev{left:18px;color:var(--bad);border-color:var(--bad);transform:rotate(12deg)}
.stamp-easy{left:50%;translate:-50% 0;color:var(--accent);border-color:var(--accent)}

/* 滑出/回弹/进场（JS 挂 class）*/
.study-card.swipe-r{transition:transform .28s var(--ease-out),opacity .28s;
  transform:translateX(120%) rotate(8deg);opacity:0}
.study-card.swipe-l{transition:transform .28s var(--ease-out),opacity .28s;
  transform:translateX(-120%) rotate(-8deg);opacity:0}
.study-card.swipe-u{transition:transform .28s var(--ease-out),opacity .28s;
  transform:translateY(-110%);opacity:0}
.study-card.snap-back{transition:transform .2s var(--ease-spring)}
.study-card.enter{animation:cardIn .24s var(--ease-out)}
@keyframes cardIn{from{opacity:0;transform:translateY(14px) scale(.98)}}
.study-card.shake{animation:cardShake .3s var(--ease)}
@keyframes cardShake{25%{transform:translateX(-7px)}75%{transform:translateX(7px)}}

/* 四档评分（契约 §4：忘了/模糊/记住/秒会 = 1/2/3/4）*/
.card-ctrl{display:flex;gap:var(--sp-2);padding:var(--sp-3) var(--sp-1) var(--sp-1);
  max-width:560px;margin:0 auto}
.card-ctrl .btn{flex:1;padding:0 var(--sp-2)}
.card-ctrl .btn kbd{background:rgba(0,0,0,.14);border:none;color:inherit;opacity:.85}
.btn-easy{background:var(--accent);color:var(--on-solid)}
.card-counter{text-align:center;font-size:var(--fs-xs);color:var(--text-3);
  padding-top:var(--sp-2);font-variant-numeric:tabular-nums}
@media (max-width:768px){
  .card-stage{max-width:none;padding:var(--sp-1)}
  .card-ctrl{max-width:none}
  .card-ctrl .btn{min-height:48px;font-size:var(--fs-sm)}
  .card-ctrl .btn kbd{display:none}
}

/* ============ 4. 模块卡 / 进度环 / 热力图 ============ */
.module-card{display:flex;align-items:center;gap:var(--sp-4);position:relative;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:var(--sp-4) var(--sp-5);min-height:44px;
  text-decoration:none;color:var(--text-1);box-shadow:var(--edge-top),var(--shadow-1);
  transition:transform var(--t-fast) var(--ease),box-shadow var(--t-fast),
             border-color var(--t-fast)}
.module-card:hover{transform:translateY(-2px);box-shadow:var(--edge-top),var(--shadow-2);
  border-color:var(--dm);text-decoration:none}
.module-card:active{transform:scale(.985)}
.mc-icon{width:46px;height:46px;flex:none;border-radius:var(--r-md);
  display:grid;place-items:center;font-size:22px;
  background:color-mix(in srgb,var(--dm) 10%,var(--surface))}
.mc-info{flex:1;min-width:0}
.mc-name{font-weight:800;font-size:var(--fs-md)}
.mc-desc{font-size:var(--fs-sm);color:var(--text-3);margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mc-meta{display:flex;gap:var(--sp-3);font-size:var(--fs-xs);color:var(--text-3);
  margin-top:6px}
.mc-due{color:var(--warn);font-weight:700}
.module-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));
  gap:var(--sp-4)}
/* 网格项默认 min-width:auto 会以内容 min-content 撑破轨道，统一清零；
   手机单列必须 minmax(0,1fr)（裸 1fr = minmax(auto,1fr)，窄屏横向溢出根因）*/
.module-grid>*{min-width:0}
@media (max-width:768px){.module-grid{grid-template-columns:minmax(0,1fr)}}

/* 进度环：<svg class="ring" viewBox="0 0 44 44" style="--p:62">
     <circle class="ring-track" cx="22" cy="22" r="19"/>
     <circle class="ring-val" cx="22" cy="22" r="19" pathLength="100"/>
     <text class="ring-num" x="22" y="23">62</text></svg>  JS 只改 --p */
.ring{width:44px;height:44px;flex:none}
.ring circle{fill:none;stroke-width:4.5}
.ring-track{stroke:var(--surface-3)}
/* 渐变描边（升级令 A6）：页内需内嵌一份共享 defs（id=ringGrad，见 _spec/01 §5.4）；
   缺 defs 时按 <paint> 回退语法落回 --dm 纯色，环不会消失 */
.ring-val{stroke:var(--dm);stroke:url(#ringGrad) var(--dm);stroke-linecap:round;
  stroke-dasharray:var(--p,0) 100;transform:rotate(-90deg);transform-origin:center;
  /* --p=0 时圆头线帽仍会渲出一颗色点（审计 17·P1-2）：
     opacity=clamp(0,p×999,1)——0 进度整环隐藏，任何 >0 进度立即全显 */
  opacity:clamp(0,calc(var(--p,0)*999),1);
  transition:stroke-dasharray .6s var(--ease),opacity .2s linear}
.ring-num{font:700 11px var(--font-mono);fill:var(--text-2);
  font-variant-numeric:tabular-nums;text-anchor:middle;dominant-baseline:middle}
.ring-lg{width:88px;height:88px}
.ring-lg circle{stroke-width:4}
.ring-lg .ring-num{font-size:13px}

/* 掌握度四段条（R5 收编自 index .mbar / stats .st-mbar）
   段宽由内联 style="width:NN%" 控制（也兼容 flex-basis 写法）；
   段可为 <a>（可点跳转/筛选）或 <span>；迷你变体 .mastery-bar--mini。
   四态 data-k：new 未学(灰) / learning 学习中(橙，含 relearning)
              / young 复习期(蓝) / mature 已掌握(绿) */
.mastery-bar{display:flex;gap:2px;height:8px;border-radius:var(--r-full);
  background:var(--surface-3)}
/* ↑ 特意不设 overflow:hidden：圆角由首末段自带，裁剪会顺带切掉
   a.mb-seg 的外扩触控热区（审计 18·P2-6）*/
.mastery-bar--mini{height:6px}
.mb-seg{display:block;height:100%;min-width:0;flex:0 0 auto;
  transition:width var(--t-slow) var(--ease-out),flex-basis var(--t-slow) var(--ease-out)}
a.mb-seg{position:relative}
a.mb-seg::after{content:"";position:absolute;inset:-16px 0} /* 8px 条 → 40px 触控带 */
.mb-seg:first-child{border-radius:var(--r-full) 0 0 var(--r-full)}
.mb-seg:last-child{border-radius:0 var(--r-full) var(--r-full) 0}
.mb-seg[data-k="new"]{background:var(--line-strong)}
.mb-seg[data-k="learning"]{background:var(--warn)}
.mb-seg[data-k="young"]{background:var(--brand)}
.mb-seg[data-k="mature"]{background:var(--ok)}
a.mb-seg:hover{filter:brightness(1.12)}
/* 图例：.ml-item 用 <a>/<button> 时可点，纯 <span> 静态 */
.mastery-legend{display:flex;gap:var(--sp-2);flex-wrap:wrap;margin-top:var(--sp-3)}
.mastery-legend .ml-item{display:inline-flex;align-items:center;gap:var(--sp-2);min-height:34px;
  padding:2px 12px;border-radius:var(--r-full);border:1px solid var(--line);
  font-size:var(--fs-sm);color:var(--text-2);text-decoration:none;background:none}
.mastery-legend a.ml-item,.mastery-legend button.ml-item{cursor:pointer}
.mastery-legend a.ml-item:hover,.mastery-legend button.ml-item:hover{
  border-color:var(--dm);background:var(--surface-2);text-decoration:none}
.mastery-legend .dot{width:9px;height:9px;border-radius:50%;flex:none}
.mastery-legend .dot[data-k="new"]{background:var(--line-strong)}
.mastery-legend .dot[data-k="learning"]{background:var(--warn)}
.mastery-legend .dot[data-k="young"]{background:var(--brand)}
.mastery-legend .dot[data-k="mature"]{background:var(--ok)}
.mastery-legend b{font-family:var(--font-mono);color:var(--text-1)}

/* 热力图：列=周、行=周一→周日；level 0 卡=0 / 1–9=1 / 10–29=2 / 30–59=3 / ≥60=4 */
.heatmap{display:grid;grid-template-rows:repeat(7,11px);grid-auto-flow:column;
  grid-auto-columns:11px;gap:3px}
.heat-cell{position:relative;border-radius:3px;background:var(--heat-0);
  transition:transform var(--t-fast) var(--ease-spring)}
.heat-cell::before{content:"";position:absolute;inset:-4px} /* 扩触控热区 */
.heat-cell[data-lv="1"]{background:var(--heat-1)}
.heat-cell[data-lv="2"]{background:var(--heat-2)}
.heat-cell[data-lv="3"]{background:var(--heat-3)}
.heat-cell[data-lv="4"]{background:var(--heat-4)}
.heat-cell:hover{transform:scale(1.25)}
/* 「今日」高亮官方画法（审计 17·P1-1）：内收双环（dm 环 + surface 隔离环），
   永不被 overflow 滚动容器裁成 U 形；页组请删除各自的 outline/box-shadow 版本 */
.heat-cell.today{box-shadow:inset 0 0 0 2px var(--dm),inset 0 0 0 3.5px var(--surface)}
/* 桌面大屏格子放大，撑起面板呼吸感（审计 17·P2-4）*/
@media (min-width:1025px){
  .heatmap{grid-template-rows:repeat(7,14px);grid-auto-columns:14px;gap:4px}
}
@media (max-width:768px){
  /* 12px 起（9px 点日详情命中率过低，审计 18·P2-7）；手机仍只渲染最近 16 周 */
  .heatmap{grid-template-rows:repeat(7,12px);grid-auto-columns:12px;gap:2px}
}

/* 仪表盘统计卡（大数字）*/
.stat-card{background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);padding:var(--sp-4) var(--sp-5);
  box-shadow:var(--edge-top),var(--shadow-1)}
.stat-num{font-size:var(--fs-4xl);font-weight:800;color:var(--text-1);line-height:1.15;
  font-variant-numeric:tabular-nums}
.stat-label{font-size:var(--fs-sm);color:var(--text-3)}

/* ---- 质感层（升级令 A5/A10）---- */
/* hover 顶光晕：module-card 内建；页组的 .nav-card/.dom-cell 等挂 .hover-glow 即可。
   只切 opacity（合成器友好）；(hover:hover) 内防手机粘滞；--dm 混入 11% ≤ 12% 红线 */
@media (hover:hover){
  .hover-glow{position:relative}
  .module-card::after,.hover-glow::after{content:"";position:absolute;inset:0;
    border-radius:inherit;pointer-events:none;opacity:0;
    background:radial-gradient(140px 70px at 50% 0%,
      color-mix(in srgb,var(--dm) 11%,transparent), transparent 70%);
    transition:opacity var(--t-base) var(--ease)}
  .module-card:hover::after,.hover-glow:hover::after{opacity:1}
}
/* 深色表面顶光微渐变（≤4%，代码块不加、嵌套 surface-2 不加）*/
html[data-theme="dark"] :is(.module-card,.stat-card,.face:not(.back)){
  background-image:linear-gradient(180deg,
    color-mix(in srgb,#fff 3%,transparent), transparent 55%)}

/* ============ 5. 测验选项 ============ */
.quiz{border:none;margin:0;padding:0}
.quiz-q{font-size:var(--fs-lg);font-weight:800;color:var(--text-1);
  padding:0;margin-bottom:var(--sp-4)}
.quiz-opt{display:flex;align-items:center;gap:var(--sp-3);width:100%;min-height:52px;
  padding:var(--sp-3) var(--sp-4);margin-bottom:var(--sp-2);text-align:left;
  cursor:pointer;background:var(--surface);border:1.5px solid var(--line);
  border-radius:var(--r-md);font-size:var(--fs-md);color:var(--text-1);
  transition:border-color var(--t-fast),background var(--t-fast),transform var(--t-fast)}
.quiz-opt:hover{border-color:var(--dm);
  background:color-mix(in srgb,var(--dm) 5%,var(--surface))}
.quiz-opt:active{transform:scale(.99)}
.qo-idx{width:26px;height:26px;flex:none;border-radius:var(--r-full);
  display:grid;place-items:center;font:800 var(--fs-xs) var(--font-mono);
  background:var(--surface-3);color:var(--text-2)}
.qo-txt{flex:1;min-width:0}
.qo-mark{flex:none;width:18px;text-align:center}
.quiz-opt.is-selected{border-color:var(--dm);background:var(--brand-soft)}
.quiz-opt.is-selected .qo-idx{background:var(--dm);color:var(--on-solid)}
.quiz-opt.is-correct{border-color:var(--ok);background:var(--ok-soft)}
.quiz-opt.is-correct .qo-idx{background:var(--ok);color:var(--on-solid)}
.quiz-opt.is-correct .qo-mark::before{content:"✓";color:var(--ok);font-weight:900}
.quiz-opt.is-wrong{border-color:var(--bad);background:var(--bad-soft)}
.quiz-opt.is-wrong .qo-idx{background:var(--bad);color:var(--on-solid)}
.quiz-opt.is-wrong .qo-mark::before{content:"✕";color:var(--bad);font-weight:900}
.quiz[data-state="answered"] .quiz-opt{pointer-events:none}
.quiz-explain{display:none;margin-top:var(--sp-3);padding:var(--sp-3) var(--sp-4);
  background:var(--surface-2);border-left:3px solid var(--ok);
  border-radius:0 var(--r-sm) var(--r-sm) 0;
  font-size:var(--fs-base);color:var(--text-2)}
.quiz[data-state="answered"] .quiz-explain{display:block;
  animation:cardIn .24s var(--ease-out)}

/* ============ 6. 聊天消息区与输入区（lc-chat-*）============ */
.lc-chat-body{flex:1;min-height:0;overflow-y:auto;padding:var(--sp-4);
  display:flex;flex-direction:column;gap:var(--sp-3)}
.lc-chat-empty{margin:auto;padding:var(--sp-5);text-align:center;
  font-size:var(--fs-sm);color:var(--text-3);line-height:1.9}
.lc-chat-msg{display:flex;max-width:92%}
.lc-chat-msg--user{align-self:flex-end}
.lc-chat-msg--assistant,.lc-chat-msg--error{align-self:flex-start}
.lc-chat-bubble{padding:9px 13px;font-size:var(--fs-base);line-height:1.7;
  border-radius:var(--r-lg);box-shadow:var(--shadow-1);
  overflow-wrap:break-word;min-width:0}
.lc-chat-msg--user .lc-chat-bubble{background:var(--dm);color:var(--on-solid);
  border-top-right-radius:var(--r-xs)}
.lc-chat-msg--user .lc-chat-bubble b,.lc-chat-msg--user .lc-chat-bubble strong{color:inherit}
.lc-chat-msg--user .lc-chat-bubble code{background:rgba(0,0,0,.16);color:inherit}
.lc-chat-msg--assistant .lc-chat-bubble{background:var(--surface-2);
  border:1px solid var(--line);border-top-left-radius:var(--r-xs);color:var(--text-2)}
.lc-chat-msg--error .lc-chat-bubble{background:var(--bad-soft);color:var(--bad);
  border:1px solid color-mix(in srgb,var(--bad) 40%,transparent);
  border-top-left-radius:var(--r-xs);font-size:var(--fs-sm)}

/* markdown 渲染容器（chat.js 轻量 md 渲染的输出）*/
.lc-chat-md p{margin:0 0 8px}
.lc-chat-md ul,.lc-chat-md ol{margin:0 0 8px;padding-left:1.3em}
.lc-chat-md p:last-child,.lc-chat-md ul:last-child,.lc-chat-md ol:last-child,
.lc-chat-md .lc-chat-codeblock:last-child{margin-bottom:0}
.lc-chat-md b,.lc-chat-md strong{color:var(--text-1)}
.lc-chat-md-h{display:block;font-size:var(--fs-sm);font-weight:800;
  color:var(--text-1);margin:10px 0 4px}
.lc-chat-codeblock{position:relative;margin:8px 0;padding:26px 12px 10px;
  background:var(--code-bg);border:1px solid var(--code-line);
  border-radius:var(--r-sm);color:var(--code-ink);
  font:12px/1.6 var(--font-mono);overflow-x:auto;white-space:pre}
.lc-chat-copy{position:absolute;top:4px;right:6px;border:1px solid var(--code-line);
  background:transparent;color:var(--code-muted);border-radius:var(--r-xs);
  padding:1px 8px;font-size:11px;cursor:pointer}
.lc-chat-copy:hover{color:var(--code-ink);border-color:var(--code-muted)}
/* 流式：文本直接 append 不做逐字动画；光标由 JS 挂在流末尾 */
.lc-chat-cursor{display:inline-block;width:2px;height:1em;margin-left:2px;
  vertical-align:-2px;background:var(--dm);animation:caret 1s step-end infinite}
@keyframes caret{50%{opacity:0}}

/* 输入区 */
.lc-chat-composer{flex:none;display:flex;gap:var(--sp-2);align-items:flex-end;
  padding:var(--sp-3) var(--sp-4) calc(var(--sp-3) + env(safe-area-inset-bottom));
  border-top:1px solid var(--line)}
.lc-chat-textarea{flex:1;min-height:44px;max-height:132px;resize:none;
  font-size:var(--fs-base)}
.lc-chat-composer-actions{display:flex;flex-direction:column;gap:var(--sp-1);flex:none}
.lc-chat-send{min-height:44px;padding:0 var(--sp-4);border:none;
  border-radius:var(--r-md);background:var(--dm);color:var(--on-solid);
  font-size:var(--fs-base);font-weight:700;cursor:pointer}
.lc-chat-send:active{transform:scale(.97)}
.lc-chat-send[disabled]{opacity:.45;pointer-events:none}
.lc-chat-stop{min-height:34px;padding:0 var(--sp-3);border-radius:var(--r-sm);
  border:1px solid color-mix(in srgb,var(--bad) 50%,transparent);
  background:transparent;color:var(--bad);font-size:var(--fs-sm);
  font-weight:700;cursor:pointer}
.lc-chat-stop:hover{background:var(--bad-soft)}

/* ============ 7. 标签 pill / 空状态 / 杂项 ============ */
.tag{--tag:var(--dm);display:inline-flex;align-items:center;
  font-size:var(--fs-xs);font-weight:700;padding:2px 10px;
  border-radius:var(--r-full);color:var(--tag);
  background:color-mix(in srgb,var(--tag) 12%,var(--surface))}
.tag[data-c="accent"]{--tag:var(--accent)}
.tag[data-c="ochre"]{--tag:var(--ochre)}
.tag[data-c="ok"]{--tag:var(--ok)}
.tag[data-c="warn"]{--tag:var(--warn)}
.tag[data-c="bad"]{--tag:var(--bad)}
.tag.clickable{cursor:pointer;border:1px solid transparent;min-height:26px}
.tag.clickable:hover{border-color:var(--tag)}

/* ---- 空状态官方组件（升级令 A7：单色线稿替代 emoji）----
   结构：.empty-state > .empty-ic[data-icon] + .empty-title + .empty-desc + .empty-act
   图标 = 纯 CSS 双色线稿：::before 软色圆斑（--dm 10% 混入）+
   ::after currentColor 线稿（mask data-URI，随主题/域色自动换色），
   零额外请求、file:// 可用；装饰性元素必须 aria-hidden="true"。 */
.empty-state{text-align:center;color:var(--text-3);
  padding:var(--sp-9) var(--sp-5);font-size:var(--fs-base)}
.empty-ic{position:relative;display:inline-block;width:64px;height:64px;
  margin-bottom:var(--sp-3);color:var(--text-3)}
.empty-ic--sm{width:48px;height:48px}
.empty-ic::before{content:"";position:absolute;inset:12px 2px 0 12px;
  border-radius:var(--r-full);background:color-mix(in srgb,var(--dm) 10%,transparent)}
.empty-ic::after{content:"";position:absolute;inset:0;background:currentColor;
  -webkit-mask:var(--ei) center/contain no-repeat;mask:var(--ei) center/contain no-repeat}
/* 五枚线稿（viewBox 48、描边 2.5、圆帽圆角，≤2 色纪律）：
   deck=空卡叠+对勾(空队列/学完) quiz=问号卷(没测过) box=空盒(没数据/待装配)
   easel=画架(制作中/暂无内容) search=放大镜(无结果) */
.empty-ic[data-icon="deck"]{--ei:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='15' y='5' width='21' height='28' rx='4' transform='rotate(8 25.5 19)'/%3E%3Crect x='7' y='9' width='21' height='28' rx='4'/%3E%3Ccircle cx='35' cy='37' r='8'/%3E%3Cpath d='M31.5 37l2.6 2.6 4.4-5.2'/%3E%3C/svg%3E")}
.empty-ic[data-icon="quiz"]{--ei:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 9a4 4 0 0 1 4-4h11l9 9v25a4 4 0 0 1-4 4H16a4 4 0 0 1-4-4z'/%3E%3Cpath d='M27 5v9h9'/%3E%3Cpath d='M19.5 23a4.5 4.5 0 1 1 7 3.7c-1.8 1.2-2.5 2-2.5 4'/%3E%3Ccircle cx='24' cy='35.5' r='1.8' fill='%23000' stroke='none'/%3E%3C/svg%3E")}
.empty-ic[data-icon="box"]{--ei:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 20v15l15 8 15-8V20'/%3E%3Cpath d='M9 20l15-8 15 8-15 8z'/%3E%3Cpath d='M9 20l-5.5-4.5M39 20l5.5-4.5'/%3E%3Cpath d='M24 28v15'/%3E%3C/svg%3E")}
.empty-ic[data-icon="easel"]{--ei:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='9' y='7' width='30' height='22' rx='2.5'/%3E%3Cpath d='M14 24l6.5-8 5 5.5 4-4.5 4.5 7'/%3E%3Cpath d='M15 29l-7 13M33 29l7 13M24 29v7'/%3E%3C/svg%3E")}
.empty-ic[data-icon="search"]{--ei:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='20' cy='20' r='12'/%3E%3Cpath d='M29 29l13 13'/%3E%3Cpath d='M15.5 20h9'/%3E%3C/svg%3E")}
.empty-title{font-size:var(--fs-md);font-weight:700;color:var(--text-2);
  margin-bottom:var(--sp-1)}
.empty-desc{font-size:var(--fs-sm);color:var(--text-3);margin:0}
.empty-act{margin-top:var(--sp-4)}
/* 旧 emoji 空态（.es-ic）：暂留兼容，各页迁移完即删 */
.empty-state .es-ic{font-size:40px;display:block;margin-bottom:var(--sp-3);opacity:.7}
.empty-state .es-act{margin-top:var(--sp-4)}

/* 面包屑 */
.crumbs{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;
  font-size:var(--fs-sm);color:var(--text-3);margin-bottom:var(--sp-4)}
.crumbs a{color:var(--text-3)}
.crumbs a:hover{color:var(--dm)}
.crumbs .sep{opacity:.5}

/* 简易 toast（JS 挂 .show）*/
.toast{position:fixed;left:50%;bottom:calc(24px + env(safe-area-inset-bottom));
  translate:-50% 0;z-index:var(--z-toast);
  background:var(--text-1);color:var(--bg);font-size:var(--fs-sm);font-weight:600;
  padding:10px 18px;border-radius:var(--r-full);box-shadow:var(--shadow-3);
  opacity:0;pointer-events:none;transition:opacity var(--t-base),translate var(--t-base)}
.toast.show{opacity:1;translate:-50% -6px}

/* ---- 海拔工具类（审计 17·P2-2：--edge-top 覆盖不齐的页级卡一键补齐）----
   页组把自绘 box-shadow:var(--shadow-1) 的卡类换挂 .elev-1 即得「顶缘高光+三层影」；
   hover 抬升态换 .elev-2 或自写时记得并列 --edge-top 防高光闪断 */
.elev-1{box-shadow:var(--edge-top),var(--shadow-1)}
.elev-2{box-shadow:var(--edge-top),var(--shadow-2)}

/* ---- hero mesh 工具类（升级令 A3，壳组 index hero 调用）----
   限量纪律：一屏一处的欢迎面/页头/空状态大卡；禁全站铺底、禁正文阅读区；
   色点只用 -soft 系 ≤3 个；噪点走 --noise token（浅黑 5%/深白 4%，自动切换）。 */
.hero-mesh{position:relative;isolation:isolate;
  background-color:var(--surface);
  background-image:
    radial-gradient(at 12% 0%,  color-mix(in srgb,var(--brand-soft) 85%,transparent), transparent 55%),
    radial-gradient(at 88% 12%, color-mix(in srgb,var(--accent-soft) 70%,transparent), transparent 50%),
    radial-gradient(at 70% 115%,color-mix(in srgb,var(--ochre-soft) 55%,transparent), transparent 55%)}
.hero-mesh::after{content:"";position:absolute;inset:0;z-index:-1;
  pointer-events:none;border-radius:inherit;background-image:var(--noise)}
/* 深色叠 ≤4% 顶光（A10）；噪点保持在最上层 */
html[data-theme="dark"] .hero-mesh::after{background-image:var(--noise),
  linear-gradient(180deg,color-mix(in srgb,#fff 3%,transparent),transparent 55%)}

/* ---- 首屏进场错峰工具类（升级令 A9，壳组调用）----
   子项标 style="--i:0"…"--i:7"；≤8 项、总错峰 ≤360ms；长列表（browse 卡列表）禁用。
   reduced-motion：base.css 已把时长归零，这里再清 delay，避免"隐形等待后弹现"。 */
.stagger-in>*{opacity:0;transform:translateY(10px);
  animation:rise var(--t-slow) var(--ease-out) forwards;
  animation-delay:calc(var(--i,0)*45ms)}
@keyframes rise{to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.stagger-in>*{animation-delay:0ms}}

/* ============ 8. legacy 卡片正文兼容层 ============
   适用：data/cards/ 539 卡正文里保留的旧类与 374 处内联颜色。
   作用域 = 卡正文容器三名并列（缺一不可）：
     .kb-body（browse.js 实际渲染容器，已 rg 确认）
     .card-body（学习器 learn 规格容器）
     .lc-card-content（learn 组若走 lc- 前缀的备用约定，见 _spec/01 §5.2）
   规则按数据实测分布（top 模式）编写，非照抄旧版全套；
   覆盖内联 style 必须 !important（内联优先级高于任何选择器），
   覆盖 SVG 展示属性（fill=/stroke=）不需要（CSS 恒胜展示属性）。 */

/* ---- 8.0 卡正文防溢出白名单 ----
   长 URL/长标识符允许折行；容器不吃 min-content 地板。
   表格仅手机档转横向滚动（display:block 技法），桌面保持整宽表布局。 */
:is(.kb-body,.card-body,.lc-card-content){min-width:0;overflow-wrap:break-word}
@media (max-width:768px){
  :is(.kb-body,.card-body,.lc-card-content) table{
    display:block;max-width:100%;overflow-x:auto}
}

/* ---- 8.1 旧类官方样式（浅色即生效，原为知识库页内兜底）---- */
/* .key 黄底要点框（4 处）：mark 色 token 双主题自动翻转 */
:is(.kb-body,.card-body,.lc-card-content) .key{
  margin-top:12px;background:var(--mark-bg);color:var(--mark-ink);
  border:1px solid color-mix(in srgb,var(--ochre) 32%,var(--mark-bg));
  border-left:4px solid var(--ochre);border-radius:0 var(--r-sm) var(--r-sm) 0;
  padding:9px 12px;font-size:var(--fs-base)}
:is(.kb-body,.card-body,.lc-card-content) .key b{color:var(--mark-ink)}
/* .par 参数图例行（.row1 行 / .sym 符号列，5 处）*/
:is(.kb-body,.card-body,.lc-card-content) .par{
  margin:9px 0 2px;font-size:var(--fs-sm);color:var(--text-2);line-height:1.7}
:is(.kb-body,.card-body,.lc-card-content) .par .row1{
  display:flex;gap:8px;align-items:baseline;margin:3px 0}
:is(.kb-body,.card-body,.lc-card-content) .par .sym{
  flex:none;min-width:48px;text-align:right;font-family:var(--font-math);
  font-weight:700;color:var(--dm)}
/* .linklist/.linkbtn 链接按钮组（10 处）*/
:is(.kb-body,.card-body,.lc-card-content) .linklist{
  display:flex;flex-wrap:wrap;gap:8px;margin:8px 0 2px}
:is(.kb-body,.card-body,.lc-card-content) .linkbtn{
  display:inline-flex;align-items:center;gap:var(--sp-1);min-height:34px;
  padding:6px 11px;border-radius:var(--r-sm);text-decoration:none;
  border:1px solid var(--line-strong);background:var(--brand-soft);
  color:var(--brand);font-size:var(--fs-sm);font-weight:700}
:is(.kb-body,.card-body,.lc-card-content) .linkbtn:hover{
  border-color:var(--brand);text-decoration:none}

/* ---- 8.2 深色覆盖：SVG 写死色（按 fill=/stroke= 实测 top）---- */
/* 白底矩形（53 处 rect；text fill=#fff 是色块上的白字，勿动）*/
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content) svg rect[fill="#fff"],
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content) svg rect[fill="#ffffff"]{
  fill:var(--surface-2)}
/* 深灰文字/描边（#334155×35、#666×28、#475569×17 等，暗底下不可读）*/
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content) svg
  :is([fill="#334155"],[fill="#475569"],[fill="#666"]){fill:var(--text-2)}
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content) svg
  :is([stroke="#334155"],[stroke="#475569"]){stroke:var(--text-3)}
/* 浅色系补丁（审计 17·P1-4 实测清单）：近白/浅蓝/浅黄块暗底刺眼 → 按色相压深 */
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content) svg
  [fill="#f1f5f9"]{fill:var(--surface-3)}                       /* 米白块 ×7 */
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content) svg
  [fill="#cfe0ff"]{fill:var(--brand-soft)}                      /* 浅蓝块 ×6 */
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content) svg
  :is([fill="#fde68a"],[fill="#fef3c7"]){fill:var(--mark-bg)}   /* 浅黄高亮 ×15 */
/* 深色系按原色相提亮（图内颜色编码不换色系，只提亮度）*/
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content) svg
  [fill="#16243a"]{fill:var(--brand-ink)}                       /* 深藏青标签 ×3（审计 17·P1-5）*/
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content) svg
  [fill="#1e3a8a"]{fill:var(--brand-ink)}                       /* 深蓝 ×31 */
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content) svg
  :is([fill="#9a3412"],[fill="#92400e"]){fill:var(--warn)}      /* 深赭 ×44 */
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content) svg
  [fill="#c5571f"]{fill:var(--ochre)}                           /* 橙棕 ×20 */
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content) svg
  [fill="#166534"]{fill:var(--ok)}                              /* 深绿 ×16 */
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content) svg
  [fill="#dc2626"]{fill:var(--bad)}                             /* 深红 ×5 */
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content) svg
  [fill="#5b21b6"]{fill:#b39ce8} /* 深紫 ×5：紫系无 token，就地引用 job-hunt 域深色同值保色相 */
/* 浅色网格线/辅助线在暗底过亮 → 压到边框色 */
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content) svg
  :is([stroke="#eceff4"],[stroke="#e5e7eb"],[stroke="#cbd5e1"]){stroke:var(--line)}
/* 中间调品牌色（#3b6fe0/#e0683b/#16a34a/#0f9d8c/#9333ea/#94a3b8/#64748b）
   暗底可读，特意不覆盖。 */

/* ---- 8.3 深色覆盖：内联 style 写死色（须 !important）---- */
/* 橙黄浅底提示块 <p style="background:#fff4e5;border-left:#e0683b…"> ×28 */
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content)
  [style*="background:#fff4e5"]{background:var(--warn-soft)!important}
/* 浅蓝底（表格行/高亮块）×7 */
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content)
  :is([style*="background:#eef3ff"],[style*="background:#eef7ff"]){
  background:var(--brand-soft)!important}
/* 深色文字：<p style="color:#9a3412"> ×35 等，按色相提亮 */
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content)
  [style*="color:#9a3412"]{color:var(--warn)!important}
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content)
  [style*="color:#c5571f"]{color:var(--ochre)!important}
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content)
  [style*="color:#1e3a8a"]{color:var(--brand-ink)!important}
/* 浅色边框（#e7ebf4×137、#eceff4×32、#d6dbf6×13、#d6e2fb×6）→ 主题边框色 */
html[data-theme="dark"] :is(.kb-body,.card-body,.lc-card-content)
  :is([style*="#e7ebf4"],[style*="#eceff4"],[style*="#d6dbf6"],[style*="#d6e2fb"]){
  border-color:var(--line)!important}
/* 灰 muted 文字 color:#7a8696 ×36 暗底 ≈4.2:1 尚可读，特意不覆盖。 */
