/* 记词宝 · AI 口语模考页样式（独立，与主站样式互不影响） */
:root{
  --ink:#17202e; --muted:#68707c; --faint:#8b93a1;
  --line:#e3e7ec; --panel:#ffffff; --bg:#f2f4f7; --soft:#f7f9fb;
  --accent:#0a6a9e; --accent-soft:#e6f2fa; --accent-ink:#075985;
  --ok:#1d7a4d; --ok-soft:#e9f6ee;
  --warn:#a1620a; --warn-soft:#fdf4e4;
  --danger:#c74c59; --danger-soft:#fdeceb;
  --wave-ref:#2f7fe0;   /* 跟读对比图：原声 */
  --wave-me:#12a170;    /* 跟读对比图：我说的 */
  --r:14px;
}
/* 系统深色兜底 —— 2026-09-30 起**限定为「用户没选主站主题」时**才生效。
   选了主站主题就交给下面的 :root[data-theme="X"] 块接管；否则会出现
   「主站是浅色主题、口语页却因为系统深色而变深」这种两边不一致的错配。 */
@media (prefers-color-scheme: dark){
  :root:not([data-theme]){
    --ink:#e9ecf1; --muted:#a4adbb; --faint:#79828f;
    --line:#2b3138; --panel:#171b21; --bg:#0f1216; --soft:#1b2026;
    --accent:#5cb3e0; --accent-soft:#12293a; --accent-ink:#8ecdf0;
    --ok:#63c08d; --ok-soft:#122a1e;
    --warn:#d9a441; --warn-soft:#2b2313;
    --danger:#e08b83; --danger-soft:#2d1a19;
    --wave-ref:#5fa8ff; --wave-me:#4cc79a;
  }
}

/* ---------- 跟随主站主题（2026-09-30）----------
 * 为什么有这一段：主站主题是**用户手选**的（19 套，存 localStorage 的 wb_theme → <html data-theme>），
 *   而口语页原先只跟系统的 prefers-color-scheme —— 两边各走各的，用户在主站选了深色主题进口语页却是浅色。
 * 数据来源：**手工同步自 css/styles.css 的 :root[data-theme="X"] 块**（口语页不引用主站 CSS）。
 *   🔴 改主站主题配色时**必须同步这里**；核对脚本见 tools/tmp/verify_speaking_theme.js。
 * 8 个与主站同名的变量直接沿用主站原值 → 观感与主站一致；
 * 口语页独有的语义色（ok/warn/danger/faint/soft/wave-*）主站没有 → 按该主题的深浅取浅/深两组的对应值。
 * 生效：speaking.html 读 wb_theme → 设 <html data-theme="X">；未选主题时不设 → 走默认浅色 + 系统深色兜底。 */
/* 极光玻璃（深色） */
:root[data-theme="aurora"]{
  --bg:#0e1420; --panel:rgba(255, 255, 255, .07); --ink:#e8ecf4;
  --muted:#818ba3; --line:rgba(255, 255, 255, .1); --accent:#7c5cff;
  --accent-soft:rgba(124, 92, 255, .16); --accent-ink:#c4b5fd; --faint:#79828f;
  --soft:#1b2026; --ok:#63c08d; --ok-soft:#122a1e;
  --warn:#d9a441; --warn-soft:#2b2313; --danger:#e08b83;
  --danger-soft:#2d1a19; --wave-ref:#5fa8ff; --wave-me:#4cc79a;
}
/* 静谧蓝极光（深色） */
:root[data-theme="calmblue"]{
  --bg:#0a1626; --panel:rgba(255, 255, 255, .06); --ink:#dce6f5;
  --muted:#7a8ba9; --line:rgba(255, 255, 255, .08); --accent:#38bdf8;
  --accent-soft:rgba(56, 189, 248, .12); --accent-ink:#7dd3fc; --faint:#79828f;
  --soft:#1b2026; --ok:#63c08d; --ok-soft:#122a1e;
  --warn:#d9a441; --warn-soft:#2b2313; --danger:#e08b83;
  --danger-soft:#2d1a19; --wave-ref:#5fa8ff; --wave-me:#4cc79a;
}
/* 清新薄荷（浅色） */
:root[data-theme="mint"]{
  --bg:#f2fbf7; --panel:#ffffff; --ink:#14443a;
  --muted:#59796e; --line:#cdeae0; --accent:#2fae8d;
  --accent-soft:#dcf3ea; --accent-ink:#1a7a62; --faint:#8b93a1;
  --soft:#f7f9fb; --ok:#1d7a4d; --ok-soft:#e9f6ee;
  --warn:#a1620a; --warn-soft:#fdf4e4; --danger:#b3392f;
  --danger-soft:#fdeceb; --wave-ref:#2f7fe0; --wave-me:#12a170;
}
/* 曜石黑金（深色） */
:root[data-theme="obsidian"]{
  --bg:#0b0e13; --panel:#10141b; --ink:#e8e6df;
  --muted:#767f8e; --line:#1e2530; --accent:#d4af37;
  --accent-soft:#241f10; --accent-ink:#e5c86e; --faint:#79828f;
  --soft:#1b2026; --ok:#63c08d; --ok-soft:#122a1e;
  --warn:#d9a441; --warn-soft:#2b2313; --danger:#e08b83;
  --danger-soft:#2d1a19; --wave-ref:#5fa8ff; --wave-me:#4cc79a;
}
/* 极光晨雾（浅色） */
:root[data-theme="dawn"]{
  --bg:#f2f1f8; --panel:rgba(255, 255, 255, .65); --ink:#2a2440;
  --muted:#6f6b82; --line:rgba(120, 110, 160, .16); --accent:#7c5cff;
  --accent-soft:rgba(124, 92, 255, .1); --accent-ink:#5b4bc4; --faint:#8b93a1;
  --soft:#f7f9fb; --ok:#1d7a4d; --ok-soft:#e9f6ee;
  --warn:#a1620a; --warn-soft:#fdf4e4; --danger:#b3392f;
  --danger-soft:#fdeceb; --wave-ref:#2f7fe0; --wave-me:#12a170;
}
/* 紫藤夜语（深色） */
:root[data-theme="wisteria"]{
  --bg:#150f24; --panel:rgba(255, 255, 255, .06); --ink:#e6dcf5;
  --muted:#8c83a5; --line:rgba(255, 255, 255, .08); --accent:#c084fc;
  --accent-soft:rgba(192, 132, 252, .13); --accent-ink:#d8b4fe; --faint:#79828f;
  --soft:#1b2026; --ok:#63c08d; --ok-soft:#122a1e;
  --warn:#d9a441; --warn-soft:#2b2313; --danger:#e08b83;
  --danger-soft:#2d1a19; --wave-ref:#5fa8ff; --wave-me:#4cc79a;
}
/* 青柠汽水（深色） */
:root[data-theme="lime"]{
  --bg:#0a1a16; --panel:rgba(255, 255, 255, .06); --ink:#dff2ea;
  --muted:#719386; --line:rgba(255, 255, 255, .08); --accent:#a3e635;
  --accent-soft:rgba(163, 230, 53, .12); --accent-ink:#bef264; --faint:#79828f;
  --soft:#1b2026; --ok:#63c08d; --ok-soft:#122a1e;
  --warn:#d9a441; --warn-soft:#2b2313; --danger:#e08b83;
  --danger-soft:#2d1a19; --wave-ref:#5fa8ff; --wave-me:#4cc79a;
}
/* 冰川银辉（深色） */
:root[data-theme="glacier"]{
  --bg:#10151c; --panel:rgba(255, 255, 255, .05); --ink:#dde4ec;
  --muted:#7d8998; --line:rgba(255, 255, 255, .07); --accent:#93c5fd;
  --accent-soft:rgba(147, 197, 253, .1); --accent-ink:#b4d3f5; --faint:#79828f;
  --soft:#1b2026; --ok:#63c08d; --ok-soft:#122a1e;
  --warn:#d9a441; --warn-soft:#2b2313; --danger:#e08b83;
  --danger-soft:#2d1a19; --wave-ref:#5fa8ff; --wave-me:#4cc79a;
}
/* 赛博靛夜（深色） */
:root[data-theme="cyber"]{
  --bg:#0d1026; --panel:#11142e; --ink:#dfe3f5;
  --muted:#787da7; --line:#20234a; --accent:#8b5cf6;
  --accent-soft:#221d4e; --accent-ink:#a78bfa; --faint:#79828f;
  --soft:#1b2026; --ok:#63c08d; --ok-soft:#122a1e;
  --warn:#d9a441; --warn-soft:#2b2313; --danger:#e08b83;
  --danger-soft:#2d1a19; --wave-ref:#5fa8ff; --wave-me:#4cc79a;
}
/* 经典默认（浅色） */
:root[data-theme="classic"]{
  --bg:#f4f6fb; --panel:#ffffff; --ink:#1f2533;
  --muted:#6b717d; --line:#e7ebf3; --accent:#4f7cff;
  --accent-soft:#eaf0ff; --accent-ink:#2c59d6; --faint:#8b93a1;
  --soft:#f7f9fb; --ok:#1d7a4d; --ok-soft:#e9f6ee;
  --warn:#a1620a; --warn-soft:#fdf4e4; --danger:#b3392f;
  --danger-soft:#fdeceb; --wave-ref:#2f7fe0; --wave-me:#12a170;
}
/* 学术米白（浅色） */
:root[data-theme="academic"]{
  --bg:#f7f3ea; --panel:#fffdf7; --ink:#2e3a59;
  --muted:#796e53; --line:#e3d9c6; --accent:#a08c5a;
  --accent-soft:#efe7d5; --accent-ink:#7f641d; --faint:#8b93a1;
  --soft:#f7f9fb; --ok:#1d7a4d; --ok-soft:#e9f6ee;
  --warn:#a1620a; --warn-soft:#fdf4e4; --danger:#b3392f;
  --danger-soft:#fdeceb; --wave-ref:#2f7fe0; --wave-me:#12a170;
}
/* 深夜专注（深色） */
:root[data-theme="midnight"]{
  --bg:#151a24; --panel:#1f2634; --ink:#eef1f6;
  --muted:#828da6; --line:#2a3140; --accent:#f0b13c;
  --accent-soft:#2a3346; --accent-ink:#f5c35c; --faint:#79828f;
  --soft:#1b2026; --ok:#63c08d; --ok-soft:#122a1e;
  --warn:#d9a441; --warn-soft:#2b2313; --danger:#e08b83;
  --danger-soft:#2d1a19; --wave-ref:#5fa8ff; --wave-me:#4cc79a;
}
/* 牛津深蓝（深色） */
:root[data-theme="oxford"]{
  --bg:#0f1c33; --panel:#182747; --ink:#f5f7fb;
  --muted:#8fa3cc; --line:#1b2a4a; --accent:#d4af5a;
  --accent-soft:#22345c; --accent-ink:#e8c56e; --faint:#79828f;
  --soft:#1b2026; --ok:#63c08d; --ok-soft:#122a1e;
  --warn:#d9a441; --warn-soft:#2b2313; --danger:#e08b83;
  --danger-soft:#2d1a19; --wave-ref:#5fa8ff; --wave-me:#4cc79a;
}
/* 樱花柔粉（浅色） */
:root[data-theme="sakura"]{
  --bg:#fdf5f7; --panel:#ffffff; --ink:#5b2f3d;
  --muted:#8e6672; --line:#f2d7de; --accent:#d87d94;
  --accent-soft:#f8e4ea; --accent-ink:#a14e65; --faint:#8b93a1;
  --soft:#f7f9fb; --ok:#1d7a4d; --ok-soft:#e9f6ee;
  --warn:#a1620a; --warn-soft:#fdf4e4; --danger:#b3392f;
  --danger-soft:#fdeceb; --wave-ref:#2f7fe0; --wave-me:#12a170;
}
/* 极简黑白（浅色） */
:root[data-theme="minimal"]{
  --bg:#ffffff; --panel:#ffffff; --ink:#111111;
  --muted:#767676; --line:#e0e0e0; --accent:#e0452c;
  --accent-soft:#f5f5f5; --accent-ink:#b8352a; --faint:#8b93a1;
  --soft:#f7f9fb; --ok:#1d7a4d; --ok-soft:#e9f6ee;
  --warn:#a1620a; --warn-soft:#fdf4e4; --danger:#b3392f;
  --danger-soft:#fdeceb; --wave-ref:#2f7fe0; --wave-me:#12a170;
}
/* 森林墨绿（浅色） */
:root[data-theme="forest"]{
  --bg:#f3f7ef; --panel:#ffffff; --ink:#1e3a24;
  --muted:#617659; --line:#c9d8c5; --accent:#4a7c3f;
  --accent-soft:#e2edda; --accent-ink:#35612c; --faint:#8b93a1;
  --soft:#f7f9fb; --ok:#1d7a4d; --ok-soft:#e9f6ee;
  --warn:#a1620a; --warn-soft:#fdf4e4; --danger:#b3392f;
  --danger-soft:#fdeceb; --wave-ref:#2f7fe0; --wave-me:#12a170;
}
/* 活力晨曦（浅色） */
:root[data-theme="sunrise"]{
  --bg:#fff8ee; --panel:#ffffff; --ink:#5a3000;
  --muted:#946a2d; --line:#ffd9a8; --accent:#ff8a2a;
  --accent-soft:#ffe9c9; --accent-ink:#a8530c; --faint:#8b93a1;
  --soft:#f7f9fb; --ok:#1d7a4d; --ok-soft:#e9f6ee;
  --warn:#a1620a; --warn-soft:#fdf4e4; --danger:#b3392f;
  --danger-soft:#fdeceb; --wave-ref:#2f7fe0; --wave-me:#12a170;
}
/* 薰衣草紫（浅色） */
:root[data-theme="lavender"]{
  --bg:#f8f5fd; --panel:#ffffff; --ink:#3d2a5e;
  --muted:#796997; --line:#ddd3f0; --accent:#7a5fc0;
  --accent-soft:#eae2f8; --accent-ink:#5f43a8; --faint:#8b93a1;
  --soft:#f7f9fb; --ok:#1d7a4d; --ok-soft:#e9f6ee;
  --warn:#a1620a; --warn-soft:#fdf4e4; --danger:#b3392f;
  --danger-soft:#fdeceb; --wave-ref:#2f7fe0; --wave-me:#12a170;
}

*{box-sizing:border-box; -webkit-tap-highlight-color:transparent}

/* 🔴 必须放在自定义 display 之前：作者样式里的 `display:inline-flex` 会**盖过**
   浏览器对 hidden 属性的 `display:none`，于是写 `<button hidden>` 的按钮照样显示出来。
   （2026-09-22 实测踩到：模考页的「停止录音 / 停止自检」和跟读页的「停止录音」
     在还没开始录音时就一直可见。）用 !important 一次性挡住这类问题。 */
[hidden]{display:none !important}
html,body{margin:0;padding:0}
body{
  background:var(--bg); color:var(--ink);
  font:15px/1.7 -apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  -webkit-font-smoothing:antialiased;
  padding-bottom:40px;
}
h1,h2{margin:0;font-size:16px;font-weight:600}
p{margin:0}

/* ---------- 顶栏 ---------- */
.sp-top{
  position:sticky; top:0; z-index:20;
  display:flex; align-items:center; gap:12px;
  padding:10px 14px; background:var(--panel); border-bottom:1px solid var(--line);
  /* 玻璃类主题（极光玻璃 / 静谧蓝极光 / 紫藤夜语 / 青柠汽水 / 冰川银辉 / 极光晨雾）的
     --panel 是半透明的，不加这行时滚动会看到内容从顶栏底下穿出来、糊成一片。
     面板不透明的主题（曜石黑金 / 赛博靛夜等）加它没有可见影响。 */
  -webkit-backdrop-filter:blur(14px); backdrop-filter:blur(14px);
}
.sp-back{
  width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center;
  color:var(--ink);text-decoration:none;font-size:18px;border:1px solid var(--line);flex:none;
}
.sp-title{flex:1;min-width:0}
.sp-title strong{display:block;font-size:15px}
.sp-title span{display:block;font-size:12px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sp-ghost{
  border:1px solid var(--line);background:transparent;color:var(--muted);
  font-size:12px;padding:5px 10px;border-radius:8px;cursor:pointer;flex:none;
}

/* ---------- 布局 ---------- */
.sp-main{max-width:760px;margin:0 auto;padding:14px}
.sp-card{
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:16px;margin-bottom:14px;
}
.sp-card h2{margin-bottom:10px}
.sp-hint{font-size:13px;color:var(--muted);margin-bottom:12px}
.sp-tiny{font-size:12px;color:var(--faint);margin-top:10px}
.sp-row{display:flex;gap:10px;flex-wrap:wrap;margin-top:14px}
.sp-row.center{justify-content:center;margin:6px 0 20px}

/* ---------- 按钮 ---------- */
.sp-btn{
  appearance:none;border:1px solid var(--line);background:var(--soft);color:var(--ink);
  font-size:14px;padding:10px 16px;border-radius:10px;cursor:pointer;text-decoration:none;
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  transition:border-color .15s, background .15s;
}@media (hover: hover) { .sp-btn:hover {border-color:var(--accent)} }
@media (hover: none) { .sp-btn:active {border-color:var(--accent)} }

.sp-btn:disabled{opacity:.55;cursor:default}
.sp-btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}@media (hover: hover) { .sp-btn.primary:hover {background:var(--accent-ink);border-color:var(--accent-ink)} }
@media (hover: none) { .sp-btn.primary:active {background:var(--accent-ink);border-color:var(--accent-ink)} }

.sp-btn.danger{background:var(--danger-soft);border-color:var(--danger);color:var(--danger)}
.sp-btn.big{font-size:15px;padding:13px 22px;flex:1}

/* ---------- 题目标签页 ---------- */
.sp-tabs{display:flex;gap:8px;margin-bottom:12px}
.sp-tab{
  flex:1;border:1px solid var(--line);background:transparent;color:var(--muted);
  padding:9px;border-radius:10px;font-size:13.5px;cursor:pointer;
}
.sp-tab.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent-ink);font-weight:600}
.sp-qlist{display:flex;flex-direction:column;gap:10px}
.sp-qitem{
  display:flex;align-items:center;gap:12px;text-align:left;width:100%;
  border:1px solid var(--line);background:var(--soft);border-radius:12px;padding:12px 14px;
  cursor:pointer;color:inherit;font:inherit;
}@media (hover: hover) { .sp-qitem:hover {border-color:var(--accent)} }
@media (hover: none) { .sp-qitem:active {border-color:var(--accent)} }

.sp-qpart{
  flex:none;width:34px;height:34px;border-radius:9px;background:var(--accent-soft);color:var(--accent-ink);
  display:flex;align-items:center;justify-content:center;font-size:12.5px;font-weight:600;
}
.sp-qbody{flex:1;min-width:0;display:flex;flex-direction:column}
.sp-qbody strong{font-size:14px;font-weight:600}
.sp-qbody em{font-size:12.5px;color:var(--muted);font-style:normal}
.sp-qgo{color:var(--faint);flex:none}

/* ---------- 麦克风与音量条 ---------- */
.sp-meter{
  height:12px;border-radius:8px;background:var(--soft);border:1px solid var(--line);
  overflow:hidden;margin:6px 0 8px;
}
.sp-meter.big{height:18px;margin:14px 0 10px}
.sp-meter i{
  display:block;height:100%;width:100%;
  background:linear-gradient(90deg,#3aa3d8,#1d7a4d);
  transform:scaleX(0);transform-origin:left center;
  transition:transform .07s linear;
}
.sp-meter i.hot{background:var(--danger)}
.sp-micstate{font-size:13px;color:var(--muted)}

/* ---------- 题目卡 ---------- */
.sp-qhead{display:flex;gap:8px;margin-bottom:10px;flex-wrap:wrap}
.sp-chip{
  font-size:12px;padding:3px 9px;border-radius:20px;
  background:var(--accent-soft);color:var(--accent-ink);border:1px solid transparent;
}
.sp-chip.ghost{background:transparent;border-color:var(--line);color:var(--muted)}
.sp-cue{
  font-size:15.5px;line-height:1.75;font-weight:500;
  padding:12px 14px;border-left:3px solid var(--accent);background:var(--soft);border-radius:0 10px 10px 0;
  margin:4px 0 12px;
}
.sp-bullets{margin:0 0 12px;padding-left:20px;color:var(--muted);font-size:13.5px}
.sp-bullets li{margin:3px 0}
.sp-qs{display:flex;flex-direction:column;gap:12px}
.sp-qone{padding-left:12px;border-left:2px solid var(--line)}
.sp-qone .qq{font-size:14.5px;font-weight:500}
.sp-qone .qh{font-size:12.5px;color:var(--faint);margin-top:2px}
.sp-note{
  margin-top:12px;font-size:13px;color:var(--warn);
  background:var(--warn-soft);border-radius:10px;padding:9px 12px;
}

/* ---------- 计时与录音 ---------- */
.sp-timer{
  display:flex;align-items:baseline;gap:10px;justify-content:center;
  padding:10px 0 4px;
}
.sp-tlabel{font-size:13px;color:var(--muted)}
.sp-tnum{
  font-size:34px;font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:-1px;
}

/* ---------- 回放 ---------- */
#playback{width:100%;margin:6px 0 8px}
.sp-audioinfo{font-size:13px;color:var(--muted)}

/* ---------- 报告 ---------- */
.sp-rhead{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:6px}
.sp-overall{display:flex;align-items:baseline;gap:10px;margin:6px 0 14px}
.sp-score b{font-size:40px;font-weight:600;line-height:1;letter-spacing:-1px}
.sp-score span{font-size:13px;color:var(--muted);margin-left:8px}
.sp-score.na b{color:var(--faint)}
.sp-dims{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:10px}
.sp-dim{border:1px solid var(--line);border-radius:11px;padding:11px 13px;background:var(--soft)}
.sp-dim.na{opacity:.62}
.sp-dimtop{display:flex;align-items:baseline;justify-content:space-between;gap:8px}
.sp-dimtop span{font-size:13px;color:var(--muted)}
.sp-dimtop b{font-size:20px;font-weight:600}
.sp-dim p{font-size:12.5px;color:var(--muted);margin-top:6px;line-height:1.6}
.sp-list{margin:0;padding-left:20px;font-size:13.5px;color:var(--muted)}
.sp-list li{margin:5px 0}
.sp-actions{margin:0;padding-left:22px;font-size:14px}
.sp-actions li{margin:8px 0}
.sp-issue{border:1px solid var(--line);border-radius:11px;padding:12px 14px;margin-bottom:10px;background:var(--soft)}
.sp-itop{display:flex;gap:8px;align-items:center;margin-bottom:6px}
.sp-kind{font-size:11.5px;padding:2px 8px;border-radius:20px;background:var(--accent-soft);color:var(--accent-ink)}
.sp-kind.grammar{background:var(--danger-soft);color:var(--danger)}
.sp-kind.lexical{background:var(--warn-soft);color:var(--warn)}
.sp-kind.pronunciation{background:var(--ok-soft);color:var(--ok)}
.sp-dimtag{font-size:11.5px;color:var(--faint)}
.sp-iquote{margin:4px 0;font-size:13.5px}
.sp-ifix{margin:4px 0;font-size:13.5px;color:var(--ok);font-weight:500}
.sp-iwhy{margin:4px 0;font-size:12.5px;color:var(--muted)}
.sp-trans{font-size:14px;line-height:1.8;white-space:pre-wrap}

/* ---------- 提示条 ---------- */
.sp-toast{
  position:fixed;left:50%;bottom:26px;transform:translate(-50%,20px);
  background:#1d2430;color:#fff;font-size:13.5px;padding:10px 16px;border-radius:10px;
  opacity:0;pointer-events:none;transition:opacity .2s, transform .2s;z-index:50;max-width:88vw;text-align:center;
}
.sp-toast.show{opacity:1;transform:translate(-50%,0)}

@media (max-width:520px){
  .sp-main{padding:10px}
  .sp-card{padding:14px;border-radius:12px}
  .sp-tnum{font-size:30px}
  .sp-score b{font-size:34px}
  .sp-dims{grid-template-columns:1fr 1fr}
}


/* =========================================================================
   影子跟读（2026-09-22）
   ========================================================================= */

/* ---------- 模式切换 ---------- */
/* 🔴 原来写死 repeat(5,1fr)：加第 6 个模式后每格只剩 ~114px，副标题被挤成三行。
   改成 auto-fit + minmax，由宽度决定列数（宽屏 3~4 列、窄屏 2 列），以后再加模式不用动这里。 */
.sp-modes{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(168px, 1fr)); gap:8px;
  max-width:720px; margin:12px auto 0; padding:0 14px;
}
.sp-mode{
  display:flex; flex-direction:column; gap:2px; align-items:flex-start;
  padding:10px 13px; border:1px solid var(--line); border-radius:12px;
  background:var(--panel); color:var(--ink); cursor:pointer; text-align:left;
  font:inherit; transition:border-color .15s, background .15s;
}
.sp-mode b{font-size:14px; font-weight:600}
.sp-mode span{font-size:11px; color:var(--faint)}
.sp-mode.on{border-color:var(--accent); background:var(--accent-soft)}
.sp-mode.on b{color:var(--accent-ink)}

/* ---------- 场景选择 ---------- */
.sp-pickrow{display:flex; gap:10px; flex-wrap:wrap; margin:10px 0 4px}
.sp-pick{display:flex; align-items:center; gap:6px; font-size:12px; color:var(--muted)}
.sp-pick select{
  font:inherit; font-size:13px; padding:6px 8px; border-radius:10px;
  border:1px solid var(--line); background:var(--soft); color:var(--ink);
}
.sp-scenes{display:flex; flex-direction:column; gap:7px; margin-top:10px; max-height:52vh; overflow:auto}
.sp-scene{
  display:flex; align-items:center; gap:10px; width:100%;
  padding:10px 12px; border:1px solid var(--line); border-radius:12px;
  background:var(--panel); color:var(--ink); cursor:pointer; text-align:left; font:inherit;
}@media (hover: hover) { .sp-scene:hover {border-color:var(--accent); background:var(--accent-soft)} }
@media (hover: none) { .sp-scene:active {border-color:var(--accent); background:var(--accent-soft)} }

.sp-sceneicon{font-size:19px; flex:none}
.sp-scenebody{display:flex; flex-direction:column; flex:1; min-width:0}
.sp-scenebody strong{font-size:14px; font-weight:600}
.sp-scenebody em{font-size:11px; color:var(--faint); font-style:normal}
.sp-scenego{font-size:12px; color:var(--accent-ink); flex:none}

/* ---------- 跟读句卡 ---------- */
.sp-shadowsent{padding:12px 0 4px}
.sp-sd-en{margin:0; font-size:21px; line-height:1.5; font-weight:600; letter-spacing:.1px; overflow-wrap:anywhere}
.sp-sd-cn{margin:6px 0 0; font-size:14px; color:var(--muted)}
.sp-sd-from{margin:6px 0 0; font-size:11px; color:var(--faint)}
.sp-chip.lv1{background:var(--ok-soft); color:var(--ok)}
.sp-chip.lv2{background:var(--warn-soft); color:var(--warn)}
.sp-chip.lv3{background:var(--danger-soft); color:var(--danger)}

/* ---------- 对比区 ---------- */
.sp-canvas{width:100%; height:120px; display:block; margin:6px 0 12px}
.sp-cmp{
  padding:9px 11px; border:1px solid var(--line); border-radius:11px;
  background:var(--soft); margin-bottom:7px;
}
.sp-cmp.ok{border-color:var(--ok); background:var(--ok-soft)}
.sp-cmp.warn{border-color:var(--warn); background:var(--warn-soft)}
.sp-cmptop{display:flex; justify-content:space-between; align-items:baseline; gap:8px}
.sp-cmptop span{font-size:12px; color:var(--muted)}
.sp-cmptop b{font-size:15px}
.sp-cmp p{margin:3px 0 0; font-size:12px; color:var(--muted); line-height:1.6}

/* ---------- 结算 ---------- */
.sp-kpis{display:grid; grid-template-columns:repeat(auto-fit,minmax(120px,1fr)); gap:9px; margin:10px 0}
.sp-kpi{
  display:flex; flex-direction:column; gap:2px; align-items:center;
  padding:13px 8px; border:1px solid var(--line); border-radius:12px; background:var(--soft);
}
.sp-kpi b{font-size:23px; line-height:1.1}
.sp-kpi span{font-size:11px; color:var(--faint); text-align:center}

@media (max-width:520px){
  .sp-sd-en{font-size:19px}
  .sp-scenes{max-height:none}
  /* 手机上排 2 列；**只有总数是单数时**最后一个才占满整行（否则它会孤零零剩一格）。
     🔴 原来写的是 `.sp-mode:last-child`：5 个模式时刚好对，加到 6 个模式就错了 ——
        第 6 项本来在偶数位（右列），却被强行拉成整行，白占一行（手机截图看出来）。
        「最后一个是单数位」要写 `:last-child:nth-child(odd)`。 */
  .sp-modes{grid-template-columns:repeat(2, 1fr)}
  .sp-mode:last-child:nth-child(odd){grid-column:1 / -1}
  .sp-mode span{display:none}
}

/* =========================================================================
   追问式模考（2026-09-22）：套卷列表 / 逐轮问答 / 本轮小结 / 整场小结
   ========================================================================= */

/* ---------- 套卷列表 ---------- */
.sp-sethead{padding:8px 2px 6px; font-size:12px; color:var(--faint)}
.sp-sethead b{color:var(--accent-ink)}
.sp-setitem{
  display:flex; align-items:center; gap:10px; width:100%;
  padding:9px 12px; margin-bottom:6px;
  border:1px solid var(--line); border-radius:11px;
  background:var(--panel); color:var(--ink); cursor:pointer; text-align:left; font:inherit;
  transition:border-color .15s, background .15s;
}@media (hover: hover) { .sp-setitem:hover {border-color:var(--accent); background:var(--accent-soft)} }
@media (hover: none) { .sp-setitem:active {border-color:var(--accent); background:var(--accent-soft)} }

.sp-setno{
  flex:none; min-width:24px; height:24px; padding:0 4px; border-radius:7px;
  display:flex; align-items:center; justify-content:center;
  background:var(--accent-soft); color:var(--accent-ink); font-size:12px; font-weight:600;
}
.sp-setbody{display:flex; flex-direction:column; flex:1; min-width:0}
.sp-setbody strong{font-size:14px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.sp-setbody em{font-size:11px; color:var(--faint); font-style:normal}
.sp-setgo{flex:none; color:var(--accent-ink); font-size:12px}

/* ---------- 逐轮问答 ---------- */
.sp-exname{font-size:11px; color:var(--faint); flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.sp-ghost.sm{padding:4px 9px; font-size:11px}
.sp-turnsent{padding:6px 0 10px}
.sp-turn-label{margin:0; font-size:11px; color:var(--faint); letter-spacing:.4px}
.sp-turn-q{margin:4px 0 0; font-size:20px; line-height:1.5; font-weight:600; overflow-wrap:anywhere}
.sp-turn-cn{margin:6px 0 0; font-size:13px; color:var(--muted)}
.sp-bullets{margin-top:10px; padding:9px 11px; border-radius:10px; background:var(--soft); border:1px solid var(--line)}
.sp-bullettitle{font-size:11px; color:var(--faint); margin-bottom:4px}
.sp-bullet{font-size:13px; color:var(--muted); line-height:1.7}
.sp-tip{
  margin:12px 0 0; padding:8px 11px; border-left:3px solid var(--accent);
  background:var(--accent-soft); border-radius:0 9px 9px 0;
  font-size:12.5px; color:var(--accent-ink); line-height:1.7;
}

/* ---------- 示范回答 ---------- */
.sp-model{margin-top:11px; padding:10px 12px; border:1px dashed var(--line); border-radius:11px; background:var(--soft)}
.sp-modeltitle{margin:0 0 7px; font-size:11px; color:var(--faint)}
.sp-modelrow{padding:7px 0; border-bottom:1px solid var(--line)}
.sp-modelrow:last-child{border-bottom:0; padding-bottom:0}
.sp-modelen{margin:0; font-size:14px; line-height:1.55}
.sp-modelcn{margin:3px 0 0; font-size:12px; color:var(--muted)}

/* ---------- 整场小结的逐轮条形 ---------- */
.sp-turnbars{margin:12px 0 4px}
.sp-tbar{display:flex; align-items:center; gap:8px; margin-bottom:5px}
.sp-tbarlab{flex:none; width:78px; font-size:11px; color:var(--muted); display:flex; gap:3px; align-items:baseline}
.sp-tbarlab i{font-style:normal; color:var(--faint)}
.sp-tbartrack{flex:1; height:9px; border-radius:5px; background:var(--line); overflow:hidden}
.sp-tbartrack i{display:block; height:100%; border-radius:5px; background:var(--wave-me)}
.sp-tbartrack i.bad{background:var(--warn)}
.sp-tbarval{flex:none; width:46px; text-align:right; font-size:11px; color:var(--faint)}
.sp-kind.ok{background:var(--ok-soft); color:var(--ok)}

@media (max-width:520px){
  .sp-turn-q{font-size:18px}
  .sp-tbarlab{width:64px}
  .sp-tbarval{width:42px}
}

/* =========================================================================
   易错本 + 一键回灌生词本（2026-09-22）
   ========================================================================= */

/* ---------- 分类筛选 ---------- */
.sp-chips{display:flex; flex-wrap:wrap; gap:6px; margin:10px 0 8px}
.sp-chips .chip{
  font:inherit; font-size:12px; padding:5px 10px; border-radius:999px;
  border:1px solid var(--line); background:var(--soft); color:var(--muted); cursor:pointer;
}@media (hover: hover) { .sp-chips .chip:hover {border-color:var(--accent)} }
@media (hover: none) { .sp-chips .chip:active {border-color:var(--accent)} }

.sp-chips .chip.active{background:var(--accent); border-color:var(--accent); color:#fff}
.sp-chips .chip-n{opacity:.7; margin-left:3px}

/* ---------- 易错条目 ---------- */
.sp-errlist{display:flex; flex-direction:column; gap:9px; margin-top:10px}
.sp-err{
  padding:11px 13px; border:1px solid var(--line); border-radius:12px; background:var(--panel);
}
.sp-errcat{
  display:inline-block; margin-bottom:6px; padding:2px 8px; border-radius:999px;
  font-size:11px; background:var(--accent-soft); color:var(--accent-ink);
}
.sp-errwrong, .sp-errright{margin:0; font-size:14px; line-height:1.6; display:flex; gap:7px}
.sp-errwrong{color:var(--danger)}
.sp-errright{color:var(--ok); margin-top:3px}
.sp-errwrong span, .sp-errright span{flex:none; font-weight:700}
.sp-errwhy{margin:6px 0 0; font-size:12.5px; color:var(--muted); line-height:1.7}
.sp-errkeys{display:flex; flex-wrap:wrap; gap:6px; margin-top:8px}

/* ---------- 一键加进生词本 ---------- */
.sp-addword{
  font:inherit; font-size:12px; padding:4px 10px; border-radius:999px;
  border:1px dashed var(--accent); background:transparent; color:var(--accent-ink); cursor:pointer;
  display:inline-flex; align-items:center; gap:6px;
}@media (hover: hover) { .sp-addword:hover {background:var(--accent-soft)} }
@media (hover: none) { .sp-addword:active {background:var(--accent-soft)} }

.sp-addword.on, .sp-addword:disabled{border-style:solid; border-color:var(--ok); color:var(--ok); background:var(--ok-soft); cursor:default}
.sp-addword.big{flex-direction:column; align-items:flex-start; border-style:solid; padding:8px 12px; gap:2px}
.sp-addword.big .sp-aw-en{font-size:14px}
.sp-addword.big i{font-style:normal; font-size:11.5px; color:var(--muted)}
.sp-addword em.ok{
  font-style:normal; font-size:10px; padding:1px 6px; border-radius:999px;
  background:var(--ok-soft); color:var(--ok); border:1px solid var(--ok);
}
.sp-vocab{display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:7px; margin-top:10px}

/* ---------- 题卡里的「这题最容易踩的坑」 ---------- */
.sp-tips{margin-top:12px; border-top:1px dashed var(--line); padding-top:10px}
.sp-tipstitle{margin:0 0 7px; font-size:12px; color:var(--warn); font-weight:600}
.sp-tips .sp-err{background:var(--soft); margin-bottom:7px; padding:9px 11px}
.sp-tips .sp-errwrong, .sp-tips .sp-errright{font-size:13.5px}

/* ---------- 「这一轮想记住哪个词」 ---------- */
.sp-capture{margin-top:12px; padding:10px 12px; border:1px solid var(--line); border-radius:11px; background:var(--soft)}
.sp-capturetitle{margin:0 0 7px; font-size:12.5px; color:var(--ink)}
.sp-capturerow{display:flex; gap:6px; flex-wrap:wrap}
.sp-capturerow input{
  font:inherit; font-size:13px; padding:7px 10px; border-radius:9px;
  border:1px solid var(--line); background:var(--panel); color:var(--ink); min-width:0; flex:1 1 120px;
}
.sp-capturerow input:focus{outline:none; border-color:var(--accent)}
.sp-btn.sm{font-size:12.5px; padding:7px 12px}

@media (max-width:520px){
  .sp-vocab{grid-template-columns:1fr 1fr}
  .sp-modes{gap:6px}
  .sp-mode{padding:8px 10px}
}

/* 易错点：与本题相关的标记 + 副标题 */
.sp-tipsub{display:block; margin-top:3px; font-size:11px; font-weight:400; color:var(--faint)}
.sp-rel{
  display:inline-block; margin:0 0 6px 6px; padding:2px 7px; border-radius:999px;
  font-size:10.5px; background:var(--warn-soft); color:var(--warn); border:1px solid var(--warn);
}

/* =========================================================================
   发音训练（2026-09-23）：最小对立对 / 口型示意图 / 听辨小测
   ========================================================================= */

/* ---------- 卡片列表 ---------- */
.sp-sounds{display:flex; flex-direction:column; gap:7px; margin-top:10px}
.sp-sound{
  display:flex; align-items:center; gap:10px; width:100%;
  padding:10px 12px; border:1px solid var(--line); border-radius:12px;
  background:var(--panel); color:var(--ink); cursor:pointer; text-align:left; font:inherit;
  transition:border-color .15s, background .15s;
}@media (hover: hover) { .sp-sound:hover {border-color:var(--accent); background:var(--accent-soft)} }
@media (hover: none) { .sp-sound:active {border-color:var(--accent); background:var(--accent-soft)} }

.sp-soundipa{
  flex:none; min-width:56px; padding:4px 6px; border-radius:8px; text-align:center;
  background:var(--accent-soft); color:var(--accent-ink);
  font-size:13px; font-weight:600; letter-spacing:.2px;
}
.sp-soundbody{display:flex; flex-direction:column; flex:1; min-width:0}
.sp-soundbody strong{font-size:14px; font-weight:600}
.sp-soundbody em{font-size:11.5px; color:var(--faint); font-style:normal; line-height:1.5}
.sp-soundbadge{
  flex:none; padding:2px 7px; border-radius:999px; font-size:10.5px;
  background:var(--danger-soft); color:var(--danger); border:1px solid var(--danger);
}
.sp-soundok{
  flex:none; padding:2px 7px; border-radius:999px; font-size:10.5px;
  background:var(--ok-soft); color:var(--ok); border:1px solid var(--ok);
}

/* ---------- 通用小块 ---------- */
.sp-pr-block{margin-top:14px; padding-top:12px; border-top:1px dashed var(--line)}
.sp-pr-block:first-child{border-top:0; padding-top:0; margin-top:0}
.sp-pr-h{margin:0 0 7px; font-size:12.5px; font-weight:600; color:var(--accent-ink)}
.sp-pr-oneline{margin:6px 0 0; font-size:14px; color:var(--muted); line-height:1.65}
.sp-pr-why{margin:0; font-size:13.5px; color:var(--muted); line-height:1.8}
.sp-pr-why b, .sp-pr-how b, .sp-pr-result b{color:var(--ink)}
.sp-pr-how{margin:0; padding-left:20px}
.sp-pr-how li{font-size:13.5px; color:var(--muted); line-height:1.8; margin-bottom:6px}
.sp-pr-self{margin:0; padding-left:20px}
.sp-pr-self li{font-size:13px; color:var(--muted); line-height:1.75; margin-bottom:5px}
.sp-pr-sent{margin:4px 0 0; font-size:19px; line-height:1.55; font-weight:600; overflow-wrap:anywhere}
.sp-pr-sentcn{margin:4px 0 0; font-size:13px; color:var(--muted)}
.sp-tiny.warn{color:var(--warn)}
.sp-card.inner{
  margin-top:12px; background:var(--soft); border-style:dashed;
}
.sp-kpis.small{margin:8px 0}
.sp-kpis.small .sp-kpi{padding:9px 6px}
.sp-kpis.small .sp-kpi b{font-size:18px}

/* ---------- 小号 chip ---------- */
.sp-chips.small .chip{font-size:11.5px; padding:4px 9px}
.sp-chips .chip.plain{background:var(--soft); color:var(--muted); border-color:var(--line)}
.sp-chips .chip.warn{background:var(--warn-soft); color:var(--warn); border-color:var(--warn)}

/* ---------- 口型示意图 ---------- */
.sp-mouths{display:grid; grid-template-columns:1fr 1fr; gap:12px}
.sp-mouths > :only-child{grid-column:1 / -1}
.pr-mouthfig{
  margin:0; padding:10px 10px 8px; border:1px solid var(--line); border-radius:12px; background:var(--soft);
}
.pr-mouthlab{margin:0 0 6px; font-size:12px; font-weight:600; color:var(--accent-ink)}
.pr-mouthsvg{width:100%; height:auto; display:block; max-width:260px; margin:0 auto}
.pr-mouthcap{margin:7px 0 0; font-size:11.5px; color:var(--muted); line-height:1.65}
.pr-head{stroke:var(--faint)}
.pr-palate{stroke:var(--muted)}
.pr-tooth{fill:var(--panel); stroke:var(--muted); stroke-width:1}
.pr-tongue{stroke:var(--warn); opacity:.32}
.pr-tonguetip{fill:var(--warn); stroke:var(--panel); stroke-width:1.2}
/* 唇齿接触点：标出「上齿碰到下唇」这个唯一的关键动作 */
.pr-contact{fill:var(--danger); stroke:var(--panel); stroke-width:1}
.pr-lip{stroke:var(--ink); opacity:.85}
.pr-air{stroke:var(--wave-ref); fill:none}
.pr-airfill{fill:var(--wave-ref)}
.pr-voice{stroke:var(--ok)}
.pr-novoice{fill:var(--muted)}
.pr-svglab{fill:var(--faint); font-size:9.5px; font-family:inherit}

/* ---------- 节奏示意（规则课） ---------- */
.pr-prow{
  display:flex; align-items:baseline; gap:8px; flex-wrap:wrap;
  padding:8px 11px; border-radius:10px; margin-bottom:6px;
  border:1px solid var(--line); background:var(--soft);
}
.pr-prow.bad{border-color:var(--danger); background:var(--danger-soft)}
.pr-prow.ok{border-color:var(--ok); background:var(--ok-soft)}
.pr-pmark{flex:none; font-weight:700; font-size:13px}
.pr-prow.bad .pr-pmark{color:var(--danger)}
.pr-prow.ok .pr-pmark{color:var(--ok)}
.pr-prow b{font-size:15px; letter-spacing:.3px}
.pr-prow span:last-child{font-size:11.5px; color:var(--muted); flex:1 1 100%}

/* ---------- 对立对 / 示范短语 ---------- */
.pr-drill{display:flex; flex-direction:column; gap:6px}
.pr-pair{display:flex; align-items:center; gap:6px; flex-wrap:wrap}
.pr-pairno{
  flex:none; width:20px; text-align:center; font-size:11px; color:var(--faint);
}
.pr-demo{display:flex; align-items:flex-start; gap:8px; padding:4px 0}
.pr-demobody{display:flex; flex-direction:column; min-width:0}
.pr-demobody b{font-size:13px; font-weight:500}
.pr-demobody em{font-size:11.5px; color:var(--faint); font-style:normal}

/* ---------- 听辨小测 ---------- */
.pr-quiz{margin-top:4px; padding:11px 12px; border:1px solid var(--line); border-radius:12px; background:var(--soft)}
.pr-quizbar{display:flex; justify-content:space-between; align-items:baseline; font-size:12px; color:var(--muted)}
.pr-quizscore{color:var(--accent-ink); font-weight:600}
.pr-quizactions{display:flex; gap:6px; flex-wrap:wrap; margin-top:9px}
.pr-quizbody{margin-top:10px}
.pr-quizask{margin:0 0 8px; font-size:13.5px}
.pr-quizopts{display:flex; gap:8px; flex-wrap:wrap}
.pr-quizopt{
  flex:1 1 130px; justify-content:center; font-size:15px; padding:11px 12px;
}
.pr-quizopt.right{border-color:var(--ok); background:var(--ok-soft); color:var(--ok); font-weight:700}
.pr-quizopt.wrong{border-color:var(--danger); background:var(--danger-soft); color:var(--danger)}
.pr-quizfeed{margin:9px 0 0; font-size:12.5px; line-height:1.7; min-height:1.2em}
.pr-quizfeed.ok{color:var(--ok)}
.pr-quizfeed.bad{color:var(--danger)}
.pr-quizresult{text-align:center; padding:6px 0}
.pr-quizbig{font-size:30px; font-weight:700; color:var(--accent-ink); line-height:1.1}
.pr-quizresult.ok .pr-quizbig{color:var(--ok)}
.pr-quizresult p{margin:8px 0 0; font-size:13px; color:var(--muted); line-height:1.75}
.pr-quizresult .sp-chips{justify-content:center; margin-top:10px}

@media (max-width:520px){
  .sp-mouths{grid-template-columns:1fr}
  .sp-pr-sent{font-size:17px}
  .pr-quizopt{flex:1 1 100%}
}

/* =========================================================================
   AI 角色扮演（2026-09-23）：剧本列表 / 对话气泡 / 参考说法
   ========================================================================= */

/* ---------- 剧本列表 ---------- */
.sp-scripts{display:flex; flex-direction:column; gap:6px; margin-top:10px}
.sp-script{
  display:flex; align-items:center; gap:10px; width:100%;
  padding:10px 12px; border:1px solid var(--line); border-radius:12px;
  background:var(--panel); color:var(--ink); cursor:pointer; text-align:left; font:inherit;
  transition:border-color .15s, background .15s;
}@media (hover: hover) { .sp-script:hover {border-color:var(--accent); background:var(--accent-soft)} }
@media (hover: none) { .sp-script:active {border-color:var(--accent); background:var(--accent-soft)} }

.sp-scripticon{flex:none; font-size:18px}
.sp-scriptbody{display:flex; flex-direction:column; flex:1; min-width:0}
.sp-scriptbody strong{font-size:14px; font-weight:600}
.sp-scriptbody em{font-size:11.5px; color:var(--faint); font-style:normal; line-height:1.5}
.sp-scriptbody em.opener{color:var(--muted)}
.sp-scriptok{flex:none; font-size:13px; color:var(--accent-ink)}

/* ---------- 对话气泡 ---------- */
.rp-chat{
  display:flex; flex-direction:column; gap:9px;
  max-height:46vh; overflow-y:auto; padding:12px 10px; margin:10px 0;
  border:1px solid var(--line); border-radius:12px; background:var(--soft);
}
.rp-row{display:flex}
.rp-row.ai{justify-content:flex-start}
.rp-row.me{justify-content:flex-end}
.rp-bubble{
  max-width:82%; padding:9px 12px; border-radius:12px;
  border:1px solid var(--line); background:var(--panel);
}
.rp-bubble.ai{border-bottom-left-radius:3px; border-color:var(--wave-ref); background:var(--accent-soft)}
.rp-bubble.me{border-bottom-right-radius:3px; border-color:var(--wave-me); background:var(--ok-soft)}
.rp-bubble.miss{opacity:.72; border-style:dashed; border-color:var(--danger)}
.rp-bubble.pending{background:transparent; border-style:dashed; color:var(--muted); font-size:12.5px}
.rp-en{margin:0; font-size:14.5px; line-height:1.55; overflow-wrap:anywhere}
.rp-cn{margin:4px 0 0; font-size:12px; color:var(--muted); line-height:1.5}
.rp-tiny{margin:3px 0 0; font-size:11px; color:var(--faint)}
.rp-replay{
  margin-top:7px; font:inherit; font-size:11.5px; padding:3px 9px; border-radius:999px;
  border:1px solid var(--line); background:var(--panel); color:var(--accent-ink); cursor:pointer;
}@media (hover: hover) { .rp-replay:hover {border-color:var(--accent)} }
@media (hover: none) { .rp-replay:active {border-color:var(--accent)} }

/* 「等你接话」的三个跳点 */
.rp-dots{display:inline-flex; gap:3px; vertical-align:middle; margin-right:5px}
.rp-dots i{
  width:5px; height:5px; border-radius:50%; background:var(--muted);
  animation:rpdot 1.1s infinite ease-in-out;
}
.rp-dots i:nth-child(2){animation-delay:.18s}
.rp-dots i:nth-child(3){animation-delay:.36s}
@keyframes rpdot{0%,80%,100%{opacity:.25; transform:translateY(0)}40%{opacity:1; transform:translateY(-2px)}}

/* ---------- 参考说法 ---------- */
.rp-hintbox{
  margin:8px 0; padding:10px 12px; border-radius:11px;
  border:1px dashed var(--warn); background:var(--warn-soft);
}
.rp-hintlab{margin:0 0 5px; font-size:11.5px; color:var(--warn)}
.rp-hinten{margin:0; font-size:15.5px; line-height:1.55; font-weight:600; overflow-wrap:anywhere}
.rp-hintcn{margin:4px 0 0; font-size:12.5px; color:var(--muted)}

.rp-refs{display:flex; flex-direction:column; gap:7px; margin-top:8px}
.rp-ref{padding:9px 11px; border:1px solid var(--line); border-radius:11px; background:var(--soft)}
.rp-ref.ok{border-left:3px solid var(--ok)}
.rp-ref.hint{border-left:3px solid var(--warn)}
.rp-ref.miss, .rp-ref.skip{border-left:3px solid var(--danger)}
.rp-refctx{margin:0 0 5px; font-size:11.5px; color:var(--faint)}
.rp-refen{margin:0; font-size:14.5px; line-height:1.55; overflow-wrap:anywhere}
.rp-refcn{margin:3px 0 0; font-size:12.5px; color:var(--muted)}

@media (max-width:520px){
  .rp-chat{max-height:40vh}
  .rp-bubble{max-width:90%}
  .sp-scriptbody em.opener{display:none}
}

/* =========================================================================
   每日 3 分钟微练习 + 打卡（2026-09-23）
   设计约束：这是「每天都要做一遍」的界面，所以信息密度要低、
   主按钮要大、一眼能看见连续天数 —— 别让人在第二屏才找到开始按钮。
   ========================================================================= */

/* ---------- 四个统计数 ---------- */
.dk-stats{display:grid; grid-template-columns:repeat(4, 1fr); gap:8px; margin:12px 0}
.dk-stat{
  border:1px solid var(--line); border-radius:11px; padding:9px 6px;
  background:var(--soft); text-align:center;
}
.dk-stat b{display:block; font-size:20px; font-weight:600; line-height:1.2}
.dk-stat span{display:block; font-size:11px; color:var(--faint); margin-top:2px}
.dk-today{
  margin:12px 0 0; padding:9px 12px; border-radius:10px;
  background:var(--accent-soft); color:var(--accent-ink); font-size:13px;
}

/* ---------- 今日五步清单 ---------- */
.dk-planlab{margin:14px 0 6px; font-size:12px; color:var(--faint)}
.dk-plan{display:flex; flex-direction:column; gap:5px}
.dk-planitem{
  display:flex; align-items:center; gap:8px;
  padding:7px 11px; border:1px solid var(--line); border-radius:10px; background:var(--soft);
}
.dk-planitem span{font-size:15px; flex:none}
.dk-planitem b{font-size:13px; font-weight:600; flex:none}
.dk-planitem em{font-size:11.5px; color:var(--faint); font-style:normal; margin-left:auto; text-align:right}

/* ---------- 打卡日历（近 12 周，周一起） ----------
   第一版格子只有 13px，整块 190px 宽，在 700px 的卡片里像个小补丁（看截图才发现）。
   放大到 16px + gap 4px，并补一个「少→多」图例 —— 不然光看深浅不知道代表什么。 */
.dk-cal{margin:12px 0 6px}
.dk-calrow{display:flex; gap:4px; overflow-x:auto; padding-bottom:2px}
.dk-week{display:grid; grid-template-rows:repeat(7, 1fr); gap:4px}
.dk-legend{display:flex; align-items:center; gap:5px; margin-top:9px; font-size:11px; color:var(--faint)}
.dk-legend i{display:block}
.dk-cell{
  width:16px; height:16px; border-radius:4px; background:var(--line); display:block;
}
.dk-cell.none{background:var(--line); opacity:.55}
.dk-cell.lv1{background:var(--accent); opacity:.34}
.dk-cell.lv2{background:var(--accent); opacity:.67}
.dk-cell.lv3{background:var(--accent)}
.dk-cell.future{background:transparent; border:1px dashed var(--line)}
.dk-cell.today{box-shadow:0 0 0 2px var(--warn)}

/* ---------- 练习中 ---------- */
.dk-dots{display:inline-flex; gap:5px; align-items:center; margin-left:auto}
.dk-dot{
  width:7px; height:7px; border-radius:50%; background:var(--line); display:block;
}
.dk-dot.done{background:var(--accent); opacity:.45}
.dk-dot.on{background:var(--accent)}
.dk-busy{
  width:7px; height:7px; border-radius:50%; background:var(--accent);
  display:inline-block; margin-right:6px; animation:dkpulse 1s infinite ease-in-out;
}
@keyframes dkpulse{0%,100%{opacity:.3}50%{opacity:1}}

.dk-en{margin:6px 0 0; font-size:20px; line-height:1.5; font-weight:600; overflow-wrap:anywhere}
.dk-en.sm{font-size:16px}
.dk-cn{margin:5px 0 0; font-size:13.5px; color:var(--muted)}
.dk-from{margin:8px 0 0; font-size:11.5px; color:var(--faint)}
.dk-scene{margin:6px 0 0; font-size:13px; color:var(--accent-ink); font-weight:600}
.dk-label{margin:10px 0 4px; font-size:12px; color:var(--faint)}
.dk-wrong{margin:0; font-size:17px; font-weight:600; color:var(--danger); overflow-wrap:anywhere}
.dk-right{margin:6px 0 0; font-size:15px; font-weight:600; color:var(--ok); overflow-wrap:anywhere}
.dk-why{margin:4px 0 0; font-size:12.5px; color:var(--muted); line-height:1.65}
.dk-topic{margin:4px 0 0; font-size:18px; font-weight:600; overflow-wrap:anywhere}
.dk-quizask{margin:6px 0 8px; font-size:14px; color:var(--muted)}
.dk-src{margin:10px 0 0; font-size:11px; color:var(--faint)}

/* 选项（听辨 / 改错共用） */
.dk-opts{display:flex; flex-direction:column; gap:7px; margin:6px 0 0}
.dk-opt{justify-content:flex-start; text-align:left; font-size:15px; padding:11px 14px}
.dk-opt.right{border-color:var(--ok); background:var(--ok-soft); color:var(--ok); font-weight:600}
.dk-opt.wrong{border-color:var(--danger); background:var(--danger-soft); color:var(--danger)}
.dk-feed{margin:9px 0 0; font-size:12.5px; min-height:18px}
.dk-feed.ok{color:var(--ok)}
.dk-feed.bad{color:var(--danger)}

/* 结果小条 */
.dk-res{
  margin:12px 0 0; padding:9px 12px; border-radius:10px;
  background:var(--soft); border:1px solid var(--line); font-size:13px; color:var(--muted);
}
.dk-res b{color:var(--ink); font-size:15px}
.dk-tip{
  margin:8px 0 0; padding:9px 12px; border-left:3px solid var(--warn);
  background:var(--warn-soft); font-size:12.5px; color:var(--ink); line-height:1.65;
}
.dk-ref{margin:10px 0 0; padding:9px 12px; border:1px dashed var(--line); border-radius:10px}
.dk-keys{display:flex; flex-wrap:wrap; gap:6px; margin-top:8px}

/* 完成页「今天带走的」 */
.dk-take{margin:4px 0 8px; font-size:17px; font-weight:600; overflow-wrap:anywhere}
.dk-take span{display:block; font-size:13px; font-weight:400; color:var(--muted); margin-top:3px}

@media (max-width:520px){
  .dk-stats{grid-template-columns:repeat(2, 1fr)}
  .dk-en{font-size:18px}
  .dk-cell{width:13px; height:13px}
  .dk-planitem em{display:none}
  .dk-legend span:last-child{display:none}
}

/* 完成页的「复制这句话」预览：用强调色块，不要跟 ⚠️ 警告框（sp-note）混在一起 */
.dk-share{
  margin:0; padding:10px 13px; border-radius:11px;
  background:var(--accent-soft); color:var(--accent-ink);
  font-size:13.5px; line-height:1.7;
}


/* =========================================================================
   安全区兜底（2026-10-06 安卓兼容性体检）
   -------------------------------------------------------------------------
   与首页 index.html 对齐后，本页开启了 `viewport-fit=cover` —— 这个声明等于
   向浏览器承诺「我自己兜安全区」。**只声明不兜兜，比不声明更糟**：
   刘海屏上顶栏会钻到状态栏底下、底部内容被手势条压住。
   所以这里补 env() 兜底，与声明成对。

   🔴 写法沿用项目里「dvh 补 vh」的兜底思路：旧浏览器不认识 env()，会**整条丢弃**
      下面这两条声明 → 上面原有的 padding 仍然生效，布局不会塌。
   env() 在非刘海 / 非全屏环境恒为 0 ⇒ 普通手机上这两条是空操作，无副作用。
   ========================================================================= */
.sp-top{
  padding-top:calc(10px + env(safe-area-inset-top, 0px));
  padding-left:calc(14px + env(safe-area-inset-left, 0px));
  padding-right:calc(14px + env(safe-area-inset-right, 0px));
}
body{
  padding-bottom:calc(40px + env(safe-area-inset-bottom, 0px));
}

/* =========================================================================
   AI 语法批改 modal（2026-10-30 新增，speaking.html 专用）
   复用页面已有类：sp-card / sp-btn / sp-row / sp-meter / sp-micstate /
   sp-note / sp-tiny / sp-ghost。这里只新增 modal 外壳与结果区样式。
   ========================================================================= */
.air-modal{
  position:fixed; inset:0; z-index:2000; display:none;
  align-items:center; justify-content:center;
  background:rgba(0,0,0,.5); padding:18px;
  padding-top:calc(18px + env(safe-area-inset-top,0px));
  padding-bottom:calc(18px + env(safe-area-inset-bottom,0px));
}
.air-modal.show{ display:flex; }
.air-sheet{
  width:100%; max-width:560px; max-height:88vh; display:flex; flex-direction:column;
  background:var(--card,#fff); color:var(--ink,#222);
  border-radius:16px; box-shadow:0 18px 50px rgba(0,0,0,.28); overflow:hidden;
}
.air-head{
  display:flex; align-items:center; justify-content:space-between;
  padding:14px 16px; border-bottom:1px solid var(--line,#eee);
  font-size:16px; font-weight:700;
}
.air-scroll{ overflow-y:auto; padding:14px 16px 18px; -webkit-overflow-scrolling:touch; }
.air-lbl{ display:block; font-size:13px; color:var(--muted,#888); margin:2px 0 6px; }
.air-input{
  width:100%; box-sizing:border-box; padding:9px 11px; margin-bottom:12px;
  border:1px solid var(--line,#e2e2e2); border-radius:10px;
  background:var(--bg,#fff); color:var(--ink,#222); font-size:14px;
}
.air-rec{ margin-bottom:14px; }
.air-trans{
  margin:6px 0 0; padding:10px 12px; border-radius:10px;
  background:var(--bg,#f6f8fa); color:var(--ink,#222); font-size:14px; line-height:1.7;
}
.air-sec{ margin:16px 0 4px; font-size:14px; font-weight:700; }
.air-issue, .air-sugg{
  border:1px solid var(--line,#eee); border-radius:12px; padding:11px 12px; margin:9px 0;
  background:var(--bg,#fafbfc);
}
.air-tag{
  display:inline-block; font-size:11px; font-weight:700; padding:2px 8px; border-radius:999px; margin-bottom:7px;
}
.air-tag.must{ background:#fdecea; color:#c0392b; }
.air-tag.suggest{ background:var(--accent-soft,#e7f1fb); color:var(--accent-ink,#1f6fb2); }
.air-line{ font-size:14.5px; line-height:1.7; }
.air-x{ color:#c0392b; background:#fdecea; padding:1px 5px; border-radius:6px; }
.air-f{ color:#1a9e5a; background:#e7f7ee; padding:1px 5px; border-radius:6px; }
.air-sugg .air-alt{ color:#1a9e5a; font-weight:600; }
.air-add{ margin-top:8px; }
.air-actions{ margin:6px 0 0; padding-left:20px; }
.air-actions li{ margin:4px 0; font-size:14px; }
.air-priv{ margin-top:10px; }
