/* ============================================================
   化学仿真引擎 · 样式（chem-lab.css）
   - 讲解页头部（sim-head / crumb）  ← 19 个 index.html 共用骨架
   - 讲解卡片（deck）
   - 实验室外壳（lab）
   - 参数面板（cp-*）
   - 读数条（ro）
   全部使用 theme.css 的 CSS 变量 → 自动跟随夜航/白天主题。
   ============================================================ */

/* ================= 讲解页头部 =================
   ★ 这段是 19 个 index.html 里**逐字重复**的骨架，2026-09-29 从各页 <style> 抽出。
     实测：18 页有此块（15 页一字不差，polymer/route/spectrum 三页仅 max-width
     660→680，此处统一为 660 的基准，三页在各自 <style> 里保留一条覆盖）。
     periodic-table/index.html 结构不同，**不适用**本段。
     ⚠️ 抽这块的语义约束：`.crumb`/`.sim-head`/`.sim-body` 只决定讲解页排版，
        不含画布高度类规则（那些在「实验室外壳」段），改动不影响任何仿真行为。 */
.sim-head{padding:30px 0 6px}
.crumb{font-family:'SF Mono',Consolas,monospace;font-size:10.5px;letter-spacing:.1em;
  color:var(--ink-3);margin-bottom:14px;display:flex;align-items:center;gap:8px}
.crumb a{color:var(--ink-3);text-decoration:none;transition:.16s}
.crumb a:hover{color:var(--accent)}
.sim-head h1{font-size:29px;font-weight:800;letter-spacing:-.02em;margin-bottom:8px}
.sim-head .lead{font-size:13.5px;color:var(--ink-2);max-width:660px;line-height:1.75}
.sim-meta{display:flex;flex-wrap:wrap;gap:7px;margin-top:15px}
.sim-meta .tag{font-family:'SF Mono',Consolas,monospace;font-size:10px}
.sim-body{padding:26px 0 10px}

/* ================= 讲解卡片 ================= */
.deck{max-width:920px;margin:0 auto}
.deck-rail{display:flex;gap:6px;margin-bottom:14px;align-items:center}
.deck-dot{width:26px;height:3px;border:0;padding:0;border-radius:100px;cursor:pointer;
  background:var(--line-strong);opacity:.5;transition:.2s}
.deck-dot:hover{opacity:.85}
.deck-dot.on{background:var(--accent);opacity:1;width:40px}

.deck-card{background:var(--panel);border:1px solid var(--line);border-radius:3px;
  padding:26px 28px 24px;backdrop-filter:blur(6px);box-shadow:var(--shadow-sm);
  position:relative;overflow:hidden;min-height:300px}
.deck-card::before{content:'';position:absolute;inset:0 0 auto 0;height:2.5px;
  background:linear-gradient(90deg,var(--link),var(--accent))}
.deck-top{display:flex;align-items:center;gap:10px;margin-bottom:16px}
.deck-q-mark{font-family:'SF Mono',Consolas,monospace;font-size:10.5px;letter-spacing:.16em;
  color:var(--accent)}
.deck-tag{font-family:'SF Mono',Consolas,monospace;font-size:9.5px;letter-spacing:.1em;
  padding:2px 8px;border-radius:100px;border:1px solid var(--accent-dim);
  color:var(--accent);background:var(--accent-soft)}
.deck-pager{margin-left:auto;font-family:'SF Mono',Consolas,monospace;
  font-size:10.5px;color:var(--ink-3)}
.deck-q{font-size:21px;font-weight:800;line-height:1.45;letter-spacing:-.015em;
  margin-bottom:18px;color:var(--ink)}
.deck-points{list-style:none;display:flex;flex-direction:column;gap:10px}
.deck-points li{font-size:13.5px;line-height:1.78;color:var(--ink-2);
  padding-left:20px;position:relative}
.deck-points li::before{content:'';position:absolute;left:4px;top:.72em;
  width:5px;height:5px;border-radius:50%;background:var(--accent);opacity:.75}
.deck-points strong{color:var(--ink);font-weight:700}
.deck-points code{font-family:'SF Mono',Consolas,monospace;font-size:12.5px;
  background:var(--accent-soft);color:var(--accent);padding:1px 6px;border-radius:2px}
.deck-note{margin-top:20px;padding:13px 16px;border-left:2px solid var(--accent);
  background:var(--hover-bg-2,var(--hover-bg));border-radius:0 2px 2px 0;
  font-size:12.5px;line-height:1.75;color:var(--ink-2)}
.deck-note strong{color:var(--ink)}
.deck-demo{margin:20px 0}
/* buildDeck 的 demoCaption 会插这个节点。
   ⚠️ 早先在滴定/VSEPR 讲解页里它只有 class 没有样式 —— 那行小字一直是
      浏览器默认字体，跟全站字体不搭。统一放这里。 */
.deck-demo .demo-cap{margin-top:8px;font-size:11.5px;line-height:1.6;
  color:var(--ink-3);font-family:'SF Mono',Consolas,monospace;letter-spacing:.01em}

/* ================= 讲解卡里的富文本表（deck-rich） =================
   ★★★ 2026-09-29 补这段的原因：全站**从来没有**任何 table 样式。
     讲解卡里的对照表（「分子 / 碳碳键 / σ 数 / π 数」这类）列与列**紧贴在一起**，
     1366 宽的截图上是 `乙烷C₂H₆C—C 7 0` —— 完全读不出列边界，学生没法看。
     这不是某一个仿真引入的，是**从第一件就带着**的、横跨 8 个讲解页的老账。

   ★ 为什么只写 `.deck-rich table`（后代选择器）而**不是**裸 `table{}`：
     全站有 6 处**页面自带**的表格样式，各自定义在页面的 `<style>` 里，不能碰：
       table.crit（electrochem/index）· table.idx（electrochem/lab）
       .eg-tab（electroneg/lab）· .sp-table（electron / hess / spectrum 的 lab）
       table.vt（vsepr/lab）· design-previews 自己的 `table{}`
     裸 `table{}` 与它们**同权重**，谁赢只取决于 `<style>` 与本文件的加载先后
     —— 那是「改 A 影响 B」的隐性耦合。用 `.deck-rich table` 把作用域钉死在
     讲解卡的富文本容器里，老页面零风险。

   ★ `.deck-rich` 这个容器名有**两个来源**，别只认一处：
     ① `chem-lab.js` 的 buildDeck 生成
        `<div class="deck-rich" data-rich>` —— 覆盖讲解页数据层的 `html:` 字段
        （22 处：bonding / electron / electroneg / hess / ionic-eq / redox /
         sigma-pi / stoich）。
     ② `stoich/lab.html` 里**手写**的 `<div class="deck-rich">`（注释写着
        「借用引擎的富文本样式（表格）」）—— 它借的**就是本段规则**；
        在本段存在之前，它借到的是**空的**。
     ⚠️ isomer / organic 两页写的是 `<table class="deck-table">`，但全仓
        **没有任何 `.deck-table` 样式定义**（死类名）。它们是 `.deck-rich`
        的后代，本段照样命中，所以**不必**为它补一条同名规则。
        （要清理这个死类名属于独立项，别顺手动已验收页面。）

   ★ 刻意**不给 table 设 min-width**：讲解卡在窄屏（430px 视口）内宽只有 ~330px，
     设 min-width 会横向溢出；`width:100%` + 自动换行才是安全解。
     列太挤时靠文件末尾「响应式」段缩字号与内边距，而不是让它横向滚。 */
.deck-rich table{width:100%;border-collapse:collapse;margin:2px 0 4px;
  font-size:12.5px;line-height:1.6}
.deck-rich th,.deck-rich td{padding:7px 10px;text-align:left;vertical-align:top;
  border-bottom:1px solid var(--line)}
.deck-rich thead th{color:var(--ink-3);font-weight:700;font-size:11px;
  letter-spacing:.02em;background:var(--hover-bg)}
.deck-rich tbody tr:last-child td{border-bottom:none}
.deck-rich table b,.deck-rich table strong{color:var(--ink);font-weight:700}
.deck-rich table code{font-family:'SF Mono',Consolas,monospace;font-size:11.5px}

.deck-cta{display:flex;align-items:center;justify-content:space-between;
  margin-top:22px;padding:15px 20px;border:1px solid var(--accent);
  border-radius:3px;background:var(--accent-soft);color:var(--accent);
  text-decoration:none;font-size:14px;font-weight:700;transition:.2s}
.deck-cta:hover{background:var(--accent);color:var(--on-accent);
  box-shadow:0 6px 22px var(--glow)}
.deck-cta .arw{font-size:17px;transition:transform .2s}
.deck-cta:hover .arw{transform:translateX(4px)}

.deck-nav{display:flex;align-items:center;gap:14px;margin-top:16px}
.deck-prog{flex:1;height:2px;background:var(--line);border-radius:100px;overflow:hidden}
.deck-prog i{display:block;height:100%;background:var(--accent);border-radius:100px;
  transition:width .35s cubic-bezier(.2,.8,.2,1)}
.btn-sm{padding:7px 15px;font-size:12.5px}
.btn:disabled{opacity:.35;cursor:not-allowed;pointer-events:none}

.mini-canvas{width:100%;height:210px;border:1px solid var(--line);border-radius:2px;
  overflow:hidden;background:var(--bg-2);position:relative}
.mini-canvas canvas{display:block;width:100%;height:100%}
.mini-canvas.tall{height:280px}
/* grid4：四方格总览图专用高度。
   ★ 为什么必须单开一档：「化学能与电能的转化」总览页要把**四个装置**
     摆成 2×2，其包围盒宽高比 ≈ 1.22；而默认画布（210px）AR ≈ 3.3、
     tall（280px）AR ≈ 2.5 —— 等比适配只能填满一维，四格图会挤在中间一条
     竖带里（实测横填充仅 34% / 46%）。420px 时 AR ≈ 1.65，
     横向填充升到 70%，且四个装置仍各自可辨。
     ★ 这也符合 ENGINE §11.5「装置形状决定画多大」：容器要迁就内容。 */
.mini-canvas.grid4{height:420px}

/* ================= 实验室外壳 ================= */
.lab{display:flex;flex-direction:column;min-height:100vh}
.lab-bar{display:flex;align-items:center;gap:18px;padding:12px 20px;
  border-bottom:1px solid var(--line);background:var(--nav-bg);
  backdrop-filter:blur(10px);position:sticky;top:0;z-index:20;flex-wrap:wrap}
.lab-back{display:inline-flex;align-items:center;gap:7px;padding:6px 13px;
  font-family:'SF Mono',Consolas,monospace;font-size:11px;letter-spacing:.06em;
  color:var(--accent);border:1px solid var(--accent-dim);border-radius:2px;
  text-decoration:none;transition:.18s;flex:none}
.lab-back:hover{background:var(--accent-soft);border-color:var(--accent)}
.lab-back .arw{transition:transform .18s}
.lab-back:hover .arw{transform:translateX(-3px)}
.lab-title{display:flex;align-items:center;gap:12px;min-width:0}
.lab-badge{font-family:'SF Mono',Consolas,monospace;font-size:9.5px;letter-spacing:.14em;
  padding:3px 9px;border-radius:2px;background:var(--accent);color:var(--on-accent);
  flex:none;font-weight:600}
.lab-title h1{font-size:17px;font-weight:800;letter-spacing:-.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lab-actions{margin-left:auto;display:flex;gap:8px;align-items:center;flex:none}

.lab-scope{font-size:12.5px;color:var(--ink-2);line-height:1.7;
  padding:14px 20px 0;max-width:1100px}

.lab-readout{display:flex;flex-wrap:wrap;gap:1px;margin:14px 20px 0;
  background:var(--line);border:1px solid var(--line);border-radius:3px;overflow:hidden}
.ro{flex:1;min-width:104px;padding:11px 14px;background:var(--panel);text-align:center}
.ro b{display:block;font-family:'SF Mono',Consolas,monospace;font-size:18px;
  font-weight:600;color:var(--accent);line-height:1.25;letter-spacing:-.01em}
.ro span{font-size:10.5px;color:var(--ink-3)}
.ro.c-warn b{color:var(--warn)}
.ro.c-ok b{color:var(--ok)}
.ro.c-danger b{color:var(--danger)}

.lab-body{display:grid;grid-template-columns:296px 1fr;gap:1px;
  background:var(--line);border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);margin-top:14px;flex:1;min-height:0}
.lab-side{background:var(--panel);padding:20px;overflow-y:auto;max-height:calc(100vh - 220px)}
.lab-stage{background:var(--bg-2);display:flex;flex-direction:column;min-width:0;position:relative}
.lab-canvas-wrap{flex:1;min-height:440px;position:relative}
.lab-canvas-wrap canvas{display:block;width:100%;height:100%}
/* grid4：四方格总览实验室专用 —— 画布必须够高，否则 2×2 只能填满一维。
   ★ 实测（_measure.sh）：默认时画布 735×368（AR 2.00），2×2 图（AR 1.22）
     横向只填 58%。把画布撑到 735×520（AR 1.41）后填充率升到 ~78%，
     四个装置才真正「横过来对着看」。
   ★★ 还必须**设上限**：.lab-canvas-wrap 是 flex:1，会吸收全部剩余高度 ——
     窗口一高（实测 2400px 视口），画布被拉到 ~2000px，
     于是 canvas 里那幅 2×2 图仍然只占中间一小块（等比适配按宽度算的），
     而真正的「判据索引表」被顶到视口外，本页最重要的资产反倒看不见。
     ⇒ 高度上限 560px + 居中：图与表都在首屏。
     上限取 560 而不是 520（下限）：留 40px 余量，让 .lab-stage-foot
     不与画布贴死，同时不至于把 foot 推远。 */
.lab-canvas-wrap.grid4{min-height:520px;max-height:560px}
/* capfeet：**页脚内容多**的实验室（方程式 + 解释 + 对照表）专用 ——
   与 grid4 同一个病根：.lab-canvas-wrap 是 flex:1 会吸走全部剩余高度，
   于是画布被拉到上千像素、而真正有信息量的页脚被顶到视口外。
   ★ 实测（盐类水解实验室，1440×1900 视口）：不设上限时画布 ~1000px 高，
     天平画在 h*0.34 处 → 悬在一大片空白正中，pH 色带贴到视口最底，
     而「越弱越水解」对照表完全在首屏之外 —— 看起来像页脚根本没渲染。
   ⇒ 上限 520px：天平与色带落在舒适区，页脚紧跟其后进入首屏。 */
.lab-canvas-wrap.capfeet{min-height:420px;max-height:520px}
/* ★★ flat：**浅图**专用（2026-09-29 新增）。
   病根与 capfeet 相同（.lab-canvas-wrap 是 flex:1 会吸走全部剩余高度），
   但 capfeet 的 420–520px 对**扁平带式图**（两层判据条 / 换算阶梯 / 方程对照）
   仍然过高 —— 图只占顶部 ~110px，下面留下 300+px 空白，
   而页脚被推到首屏之外，截图上看像「结论没渲染」（实测踩到，三个轻交互仿真同时中招）。
   ⇒ 给浅图一个**固定高度 196px**：不再 flex 吸收，画布贴住页脚，整页一屏看完。
     新写的浅图实验室请显式传 canvasClass:'flat'（不传会静默退回 flex:1 → 页脚出屏）。 */
.lab-canvas-wrap.flat{flex:none;height:196px;min-height:0;max-height:none}
/* ★★ figfit：**自带纵横比的 SVG 示意图**专用（2026-09-29 新增，σ键/π键件）。
   病根与 capfeet/flat 相同（.lab-canvas-wrap 是 flex:1 会吸走全部剩余高度），
   但 capfeet 的 420–520px 对**非 canvas 的图**过高 —— 本页图是 SVG（`width:100%;height:auto`
   按容器宽度定高，不是等比适配的 canvas），给它 420px 只会上下留白，
   把「判定卡 + 考点行」整块顶出首屏。
   ★ 实测（1366×1000 视口，σ键/π键实验室）：capfeet 时画布吸到 420px，
     页脚只剩 ~88px ⇒ 判定卡只露出「题面」一行、判定结果**整块在首屏之外**，
     截图上看像「判定没渲染」。
   ★★ 与 flat 同样的解法：**flex:none + 固定高度**。
     只把上限调小（min 340 / max 420）**不够** —— .lab-canvas-wrap 是 flex:1，
     只要还有空间就一路涨到上限，页脚照样被挤出去（实测：改成 340/420 后
     画布仍是 420px，判定卡依旧出屏）。**必须脱离 flex 分配**才有确定的高度。
   ⇒ 固定 320px：20px padding + 图 ≈ 300px，页脚（题面 + 判定卡 3 行 + 考点行 ≈ 200px）
     紧随其后，378 + 320 + 200 = 898 < 1000，整页一屏看完。
   ⇒ 新写的**示意图型**（非 canvas）实验室请显式传 canvasClass:'figfit'。 */
.lab-canvas-wrap.figfit{flex:none;height:320px;min-height:0;max-height:none}
.lab-stage-foot{padding:12px 18px;border-top:1px solid var(--line);
  font-size:11.5px;color:var(--ink-3);line-height:1.65;background:var(--panel)}

/* ================= 参数面板 ================= */
.cp-row{display:flex;flex-direction:column;gap:7px;padding:12px 0;
  border-bottom:1px solid var(--line)}
.cp-row:last-child{border-bottom:0}
.cp-row-block{gap:10px}
.cp-lab{font-size:12px;font-weight:600;color:var(--ink);display:flex;
  align-items:baseline;gap:7px;flex-wrap:wrap}
.cp-hint{font-size:10.5px;font-weight:400;color:var(--ink-3)}
.cp-ctl{display:flex;align-items:center;gap:11px}
.cp-ctl input[type=range]{flex:1;height:3px;-webkit-appearance:none;appearance:none;
  background:var(--line-strong);border-radius:100px;outline:none;cursor:pointer}
.cp-ctl input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;
  width:15px;height:15px;border-radius:50%;background:var(--accent);
  cursor:pointer;border:2px solid var(--bg);box-shadow:0 0 0 1px var(--accent)}
.cp-ctl input[type=range]::-moz-range-thumb{width:13px;height:13px;border-radius:50%;
  background:var(--accent);cursor:pointer;border:2px solid var(--bg)}
.cp-val{font-family:'SF Mono',Consolas,monospace;font-size:13px;font-weight:600;
  color:var(--accent);min-width:58px;text-align:right;flex:none}
.cp-unit{font-size:10px;color:var(--ink-3);margin-left:2px}
.cp-select{width:100%;padding:7px 10px;font-size:12.5px;font-family:inherit;
  background:var(--bg-2);border:1px solid var(--line);border-radius:2px;
  color:var(--ink);outline:none;cursor:pointer;transition:.16s}
.cp-select:focus{border-color:var(--accent-dim);box-shadow:0 0 0 2px var(--accent-soft)}
.cp-btns{display:flex;gap:0;border:1px solid var(--line);border-radius:2px;overflow:hidden}
.cp-btns button{flex:1;padding:7px 8px;font-size:11.5px;background:transparent;
  color:var(--ink-2);border:0;border-right:1px solid var(--line);cursor:pointer;
  font-family:inherit;transition:.16s;white-space:nowrap}
.cp-btns button:last-child{border-right:0}
.cp-btns button:hover{background:var(--hover-bg);color:var(--ink)}
.cp-btns button.on{background:var(--accent);color:var(--on-accent);font-weight:600}
/* 多按钮换行版：用于「物系清单」这类 5~6 个且名字长短不一的按钮组。
   ⚠️ 基类 .cp-btns 是单行分段控件（flex + overflow:hidden），
      按钮超过面板宽度时会被直接**裁掉右侧**（不是折行）——
      表现为「最后一个按钮显示成 Ba」，看不出是 bug，只像名字短。
      所以物系清单必须用这个换行版。 */
.cp-btns.wrap{flex-wrap:wrap;gap:1px;overflow:visible}
.cp-btns.wrap button{flex:0 0 auto;border-right:1px solid var(--line);border-bottom:1px solid var(--line)}
.cp-btns.wrap button:last-child{border-right:1px solid var(--line)}
.cp-switch{position:relative;display:inline-block;width:42px;height:23px;flex:none;cursor:pointer}
.cp-switch input{opacity:0;width:0;height:0;position:absolute}
.cp-switch span{position:absolute;inset:0;background:var(--line-strong);
  border-radius:100px;transition:.22s}
.cp-switch span::before{content:'';position:absolute;width:17px;height:17px;left:3px;top:3px;
  background:var(--bg);border-radius:50%;transition:.22s;box-shadow:0 1px 3px rgba(0,0,0,.3)}
.cp-switch input:checked + span{background:var(--accent)}
.cp-switch input:checked + span::before{transform:translateX(19px);background:#fff}
.cp-switch input:focus-visible + span{box-shadow:0 0 0 2px var(--accent-soft)}

.cp-group+.cp-group{margin-top:18px;padding-top:16px;border-top:1px solid var(--line)}
.cp-group-title{font-family:'SF Mono',Consolas,monospace;font-size:10px;
  letter-spacing:.16em;color:var(--accent);margin-bottom:4px}

/* 图例块（实验室侧栏底部常用） */
.lab-legend{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px;padding-top:14px;
  border-top:1px solid var(--line)}
.lab-legend i{width:9px;height:9px;border-radius:50%;flex:none}
.lab-legend span{display:inline-flex;align-items:center;gap:6px;font-size:11px;
  color:var(--ink-2)}

/* ================= 响应式 ================= */
@media(max-width:900px){
  .lab-body{grid-template-columns:1fr}
  .lab-side{max-height:none;border-bottom:1px solid var(--line)}
  .lab-canvas-wrap{min-height:340px}
  .deck-card{padding:20px 18px}
  .deck-q{font-size:17.5px}
  .deck-points li{font-size:13px}
  .ro{min-width:88px;padding:9px 10px}
  .ro b{font-size:16px}
  /* ★ 窄屏：讲解卡内宽只有 ~330px，4 列表格必须缩内边距 + 缩字号，
     否则每格只剩几像素可放字（见本文件「讲解卡里的富文本表」段的说明）。 */
  .deck-rich table{font-size:11.5px}
  .deck-rich th,.deck-rich td{padding:5px 7px}
  .deck-rich thead th{font-size:10px}
}

/* ================= 原子结构示意图（atom-structure-data.js 生成的 SVG） =================
   ★ 为什么放在**共享 css** 而不是两个页面各写一份 `<style>`：
     讲解页与实验室用的是**同一个** `A.atomSVG()`，样式当然也该只有一份。
     讲解页照 `electron/index.html` 的先例一并引 chem-lab.css 即可
     （全站讲解页默认只引 theme.css，这里属于「有共享组件」的例外）。
     类名与 atom-structure-data.js 里写死的 class 一一对应：
       .as-nucl 原子核圆 · .as-z 核电荷数 · .as-arc 电子层弧线
       .as-e 电子点 · .as-lab 「层名 电子数」 · .as-cap 底部说明 */
.atom-svg{width:100%;height:auto;max-height:100%;display:block}
.atom-svg .as-nucl{fill:var(--accent-soft);stroke:var(--accent);stroke-width:1.6}
.atom-svg .as-z{fill:var(--accent);font-size:15px;font-weight:700;
  font-family:'SF Mono',Consolas,monospace}
.atom-svg .as-arc{stroke:var(--line-strong);stroke-width:1.4;fill:none}
.atom-svg .as-e{fill:var(--ink-2)}
.atom-svg .as-lab{fill:var(--ink-3);font-size:10.5px;
  font-family:'SF Mono',Consolas,monospace}
.atom-svg .as-cap{fill:var(--ink-2);font-size:11px}
.as-pair{display:flex;gap:14px;align-items:flex-start;justify-content:center;
  flex-wrap:wrap}
.as-pair figure{margin:0;flex:1 1 200px;max-width:260px;text-align:center}
.as-pair figcaption{font-size:11.5px;color:var(--ink-3);margin-top:2px}
@media(max-width:720px){
  .atom-svg .as-cap{font-size:10px}
}

/* ================= 球棍模型搭建（molmodel-data.js 生成的 SVG 与页内版式） =================
   ★ 为什么放**共享 css**：讲解页与实验室用的是同一份 `M.skeletonSVG()` /
     `M.shapeCompareSVG()`，样式当然也只该有一份（讲解页照 atom-structure 的先例
     一并引 chem-lab.css）。
   类名与 molmodel-data.js 里写死的 class 一一对应：
     .mm-cmp 对照图 · .mm-bond 键线 · .mm-wedge 楔形（朝向读者）
     .mm-dash 虚线（背向读者） · .mm-c/mm-h 碳/氢球 · .mm-cap 面板标题
     .mm-sub 面板结论 · .mm-cmpnote 底部说明 */
.mm-cmp{width:100%;height:auto;max-height:200px;display:block}
.mm-cmp .mm-bond{stroke:var(--line-strong);stroke-width:1.6}
.mm-cmp .mm-wedge{fill:var(--ink-3);stroke:none}
.mm-cmp .mm-dash{stroke:var(--ink-3);stroke-width:1.4;stroke-dasharray:4 3}
.mm-cmp .mm-c{fill:var(--accent-soft);stroke:var(--accent);stroke-width:1.6}
.mm-cmp .mm-h{fill:var(--bg-2);stroke:var(--ink-3);stroke-width:1.3}
.mm-cmp .mm-clab{fill:var(--accent);font-size:13px;font-weight:700;text-anchor:middle;
  font-family:'SF Mono',Consolas,monospace}
.mm-cmp .mm-hlab{fill:var(--ink-2);font-size:10px;text-anchor:middle;
  font-family:'SF Mono',Consolas,monospace}
.mm-cmp .mm-cap{fill:var(--ink);font-size:11.5px;font-weight:700;text-anchor:middle}
.mm-cmp .mm-sub{fill:var(--ink-3);font-size:10.5px;text-anchor:middle;
  font-family:'SF Mono',Consolas,monospace}
.mm-cmpnote{margin-top:6px;font-size:11px;line-height:1.7;color:var(--ink-3);text-align:center}
.mm-cmpnote u{text-decoration:none;color:var(--accent)}

/* 球棍/填充模型的三维宿主（实验室页）
   ⚠️ 高度必须**显式给**：`.lab-canvas-wrap` 是 flex 容器，
      内容不设高度会塌成 0（chem-stage 的定高契约也是同一条规则）。 */
.mm-3dbox{width:100%;height:100%;min-height:0;display:block}
@media(max-width:720px){
  .mm-cmpnote{font-size:10.5px}
}

/* ============================================================
   中和热测定（neut-heat）—— 图形样式（讲解页与实验室共用）
   ============================================================ */
.nh-curve,.nh-device{width:100%;height:auto;display:block}
.nh-curve text{font-family:'SF Mono',Consolas,monospace}
.nh-device text{font-family:'SF Mono',Consolas,monospace}
@media(max-width:720px){
  .nh-curve text,.nh-device text{font-size:9px}
}

/* ============================================================
   反应速率调节器（rate-control）—— 图形样式（讲解页与实验室共用）
   ============================================================ */
.rt-bars,.rt-ct{width:100%;height:auto;display:block}
.rt-bars text,.rt-ct text{font-family:'SF Mono',Consolas,monospace}
@media(max-width:720px){
  .rt-bars text,.rt-ct text{font-size:9px}
}

/* ============================================================
   3D 壳层视图（atom-structure 3D 模式）—— makeStage 的定高容器
   ============================================================ */
.as-3dbox{width:100%;height:100%;min-height:0;display:block}
