/* 中小学·高中知识图谱：全站配色、字号、导航。浏览页与诊断页共用。 */

:root {
  color-scheme: light;
  --bg: #f4f5f7;
  --bg-elev: #ffffff;
  --bg-muted: #eef0f3;
  --text: #17191f;
  --muted: #5c6370;
  --line: #e3e6ed;
  --brand: #0f6e62;
  --brand-strong: #0c574e;
  --brand-soft: #e6f4f1;
  --on-brand: #ffffff;
  --junior: #1d4ed8;
  --junior-soft: #e8efff;
  --focus: #0f6e62;
  --shadow: 0 1px 2px rgba(23, 25, 31, 0.04), 0 10px 28px rgba(23, 25, 31, 0.05);
  --radius: 14px;
  --radius-sm: 10px;
  --header-bg: #f7faf9;
  --logo-sheet: #dff3ef;
  --logo-fold: #ffffff;
  --font: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "Noto Sans SC", "Source Han Sans SC", sans-serif;
  --fs: 16px;
  --ok: #157a3a;
  --ok-bg: #dcfce7;
  --on-ok: #ffffff;
  --bad: #b91c1c;
  --bad-bg: #fee2e2;
  --on-bad: #ffffff;
  --warn: #9a3412;
  --warn-bg: #ffedd5;
  --unk: #475569;
  --unk-bg: #e8eef6;
  --accent: #0f766e;
  --panel: #ffffff;
  --node-primary: #0f766e;
  --node-primary-bg: #d5f3ee;
  --node-junior: #1d4ed8;
  --node-junior-bg: #dbe7ff;
  --node-senior: #a21caf;
  --node-senior-bg: #fae8ff;
  --node-current-bg: #fff4e5;
  --node-current-border: #ea580c;
  --node-text: #162033;
  --edge: #526274;
  --edge-soft: #8aa0b4;
  --hard-bg: #ffedd5;
  --hard-fg: #9a3412;
  --soft-bg: #e7eef6;
  --soft-fg: #475569;
  --diagram-ok-bg: #dcfce7;
  --diagram-ok: #157a3a;
  --diagram-bad-bg: #fee2e2;
  --diagram-bad: #b91c1c;
  --diagram-unk-bg: #f1f5f9;
  --diagram-unk: #64748b;
  --diagram-shaky-bg: #fef3c7;
  --diagram-shaky: #b45309;
  --diagram-text: #162033;
  --diagram-edge: #64748b;
}

body.subject-physics {
  --brand: #b45309;
  --brand-strong: #92400e;
  --brand-soft: #fff7ed;
  --on-brand: #ffffff;
  --focus: #b45309;
  --accent: #b45309;
  --logo-sheet: #fde9d4;
  --logo-fold: #ffffff;
}

body.subject-english {
  --brand: #4338ca;
  --brand-strong: #3730a3;
  --brand-soft: #eef2ff;
  --on-brand: #ffffff;
  --focus: #4338ca;
  --accent: #4338ca;
  --logo-sheet: #e6e8fb;
  --logo-fold: #ffffff;
}

body.subject-chinese {
  --brand: #9f1239;
  --brand-strong: #881337;
  --brand-soft: #fff1f2;
  --on-brand: #ffffff;
  --focus: #9f1239;
  --accent: #9f1239;
  --logo-sheet: #ffe4e6;
  --logo-fold: #ffffff;
}

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --bg: #10141c;
    --bg-elev: #181e29;
    --bg-muted: #232b39;
    --text: #e8edf5;
    --muted: #a7b2c2;
    --line: #313b4d;
    --brand: #2dd4bf;
    --brand-strong: #5eead4;
    --brand-soft: #134e4a;
    --on-brand: #042f2e;
    --junior: #93c5fd;
    --junior-soft: #1e3a8a;
    --focus: #5eead4;
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 12px 28px rgba(0, 0, 0, 0.28);
    --ok: #4ade80;
    --ok-bg: #14532d;
    --on-ok: #052e16;
    --bad: #fca5a5;
    --bad-bg: #7f1d1d;
    --on-bad: #450a0a;
    --warn: #fdba74;
    --warn-bg: #7c2d12;
    --unk: #cbd5e1;
    --unk-bg: #223044;
    --accent: #2dd4bf;
    --header-bg: #171e2a;
    --logo-sheet: #123f3c;
    --logo-fold: #1c5c56;
    --panel: #172232;
    --node-primary: #5eead4;
    --node-primary-bg: #115e59;
    --node-junior: #93c5fd;
    --node-junior-bg: #1e3a8a;
    --node-senior: #f0abfc;
    --node-senior-bg: #4a044e;
    --node-current-bg: #7c2d12;
    --node-current-border: #fdba74;
    --node-text: #f8fafc;
    --edge: #94a3b8;
    --edge-soft: #64748b;
    --hard-bg: #7c2d12;
    --hard-fg: #ffedd5;
    --soft-bg: #232b39;
    --soft-fg: #cbd5e1;
    --diagram-ok-bg: #14532d;
    --diagram-ok: #4ade80;
    --diagram-bad-bg: #7f1d1d;
    --diagram-bad: #fca5a5;
    --diagram-unk-bg: #1e293b;
    --diagram-unk: #cbd5e1;
    --diagram-shaky-bg: #78350f;
    --diagram-shaky: #fcd34d;
    --diagram-text: #f8fafc;
    --diagram-edge: #94a3b8;
  }
  body.subject-physics {
    --brand: #fdba74;
    --brand-strong: #fed7aa;
    --brand-soft: #7c2d12;
    --on-brand: #431407;
    --focus: #fed7aa;
    --accent: #fdba74;
    --logo-sheet: #6b2f12;
    --logo-fold: #8a4218;
  }
  body.subject-english {
    --brand: #a5b4fc;
    --brand-strong: #c7d2fe;
    --brand-soft: #312e81;
    --on-brand: #1e1b4b;
    --focus: #c7d2fe;
    --accent: #a5b4fc;
    --logo-sheet: #2a2870;
    --logo-fold: #3c3a96;
  }
  body.subject-chinese {
    --brand: #fda4af;
    --brand-strong: #fecdd3;
    --brand-soft: #881337;
    --on-brand: #4c0519;
    --focus: #fecdd3;
    --accent: #fda4af;
    --logo-sheet: #6b1230;
    --logo-fold: #9f1239;
  }
}

@media print {
  :root {
    --bg: #fff;
    --bg-elev: #fff;
    --bg-muted: #f4f7fb;
    --text: #162033;
    --muted: #475569;
    --line: #d5dde6;
    --panel: #fff;
    --header-bg: #fff;
    --logo-sheet: #dff3ef;
    --logo-fold: #ffffff;
    --shadow: none;
  }
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs);
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  letter-spacing: 0.01em;
}
img { max-width: 100%; height: auto; }
.node-tip {
  position: absolute;
  z-index: 6;
  max-width: min(280px, calc(100% - 16px));
  padding: 6px 10px;
  border-radius: 10px;
  background: var(--text);
  color: var(--bg);
  font-size: 0.92rem;
  font-weight: 700;
  line-height: 1.45;
  pointer-events: none;
  box-shadow: var(--shadow);
  overflow-wrap: anywhere;
}
code { overflow-wrap: anywhere; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; scroll-behavior: auto !important; }
}

.top-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  min-height: 34px;
  padding: 5px 12px;
  background: #17191f;
  color: #f4f5f7;
  font-size: 14px;
  font-weight: 650;
  line-height: 1.3;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  letter-spacing: 0;
}
.top-banner:hover { background: var(--brand-strong); color: var(--on-brand); }
@media (max-width: 420px) {
  .top-banner { font-size: 12.5px; padding: 5px 8px; }
}
@media print {
  .top-banner { display: none !important; }
}

.site-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 24px;
  padding: 12px 28px;
  background: var(--header-bg);
  border-bottom: 1px solid var(--line);
  max-width: 100%;
}
body:not(.page-explore) .site-header {
  position: sticky;
  top: 0;
  z-index: 30;
}
.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 48px;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}
.logo {
  color: var(--brand);
  width: 40px;
  height: 40px;
  flex: none;
  display: block;
}
/* 头部标识已从内联 SVG 换成 dudu 头像图（JPG，无透明通道）：
 * 用 object-fit 填满 40×40 并给个圆角，避免白底方块直接磕在页头背景上。 */
img.logo {
  object-fit: cover;
  border-radius: 10px;
  background: #fff;
}
.brand-copy {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  gap: 1px;
}
.brand-name {
  font-size: 1.08rem;
  font-weight: 750;
  line-height: 1.15;
  letter-spacing: -0.03em;
  color: var(--text);
  overflow-wrap: anywhere;
}
.brand-kicker {
  font-size: 0.75rem;
  font-weight: 650;
  line-height: 1.2;
  letter-spacing: 0.08em;
  color: var(--brand);
}
.site-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 18px;
  min-width: 0;
  max-width: 100%;
}
/* 学科切换容器（2026-10-31 改版）
 * ---------------------------------------------------------------------------
 * 原先是「横向平铺 10 个学科胶囊」，现在收敛为一个下拉：
 *   容器里只有一个「当前学科 ▾」按钮 + 一个浮层面板（小学/初中/高中 分组）。
 * 结构、开合、无障碍都由 assets/subjects.js 生成并注入样式，这里只负责定位；
 * 想要改外观请改 subjects.js 里的 CSS 段，别再往这里加页脚式的一次性规则。
 * ⛔ 不要恢复平铺胶囊：10 科铺开在窄屏会挤成两行，也撑不住后续还要加的学科。
 */
.subject-switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-width: 0;
}
.page-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px;
  min-width: 0;
}
.nav-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  border-radius: 999px;
  color: var(--muted);
  text-decoration: none;
  font-size: 0.94rem;
  font-weight: 650;
}
.nav-link:hover { background: var(--bg-muted); color: var(--text); }
.nav-link.active, .nav-link[aria-current="page"] {
  background: var(--brand-soft);
  color: var(--brand-strong);
  font-weight: 750;
}
.nav-link.active:hover, .nav-link[aria-current="page"]:hover {
  background: var(--brand-soft);
  color: var(--brand-strong);
}
/* 页面导航二级菜单（2026-10-31）
 * ---------------------------------------------------------------------------
 * 原来「首页 / 知识图谱 / 诊断 / 档案」四个平级链接 + 学科切换 + 登录 chip 横排，
 * 窄屏下顶栏被撑到 500px 以上、必出横向滚动。现在四个页面收进「首页」一个入口：
 *   一级 = 当前所在区（按钮文字跟着页面走，看到按钮就知道自己在哪）
 *   二级 = 首页概览 / 知识图谱 / 诊断 / 档案
 * 开合逻辑在 assets/nav.js（hover 展、移出收、点击切换、Esc 收）。
 * 交互由 JS 承担，但链接是静态 HTML —— 脚本失效时仍是一组可点的普通链接。 */
.nav-menu {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.nav-menu__trigger { gap: 6px; }
.nav-menu__caret {
  flex: none;
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  opacity: 0.7;
  transition: transform 0.15s ease;
}
.nav-menu[data-open="1"] .nav-menu__caret { transform: rotate(180deg); }
.nav-menu[data-open="1"] > .nav-menu__trigger {
  background: var(--bg-muted);
  color: var(--text);
}
.nav-menu__panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 80;
  min-width: 168px;
  padding: 6px;
  background: var(--bg-elev, #fff);
  border: 1px solid var(--line);
  border-radius: var(--radius, 14px);
  box-shadow: var(--shadow, 0 10px 28px rgba(23, 25, 31, 0.08));
  /* ⚠️ 这里【不要】写 display:none / [data-open] display:block 来控制开合 ——
   * 2026-11-01 事故就是它引起的：桌面浏览器用旧版 CSS（HTML 已是新版），
   * 旧 CSS 里没有这条 display:none ⇒ 面板里的账号行、选科、四个链接全摊在页面上。
   * 现在开合只由 assets/nav.js 切 hidden 属性，样式表再旧也不会漏内容。 */
}
.nav-menu__item {
  display: flex;
  align-items: center;
  min-height: 42px;
  padding: 0 12px;
  border-radius: 10px;
  color: var(--text);
  font-size: 15px;
  line-height: 1.3;
  text-decoration: none;
  white-space: nowrap;
}
.nav-menu__item:hover { background: var(--bg-muted); color: var(--text); }
.nav-menu__item[aria-current="page"] {
  background: var(--brand-soft);
  color: var(--brand-strong);
  font-weight: 750;
}
.nav-menu__item:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
/* 面板里的「设置」是按钮不是链接（点击开弹窗，不跳页）。外观必须和旁边的链接完全一致，
 * 否则同一列里会冒出一个「长得像按钮」的怪项。 */
.nav-menu__item--btn {
  width: 100%;
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 15px;
  text-align: left;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

/* 旧的「学科胶囊」样式已随下拉改版退役（面板项改用 .subj-opt，样式在 subjects.js 内）。
 * 保留这段注释是为了让后来者知道：曾经有一版平铺胶囊，别照着旧样式往回改。 */
.nav-link.subject-link {
  color: var(--muted);
  border: 0;
  background: transparent;
  padding: 0 14px;
}
.nav-link.subject-link:hover { background: transparent; color: var(--text); }
.nav-link.subject-link.on {
  background: var(--brand);
  color: var(--on-brand);
  font-weight: 750;
}
.nav-link.subject-link.on:hover { background: var(--brand); color: var(--on-brand); }
.nav-link.resource-search-btn {
  gap: 6px;
  border: 1px solid var(--brand);
  background: transparent;
  color: var(--brand-strong);
  margin-left: 6px;
  text-decoration: none;
}
.nav-link.resource-search-btn:hover { background: var(--brand-soft); color: var(--brand-strong); }
.resource-search-ico { width: 14px; height: 14px; flex: none; }
.resource-search-btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
@media (max-width: 720px) {
  .nav-link.resource-search-btn { margin-left: 0; padding: 0 9px; min-height: 36px; }
  .resource-search-ico { display: none; }
  .site-header { padding: 10px 14px 8px; gap: 4px 12px; }
  .brand { gap: 10px; min-height: 44px; }
  .logo { width: 34px; height: 34px; }
  .brand-name { font-size: 1.02rem; }
  .brand-kicker { font-size: 0.72rem; letter-spacing: 0.06em; }
  /* 2026-11-01：顶栏只剩一个入口，窄屏不再需要「导航独占一行」。
   * 旧写法 flex:1 1 100% 会把「登录」挤到品牌下面单独一行（390 实测：品牌一行、
   * 一枚胶囊孤零零挂在第二行），既费高度又难看。现在贴右、与品牌同行。 */
  .site-nav { flex: 0 0 auto; margin-left: auto; justify-content: flex-end; gap: 4px 8px; }
  .nav-link { padding: 0 8px; font-size: 0.9rem; }
  .nav-link.subject-link { padding: 0 12px; }
  /* 窄屏：导航独占一行且**右对齐**（2026-11-01 修正）。
   * 旧写法 justify-content:space-between —— 当这一行只剩一个入口时，
   * 唯一子元素被推到最左，而面板是 right:0 ⇒ 面板从按钮右缘往左伸 240px，
   * 375/390 实测整块跑出屏幕左侧（只看到「管理账号」和半列学科）。
   * 现在：入口贴右 + 面板 right:0 + 宽度按视口收敛，四种宽度都不出界。 */
  .nav-menu__panel {
    left: auto;
    right: 0;
    min-width: 0;
    width: min(320px, calc(100vw - 24px));
  }
}

/* 页脚：只用共享组件，本站不再自造
 * ---------------------------------------------------------------------------
 * 依据「项目共享看板 · UI 设计体系 V2.1.1 与全局组件」§59/§71：
 *   ⛔ 禁止自造页脚，全站统一页脚只允许引 footer.js 单一真源；
 *   ⛔ 宿主页面不得保留自有 <footer>。
 * 2026-10-30 老牛令：本页页脚换成看板里的最新组件 ⇒
 *   已删除自制的 .qk-note 产品信息条与旧 .site-footer 样式，页脚全部由
 *   /policies/assets/footer.js（v4.6-20261030）渲染，本仓只保留文案级覆盖
 *   （见 assets/footer-overrides.js：品牌行 + 合规声明弹窗）。
 * ⚠️ 不要再往这里加页脚样式，改页脚请改共享组件（须报批）。
 * 线上访问地址（老牛 2026-10-25 令：地址须在代码项目中注明）：https://dxb.mahong.tech/
 */

/* 「添加到桌面」入口由 pwa.js 注入共享页脚的链接行（原先挂在自造页脚里）。
   pwa.css 的 .pwa-footer-link 用的是本站品牌色，放进共享页脚会跟旁边
   「合规声明 / 联系我们」不同色 ⇒ 这里按组件链接的色值对齐（#mh-footer 提高优先级）。 */
#mh-footer .pwa-footer-link {
  color: #8A939F;
  font-size: 12px;
  line-height: 1.8;
  min-height: 0;
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
}
#mh-footer .pwa-footer-link:hover {
  color: #0C6BA0;
  text-decoration: underline;
  background: none;
}

button, .btn {
  font: inherit;
  font-weight: 650;
  min-height: 44px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-elev);
  color: var(--text);
  cursor: pointer;
}
button:hover, .btn:hover { background: var(--bg-muted); }
button.primary, .btn-primary {
  background: var(--brand);
  border-color: transparent;
  color: var(--on-brand);
}
button.primary:hover, .btn-primary:hover { filter: brightness(1.06); background: var(--brand); }

/* 题目图示：只用 currentColor，浅色和深色都看得见。宽度跟着容器走，不写死像素。 */
.q-figure { color: inherit; max-width: 100%; min-width: 0; margin: 8px 0 2px; }
.q-figure svg { width: 100%; max-width: 440px; height: auto; display: block; overflow: visible; }
.choices.fig-icons, .sample-choices.fig-icons {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr));
}
.choices.fig-icons .q-figure svg, .sample-choices.fig-icons .q-figure svg { max-width: 100%; }
button.choice.fig-choice {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  min-width: 0;
}
.sample-choices { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.sample-choice {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-elev);
  color: var(--text);
  padding: 8px 10px;
  min-width: 0;
}
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-decoration: none;
  text-align: center;
}
.btn-lg { min-height: 48px; padding: 10px 18px; font-size: 1rem; }
/* 禁用态要看得出来（设置里没档案时「导出备份」是禁用） */
.btn:disabled, .btn[disabled] { opacity: 0.45; cursor: not-allowed; }
.btn-block { width: 100%; }

input[type="search"], input[type="text"], input[type="number"], select, textarea {
  font: inherit;
  color: var(--text);
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px 12px;
  min-height: 44px;
  max-width: 100%;
}
textarea { min-height: 96px; }
.search-lg { width: 100%; font-size: 1.08rem; min-height: 52px; }

.stage-tabs { display: flex; flex-wrap: wrap; gap: 8px; }
.stage-tab { border-radius: 999px; }
.stage-tab.on, .stage-tab[aria-selected="true"] {
  background: var(--brand);
  color: var(--on-brand);
  border-color: transparent;
}

.badge {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 0 8px;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 800;
  white-space: nowrap;
}
.badge.hard { background: var(--hard-bg); color: var(--hard-fg); }
.badge.soft { background: var(--soft-bg); color: var(--soft-fg); }

/* 首页 */
.home { width: min(1040px, 100%); margin: 0 auto; padding: 20px 16px 48px; }
.hero {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 28px 24px 22px;
  box-shadow: var(--shadow);
}
.eyebrow {
  margin: 0 0 10px;
  color: var(--brand-strong);
  font-weight: 700;
  font-size: 0.92rem;
  letter-spacing: 0.04em;
}
.hero h1 {
  margin: 0 0 10px;
  font-size: clamp(1.85rem, 4.4vw, 2.7rem);
  line-height: 1.18;
  letter-spacing: -0.03em;
  font-weight: 750;
}
.lede { margin: 0 0 18px; font-size: 1.05rem; max-width: 38em; color: var(--muted); }
.hero-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.hero-actions .btn { flex: 1 1 180px; }
.quiet-link { margin: 14px 0 0; }
.quiet-link a { color: var(--brand-strong); font-weight: 650; text-underline-offset: 3px; }
/* 首屏的一句话交代：不用注册、数据只在本机、换设备可导出。
 * 家长的疑问（“这东西要不要注册？我孩子的东西存哪儿？”）应该在点“开始诊断”之前就有答案。 */
.hero-note { margin: 12px 0 0; font-size: 0.92rem; line-height: 1.65; color: var(--muted); }
.hero-note a { color: var(--brand-strong); font-weight: 650; text-underline-offset: 3px; }

.section-title { margin: 32px 0 12px; font-size: 1.15rem; letter-spacing: -0.02em; }
.steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}
.steps li {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 16px 18px;
  min-width: 0;
}
.step-no {
  display: inline-flex;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  align-items: center;
  justify-content: center;
  background: var(--brand-soft);
  color: var(--brand-strong);
  font-weight: 750;
  font-size: 0.92rem;
}
.steps h3 { margin: 10px 0 4px; font-size: 1.05rem; letter-spacing: -0.02em; }
.steps p { margin: 0; color: var(--muted); font-size: 0.95rem; }

.stat-grid, .grade-grid {
  display: grid;
  gap: 12px;
}
.stat-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grade-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.stat-card, a.grade-card, a.iq-card {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  min-width: 0;
}
.stat-card { padding: 14px 16px; }
.stat-num { font-size: 1.7rem; font-weight: 750; line-height: 1.1; letter-spacing: -0.03em; color: var(--text); }
.stat-label { color: var(--muted); font-weight: 650; font-size: 0.92rem; }
.stat-note { color: var(--muted); margin: 8px 0 0; font-size: 0.92rem; }
a.grade-card, a.iq-card {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 14px;
  min-height: 96px;
  text-decoration: none;
  color: inherit;
  border-top: 3px solid var(--node-primary);
}
a.grade-card.is-junior { border-top-color: var(--node-junior); }
a.grade-card.is-senior { border-top-color: var(--node-senior); }
a.grade-card:hover, a.iq-card:hover { border-color: var(--brand); }
a.grade-card strong, a.iq-card strong { font-size: 1.08rem; letter-spacing: -0.02em; }
a.iq-card { margin-top: 22px; gap: 4px; max-width: 100%; border-top-color: var(--brand); }
a.iq-card .iq-sub { font-weight: 650; overflow-wrap: anywhere; }
a.iq-card .iq-note { color: var(--muted); font-size: 0.82rem; font-weight: 650; overflow-wrap: anywhere; }
.grade-stage { color: var(--muted); font-size: 0.82rem; font-weight: 650; }
.grade-count { font-weight: 650; }
.load-error {
  background: var(--bad-bg);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  margin-top: 12px;
}
@media (max-width: 900px) {
  .grade-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 800px) {
  .steps { grid-template-columns: 1fr; }
  .stat-grid { grid-template-columns: 1fr 1fr; }
  .hero { padding: 22px 16px 18px; }
}

/* 账号位 = 顶栏行末唯一的那个 pill（2026-10-31 老牛令：与「首页」入口合并归一）。
 * 结构对齐主站 mhs-user：<b>登</b><span class="nm">未登录</span>
 * 它同时是两个东西：
 *   · 身份指示——访客灰 / 本机档案橙 / 已登录绿（三态见下方 data-state 规则）
 *   · 唯一入口——点开面板，上半是账号操作，下半是四项页面导航（开合在 assets/nav.js）
 * 尺寸 44px 触控目标，与 .nav-link 对齐。内层仍是 .id-chip__dot/label/count 三个 span。 */
.mhs-user {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 40px;
  padding: 0 14px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: #fff;
  color: var(--text);
  font-weight: 650;
  font-size: 0.9rem;
  line-height: 1;
  text-decoration: none;
  max-width: 12em;
}
.mhs-user:hover { border-color: var(--brand); color: var(--brand-strong); }
.mhs-user:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.id-chip__dot {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--muted);
  opacity: 0.55;
}
.id-chip__label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.id-chip__count {
  flex: none;
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 0.72rem;
  font-weight: 700;
  opacity: 0.7;
}
/* 账号位的「已登录」形态（老牛 2026-11-01 给的参考图定案）：
 *   未登录 = 白底描边胶囊，只写「登录」，没有三角；
 *   已登录 = 同一枚白底胶囊：[微信头像] 昵称 ▾。
 * ⇒ 取消 2026-10-27 那套三态底色（绿/橙/灰）。那套把「未登录」涂成橙色，
 *   在家长眼里像报错；而且三态色与学科主题色混在一起更花。现在状态差异只靠头像。 */
.mhs-user[data-state] {
  background: #fff;
  color: var(--text);
  border-color: var(--line);
}
.mhs-user[data-state="local"] .id-chip__dot { background: var(--warn); opacity: 1; }
.mhs-user[data-state="signed-in"] .id-chip__dot { background: var(--ok); opacity: 1; }
.mhs-user[data-state="guest"] .id-chip__dot { background: var(--muted); opacity: 0.55; }
.mhs-user[data-state="guest"] .id-chip__label { font-weight: 600; }

/* 缺孩子态（老牛 2026-11-04）：这枚胶囊此刻是「添加孩子」按钮，不再回答「我是谁」。
 * 用品牌色描边 + 淡底，和旁边的导航图标拉开层次，家长一眼知道下一步点这里。
 * 选择器必须带 [data-state] 双属性：上面那条 .mhs-user[data-state] 是同权重、
 * 且写在后面，单靠 [data-kid-cta] 会被它覆盖成白底（实测踩过一次）。 */
.mhs-user[data-state][data-kid-cta="1"] {
  border-color: var(--brand);
  background: #eef7f5;
  color: var(--brand-strong);
  font-weight: 700;
}
.mhs-user[data-state][data-kid-cta="1"]:hover { background: #e3f2ee; }
/* ▾：纯 CSS 三角，不用图标文件（各端字形差异大）。已登录才显示，脚本控 hidden。 */
.mhs-user__caret {
  flex: none;
  width: 0;
  height: 0;
  margin-left: 1px;
  border-left: 4.5px solid transparent;
  border-right: 4.5px solid transparent;
  border-top: 5px solid currentColor;
  opacity: 0.5;
}
.mhs-user__caret[hidden] { display: none; }

@media (max-width: 420px) {
  .mhs-user { padding: 0 10px; font-size: 0.88rem; }
}
@media print {
  .mhs-user { display: none; }
}

/* 账号位是 button，不是 a：需要抹掉浏览器默认外形，同时保留 44px 触控高度 */
.mhs-user { font: inherit; cursor: pointer; -webkit-appearance: none; appearance: none; }

/* mhs-user 的子部件：<b>登</b> / <span class="nm"> / 面板内的账号行。
 * 「登」不做图标文件，纯文字加字重，与主站写法保持一致（图标在各端渲染差异大）。
 * 面板里：上半账号行用一个实心品牌色按钮（动作），下半导航项是浅底行（跳转）——
 * 动作与跳转在视觉上必须能分开，否则家长会把「登录」当成又一个页面入口。 */
.mhs-user > b {
  flex: none;
  font-size: 0.88em;
  font-weight: 800;
  letter-spacing: 0.02em;
  opacity: 0.9;
}
.mhs-user > .nm {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 面板必须【始终右对齐】：触发器现在是顶栏最右元素，若沿用 .nav-menu__panel 的
 * left:0，面板会从按钮左边起步、往右伸 216px 直接顶出视口 —— 1280 下实测右侧被裁掉
 * 半个「登录」按钮。桌面同样要 right:0，这是合并后与旧「首页」入口的关键差别。 */
.mhs-user__panel {
  min-width: 264px;
  left: auto;
  right: 0;
}
.mhs-user__acct {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px 10px;
}
/* 账号行单行显示。试过折行（line-clamp:2）：面板宽度只够 10 个字，
 * 「小满（七年级）· 未登录」会断在「未登 / 录」，一个孤字掉到第二行更难看。
 * 定案：文案本身写短（不带年级），超长昵称用省略号收，完整的说明在按钮 title 里。 */
.mhs-user__who {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.82rem;
  line-height: 1.35;
  color: var(--muted);
}
.mhs-user__act {
  flex: none;
  min-height: 34px;
  padding: 0 12px;
  border: 1px solid var(--brand);
  border-radius: 999px;
  background: var(--brand);
  color: #fff;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 750;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.mhs-user__act:hover { background: var(--brand-strong); border-color: var(--brand-strong); }
.mhs-user__act:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.mhs-user__sep { height: 1px; margin: 0 6px 6px; background: var(--line); }

/* ---------------- 微信头像 + 面板内选科（老牛 2026-11-01 令） ----------------
 * 顶栏入口从「首页」改名为「登录」：未登录是文字，登录后换成用户自己的微信头像。
 * 头像用 <span data-acct-face><img></span>（account.js 填 src，带 no-referrer ——
 * 微信 CDN 带 referrer 会 403，表现为一直空白）。无头像的老账号退回文字，不留空框。 */
.mhs-user__face {
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--brand-soft);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.mhs-user__face[hidden] { display: none; }
.mhs-user__face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mhs-user__face--lg { width: 30px; height: 30px; }
.mhs-user[data-has-face="1"] { gap: 7px; }

/* 面板里的选科：**竖式列表**（老牛 2026-11-01 19:0x 令）。
 * 原来是横向铺 chips，在手机的小浮层里会被挤成两三列、每列长短不一，
 * 看着就是「要素漂移」；改成一行一科，左边科目名、右边「当前」，
 * 高度固定 40px，10 个科目纵向排下来也不会有任何一格错位。 */
.mhs-user__subj { padding: 2px 6px 6px; }
.subj-embed__head {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin: 0 0 6px;
  padding: 0 6px;
  font-size: 0.76rem;
  font-weight: 750;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.subj-embed__hint { font-weight: 400; opacity: 0.75; letter-spacing: 0; }
.subj-embed__list {
  display: flex;
  flex-direction: column;
  gap: 1px;
  max-height: min(56vh, 400px);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
.subj-embed__chip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  box-sizing: border-box;
  min-height: 40px;
  padding: 0 12px;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  color: var(--text);
  font-size: 0.9rem;
  font-weight: 650;
  text-decoration: none;
  text-align: left;
  white-space: nowrap;
}
.subj-embed__chip:hover { background: var(--bg-muted); color: var(--brand-strong); }
.subj-embed__chip.on {
  background: var(--brand-soft);
  border-color: transparent;
  color: var(--brand-strong);
  font-weight: 750;
}
/* 当前科右侧的标记：文字而不是对勾 —— 家长扫一眼就知道「现在用的是这科」 */
.subj-embed__chip.on::after {
  content: '当前';
  flex: none;
  font-size: 0.7rem;
  font-weight: 700;
  opacity: 0.9;
}
.subj-embed__chip:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* 未登录：选科整块置灰（老牛 2026-11-01 令）。
 * 用「可见但不可点」而不是隐藏 —— 家长得先看到「有哪些科」才知道登录值不值；
 * 点不动 + 虚线边框 + 提示「登录后按年级显示」，比直接消失更说得清。 */
.mhs-user__subj[data-locked="1"] .subj-embed__head { opacity: 0.6; }
.mhs-user__subj[data-locked="1"] .subj-embed__chip {
  opacity: 0.45;
  border: 1px dashed var(--line);
  background: transparent;
  color: var(--muted);
  cursor: not-allowed;
}
/* 锁态下当前科也一起灰掉：留着品牌绿会让人以为「这个还能点」 */
.mhs-user__subj[data-locked="1"] .subj-embed__chip.on {
  background: transparent;
  border-color: var(--line);
  border-style: dashed;
  color: var(--muted);
  font-weight: 650;
}
/* 锁态的「当前」标记也去掉：留着会让人以为这一科还能点 */
.mhs-user__subj[data-locked="1"] .subj-embed__chip.on::after { content: none; }

/* 窄屏：留到 360 以下才收昵称（375/390 的常见机型要能看到「头像 + 名字 + ▾」，
 * 选科已经从顶栏收进面板，横向空间足够） */
@media (max-width: 360px) {
  .mhs-user[data-has-face="1"] .nm { display: none; }
  .mhs-user[data-has-face="1"] { padding: 0 8px; }
  /* 缺孩子态例外：这枚胶囊是「添加孩子」按钮，文字不能被收掉 ——
   * 只剩一个头像的话，家长根本看不出这里是入口。腾地方的办法是收起头像，
   * 而不是收掉动作文字。 */
  .mhs-user[data-state][data-kid-cta="1"] .nm { display: inline; }
  .mhs-user[data-state][data-kid-cta="1"] [data-acct-face] { display: none; }
}

/* ---------------- 登录弹窗（assets/login.js） ----------------
 * 三种形态共用一张卡：桌面→扫码，微信内→静默，手机浏览器→手机号。
 * 所有尺寸都按 320px 起算，平板只是“更宽的手机”，不另开一套布局。 */
body.dxb-modal-open { overflow: hidden; }
.dxb-modal {
  position: fixed;
  inset: 0;
  z-index: 10050;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(15, 23, 42, 0.55);
}
.dxb-modal.open { display: flex; }
.dxb-modal__card {
  width: 100%;
  max-width: 360px;
  max-height: min(88vh, 660px);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(15, 23, 42, 0.28);
  padding: 16px 16px 12px;
}
.dxb-modal__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.dxb-modal__title { margin: 0; font-size: 1.06rem; letter-spacing: -0.01em; }
.dxb-modal__close {
  flex: none;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--muted);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
}
.dxb-modal__close:hover { background: var(--bg-muted); color: var(--text); }
.dxb-modal__body { margin-top: 4px; }
.dxb-modal [hidden] { display: none !important; }

.dxb-tabs {
  display: flex;
  gap: 4px;
  padding: 3px;
  margin: 2px 0 14px;
  background: var(--bg-muted);
  border-radius: 999px;
}
.dxb-tab {
  flex: 1 1 0;
  min-height: 38px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font: inherit;
  font-weight: 700;
  color: var(--muted);
  cursor: pointer;
}
.dxb-tab.on { background: #fff; color: var(--brand-strong); box-shadow: var(--shadow); }

.dxb-pane { display: flex; flex-direction: column; gap: 10px; }
.dxb-qr {
  width: 180px;
  height: 180px;
  align-self: center;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: #fff;
}
.dxb-stage { margin: 0; min-height: 22px; text-align: center; font-weight: 650; color: var(--muted); }
.dxb-hint { margin: 0; text-align: center; font-size: 0.86rem; color: var(--muted); }
.dxb-pane input {
  width: 100%;
  min-height: 46px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
}
.dxb-pane input:focus { outline: 2px solid var(--focus); outline-offset: 1px; }
.dxb-coderow { display: flex; gap: 8px; }
.dxb-coderow input { flex: 1 1 auto; min-width: 0; }
.dxb-send {
  flex: none;
  min-height: 46px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  font: inherit;
  font-weight: 650;
  color: var(--brand-strong);
  white-space: nowrap;
  cursor: pointer;
}
.dxb-send:disabled { opacity: 0.6; cursor: default; }
.dxb-go { min-height: 46px; margin: 0; }
.dxb-msg { margin: 0; min-height: 18px; font-size: 0.86rem; color: var(--muted); }
.dxb-msg.is-ok { color: var(--ok); }
.dxb-msg.is-bad { color: var(--bad); }
.dxb-cp { margin: 0; text-align: center; }
.dxb-linkbtn {
  border: 0;
  background: transparent;
  padding: 4px;
  font: inherit;
  font-size: 0.84rem;
  color: var(--brand-strong);
  text-decoration: underline;
  cursor: pointer;
}
.dxb-me { margin: 2px 0 6px; text-align: center; font-size: 1rem; font-weight: 700; }
.dxb-modal__foot {
  margin: 12px 0 0;
  text-align: center;
  font-size: 0.76rem;
  line-height: 1.55;
  color: var(--muted);
}
.dxb-modal__foot a { color: var(--brand-strong); }
/* ☑️ 授权同意行（2026-11-05 老牛令）：确认卡与弹窗底部共用；默认不勾选 */
.dxb-agree {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  text-align: left;
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--muted);
  cursor: pointer;
}
.dxb-agree input { flex: none; margin: 3px 0 0; accent-color: var(--brand); }
.dxb-agree a { color: var(--brand-strong); }
.dxb-wxconfirm .dxb-agree { margin: 12px 0 2px; }
button.dxb-go[disabled] { opacity: .5; cursor: not-allowed; }

/* ---------------- 多端适配：手机 / 平板 / 桌面 ----------------
 * 三档就够了：≤640 手机（含横屏小屏）、641–1024 平板、>1024 桌面。
 * 只调密度不换布局 —— 同一套 DOM 在三种宽度下都不出现横向滚动。 */
@media (max-width: 640px) {
  .site-header { padding: 10px 14px; }
  .site-nav { gap: 6px 10px; }
  .nav-link { padding: 0 9px; font-size: 0.95rem; }
  .mhs-user { max-width: 8.5em; }
  .dxb-modal { padding: 12px; align-items: flex-end; }
  .dxb-modal__card { max-width: none; max-height: 90vh; border-radius: 16px 16px 12px 12px; }
  .dxb-qr { width: 168px; height: 168px; }
}
@media (min-width: 641px) and (max-width: 1024px) {
  .site-header { padding: 12px 18px; }
  .mhs-user { max-width: 10em; }
}
@media (min-width: 1025px) {
  .dxb-modal__card { max-width: 380px; }
}

/* ===================================================================
   首页引导式布局（2026-10-26 老牛要求：不要一进来就给一大堆数据）
   =================================================================== */
.guide-root { margin: 0 0 8px; }

.guide-card {
  background: #fff;
  border: 1px solid var(--line, #e4eaf0);
  border-radius: 16px;
  padding: 22px 22px 20px;
  margin-bottom: 18px;
}
.guide-step {
  margin: 0 0 6px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  color: var(--brand-strong, #0f6e62);
  text-transform: uppercase;
}
.guide-title {
  margin: 0 0 10px;
  font-size: 1.45rem;
  line-height: 1.35;
  letter-spacing: -.02em;
  color: var(--text, #16233a);
}
.guide-card .lede { margin-bottom: 16px; }

/* 建档表单 */
.guide-form { padding: 0; margin: 0; }
.guide-form label { display: block; margin: 14px 0 4px; font-weight: 700; font-size: .95rem; }
.guide-form input, .guide-form select { width: 100%; }
.guide-form .form-actions { display: flex; gap: 8px; margin-top: 16px; }
.guide-form .form-actions button { flex: 1 1 0; }
.guide-form .err { margin: 10px 0 0; }

/* 报告摘要 */
.guide-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.guide-weak {
  list-style: none;
  margin: 6px 0 16px;
  padding: 0;
}
.guide-weak li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 0;
  border-bottom: 1px solid var(--line, #eef2f6);
}
.guide-weak li:last-child { border-bottom: none; }
.guide-weak-name { font-size: .95rem; color: var(--text, #16233a); }
.guide-weak-rate { font-size: .9rem; font-weight: 700; color: #b91c1c; }

/* ===================================================================
   首页 · 项目介绍与使用指南（2026-10-31 老牛要求）
   全部沿用本站令牌：--radius / --line / --brand / --brand-soft / --muted
   =================================================================== */
.home-about { margin-top: 4px; }

.about-points {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
}
.about-points li {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
  padding: 14px 14px 12px;
}
.about-points__ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  margin-bottom: 10px;
  border-radius: 10px;
  background: var(--brand-soft);
  color: var(--brand-strong);
}
.about-points__ico svg { width: 19px; height: 19px; display: block; }
.about-points strong { display: block; margin-bottom: 4px; font-size: .98rem; color: var(--text); }
.about-points p { margin: 0; color: var(--muted); font-size: .9rem; line-height: 1.65; }

.about-steps { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 14px; }
.about-steps li { display: flex; align-items: flex-start; gap: 12px; }
.about-steps__no {
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--brand);
  color: var(--on-brand);
  font-size: 13px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.about-steps h3 { margin: 0 0 3px; font-size: .98rem; letter-spacing: -.01em; color: var(--text); }
.about-steps p { margin: 0; color: var(--muted); font-size: .9rem; line-height: 1.65; }

.about-note {
  margin: 14px 0 0;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--brand-soft);
  color: var(--brand-strong);
  font-size: .9rem;
  line-height: 1.65;
}

/* 常见问题：折叠符号与学科下拉同一套语言（+/−） */
.about-faq { margin-top: 12px; }
.about-faq details { border-top: 1px solid var(--line); padding: 11px 0 2px; }
.about-faq details:first-of-type { border-top: 0; }
.about-faq summary {
  position: relative;
  padding-right: 24px;
  cursor: pointer;
  font-weight: 700;
  font-size: .95rem;
  color: var(--text);
  list-style: none;
}
.about-faq summary::-webkit-details-marker { display: none; }
.about-faq summary::after {
  content: '+';
  position: absolute;
  right: 4px;
  top: 0;
  color: var(--muted);
  font-weight: 700;
}
.about-faq details[open] summary::after { content: '\2212'; }
.about-faq summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: 4px; }
.about-faq p { margin: 8px 0 6px; color: var(--muted); font-size: .9rem; line-height: 1.7; }
.about-faq strong { color: var(--text); }

@media (max-width: 640px) {
  .about-points { grid-template-columns: 1fr; }
  .about-steps { gap: 12px; }
  .about-steps h3 { font-size: .95rem; }
}

/* 折叠区：图谱规模与年级入口收进「想自己找时再看」 */
.guide-secondary { margin-top: 4px; }
.guide-details {
  background: #fff;
  border: 1px solid var(--line, #e4eaf0);
  border-radius: 14px;
  padding: 12px 16px;
  margin-bottom: 12px;
}
.guide-details > summary {
  cursor: pointer;
  font-size: .95rem;
  font-weight: 650;
  color: var(--brand-strong, #0f6e62);
  list-style: none;
}
.guide-details > summary::-webkit-details-marker { display: none; }
.guide-details > summary::before {
  content: '＋';
  display: inline-block;
  width: 1.1em;
  font-weight: 700;
  color: var(--muted, #6b7c93);
}
.guide-details[open] > summary::before { content: '－'; }
.guide-details > summary:hover { text-decoration: underline; }
.guide-details .stat-grid { margin-top: 14px; }
.guide-details .grade-grid { margin-top: 14px; }

@media (max-width: 560px) {
  .guide-card { padding: 18px 16px 16px; }
  .guide-title { font-size: 1.25rem; }
  .guide-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ===================================================================
   设置弹窗（assets/settings.js）——老牛 2026-11-01 令：「档案」并入「设置」
   ===================================================================
 * 一个弹窗（2026-11-02 重构）：顶部常驻身份条 + 「孩子档案 / 备份与换设备」两个 tab。
 * 为什么合：原来改个年级得从诊断页跳到「档案页」，改完再跳回来，中途上下
 * 文全断；而且导航里「档案」这两个字家长也不一定知道是「孩子档案」。
 * 为什么再分 tab：三块纵向堆在手机上要滚好几屏，备份区常年用不到却占着位置。
 * 复用登录弹窗的 .dxb-modal 骨架（关窗、遮罩、Esc 同一套行为），只加内容区样式。 */
.dxb-settings .dxb-modal__card { max-width: 440px; }

/* 身份条：头像 + 昵称/状态 + （未登录时的）登录按钮。
 * 已登录不放退出登录 —— 退出只留顶栏头像下拉一个入口（2026-11-02 令）。 */
.set-id {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 2px 12px;
  border-bottom: 1px solid var(--line);
}
.set-id__who { flex: 1 1 auto; min-width: 0; }
.set-id__name {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 750;
  font-size: 0.98rem;
}
.set-id__hint { margin: 2px 0 0; font-size: 0.76rem; line-height: 1.45; }

/* Tab 栏：两个按钮，选中态用品牌色下划线 + 加粗，不用大色块（别抢内容） */
.set-tabs { display: flex; gap: 4px; padding: 8px 0 0; border-bottom: 1px solid var(--line); }
.set-tab {
  position: relative;
  flex: 1 1 0;
  min-height: 40px;
  padding: 0 8px;
  border: 0;
  border-radius: 10px 10px 0 0;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 650;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.set-tab:hover { background: var(--bg-muted); color: var(--text); }
.set-tab.is-on { color: var(--brand-strong, #0f5b50); font-weight: 800; }
.set-tab.is-on::after {
  content: "";
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: -1px;
  height: 2px;
  border-radius: 2px;
  background: var(--brand);
}
.set-tab:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
.set-pane { padding-top: 4px; }

.set-block {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 0;
  border-top: 1px solid var(--line);
}
.set-block:first-child { border-top: 0; padding-top: 2px; }
.set-block__title {
  margin: 0;
  font-size: 0.8rem;
  font-weight: 750;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.set-kids { display: flex; flex-direction: column; gap: 8px; }
.set-kid {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-elev);
}
.set-kid__main { flex: 1 1 auto; min-width: 0; }
.set-kid__name { display: block; font-weight: 700; font-size: 0.94rem; }
.set-kid__meta { display: block; font-size: 0.76rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.set-kid__badge {
  flex: none;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--brand-soft);
  color: var(--brand-strong);
  font-size: 0.72rem;
  font-weight: 750;
}
.set-kid__act {
  flex: none;
  min-height: 32px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #fff;
  font: inherit;
  font-size: 0.78rem;
  color: var(--text);
  cursor: pointer;
}
.set-kid__act:hover { border-color: var(--brand); color: var(--brand-strong); }
.set-kid__act--danger:hover { border-color: var(--bad); color: var(--bad); }
.set-empty { margin: 0; font-size: 0.86rem; color: var(--muted); }

.set-form { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.set-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.78rem;
  color: var(--muted);
}
.set-field--full { grid-column: 1 / -1; }
.set-form input, .set-form select {
  width: 100%;
  min-height: 40px;
  padding: 0 10px;
  font: inherit;
  font-size: 0.92rem;
}
.set-form__row { grid-column: 1 / -1; display: flex; gap: 8px; }
.set-form__row .btn, .set-form__row button { flex: 1 1 0; min-height: 42px; }
.set-err { grid-column: 1 / -1; margin: 0; font-size: 0.82rem; color: var(--bad); }

/* 高考选科（2026-11-02 老牛令：海南 3+3 MVP）——档案表单里高中段才出现的六选三块 */
.set-elect__title { font-weight: 750; color: var(--text); }
.set-elect__chips { display: flex; flex-wrap: wrap; gap: 6px; }
.set-elect__chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg-elev, #fff);
  color: var(--text);
  font-size: 0.88rem;
  font-weight: 600;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
}
.set-elect__chip:has(input:checked) { border-color: var(--brand); background: var(--brand-soft, #e6f2ef); color: var(--brand-strong, #0f5b50); }
.set-elect__chip input { width: auto; min-height: 0; margin: 0; accent-color: var(--brand, #0f766e); }
.set-elect__chip:focus-within { outline: 2px solid var(--focus); outline-offset: 2px; }
.set-elect .set-note { margin-top: 2px; }

.set-note { margin: 0; font-size: 0.8rem; line-height: 1.55; color: var(--muted); }
.set-row { display: flex; gap: 8px; flex-wrap: wrap; }
.set-row .btn { flex: 1 1 0; min-height: 40px; font-size: 0.88rem; }
.set-status { margin: 0; font-size: 0.8rem; line-height: 1.5; color: var(--muted); }
.set-status.is-bad { color: var(--bad); }
.set-status.is-ok { color: var(--ok); }
.set-foot {
  margin: 8px 0 0;
  text-align: center;
  font-size: 0.74rem;
  line-height: 1.55;
  color: var(--muted);
}
.set-foot a { color: var(--brand-strong); }
@media (max-width: 420px) {
  .set-form { grid-template-columns: 1fr; }
}

/* ===================================================================
   诊断前置校验（assets/gate.js）
   ===================================================================
 * 点「诊断」时先看登录态和孩子档案：缺哪个就补哪个，补完自动续跳诊断。
 * 视觉沿用登录弹窗，只有正文用列表，读起来比一坨段落清楚。 */
.gate-lines {
  margin: 0;
  padding-left: 18px;
  font-size: 0.86rem;
  line-height: 1.7;
  color: var(--muted);
}
.gate-esc {
  align-self: center;
  border: 0;
  background: transparent;
  padding: 6px 4px;
  font: inherit;
  font-size: 0.82rem;
  color: var(--muted);
  text-decoration: underline;
  cursor: pointer;
}
.gate-esc:hover { color: var(--text); }

/* 微信内登录确认卡（assets/login.js · 2026-11-04 老牛令：不许静默登录）。
 * 卡片里是「竖排两条按钮」：主按钮整宽，「先不登录」另起一行居中。
 * 不加这段的话两颗按钮会挤在同一行、右侧那颗被卡片的 overflow 裁掉一半（实测过）。 */
.dxb-wxconfirm .gate-lines { margin: 10px 0 0; padding-left: 18px; }
.dxb-wxconfirm .dxb-go { display: block; width: 100%; margin: 14px 0 0; }
.dxb-wxconfirm .gate-esc { display: block; width: 100%; margin: 6px 0 0; text-align: center; }

/* ============================================================================
   QK12 · 顶栏图标导航（老牛 2026-11-01 令）
   ----------------------------------------------------------------------------
   首页概览 / 选科 / 知识图谱 / 诊断 / 用户切换 五项，从「登录」面板里搬出来，
   改成顶栏一排图标按钮；文字只做悬停提示（.nav-ico__tip）。

   图标全部取自 tabler-icons（MIT），按「图文同义」挑，改图标前先看对应关系：
     home        → 首页概览      list-check  → 选科（从科目清单里勾选）
     binary-tree → 知识图谱(树状层级)  stethoscope → 诊断
     users       → 用户切换(多孩) user-circle → 个人中心（账号面板内）
   ⛔ 不要换成图标字体或 sprite：图标直接内联在 HTML 里，样式表/脚本旧了照常显示，
      也不会出现「字体没下到 → 全是方框」这类事故。
   ============================================================================ */
.nav-icons { gap: 2px; }
.nav-ico {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  text-decoration: none;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.nav-ico:hover { background: var(--bg-muted); color: var(--brand-strong); }
.nav-ico:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
/* 当前所在页：浅品牌底 + 品牌色，和原来的 .nav-link[aria-current] 保持同一套视觉语言 */
.nav-ico[aria-current="page"] { background: var(--brand-soft); color: var(--brand-strong); }
.nav-ico__svg { width: 22px; height: 22px; display: block; }

/* 悬停提示：纯 CSS，不依赖 title（title 在触屏永远不出现，且与自绘提示会叠成两个框） */
.nav-ico__tip {
  position: absolute;
  top: calc(100% + 7px);
  left: 50%;
  z-index: 95;
  padding: 4px 9px;
  border-radius: 7px;
  background: rgba(23, 25, 31, 0.92);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, -4px);
  transition: opacity 0.14s ease, transform 0.14s ease, visibility 0.14s;
  pointer-events: none;
}
.nav-ico:hover .nav-ico__tip,
.nav-ico:focus-visible .nav-ico__tip {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
}
/* 触屏没有 hover：提示常驻反而会挡住内容，直接不显示（aria-label 仍给读屏） */
@media (hover: none) {
  .nav-ico__tip { display: none; }
}
@media print {
  .nav-ico { display: none; }
}

/* 图标按钮弹层（选科 / 用户切换）：都挂在顶栏右侧，必须 right:0 往左展开，
 * 否则 1280 下右侧会被裁掉半块（这就是 QK9 踩过的坑）。 */
.nav-pop {
  left: auto;
  right: 0;
  width: 300px;
  min-width: 0;
  padding: 8px;
}
.nav-pop--kid { width: 268px; }
@media (max-width: 420px) {
  .nav-pop { width: min(300px, calc(100vw - 24px)); }
  .nav-pop--kid { width: min(268px, calc(100vw - 24px)); }
}

/* ⚠️ 窄屏浮层必须改成「贴视口」定位，不能再用 right:0 挂在图标上。
 * 2026-11-01 手机微信实拍事故：选科图标是顶栏第 2 枚，面板 right:0 意味着
 * 右边缘对齐图标右边缘、300px 宽度整体向左伸 ⇒ 左侧大半截跑到屏幕外（就是用户
 * 截图里那块「科学 / 一年级）」被裁掉的漂移）。浮层里还有 10 个科目，越左越糟。
 * 改法：≤760px 一律 position:fixed 贴住视口左右各 12px，top 由 nav.js 按顶栏
 * 实际底边写进 --nav-pop-top（顶栏高度会随品牌副标题显隐变化，CSS 里写死会错位）。 */
@media (max-width: 760px) {
  .nav-pop,
  /* 账号面板（个人中心）同理：老牛 2026-11-01 19:2x 反馈「手机端图标下拉均漂移」，
   * 它虽然挂在最右的登录胶囊上、right:0 通常不出右界，但 300px 宽度在 320px 小屏
   * 上仍会把左边顶出视口 —— 一律同规则贴视口，五种浮层行为完全一致。 */
  .mhs-user__panel {
    position: fixed;
    left: 12px;
    right: 12px;
    width: auto;
    top: var(--nav-pop-top, 64px);
    max-height: calc(100vh - var(--nav-pop-top, 64px) - 16px);
    max-height: calc(100dvh - var(--nav-pop-top, 64px) - 16px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }
  .nav-pop--kid { width: auto; }
}

/* ---------------- 用户切换（assets/kidswitch.js） ---------------- */
.kid-sw { display: flex; flex-direction: column; gap: 2px; }
.kid-sw__head {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 4px 10px 8px;
}
.kid-sw__title {
  font-size: 0.76rem;
  font-weight: 750;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.kid-sw__hint { font-size: 0.72rem; color: var(--muted); opacity: 0.85; }
.kid-sw__row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 7px 10px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.kid-sw__row:hover { background: var(--bg-muted); }
.kid-sw__row:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
.kid-sw__row[data-cur="1"] { background: var(--brand-soft); }
.kid-sw__row[data-cur="1"]:hover { background: var(--brand-soft); }
.kid-sw__body { min-width: 0; flex: 1 1 auto; }
.kid-sw__name {
  display: block;
  font-size: 0.9rem;
  font-weight: 700;
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kid-sw__meta {
  display: block;
  font-size: 0.73rem;
  line-height: 1.3;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kid-sw__check {
  flex: none;
  font-size: 0.72rem;
  font-weight: 750;
  color: var(--brand-strong);
}
.kid-sw__empty { padding: 6px 10px 10px; }
.kid-sw__empty p {
  margin: 0 0 8px;
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--muted);
}
.kid-sw__sep { height: 1px; margin: 6px 6px; background: var(--line); }
.kid-sw__foot {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  min-height: 38px;
  padding: 0 10px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 0.82rem;
  font-weight: 650;
  text-align: left;
  cursor: pointer;
}
.kid-sw__foot:hover { background: var(--bg-muted); color: var(--text); }

/* ---------------- 孩子头像（children.js 的 faceEl 统一产出） ----------------
 * 支持家长自己换头像：上传后在浏览器里裁圆 + 压到 240px（约 15KB）再存 localStorage，
 * 所以这里只负责显示。没换过头像就退回首字头像，不留空框。 */
.dxb-face {
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--brand-soft);
  color: var(--brand-strong);
  font-size: 0.88rem;
  font-weight: 800;
  line-height: 1;
}
.dxb-face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dxb-face--sm { width: 28px; height: 28px; font-size: 0.78rem; }
.dxb-face--lg { width: 44px; height: 44px; font-size: 1rem; }

/* 账号面板里的「个人中心」：面板项带图标，和纯文字项区分开（同一列里只有这一项） */
.nav-menu__ico { width: 17px; height: 17px; flex: none; margin-right: 9px; opacity: 0.8; }

/* 窄屏收敛：顶栏现在是「品牌 + 5 枚图标 + 登录胶囊」，一行放不下就先收文字再收字号。
 * 实测 390/375/360/320 四档都要求不出现横向滚动（QK9 的老账）。 */
@media (max-width: 720px) {
  .site-header { padding: 10px 12px; gap: 6px 10px; }
  .brand { gap: 8px; min-height: 40px; }
  .logo { width: 32px; height: 32px; border-radius: 9px; }
  .brand-kicker { display: none; }
  .brand-name { font-size: 0.98rem; }
  .nav-icons { gap: 0; }
  .nav-ico { width: 36px; height: 36px; border-radius: 11px; }
  .nav-ico__svg { width: 21px; height: 21px; }
}
@media (max-width: 560px) {
  /* 品牌只留 logo：五个图标换来的横向空间，优先保证图标与登录按钮都在第一行 */
  .brand-copy { display: none; }
  .nav-ico { width: 34px; height: 34px; }
  .nav-ico__svg { width: 20px; height: 20px; }
  .mhs-user { min-height: 34px; padding: 0 10px; font-size: 0.84rem; }
  .mhs-user__face { width: 22px; height: 22px; }
}
@media (max-width: 360px) {
  .nav-ico { width: 32px; height: 32px; border-radius: 10px; }
  .nav-ico__svg { width: 19px; height: 19px; }
  .mhs-user { padding: 0 8px; }
}

/* ============================================================================
   QK12 · 登录弹窗（复刻官网登录窗口）+ 个人中心里的头像
   ============================================================================ */

/* ---- 官网同款登录窗：左扫码 210px，右手机号/邮箱 250px，底部服务号二维码 ---- */
.dxb-modal.dxb-lg .dxb-modal__card { max-width: 600px; width: 100%; }
.dxb-lg__pane { padding: 2px 0 0; }
.dxb-lg__cols { display: flex; gap: 26px; align-items: flex-start; }
.dxb-lg__qr { flex: 1 1 auto; min-width: 220px; text-align: center; }
.dxb-lg__lead {
  margin: 0;
  font-size: 0.82rem;
  line-height: 1.7;
  color: var(--muted);
}
.dxb-lg__lead--sub { margin-top: 0; }
.dxb-lg__qrimg {
  display: block;
  width: 210px;
  height: 210px;
  max-width: 100%;
  object-fit: contain;
  margin: 14px auto 4px;
  border-radius: 8px;
  background: #fff;
  cursor: zoom-in;      /* 官网同款：点开看大图 */
  user-select: none;
  touch-action: manipulation;
}
/* 二维码图位占位块（2026-11-05 12:57 老牛反馈「登录窗不显示二维码」）：
 * 未勾选 ☑️ 时图位不能空着 —— 用同尺寸虚线块顶住位置，块里写明原因，
 * 点它即勾选同意并立刻出码，不用家长再去下面找那个小方框。 */
.dxb-lg__qrhold {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 210px;
  height: 210px;
  max-width: 100%;
  margin: 14px auto 4px;
  padding: 14px;
  border: 1.5px dashed #C9D2DE;
  border-radius: 8px;
  background: #F7F9FB;
  color: var(--muted);
  font: inherit;
  font-size: 0.82rem;
  line-height: 1.6;
  text-align: center;
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.dxb-lg__qrhold:hover,
.dxb-lg__qrhold:focus-visible {
  border-color: var(--brand);
  background: #EEF7F5;
  color: var(--brand-strong);
}
.dxb-lg__qrhold-ico { font-size: 1.5rem; line-height: 1; opacity: .5; }
.dxb-lg__qrhold-txt { display: block; }
.dxb-lg__qrhold-btn {
  margin-top: 2px;
  padding: 5px 13px;
  border-radius: 999px;
  background: var(--brand);
  color: #fff;
  font-size: 0.78rem;
  font-weight: 600;
}
/* 登录窗底部：未登录但本机已有孩子时给的「先不登录 · 切换/管理孩子信息」出口 */
.dxb-lg__switch { margin: 16px 0 0; text-align: center; }
.dxb-lg__switchbtn {
  border: 0;
  background: none;
  padding: 4px 6px;
  font: inherit;
  font-size: 0.82rem;
  color: var(--brand-strong);
  text-decoration: underline;
  cursor: pointer;
}
/* 这几个元素自带 display 声明，会盖掉 [hidden] 的 UA 样式 ⇒ 显式兜底，否则「藏」不干净 */
.dxb-lg__qrimg[hidden],
.dxb-lg__qrhold[hidden],
.dxb-lg__switch[hidden] { display: none !important; }
.dxb-lg__stage {
  margin: 4px 0 0;
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--muted);
  min-height: 18px;
}
/* QK23-20261106：登录窗左侧「手机微信外」保存/相册识别说明（微信内与桌面端不渲染节点） */
.dxb-lg__tip {
  margin: 14px 0 0;
  padding: 12px 13px;
  border: 1px solid #EFCB84;
  border-radius: 12px;
  background: #FEF8E7;
  text-align: left;
}
.dxb-lg__tip-t {
  margin: 0 0 8px;
  font-size: 0.8rem;
  line-height: 1.6;
  font-weight: 600;
  color: #7A4E11;
}
.dxb-lg__tip-l {
  margin: 0 0 6px;
  font-size: 0.78rem;
  line-height: 1.6;
  color: #7A4E11;
}
.dxb-lg__tip-l:last-child { margin-bottom: 0; }
.dxb-lg__tip-l b { font-weight: 700; margin-right: 3px; }

.dxb-lg__retry {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: 0.8rem;
  color: var(--brand-strong);
  text-decoration: underline;
  cursor: pointer;
}
.dxb-lg__svc {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
  padding: 10px;
  border: 1px solid #E2E8F0;
  border-radius: 8px;
}
.dxb-lg__svcimg {
  flex: none;
  width: 64px;
  height: 64px;
  object-fit: contain;
  border-radius: 6px;
  background: #fff;
}
.dxb-lg__svctxt {
  flex: 1 1 auto;
  font-size: 0.72rem;
  line-height: 1.65;
  color: var(--muted);
  text-align: center;
}

.dxb-lg__right { flex: none; width: 250px; text-align: left; }
.dxb-lg__h3 { margin: 0 0 12px; font-size: 16px; color: #0F172A; }
.dxb-lg__tabs {
  display: flex;
  border: 1px solid #E2E8F0;
  border-radius: 8px;
  overflow: hidden;
  margin-bottom: 10px;
  font-size: 0.8rem;
}
.dxb-lg__tab {
  flex: 1;
  text-align: center;
  padding: 8px 4px;
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
}
.dxb-lg__tab + .dxb-lg__tab { border-left: 1px solid #E2E8F0; }
.dxb-lg__tab.is-on { background: #0EA5E9; color: #fff; font-weight: 600; }
.dxb-lg__tabpane[hidden] { display: none; }
.dxb-lg__input {
  width: 100%;
  box-sizing: border-box;
  min-height: 40px;
  padding: 9px 12px;
  border: 1px solid #E2E8F0;
  border-radius: 8px;
  background: var(--bg-elev);
  color: var(--text);
  font: inherit;
  font-size: 0.88rem;
}
.dxb-lg__input:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.dxb-lg__row { display: flex; gap: 8px; margin-top: 8px; }
.dxb-lg__row .dxb-lg__input { flex: 1 1 0; min-width: 0; }
.dxb-lg__send {
  flex: none;
  white-space: nowrap;
  padding: 0 12px;
  border: 1px solid #0EA5E9;
  border-radius: 8px;
  background: #fff;
  color: #0EA5E9;
  font: inherit;
  font-size: 0.78rem;
  cursor: pointer;
}
.dxb-lg__send:disabled { opacity: 0.55; cursor: default; }
.dxb-lg__go {
  width: 100%;
  margin-top: 10px;
  padding: 9px 0;
  border: 0;
  border-radius: 8px;
  background: #0EA5E9;
  color: #fff;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.dxb-lg__go:hover { background: #0284c7; }
.dxb-lg__go:disabled { opacity: 0.6; cursor: default; }
.dxb-lg__msg { margin-top: 7px; min-height: 17px; font-size: 0.76rem; line-height: 1.5; }
.dxb-lg__msg.is-ok { color: var(--ok); }
.dxb-lg__msg.is-bad { color: var(--bad); }
.dxb-lg__mobtip { margin: 12px 0 6px; font-size: 0.76rem; line-height: 1.6; color: var(--muted); }
.dxb-lg__mobgo {
  width: 100%;
  padding: 9px 0;
  border: 1px solid var(--brand);
  border-radius: 8px;
  background: transparent;
  color: var(--brand-strong);
  font: inherit;
  font-size: 0.84rem;
  font-weight: 700;
  cursor: pointer;
}
/* 手机不再进这个弹窗（改成整页跳 login/），所以这里不再有 .dxb-lg--mob 分支。 */
@media (max-width: 640px) {
  .dxb-lg__cols { flex-direction: column; gap: 14px; }
  .dxb-lg__qr { min-width: 0; }
  .dxb-lg__right { width: 100%; }
}

/* ---- 个人中心：孩子头像（点击换图） ---- */
.set-kid__facewrap {
  flex: none;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  line-height: 0;
  cursor: pointer;
}
.set-kid__facewrap:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.set-avatar {
  display: flex;
  align-items: center;
  gap: 12px;
  grid-column: 1 / -1;
  padding: 2px 0 4px;
}
.set-avatar.is-off .set-avatar__face { opacity: 0.5; }
.set-avatar__face { flex: none; line-height: 0; }
.set-avatar__body { min-width: 0; }
.set-avatar__btns { display: flex; align-items: center; gap: 10px; }
.set-avatar__btn { min-height: 34px; padding: 0 12px; font-size: 0.82rem; }
.set-avatar__clear {
  border: 0;
  background: none;
  padding: 0 2px;
  font: inherit;
  font-size: 0.78rem;
  color: var(--muted);
  text-decoration: underline;
  cursor: pointer;
}
.set-avatar__clear:hover { color: var(--bad); }

/* 首页「静链接」里的文字按钮（跳转改成开弹窗后仍要长得像链接，别变成一颗灰按钮） */
.quiet-btn {
  border: 0;
  background: none;
  padding: 0;
  margin: 0;
  font: inherit;
  font-size: 1em;
  color: var(--brand-strong);
  font-weight: 650;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.quiet-btn:hover { color: var(--brand); }

/* ============================================================================
   QK13 · 选科竖排 / 浮层贴视口 / 登录窗对齐官网 / 面板里的退出登录
   ============================================================================ */

/* 官网同款小字「点二维码可放大」（在服务号块下面） */
.dxb-lg__svctip {
  margin: 6px 0 0;
  font-size: 11px;
  line-height: 1.5;
  color: #94A3B8;
  text-align: center;
}

/* 二维码放大层：点任意处关闭。独立于登录弹窗（z-index 更高），
 * 这样桌面扫码时点图放大不会被弹窗的遮罩压在下面。 */
.dxb-qrzoom {
  position: fixed;
  inset: 0;
  z-index: 10080;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 24px;
  background: rgba(12, 16, 20, 0.78);
  cursor: zoom-out;
}
.dxb-qrzoom.open { display: flex; }
.dxb-qrzoom__img {
  width: min(78vw, 420px);
  height: auto;
  background: #fff;
  border-radius: 10px;
  padding: 8px;
}
.dxb-qrzoom__cap {
  margin: 0;
  font-size: 0.8rem;
  color: #e7edf2;
  text-align: center;
}

/* 头像下拉里唯一的一项「退出登录」（老牛 2026-11-02 令：从弹窗里挪进下拉列表内，
 * 元素沿用 mhs-user__act 这个 class 名）。
 * 2026-11-02 晚：面板里的「个人中心」入口删掉（与「用户切换 → 管理孩子档案」重复），
 * 于是这一项顶上要自带一条分隔线 —— 用 inset 阴影而不是 border-top，
 * 因为 hover 会把 border-color 刷成红色，上边线跟着变红就脏了。
 * 它必须长得像一条菜单项、而不是那颗绿色胶囊按钮：整行、透明底 + 次要文字色，
 * hover 才转红 —— 退出是不可逆动作，不能比面板里的身份条还显眼。 */
.mhs-user__panel .mhs-user__act[data-acct-logout] {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 40px;
  margin: 6px 0 0;
  padding: 0 12px;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  box-shadow: inset 0 1px 0 var(--line);
  color: var(--muted);
  font: inherit;
  font-size: 0.88rem;
  font-weight: 650;
  text-align: left;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.mhs-user__panel .mhs-user__act[data-acct-logout]:hover {
  background: var(--bad-bg, rgba(220, 38, 38, 0.08));
  border-color: var(--bad, #dc2626);
  color: var(--bad, #dc2626);
}
.mhs-user__panel .mhs-user__act[data-acct-logout]:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
.mhs-user__panel .mhs-user__act[data-acct-logout][hidden] { display: none; }

/* QK25-20261106：面板首项「＋ 添加孩子」—— 已登录但本机还没有孩子时的唯一主行动。
 * 原来这一态点胶囊直接奔建档、面板打不开，「退出登录」被埋死（老牛 02:0x 反馈）。
 * 现在面板照常展开，第一项长成一颗绿色描边按钮，退出仍在最下面一条分隔线之后。 */
.mhs-user__panel .mhs-user__act[data-acct-addkid] {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 40px;
  margin: 2px 0 8px;
  padding: 0 12px;
  border: 1px solid var(--brand, #0f6e62);
  border-radius: 10px;
  background: var(--brand-wash, rgba(15, 110, 98, 0.08));
  color: var(--brand-strong, #0f6e62);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 700;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.mhs-user__panel .mhs-user__act[data-acct-addkid]:hover { background: var(--brand-weak, rgba(15, 110, 98, 0.14)); }
.mhs-user__panel .mhs-user__act[data-acct-addkid]:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
.mhs-user__panel .mhs-user__act[data-acct-addkid][hidden] { display: none; }

/* ============================================================================
   QK13 · 右下角「登录」浮钮（与官网 dudu 客服球同一竖列）
   ----------------------------------------------------------------------------
   客服球是官网同一份 mhcs-widget.js（56px、bottom/right 24px、手机 16px），
   这里只补一枚登录钮：尺寸/圆角/阴影与球保持一致，位置 = 球正上方 12px。
   ⛔ 不要改球的定位参数 —— 它对不上会两个控件叠在一起。
   ============================================================================ */
.dxb-dock__btn {
  position: fixed;
  right: 24px;
  bottom: calc(24px + 56px + 12px);
  z-index: 2147483000;      /* 与 .mhcs-fab 同层；面板打开时本按钮隐藏 */
  display: flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--bg-elev, #fff);
  color: var(--brand-strong);
  box-shadow: 0 6px 18px rgba(23, 25, 31, 0.14);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  overflow: hidden;
  transition: transform 0.16s ease, box-shadow 0.16s ease;
}
.dxb-dock__btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 10px 24px rgba(23, 25, 31, 0.2);
}
.dxb-dock__btn:focus-visible { outline: 2px solid #0EA5E9; outline-offset: 3px; }
.dxb-dock__ico { display: flex; width: 26px; height: 26px; }
.dxb-dock__ico svg { width: 100%; height: 100%; }
.dxb-dock__face {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* 已登录：给一圈品牌色描边，和「登录」态区分 */
.dxb-dock__btn[data-state="signed-in"] { border-color: var(--brand); }

/* 客服面板展开时让位（面板 bottom:96px 正好压在这里） */
body.dxb-cs-open .dxb-dock__btn { display: none; }

@media (max-width: 640px) {
  .dxb-dock__btn {
    right: 16px;
    bottom: calc(16px + 56px + 12px + env(safe-area-inset-bottom, 0px));
  }
}
@media print {
  .dxb-dock__btn { display: none; }
}
