/* ============================================================
   数海探奇（数学学科子栏目）· 专属样式
   颜色一律取站点主题变量（themes.css 11 套皮肤自动适配），不写死面色。
   布局只作用于 #math 页内，不影响其他栏目。
   ============================================================ */

/* ★★ 两条配色铁律（本文件是三栏共用的，改之前先读这两条）
   ------------------------------------------------------------
   ① 压在强调色上的字一律用 --onAccent，不许写死 #fff / #000。
      本文件原先有 8 处选中态写的是 `background: var(--accent); color: #fff`
      （.m-tab.m-sel / .m-segbtn button.m-sel / .m-btn / .mb-stage.m-sel /
        .m-rel-chip.m-sel / .mk-no.cur / .m-sg-btn.m-sel / .m-tl-seg.m-sel）。
      但 --accent 在 12 套皮肤里既有深色（墨 #7A6127）也有亮色（夜读 #FF9F43、
      秋 #D4AF37、春 #F0D080…），白字压在亮强调色上实测低到 1.29:1
      （night 2.04 / film 2.10 / custom 3.38 / spring 1.50 / midautumn 1.29）。
      --onAccent 是 themes.css 专门为此定义的「压在强调色上的字」：浅底主题给近白、
      深底主题给近黑，方向随皮肤自动翻转（反算 #1A1508 on #D4AF37 = 8.65，
      #1A1206 on #FF9F43 = 9.08）。

   ② 正文一律不用 --tx3，至少 --tx2 起。
      --tx3 的语义是「三级弱化」，做**装饰性**描边没问题；当文字色就是
      「看得见但读不清」：默认主题下 #877E70 落在面板 #F5F0E8 上实测 3.53:1、
      落在深色描边块上 3.62:1，都低于 AA 对正文的 4.5:1。本文件原先有 20 处
      把 --tx3 当文字色（含 .m-head span / .m-sh-tag / .m-sh-why / .ma-lead /
      .ml-desc / .m-tip / .mb-lv / .mb-stage-tip …），已统一改 --tx2。
      ★ 化学栏（chem/style.css）此前为 .m-head span 等加过 #chem-root 作用域内的兜底，
        这里改完之后那几条兜底已经冗余，可以删（chem 那边自己收）。
   ============================================================ */

/* 根选择器必须是 #math-root —— 数学页的真实容器是 index.html 里的 <div id="math-root">，
   由 math.js 的 MathInit 往里塞 .m-wrap。这里以前写成 #m-math（DOM 里从来没有这个 id），
   整条规则是死代码：max-width / margin:auto / padding-bottom 全都没生效。 */
#math-root .m-wrap { max-width: 1100px; margin: 0 auto; padding-bottom: 40px; }

/* ---- 通用卡片 ---- */
.m-card { background: var(--cardF, var(--panel)); border: 1px solid var(--line);
  border-radius: 14px; padding: 18px; box-shadow: 0 2px 14px rgba(0,0,0,.06); }
.m-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }

/* ============================================================
   垂直节奏 —— 相邻块之间必须留出真实间距
   ------------------------------------------------------------
   数学页里「卡片头 / 分段按钮 / 内容区」是三个紧挨着的兄弟元素：
       <div class="m-card"><div class="m-head">…</div><div>(body)</div></div>
       <div class="m-segbtn">…</div>
       <div>(stage / m-widget)</div>
   纵向间距原本全靠 .m-card 的 padding:18px 撑着，兄弟之间的边界间距实测 = 0px。
   在整数 DPR 的桌面 Chrome 上只是「贴得紧」；但在折叠屏这类非整数 DPR 机型
   （如 Honor Magic V2 展开态 ≈ 800 CSS px / DPR 2.695）上，下一块的 1px 边框
   与 12–14px 圆角会被压到上一块的按钮上，看起来就是「模块重叠」（用户反馈的现象）。
   这里把间距显式给到相邻元素，不再依赖某个盒子的 padding。
   .m-head 原本的 margin-bottom 改成「相邻兄弟的 margin-top」，
   对 .m-head 后面直接跟内容的写法（快问 / 榜单 / 学情表等）视觉等价。

   ★ 2026-09-29：这条规则原先在五个学科栏各写了一份（#math-root / #phys-root /
   #chem-root / #hum-root / #code-root），**三个平台栏目（素养画像 / AI 治理 /
   育人中台）一份都没有** —— 于是那三栏里相邻的两张 .m-card 边界间距实测 = 0px，
   卡片边框与圆角直接贴在一起。同一类缺陷不该靠「每个新栏目记得抄一份」来避免，
   所以这里去掉 root 前缀、做成全站通用：任何用到 .m-pane 的栏目自动获得垂直节奏。
   （五科各自的同名单条规则保留，选择器更具体、结果一致，不冲突。）
   ------------------------------------------------------------
   为什么是「相邻兄弟的 margin-top」而不是各块的 margin-bottom：
   相邻兄弟的 margin 会折叠，只写一边就不会出现「14 + 16 = 30」的双倍间距。 */
.m-pane > * + *,
.m-card-b > * + *,
.m-head + *,
.m-instruction + *,
.m-segbtn + *,
.m-segbtn + .m-segbtn { margin-top: 16px; }
#math-root .m-head { margin-bottom: 0; }
#math-root .m-head + *,
#math-root .m-segbtn + *,
#math-root .m-segbtn + .m-segbtn,
#math-root .m-pane > * + * { margin-top: 16px; }
.m-head b { font-size: 15px; letter-spacing: 2px; color: var(--accent); }
.m-head span { font-size: 12px; color: var(--tx2); }
.m-lead { color: var(--tx2); font-size: 13.5px; line-height: 1.9; }

/* ---- 引言 / Hero ---- */
.m-intro { text-align: center; padding: 26px 16px 30px; position: relative; }
.m-intro h1 { font-size: clamp(28px, 5vw, 46px); letter-spacing: 8px; color: var(--accent);
  margin: 0; text-shadow: 0 0 26px rgba(var(--accentRGB), .8); }
.m-intro .m-slogan { margin-top: 10px; font-size: 14px; color: var(--accent2); letter-spacing: 2px; }
.m-intro p.m-lead { max-width: 620px; margin: 16px auto 0; }
.m-stages { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-top: 18px; }

/* ---- 模块切换标签 ---- */
.m-tabs { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; margin: 8px 0 22px; }
.m-tab { border: 1px solid var(--line); background: var(--panel2); color: var(--tx2);
  padding: 9px 16px; border-radius: 999px; cursor: pointer; font-size: 13.5px; letter-spacing: 1px;
  transition: all .16s; }
.m-tab:hover { color: var(--tx); border-color: var(--accent); }
.m-tab.m-sel { background: var(--accent); color: var(--onAccent); border-color: var(--accent);
  box-shadow: 0 4px 14px rgba(var(--accentRGB), .4); }

.m-pane { display: none; }
.m-pane.on { display: block; animation: mFade .35s ease; }
@keyframes mFade { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ---- 数海地图：真实底图（高德） ---- */
.m-realmap { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; background: var(--panel2); }
/* 容器必须有确定的像素高度，否则高德拿不到尺寸、只画出一半或整块空白 */
.m-amap { width: 100%; height: 380px; background: var(--panel2); }
.m-amap-off { height: auto; padding: 14px; background: var(--panel2) !important; }
/* ↑ 为什么要 !important 显式压一层底：底图初始化失败时（高德 SDK 加载到了、
   但瓦片/尺寸/授权任一出错），AMap 已经把容器的底色写进**内联样式**里
   （实测 rgb(26,35,44)），随后 subj-map.js 的 degrade() 只加 .m-amap-off、不清内联。
   于是「降级占位」整块压在 AMap 残留的暗底上：降级文案吃 --tx2、重试按钮吃 --accent，
   在浅底皮肤里这两个都是深色字 —— ink 实测 2.7:1、bright 2.35:1、custom 2.56:1，
   全低于 AA 4.5:1（只有深底皮肤凑巧过得去）。
   降级态本来就不该有暗底，这里显式盖回面板色；!important 是为了压过那条内联样式。
   只在 .m-amap-off（降级态）生效，正常底图不受影响。 */
/* 兜底：按真实经纬度定位的示意图（只画经纬网与圆点，不画海岸线/国界）。
   高德底图建不出来时（弱网、切页动画中容器还没尺寸、key 未授权）用它顶上，
   保证「数海地图」任何时候都不是一块空白。 */
.m-geo-wrap { margin: 6px 0 4px; }
.m-geo-sketch { display: block; width: 100%; height: auto; background: var(--panel);
  border: 1px solid var(--line); border-radius: 10px; }
.m-geo-dot:hover circle { opacity: 1; }
/* ★ 联动高亮（时间轴 ↔ 地图）。判据不能只看「类加上了没有」：
   高亮必须是**画面上看得见的差异** —— 所以这里同时改半径描边与透明度，
   而不是只加一个没有视觉效果的类名，否则「点了没反应」会照样复现。 */
.m-geo-dot.is-focus circle { opacity: 1; stroke: var(--tx); stroke-width: 2; }
.m-geo-dot.is-focus text { font-weight: 700; fill: var(--accent); }
/* 底图上的自定义标记：只画点与名字，不画任何边界 */
.m-pin { width: 12px; height: 12px; border-radius: 50%; background: var(--accent);
  border: 2px solid rgba(255,255,255,.9); box-shadow: 0 0 8px rgba(var(--accentRGB), .65); cursor: pointer; }
.m-pin.big { width: 17px; height: 17px; background: var(--accent2); position: relative; }
/* 第二层：开源社区 / 项目。用空心 + 实心两种形状区分两层，
   而不是只换个相近的颜色 —— 色差在小点上本来就难分辨。 */
.m-pin.os { width: 11px; height: 11px; background: var(--panel); border-color: var(--accent2); border-width: 2.5px; }
.m-pin.big:hover, .m-pin:hover { transform: scale(1.25); }
.m-pin.is-focus { transform: scale(1.5); box-shadow: 0 0 0 3px rgba(var(--accentRGB), .35), 0 0 10px rgba(var(--accentRGB), .7); }
.m-pin-label { position: absolute; left: 50%; bottom: 20px; transform: translateX(-50%); white-space: nowrap;
  font-family: var(--serif); font-size: 12px; letter-spacing: 1px; color: var(--tx);
  background: rgba(var(--bgRGB, 255,255,255), .86); border: 1px solid var(--line);
  border-radius: 999px; padding: 1px 8px; }
/* 高德的 logo / 版权条在深色皮肤下要能看清，不做隐藏（合规要求保留） */
.m-amap .amap-logo, .m-amap .amap-copyright { opacity: .75; }
.m-map-info { margin-top: 14px; }
.m-map-info h3 { color: var(--accent); margin: 0 0 4px; font-size: 17px; letter-spacing: 1px; }
/* 这里的类名曾经叫 .era —— 与全站时间轴的 .era{position:absolute;height:30px} 撞名，
   结果这行「朝代 · 时期」被绝对定位、脱离文档流，与下方正文叠在一起（用户反馈的文字折叠）。
   现在用 .m-era，并显式复位 position/height 做双保险。 */
.m-map-info .m-era { position: static; height: auto; display: block; white-space: normal;
  color: var(--tx2); font-size: 12px; margin-bottom: 8px; }

/* ---- 数形视界（可视化引擎） ---- */
.m-widget { display: grid; grid-template-columns: 1fr 280px; gap: 18px; align-items: start; }
.m-canvas-box { background: var(--panel2); border: 1px solid var(--line); border-radius: 12px; padding: 10px; }
.m-canvas-box canvas { width: 100%; height: auto; display: block; border-radius: 8px; background: var(--panel); }
.m-ctrl label { display: block; font-size: 12.5px; color: var(--tx2); margin: 12px 0 4px; }
.m-ctrl input[type=range] { width: 100%; accent-color: var(--accent); }
.m-ctrl .val { color: var(--accent); font-weight: 700; }
.m-segbtn { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.m-segbtn button { border: 1px solid var(--line); background: var(--panel2); color: var(--tx2);
  padding: 6px 11px; border-radius: 8px; cursor: pointer; font-size: 12.5px; }
.m-segbtn button.m-sel { background: var(--accent); color: var(--onAccent); border-color: var(--accent); }
.m-stat-line { font-size: 13px; color: var(--tx2); margin-top: 8px; }
.m-stat-line b { color: var(--accent2); }

/* ---- 数海百科 ---- */
.m-kno-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 14px; }
.m-kno { border: 1px solid var(--line); border-radius: 12px; padding: 14px 15px; background: var(--panel2);
  cursor: pointer; transition: transform .16s, border-color .16s, box-shadow .16s; }
.m-kno:hover { transform: translateY(-3px); border-color: var(--accent); box-shadow: 0 6px 18px rgba(0,0,0,.08); }
.m-kno .kb { font-weight: 700; color: var(--tx); font-size: 14.5px; }
.m-kno .kp { font-size: 12.5px; color: var(--tx2); margin: 5px 0 8px; }
.m-kno .km { font-size: 12px; color: var(--accent); background: rgba(var(--accentRGB), .12);
  display: inline-block; padding: 2px 8px; border-radius: 6px; }
.m-kno .kf { font-size: 12.5px; color: var(--tx2); margin-top: 8px; line-height: 1.7; }

/* ---- 数学名人 ---- */
.m-people { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 14px; }
.m-person { border: 1px solid var(--line); border-radius: 14px; padding: 16px; background: var(--cardF, var(--panel));
  cursor: pointer; transition: transform .16s, box-shadow .16s; }
.m-person:hover { transform: translateY(-3px); box-shadow: 0 8px 20px rgba(0,0,0,.1); }
/* 注意：下面三个类名曾经直接叫 .pn/.pe/.pc，与全站 style.css 里的 .pc（padding+grid）
   撞名，人物/作品卡片的描述区被塞进了 18px 内边距并变成栅格。一律加 m- 前缀隔开。 */
.m-person .m-pn { font-size: 16px; font-weight: 700; color: var(--accent); }
.m-person .m-pe { font-size: 11.5px; color: var(--tx2); }
.m-person .m-pc { font-size: 12.5px; color: var(--tx2); margin-top: 8px; line-height: 1.7; }
/* 可点开的卡片（目前只有「跨学科建模」）：给指针与一行「前往」提示。
   不给所有 .m-person 加 cursor:pointer —— 家庭实验那些卡点了什么都不会发生，
   加了指针反而骗用户。 */
.m-person-go { cursor: pointer; }
.m-person-go::after { content: '前往对应小节 →'; display: block; margin-top: 9px;
  font-size: 11.5px; letter-spacing: .5px; color: var(--accent); }

/* ---- 思维闯关 ---- */
.m-quiz-q { font-size: 15px; color: var(--tx); margin: 6px 0 12px; line-height: 1.7; }
.m-opt { display: block; width: 100%; text-align: left; border: 1px solid var(--line); background: var(--panel2);
  color: var(--tx2); padding: 11px 14px; border-radius: 10px; margin: 7px 0; cursor: pointer; font-size: 13.5px;
  transition: all .14s; }
.m-opt:hover { border-color: var(--accent); color: var(--tx); }
.m-opt.m-sel { border-color: var(--accent); background: rgba(var(--accentRGB), .14); color: var(--tx); }
.m-opt.ok { border-color: #2e9e5b; background: rgba(46,158,91,.14); color: var(--tx); }
.m-opt.no { border-color: #d9534f; background: rgba(217,83,79,.14); color: var(--tx); }
.m-quiz-foot { display: flex; align-items: center; gap: 12px; margin-top: 14px; flex-wrap: wrap; }
.m-tip { font-size: 12.5px; color: var(--tx2); margin-top: 10px; line-height: 1.7;
  border-left: 3px solid var(--accent); padding-left: 10px; }

/* ---- 通用按钮 ---- */
.m-btn { border: 1px solid var(--accent); background: var(--accent); color: var(--onAccent); padding: 9px 18px;
  border-radius: 10px; cursor: pointer; font-size: 13.5px; letter-spacing: 1px; transition: filter .15s; }
.m-btn:hover { filter: brightness(1.08); }
.m-btn.ghost { background: transparent; color: var(--accent); }
.m-btn:disabled { opacity: .5; cursor: not-allowed; }

/* ---- 积分结算条 ---- */
.m-earn { margin-top: 14px; padding: 12px 14px; border-radius: 10px; background: rgba(var(--accentRGB), .14);
  color: var(--tx); font-size: 13.5px; }
.m-earn b { color: var(--accent); }

/* ============================================================
   扩展样式 v2 —— 覆盖 8 大模块：精灵状态条 / 图鉴养成 / 教师端 /
   建模 / 竞赛 / 模态框 / 表格 / 知识图谱 / 输入区
   颜色一律取站点主题变量，11 套皮肤自动适配。
   ============================================================ */

/* ---- 顶部状态条：数字精灵 + 能量 + 学段切换 ---- */
.m-bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  background: var(--cardF, var(--panel)); border: 1px solid var(--line); border-radius: 14px;
  padding: 14px 18px; margin-bottom: 18px; }
.mb-left { display: flex; align-items: center; gap: 14px; min-width: 260px; }
.mb-sprite { font-size: 40px; line-height: 1; filter: drop-shadow(0 3px 8px rgba(var(--accentRGB), .4)); }
.mb-meta { min-width: 0; }
.mb-name { font-size: 14.5px; font-weight: 700; color: var(--accent); letter-spacing: 1px; }
.mb-lv { font-size: 12px; color: var(--tx2); font-weight: 400; }
.mb-prog { height: 7px; border-radius: 99px; background: var(--panel2); border: 1px solid var(--line);
  overflow: hidden; margin: 6px 0 4px; width: 220px; max-width: 100%; }
.mb-prog i { display: block; height: 100%; background: linear-gradient(90deg, var(--accent2), var(--accent)); transition: width .4s ease; }
.mb-energy { font-size: 12px; color: var(--tx2); }
.mb-stages { display: flex; gap: 6px; flex-wrap: wrap; }
.mb-stage { border: 1px solid var(--line); background: var(--panel2); color: var(--tx2);
  padding: 6px 12px; border-radius: 999px; cursor: pointer; font-size: 12.5px; transition: all .16s; }
.mb-stage:hover { border-color: var(--accent); color: var(--tx); }
.mb-stage.m-sel { background: var(--accent); color: var(--onAccent); border-color: var(--accent); }
/* 学段按钮右侧一栏：按钮 + 一行「学段影响什么」的说明。
   说明必须跟着按钮走 —— 四个学段按钮原先只改了状态，界面上没有任何地方
   说明它管什么，用户点完看不到变化就当成坏了。 */
.mb-right { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; min-width: 0; }
.mb-stage-tip { font-size: 11.5px; color: var(--tx2); line-height: 1.6; text-align: right; }

/* ---- 学段相关的通用件 ---- */
/* 面板顶部一行「当前学段 · 本学段 N 条」 */
.m-stage-note { font-size: 12.5px; color: var(--tx2); margin: 0 0 12px; }
.m-stage-note b { color: var(--accent); font-weight: 700; }
/* 面板顶部的学段页头（M.stageHead 产出）。
   ★ 存在的理由：学段按钮在页面最顶上，用户点完要往下滚很久才看到内容；
   每个面板顶上再放一条「当前学段 + 本页有多少条」，切换的反馈才落在眼睛所在的位置。
   它是「这个按钮管用」的最小可见证据，所以每个视图都要插一条。 */
.m-stage-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin: 0 0 14px; padding: 9px 13px; border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: 10px; background: var(--panel2); font-size: 12.5px; color: var(--tx2); line-height: 1.6; }
.m-stage-head .m-sh-tag { font-size: 11px; letter-spacing: 1px; color: var(--tx2); }
.m-stage-head .m-sh-cur { color: var(--accent); font-weight: 700; font-size: 13.5px; }
.m-stage-head .m-sh-sep { color: var(--line); }
.m-stage-head .m-sh-note { color: var(--tx2); }
.m-stage-head .m-sh-why { color: var(--tx2); }
.m-stage-head .m-sh-why::before { content: '（'; }
.m-stage-head .m-sh-why::after { content: '）'; }
@media (max-width: 640px) { .m-stage-head { font-size: 12px; padding: 8px 11px; } }
/* 本学段课标板块（教师端备课选题用）：一整排板块名，换学段整排全换 */
.m-stage-kb { margin: 14px 0 4px; }
.m-kb-cloud { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 9px; }
/* 「本学段示例课程 · 学段范围」一行正文（教师端 AI 备课顶上） */
.m-stage-course { display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin: 12px 0 0; padding: 10px 13px; border: 1px dashed var(--line); border-radius: 10px;
  font-size: 12.5px; color: var(--tx2); line-height: 1.7; }
.m-stage-course .m-sc-k { color: var(--tx2); font-size: 11.5px; letter-spacing: 1px; }
.m-stage-course b { color: var(--tx); }
/* 每条内容右上角的学段小标；本学段的高亮 */
.m-stage-chip { display: inline-block; font-size: 11px; line-height: 1.5; padding: 0 7px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--tx2); background: var(--panel2); white-space: nowrap; }
.m-stage-chip.is-now { color: var(--accent); border-color: var(--accent); background: transparent; font-weight: 700; }
/* 空态：某学段暂时没有内容时用它，别留一片空白 */
.m-stage-empty { color: var(--tx2); font-size: 13.5px; line-height: 1.9; }
/* 数海百科 · 学段知识点大纲 */
.m-kno-outline { margin-top: 16px; }
.m-ko-head { font-size: 13px; color: var(--accent); letter-spacing: 1px; font-weight: 700; margin-bottom: 8px; }
.m-ko-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px; }
.m-ko { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; background: var(--panel2); }
.m-ko .kob { font-size: 13.5px; font-weight: 700; color: var(--tx); }
.m-ko .kop { font-size: 12px; color: var(--tx2); margin-top: 3px; }
.m-ko .kom { font-size: 11.5px; color: var(--tx2); margin-top: 5px; }
.m-ko .kof { font-size: 12px; color: var(--tx2); margin-top: 5px; line-height: 1.7; }

/* ---- 标签页里的「看/探/学/玩/教/用」小标 ---- */
/* 这条小标踩过两次坑，两次都出在「底是强调色淡染」上（12 套皮肤逐条复算得到）：
   ① alpha 太深：.18 时 night 4.24 / spring 3.68 / film 3.95（11px 要 4.5:1）→ 降到 .12。
   ② 光降 alpha 到不了头：spring 的 --accent 是暗红、--tx2 是浅米，
      .12 淡染底上 --tx2 只有 **4.07:1**，而且 alpha 一路降到 .06 也才 4.48:1 ——
      根因不是淡染浓度，是「次级色 --tx2 本就不该压在强调色淡染上」。
   正解是把淡染底上的字换成 --tx（正文色）：12 套皮肤里最差 spring 6.05:1、
   film 9.6:1。语义上也对 —— 小标本来就比页签文字更强调一层。
   （所以「调和 alpha」只能算缓解，「换字色」才是治本；两者都留着。） */
.m-tab i { font-style: normal; display: inline-block; font-size: 11px; line-height: 1;
  margin-right: 6px; padding: 3px 6px; border-radius: 6px;
  background: rgba(var(--accentRGB), .12); color: var(--tx); }
/* 选中页签里的角标（看 / 探 / 学…）：底要用**和字反向**的颜色。
   --hlRGB 正是 themes.css 里「强调色对面」的那个色（浅底主题 = 墨色 44,44,44，
   深底主题 = 255,255,255），所以 rgba(var(--hlRGB), .26) 会随皮肤自动反向：
   浅底主题上把底压暗、深底主题上把底提亮，两边都把字衬出来。
   原先写死 rgba(255,255,255,.26) —— 深底主题上等于在亮强调色上再刷一层白，
   字（--onAccent，深色）反而更糊；浅底主题上实测 3.37:1。
   ★ 字色必须在这里**显式**写 --onAccent：上面那条已把 .m-tab i 的字定成 --tx，
     选中态若继续靠 inherit 就继承到 --tx，压在强调色实底上会掉下来。 */
.m-tab.m-sel i { background: rgba(var(--hlRGB), .26); color: var(--onAccent); }

/* ---- 登录提示 ---- */
.m-login-hint { text-align: center; padding: 26px 20px; }
.lh-ico { font-size: 34px; margin-bottom: 8px; }
.lh-t { font-size: 14px; color: var(--tx); margin-bottom: 6px; letter-spacing: 1px; }
.m-login-hint .ma-lead { max-width: 400px; margin: 0 auto 14px; }

/* ---- 未登录占位（AI 卡片）------------------------------------------------
   ★ 产品硬规则：AI 功能必须登录后才能用。未登录时这些卡片**不渲染输入框** ——
     用户没法先白填一遍再被拒 —— 而是直接显示这块占位。
     虚线边框是刻意的：它是「空态/待解锁」，跟真实内容区（实线 .m-card）区分开，
     用户一眼就知道不是页面坏了。
     ★ 只写这一份：本文件是数/物/化/人/码五栏共用的组件表（见 index.html 的
     「五个文件的布局规则各以…共用 math/style.css 里的 .m-* 组件」），
     所以物化人码各栏的 style.css 里不再各抄一份 —— 漏抄一处就会出现
     「这一栏的占位没有边框」这种静默不一致。 */
.m-ai-gate { text-align: center; padding: 22px 18px; background: var(--panel2);
  /* 上方常是一张课程/课题卡，贴着会把两块看成一块 —— 与全站 16px 节奏一致 */
  margin-top: 16px;
  border: 1px dashed var(--line); border-radius: 12px; }
.m-ai-gate-t { font-size: 14.5px; color: var(--tx); letter-spacing: 1px; margin-bottom: 8px; }
.m-ai-gate .m-instruction { display: inline-block; max-width: 460px; text-align: left; }
.m-ai-gate .btn { margin-top: 14px; }

/* ---- 轻提示 ---- */
.m-toasts { position: fixed; top: 18px; left: 50%; transform: translateX(-50%); z-index: 5000;
  display: flex; flex-direction: column; gap: 8px; align-items: center; pointer-events: none; }
.m-toast { background: var(--panel); border: 1px solid var(--accent); color: var(--tx);
  border-radius: 999px; padding: 10px 20px; font-size: 13px; box-shadow: 0 8px 26px rgba(0,0,0,.28);
  transition: opacity .4s, transform .4s; max-width: min(90vw, 520px); text-align: center; }
.m-toast.big { border-color: var(--accent2); font-size: 13.5px; padding: 12px 22px; }
/* 同一句话在气泡还在场时又被请求 → 复用它并回弹一下，而不是叠出第二个一模一样的气泡 */
.m-toast.m-pop { animation: mToastPop .32s ease; }
@keyframes mToastPop { 0% { transform: scale(.94); } 60% { transform: scale(1.035); } 100% { transform: scale(1); } }
/* 手机端：顶到 18px 会正好压住页头（汉堡按钮 / 标题 / 「未登录」），
   提示挡住了入口反而更烦；往下让开一条，并收一收横向占位 */
@media (max-width: 640px) {
  .m-toasts { top: calc(env(safe-area-inset-top, 0px) + 72px); max-width: 100%; padding: 0 14px; }
  .m-toast { max-width: 100%; }
}

/* ---- 模态框（定理详情 / 建模项目） ---- */
.m-modal { position: fixed; inset: 0; background: rgba(0,0,0,.55); display: flex;
  align-items: center; justify-content: center; padding: 20px; z-index: 4000; animation: mFade .2s ease; }
.m-modal-box { width: min(640px, 100%); max-height: 86vh; overflow: auto; background: var(--panel);
  border: 1px solid var(--line); border-radius: 16px; padding: 20px 22px; box-shadow: 0 20px 60px rgba(0,0,0,.4); }
.mmb-head { display: flex; align-items: center; gap: 10px; padding-bottom: 12px;
  border-bottom: 1px solid var(--line); margin-bottom: 14px; flex-wrap: wrap; }
.mmb-head b { font-size: 17px; color: var(--accent); letter-spacing: 1px; }
.mmb-head span { font-size: 12px; color: var(--tx2); }
.mmb-head .m-x { margin-left: auto; }
.m-x { border: none; background: transparent; color: var(--tx2); font-size: 18px; cursor: pointer;
  line-height: 1; padding: 4px 8px; border-radius: 8px; }
.m-x:hover { color: var(--tx); background: var(--panel2); }
.m-formula-eq { font-size: 16px; text-align: center; color: var(--tx); background: var(--panel2);
  border: 1px dashed var(--line); border-radius: 10px; padding: 14px; margin-bottom: 14px; letter-spacing: 1px; }
.mmb-sec { margin-bottom: 12px; }
.mmb-sec > b { display: block; font-size: 13px; color: var(--accent); letter-spacing: 1px; margin-bottom: 4px; }
.mmb-sec p { margin: 0; font-size: 13.5px; color: var(--tx2); line-height: 1.9; }
.mmb-foot { display: flex; gap: 10px; justify-content: flex-end; padding-top: 12px;
  border-top: 1px solid var(--line); margin-top: 6px; flex-wrap: wrap; }

/* ---- 知识图谱 ---- */
.m-graph-root { text-align: center; font-size: 16px; color: var(--accent); letter-spacing: 2px; padding: 6px 0 16px; }
.m-graph-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.m-graph-col { border: 1px solid var(--line); border-radius: 12px; padding: 10px; background: var(--panel2); }
.m-graph-dom { font-size: 13.5px; font-weight: 700; color: var(--tx); padding: 7px 10px;
  border-radius: 8px; background: var(--cardF, var(--panel)); border: 1px solid var(--line); margin-bottom: 8px; }
.m-graph-dom.lv-ok { border-color: #2e9e5b; background: rgba(46,158,91,.16); }
.m-graph-dom.lv-mid { border-color: #c9a24a; background: rgba(216,178,110,.20); }
.m-graph-dom.lv-low { border-color: #d9534f; background: rgba(217,83,79,.14); }
/* 四态里的「未学」：灰 —— 之前缺这一态，「没有作答记录」和「答得还行」在视觉上分不开 */
.m-graph-dom.lv-none { border-color: var(--line); background: var(--cardF, var(--panel)); color: var(--tx2); cursor: pointer; }
.m-graph-dom { cursor: pointer; }
.m-graph-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; }
.m-graph-legend .lg { font-size: 12px; padding: 3px 9px; border-radius: 6px; border: 1px solid var(--line); color: var(--tx2); }
.m-graph-legend .lg-none { border-color: var(--line); }
.m-graph-legend .lg-low { border-color: #d9534f; color: #d9534f; }
.m-graph-legend .lg-mid { border-color: #c9a24a; color: #c9a24a; }
.m-graph-legend .lg-ok { border-color: #2e9e5b; color: #2e9e5b; }
.m-graph-legend .lg-note { font-size: 11.5px; color: var(--tx2); }
.m-graph-detail { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--line); }
.m-graph-detail:empty { display: none; }
.m-graph-kids { display: flex; flex-wrap: wrap; gap: 5px; }
.m-graph-kid { font-size: 11.5px; color: var(--tx2); background: var(--cardF, var(--panel));
  border: 1px solid var(--line); border-radius: 6px; padding: 3px 7px; }

/* ---- 关系标签 / 筛选 chips ---- */
.m-rel { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; }
.m-rel-chip { font-size: 12.5px; color: var(--tx2); border: 1px solid var(--line); background: var(--panel2);
  border-radius: 999px; padding: 5px 12px; cursor: pointer; transition: all .14s; }
.m-rel-chip:hover { border-color: var(--accent); color: var(--tx); }
.m-rel-chip.m-sel { background: var(--accent); color: var(--onAccent); border-color: var(--accent); }
/* 降级态下「被时间轴选中的那一处」：与 .m-sel 同款填充，另加一道外框，
   让它和「当前页签」这类常驻选中态区分开。 */
.m-rel-chip.is-focus { background: var(--accent); color: var(--onAccent); border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accentRGB), .28); font-weight: 700; }
.m-fav { color: var(--accent); }

/* ---- 表单 / 输入区 ---- */
.m-input { width: 100%; box-sizing: border-box; background: var(--panel2); border: 1px solid var(--line);
  color: var(--tx); border-radius: 10px; padding: 10px 13px; font-size: 13.5px; font-family: inherit; }
.m-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px rgba(var(--accentRGB), .25); }
.m-input::placeholder { color: var(--tx2); }
.ma-row { display: flex; align-items: center; gap: 10px; margin: 10px 0; flex-wrap: wrap; }
.ma-row .m-input { flex: 1; min-width: 180px; }
.ma-ta { resize: vertical; line-height: 1.8; margin: 10px 0; min-height: 84px; }
.ma-lead { font-size: 12.5px; color: var(--tx2); line-height: 1.8; margin-top: 6px; }

/* ---- 通用「说明/结论」块（AI 输出、实验结论等） ---- */
.m-instruction { font-size: 13.5px; color: var(--tx); line-height: 1.9; background: var(--panel2);
  border-left: 3px solid var(--accent); border-radius: 0 10px 10px 0; padding: 10px 14px;
  margin-top: 10px; white-space: pre-wrap; word-break: break-word; }
.m-ai-out, .m-qa-out, .m-lesson-out { margin-top: 4px; }
.m-ol { margin: 6px 0 0; padding-left: 20px; color: var(--tx2); font-size: 13px; line-height: 1.9; }
.m-ol li { margin: 3px 0; }

/* ---- 教学设计 ---- */
.m-lesson-card { border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px;
  background: var(--cardF, var(--panel)); margin-top: 12px; }
.mlc-t { font-size: 14.5px; font-weight: 700; color: var(--accent); letter-spacing: 1px; margin-bottom: 8px; }

/* ---- 错题本 / 日志列表 ---- */
.m-wrong-list { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; max-height: 340px; overflow: auto; }
.m-wrong { font-size: 12.8px; color: var(--tx2); line-height: 1.7; background: var(--panel2);
  border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; }
.m-wrong b { color: var(--accent); }
.m-wrong .m-tip { margin-top: 6px; }

/* ---- 关卡地图 ---- */
.m-level-map { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 14px; }
.m-level { position: relative; border: 1px solid var(--line); border-radius: 14px; padding: 16px;
  background: var(--cardF, var(--panel)); cursor: pointer;
  transition: transform .16s, box-shadow .16s, border-color .16s; }
.m-level:hover { transform: translateY(-3px); border-color: var(--accent); box-shadow: 0 8px 20px rgba(0,0,0,.1); }
.ml-tier { font-size: 11.5px; color: var(--accent); letter-spacing: 1px; }
.ml-name { font-size: 15.5px; font-weight: 700; color: var(--tx); margin: 4px 0 6px; }
.ml-desc { font-size: 12.5px; color: var(--tx2); line-height: 1.7; min-height: 34px; }
.ml-prog { height: 6px; border-radius: 99px; background: var(--panel2); border: 1px solid var(--line);
  overflow: hidden; margin: 10px 0 5px; }
.ml-prog i { display: block; height: 100%; background: linear-gradient(90deg, var(--accent2), var(--accent)); }
.ml-acc { font-size: 12px; color: var(--tx2); }

/* ---- 图鉴/精灵/徽章状态 ---- */
.m-person.locked { opacity: .55; filter: grayscale(.5); }
.m-person.owned { border-color: var(--accent); }
.m-person.cur { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(var(--accentRGB), .4); }

/* ---- 表格（排行 / 学情热力 / 探究记录） ---- */
.m-table { width: 100%; border-collapse: collapse; font-size: 13px; margin-top: 8px; }
.m-table th, .m-table td { border: 1px solid var(--line); padding: 8px 10px; text-align: left; color: var(--tx2); }
.m-table th { background: var(--panel2); color: var(--accent); font-weight: 700; letter-spacing: .5px; }
.m-table tr.me td { background: rgba(var(--accentRGB), .12); color: var(--tx); }
.m-table.m-heat td.h-ok { background: rgba(46,158,91,.20); color: var(--tx); }
.m-table.m-heat td.h-mid { background: rgba(216,178,110,.24); color: var(--tx); }
.m-table.m-heat td.h-low { background: rgba(217,83,79,.20); color: var(--tx); }
/* 「没有过程数据」不是「差」：不给底色，也不着色，只把话说清楚。
   ★ 字色用 --tx2 而不是 --tx3：「未作答」是有语义的真文字（这个学生这块没作答），
     不是装饰占位；--tx3 当正文色在默认主题只有 3.53:1，低于 AA 正文 4.5:1。 */
.m-table.m-heat td.h-none { background: transparent; color: var(--tx2); font-weight: 400; }

/* ---- 资源共享 / 班级列表 ---- */
.m-share-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; margin-top: 8px; }
.m-cls-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.m-filter { margin: 8px 0; }

/* ---- 真题库 · 限时全真模拟赛 ---- */
.m-mock-entry { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--line); }
.m-mock-entry .m-lead { margin-bottom: 6px; }
.m-mock-entry .m-input { margin-right: 8px; }
.mk-clock { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--accent); letter-spacing: 1px; }
.mk-nav { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.mk-no { min-width: 30px; height: 30px; border: 1px solid var(--line); background: var(--panel2);
  color: var(--tx2); border-radius: 6px; cursor: pointer; font-size: 13px; }
.mk-no.answered { border-color: var(--accent); color: var(--accent); }
.mk-no.cur { background: var(--accent); color: var(--onAccent); border-color: var(--accent); }
.mk-prog { margin-left: auto; font-size: 12px; color: var(--tx2); }
.mk-result { border-top: 1px dashed var(--line); padding-top: 12px; }
/* 模拟赛结算里的小榜单：与「排行榜」同一个挂点类名，便于回归脚本统一找 */
.m-rank-board { margin-top: 6px; }
.m-rank-board .m-wrong.is-me { border-left: 3px solid var(--accent); }

/* ---- 教练系统：AI 批注 / 成长曲线 / 一题多解 ---- */
.cw-item { margin-bottom: 12px; }
.cw-a { width: 100%; box-sizing: border-box; margin-top: 6px; }
.cw-out .m-instruction { margin-top: 8px; }
.cw-out .m-earn { margin-top: 6px; }
.cw-qs:empty { display: none; }
.cw-qs .cw-q { padding: 8px 0 4px; border-top: 1px dashed var(--line); }
.cw-qs .cw-q:first-of-type { border-top: 0; }
.cw-qs .m-opt { display: block; width: 100%; text-align: left; margin: 4px 0; }

/* ---- 图鉴分享与好友交换 ---- */
.m-card-share { margin-top: 14px; }
.m-card-share .cs-in, .m-card-share .cs-out-t { width: 100%; box-sizing: border-box; }
.m-card-share .cs-out-t { margin-top: 6px; font-family: var(--serif); }

/* ---- 首次进入 · 选学段 ----
   自己的遮罩类（不是 .m-modal）：页面里其它弹窗与回归用例都按 .m-modal 找元素，
   首启引导复用它就会把那些选择器抢过去。 */
.m-sg-ov { position: fixed; inset: 0; background: rgba(0,0,0,.55); display: flex;
  align-items: center; justify-content: center; z-index: 900; padding: 16px; }
.m-stage-guide .m-sg-btns { display: flex; flex-wrap: wrap; gap: 10px; }
.m-stage-guide .m-sg-btn { flex: 1 1 44%; min-width: 120px; }
.m-stage-guide .m-sg-btn.m-sel { background: var(--accent); color: var(--onAccent); border-color: var(--accent); }

/* ---- 数值强调 ---- */
.m-stat-line b { color: var(--accent); font-weight: 700; }
.m-earn b { color: var(--accent); }

/* ============================================================
   断点
   ------------------------------------------------------------
   本文件原本只有 720px 一个断点，但全站在 1023px 就切成了移动布局
   （侧栏收起、内容满宽）。于是 721–1023px 这一档掉进夹缝：
   全站按移动端排版，数学页却还在用桌面假设 ——
   地图固定 380px 高、.mb-left 最小 260px 宽、知识图谱按 150px 起排。
   折叠屏展开态的 CSS 宽度正好落在这条夹缝里（实测 ≈ 800px），
   所以这里补一档，把这一段的假设也降到移动端。 */
@media (max-width: 1023px) {
  .m-amap { height: 320px; }
  .mb-left { min-width: 0; }
  .m-graph-cols { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
  /* 宽屏时学段按钮是靠右的一小栏；这一档改回左对齐，免得行尾只剩几个字 */
  .mb-right { align-items: flex-start; }
  .mb-stage-tip { text-align: left; }
}

@media (max-width: 720px) {
  .m-widget { grid-template-columns: 1fr; }
  .mb-left { min-width: 0; flex: 1 1 100%; }
  .mb-right { width: 100%; align-items: flex-start; }
  .mb-stages { width: 100%; }
  .mb-stage-tip { text-align: left; }
  .m-modal-box { padding: 16px; }
  .m-graph-cols { grid-template-columns: 1fr 1fr; }
  .m-ko-grid { grid-template-columns: 1fr; }
  .m-amap { height: 260px; }
}

/* ============================================================
   时空中的数学发现 · 按真实年份的时间轴
   ------------------------------------------------------------
   朝代条的位置与宽度来自 ERAS.y0/y1（真实公元年份），所以「谁在前、各持续多久」
   是被画出来的，而不是排成一行等距 chip；.m-tl-cursor 是时间游标，
   与下方 range 的拇指共用同一套百分比映射，两者才会对齐。
   ============================================================ */
.m-timeline { position: relative; margin: 10px 0 2px; }
.m-tl-bar { position: relative; height: 30px; border-radius: 8px; background: var(--line2, rgba(255, 255, 255, .06)); }
.m-tl-seg { position: absolute; top: 4px; height: 22px; padding: 0 6px; border: 0; border-radius: 6px; font: inherit; font-size: 11.5px; line-height: 22px; color: var(--tx2); background: var(--panel2, rgba(255, 255, 255, .08)); white-space: nowrap; overflow: hidden; cursor: pointer; }
.m-tl-seg:hover { color: var(--tx); }
.m-tl-seg.m-sel { background: var(--accent); color: var(--onAccent); }
.m-tl-axis { position: relative; height: 15px; margin-top: 2px; }
.m-tl-tick { position: absolute; transform: translateX(-50%); font-size: 10.5px; color: var(--tx2); }
.m-tl-cursor { position: absolute; top: -4px; width: 2px; height: 38px; background: var(--red, #c05a4e); pointer-events: none; }
.m-tl-range { display: block; width: 100%; margin: 6px 0 2px; accent-color: var(--accent); }

/* 同一张卡里并列多个画布件时补一条分隔线（否则两块看起来像一块） */
.m-card-b > .m-widget + .m-widget { margin-top: 18px; padding-top: 16px; border-top: 1px dashed var(--line); }

/* ============================================================
   课堂弹幕
   ------------------------------------------------------------
   弹幕用 CSS 动画横向滚过舞台，滚完由 animationend 把节点移除 ——
   不挂定时器，所以面板被切走时不会留下后台任务。
   ============================================================ */
.dm-stage { position: relative; height: 180px; margin: 8px 0; overflow: hidden; border-radius: 10px; background: var(--line2, rgba(255, 255, 255, .06)); }
.dm-item { position: absolute; right: 0; padding: 3px 10px; white-space: nowrap; font-size: 12.5px; line-height: 1.6; color: var(--tx2); background: var(--panel2, rgba(255, 255, 255, .08)); border-radius: 999px; cursor: pointer; transform: translateX(100%); animation-name: dmFly; animation-timing-function: linear; animation-fill-mode: forwards; animation-duration: 8s; }
.dm-item.mine { color: var(--accent); border: 1px solid var(--accent); }
.dm-item:hover { color: var(--tx); }
@keyframes dmFly { from { transform: translateX(100%); } to { transform: translateX(-110vw); } }
/* 「减少动效」偏好下的静态舞台：不飞、不定位，逐条从上往下排，超出可滚。 */
.dm-stage.dm-static-mode { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 8px; overflow-y: auto; }
.dm-item.dm-static { position: static; right: auto; margin: 0; transform: none; animation: none; }
