/* 学考练系统 · 学生端样式
   基调：反焦虑。不加排名、不加百分比、不加进度条压力。
   平板适配：竖屏优先，最小可点区域 44×44px，公式超宽允许横向滚动。
   亮色主题（跟随 IDE 主题 = light）。 */

:root{
  --bg:#f6f7f9;
  --card:#ffffff;
  --ink:#1f2328;
  --ink-2:#5b6472;
  --ink-3:#8b94a3;
  --line:#e6e9ee;
  --brand:#2f6bff;
  --brand-soft:#eef3ff;
  --ok:#12924f;
  --ok-soft:#e8f7ef;
  --warn:#b26a00;
  --warn-soft:#fff5e6;
  --bad:#c8342b;
  --bad-soft:#fdecea;
  --radius:14px;
  --radius-sm:10px;
  --shadow:0 1px 2px rgba(16,24,40,.04), 0 6px 20px rgba(16,24,40,.06);
  --tap:48px;
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0}
body{
  background:var(--bg); color:var(--ink);
  font:16px/1.7 -apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  -webkit-font-smoothing:antialiased;
}
#app{max-width:760px;margin:0 auto;padding:0 16px 96px;min-height:100vh}

/* ---------- 顶栏 ---------- */
.topbar{
  position:sticky;top:0;z-index:20;margin:0 -16px 8px;padding:12px 16px 10px;
  background:rgba(246,247,249,.92);backdrop-filter:blur(8px);border-bottom:1px solid var(--line);
}
.topbar h1{margin:0;font-size:17px;font-weight:650;letter-spacing:.2px}
.topbar .sub{margin-top:2px;font-size:13px;color:var(--ink-3)}
.topbar .right{position:absolute;right:16px;top:14px;font-size:13px;color:var(--ink-3)}

/* ---------- 卡片 ---------- */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:16px;margin:12px 0;box-shadow:var(--shadow)}
.card.tight{padding:12px 14px}
.card h2{margin:0 0 8px;font-size:15px;font-weight:650;color:var(--ink-2)}
.card p{margin:8px 0}
.muted{color:var(--ink-3);font-size:13.5px}
.hr{height:1px;background:var(--line);margin:14px -16px}

/* ---------- 待办入口 ---------- */
.todo{
  display:flex;align-items:center;gap:12px;width:100%;text-align:left;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:14px 16px;margin:10px 0;min-height:var(--tap);cursor:pointer;
  box-shadow:var(--shadow);transition:transform .06s ease,border-color .15s ease;
  font-size:15px;color:inherit;font-family:inherit;
}
.todo:active{transform:scale(.995)}
.todo:hover{border-color:#d5dae3}
.todo .num{
  flex:0 0 30px;height:30px;border-radius:50%;background:var(--brand-soft);color:var(--brand);
  font-size:14px;font-weight:650;display:flex;align-items:center;justify-content:center;
}
.todo .body{flex:1;min-width:0}
/* ⚠️ 必须 display:block（2026-10-02 修）：.t/.s 是 span（inline），不块级化的话
   margin-top 不生效、标题和副标题挤同一行 —— 首页第一条待办就撞上
   「约 38 分钟跟学校进度同步的复习」连成一句。真机截图实锤。 */
.todo .t{display:block;font-weight:600;line-height:1.45}
.todo .s{display:block;font-size:13px;color:var(--ink-3);margin-top:2px}
.todo .go{color:var(--ink-3);font-size:20px;line-height:1}

/* ---------- 按钮 ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  min-height:var(--tap);padding:0 20px;border-radius:12px;border:1px solid var(--line);
  background:#fff;color:var(--ink);font:inherit;font-weight:600;cursor:pointer;
  transition:filter .12s ease,opacity .12s ease;
}
.btn:active{filter:brightness(.96)}
.btn.primary{background:var(--brand);border-color:var(--brand);color:#fff}
.btn.ghost{background:transparent;border-color:transparent;color:var(--brand);padding:0 10px;min-height:40px}
.btn.block{width:100%}
.btn[disabled]{opacity:.45;cursor:not-allowed}
.btn-row{display:flex;gap:10px;margin-top:14px;flex-wrap:wrap}
.btn-row .btn{flex:1}

/* ---------- 做题 ---------- */
.progress-line{font-size:13px;color:var(--ink-3);text-align:center;margin:2px 0 14px;letter-spacing:.5px}
.stem{font-size:19px;line-height:1.9;margin:4px 0 18px}
.stem .katex{font-size:1.06em}
.formula-scroll{overflow-x:auto;overflow-y:hidden;max-width:100%}
/* 2026-10-04：题目配图（内联 SVG）。居中、限宽、不拉伸变形。 */
.fig{margin:-6px 0 16px;text-align:center}
.fig svg{max-width:100%;height:auto}

.field{margin:14px 0}
.field .label{font-size:14px;color:var(--ink-2);margin-bottom:6px}
.field .label .katex{font-size:1em}
.input{
  width:100%;min-height:56px;padding:12px 14px;font-size:20px;font-family:inherit;
  border:1.5px solid var(--line);border-radius:12px;background:#fff;color:var(--ink);
  outline:none;transition:border-color .15s ease,box-shadow .15s ease;
}
.input:focus{border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-soft)}
.input.ok{border-color:var(--ok);background:var(--ok-soft)}
.input.bad{border-color:var(--bad);background:var(--bad-soft)}

/* ---------- 符号键盘 ---------- */
.sympad{margin-top:8px;display:grid;grid-template-columns:repeat(6,1fr);gap:8px}
.sympad .skey{min-height:44px;padding:0;font-size:18px;font-weight:600;border-radius:10px}
.sympad .skey-del{color:var(--ink-3);font-size:14px}

.opts{display:flex;flex-direction:column;gap:10px}
.opt{
  min-height:var(--tap);padding:12px 16px;border:1.5px solid var(--line);border-radius:12px;
  background:#fff;font:inherit;font-size:16px;text-align:left;cursor:pointer;
}
.opt.sel{border-color:var(--brand);background:var(--brand-soft);font-weight:600;color:var(--brand)}

/* 反馈条 */
.feedback{
  margin-top:14px;padding:12px 14px;border-radius:12px;font-size:15px;
  display:flex;align-items:center;gap:8px;min-height:48px;
}
.feedback.ok{background:var(--ok-soft);color:var(--ok)}
.feedback.mid{background:#f1f3f6;color:var(--ink-2)}

/* ---------- 结论页 ---------- */
.hero{background:linear-gradient(180deg,#f2f6ff,#fff);border:1px solid var(--line);border-radius:var(--radius);padding:18px;box-shadow:var(--shadow)}
.hero .headline{font-size:17px;font-weight:650;line-height:1.7}
.hero .block{font-size:15px;color:var(--ink-2);margin:8px 0;white-space:pre-wrap}

.step{
  border:1px solid var(--line);border-radius:var(--radius);padding:14px;margin:10px 0;background:#fff;
  box-shadow:var(--shadow);
}
.step .st-head{display:flex;align-items:center;gap:10px}
.step .st-idx{
  flex:0 0 26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  font-size:13px;font-weight:700;background:var(--bad-soft);color:var(--bad);
}
.step.partial .st-idx{background:var(--warn-soft);color:var(--warn)}
.step .st-name{font-weight:650;flex:1}
.step .st-eta{font-size:13px;color:var(--ink-3)}
.step .st-why{margin-top:8px;font-size:14px;color:var(--ink-2);line-height:1.75}
.step .btn{margin-top:12px}

table.pl{width:100%;border-collapse:collapse;font-size:14px}
table.pl th,table.pl td{padding:9px 8px;border-bottom:1px solid var(--line);text-align:left;vertical-align:top}
table.pl th{color:var(--ink-3);font-weight:600;font-size:13px}
.v-pass{color:var(--ok)}
.v-partial{color:var(--warn)}
.v-hole{color:var(--bad)}

details{border:1px solid var(--line);border-radius:var(--radius-sm);padding:10px 14px;margin:10px 0;background:#fff}
details>summary{cursor:pointer;font-size:14px;color:var(--ink-2);font-weight:600;min-height:32px;display:flex;align-items:center}
details[open]>summary{margin-bottom:8px}

.review-item{padding:10px 0;border-bottom:1px dashed var(--line)}
.review-item:last-child{border-bottom:0}
.review-item .q{font-size:15px}
.review-item .mine{font-size:13.5px;margin-top:4px}
.review-item .mine .tag-ok{color:var(--ok)}
.review-item .mine .tag-bad{color:var(--bad)}
.review-item .ans{font-size:14px;margin-top:4px;color:var(--ink-2)}
.review-item .cause{font-size:13.5px;margin-top:6px;padding:8px 10px;background:var(--bad-soft);border-radius:8px;color:#7d2b25}

/* ---------- 讲解卡 ---------- */
.teach h3{font-size:16px;margin:16px 0 6px}
.teach .body{font-size:15.5px;line-height:1.85;color:var(--ink)}
.teach ul{margin:8px 0;padding-left:22px}
.teach li{margin:5px 0}
.teach .ex{background:var(--brand-soft);border-radius:var(--radius-sm);padding:12px 14px;margin:12px 0}
.teach .ex .step{font-size:15px;margin:6px 0;padding:0;border:0;box-shadow:none;background:none}
.teach .pit{background:var(--warn-soft);border-radius:var(--radius-sm);padding:12px 14px;margin:12px 0}

/* ---------- 掌握地图 ---------- */
.mrow{display:flex;align-items:center;gap:10px;padding:12px 4px;border-bottom:1px solid var(--line)}
.mrow:last-child{border-bottom:0}
.dot{flex:0 0 10px;height:10px;border-radius:50%;background:#cfd6df}
/* ---- U8 掌握地图热力档位（2026-10-13）----
   ⚠️ **档位色只有这一处定义**。前端不按分数算档：
   `/api/mastery` 下发 `level`（0~4，来自 `mastery.level_of`，与状态文字同源），
   这里只负责上色。原来这里有一份自己的阈值（`.dot.s-pass` 对应 `score>=85`），
   与后端 `state_of()` 是两份 —— 改一处忘另一处就会「文字写已掌握、圆点涂成黄的」，
   而两边各自都自洽、测不出来。
   0 未诊断 / 1 未学 / 2 学习中 / 3 基本掌握 / 4 已掌握
   0 与 1 必须**一眼可分**（验收 #6）：0 是"还没测过"（浅灰 + 描边，像空槽），
   1 是"有记录但还没作答"（实心蓝灰）。 */
.dot.lv-0,.hcell.lv-0{background:#e9edf3;border:1.5px solid #cfd6df}
.dot.lv-1,.hcell.lv-1{background:#aeb9c9}
.dot.lv-2,.hcell.lv-2{background:var(--bad)}
.dot.lv-3,.hcell.lv-3{background:var(--warn)}
.dot.lv-4,.hcell.lv-4{background:var(--ok)}
.mrow .nm{flex:1;font-size:15px}
.mrow .vv{font-size:13px;color:var(--ink-3)}
.mrow .sc{font-size:13px;color:var(--ink-3);min-width:52px;text-align:right}

/* 热力网格：格子按最小可点区域 44px 排（平板竖屏约 7 列），点一格看详情。 */
.heat{display:grid;grid-template-columns:repeat(auto-fill,minmax(44px,1fr));gap:8px;padding:12px 4px 6px}
.hcell{min-height:44px;border:0;border-radius:10px;background:#cfd6df;color:#fff;
       font-size:12px;font-weight:600;font-family:inherit;padding:0;cursor:pointer;
       display:flex;align-items:center;justify-content:center;overflow:hidden}
.hcell.lv-0{color:var(--ink-3)}
.hcell.lv-1{color:#26313f}
.hcell.on{outline:2px solid var(--brand);outline-offset:2px}
.legend{display:flex;flex-wrap:wrap;gap:12px;margin:12px 2px 0}
.legend .lg{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--ink-2)}
/* 点选详情（点格子/点行都出）：钉在最上面，手指点完不用滚动找结果。 */
.sel-card{border-left:3px solid var(--brand)}
.sel-head{display:flex;align-items:center;gap:8px;font-weight:650;font-size:16px}
.tr{margin-top:8px;font-size:13px;color:var(--ink-2)}
.spark{width:100%;height:44px;display:block;margin:6px 0 2px;
       background:linear-gradient(#fff,#fbfcfe);border:1px solid var(--line);border-radius:8px}
.spark polyline{fill:none;stroke:var(--brand);stroke-width:2;vector-effect:non-scaling-stroke}
.tr-txt{font-size:13px;color:var(--ink)}
.tr-note{margin-top:4px;font-size:12px;color:var(--ink-3)}

/* ---------- 底部导航 ---------- */
.nav{
  position:fixed;left:0;right:0;bottom:0;z-index:30;
  display:flex;background:rgba(255,255,255,.96);backdrop-filter:blur(8px);
  border-top:1px solid var(--line);padding:6px max(8px,calc(50vw - 380px)) calc(6px + env(safe-area-inset-bottom));
}
.nav button{
  flex:1;min-height:56px;background:none;border:0;font:inherit;font-size:12.5px;
  color:var(--ink-3);cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:3px;
}
.nav button.on{color:var(--brand);font-weight:650}
.nav .ic{font-size:19px;line-height:1}

/* ---------- 口令页 ---------- */
.unlock-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px}
.unlock{width:100%;max-width:360px;background:#fff;border:1px solid var(--line);border-radius:18px;padding:28px 24px;box-shadow:var(--shadow)}
.unlock h1{font-size:19px;margin:0 0 6px}
.unlock .pin{
  width:100%;letter-spacing:14px;text-align:center;font-size:26px;min-height:60px;
  padding:12px;border:1.5px solid var(--line);border-radius:12px;outline:none;font-family:ui-monospace,monospace;
}
.unlock .pin:focus{border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-soft)}
.unlock .msg{min-height:22px;font-size:13.5px;color:var(--bad);margin-top:10px}

/* ---------- 状态 ---------- */
.center{text-align:center}
.pad{padding:40px 0}
.spin{display:inline-block;width:22px;height:22px;border:2.5px solid var(--line);border-top-color:var(--brand);border-radius:50%;animation:sp .8s linear infinite}
@keyframes sp{to{transform:rotate(360deg)}}
.hide{display:none !important}

.katex-display{overflow-x:auto;overflow-y:hidden;padding:2px 0}

/* ---------- 学习计划 ---------- */
.day-head{margin:16px 2px 8px;font-weight:650;font-size:15px;color:var(--ink)}
.card.task{padding:12px 14px}
.card.task .tt{display:flex;align-items:center;gap:8px;font-size:16px;font-weight:650}
.card.task .tic{
  width:22px;height:22px;flex:0 0 22px;border-radius:50%;
  background:var(--brand-soft);color:var(--brand);font-size:12px;line-height:22px;text-align:center;
}
.card.task .tn{flex:1 1 auto}
.card.task .mm{flex:0 0 auto;font-size:13px;color:var(--ink-3);font-weight:500}
.card.task .why{
  margin:8px 0 2px;padding:8px 10px;background:#f7f8fa;border-radius:8px;
  font-size:13px;line-height:1.55;color:var(--ink-2);
}
button.plain{background:none;border:0;padding:0;width:100%;text-align:left;font:inherit;color:inherit;cursor:pointer}
.dayrow{display:flex;align-items:center;gap:8px}
.dayrow .go{flex:0 0 auto;color:var(--ink-3)}
ul.daylist{margin:8px 0 0;padding-left:20px;font-size:14px;color:var(--ink-2)}
ul.daylist li{margin:3px 0}

/* ---------- 知识点快练 ---------- */
.slotres{font-size:13px;margin-top:4px;color:var(--ink-2)}
.slotres.ok{color:var(--ok)}
.slotres.bad{color:var(--bad)}
.ansline{margin-top:6px;font-size:15px}

/* ---------- 错题本：复习闭环（2026-10-01） ---------- */
.row-between{display:flex;align-items:center;justify-content:space-between;gap:10px}
.chip{
  display:inline-block;padding:2px 10px;border-radius:999px;
  font-size:12.5px;line-height:1.7;
  background:var(--bg);color:var(--ink-3);border:1px solid var(--line);white-space:nowrap;
}
.chip.hot{background:var(--warn-soft);color:var(--warn);border-color:#f2ddb8}
.summary-card{background:var(--brand-soft);border-color:#d9e4ff}
.summary-line{font-size:14px;color:var(--ink-2)}
.summary-line b{color:var(--brand);font-size:17px;font-weight:700;padding:0 1px}
/* ---- 错题本按知识点归组（2026-10-04）----
   一组 = 一节，组头给「练这一节」，把该节今天到期的错题排成队列逐道出变式。 */
.kp-group{margin-top:14px}
.kp-head{
  padding:8px 12px;border-radius:10px;background:var(--brand-soft);
  border:1px solid #d9e4ff;font-size:14px;color:var(--ink-2);margin-bottom:8px;
}
.kp-head b{color:var(--ink);font-size:15px}
.btn.small{padding:5px 12px;font-size:13.5px;min-height:0}

/* ---- 错因分类（U6，2026-10-13）----
   PRD 4.5.2 的五类 + 「未分类」。颜色只用来**区分**，不用来表达"好/坏"：
   五类错因没有哪一类更严重，用红绿会让家长误以为"概念不清比计算失误糟"。
   （本项目里红/绿的语义已经被"掌握度差/好"占了，混用会读反。） */
.cause-tag{
  display:inline-block;padding:1px 8px;border-radius:999px;font-size:12px;
  line-height:1.75;border:1px solid var(--line);background:var(--bg);
  color:var(--ink-2);white-space:nowrap;margin-right:6px;
}
.cause-tag.c-concept{background:#f1eeff;border-color:#ddd6ff;color:#5b46c8}
.cause-tag.c-calc{background:#eef3ff;border-color:#d9e4ff;color:#2f5be0}
.cause-tag.c-reading{background:#e9f7f2;border-color:#cbeade;color:#167a58}
.cause-tag.c-method{background:#fff5e6;border-color:#f2ddb8;color:#a8630a}
.cause-tag.c-forget{background:#fdeef5;border-color:#f5d3e4;color:#a83a72}
.cause-tag.c-unknown{background:var(--bg);border-color:var(--line);color:var(--ink-3)}

/* ---- U7 难度自适应（PRD 4.4 难度分层）----
   一行说明"本轮是什么档、为什么是这一档"。刻意用**弱化**的样式：
   它是背景信息，不该把孩子的注意力从题上抢走。 */
.q-diff{color:var(--ink-3)}
.adapt-line{
  font-size:12px;color:var(--ink-3);text-align:center;
  margin:-8px 0 12px;line-height:1.7;
}
.adapt-note{color:var(--ink-2)}
.adapt-why{margin-left:6px}
.adapt-why:before{content:"·";margin-right:6px}
/* 梯度不够的告警：比说明条重一档（它说的是"这件事本身没做到"），
   但仍不喧宾夺主 —— 不是错误，是一条如实告知。 */
.adapt-warn{
  font-size:12px;color:#a8630a;background:#fff5e6;border:1px solid #f2ddb8;
  border-radius:8px;padding:5px 10px;margin:-8px 0 12px;line-height:1.65;
}

/* ---- 错因画像（PRD 4.5.8）----
   一条横向占比条 + 图例。不用图表库：五类占比用"堆叠条"表达就够了，
   引入 ECharts 会为一个模块拉进一个 CDN 依赖（本项目零构建、离线可用）。 */
.portrait{margin-top:10px}
.portrait-bar{
  display:flex;height:10px;border-radius:999px;overflow:hidden;
  background:var(--bg);border:1px solid var(--line);
}
.portrait-bar i{display:block;height:100%}
.portrait-legend{
  display:flex;flex-wrap:wrap;gap:4px 14px;margin-top:8px;
  font-size:13px;color:var(--ink-2);
}
.portrait-legend em{font-style:normal;color:var(--ink);font-weight:600}
.portrait-legend span.d{
  display:inline-block;width:8px;height:8px;border-radius:2px;
  margin-right:5px;vertical-align:middle;
}
.portrait-head{font-size:14px;color:var(--ink-2);margin-top:9px}
.portrait-warn{font-size:13px;color:var(--warn);margin-top:6px}

/* ---- 多账号：全站常驻的「切换用户」（2026-10-03 取代原来的小 whoami 按钮）----
   为什么固定定位、而不是放进某一屏的顶栏或底部导航：
     * 底部导航在做题/讲解/结论时是**隐藏的**（App.showNav），
     * 顶栏也不是每屏都有；
   而"做到一半换人"是真实场景 —— 入口不能依赖任何一屏的布局。
   位置正对顶栏右侧（原来首页那儿放的是章节名，已让位）。
   z-index 26：高于 sticky 顶栏（20），低于底部导航（30）→ 不会盖住导航。 */
.switch-user {
  position: fixed; z-index: 26; top: 10px; right: 12px;
  display: flex; align-items: center; gap: 6px;
  min-height: var(--tap); padding: 6px 14px;      /* 触控目标按 PRD 827 ≥44 */
  border: 1px solid #dfe3ea; border-radius: 999px;
  background: rgba(255,255,255,.94); backdrop-filter: blur(6px);
  color: #4a5568; font: inherit; font-size: 12.5px; cursor: pointer;
  box-shadow: 0 1px 4px rgba(20,30,60,.06);
}
.switch-user:active { background: #f0f5ff; }
/* 顶栏标题给右侧让出位置，长标题（「补一下：去括号与合并同类项」）不至于钻到药丸底下 */
.topbar h1 { padding-right: 122px; }

/* 批改表单的小输入框（P5，2026-10-13）。
   ⚠️ 为什么另开一个 .sm 而不是直接用 .input：`.input` 是**答题框**
   （min-height:56px / font-size:20px），尺寸是为"手指点着写答案"定的；
   批改只是录题号与备注，用那么大的框一行放不下三个字段。
   但仍保留 44px 的最小可点高度（styles.css 头部的平板适配口径）。 */
.input.sm{min-height:44px;font-size:15px;padding:8px 12px;border-width:1.5px}

/* ---------- 学习进度（老板 2026-10-16） ----------
   ⚠️ 本文件开头写着「反焦虑：不加排名、不加百分比、不加进度条压力」——
      这一页加了进度条，**不违反那条**，因为两者标的不是同一件事：
      它标的是「老师课上到哪、我练到哪」，**不是**「你考了多少分」；
      没有排名、没有和别人比、没有倒计时。孩子看到的是"下一步练哪一块"，
      而不是"我落后了多少"。配色与措辞都按这个基调来。
   ⚠️ 档位色**不在这里另定一套**：.pseg / .kpchip 的 lv-* 与掌握地图的
      .dot / .hcell 同色（lv-0 灰、lv-2 红、lv-3 黄、lv-4 绿），
      而档位值只来自服务端下发的 level（mastery.level_of）。
      两处各调一次色，就会出现"进度条说会了、掌握地图说没会"。 */
.booktabs{display:flex;gap:8px;overflow-x:auto;margin:10px 0 0;padding-bottom:2px}
.booktabs button{
  flex:0 0 auto;min-height:36px;padding:0 14px;border-radius:999px;
  background:var(--card);border:1px solid var(--line);font:inherit;
  font-size:13.5px;color:var(--ink-2);cursor:pointer}
.booktabs button.on{background:var(--brand-soft);border-color:#d9e4ff;color:var(--brand);font-weight:650}

.sch-t{font-size:17px;font-weight:650;margin-top:2px}
.sch-note{
  margin-top:10px;padding:8px 10px;border-radius:8px;font-size:13px;
  background:var(--warn-soft);color:var(--warn)}
.sch-note.tip{background:var(--brand-soft);color:var(--brand)}

.pbar{display:flex;gap:3px;height:12px;margin:12px 0 8px}
.pseg{flex:1;border-radius:4px;background:#e9edf3}
.pseg.none{background:#eef1f5}
.pseg.lv-1{background:#aeb9c9}
.pseg.lv-2{background:var(--bad)}
.pseg.lv-3{background:var(--warn)}
.pseg.lv-4{background:var(--ok)}
.pseg.cur{outline:2px solid var(--brand);outline-offset:1px}
.pbar-note{display:flex;justify-content:space-between;font-size:12.5px;color:var(--ink-3)}

.secrow{display:flex;gap:10px;padding:12px 0;border-bottom:1px solid var(--line)}
.secrow:last-child{border-bottom:0}
.secrow .dot{margin-top:7px}
.sec-main{flex:1;min-width:0}
.sec-t{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:15px;font-weight:600}
.tag-school{
  font-size:12px;padding:1px 8px;border-radius:999px;font-weight:500;
  background:var(--brand-soft);color:var(--brand)}
.sec-s{font-size:13px;color:var(--ink-3);margin-top:2px}
.kpwrap{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.kpchip{
  min-height:34px;padding:0 11px;border-radius:999px;font:inherit;font-size:13px;
  border:1px solid var(--line);background:var(--card);color:var(--ink-2);cursor:pointer}
.kpchip.lv-0{border-style:dashed;color:var(--ink-3)}
.kpchip.lv-3{border-color:#f2ddb8;background:var(--warn-soft);color:var(--warn)}
.kpchip.lv-4{border-color:#bfe6d1;background:var(--ok-soft);color:var(--ok)}
.kpchip[disabled]{opacity:.5;cursor:not-allowed}
.sec-acts{flex:0 0 auto;display:flex;flex-direction:column;gap:6px;align-items:flex-end}
.btn.small{min-height:34px;padding:0 12px;font-size:13px}


/* ---------- 学习进度：全课程版（老板 2026-10-17） ----------
   学期选择条沿用 .booktabs（横向滚动、胶囊按钮）；
   这里只补三样：没有内容的学期做弱化、小学折叠入口做虚线、章底部的"底子"分组做分隔线。
   ⚠️ 学期按钮的 `dim` 只是**颜色弱化**，不是禁用 —— 没内容的学期照样能点进去
      （孩子要在那儿标进度，只是没有题可练）。禁用会让人以为"这一学期不存在"。 */
.booktabs button.dim{color:var(--ink-3)}
.booktabs-more{
  flex:0 0 auto;min-height:36px;padding:0 14px;border-radius:999px;
  background:var(--card);border:1px dashed var(--line);font:inherit;
  font-size:13px;color:var(--ink-3);cursor:pointer}
.booktabs-more.on{background:var(--brand-soft);border-style:solid;border-color:#d9e4ff;color:var(--brand);font-weight:650}
.skillwrap{border-top:1px dashed var(--line);margin-top:4px;padding-top:2px}


/* ---------- 全面测试：「不会 / 暂时跳过」（老板 2026-10-17） ----------
   两件事必须**长得不一样**，否则孩子会当成同一个按钮：
     · 「暂时跳过」= 中性（灰），点错了也不罚
     · 「这题不会」= 有代价（红字），交卷时进错题本
   ⚠️ 答题卡从「24 行竖排」改成网格：加了两种状态之后，竖排要滑三屏才能看全，
      而答题卡的全部价值就是"一眼看出哪几题还没做"。 */
.btn.ghost.qblind{color:var(--bad)}
.btn.armed{background:var(--warn);border-color:var(--warn);color:#fff}
.opts.grid{display:flex;flex-direction:row;flex-wrap:wrap;gap:8px}
.opts.grid .opt{
  width:46px;min-width:46px;min-height:46px;padding:0;text-align:center;
  display:inline-flex;align-items:center;justify-content:center;
  font-variant-numeric:tabular-nums;border-radius:10px}
.opts.grid .opt.st-blind{border-color:#f0b8b3;background:var(--bad-soft);color:var(--bad)}
.opts.grid .opt.st-skip{border-style:dashed;color:var(--warn);border-color:#f2ddb8;background:var(--warn-soft)}
.tag-mk{margin-left:2px;font-size:11px;color:var(--ink-3)}
.opts.grid .opt.st-blind .tag-mk{color:var(--bad)}
.qmark{color:var(--bad);margin-left:8px}
.card-legend{margin:10px 0 0;font-size:12.5px;color:var(--ink-3);letter-spacing:.3px}
/* ⚠️ 上面这个类**不能**叫 .legend —— 那个名字在掌握地图那里已经是图例**容器**
   （display:flex，本文件第 210 行）。同名会把它的 flex 覆盖掉，症状是那张图例
   挤成一坨；它和全面测试相隔三个页面，出了事极难联想到一起。 */


/* ---------- 真题库 + 自评（2026-10-18） ----------
   两个页面共用这一套：
     · #/real 目录：年份折叠行 + 每张卷一行；
     · 报告页的自评块：三档按钮 + 标准解答的分段标题。
   为什么年份一律折叠：30 年 × 平均 23 题全摊开是几百行，翻起来比收起更累；
   折叠行本身带"几年几张卷"，不展开也能看出规模。 */
.yearline{
  display:flex;align-items:center;gap:10px;cursor:pointer;
  min-height:44px;padding:2px 0;
}
.yearline .yr{font-size:16px;font-weight:650}
.yearline .caret{margin-left:auto;color:var(--ink-3);font-size:13px}
.realrow{padding:12px 0;border-top:1px dashed var(--line)}
.realrow:first-of-type{border-top:1px solid var(--line);margin-top:6px}
.realrow .ttl{display:flex;align-items:center;gap:8px;font-size:15px;line-height:1.5}
.realrow .meta{font-size:13px;margin-top:4px}
.realrow .note{font-size:12.5px;margin:6px 0 0;line-height:1.6}
/* 卷别徽标：真题 = 实心品牌色，仿真 = 虚线描边 —— 一眼能分出哪个是原卷。
   ⚠️ 不用红/绿：那两个颜色在这个系统里是"对/错"的专用语义（见 .v-pass/.v-hole）。 */
.badge{
  display:inline-block;padding:1px 6px;border-radius:6px;font-size:11.5px;
  font-weight:650;letter-spacing:.3px;white-space:nowrap;
}
.badge.b-real{background:var(--brand-soft);border:1px solid #d9e4ff;color:var(--brand)}
.badge.b-sim{background:#fff;border:1px dashed var(--line);color:var(--ink-3)}

/* 解答题写过程的文本框：字号按"读长文"来（不是答题框的 20px），可竖向拉伸。 */
.input.ta{
  min-height:180px;padding:12px 14px;font-size:16px;line-height:1.75;
  resize:vertical;white-space:pre-wrap;
}

/* 报告页：逐题块里的知识点 / 孩子写的原文 / 标准解答分段标题 / 自评按钮组 */
.review-item .kb{font-size:12.5px;color:var(--ink-3);margin-top:3px}
.review-item .mytext{font-size:13.5px;margin-top:6px}
.review-item .mytext .pre{
  margin-top:4px;padding:10px 12px;background:var(--bg);border:1px solid var(--line);
  border-radius:10px;white-space:pre-wrap;line-height:1.7;font-size:14px;
  max-height:320px;overflow:auto;
}
.review-item .sol .solh{
  font-size:13px;font-weight:650;color:var(--ink-2);margin:10px 0 2px;
}
.review-item .sol .solh:first-child{margin-top:0}
/* 解析里的术语标注（2026-10-20 阶段 A）：老师本子上「公因式 ↑ 5x」那种批注。
   它不是正文的一部分 —— 混在句子里会被读成句子，所以单独一行、带底色、小一号。 */
.sol .solterms{display:flex;flex-wrap:wrap;gap:6px;margin:6px 0 2px}
.sol .solterm{display:inline-flex;align-items:baseline;gap:4px;
  padding:2px 8px;border-radius:8px;background:#fff7e8;border:1px solid #f0dcbb;
  font-size:12.5px;color:#8a5a12;line-height:1.5}
.sol .solterm .sw{font-weight:650}
.sol .solterm b{font-size:12.5px;font-weight:600}
.selfeval{margin-top:10px;padding:10px 12px;border:1px solid var(--line);border-radius:12px;background:#fbfcfe}
.selfeval .lbl{font-size:13.5px;color:var(--ink-2);margin-bottom:8px}
.selfeval .btn-row{display:flex;flex-wrap:wrap;gap:8px}
.selfeval .btn{min-height:40px;padding:0 14px;font-size:14px}
.selfeval .muted{font-size:12.5px;margin-top:8px}

/* 底部导航加到 7 项之后，12.5px 的"掌握地图"在 375px 宽的小屏上会顶到边。
   这里按"最窄也能放下 4 个汉字"收紧一档 —— 只改尺寸，不改结构。 */
.nav button{font-size:12px;padding:0 1px}
.nav button>span:last-child{white-space:nowrap;transform:scale(.96)}

/* ---------- 今日三步（阶段 B，2026-10-20）----------
   老师给的流程是每天固定走三步，所以它必须比"待办列表"更靠上、更像一条路 ——
   三格并排 + 段落编号，扫一眼就知道今天走到哪儿。
   ⚠️ 小屏（<=520px）竖排：三格并排时每格只剩 100px，副标题会被压成两行字头，
      反而看不清"这一步是什么"。 */
.dsteps{display:flex;gap:8px;margin:8px 0 14px}
.dstep{
  flex:1;min-width:0;text-align:left;font:inherit;color:inherit;cursor:pointer;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius-sm);
  padding:10px 11px;box-shadow:var(--shadow);transition:border-color .15s ease;
}
.dstep:active{filter:brightness(.98)}
.dstep .h{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--ink-3)}
.dstep .h b{color:var(--brand);font-size:12px}
.dstep .t{display:block;font-weight:650;font-size:14px;margin-top:3px;line-height:1.4}
.dstep .s{display:block;font-size:12px;color:var(--ink-3);margin-top:2px;line-height:1.45}
.dstep.done{background:var(--ok-soft);border-color:#bfe6cd}
.dstep.done .h b{color:var(--ok)}
.dstep.doing{border-color:var(--brand);background:var(--brand-soft)}
.dstep.skip{opacity:.62}
.dstep .tag{
  font-size:11px;padding:1px 6px;border-radius:999px;background:var(--ok-soft);
  color:var(--ok);border:1px solid #bfe6cd;
}
@media (max-width:520px){
  .dsteps{flex-direction:column}
  .dstep .s{margin-top:1px}
}

/* ---------- 单题正确率三档（阶段 C，2026-10-20）----------
   老师笔记图一下半那张表：档名 + 区间 + 题数，下面三类行「序号 / 题面 / 正确次数·总次数·正确率」。
   ⚠️ 三档只靠**左边一条色带**区分，不整块上色：一屏里三块彩色会把"看题面"这件事压掉，
      而老师在这张表上真正要读的是题面本身。
   ⚠️ 题面只给一行半（`-webkit-line-clamp`）：表格是索引，不是题目页 ——
      题面完整显示会让三道题占满一屏，剩下两档看不见。 */
.sband{margin-top:10px;padding-left:9px;border-left:3px solid var(--line)}
.sband.remedy{border-left-color:#e8735a}
.sband.consolidate{border-left-color:var(--brand)}
.sband.solid{border-left-color:var(--ok)}
.sband .h{display:flex;align-items:baseline;gap:8px;font-size:13px}
.sband .h .sw{font-weight:650}
.sband .h .muted{font-size:12px}
.srow{display:flex;align-items:flex-start;gap:8px;margin-top:5px;font-size:13px;line-height:1.5}
.srow .ix{flex:0 0 15px;color:var(--ink-3);font-size:12px;padding-top:1px}
.srow .st{
  flex:1;min-width:0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;
}
.srow .num{flex:0 0 auto;color:var(--ink-3);font-size:12px;white-space:nowrap;padding-top:1px}


/* ---- 手写过程拍照上传（2026-10-24）---- */
.photoline { display: flex; align-items: center; gap: 10px; margin-top: 8px; flex-wrap: wrap; }
.photoline .muted { font-size: 12px; }
.shots { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.shot { position: relative; width: 96px; height: 96px; border-radius: 8px; overflow: hidden;
        border: 1px solid #e3e6ea; background: #fff; display: block; }
.shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.shot-del { position: absolute; top: 0; right: 0; width: 24px; height: 24px; line-height: 22px;
            text-align: center; border: none; border-radius: 0 0 0 8px;
            background: rgba(0, 0, 0, 0.55); color: #fff; font-size: 14px; cursor: pointer; }
.geopad { margin-top: 8px; }
