/* ============ 汉语伙伴 · Mandarin Buddy ============ */
* { margin: 0; padding: 0; box-sizing: border-box; }

/* HTML hidden 属性必须始终生效（防止被 display:grid/flex 覆盖） */
[hidden] { display: none !important; }

:root {
  --red: #b23a48;
  --red-deep: #8c2f39;
  --red-dark: #6a222a;
  --ink: #2e2a26;
  --ink-soft: #6f675f;
  --paper: #faf6ef;
  --paper-warm: #f3ede2;
  --line: #e8e0d3;
  --gold: #d9a441;
  --green: #3e8e5a;
  --shadow: 0 2px 10px rgba(80, 55, 40, .08);

  /* 全面屏安全区（刘海 / 底部手势条）。取不到值时回退 0px，
     所以桌面端与非全面屏手机的表现和没有这几个变量时完全一致。 */
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
}

html, body { height: 100%; }

body {
  /* 字体栈中文优先（教师反馈 2026-10-08）：原顺序 "Segoe UI" 在首，DC 课的
     英文/拼音渲染成 Segoe UI（电脑）/ Roboto（手机），而 NPCR 课的汉字走
     雅黑 / Noto Sans CJK —— 两边观感不一致。中文字体提到最前后，全 app
     （DC 课卡片 / Settings 面板 / 底部按钮）的拉丁字形也走中文字体，
     与 NPCR 1 统一。Windows→雅黑、Android→Noto Sans SC、iOS→PingFang SC。 */
  font-family: "PingFang SC", "Noto Sans SC", "Microsoft YaHei", "Segoe UI", sans-serif;
  background: var(--paper);
  color: var(--ink);
  overflow: hidden;
}

.app {
  display: flex;
  height: 100vh;    /* 回退：老浏览器不认 dvh */
  height: 100dvh;   /* 手机地址栏伸缩 / 键盘弹出时跟着实际可视高度变，否则输入框会被顶出屏幕 */
  max-width: 1200px;
  margin: 0 auto;
}

/* ============ Sidebar ============ */
.sidebar {
  width: 280px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  background: linear-gradient(170deg, var(--red-deep) 0%, var(--red-dark) 100%);
  color: #f6e9e2;
  padding: 22px 18px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 26px;
}

.brand-mark {
  width: 46px; height: 46px;
  display: grid; place-items: center;
  background: #f6e9e2;
  color: var(--red-deep);
  font-size: 24px;
  font-weight: 700;
  border-radius: 12px;
  box-shadow: inset 0 0 0 2px rgba(138, 47, 57, .25);
}

.brand-name { font-size: 19px; font-weight: 700; letter-spacing: 1px; }
.brand-sub  { font-size: 12px; opacity: .7; letter-spacing: .5px; }

.steps-title {
  font-size: 11.5px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  opacity: .6;
  margin: 0 12px 6px;
}
.steps-title em { font-style: normal; letter-spacing: .5px; }

.steps {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 12px;
  background: rgba(0,0,0,.16);
  border-radius: 14px;
  margin-bottom: 22px;
}

.step {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 8px;
  border-radius: 10px;
  font-size: 13.5px;
  opacity: .55;
  transition: all .25s;
  /* 四步是可点按钮：去掉浏览器默认样式，整行可点（点击 = 跳到该环节） */
  width: 100%;
  border: 0;
  background: transparent;
  color: inherit;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.step:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; opacity: 1; }

.step em { font-style: normal; font-size: 11px; opacity: .7; margin-left: 2px; pointer-events: none; }

.step-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: rgba(255,255,255,.35);
  transition: all .25s;
  flex-shrink: 0;
  pointer-events: none;
}

.step.active { opacity: 1; background: rgba(255,255,255,.12); }
.step.active .step-dot { background: var(--gold); box-shadow: 0 0 0 4px rgba(217,164,65,.25); }
.step.done   { opacity: .85; }
.step.done .step-dot { background: #9fd4a8; }

/* MD7.5：滚动职责从 .lessons 上移到 .lessons-scroll —— DC1 + NPCR 全部轨道组
   共用一个滚动容器，课再多也不越过侧栏边界（R0 溢出修复） */
.lessons-scroll {
  flex: 1;
  min-height: 0;          /* flex 子项默认 min-height:auto 会撑破 overflow，必须归零 */
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-right: 2px;
}

.lessons {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.lessons-scroll::-webkit-scrollbar { width: 5px; }
.lessons-scroll::-webkit-scrollbar-thumb { background: rgba(255,255,255,.2); border-radius: 3px; }

/* MD8.2（simplify-course-nav）：「Lessons 课本」折叠按钮已删 ——
   .lessons-scroll 常驻（不再有 lessons-open 收起态），课再多在容器里滚 */
.lesson-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 12px;
  background: rgba(255,255,255,.07);
  border: 1px solid rgba(255,255,255,.08);
  border-radius: 12px;
  color: #f6e9e2;
  /* 字体统一（教师反馈 2026-10-08）：DC 课按钮字号对齐 NPCR 的 .npcr-lesson-btn
     （12.5px），三档一致；侧栏课列表不是主要教学内容，走紧凑口径 */
  font-size: 12.5px;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: all .2s;
}

.lesson-btn:hover { background: rgba(255,255,255,.14); transform: translateX(2px); }
.lesson-btn.current { background: #f6e9e2; color: var(--red-dark); font-weight: 600; border-color: transparent; }

.lesson-num {
  width: 24px; height: 24px;
  display: grid; place-items: center;
  border-radius: 6px;
  background: rgba(0,0,0,.18);
  font-size: 11px;
  font-weight: 700;
  flex-shrink: 0;
}

.lesson-btn.current .lesson-num { background: var(--red-deep); color: #fff; }

/* 加练课（U1+ / U2+）的标号比 U1 多一个字符，宽度自动放宽 */
.lesson-num.plus {
  width: auto;
  min-width: 22px;
  padding: 0 4px;
}

.lesson-done {
  margin-left: auto;
  color: #9fd4a8;
  font-size: 13px;
  font-weight: 700;
}

.sidebar-footer {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 16px;
}

.footer-row { display: flex; gap: 8px; width: 100%; }
.footer-row .ghost-btn { flex: 1; white-space: nowrap; }

/* 版本号 + 「有新版本」按钮（桌面版排查更新用） */
.footer-ver {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 2px 0 0;
  font-size: 10.5px;
  color: rgba(246,233,226,.55);
  letter-spacing: .3px;
}
.footer-ver b { color: rgba(246,233,226,.9); font-weight: 700; }
.footer-ver .ghost-btn {
  flex: 0 0 auto;
  padding: 5px 8px;
  font-size: 10.5px;
  background: rgba(178,58,72,.55);
  border-color: rgba(255,255,255,.3);
  color: #fff;
}

.ghost-btn.wide { width: 100%; }

.ghost-btn {
  flex: 1;
  padding: 8px 6px;
  background: rgba(255,255,255,.08);
  border: 1px solid rgba(255,255,255,.14);
  border-radius: 10px;
  color: #f6e9e2;
  font-size: 11.5px;
  cursor: pointer;
  font-family: inherit;
  transition: background .2s;
}

.ghost-btn:hover { background: rgba(255,255,255,.16); }

/* ============ Chat ============ */
.chat {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.chat-header {
  padding: 16px 28px;
  background: rgba(255,255,255,.75);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.header-right { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

#currentLesson { font-size: 16px; font-weight: 700; color: var(--red-deep); }
.chat-sub { font-size: 12.5px; color: var(--ink-soft); }

/* 移动端左上角菜单按钮（默认隐藏） */
/* v131：标题列两行（当前课 / 当前阶段）—— 阶段行原来挂在按钮区当第四个元素，
   手机上换行会把聊天区整个压下去 */
.chat-title-row { display: flex; align-items: center; gap: 10px; min-width: 0; }
.chat-title-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }

.menu-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 38px; height: 38px;
  border: 1.5px solid var(--line);
  border-radius: 11px;
  background: #fff;
  color: var(--red-deep);
  cursor: pointer;
  flex-shrink: 0;
  transition: all .18s;
}
.menu-toggle:hover { border-color: var(--red); color: var(--red); }

.messages {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;   /* 滑到底不再带着整页回弹（手机上下拉会误触发刷新） */
  padding: 26px 28px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  scroll-behavior: smooth;
}

.messages::-webkit-scrollbar { width: 7px; }
.messages::-webkit-scrollbar-thumb { background: #d8cfc0; border-radius: 4px; }

.msg { display: flex; gap: 10px; max-width: 82%; animation: rise .3s ease; }
@keyframes rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* v66：环节分隔线——上一段活动（闪卡 / 配对 / 跟读 / 对话 / 练习 / 错题）做完，
   下一段内容出现前先画一条线，主聊天流里各环节界限分明 */
.stage-divider {
  align-self: stretch;
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 18px 0 6px;
  animation: rise .3s ease;
}
.stage-divider::before,
.stage-divider::after {
  content: '';
  flex: 1;
  border-top: 2px dashed rgba(122, 32, 43, .22);
  border-radius: 2px;
}
.stage-divider i {
  font-style: normal;
  font-size: 11px;
  letter-spacing: 2px;
  opacity: .45;
}

.msg.bot { align-self: flex-start; }
.msg.user { align-self: flex-end; flex-direction: row-reverse; }

.avatar {
  width: 36px; height: 36px;
  border-radius: 12px;
  flex-shrink: 0;
  display: grid; place-items: center;
  font-size: 16px;
  font-weight: 700;
  margin-top: 2px;
}

.msg.bot .avatar { background: linear-gradient(140deg, var(--red), var(--red-dark)); color: #f6e9e2; }
.msg.user .avatar { background: #fff; color: var(--red-deep); border: 1.5px solid var(--line); }

/* v144（cap-course-typography，教师反馈 2026-10-08）：课程内容字号 12.5px 封顶
   （对齐侧栏课菜单），重点行用粗体（≥700）不再放大字号 */
.bubble {
  padding: 12px 16px;
  border-radius: 16px;
  font-size: 12.5px;
  line-height: 1.65;
  box-shadow: var(--shadow);
  min-width: 60px;
}

.msg.bot .bubble { background: #fff; border: 1px solid var(--line); border-top-left-radius: 4px; }
.msg.user .bubble { background: linear-gradient(140deg, var(--red), var(--red-deep)); color: #fff; border-top-right-radius: 4px; }

.bubble .zh { font-size: 12.5px; font-weight: 700; letter-spacing: .3px; }

/* v52 点词跟读：词组 / 每个字可点按发音（Duolingo 式） */
.bubble .zh .tap-ph { border-radius: 4px; cursor: pointer; }
.bubble .zh .tap-ch {
  cursor: pointer; border-radius: 3px; transition: background .12s;
}
.bubble .zh .tap-ch:hover { background: rgba(157, 40, 44, .12); }
.bubble .zh .tap-ch:active { background: rgba(157, 40, 44, .25); }
.msg.user .bubble .zh { color: #fff; }
.bubble .py { color: var(--red); font-size: 12.5px; margin-top: 2px; }
.msg.user .bubble .py { color: rgba(255,255,255,.75); }
.bubble .en { color: var(--ink-soft); font-size: 12.5px; margin-top: 2px; }
.msg.user .bubble .en { color: rgba(255,255,255,.7); }
.bubble.plain { font-size: 12.5px; }

/* 操作说明（没有拼音的句子）：英文当主行，中文退为下面一行小字 */
.bubble .zh.en-main {
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1.58;
}

body.nopy .py { display: none !important; }

.bubble.correct { border-color: #bfe0c8; background: #f4fbf6; }
.bubble.wrong   { border-color: #f0d3a8; background: #fdf8ee; }

.caret {
  display: inline-block;
  width: 2px; height: 1em;
  background: var(--red);
  vertical-align: -2px;
  animation: blink .8s infinite;
}
@keyframes blink { 50% { opacity: 0; } }

/* typing indicator */
.typing .bubble { display: flex; gap: 5px; align-items: center; }
.typing .dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: #c9bfae;
  animation: bounce 1.2s infinite;
}
.typing .dot:nth-child(2) { animation-delay: .15s; }
.typing .dot:nth-child(3) { animation-delay: .3s; }
@keyframes bounce { 0%, 60%, 100% { transform: none; } 30% { transform: translateY(-5px); } }

/* ============ 生词闪卡 flashcards ============ */
.deck { margin-top: 10px; }

.deck-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
}

.deck-count { font-size: 12.5px; font-weight: 600; color: var(--ink-soft); }

.deck-dots { display: flex; gap: 5px; }
.deck-dots span {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--line);
  transition: all .2s;
}
.deck-dots span.on { background: var(--gold); }
.deck-dots span.cur { transform: scale(1.5); box-shadow: 0 0 0 2px rgba(217,164,65,.3); }

.deck-stage { perspective: 1000px; }

.flashcard {
  position: relative;
  height: 158px;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.flashcard:focus-visible { outline: 2px solid var(--red); outline-offset: 3px; border-radius: 14px; }

.fc-inner {
  position: relative;
  width: 100%; height: 100%;
  transform-style: preserve-3d;
  transition: transform .5s;
}
.flashcard.flipped .fc-inner { transform: rotateY(180deg); }

.fc-face {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 14px;
  text-align: center;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--paper-warm);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.fc-back {
  transform: rotateY(180deg);
  background: #fff8ef;
  border-color: var(--gold);
}

.fc-h  { font-size: 12.5px; font-weight: 800; color: var(--red-deep); letter-spacing: 3px; }
.fc-h2 { font-size: 12.5px; font-weight: 700; color: var(--red-deep); letter-spacing: 1px; }
.fc-hint { font-size: 11.5px; color: var(--ink-soft); line-height: 1.4; }

/* 闪卡右上角的独立发音按钮 */
.fc-speak {
  position: absolute;
  top: 8px;
  right: 8px;
  margin: 0;
  background: #fff;
}
.fc-speak:hover { background: var(--red); color: #fff; border-color: var(--red); }

.deck-ctrls { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }

/* v59 录音倒计时：2 → 1 → 开始，数字放大跳动提醒学生准备开口 */
.chip.counting { font-weight: 800; letter-spacing: .06em; }
@media (prefers-reduced-motion: no-preference) {
  .chip.counting { animation: recCount .72s ease infinite; }
}
@keyframes recCount {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.08); }
}

/* ============ v57 任务卡 stage map（闪卡下面的五步任务） ============ */
.stage-map { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 12px; }

.sm-task {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  padding: 12px 12px 10px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: #fffdf8;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: var(--ink);
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s;
}
.sm-task:active { transform: scale(.97); }
.sm-task:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.sm-task.cur { border-color: var(--red); box-shadow: 0 0 0 1px var(--red); }

/* 每张卡顶部一条 Duolingo 式完成条 */
.sm-bar { position: absolute; top: 0; left: 0; right: 0; height: 4px; background: var(--line); }
.sm-fill { display: block; height: 100%; width: 0; background: var(--gold); transition: width .3s; }
.sm-fill.full { background: var(--green); }

.sm-name { font-size: 12.5px; font-weight: 700; line-height: 1.3; padding-right: 44px; }
.sm-name em { font-style: normal; font-weight: 600; color: var(--ink-soft); margin-left: 4px; }

/* 右上角：做一半显示 3/6，全做完打 ✓ */
.sm-badge {
  position: absolute;
  top: 9px;
  right: 8px;
  min-width: 22px;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  text-align: center;
  background: var(--paper-warm);
  border: 1px solid var(--line);
  color: var(--ink-soft);
}
.sm-badge.part { background: var(--gold); border-color: var(--gold); color: #fff; }
.sm-badge.ok { background: var(--green); border-color: var(--green); color: #fff; }

/* ============ 词语配对 matching ============ */
.match-box { margin-top: 10px; }

.match-status {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 8px;
}
.match-status.all { color: var(--green); }

.match-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.mcol { display: flex; flex-direction: column; gap: 8px; }

.mcard {
  min-height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 10px;
  border-radius: 10px;
  border: 1.5px solid var(--line);
  background: #fff;
  font-family: inherit;
  font-size: 12.5px;
  color: var(--ink);
  line-height: 1.35;
  text-align: center;
  cursor: pointer;
  transition: all .16s;
}
.mcard:hover { border-color: var(--red); }
.mcard.zh { font-size: 12.5px; font-weight: 700; color: var(--red-deep); letter-spacing: 1px; }

.mcard.pick {
  border-color: var(--red);
  background: #fff2f2;
  box-shadow: 0 0 0 3px rgba(178,58,72,.14);
}
.mcard.matched {
  border-color: #bfe0c8;
  background: #f4fbf6;
  color: var(--green);
  cursor: default;
}
.mcard.matched.zh { color: var(--green); }
.mcard.bad { border-color: #d9534f; background: #fdf0ef; animation: shake .3s; }

@keyframes shake {
  0%, 100% { transform: none; }
  25%      { transform: translateX(-5px); }
  75%      { transform: translateX(5px); }
}

@media (max-width: 560px) {
  .flashcard { height: 182px; }   /* 手机档（v24）把汉字主行提到 46px，卡片高度跟上（156px 是配 40px 字的） */
  .mcard { padding: 7px 8px; }
}

/* pattern box */
.pattern-box {
  margin-top: 10px;
  background: linear-gradient(135deg, #fdf3e3, #faecd7);
  border: 1.5px dashed var(--gold);
  border-radius: 12px;
  padding: 12px 16px;
}

.pattern-box .pat-zh { font-size: 12.5px; font-weight: 700; letter-spacing: 1px; }

/* 句型里的「空位」：不用下划线，只留一个看得见的小空格 */
.blank {
  display: inline-block;
  width: 34px;
  height: .92em;
  margin: 0 5px;
  vertical-align: -.08em;
  border-radius: 6px;
  background: rgba(178, 58, 72, .12);
}
.pattern-box .pat-py { color: var(--red); font-size: 12.5px; margin-top: 2px; }
.pattern-box .pat-en { color: var(--ink-soft); font-size: 12.5px; margin-top: 2px; }
.pattern-box .pat-note { font-size: 12.5px; color: #8a7350; margin-top: 8px; line-height: 1.55; }

/* practice prompt card */
.prompt-card {
  margin-top: 10px;
  background: #f2f0fb;
  border: 1px solid #ddd7f0;
  border-radius: 12px;
  padding: 12px 16px;
}
.prompt-card .task { font-size: 12.5px; font-weight: 700; }
.prompt-card .tip  { font-size: 12.5px; color: var(--ink-soft); margin-top: 4px; }

/* v47 Duolingo 式对话练习题：
   顶部进度 → 简短指令（英文主行）→ 整行大按钮；对错用底部反馈条 + Continue
   v58 对话气泡：整张任务卡长成一个「台词气泡」，左上角小尾巴指向头像 */
.duo-card { background: #fff; border-color: var(--line); position: relative; }
.duo-card::before {
  content: '';
  position: absolute;
  top: -8px;
  left: 16px;
  border: 8px solid transparent;
  border-top: 0;
  border-bottom-color: #fff;
}
.duo-card .dlg-line { margin-top: 9px; }
.duo-progress {
  position: relative;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding-bottom: 7px;
}
.duo-progress::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 6px;
  border-radius: 99px;
  background: var(--line);
}
.duo-progress i {
  position: absolute;
  left: 0; bottom: 0;
  height: 6px;
  border-radius: 99px;
  background: var(--red);
  transition: width .35s ease;
}
.duo-card .task { margin-top: 9px; font-size: 12.5px; font-weight: 700; }
.duo-card .tip  { margin-top: 3px; font-size: 12.5px; }
.duo-actions .chip.duo-primary {
  flex: 1 1 100%;
  padding: 13px 16px;
  font-size: 12.5px;
  text-align: center;
  box-shadow: 0 5px 0 rgba(160, 30, 30, .28);
}
.duo-actions .chip.duo-primary:active { transform: translateY(2px); box-shadow: 0 3px 0 rgba(160,30,30,.28); }
.duo-actions .chip.duo-secondary { font-size: 12.5px; }

.duo-feedback {
  margin-top: 12px;
  padding: 13px 16px;
  border-radius: 16px;
  color: #fff;
  background: linear-gradient(140deg, #4a9e64, #2f6f47);
  box-shadow: 0 10px 26px rgba(40,30,20,.18);
  animation: fbIn .28s cubic-bezier(.2,.9,.3,1.2);
}
.duo-feedback.wrong { background: linear-gradient(140deg, #d5544d, #a3302c); }
.duo-feedback.done { opacity: .72; }
.duo-feedback .df-head { font-size: 12.5px; font-weight: 700; }
.duo-feedback .df-sub  { font-size: 12.5px; opacity: .9; margin-top: 2px; }
.duo-feedback .pattern-box {
  margin-top: 9px;
  background: rgba(255,255,255,.94);
  border-color: transparent;
}
.duo-feedback .df-btns { display: flex; gap: 9px; margin-top: 11px; }
.duo-feedback .df-btns .chip.duo-continue { margin-top: 0; flex: 1; }
.duo-feedback .chip.duo-continue {
  margin-top: 11px;
  width: 100%;
  padding: 11px 16px;
  font-size: 12.5px;
  background: #fff;
  border-color: transparent;
  color: var(--red-deep);
}
.duo-feedback .chip.duo-continue:hover { background: #fff; color: var(--red-deep); }
.duo-feedback .chip.duo-continue:disabled { opacity: .5; }
/* v90：「再试一次 Try again」副按钮（揭示反馈条）——半透明白，主操作仍是白底「继续」 */
.duo-feedback .chip.duo-retry {
  padding: 11px 14px;
  font-size: 12.5px;
  background: rgba(255,255,255,.16);
  border-color: rgba(255,255,255,.55);
  color: #fff;
  white-space: nowrap;
}
.duo-feedback .chip.duo-retry:hover { background: rgba(255,255,255,.28); }
.duo-feedback .chip.duo-retry:disabled { opacity: .5; }
@keyframes fbIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .duo-feedback { animation: none; }
}

/* lesson summary card (end of lesson) */
.summary-card {
  margin-top: 10px;
  background: linear-gradient(160deg, #fffdf8, #f7f1e6);
  border: 1.5px solid var(--gold);
  border-radius: 12px;
  padding: 12px 15px;
  max-height: 48vh;
  overflow-y: auto;
}
.summary-card .sm-sec + .sm-sec {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
}
.summary-card .sm-title {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--red-deep);
  letter-spacing: .5px;
}
.summary-card .sm-sub {
  font-size: 11.5px;
  font-weight: 600;
  color: #8a7350;
  margin: 9px 0 2px;
}
.summary-card .sm-list { list-style: none; margin: 6px 0 0; padding: 0; }
.summary-card .sm-list li { padding: 5px 0; border-bottom: 1px dotted #e6ddcd; }
.summary-card .sm-list li:last-child { border-bottom: none; }
.summary-card .sm-zh { display: block; font-size: 12.5px; font-weight: 700; letter-spacing: 1px; }
.summary-card .sm-py { display: block; font-size: 12.5px; color: var(--red); margin-top: 1px; }
.summary-card .sm-en { display: block; font-size: 12.5px; color: var(--ink-soft); margin-top: 1px; }
.summary-card .sm-pat { font-size: 12.5px; font-weight: 700; letter-spacing: 1px; margin-top: 8px; }
.summary-card .sm-pat-py { font-size: 12.5px; color: var(--red); margin-top: 2px; }
.summary-card .sm-pat-en { font-size: 12.5px; color: var(--ink-soft); margin-top: 2px; }

/* 课末错题回顾卡：列本课第一次尝试就出错的题（题目 / 输入 / 正确答案） */
.mistakes-card {
  margin-top: 10px;
  background: linear-gradient(160deg, #fff7f5, #fce8e3);
  border: 1.5px solid #e7a99a;
  border-radius: var(--radius-lg, 14px);
  padding: 14px 16px 12px;
  box-shadow: 0 2px 0 rgba(180, 60, 50, 0.06);
}
.mistakes-card .mk-title {
  font-size: 12.5px;
  font-weight: 700;
  color: #b03a2a;
  margin-bottom: 10px;
}
.mistakes-card .mk-list { list-style: none; margin: 0; padding: 0; }
.mistakes-card .mk-item {
  padding: 10px 0;
  border-top: 1px dashed #ecc6bd;
}
.mistakes-card .mk-item:first-child { border-top: none; padding-top: 0; }
.mistakes-card .mk-task {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink, #2a2a2a);
  line-height: 1.5;
  margin-bottom: 6px;
}
.mistakes-card .mk-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 8px;
  margin-top: 4px;
}
.mistakes-card .mk-tag {
  font-size: 12px;
  padding: 2px 7px;
  border-radius: 999px;
  font-weight: 600;
  letter-spacing: 0.2px;
}
.mistakes-card .mk-tag-wrong { background: #fde0dc; color: #b03a2a; }
.mistakes-card .mk-tag-right { background: #e6f4ea; color: #1e7a3c; }
.mistakes-card .mk-input {
  font-size: 16px;
  color: #b03a2a;
  text-decoration: line-through;
  text-decoration-thickness: 1.5px;
  word-break: break-word;
}
.mistakes-card .mk-zh {
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.5px;
  color: #1e7a3c;
}
.mistakes-card .mk-py {
  font-size: 12.5px;
  color: #6c5b50;
}

/* chips */
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }

.chip {
  padding: 7px 15px;
  background: #fff;
  border: 1.5px solid var(--red);
  color: var(--red-deep);
  border-radius: 999px;
  font-size: 12.5px;
  font-family: inherit;
  cursor: pointer;
  transition: all .18s;
  font-weight: 600;
}

.chip:hover { background: var(--red); color: #fff; }
.chip:disabled { opacity: .35; cursor: default; }
.chip:disabled:hover { background: #fff; color: var(--red-deep); }

.chip.soft { border-color: var(--line); color: var(--ink-soft); font-weight: 500; }
.chip.soft:hover { border-color: var(--ink-soft); background: var(--ink-soft); color: #fff; }

/* composer */
.composer {
  display: flex;
  gap: 10px;
  padding: 16px 28px 20px;
  background: rgba(255,255,255,.7);
  backdrop-filter: blur(6px);
  border-top: 1px solid var(--line);
}

#userInput {
  flex: 1;
  padding: 13px 18px;
  border: 1.5px solid var(--line);
  border-radius: 14px;
  font-size: 16px;    /* 低于 16px 时 iOS 聚焦会强制放大且不缩回，手机上再想点哪儿都点不准 */
  font-family: inherit;
  background: #fff;
  outline: none;
  transition: border-color .2s, box-shadow .2s;
}

#userInput:focus { border-color: var(--red); box-shadow: 0 0 0 3px rgba(178,58,72,.12); }

.composer button {
  width: 52px;
  border: none;
  border-radius: 14px;
  background: linear-gradient(140deg, var(--red), var(--red-dark));
  color: #fff;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: transform .15s, filter .15s;
}

.composer button:hover { filter: brightness(1.1); transform: translateY(-1px); }

/* v144（enlarge-composer-touch-targets，教师真机反馈）：底部输入栏图标 26px
   ——CSS 盖过内联 SVG 的 20×20 属性，按钮里的视觉目标贴着指头大小 */
.composer button svg { width: 26px; height: 26px; }

/* mic button */
.mic-btn {
  width: 52px;
  border: 1.5px solid var(--line);
  border-radius: 14px;
  background: #fff;
  color: var(--ink-soft);
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: all .18s;
}

.mic-btn:hover { border-color: var(--red); color: var(--red); }

.mic-btn.recording {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
  animation: pulse 1.3s infinite;
}

@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 rgba(178,58,72,.45); }
  70%  { box-shadow: 0 0 0 12px rgba(178,58,72,0); }
  100% { box-shadow: 0 0 0 0 rgba(178,58,72,0); }
}

/* speak button (in bot bubbles) */
.speak-btn {
  border: 1px solid var(--line);
  background: var(--paper-warm);
  color: var(--red-deep);
  width: 27px; height: 27px;
  border-radius: 9px;
  cursor: pointer;
  display: inline-grid;
  place-items: center;
  margin-top: 8px;
  transition: all .18s;
  vertical-align: middle;
}

.speak-btn:hover { background: var(--red); color: #fff; border-color: var(--red); }

/* 播放速度按钮（0.5× / 0.75× / 1× 循环）：跟 🔊 同款但能装下文字 */
.speak-btn.speed-btn {
  width: auto;
  min-width: 27px;
  padding: 0 7px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .02em;
}

/* settings modal */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(46,42,38,.5);
  backdrop-filter: blur(3px);
  display: grid;
  place-items: center;
  z-index: 50;
  animation: rise .2s ease;
}

.modal {
  background: #fff;
  border-radius: 18px;
  padding: 26px;
  width: min(440px, 92vw);
  max-height: 90vh;
  max-height: 90dvh;   /* 手机上键盘弹出后，弹窗底部的按钮仍然够得到 */
  overflow-y: auto;
  box-shadow: 0 18px 50px rgba(60,35,25,.25);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.modal { position: relative; }

.modal-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 30px;
  height: 30px;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--ink-soft);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  transition: background .2s, color .2s;
}
.modal-close:hover { background: var(--line); color: var(--ink); }

.modal h3 { color: var(--red-deep); font-size: 18px; padding-right: 28px; }
.modal-desc { font-size: 12.5px; color: var(--ink-soft); line-height: 1.6; user-select: none; }

.modal label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}

.modal label.check-row {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-soft);
  cursor: pointer;
}

.modal input[type="text"],
.modal input:not([type="checkbox"]) {
  padding: 10px 12px;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  font-size: 16px;    /* 同上：手机上填 API Key / 地址时也不会被 iOS 放大 */
  font-family: inherit;
  outline: none;
  transition: border-color .2s;
}

.modal input:focus { border-color: var(--red); }

.modal-actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  margin-top: 6px;
}

.ghost-btn2 {
  padding: 9px 16px;
  background: none;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
  font-family: inherit;
  font-size: 13.5px;
  color: var(--ink-soft);
  transition: all .18s;
}

.ghost-btn2:hover { border-color: var(--ink-soft); }

/* MD7.8：破坏性操作（Restart Course · 重新开始课程）—— 低饱和红，提示「点了不可逆」 */
.ghost-btn2.danger {
  color: #a4262c;
  border-color: #e6b9bc;
  background: #fdf6f6;
}
.ghost-btn2.danger:hover { border-color: #d08d92; background: #fbeaea; }

.primary-btn {
  padding: 9px 22px;
  background: var(--red);
  color: #fff;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  transition: filter .18s;
}

.primary-btn:hover { filter: brightness(1.12); }

/* ============ MD7.6：选课本浮层的课程卡 ============ */
.course-cards {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 4px;
}
.course-card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  align-items: flex-start;
  width: 100%;
  padding: 14px 16px;
  border: 1.5px solid var(--line);
  border-radius: 14px;
  background: #fff;
  cursor: pointer;
  font-family: inherit;
  text-align: left;
  transition: border-color .18s, box-shadow .18s, transform .12s;
}
.course-card:hover { border-color: var(--red); box-shadow: 0 6px 18px rgba(60,35,25,.10); }
.course-card:active { transform: scale(.995); }
.course-card .cc-title { font-size: 16px; font-weight: 700; color: var(--ink); }
.course-card .cc-title-en { font-size: 12.5px; color: var(--ink-soft); }
.course-card .cc-count { font-size: 12.5px; color: var(--ink-soft); }
.course-card .cc-empty { font-size: 12px; color: var(--ink-soft); font-style: italic; }
.course-card .cc-badge {
  margin-top: 4px;
  padding: 2px 9px;
  border-radius: 999px;
  background: rgba(217, 164, 65, .18);
  color: #8a5a12;
  font-size: 11.5px;
  font-weight: 700;
}
.course-card.current { border-color: var(--red); box-shadow: 0 0 0 2px rgba(178,58,72,.12); }

/* ============ 顶部入口：Free Chat / Live（v131 两只并排，同规格） ============ */
.entry-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 16px;
  border-radius: 999px;
  border: 1.5px solid var(--line);
  background: #fff;
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all .18s;
  white-space: nowrap;
}

/* Free Chat 描边款（Live 保持红色实心：口语加练的标记色，不跟它抢） */
.free-btn:hover { border-color: var(--green); color: var(--green); }
.free-btn.on { border-color: var(--green); background: rgba(62,142,90,.1); color: var(--green); }

/* ============ Live 语音通话 ============ */
.live-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 16px;
  border-radius: 999px;
  border: 1.5px solid var(--red);
  background: #fff;
  color: var(--red-deep);
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  font-size: 13px;
  transition: all .18s;
  white-space: nowrap;
}

.live-btn:hover { background: var(--red); color: #fff; }

.live-btn.on {
  background: var(--red);
  color: #fff;
  animation: pulse 1.3s infinite;
}

.live-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 14px 28px 0;
  padding: 11px 18px;
  background: linear-gradient(135deg, var(--red-deep), var(--red-dark));
  color: #fff;
  border-radius: 14px;
  box-shadow: var(--shadow);
  animation: rise .25s ease;
}

.live-bar .eq { display: flex; gap: 3px; align-items: center; height: 20px; }
.live-bar .eq span {
  width: 3px;
  height: 100%;
  background: #f6e9e2;
  border-radius: 2px;
  transform-origin: center;
  animation: eq 1s infinite ease-in-out;
}
.live-bar .eq span:nth-child(1) { animation-delay: 0s; }
.live-bar .eq span:nth-child(2) { animation-delay: .12s; }
.live-bar .eq span:nth-child(3) { animation-delay: .24s; }
.live-bar .eq span:nth-child(4) { animation-delay: .36s; }
.live-bar .eq span:nth-child(5) { animation-delay: .48s; }

@keyframes eq {
  0%, 100% { transform: scaleY(.25); }
  50%      { transform: scaleY(1); }
}

.live-bar.speaking .eq span { animation-duration: .45s; }
.live-bar.thinking .eq span  { animation-duration: .3s; opacity: .7; }

#liveStatus {
  font-size: 13.5px;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#liveEnd {
  border: none;
  background: rgba(255,255,255,.22);
  color: #fff;
  padding: 7px 16px;
  border-radius: 999px;
  cursor: pointer;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  transition: background .18s;
  white-space: nowrap;
}

#liveEnd:hover { background: rgba(255,255,255,.38); }

/* 设置面板里的预设按钮 */
.preset-btn {
  padding: 10px 12px;
  background: #fdf3e3;
  border: 1.5px dashed var(--gold);
  border-radius: 10px;
  color: #8a6d2f;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: all .18s;
  text-align: center;
}

.preset-btn:hover { background: #fae9c8; }

/* 设置面板里的「测试连接」输出 */
.cfg-test-out {
  margin: 0;
  padding: 10px 12px;
  max-height: 190px;
  overflow: auto;
  background: #faf7f1;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 12px;
  line-height: 1.65;
  color: var(--ink);
  white-space: pre-wrap;
  word-break: break-all;
  user-select: text;
}

.modal-ver {
  margin: 0;
  text-align: right;
  font-size: 11.5px;
  color: var(--ink-soft);
  user-select: none;
}

/* responsive */
/* 中等偏窄窗口：侧栏变窄但保持左侧 */
@media (max-width: 1100px) {
  .sidebar { width: 240px; padding: 20px 14px; }
}

/* 窄屏（手机 + 平板竖屏，≤900px）：字号整体提到「拿在手里也看得清」的尺度。
   手机（≤560px）v24 起另有加大一档，见文件末尾；>900px 的桌面一行都不改 ——
   phone-type-scale 规范守着这两件事。 */
@media (max-width: 900px) {
  .sidebar { width: 200px; padding: 16px 11px; }
  .brand { gap: 9px; margin-bottom: 16px; }
  .brand-mark { width: 36px; height: 36px; font-size: 18px; border-radius: 10px; }
  .brand-name { font-size: 16px; }
  .brand-sub { display: none; }
  .steps { padding: 10px 8px; margin-bottom: 14px; gap: 2px; }
  .step { font-size: 15px; padding: 6px; gap: 7px; }
  .step em { display: none; }
  .lessons { gap: 5px; }
  .lesson-btn { padding: 9px 9px; gap: 7px; }   /* 字体统一（2026-10-08）：字号走全局 12.5px，对齐 NPCR */
  .lesson-num { width: 24px; height: 24px; border-radius: 6px; }
  .sidebar-footer { gap: 6px; margin-top: 12px; }
  .ghost-btn { font-size: 13.5px; padding: 7px 4px; }
  .footer-row .ghost-btn { white-space: normal; }

  /* 学生要读的内容（v144 cap-course-typography：内容字号 12.5px 封顶——
     对齐 NPCR 侧栏课菜单，重点用粗体不用大字，窄屏不再抬升） */
  #currentLesson { font-size: 17px; }
  .chat-sub { font-size: 13.5px; }
  .messages { padding: 18px 16px; }
  .msg { max-width: 88%; }
  .bubble { font-size: 12.5px; }
  .bubble.plain { font-size: 12.5px; }
  .bubble .zh { font-size: 12.5px; }
  .bubble .py, .bubble .en { font-size: 12.5px; }
  .pattern-box .pat-zh { font-size: 12.5px; }
  .pattern-box .pat-py { font-size: 12.5px; }
  .pattern-box .pat-en { font-size: 12.5px; }
  .pattern-box .pat-note { font-size: 12.5px; }
  .prompt-card .task { font-size: 12.5px; }
  .prompt-card .tip { font-size: 12.5px; }
  .fc-h { font-size: 12.5px; }
  .fc-h2 { font-size: 12.5px; }
  .fc-hint { font-size: 12.5px; }
  .mcard { min-height: 56px; font-size: 12.5px; }
  .mcard.zh { font-size: 12.5px; }
  .match-status { font-size: 12.5px; }
  .summary-card .sm-title { font-size: 12.5px; }
  .summary-card .sm-sub { font-size: 12.5px; }
  .summary-card .sm-zh { font-size: 12.5px; }
  .summary-card .sm-py { font-size: 12.5px; }
  .summary-card .sm-en { font-size: 12.5px; }
  .summary-card .sm-pat { font-size: 12.5px; }
  .summary-card .sm-pat-py { font-size: 12.5px; }
  .summary-card .sm-pat-en { font-size: 12.5px; }
  .chip { font-size: 12.5px; }
  #userInput { font-size: 17px; }

  /* 基础规则在文件前半段（<900 行）、手机上照样显示的小字：窄屏抬到 ≥12px */
  .footer-ver { font-size: 12px; }
  .footer-ver .ghost-btn { font-size: 12px; }
  .step em { font-size: 13px; }
  .modal-ver { font-size: 12px; }
}

/* ≤900px（手机 + 平板竖屏 + 一切窄视口）：菜单变为左侧滑出抽屉。
   v37 从 560px 提到 900px：真机上视口落在 561–900 的机器（「桌面模式」三条判据
   都套不上）此前仍是双栏侧栏布局，聊天区被挤成窄条 —— 结构性修复：
   凡 ≤900px 一律折叠侧栏，与 app.js 里 narrow = innerWidth <= 900 的判定同一个数。 */
@media (max-width: 900px) {
  .menu-toggle { display: inline-flex; }

  /* 抽屉有完整宽度，恢复完整文字。字号统一由上面的 ≤900px 断点管，
     这里只管布局（padding / gap / 换行），不再各写一套小字 */
  .brand-sub { display: block; }
  .step em { display: inline; }
  .step { padding: 7px 8px; gap: 10px; }
  .lesson-btn { padding: 11px 12px; gap: 10px; }
  .lesson-num { width: 26px; height: 26px; border-radius: 8px; }
  .ghost-btn { padding: 8px 6px; }
  .footer-row .ghost-btn { white-space: nowrap; }

  .sidebar {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: min(300px, 84vw);
    height: 100%;
    max-height: none;
    padding: 20px 16px;
    transform: translateX(-105%);
    transition: transform .25s ease;
    z-index: 60;
  }
  .sidebar.open { transform: translateX(0); box-shadow: 0 0 44px rgba(0,0,0,.35); }

  .sidebar-backdrop {
    position: fixed;
    inset: 0;
    z-index: 55;
    border: none;
    padding: 0;
    background: rgba(46,42,38,.45);
    backdrop-filter: blur(2px);
    cursor: pointer;
  }

  .messages, .composer, .chat-header { padding-left: 16px; padding-right: 16px; }
  .live-bar { margin: 10px 16px 0; }
  .msg { max-width: 92%; }
}

.chip-hint {
  align-self: center;
  font-size: 12px;
  color: var(--ink-soft);
  user-select: none;
}

/* ============ 录音中屏幕徽章（v38 跟读三件套） ============
   点 🎤 录音后常驻屏幕：红点脉冲 + REC 正在录音。
   v53：曾改到屏幕正中（top/left 50% + translate 居中）、字号加大到 18px。
   v136（unify-task-recording-feedback）：**收成右上角小胶囊**——教师真机反馈
   「正中央那个大 REC 徽章挡住了要读/要看的内容」。录音态仍一眼可见（红点脉冲
   保留），但让开内容区；仍 pointer-events:none，不挡 Stop / Skip。 */
.rec-badge {
  position: fixed;
  top: 10px;
  right: 12px;
  z-index: 90;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px;
  border-radius: 999px;
  background: #fff;
  border: 2px solid var(--red);
  color: var(--red-deep);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .3px;
  box-shadow: 0 4px 14px rgba(46,42,38,.18);
  user-select: none;
  pointer-events: none;
}

.rec-badge::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--red);
  animation: recPulse 1s ease-in-out infinite;
}

@keyframes recPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .3; transform: scale(.75); }
}

/* Record 按钮自身的录音态：与徽章同色，双保险提示 */
.rep-record.recording,
.rec-hear.recording {
  border-color: var(--red);
  color: var(--red-deep);
  background: #fdf0f0;
}

/* add-android-playback：Hear yourself 录音中按钮变「⏹ Stop」，实心红底一眼看出「再点一下就停」 */
.chip.rec-hear.stoppable,
.chip.rec-hear.stoppable:hover {
  border-color: var(--red);
  background: var(--red);
  color: #fff;
}

/* 气泡上第二个（英文）朗读按钮。
   v62：补回 margin-top —— .bubble .en（英文小字）的同名类命中会把 EN
   按钮抬高 3px，和旁边的 🔊 / 0.5× 对不齐 */
.speak-btn.en {
  width: auto;
  min-width: 27px;
  padding: 0 6px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .4px;
  margin-left: 6px;
  margin-top: 8px;
  font-family: inherit;
}

/* ============ 设置面板：学习节奏 ============ */
.cfg-divider {
  margin-top: 2px;
  padding-top: 12px;
  border-top: 1px dashed var(--line);
  font-size: 12.5px;
  font-weight: 700;
  color: var(--red-deep);
}

.cfg-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

.modal select {
  padding: 9px 10px;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  background: #fff;
  color: var(--ink);
  font-family: inherit;
  font-size: 13.5px;
  outline: none;
  cursor: pointer;
  transition: border-color .2s;
}

.modal select:focus { border-color: var(--red); }

.cfg-note {
  margin: 0;
  padding: 9px 12px;
  background: #faf7f1;
  border-radius: 10px;
  font-size: 12px;
  line-height: 1.65;
  color: var(--ink-soft);
}

.cfg-note b { color: var(--red-deep); }

@media (max-width: 560px) {
  .cfg-grid { grid-template-columns: 1fr; }
}

/* ============ 新手导览 ============ */
.tour-root {
  position: fixed;
  inset: 0;
  z-index: 9998;
}

.tour-root[hidden] { display: none; }

.tour-hole {
  position: fixed;
  border-radius: 14px;
  border: 2px solid rgba(255,255,255,.85);
  box-shadow: 0 0 0 9999px rgba(40,32,28,.64);
  pointer-events: none;
  transition: left .22s ease, top .22s ease, width .22s ease, height .22s ease;
}

.tour-card {
  position: fixed;
  width: min(346px, calc(100vw - 24px));
  padding: 15px 18px 16px;
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 20px 54px rgba(0,0,0,.32);
  color: var(--ink);
}

.tour-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}

.tour-count {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 1.2px;
  color: var(--gold);
}

.tour-close {
  background: none;
  border: none;
  padding: 0 2px;
  color: var(--ink-soft);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}

.tour-close:hover { color: var(--ink); }

.tour-card h4 {
  margin: 0 0 8px;
  color: var(--red-deep);
  font-size: 15.5px;
}

.tour-en {
  margin: 0 0 6px;
  font-size: 13.5px;
  line-height: 1.65;
}

.tour-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 14px;
}

.tour-play { padding: 9px 12px; }

.tour-actions { flex-wrap: wrap; }

.tour-actions .tour-prev:disabled { opacity: .35; cursor: default; }

/* 卡片里的进度条 */
.tour-bar {
  height: 4px;
  margin: 0 0 10px;
  background: var(--line);
  border-radius: 999px;
  overflow: hidden;
}

.tour-bar i {
  display: block;
  width: 0;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--red), var(--gold));
  transition: width .25s ease;
}

/* 页面上的编号小圆点 ①②③ —— italki 式视觉导览的核心 */
.tour-badges {
  position: fixed;
  inset: 0;
  pointer-events: none;
}

.tour-badge {
  position: fixed;
  width: 30px;
  height: 30px;
  margin: -15px 0 0 -15px;
  border: 2px solid #fff;
  border-radius: 50%;
  background: rgba(255,255,255,.94);
  color: var(--red-deep);
  font-family: inherit;
  font-size: 14px;
  font-weight: 800;
  line-height: 1;
  cursor: pointer;
  pointer-events: auto;
  box-shadow: 0 3px 12px rgba(0,0,0,.4);
  transition: transform .18s, background .18s, color .18s;
}

.tour-badge:hover { transform: scale(1.12); }

.tour-badge.on {
  background: var(--red);
  border-color: #fff;
  color: #fff;
  transform: scale(1.28);
  box-shadow: 0 5px 18px rgba(0,0,0,.5), 0 0 0 6px rgba(207,58,58,.28);
}

/* 全部步骤清单 */
.tour-list-toggle {
  width: 100%;
  margin-top: 10px;
  padding: 6px 10px;
  border: 1px dashed var(--line);
  border-radius: 9px;
  background: #fff;
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: all .18s;
}

.tour-list-toggle:hover { border-color: var(--gold); color: var(--ink); }

.tour-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 8px;
  max-height: 168px;
  overflow: auto;
}

.tour-list-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 12px;
  text-align: left;
  cursor: pointer;
}

.tour-list-item:hover { background: #faf7f1; color: var(--ink); }

.tour-list-item b {
  flex: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--line);
  color: var(--ink);
  font-size: 11px;
  line-height: 18px;
  text-align: center;
}

.tour-list-item.on { background: #fdf6ea; color: var(--red-deep); font-weight: 700; }

.tour-list-item.on b { background: var(--red); color: #fff; }

@media (max-width: 560px) {
  .tour-card { padding: 13px 14px 14px; }
  .tour-actions { gap: 6px; }
  .tour-actions button { padding: 8px 10px; font-size: 14px; }
  .tour-badge { width: 26px; height: 26px; margin: -13px 0 0 -13px; font-size: 14px; }
}

/* ============ 奖励系统：XP / 连击 / 连续天数 / 烟花 ============ */
.stats-strip {
  margin-bottom: 16px;
  padding: 10px 11px 11px;
  background: rgba(0,0,0,.16);
  border: 1px solid rgba(255,255,255,.09);
  border-radius: 12px;
}

.stat-row { display: flex; gap: 6px; }

.stat-chip {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 5px 4px;
  background: rgba(255,255,255,.08);
  border-radius: 8px;
  font-size: 10.5px;
  color: rgba(255,255,255,.72);
  white-space: nowrap;
}

.stat-chip b { font-size: 13px; color: #fff; }

.xp-bar {
  height: 6px;
  margin: 8px 0 6px;
  background: rgba(0,0,0,.28);
  border-radius: 99px;
  overflow: hidden;
}

.xp-bar i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--gold), #f6d27a);
  transition: width .5s ease;
}

.stat-goal { font-size: 10.5px; color: rgba(255,255,255,.62); }

/* 烟花 / 星星画布：铺满全屏，不挡点击 */
.fx-canvas {
  position: fixed;
  inset: 0;
  z-index: 9997;
  pointer-events: none;
}

/* 飘出来的 XP / 连击 / 升级提示 */
.xp-toast {
  position: fixed;
  left: 50%;
  bottom: 96px;
  transform: translateX(-50%);
  z-index: 9999;
  padding: 9px 18px;
  border-radius: 99px;
  background: rgba(46,42,38,.92);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  box-shadow: 0 8px 24px rgba(0,0,0,.28);
  pointer-events: none;
  animation: toastUp .45s cubic-bezier(.2,.9,.3,1.4);
}

.xp-toast.goal { background: rgba(62,142,90,.95); }
.xp-toast.level { background: linear-gradient(90deg, var(--red), var(--gold)); }
.xp-toast.streak { background: rgba(217,164,65,.96); color: #3a2a10; }
.xp-toast.out { opacity: 0; transform: translate(-50%, -14px); transition: opacity .5s ease, transform .5s ease; }

@keyframes toastUp {
  from { opacity: 0; transform: translate(-50%, 16px) scale(.9); }
  to   { opacity: 1; transform: translate(-50%, 0) scale(1); }
}

/* 课末奖励卡 */
.reward-card {
  margin-top: 10px;
  padding: 16px 18px;
  background: linear-gradient(160deg, #fffaea, #fdf1dc);
  border: 1px solid #f0dfbe;
  border-radius: 14px;
  text-align: center;
  box-shadow: var(--shadow);
  animation: rewardIn .5s cubic-bezier(.2,.9,.3,1.3);
}

@keyframes rewardIn {
  from { opacity: 0; transform: translateY(10px) scale(.96); }
  to   { opacity: 1; transform: none; }
}

.rw-stars { font-size: 26px; letter-spacing: 4px; color: var(--gold); }
.rw-stars span { color: #e4d9c4; }
.rw-title { margin-top: 4px; font-size: 12.5px; font-weight: 700; color: var(--red-deep); }
.rw-xp { margin: 6px 0 12px; font-size: 12.5px; font-weight: 800; color: var(--green); }

.rw-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: 12px;
}

.rw-grid div { padding: 8px 4px; background: #fff; border-radius: 10px; }
.rw-grid b { display: block; font-size: 12.5px; color: var(--ink); }
.rw-grid span { font-size: 9.5px; line-height: 1.35; color: var(--ink-soft); }

.rw-goal { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--ink-soft); }
.rw-goal b { color: var(--red-deep); }

.rw-bar {
  height: 8px;
  margin: 6px 0 8px;
  background: var(--paper-warm);
  border-radius: 99px;
  overflow: hidden;
}

.rw-bar i {
  display: block;
  height: 100%;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--green), #7cc194);
  transition: width .6s ease;
}

.rw-next { font-size: 11px; color: var(--ink-soft); }

/* 「看完了，继续」：等待读者，同时给一个提前继续的出口 */
.chip.ready { background: var(--red); color: #fff; border-color: transparent; font-weight: 700; }
.chip.ready:hover { background: var(--red-deep); }

@media (max-width: 900px) {
  .rw-grid { grid-template-columns: repeat(2, 1fr); }
  .xp-toast { bottom: 78px; font-size: 13px; }
}

/* ============ 鼓励系统：视觉反馈（参考 Duolingo） ============
   学生常常不方便外放声音，所以「做对了」必须有看得见的反馈：
   ① 顶部本课进度条  ② 头部 HUD：连续天数 / XP / 等级 / 连对徽章
   ③ 底部反馈横幅    ④ 里程碑全屏庆祝
   动效统一遵守 prefers-reduced-motion（见文件末尾）。 */

/* 读屏专用：视觉横幅出现时也播报一次夸奖 */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---- ① 顶部：本课进度条 ---- */
.lesson-bar {
  position: relative;
  flex-shrink: 0;
  height: 7px;
  background: var(--paper-warm);
  border-bottom: 1px solid var(--line);
}

.lesson-bar > i {
  position: relative;
  display: block;
  height: 100%;
  width: 0;
  border-radius: 0 99px 99px 0;
  background: linear-gradient(90deg, var(--red), var(--gold));
  transition: width .5s cubic-bezier(.2,.9,.3,1.2);
}

/* 前进时扫一道光：眼睛能抓住「刚刚又往前走了一步」 */
.lesson-bar.shine > i::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0; right: 0;
  width: 64px;
  background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.92), rgba(255,255,255,0));
  animation: lbShine .75s ease-out;
}

@keyframes lbShine {
  from { transform: translateX(-64px); opacity: .9; }
  to   { transform: translateX(64px); opacity: 0; }
}

.lb-dot {
  position: absolute;
  top: 50%;
  width: 11px; height: 11px;
  margin: -5.5px 0 0 -5.5px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--line);
  transition: border-color .3s ease, background .3s ease, transform .3s ease;
}

.lb-dot:nth-of-type(1) { left: 25%; }
.lb-dot:nth-of-type(2) { left: 50%; }
.lb-dot:nth-of-type(3) { left: 75%; }

.lb-dot.on { background: var(--gold); border-color: #fff; transform: scale(1.1); }

/* ---- ② 头部 HUD：一直看得见的成就 ---- */
.hud { display: flex; align-items: center; gap: 6px; }

.hud-pill {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 9px;
  border: 1px solid var(--line);
  border-radius: 99px;
  background: #fff;
  color: var(--ink-soft);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
}

.hud-pill b { font-size: 12.5px; color: var(--ink); }

/* 数字一跳，学生就知道「刚刚又涨了」 */
.hud-pill.pop { animation: pillPop .5s cubic-bezier(.2,.9,.3,1.5); }

@keyframes pillPop {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.22); }
  100% { transform: scale(1); }
}

/* v131（refactor-top-bar）：HUD 只剩等级药丸 —— 连续天数 / XP / 连对三个药丸的规则
   随 index.html 一起删掉，数据照记（完课卡、里程碑还在用），只是顶部不再挂数字 */
.hud-lv { flex-direction: column; gap: 2px; padding: 3px 9px 4px; }

.hud-lv-bar {
  display: block;
  width: 100%;
  height: 3px;
  border-radius: 99px;
  background: var(--paper-warm);
  overflow: hidden;
}

.hud-lv-bar > i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--gold), #f6d27a);
  transition: width .6s ease;
}

/* ---- ③ 底部反馈横幅：答对了 · 看得见的绿勾 ---- */
.feed-banner {
  position: fixed;
  left: 50%;
  bottom: 106px;
  z-index: 9998;
  display: flex;
  align-items: center;
  gap: 12px;
  width: min(520px, calc(100vw - 28px));
  padding: 12px 16px;
  border-radius: 16px;
  background: linear-gradient(140deg, #4a9e64, #2f6f47);
  color: #fff;
  box-shadow: 0 14px 34px rgba(40,30,20,.3);
  opacity: 0;
  pointer-events: none;              /* 永远不挡打字 */
  transform: translate(-50%, 26px);
  transition: opacity .22s ease, transform .36s cubic-bezier(.2,.9,.3,1.35);
}

.feed-banner.in { opacity: 1; transform: translate(-50%, 0); }

.feed-banner.combo  { background: linear-gradient(140deg, #f0a039, #d0631d); }
.feed-banner.wrong  { background: linear-gradient(140deg, #dfae52, #b8801f); }
.feed-banner.step   { background: linear-gradient(140deg, #4a9e64, #2f6f47); }
.feed-banner.lesson { background: linear-gradient(140deg, var(--gold), #b8801f); }
.feed-banner.goal,
.feed-banner.level,
.feed-banner.streak { background: linear-gradient(130deg, var(--red), var(--gold)); }

.fb-ico {
  display: grid;
  place-items: center;
  width: 36px; height: 36px;
  flex-shrink: 0;
  border-radius: 50%;
  background: rgba(255,255,255,.24);
  animation: iconPop .5s cubic-bezier(.2,.9,.3,1.6);
}

@keyframes iconPop {
  0%   { transform: scale(.2); }
  60%  { transform: scale(1.18); }
  100% { transform: scale(1); }
}

.fb-text { flex: 1; min-width: 0; }
.fb-text b { display: block; font-size: 15.5px; line-height: 1.35; }
.fb-text span { font-size: 12px; opacity: .85; }
.fb-xp { font-size: 14px; font-weight: 800; white-space: nowrap; }

.fb-combo {
  padding: 3px 9px;
  border-radius: 99px;
  background: rgba(0,0,0,.22);
  font-size: 12px;
  font-weight: 800;
  white-space: nowrap;
}

/* 答错：输入框抖一下 + 琥珀色，不打断、不扣分，只是「再看一眼」 */
.composer.nudge { animation: nudge .5s ease; }
.composer.nudge #userInput { border-color: #d9a441; box-shadow: 0 0 0 3px rgba(217,164,65,.18); }

@keyframes nudge {
  0%, 100% { transform: none; }
  20% { transform: translateX(-7px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(2px); }
}

/* 答对的对话气泡：弹一下，右上角留一个绿勾（往回翻也知道这题过了） */
.bubble.pop { animation: bubblePop .5s cubic-bezier(.2,.9,.3,1.4); }

@keyframes bubblePop {
  0%   { transform: scale(.97); }
  55%  { transform: scale(1.025); }
  100% { transform: scale(1); }
}

.bubble.correct { position: relative; }

.bubble.correct::after {
  content: '✓';
  position: absolute;
  top: -9px; right: -9px;
  width: 23px; height: 23px;
  border-radius: 50%;
  background: var(--green);
  color: #fff;
  font-size: 12.5px;
  font-weight: 800;
  line-height: 23px;
  text-align: center;
  box-shadow: 0 3px 10px rgba(62,142,90,.42);
  animation: iconPop .45s cubic-bezier(.2,.9,.3,1.6);
}

/* 头像跟着一起高兴 */
.msg.bot .avatar { position: relative; }
.avatar.cheer { animation: cheerBounce .75s cubic-bezier(.3,.9,.3,1.4); }

.avatar.cheer::after {
  content: '';
  position: absolute;
  inset: -5px;
  border-radius: 17px;
  border: 2px solid rgba(217,164,65,.9);
  animation: ringOut .85s ease-out;
}

@keyframes cheerBounce {
  0%   { transform: none; }
  25%  { transform: translateY(-7px) scale(1.06); }
  55%  { transform: translateY(0) scale(.97); }
  100% { transform: none; }
}

@keyframes ringOut {
  from { opacity: .9; transform: scale(.72); }
  to   { opacity: 0; transform: scale(1.45); }
}

/* ---- ④ 里程碑全屏庆祝：升级 / 今日目标 / 连续天数 ---- */
.celebrate {
  position: fixed;
  inset: 0;
  z-index: 10001;
  display: grid;
  place-items: center;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(58% 48% at 50% 46%, rgba(140,90,30,.28), rgba(40,28,18,.44));
  transition: opacity .32s ease;
}

.celebrate.in { opacity: 1; }

.cel-ring {
  position: absolute;
  width: 150px; height: 150px;
  border-radius: 50%;
  border: 3px solid rgba(217,164,65,.85);
}

.celebrate.in .cel-ring { animation: ringOut 1.1s ease-out; }

.cel-card {
  position: relative;
  padding: 24px 34px 26px;
  border-radius: 22px;
  background: linear-gradient(160deg, #fffdf7, #fdf0d8);
  border: 1px solid #f0dfbe;
  box-shadow: 0 26px 64px rgba(40,25,10,.36);
  text-align: center;
  transform: scale(.8);
  transition: transform .5s cubic-bezier(.2,.9,.3,1.5);
}

.celebrate.in .cel-card { transform: scale(1); }

.cel-ico {
  display: grid;
  place-items: center;
  width: 62px; height: 62px;
  margin: 0 auto 10px;
  border-radius: 50%;
  background: linear-gradient(140deg, var(--gold), #f6d27a);
  color: #fff;
  animation: iconPop .6s cubic-bezier(.2,.9,.3,1.6);
}

.cel-title { font-size: 12.5px; font-weight: 800; color: var(--red-deep); }
.cel-sub { margin-top: 3px; font-size: 12.5px; color: var(--ink-soft); }

.cel-lines {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 14px;
}

.cel-lines > span {
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink);
}

/* 奖励卡：星星一颗一颗蹦出来，XP 数字滚上去 */
.rw-stars { display: flex; justify-content: center; gap: 7px; font-size: 27px; }

.rw-stars > i {
  font-style: normal;
  line-height: 1;
  color: #e4d9c4;
  animation: starPop .55s cubic-bezier(.2,.9,.3,1.6) backwards;
}

.rw-stars > i.on { color: var(--gold); text-shadow: 0 0 12px rgba(217,164,65,.6); }

@keyframes starPop {
  from { opacity: 0; transform: scale(.2) rotate(-40deg); }
  60%  { opacity: 1; transform: scale(1.28) rotate(7deg); }
  to   { opacity: 1; transform: none; }
}

@media (max-width: 900px) {
  .feed-banner { bottom: 92px; padding: 11px 13px; gap: 10px; }
  .fb-text b { font-size: 14.5px; }
  .fb-ico { width: 32px; height: 32px; }
}

@media (max-width: 560px) {
  /* v131：等级是 HUD 里唯一的东西，小屏不再藏它（原来藏等级留 XP，正好反了） */
  .hud-pill { padding: 4px 8px; }
  /* v131：两只入口标签已是纯英文短词，小屏只收紧 padding，不隐藏文字 */
  .entry-btn { padding: 7px 10px; white-space: nowrap; }
}

/* 尊重「减少动态效果」：保留颜色和文字，只把动画关掉 */
@media (prefers-reduced-motion: reduce) {
  /* add-guided-retry-loop：脉冲降级为静态描边（提示仍在，只是不闪） */
  .btn-highlight { animation: none; box-shadow: 0 0 0 3px rgba(194, 65, 12, .35); }

  .lesson-bar > i,
  .hud-lv-bar > i,
  .xp-bar i,
  .rw-bar i { transition: none; }

  .feed-banner { transition: opacity .01s linear; transform: translate(-50%, 0); }
  .celebrate { transition: opacity .01s linear; }
  .celebrate .cel-card { transition: none; transform: none; }
  .celebrate .cel-ring { display: none; }

  .lesson-bar.shine > i::after,
  .hud-pill.pop,
  .fb-ico,
  .bubble.pop,
  .bubble.correct::after,
  .avatar.cheer,
  .avatar.cheer::after,
  .cel-ico,
  .rw-stars > i,
  .rec-badge::before,
  .composer.nudge { animation: none; }
}

/* ============ 手机 / 平板：安全区与触控 ============
   ① 安全区：viewport 声明了 viewport-fit=cover，内容会铺到刘海和底部手势条底下，
      所以要自己留白。env() 取不到值时回退 0px，桌面端表现与改动前完全一致。
      放在文件末尾，才能盖住上面各断点里的 padding 简写。
   ② touch-action: manipulation：去掉「双击放大」这条手势（配对环节连点两下不再被吞掉），
      但保留双指缩放 —— 学生要放大看汉字，所以绝不写 user-scalable=no。
   ③ 配对卡片：长按不弹系统的「拷贝 / 查询」菜单，手机上也当按键盘玩。 */
.chat-header { padding-top: calc(16px + var(--safe-t)); }
.composer    { padding-bottom: calc(20px + var(--safe-b)); }
.sidebar     { padding-top: calc(22px + var(--safe-t)); padding-bottom: calc(22px + var(--safe-b)); }

/* 横屏时刘海会压在左右两侧，所以左右也要让开 */
.chat-header, .composer, .messages {
  padding-left: calc(28px + var(--safe-l));
  padding-right: calc(28px + var(--safe-r));
}
.sidebar { padding-left: calc(18px + var(--safe-l)); padding-right: calc(18px + var(--safe-r)); }

@media (max-width: 1100px) {
  .sidebar {
    padding-left: calc(14px + var(--safe-l));
    padding-right: calc(14px + var(--safe-r));
  }
}

@media (max-width: 900px) {
  .sidebar {
    padding-top: calc(16px + var(--safe-t));
    padding-bottom: calc(16px + var(--safe-b));
    padding-left: calc(11px + var(--safe-l));
    padding-right: calc(11px + var(--safe-r));
  }
}

@media (max-width: 560px) {
  .sidebar {
    padding-top: calc(20px + var(--safe-t));
    padding-bottom: calc(20px + var(--safe-b));
    padding-left: calc(16px + var(--safe-l));
    padding-right: calc(16px + var(--safe-r));
  }
  .chat-header, .composer, .messages {
    padding-left: calc(16px + var(--safe-l));
    padding-right: calc(16px + var(--safe-r));
  }
}

button,
input,
select,
.chip,
.mcard,
.flashcard,
.lesson-btn { touch-action: manipulation; }

.mcard { user-select: none; -webkit-user-select: none; }

/* 窄屏（≤900px）小字抬升 · 续：这些选择器的基础规则在文件后半段（>900 行），
   同特异性时后写的赢，所以抬升必须放在它们后面才真的生效
   （前面的 900px 断点块会被这些基础规则盖掉 —— phone-type-scale 测试守着）。 */
@media (max-width: 900px) {
  .speak-btn.en { font-size: 12px; }
  .tour-count { font-size: 12px; }
  .tour-list-item b { font-size: 12px; }
  .stat-chip { font-size: 12px; }
  .stat-goal { font-size: 12px; }
  .rw-grid span { font-size: 12px; }
  .rw-goal { font-size: 12px; }
  .rw-next { font-size: 12px; }
  .hud-pill { font-size: 12px; }
}

/* ============ 手机档（≤560px） ============
   v144（cap-course-typography，教师反馈 2026-10-08）：课程内容字号 12.5px
   封顶 —— 手机档不再抬升内容字号（旧「第三档加大」口径作废）；本块只剩
   外壳小字抬升与卡片自适应 / 触控规则。放在文件最后保证级联赢过前面的断点，
   phone-type 测试守着封顶。 */
@media (max-width: 560px) {
  #userInput { font-size: 20px; }
  #currentLesson { font-size: 20px; }
  .step { font-size: 18px; }
  .chat-sub { font-size: 16px; }
  .mistakes-card .mk-input { font-size: 17px; }

  /* 字体统一（教师反馈 2026-10-08）：.lesson-btn / .lesson-num 退出手机档抬升 ——
     侧栏课列表是紧凑导航（手机上是抽屉），字号走全局 12.5px / 11px，与 NPCR 一致 */
  .ghost-btn { font-size: 16px; }
  .primary-btn { font-size: 16px; }
  .brand-name { font-size: 18px; }

  /* 小字抬到 ≥14px（版本号行、导览按钮 —— 学生和家长要读；v144 起外壳专属，
     内容小字随 12.5px 封顶不再抬升） */
  .footer-ver { font-size: 14px; }
  .footer-ver .ghost-btn { font-size: 14px; }
  .modal-ver { font-size: 14px; }
  .step em { font-size: 15px; }
  .speak-btn.en { font-size: 12.5px; }
  .tour-count { font-size: 14px; }
  .tour-list-item b { font-size: 14px; }
  .stat-chip { font-size: 14px; }
  .stat-goal { font-size: 14px; }
  .rw-grid span { font-size: 12.5px; }
  .rw-goal { font-size: 12.5px; }
  .rw-next { font-size: 12.5px; }
  .hud-pill { font-size: 14px; }

  /* ---- 卡片自适应 + 触控增大（教师反馈 2026-10-08）----
     ① 任务卡占满宽 + 隐藏头像：v144（stack-avatar-on-narrow-screens）已把
     这组 :has() 规则上移到 ≤900px 头像上移块（平板竖屏同样受益），此处不再重复 */
  .rep-line-card { max-width: 100%; }

  /* ② 操作按钮触控高度 ≥48px —— 录音 / 💬 Type 打字 / Skip 都用 .chip 这套
     （NPCR 卡内 ctrls 行 + DC 跟读底部固定栏），手机上更好按
     （触控目标靠 padding 撑，文字仍 12.5px 封顶） */
  .chip { padding: 11px 16px; }

  /* ③ 底部输入栏触控加大（v144 enlarge-composer-touch-targets）：
     麦克风 / 发送按钮 60×56、间距 12 —— 桌面档维持 52px 不放大；
     .mic-btn 也在 .composer 里，被 .composer button 一并覆盖 */
  .composer button { width: 60px; min-height: 56px; }
  .composer { gap: 12px; }
  #repeatBar .rep-bar-mic, #repeatBar .rep-bar-skip { padding: 15px 16px; font-size: 12.5px; }
  body.repeat-bar-on #chatScroll { padding-bottom: 100px; }
  .npcr-type-input { padding: 12px 14px; font-size: 16px; }
}

/* v144（cap-course-typography，教师反馈 2026-10-08）：字号设置（大 / 特大）
   已整体移除——课程内容字号 12.5px 封顶与放大模式冲突；旧 mb-cfg 里残留的
   textScale 键无人再读。原 body.ts-large / body.ts-xl 覆盖段删除。 */

/* ================= v75 生词表卡（vocab-list-search-favorites） =================
   跨课查词：搜索框 + 行（☆ 收藏 / 汉字 / 拼音 / 英文 / 单元标签 / 🔊）。 */
.vocab-list-card {
  margin-top: 10px;
  background: linear-gradient(160deg, #f7fbf8, #eef5f0);
  border: 1.5px solid #9dc3a6;
  border-radius: 12px;
  padding: 12px 15px;
  max-height: 52vh;
  overflow-y: auto;
}
.vocab-list-card .vl-title {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--red-deep);
  letter-spacing: .5px;
}
.vocab-list-card .vl-bar {
  display: flex;
  gap: 8px;
  align-items: center;
  margin: 8px 0 4px;
  flex-wrap: wrap;
}
.vocab-list-card .vl-search {
  flex: 1 1 180px;
  min-width: 0;
  padding: 8px 10px;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  font-size: 14px;
}
.vocab-list-card .vl-list { list-style: none; margin: 4px 0 0; padding: 0; }
.vocab-list-card .vl-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px dotted #d8e4db;
}
.vocab-list-card .vl-row:last-child { border-bottom: none; }
.vocab-list-card .vl-star { padding: 2px 8px; font-size: 12.5px; }
.vocab-list-card .vl-zh { font-size: 12.5px; font-weight: 700; letter-spacing: 1px; min-width: 3.2em; }
.vocab-list-card .vl-py { font-size: 12.5px; color: var(--red); min-width: 6em; }
.vocab-list-card .vl-en { font-size: 12.5px; color: var(--ink-soft); flex: 1; }
.vocab-list-card .vl-unit {
  font-size: 11px; font-weight: 700; color: #4e7a58;
  background: #e4efe7; border-radius: 6px; padding: 1px 6px;
}
.vocab-list-card .vl-speak { border: none; background: none; font-size: 12.5px; cursor: pointer; padding: 2px; }
.vocab-list-card .vl-empty { padding: 12px 0; font-size: 12.5px; color: var(--ink-soft); }
.vocab-list-card .vl-hint { margin-top: 8px; font-size: 11.5px; color: var(--ink-soft); }

/* 手机档：与 summary-card 同思路抬一档，学生要能看清（断点内 ≥14px 由 phone-type 守门） */
@media (max-width: 560px) {
  .vocab-list-card .vl-title { font-size: 12.5px; }
  .vocab-list-card .vl-search { font-size: 16px; }
  .vocab-list-card .vl-zh { font-size: 12.5px; }
  .vocab-list-card .vl-py { font-size: 12.5px; }
  .vocab-list-card .vl-en { font-size: 12.5px; }
  .vocab-list-card .vl-unit { font-size: 12.5px; }
  .vocab-list-card .vl-hint { font-size: 12.5px; }
}

/* ================= v82/v83（strict-book-aligned-activities）环节配色 + 徽章 =================
   v83 语义：颜色属于**活动卡片本身**（ph-* 着色类）——渲染时套色，滚进历史也
   保持原色不变；聊天区整体底色不随环节切换变化。全部浅色底，不压文字对比度；
   宽窄屏一致。 */
.ph-vocab    { background: #fefce8; }   /* 闪卡 · 淡黄 */
.ph-match    { background: #eff6ff; }   /* 配对 · 淡蓝 */
.ph-repeat   { background: #f0fdf4; }   /* 跟读 · 淡绿 */
.ph-activity { background: #fdf4ff; }   /* 对话/问答 · 淡紫 */
.ph-practice { background: #fff7ed; }   /* 练习 · 淡橙 */

/* 分隔线上的双语环节徽章：底色取对应环节的深一档，和卡片同色系 */
.stage-divider { display: flex; align-items: center; gap: 10px; }
.phase-badge {
  flex: none;
  padding: 3px 12px;
  border-radius: 999px;
  background: var(--red, #9d282c);
  color: #fff;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .5px;
}
.phase-badge[data-phase="vocab"]    { background: #a16207; }   /* 闪卡 · 黄 */
.phase-badge[data-phase="match"]    { background: #1d4ed8; }   /* 配对 · 蓝 */
.phase-badge[data-phase="repeat"]   { background: #15803d; }   /* 跟读 · 绿 */
.phase-badge[data-phase="activity"] { background: #7e22ce; }   /* 对话/问答 · 紫 */
.phase-badge[data-phase="practice"] { background: #c2410c; }   /* 练习 · 橙 */
.stage-divider .phase-badge { order: 2; }

/* ================= v82 分步指令卡（每环节开头，双语，不含答案） ================= */
.stage-steps {
  margin: 10px 0 4px;
  padding: 10px 14px;
  background: rgba(157, 40, 44, .05);
  border: 1px solid rgba(157, 40, 44, .18);
  border-radius: 12px;
}
.stage-steps .ss-title { font-size: 12.5px; font-weight: 700; color: var(--ink, #222); margin-bottom: 6px; }
.stage-steps .ss-list { margin: 0; padding-left: 20px; }
.stage-steps .ss-item { display: block; margin: 3px 0; }
.stage-steps .ss-zh { display: block; font-size: 12.5px; font-weight: 600; }
.stage-steps .ss-en { display: block; font-size: 12.5px; color: var(--ink-soft, #666); }

/* ================= v82 对话泡布局（对话 / 问答 / 练习） =================
   Buddy 左泡带头像；学生回答区右泡（不同颜色）。判分控件只在右泡。 */
.chat-pair { display: flex; flex-direction: column; gap: 8px; margin-top: 6px; }
.cp-side { display: flex; align-items: flex-start; gap: 8px; max-width: 92%; }
.cp-side.cp-left  { align-self: flex-start; }
.cp-side.cp-right { align-self: flex-end; flex-direction: row-reverse; }
.cp-avatar {
  flex: none;
  width: 34px; height: 34px;
  border-radius: 50%;
  background: #f1f5f9;
  border: 1px solid #e2e8f0;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px;
}
.cp-avatar.you { background: #fdf2f2; border-color: #f3d4d5; }
.cp-bubble {
  padding: 8px 12px;
  border-radius: 14px;
  min-width: 0;
  flex: 1;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
}
.cp-bubble.cp-buddy { border-top-left-radius: 4px; }
.cp-bubble.cp-student {
  background: #fdf6ec;
  border: 1px solid #eeddc3;
  border-top-right-radius: 4px;
}
.cp-who { font-size: 11.5px; color: var(--ink-soft, #666); margin-bottom: 3px; }
.cp-said { font-size: 12.5px; font-weight: 700; }
.cp-verdict { font-size: 12.5px; font-weight: 700; margin-top: 4px; }
.cp-verdict.ok { color: #15803d; }
.cp-verdict.no { color: #b91c1c; }
.cp-target { font-size: 12.5px; color: var(--ink-soft, #666); margin-top: 3px; }
.cp-target-en { font-size: 12px; color: var(--ink-soft, #666); margin-top: 2px; font-style: italic; }
.cp-bubble.said-ok { border-color: #bbe5c0; background: #f2fbf4; }
.cp-bubble.said-no { border-color: #f1c5c5; background: #fdf4f4; }

/* ================= v82 跟读单卡（repeat-single-card） =================
   全部跟读句一张卡：≤720px 单列、>720px 两列；当前句高亮、完成打 ✓。 */
.repeat-card {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
  padding: 10px;
  margin: 10px 0 4px;
  background: #f0fdf4;
  border: 1px solid #cdeed6;
  border-radius: 14px;
}
@media (min-width: 721px) { .repeat-card { grid-template-columns: 1fr 1fr; } }
.rep-item {
  padding: 8px 10px;
  border-radius: 10px;
  border: 1px solid transparent;
  display: flex;
  flex-direction: column;
  gap: 2px;
  position: relative;
}
.rep-item.cur {
  border-color: #34d399;
  background: #fff;
  box-shadow: 0 0 0 2px rgba(52, 211, 153, .25);
}
.rep-item.done .rep-state { color: #15803d; }
.rep-state { position: absolute; top: 6px; right: 10px; font-size: 12.5px; font-weight: 700; }
.rep-zh { font-size: 12.5px; font-weight: 700; letter-spacing: .3px; }
.rep-py { color: var(--red, #9d282c); font-size: 12.5px; }
.rep-en { color: var(--ink-soft, #666); font-size: 12.5px; }
.rep-item .chips { margin-top: 6px; }

/* ============== v91 跟读对话式单句流程（repeat-conversation-flow） ==============
   每句一张系统气泡（rep-line-card）、识别转写走学生气泡（rep-heard）、
   合并结果（rep-fb.ok / rep-fb.no）；录音 / 跳过统一收到底部操作栏 #repeatBar。 */
#repeatBar {
  position: fixed; left: 0; right: 0; bottom: 0;
  display: flex; gap: 10px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0)) 16px;
  background: rgba(255, 255, 255, .96);
  box-shadow: 0 -6px 18px rgba(40, 30, 20, .12);
  z-index: 50;
}
#repeatBar.hidden { display: none; }
#repeatBar .rep-bar-mic { flex: 1; padding: 13px 16px; font-size: 12.5px; text-align: center; }
#repeatBar .rep-bar-skip { flex: 0 0 auto; padding: 13px 16px; font-size: 12.5px; }
body.repeat-bar-on #chatScroll { padding-bottom: 84px; }

.rep-line-card {
  padding: 12px 14px; border-radius: 14px;
  background: #fff; box-shadow: 0 4px 12px rgba(40, 30, 20, .08);
  max-width: 92%;
}
.rep-line-head {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 12px; color: var(--ink-soft, #666); margin-bottom: 6px;
  font-weight: 700;
}
.rep-line-head .zh { color: #1a1a1a; margin-right: 8px; }
.rep-line-zh { font-size: 12.5px; font-weight: 700; letter-spacing: .3px; }
.rep-line-py { color: var(--red, #9d282c); font-size: 12.5px; margin-top: 2px; }
.rep-line-en { color: var(--ink-soft, #666); font-size: 12.5px; margin-top: 2px; }
.rep-line-actions { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }

/* 学生气泡：识别转写 */
.rep-heard-row { display: flex; justify-content: flex-end; margin-top: 6px; }
.rep-heard {
  background: #f0e4d6; color: #1a1a1a;
  border-radius: 14px 14px 4px 14px;
  padding: 8px 12px; max-width: 80%;
}
.rep-heard .zh { font-size: 12.5px; }
.rep-heard .lab { font-size: 12px; color: var(--ink-soft, #666); margin-right: 6px; }

/* 合并结果气泡（绿成功 / 橙失败） */
.rep-fb {
  padding: 11px 14px; border-radius: 14px; margin-top: 6px;
  max-width: 92%;
}
.rep-fb.ok { background: linear-gradient(135deg, #d6f1de, #b9e4c5); color: #134e2c; }
.rep-fb.no { background: linear-gradient(135deg, #fde2cb, #f9c8a3); color: #7a3414; }
.rep-fb .zh-main { font-size: 12.5px; font-weight: 700; }
.rep-fb .en-sub { font-size: 12.5px; opacity: .85; margin-top: 3px; }
/* v136（unify-task-recording-feedback）：「您好 = 礼貌说法」英文说明小字——
   出现在句卡 / 题卡 / NPCR 卡片上，只解释用法，不参与判分 */
.polite-note {
  margin-top: 4px;
  font-size: 12.5px;
  line-height: 1.5;
  color: #6b6259;
  background: #fdf8f3;
  border-left: 3px solid var(--gold, #c9a227);
  border-radius: 6px;
  padding: 4px 8px;
}
.rep-fb .rep-line-zh { font-size: 12.5px; margin-top: 6px; }
/* v136（unify-task-recording-feedback）：红绿语义统一——错/缺字 = 红色粗体
   （去掉下划线，橙色也换成红色，与「错」的直觉一致）；对字 = 绿色。
   教师反馈：「不要下划线，错的红色粗体，对的绿色」。 */
.rep-fb .miss { color: var(--red); font-weight: 800; text-decoration: none; }
/* v134（improve-recording-feedback-clarity）：判红逐字红绿上色——对字绿 */
.rep-fb .ok-char, .npcr-read-h .ok-char { color: #15803d; font-weight: 600; }
.npcr-read-h .miss { color: var(--red); font-weight: 800; text-decoration: none; }
.rep-fb .rep-fb-hl { font-size: 12.5px; font-weight: 700; opacity: .95; }
/* v135（fix-rec-playback-not-showing）：设备录不了音时的低调英文小字——挂在
   回放按钮的位置，老师一眼识别设备问题；能回放时不出现 */
.rec-cap-note { font-size: 12.5px; opacity: .62; margin: 3px 0 2px; color: inherit; }
/* add-android-playback（真机反馈）：AI 判分的说明 / Marking… 挂在该句里，低调小字 */
.rec-ai-note { font-size: 12.5px; opacity: .78; margin: 4px 0 2px; color: inherit; }
/* add-lesson-opening-order：开课判分方式卡 */
.mark-card { display: flex; flex-direction: column; gap: 6px; }
.mark-card-text { font-size: 12.5px; line-height: 1.45; }
.mark-card-note { font-size: 12px; opacity: .7; line-height: 1.4; }
.mark-card .mark-open { align-self: flex-start; }
.cfg-test-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 2px 0 8px; }
.rep-fb .rep-fb-choices { display: flex; gap: 6px; margin-top: 9px; flex-wrap: wrap; }
.rep-fb .chip { padding: 9px 12px; font-size: 12.5px; }

/* v110（dc1-live-record-controls）：录音中聊天流内联 Stop / Skip 行——
   真机底部固定栏可能被浏览器 UI 遮住，操作出口必须跟着内容走 */
.rep-live-actions { display: flex; gap: 8px; margin: 8px 0 4px; flex-wrap: wrap; }

/* add-guided-retry-loop：判红后「先听范读」按钮的视觉突出（脉冲描边，
   提醒学生先听再试）；reduced-motion 降级见文件尾媒体查询 */
/* v115：btn-highlight 从纯光圈升级为实底行动按钮——红底白字高对比。
   此前只有 box-shadow 脉冲，chip soft 的 --ink-soft 字色落在浅色反馈卡
   （.rep-fb.no 橙渐变）上几乎不可见，学生看到的是「空按钮」。
   组合选择器抬到 (0,2,0) 才能压过 .chip.soft / .ghost-btn 的字色背景。 */
.btn-highlight, .btn-highlight.chip, .btn-highlight.ghost-btn {
  background: var(--red);
  color: #fff;
  border-color: transparent;
  font-weight: 700;
  animation: btnGlow 1.6s ease-in-out infinite;
  border-radius: 10px;
}
.btn-highlight:hover, .btn-highlight.chip:hover, .btn-highlight.ghost-btn:hover {
  background: var(--red-deep);
  color: #fff;
}
@keyframes btnGlow {
  0%, 100% { box-shadow: 0 0 0 2px rgba(194, 65, 12, .35); }
  50% { box-shadow: 0 0 0 6px rgba(194, 65, 12, .18); }
}

/* ================= v92+ NPCR 侧栏轨道列表 + Read-Aloud / Reading 卡 =================
   与现有侧栏主题色协调（米色纸张 + 红 + 金）；不破坏 DC1 .lesson-btn 计数。 */
.npcr-tracks { display: flex; flex-direction: column; gap: 10px; }
/* MD8.2（simplify-course-nav）：轨道组手风琴已删 —— 组里只有「非交互标题 + 平铺课按钮」，
   标题只说明这是哪本课本（含课数），不是 button、点了没反应 */
.track-group { display: flex; flex-direction: column; gap: 6px; }
.track-title {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  padding: 9px 10px;
  background: rgba(246, 233, 226, .08);
  border: 1px solid rgba(246, 233, 226, .16);
  border-radius: 10px;
  color: #f6e9e2;
  font-size: 12.5px; font-weight: 700;
  letter-spacing: .5px;
  cursor: default; text-align: left;
}
.track-title .th-title { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.track-title .th-count { font-size: 11px; font-weight: 600; opacity: .65; flex-shrink: 0; }
.npcr-track-group {
  padding: 0;
  background: none;
  border: none;
}
.npcr-track-empty {
  font-size: 11.5px; color: #f6e9e2; opacity: .55;
  padding: 8px 10px; font-style: italic;
}
/* v137（fix-npcr-typing-and-recording-fallback / B5）：read-aloud 卡片
   「💬 Type 打字」入口的输入行——与 ctrls 行同宽、input 占满剩余宽度 */
.npcr-type-row {
  display: flex; align-items: center; gap: 8px;
  width: 100%; min-width: 0;
  margin-top: 6px;
}
.npcr-type-input {
  flex: 1 1 auto; min-width: 0;
  padding: 8px 10px;
  background: rgba(0, 0, 0, .18);
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 8px;
  color: #f6e9e2; font-size: 14px; font-family: inherit;
  outline: none;
}
.npcr-type-input:focus { border-color: #f6e9e2; }
.npcr-type-input::placeholder { color: rgba(246, 233, 226, .45); }

.npcr-lesson-btn {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; margin: 3px 0;
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: 8px;
  color: #f6e9e2; font-size: 12.5px;
  cursor: pointer; text-align: left; font-family: inherit;
  width: 100%;
  min-width: 0;
}
.npcr-lesson-btn:hover { background: rgba(255, 255, 255, .14); }
.npcr-lesson-btn.current {
  background: #f6e9e2; color: var(--red-dark); font-weight: 600;
  border-color: transparent;
}
.npcr-lesson-num {
  width: 24px; height: 24px; display: grid; place-items: center;
  border-radius: 6px; background: rgba(0, 0, 0, .18);
  font-size: 11px; font-weight: 700; flex-shrink: 0;
}
/* MD7.5（R3）：课程按钮只显示中文课名，单行省略 —— 英文全名仍在课卡标题里 */
.npcr-lesson-title { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* NPCR Read-Aloud / Reading 通用卡 */
.npcr-read-card {
  margin: 10px 0 4px;
  padding: 12px 14px;
  background: #f0fdf4;
  border: 1px solid #cdeed6;
  border-radius: 14px;
}
.npcr-read-card .npcr-read-lines { display: flex; flex-direction: column; gap: 2px; margin-bottom: 8px; }
.npcr-read-card .npcr-read-h { font-size: 12.5px; font-weight: 700; }
.npcr-read-card .npcr-read-p { color: var(--red, #9d282c); font-size: 12.5px; }
.npcr-read-card .npcr-read-e { color: var(--ink-soft, #666); font-size: 12.5px; }
.npcr-read-card .npcr-read-ctrls { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.npcr-read-card .npcr-read-status { font-size: 12.5px; color: var(--ink-soft); }
.npcr-read-card.pass { border-color: #34d399; background: #ecfdf5; }
.npcr-read-card.fail { border-color: #f87171; background: #fef2f2; }
/* MD8.3+MD8.4：红反馈内的发音教练卡（MD8.3 首版是两行文字；MD8.4 起是
   pron-coach-card，旧类名保留作锚点——视觉由 .pron-coach-card 提供） */
.npcr-read-card .npcr-read-tip { margin-top: 10px; }

/* v137（fix-npcr-typing-and-recording-fallback）：Read Aloud 打字入口。
   点 💬 Type 打字 后 ctrls 行内联展开的 input + Submit / Cancel。 */
.npcr-type-row {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  width: 100%; margin-top: 6px;
}
.npcr-type-input {
  flex: 1 1 160px; min-width: 0;
  padding: 9px 12px; font-size: 15px; line-height: 1.4;
  border: 1.5px solid rgba(17, 24, 39, .25); border-radius: 12px;
  background: #fff; color: #111827; outline: none;
}
.npcr-type-input:focus { border-color: var(--brand, #2563eb); box-shadow: 0 0 0 3px rgba(37, 99, 235, .12); }
.npcr-type-row .npcr-type-submit { flex: 0 0 auto; }
.npcr-type-row .npcr-type-cancel { flex: 0 0 auto; }

/* MD8.4（pron-coach-cards）：发音教练卡——DC1 跟读反馈与 NPCR 红反馈共用 */
.pron-coach-card {
  margin-top: 10px;
  padding: 10px 12px;
  border-left: 3px solid #f59e0b;
  background: #fffbeb;
  border-radius: 10px;
  color: #111827;   /* 浅底嵌卡：钉深色字（--ink-soft 在深色主题下是浅色，看不清） */
}
.pron-coach-card .pcc-main { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.pron-coach-card .pcc-char { font-size: 12.5px; font-weight: 700; line-height: 1.2; }
.pron-coach-card .pcc-py { color: var(--red, #9d282c); font-size: 12.5px; font-weight: 600; }
.pron-coach-card .pcc-badge {
  font-size: 11px; padding: 2px 9px; border-radius: 999px;
  background: #fde68a; color: #92400e; white-space: nowrap;
}
.pron-coach-card .pcc-svg svg { width: 100%; max-width: 260px; height: auto; display: block; margin: 6px 0 2px; }
.pron-coach-card .pcc-zh { font-size: 12.5px; line-height: 1.55; margin-top: 4px; }
.pron-coach-card .pcc-en { font-size: 12.5px; color: #6b7280; line-height: 1.5; }
.pron-coach-card .pcc-actions { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; align-items: center; }
.pron-coach-card .pcc-actions .chip { cursor: pointer; text-decoration: none; display: inline-block; }
/* 「听范读 Listen / 拼音表」按钮：浅底上黑字深边（原 var(--ink-soft) 浅色看不清） */
.pron-coach-card .pcc-actions .chip.soft { color: #111827; border-color: rgba(17, 24, 39, .35); }
.pron-coach-card .pcc-actions .chip.soft:hover { background: #111827; border-color: #111827; color: #fff; }

/* v123（coach-card-ab-playback）：慢放 chips + A/B 对比播放
   慢放更紧凑小号（次要操作，数字用等宽防止 0.75x/0.5x 抖动）；
   A/B 对比是本卡核心动作——琥珀主题呼应卡左边框 #f59e0b；
   .playing = 播放中反馈态（点一下短暂高亮，念完/放完自动熄灭） */
.pron-coach-card .pcc-actions .chip.pcc-slow {
  padding: 5px 11px;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.pron-coach-card .pcc-actions .chip.pcc-ab {
  border-color: #f59e0b;
  color: #92400e;
  font-weight: 600;
}
.pron-coach-card .pcc-actions .chip.pcc-ab:hover {
  background: #f59e0b;
  border-color: #f59e0b;
  color: #fff;
}
.pron-coach-card .pcc-actions .chip.playing {
  background: #f59e0b;
  border-color: #f59e0b;
  color: #fff;
}
@media (prefers-reduced-motion: no-preference) {
  .pron-coach-card .pcc-actions .chip.playing { animation: pccPlaying 1.1s ease infinite; }
}
@keyframes pccPlaying {
  0%, 100% { box-shadow: 0 0 0 2px rgba(245, 158, 11, .3); }
  50% { box-shadow: 0 0 0 5px rgba(245, 158, 11, .12); }
}

/* v128（fix-playback-stt-flush-retry-mic）：「▶ My Recording」播放中反馈态
   此前点击后外观零变化（再点还是从头重播，无法暂停），学生不知道有没有在放、
   放没放完。播放中红边高亮（与 app 主色一致），播完 / 暂停自动熄灭。 */
.rep-play.playing {
  border-color: var(--red, #e11d48);
  color: var(--red, #e11d48);
}
.rep-play.playing:hover {
  background: var(--red, #e11d48);
  border-color: var(--red, #e11d48);
  color: #fff;
}

/* ================= v93 NPCR 完整版渲染器（read-aloud 逐句卡 / situational 答题卡 / reading 阅读大卡） ================= */
.npcr-read-card .npcr-read-count {
  font-size: 11.5px; color: var(--ink-soft, #666); margin-bottom: 6px;
  letter-spacing: .3px;
}
.npcr-expect-card {
  margin: 10px 0 4px;
  padding: 12px 14px;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 14px;
}
.npcr-expect-card .npcr-expect-prog {
  font-size: 11.5px; color: var(--red, #9d282c); font-weight: 700; margin-bottom: 4px;
}
.npcr-expect-card .npcr-expect-task {
  font-size: 15px; font-weight: 600; margin-bottom: 4px;
}
.npcr-expect-card .npcr-expect-tip {
  font-size: 12.5px; color: var(--ink-soft, #666); margin-bottom: 8px;
}
.npcr-expect-card .npcr-expect-status {
  font-size: 13px; margin-top: 8px; min-height: 18px;
}
.npcr-expect-card.pass { border-color: #34d399; background: #ecfdf5; }
.npcr-expect-card.fail { border-color: #f59e0b; background: #fffbeb; }
.npcr-reading-card {
  margin: 10px 0 4px;
  padding: 14px 16px;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 14px;
}
.npcr-reading-card .npcr-read-toggles {
  display: flex; gap: 8px; margin-bottom: 10px; flex-wrap: wrap;
}
.npcr-toggle.off { opacity: .55; }
.npcr-reading-card .npcr-read-fulltext {
  font-size: 12.5px; line-height: 1.7; margin-bottom: 12px;
  padding: 10px 12px; background: var(--paper, #faf6ef); border-radius: 10px;
}
.npcr-reading-card .npcr-read-rows { display: flex; flex-direction: column; gap: 8px; }
.npcr-reading-card .npcr-read-row {
  padding: 8px 10px;
  border: 1px solid #e8e0d8; border-radius: 10px;
}
.npcr-reading-card .npcr-read-row.pass { border-color: #34d399; background: #ecfdf5; }
.npcr-reading-card .npcr-read-row.fail { border-color: #f87171; background: #fef2f2; }
.npcr-reading-card .npcr-read-row .npcr-read-ctrls { margin-top: 6px; }
.npcr-reading-card .npcr-read-row .primary-btn,
.npcr-reading-card .npcr-read-row .ghost-btn {
  padding: 5px 10px; font-size: 12.5px;
}

/* ================= v92+ 教师模式入口 + 教师面板 + 登录向导 ================= */
.teacher-entry { border-color: rgba(217, 164, 65, .55); }
.teacher-panel {
  position: fixed; inset: 0; z-index: 1000;
  background: var(--paper, #faf6ef);
  display: flex; flex-direction: column;
  font-family: inherit; color: var(--ink, #212121);
}
.tp-topbar {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 20px;
  background: var(--red-deep, #8c2f39); color: #f6e9e2;
}
.tp-topbar strong { font-size: 15px; }
.tp-note { font-size: 11.5px; opacity: .75; flex: 1; }
.tp-tabs { display: flex; gap: 4px; padding: 8px 20px 0; background: var(--red-deep, #8c2f39); }
.tp-tab {
  padding: 8px 14px; border: 0; background: rgba(255,255,255,.1);
  color: rgba(246,233,226,.8); font-size: 13px; cursor: pointer;
  border-radius: 8px 8px 0 0; font-family: inherit;
}
.tp-tab.current { background: var(--paper, #faf6ef); color: var(--red-dark, #6a222a); font-weight: 700; }
.tp-body { flex: 1; overflow-y: auto; padding: 16px 20px; }
.tp-section { display: none; }
.tp-section.current { display: block; }
.tp-toolbar { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.tp-import-box {
  padding: 12px; background: #fff; border: 1px solid #ddd;
  border-radius: 10px; margin-bottom: 12px;
}
.tp-import-box textarea {
  width: 100%; font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 12px; padding: 8px; border: 1px solid #ccc; border-radius: 6px;
  box-sizing: border-box; resize: vertical;
}
.tp-import-box input {
  display: block; width: 100%; box-sizing: border-box;
  padding: 8px 10px; margin: 6px 0; border: 1px solid #ccc; border-radius: 6px;
  font-size: 13.5px; font-family: inherit;
}
.tp-import-ctrls { display: flex; gap: 8px; margin-top: 8px; }
.tp-import-note { font-size: 12.5px; margin-top: 8px; }
.tp-import-note.ok { color: #2e7d32; }
.tp-import-note.err { color: #d32f2f; }
.tp-content-layout { display: grid; grid-template-columns: minmax(220px, 1fr) minmax(300px, 2fr); gap: 14px; }
@media (max-width: 800px) { .tp-content-layout { grid-template-columns: 1fr; } }
.tp-tree { background: #fff; border: 1px solid #ddd; border-radius: 10px; padding: 10px; max-height: 60vh; overflow-y: auto; }
.tp-form { background: #fff; border: 1px solid #ddd; border-radius: 10px; padding: 14px; }
.tp-form-hint { color: #888; font-size: 13px; }
.tp-track-head {
  font-size: 13px; font-weight: 700; color: var(--red-deep, #8c2f39);
  margin: 10px 0 4px; display: flex; align-items: center; gap: 6px;
}
.tp-track-head:first-child { margin-top: 0; }
.tp-track-lock { font-size: 11px; opacity: .6; }
.tp-lesson-row {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 8px; border-radius: 6px; cursor: pointer; font-size: 13px;
}
.tp-lesson-row:hover { background: rgba(178, 58, 72, .07); }
.tp-lesson-row.current { background: rgba(178, 58, 72, .14); font-weight: 600; }
.tp-lesson-row .tp-x {
  margin-left: auto; border: 0; background: transparent; color: #b71c1c;
  font-size: 14px; cursor: pointer; padding: 2px 6px;
}
.tp-lesson-row .tp-x[disabled] { color: #bbb; cursor: not-allowed; }
.tp-field { margin: 8px 0; }
.tp-field label { display: block; font-size: 12px; color: #666; margin-bottom: 3px; }
.tp-field input, .tp-field textarea, .tp-field select {
  width: 100%; box-sizing: border-box; padding: 7px 10px;
  border: 1px solid #ccc; border-radius: 6px; font-size: 13.5px; font-family: inherit;
}
.tp-field input[disabled], .tp-field textarea[disabled] {
  background: #f2f2f2; color: #999; cursor: not-allowed;
}
.tp-line-row { display: grid; grid-template-columns: 1fr 1fr 1fr 28px; gap: 6px; margin: 4px 0; }
.tp-line-row input { padding: 6px 8px; border: 1px solid #ccc; border-radius: 5px; font-size: 13px; }
.tp-line-x { border: 0; background: transparent; color: #b71c1c; cursor: pointer; font-size: 14px; }
.tp-form-actions { display: flex; gap: 8px; margin-top: 12px; }
.tp-stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px; }
.tp-stat-card { background: #fff; border: 1px solid #ddd; border-radius: 10px; padding: 12px; }
.tp-stat-card strong { display: block; font-size: 22px; color: var(--red-deep, #8c2f39); }
.tp-stat-card span { font-size: 12px; color: #666; }
.tp-teacher-row {
  display: flex; align-items: center; gap: 8px;
  background: #fff; border: 1px solid #ddd; border-radius: 8px;
  padding: 10px 12px; margin: 6px 0;
}
.tp-teacher-row strong { flex: 1; }
.tp-teacher-badge { font-size: 11px; background: rgba(217,164,65,.2); color: #8a6a1f; padding: 2px 8px; border-radius: 10px; }

/* 登录 / 首次设置向导 */
.teacher-login {
  position: fixed; inset: 0; z-index: 1100;
  background: rgba(0,0,0,.45);
  display: flex; align-items: center; justify-content: center;
}
.tl-card {
  background: var(--paper, #faf6ef); border-radius: 14px;
  padding: 20px; width: min(92vw, 380px);
  box-shadow: 0 18px 40px rgba(0,0,0,.25);
}
.tl-card h3 { margin: 0 0 6px; color: var(--red-deep, #8c2f39); }
.tl-hint { font-size: 12px; color: #888; margin: 0 0 12px; }
.tl-card input, .tl-card select {
  display: block; width: 100%; box-sizing: border-box;
  padding: 9px 12px; margin: 6px 0; border: 1px solid #ccc;
  border-radius: 8px; font-size: 14px; font-family: inherit;
}
.tl-card button { margin-top: 8px; width: 100%; }
.tl-error { color: #d32f2f; font-size: 13px; margin: 8px 0 0; }

/* v131（mic-level-guidance）：录音电平条——太小声 / 太吵现场提示（文案纯英文）
   不支持 AudioContext 的浏览器由 JS 保持 hidden，这里只需保证 hidden 真的藏住。 */
.mic-level { display: flex; align-items: center; gap: 8px; padding: 2px 12px 6px; font-size: 12px; color: #64748b; }
.mic-level[hidden] { display: none; }
.mic-level-track { display: block; flex: 1 1 auto; height: 6px; border-radius: 999px; background: #e2e8f0; overflow: hidden; }
.mic-level-fill { display: block; height: 100%; width: 0; background: #22c55e; transition: width .12s linear; }
.mic-level-fill.quiet { background: #f59e0b; }
.mic-level-fill.loud { background: #ef4444; }
.mic-level-tip { flex: 0 0 auto; }

/* ============ v144（stack-avatar-on-narrow-screens，教师真机反馈） ============
   窄屏（≤900px，含手机与平板竖屏）：「汉 / 你」头像不再占气泡侧边一整列——
   挪到各自气泡上方当 24px 小徽标，气泡横向占满可用宽度，台词 / 长卡不再被挤窄。
   放在文件末尾：同特异性后写的赢，压过前面 88%/92% 的 .msg 限宽。
   桌面（>900px）保持头像在侧的聊天观感。 */
@media (max-width: 900px) {
  .msg { flex-direction: column; gap: 4px; max-width: 100%; }
  .msg.bot  { align-items: flex-start; }   /* 汉徽标在气泡上方靠左 */
  .msg.user { align-items: flex-end; }     /* 你徽标在气泡上方靠右 */
  .avatar { width: 24px; height: 24px; font-size: 12px; border-radius: 8px; }

  /* 任务卡消息（matching / 闪卡 / 对话练习 / NPCR 卡 / 复盘 / 生词表 / 错题 / 分步）
     占满宽并隐藏头像——卡片自带边框底色，独立成行更宽。
     从 ≤560 上移到 ≤900（平板竖屏同样受益）；:has() 老浏览器不支持时退回原状 */
  .msg:has(.match-grid), .msg:has(.deck), .msg:has(.prompt-card),
  .msg:has(.npcr-read-card), .msg:has(.rep-line-card), .msg:has(.summary-card),
  .msg:has(.vocab-list-card), .msg:has(.mistakes-card), .msg:has(.stage-steps) {
    max-width: 100%;
  }
  .msg:has(.match-grid) > .avatar, .msg:has(.deck) > .avatar,
  .msg:has(.prompt-card) > .avatar, .msg:has(.npcr-read-card) > .avatar,
  .msg:has(.rep-line-card) > .avatar, .msg:has(.summary-card) > .avatar,
  .msg:has(.vocab-list-card) > .avatar, .msg:has(.mistakes-card) > .avatar,
  .msg:has(.stage-steps) > .avatar { display: none; }
}

